import type { Command } from 'commander'; import { loadConfigSafe, getConfigPath } from './shared.js'; import { existsSync } from 'fs'; export function registerStartCommand(program: Command): void { program .command('start') .description('Start the Flynn daemon') .option('-c, --config ', 'Config file path') .action(async (opts: { config?: string }) => { const configPath = opts.config ?? getConfigPath(); if (!existsSync(configPath)) { // Offer setup wizard const { createInterface } = await import('readline/promises'); const { createPrompter } = await import('./setup/prompts.js'); const rl = createInterface({ input: process.stdin, output: process.stdout }); const p = createPrompter(rl); const runWizard = await p.confirm( 'No configuration found. Would you like to run the setup wizard?', true, ); rl.close(); if (runWizard) { const { runSetup } = await import('./setup.js'); await runSetup(configPath); return; } console.error(`Config file not found: ${configPath}`); console.error('Run "flynn setup" to create one, or "flynn doctor" to diagnose.'); process.exit(1); } console.log('Flynn starting...'); console.log(`Loading config from: ${configPath}`); const { config, error } = loadConfigSafe(configPath); if (!config) { console.error(error); process.exit(1); } // Dynamic import to avoid loading daemon code for other commands const { startDaemon } = await import('../daemon/index.js'); const daemon = await startDaemon(config); if (config.telegram) { console.log(`Allowed Telegram chat IDs: ${config.telegram.allowed_chat_ids.join(', ')}`); } // Keep process alive await new Promise((resolve) => { daemon.lifecycle.onShutdown(async () => resolve()); }); }); }