import { Command } from 'commander'; import chalk from 'chalk'; import { NexusDispatcher } from '../nexus/dispatcher.js'; import { NexusContext } from '@rigstate/shared'; import inquirer from 'inquirer'; export function createNexusCommand() { const command = new Command('nexus'); command .description('Interact with The Multi-Agent Nexus (Phase 8)') .argument('', 'The natural language instruction for the swarm') .option('--dry-run', 'Enable Dry-Run mode (Kill-Switch Active)', true) .option('--force', 'Disable Dry-Run mode (DANGEROUS)', false) .action(async (intent: string, options) => { console.log(chalk.bold.magenta('\n🦁 Welcome to The Nexus (Phase 8)\n')); const dryRun = !options.force; if (!dryRun) { console.log(chalk.black.bgYellow(' WARNING ') + chalk.yellow(' Dry-Run disabled! Eitri is authorized to write code.')); const { confirm } = await inquirer.prompt([{ type: 'confirm', name: 'confirm', message: 'Are you absolutely sure you want to bypass the Kill-Switch?', default: false }]); if (!confirm) { console.log('Aborting.'); process.exit(0); } } // Context setup const context: NexusContext = { projectId: process.env.RIGSTATE_PROJECT_ID || 'local', rootPath: process.cwd(), sessionUser: 'cli-user', // Should strictly be pulled from auth dryRun }; const dispatcher = new NexusDispatcher(context); // Setup Listeners for Visualization dispatcher.on('order:created', (o) => { console.log(chalk.blue(`šŸ†• [${o.id.slice(0, 6)}] Order Created: `) + o.intent); }); dispatcher.on('order:started', (o) => { console.log(chalk.yellow(`ā³ [${o.id.slice(0, 6)}] Processing...`)); }); dispatcher.on('order:blocked', (o) => { console.log(chalk.red(`šŸ›‘ [${o.id.slice(0, 6)}] BLOCKED by Kill-Switch`)); console.log(chalk.dim(` Target: ${o.targetAgent} | Action: ${o.action}`)); console.log(chalk.dim(' Run with --force to execute automatically (NOT RECOMMENDED).')); }); dispatcher.on('agent:SINDRE', (o) => console.log(chalk.cyan(`šŸ¤– Sindre (Vault): I'm on it! (${o.action})`))); dispatcher.on('agent:EITRI', (o) => console.log(chalk.green(`šŸ‘· Eitri (Smith): Ready to build! (${o.action})`))); // Simulation: Frank Analysis Logic // In a real scenario, this would call LLM/MCP to get the decomposition. // Here we hardcode a mocked response to demonstrate the CLI flow. console.log(chalk.dim('🧠 Frank is analyzing your intent...')); await new Promise(r => setTimeout(r, 800)); // Simulate thinking // MOCK: Dispatch logic if (intent.toLowerCase().includes('db') || intent.toLowerCase().includes('database')) { await dispatcher.dispatch('FRANK', 'SINDRE', intent, 'db.analyze', { raw: intent }); } else if (intent.toLowerCase().includes('create') || intent.toLowerCase().includes('code')) { await dispatcher.dispatch('FRANK', 'EITRI', intent, 'fs.write', { path: 'src/demo.ts', content: '// demo' }); } else { console.log(chalk.gray("Frank didn't understand. Try 'create file' or 'check database'.")); } }); return command; }