import { Command, Option } from "commander"; import chalk from "chalk"; import { startLocalDaemonForeground, startLocalDaemonDetached, type DaemonStartOptions as StartOptions, } from "./local-daemon.js"; import { getErrorMessage } from "../../utils/errors.js"; export type { DaemonStartOptions as StartOptions } from "./local-daemon.js"; type RawStartCommandOptions = StartOptions & { allowedHosts?: string; }; export function startCommand(): Command { return new Command("start") .description("Start the local Paseo daemon") .option("--listen ", "Listen target (host:port, port, or unix socket path)") .option("--port ", "Port to listen on (default: 6767)") .option("--home ", "Paseo home directory (default: ~/.paseo)") .option("--foreground", "Run in foreground (don't daemonize)") .option("--relay", "Enable relay connection") .option("--no-relay", "Disable relay connection") .option("--relay-use-tls", "Use wss:// for the relay connection and pairing offers") .option("--no-mcp", "Disable the Agent MCP HTTP endpoint") .option("--no-inject-mcp", "Disable auto-injecting the Paseo MCP into created agents") .option("--web-ui", "Enable the bundled daemon web UI") .option("--no-web-ui", "Disable the bundled daemon web UI") .option( "--hostnames ", 'Daemon hostnames (comma-separated, e.g. "myhost,.example.com" or "true" for any)', ) .addOption(new Option("--allowed-hosts ").hideHelp()) .action(async (options: RawStartCommandOptions) => { await runStart({ ...options, hostnames: options.hostnames ?? options.allowedHosts, }); }); } export async function runStart(options: StartOptions): Promise { if (options.listen && options.port) { console.error(chalk.red("Cannot use --listen and --port together")); process.exit(1); } if (!options.foreground) { try { const startup = await startLocalDaemonDetached(options); console.log(chalk.green(`Daemon starting in background (PID ${startup.pid ?? "unknown"}).`)); console.log(chalk.dim(`Logs: ${startup.logPath}`)); } catch (err) { exitWithError(getErrorMessage(err)); } return; } try { const status = startLocalDaemonForeground(options); process.exit(status); } catch (err) { const message = getErrorMessage(err); exitWithError(`Failed to start daemon: ${message}`); } } function exitWithError(message: string): never { console.error(chalk.red(message)); process.exit(1); }