#!/usr/bin/env tsx // Agent Orchestrator E2E Test Daemon — CLI entry point // Usage: tsx index.ts [--full] [--spec ] [--watch] [--agent] import { resolve, dirname } from 'node:path'; import { fileURLToPath } from 'node:url'; import { watch } from 'node:fs'; import { Dashboard } from './dashboard.ts'; import { runSpecs, discoverSpecs, specDisplayName, clearCache, type RunOptions } from './runner.ts'; import { AgentBridge } from './agent-bridge.ts'; const __dirname = dirname(fileURLToPath(import.meta.url)); const SPECS_DIR = resolve(__dirname, '../specs'); // ── CLI args ── const args = process.argv.slice(2); const fullMode = args.includes('--full'); const watchMode = args.includes('--watch'); const agentMode = args.includes('--agent'); const specIdx = args.indexOf('--spec'); const specPattern = specIdx !== -1 ? args[specIdx + 1] : undefined; // ── Init ── const dashboard = new Dashboard(); let bridge: AgentBridge | null = null; let pendingRerun: RunOptions | null = null; if (agentMode) { bridge = new AgentBridge(dashboard); bridge.onRerunRequest((opts) => { pendingRerun = opts; }); bridge.start(); } // ── Run cycle ── async function runCycle(opts: RunOptions = {}): Promise { const specs = discoverSpecs(opts.pattern ?? specPattern); dashboard.setTests(specs.map((s) => ({ name: specDisplayName(s), specFile: s }))); dashboard.startRefresh(); bridge?.setRunning(true); await runSpecs({ pattern: opts.pattern ?? specPattern, full: opts.full ?? fullMode, onResult: (r) => dashboard.updateTest(r.name, r.status, r.durationMs, r.error), }); dashboard.markComplete(); dashboard.stopRefresh(); bridge?.setRunning(false); } function shutdown(poll?: ReturnType, watcher?: ReturnType): void { watcher?.close(); if (poll) clearInterval(poll); dashboard.stop(); bridge?.stop(); process.exit(0); } // ── Main ── async function main(): Promise { if (fullMode) clearCache(); await runCycle(); if (watchMode || agentMode) { const watcher = watchMode ? watch(SPECS_DIR, { recursive: false }, (_ev, f) => { if (f?.endsWith('.test.ts')) pendingRerun = { pattern: specPattern, full: false }; }) : undefined; const poll = setInterval(async () => { if (pendingRerun) { const opts = pendingRerun; pendingRerun = null; await runCycle(opts); } }, 1000); process.on('SIGINT', () => shutdown(poll, watcher)); process.on('SIGTERM', () => shutdown(poll, watcher)); } else { dashboard.stop(); bridge?.stop(); const hasFailed = dashboard.getTests().some((t) => t.status === 'failed'); process.exit(hasFailed ? 1 : 0); } } main().catch((err) => { console.error('Fatal error:', err); dashboard.stop(); bridge?.stop(); process.exit(1); });