Files
flynn/src/cli/start.ts
T
2026-02-17 15:38:13 -08:00

59 lines
2.0 KiB
TypeScript

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 <path>', '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 onboard" (or "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, { configPath });
if (config.telegram) {
console.log(`Allowed Telegram chat IDs: ${config.telegram.allowed_chat_ids.join(', ')}`);
}
// Keep process alive
await new Promise<void>((resolve) => {
daemon.lifecycle.onShutdown(async () => resolve());
});
});
}