import { Command } from "commander"; import { createRequire } from "node:module"; import { createAgentCommand } from "./commands/agent/index.js"; import { createDaemonCommand } from "./commands/daemon/index.js"; import { createPermitCommand } from "./commands/permit/index.js"; import { createProviderCommand } from "./commands/provider/index.js"; import { createSpeechCommand } from "./commands/speech/index.js"; import { createWorktreeCommand } from "./commands/worktree/index.js"; import { startCommand as daemonStartCommand } from "./commands/daemon/start.js"; import { runStatusCommand as runDaemonStatusCommand } from "./commands/daemon/status.js"; import { runRestartCommand as runDaemonRestartCommand } from "./commands/daemon/restart.js"; import { runLsCommand } from "./commands/agent/ls.js"; import { runRunCommand } from "./commands/agent/run.js"; import { runLogsCommand } from "./commands/agent/logs.js"; import { runDeleteCommand } from "./commands/agent/delete.js"; import { runStopCommand } from "./commands/agent/stop.js"; import { runSendCommand } from "./commands/agent/send.js"; import { runInspectCommand } from "./commands/agent/inspect.js"; import { runWaitCommand } from "./commands/agent/wait.js"; import { runAttachCommand } from "./commands/agent/attach.js"; import { withOutput } from "./output/index.js"; import { onboardCommand } from "./commands/onboard.js"; import { addDaemonHostOption, addJsonAndDaemonHostOptions, addJsonOption, collectMultiple, } from "./utils/command-options.js"; const require = createRequire(import.meta.url); type CliPackageJson = { version?: unknown; }; function resolveCliVersion(): string { const packageJson = require("../package.json") as CliPackageJson; if (typeof packageJson.version === "string" && packageJson.version.trim().length > 0) { return packageJson.version.trim(); } throw new Error("Unable to resolve @getpaseo/cli version from package.json."); } const VERSION = resolveCliVersion(); export function createCli(): Command { const program = new Command(); program .name("paseo") .description("Paseo CLI - control your AI coding agents from the command line") .version(VERSION, "-v, --version", "output the version number") // Global output options .option("-o, --format ", "output format: table, json, yaml", "table") .option("--json", "output in JSON format (alias for --format json)") .option("-q, --quiet", "minimal output (IDs only)") .option("--no-headers", "omit table headers") .option("--no-color", "disable colored output"); // Primary agent commands (top-level) addJsonAndDaemonHostOptions( program .command("ls") .description("List agents. By default excludes archived agents.") .option("-a, --all", "Include archived agents") .option("-g, --global", "Legacy no-op (kept for compatibility)") .option( "--label ", "Filter by label (can be used multiple times)", collectMultiple, [], ) .option("--thinking ", "Filter by thinking option ID"), ).action(withOutput(runLsCommand)); addJsonAndDaemonHostOptions( program .command("run") .description("Create and start an agent with a task") .argument("", "The task/prompt for the agent") .option("-d, --detach", "Run in background (detached)") .option("--name ", "Assign a name/title to the agent") .option( "--provider ", "Agent provider, or provider/model (e.g. codex or codex/gpt-5.4)", "claude", ) .option( "--model ", "Model to use (e.g., claude-sonnet-4-20250514, claude-3-5-haiku-20241022)", ) .option("--thinking ", "Thinking option ID to use for this run") .option("--mode ", "Provider-specific mode (e.g., plan, default, bypass)") .option("--worktree ", "Create agent in a new git worktree") .option("--base ", "Base branch for worktree (default: current branch)") .option( "--image ", "Attach image(s) to the initial prompt (can be used multiple times)", collectMultiple, [], ) .option("--cwd ", "Working directory (default: current)") .option( "--label ", "Add label(s) to the agent (can be used multiple times)", collectMultiple, [], ) .option( "--output-schema ", "Output JSON matching the provided schema file path or inline JSON schema", ), ).action(withOutput(runRunCommand)); addDaemonHostOption( program .command("attach") .description("Attach to a running agent's output stream") .argument("", "Agent ID (or prefix)"), ).action(runAttachCommand); addDaemonHostOption( program .command("logs") .description("View agent activity/timeline") .argument("", "Agent ID (or prefix)") .option("-f, --follow", "Follow log output (streaming)") .option("--tail ", "Show last n entries") .option("--filter ", "Filter by event type (tools, text, errors, permissions)") .option("--since