#!/usr/bin/env node /** * agent-workflow CLI entry point. * * Supports direct subcommands: start, review, retry-review, retry-execute, decide, status, abort. */ import { parseWorkflowArgs, workflowUsage, type WorkflowArgs, } from "./workflow-args.js"; import { startWorkflow, reviewWorkflow, decideWorkflow, statusWorkflow, abortWorkflow, logsWorkflow, retryReviewWorkflow, retryExecuteWorkflow, extendWorkflow, WorkflowEngineError, } from "./workflow-engine.js"; import { WorkflowConfigError } from "./workflow-config.js"; import { WorkflowLockError } from "./workflow-state.js"; import { startWorkflowWebServer } from "./workflow-web.js"; async function main() { let args: WorkflowArgs; try { args = parseWorkflowArgs(process.argv.slice(2)); } catch (err) { if (err instanceof Error && err.name === "WorkflowArgsError") { process.stderr.write(`Error: ${err.message}\n\n`); workflowUsage(1); } throw err; } try { switch (args.sub) { case "start": await startWorkflow({ planInput: args.planInput, executor: args.executor, vcs: args.vcs, maxCycles: args.maxCycles, newTask: args.newTask, }); break; case "review": await reviewWorkflow({ runId: args.runId }); break; case "retry-review": retryReviewWorkflow({ runId: args.runId }); break; case "retry-execute": await retryExecuteWorkflow({ runId: args.runId, sessionId: args.sessionId }); break; case "decide": await decideWorkflow({ runId: args.runId, decisionInput: args.decisionInput, }); break; case "status": statusWorkflow({ runId: args.runId, json: args.json }); break; case "abort": abortWorkflow({ runId: args.runId, reason: args.reason }); break; case "logs": await logsWorkflow({ runId: args.runId, follow: args.follow, tail: args.tail, }); break; case "extend": await extendWorkflow({ runId: args.runId, additionalCycles: args.additionalCycles, }); break; case "web": await startWorkflowWebServer(args.port); // Keep the process alive await new Promise(() => {}); break; default: { const _exhaustive: never = args; throw new Error(`Unknown subcommand: ${(_exhaustive as any).sub}`); } } } catch (err: any) { if (err && err.code === "EADDRINUSE") { process.stderr.write(`Error: Port is already in use.\n`); process.exit(1); } if (err instanceof WorkflowEngineError) { process.stderr.write(`Error: ${err.message}\n`); process.exit(err.exitCode); } if (err instanceof WorkflowConfigError) { process.stderr.write(`Configuration error: ${err.message}\n`); process.exit(4); } if (err instanceof WorkflowLockError) { process.stderr.write(`Lock error: ${err.message}\n`); process.exit(4); } throw err; } } main().catch((err) => { process.stderr.write(`Unexpected error: ${err.message}\n`); if (err.stack) { process.stderr.write(err.stack + "\n"); } process.exit(1); });