#!/usr/bin/env node import fs from 'node:fs' import path from 'node:path' import { DEFAULTS, USAGE, loadConfig } from '../src/config.mjs' import { Orchestrator } from '../src/orchestrator.mjs' import { startServer, runsBaseDir } from '../src/server.mjs' import { installTerminalControls } from '../src/terminal.mjs' import { printLog } from '../src/console.mjs' import { loadRun } from '../src/state.mjs' async function main() { let config try { config = loadConfig(process.argv.slice(2)) } catch (err) { process.stderr.write(`\n Error: ${err.message}\n\n${USAGE}\n`) process.exit(2) } if (config.help) { process.stdout.write(USAGE + '\n') process.exit(0) } if (config.promptExtra && fs.existsSync(config.promptExtra)) { config.promptExtra = fs.readFileSync(config.promptExtra, 'utf8') } const orchestrator = new Orchestrator(config) orchestrator.state.on('log', (entry) => printLog(entry, { quiet: config.quiet })) // --resume: reuse the previous run's session and stage progress. if (config.resume) { try { const prev = loadRun(runsBaseDir(config), config.resume) if (prev.sessionID) orchestrator.state.update({ sessionID: prev.sessionID }) const done = (prev.iterations || []).filter((it) => it.stageStatus === 'done' && it.stageId) for (const it of done) orchestrator.completedStages.add(it.stageId) const last = (prev.iterations || []).slice(-1)[0] if (last?.percent != null) orchestrator.lastPercent = last.percent orchestrator.log('system', `Resumed run ${config.resume} (session ${prev.sessionID || '—'}, last ${orchestrator.lastPercent}%).`) } catch { process.stderr.write(` Warning: could not load run "${config.resume}" — starting fresh.\n`) } } const dashboard = await startServer(config, orchestrator) const controls = installTerminalControls(orchestrator) let exitCode = 0 const shutdown = async (code) => { controls.dispose() await dashboard.close().catch(() => {}) process.exit(code) } process.on('SIGINT', () => { orchestrator.requestStop() }) try { const final = await orchestrator.run() if (final.status === 'done-with-errors') exitCode = 1 } catch (err) { process.stderr.write(`\n Fatal: ${err?.stack || err}\n`) exitCode = 1 } if (config.keepOpen) { process.stdout.write(`\n Dashboard still open at ${dashboard.url} (Ctrl+C to exit)\n`) return } await shutdown(exitCode) } main()