@monitoro/herd
Version:
Automate your browser, build AI web tools and MCP servers with Monitoro Herd
83 lines (82 loc) âĸ 3.51 kB
JavaScript
// This file is used to run a trail action.
// 1. Connect HerdClient
// 2. Get a device
// 3. Pass device to train run method (and run it)
// 4. Return the results
import { loadTrail } from "./loadTrail.js";
import * as fs from 'fs';
import * as path from 'path';
export async function runTrailAction(client, action, params, resources, silent = false) {
const [device] = await client.listDevices();
if (!device) {
throw new Error('â No devices found. Please make sure you have a device connected.');
}
if (!action?.run) {
throw new Error(`â Action is missing the 'run' method. Please make sure your action class implements the required interface.`);
}
const results = await action.run(device, params, resources);
if (!silent) {
console.log('⨠Action completed successfully');
console.log('đ Results:', JSON.stringify(results, null, 2));
}
return results;
}
/**
* Check if a path is a valid trail directory (either built or source)
*/
function isValidTrailDirectory(dirPath) {
// Check for source files
const hasSource = fs.existsSync(path.join(dirPath, "actions.ts")) &&
fs.existsSync(path.join(dirPath, "urls.ts")) &&
fs.existsSync(path.join(dirPath, "selectors.ts"));
// Check for built files
const hasBuild = fs.existsSync(path.join(dirPath, ".build")) &&
fs.existsSync(path.join(dirPath, ".build", "actions.js")) &&
fs.existsSync(path.join(dirPath, ".build", "urls.js")) &&
fs.existsSync(path.join(dirPath, ".build", "selectors.js"));
// Check for built files directly in the directory (downloaded trails)
const hasBuiltFiles = fs.existsSync(path.join(dirPath, "actions.js")) &&
fs.existsSync(path.join(dirPath, "urls.js")) &&
fs.existsSync(path.join(dirPath, "selectors.js"));
return hasSource || hasBuild || hasBuiltFiles;
}
export async function execute(client, path, actionName, params, silent = false) {
try {
// Validate that the path contains a trail
if (!isValidTrailDirectory(path)) {
if (!silent) {
console.warn('â ī¸ Warning: Path may not be a valid trail directory');
}
}
// Load the trail action class and run it
const { actions, resources } = await loadTrail(path);
// If no action specified and only one action exists, use that one
if (!actionName) {
const availableActions = Object.keys(actions);
if (availableActions.length === 1) {
actionName = availableActions[0];
if (!silent) {
console.log(`âšī¸ No action specified, using the only available action: ${actionName}`);
}
}
else {
throw new Error('â No action name provided. Please specify an action to run.');
}
}
if (!actions[actionName]) {
const availableActions = Object.keys(actions).join(', ');
throw new Error(`â Action '${actionName}' not found. Available actions: ${availableActions}`);
}
if (!silent) {
console.log(`đ Running action: ${actionName}`);
}
const result = await runTrailAction(client, actions[actionName], params, resources, silent);
return result;
}
catch (error) {
if (!silent) {
console.error('â Error running trail:', error.message);
}
throw error;
}
}