UNPKG

@oliverpople/agency-x

Version:

🚀 **Transform feature requests into production-ready code in seconds**

156 lines (126 loc) • 5.07 kB
#!/usr/bin/env node import * as dotenv from 'dotenv'; dotenv.config(); import { runOrchestrator } from '../orchestrator/orchestratorAgent'; import { speak } from '../utils/voice'; import { AGENT_DEFINITIONS } from '../configs/agentConfigs'; import { setDefaultProvider } from '../llm/llmRouter'; import chalk from 'chalk'; const args = process.argv.slice(2); const getArgValue = (argName: string) => { const argIndex = args.indexOf(argName); return argIndex !== -1 && args[argIndex + 1] ? args[argIndex + 1] : null; }; const showHelp = () => { console.log(chalk.dim('agency-x') + chalk.bold(' - AI Orchestration System\n')); console.log('Usage:'); console.log(chalk.cyan(' agency-x') + ' --feature ' + chalk.yellow('"description"')); console.log(chalk.cyan(' agency-x') + ' --resume ' + chalk.yellow('SPEC-ID')); console.log(''); console.log('Options:'); console.log(' --feature What to build'); console.log(' --resume Continue from session ID'); console.log(' --voice Enable audio narration'); console.log(' --concurrent Max parallel agents (default: 5)'); console.log(' --verbose Show detailed logs'); console.log(' --llm LLM provider (claude or openai, default: claude)'); console.log(' --help Show this help'); }; const feature = getArgValue('--feature'); const resume = getArgValue('--resume'); const concurrent = parseInt(getArgValue('--concurrent') || '5', 10); const llmProvider = getArgValue('--llm') || 'claude'; const voice = args.includes('--voice'); const verbose = args.includes('--verbose'); const help = args.includes('--help'); // Validate LLM provider if (!['claude', 'openai'].includes(llmProvider)) { console.error(chalk.red('Invalid LLM provider. Use: claude or openai')); process.exit(1); } // Set the LLM provider setDefaultProvider(llmProvider as 'claude' | 'openai'); if (help) { showHelp(); process.exit(0); } if (!feature && !resume) { console.error(chalk.red('Missing required argument')); console.log('Try: ' + chalk.cyan('agency-x --help')); process.exit(1); } if (verbose) { process.env.DEBUG = 'true'; } let startTime = Date.now(); let isRunning = true; const cleanup = () => { isRunning = false; process.exit(0); }; process.on('SIGINT', cleanup); process.on('SIGTERM', cleanup); // Simple progress indicator const showProgress = (completed: number, total: number, phase?: string) => { const percent = ((completed / total) * 100).toFixed(0); const bar = '█'.repeat(Math.floor(completed / total * 20)) + '░'.repeat(20 - Math.floor(completed / total * 20)); const elapsed = ((Date.now() - startTime) / 1000).toFixed(0); process.stdout.write('\r\x1b[K'); // Clear line process.stdout.write(`${chalk.blue(bar)} ${percent}% (${completed}/${total}) ${elapsed}s`); if (phase) process.stdout.write(chalk.gray(` • ${phase}`)); }; async function main() { try { // Minimal startup message if (resume) { console.log(chalk.dim('Resuming'), chalk.cyan(resume)); } else { console.log(chalk.dim('Building'), chalk.cyan(feature)); } // Show LLM provider being used const providerEmoji = llmProvider === 'openai' ? '🤖' : '🧠'; const providerName = llmProvider === 'openai' ? 'OpenAI GPT' : 'Anthropic Claude'; console.log(chalk.dim(`${providerEmoji} Using ${providerName}`)); if (concurrent !== 5 || voice) { const opts = []; if (concurrent !== 5) opts.push(`${concurrent} concurrent`); if (voice) opts.push('voice enabled'); console.log(chalk.dim(`(${opts.join(', ')})\n`)); } // Add progress tracking callback let progressInterval: NodeJS.Timeout | null = null; let lastStatus = { completed: 0, failed: 0, running: 0 }; if (!verbose) { progressInterval = setInterval(() => { // This will be updated by orchestrator callback showProgress(lastStatus.completed + lastStatus.failed, AGENT_DEFINITIONS.length); }, 500); } const result = await runOrchestrator({ feature: feature || '', voice, resume: resume || undefined, maxConcurrent: concurrent, onStop: voice ? (log) => speak(log.join('\n')) : undefined, onProgress: (status) => { lastStatus = status; } }); if (progressInterval) { clearInterval(progressInterval); process.stdout.write('\r\x1b[K'); // Clear progress line } // Final summary const duration = ((Date.now() - startTime) / 1000).toFixed(1); console.log(chalk.green('✓') + ' Complete in ' + chalk.cyan(duration + 's')); console.log(chalk.dim('Saved: ') + chalk.cyan('./sessions/' + result.specId + '.json')); } catch (error) { const errorMessage = error instanceof Error ? error.message : String(error); console.log('\n' + chalk.red('✗') + ' Failed: ' + errorMessage); if (verbose && error instanceof Error && error.stack) { console.log(chalk.dim('\n' + error.stack)); } process.exit(1); } } main();