import { Command } from "commander"; import { VMInstance } from "./vm.js"; import { installSignalHandlers } from "./cleanup.js"; import { runSetup } from "./setup.js"; import { createSnapshot } from "./snapshot.js"; import { runOverseer } from "./overseer.js"; import { startAgent, stopAgent, listAgents, } from "./agent-manager.js"; export function createCli() { const program = new Command(); program .name("fireclaw") .description("Run commands in ephemeral Firecracker microVMs") .version("0.1.3"); program .command("run") .description("Run a command inside a fresh microVM") .argument("", "Command to execute inside the microVM") .option("-t, --timeout ", "Timeout in seconds", "60") .option("-v, --verbose", "Show detailed progress", false) .option("--mem ", "Memory in MiB", "256") .option("--vcpu ", "Number of vCPUs", "1") .option("--no-snapshot", "Force cold boot, skip snapshot restore") .action(async (command: string, opts) => { installSignalHandlers(); const result = await VMInstance.run(command, { timeout: parseInt(opts.timeout) * 1000, verbose: opts.verbose, mem: parseInt(opts.mem), vcpu: parseInt(opts.vcpu), noSnapshot: opts.snapshot === false, }); if (!opts.verbose) { if (result.stdout) process.stdout.write(result.stdout); if (result.stderr) process.stderr.write(result.stderr); } process.exit(result.exitCode); }); program .command("setup") .description("Download kernel, rootfs, and configure networking") .action(async () => { await runSetup(); }); const snapshot = program .command("snapshot") .description("Manage VM snapshots"); snapshot .command("create") .description("Boot a VM and create a snapshot for fast restores") .action(async () => { installSignalHandlers(); await createSnapshot(); }); // Overseer program .command("overseer") .description("Start the overseer daemon (IRC bot for agent management)") .option("--server ", "IRC server", "localhost") .option("--port ", "IRC port", "6667") .option("--nick ", "Bot nickname", "overseer") .option("--channel ", "Control channel", "#control") .action(async (opts) => { await runOverseer({ server: opts.server, port: parseInt(opts.port), nick: opts.nick, channel: opts.channel, }); }); // Agent management const agent = program .command("agent") .description("Manage long-running agent VMs"); agent .command("start") .description("Start an agent VM from a template") .argument("