UNPKG

@monitoro/herd

Version:

Automate your browser, build AI web tools and MCP servers with Monitoro Herd

251 lines (222 loc) • 7.45 kB
import * as fs from 'fs'; import * as path from 'path'; import * as promptly from 'promptly'; // @ts-ignore import * as packageJson from '../../../package.json' with { type: "json" }; // @ts-ignore const { version } = packageJson.default; const prompt = promptly.default.prompt; // Default template files content const urlsTemplate = `import type { TrailUrl } from "@monitoro/herd"; export default [{ "id": "default-url", "template": "https://example.com/{{param1}}/{{param2}}", "description": "Default URL for the trail", "examples": [ { "param1": "value1", "param2": "value2" } ], "params": { "param1": { "type": "string", "description": "The first parameter" }, "param2": { "type": "string", "description": "The second parameter" } } }] as TrailUrl[];`; const selectorsTemplate = `import type { TrailSelector } from "@monitoro/herd"; export default [{ "id": "default-selector", "value": { "data": { "_$r": "body", "title": { "_$": "title" }, "content": { "_$": "main" } } }, "description": "Default selector for extracting basic page data", "examples": [ { "urlId": "default-url", "urlParams": { "param1": "value1", "param2": "value2" } } ] }] as TrailSelector[];`; const actionsTemplate = `import type { Device, TrailAction, TrailActionManifest, TrailRunResources } from "@monitoro/herd"; export class DefaultAction implements TrailAction { manifest: TrailActionManifest = { name: "default-action", description: "Default action for the trail", params: { "param1": { "type": "string", "description": "The first parameter" }, "param2": { "type": "string", "description": "The second parameter" } }, result: { type: "object", description: "Basic page data", properties: { title: { type: "string" }, content: { type: "string" } } }, examples: [{ "param1": "value1", "param2": "value2" }] } async test(device: Device, params: Record<string, any>, resources: TrailRunResources) { try { const result = await this.run(device, params, resources); if (!result) { return { status: "error", message: "No results found", result: null }; } return { status: "success", result }; } catch (e) { return { status: "error", message: \`Error: \${e}\`, result: null }; } } async run(device: Device, params: Record<string, any>, resources: TrailRunResources) { const page = await device.newPage(); try { // Navigate to the default URL await page.goto(resources.url('default-url', { param1: params.param1, param2: params.param2 })); // Extract data using the default selector const extracted = await page.extract(resources.selector('default-selector')); // Return the extracted data return extracted?.data || {}; } finally { await page.close(); } } }`; // Function to create package.json with the given trail name function createPackageJson(trailName) { return `{ "name": "@your-org/${trailName}", "description": "A herd.garden trail created with herd trail init", "version": "1.0.0", "type": "module", "private": true, "dependencies": { "@monitoro/herd": "${version}" } }`; } // Function to create .gitignore file function createGitignore() { return `node_modules .build .env .env.local `; } // Function to create README.md file function createReadme(trailName) { return `# ${trailName} This is a herd.garden trail created with herd trail init. ## Usage Test all actions and selectors: \`\`\`bash herd trail test \`\`\` Test a specific action: \`\`\`bash herd trail test --action default-action \`\`\` Test a specific selector: \`\`\`bash herd trail test --selector default-selector \`\`\` Run the trail: \`\`\`bash herd trail run \`\`\` Run the trail silently (only output results): \`\`\`bash herd trail run --silent # or herd trail run -s \`\`\` ## URLs ### default-url This is the default URL for the trail. #### Parameters - \`param1\`: The first parameter - \`param2\`: The second parameter ## Selectors ### default-selector This is the default selector for the trail. ## Actions ### default-action This is the default action for the trail. #### Parameters - \`param1\`: The first parameter - \`param2\`: The second parameter #### Result - \`title\`: The title of the page - \`content\`: The content of the page `; } /** * Execute the trail initialization * Creates a new trail with default structure in the specified directory */ export async function execute() { try { // Ask for the trail name const trailName = await prompt('šŸ‚ Enter a name for your new Herd trail: '); if (!trailName) { console.error('āŒ Oops! No trail name provided'); process.exit(1); } // Create the trail directory (use the provided name) const trailDir = path.join(process.cwd(), trailName); // Check if directory already exists if (fs.existsSync(trailDir)) { const response = await prompt(`šŸ¤” Directory "${trailName}" already exists. Overwrite? (y/n): `); if (response.toLowerCase() !== 'y') { console.log('šŸ›‘ Trail creation cancelled. No changes were made.'); process.exit(0); } } else { fs.mkdirSync(trailDir); } // Create the files fs.writeFileSync(path.join(trailDir, 'urls.ts'), urlsTemplate); fs.writeFileSync(path.join(trailDir, 'selectors.ts'), selectorsTemplate); fs.writeFileSync(path.join(trailDir, 'actions.ts'), actionsTemplate); fs.writeFileSync(path.join(trailDir, 'package.json'), createPackageJson(trailName)); fs.writeFileSync(path.join(trailDir, 'README.md'), createReadme(trailName)); fs.writeFileSync(path.join(trailDir, '.gitignore'), createGitignore()); console.log(`\nšŸŽ‰ Trail "${trailName}" created successfully! šŸŽ‰`); console.log(`\nšŸ“ Files created:`); console.log(` ā”œā”€ ${trailName}/urls.ts`); console.log(` ā”œā”€ ${trailName}/selectors.ts`); console.log(` ā”œā”€ ${trailName}/actions.ts`); console.log(` ā”œā”€ ${trailName}/package.json`); console.log(` ā”œā”€ ${trailName}/README.md`); console.log(` └─ ${trailName}/.gitignore`); console.log(`\nšŸš€ Ready to go! You can now:`); console.log(` 1. cd ${trailName}`); console.log(` 2. run \`npm install\` or \`yarn\` `); console.log(` 3. Run your first test: herd trail test --action default-action`); console.log(`\nšŸ‚ Happy trail blazing with Herd! šŸ‚`); } catch (error) { console.error('āŒ Error initializing trail:', error); process.exit(1); } }