Docs/Product Specs/CLI

CLI

Maturity: DECIDED | ID Prefix: CLI | Dependencies: architecture/ipc-api.md

Purpose

The pu command-line tool. A thin client that sends requests to the daemon and formats responses for terminal output. Zero domain logic — all state and operations live in the daemon.

Conceptual Model

User types: pu {command} [args] [--flags]
  CLI parses args (clap)
  CLI ensures daemon is running (auto-start if needed)
  CLI connects to Unix socket (~/.pu/daemon.sock)
  CLI sends JSON request, reads JSON response
  CLI formats response for terminal (or raw JSON with --json)
  CLI exits with appropriate code

Key behaviors:

  • Auto-starts daemon if not running
  • Machine-readable output mode for conductor agents
  • Ability to attach directly to an agent's terminal session

Decisions

! [CLI-001] Auto-start polls 30x100ms (3s timeout), exits with error pointing to ~/.pu/daemon.log — CLI calls ensure_daemon() which first checks health, then spawns pu-engine (found via which) as a detached process with stderr redirected to ~/.pu/daemon.log. Polls Request::Health every 100ms up to 30 attempts. On timeout: CliError::Other("daemon did not start within 3 seconds"). Implemented in pu-cli/src/daemon_ctrl.rs.

! [CLI-002] --json flag for machine-readable output — provides raw JSON responses for conductor agents and scripts. Available on nearly every command: init, spawn, status, bench, play, kill, logs, health, pulse, diff, clean, and all CRUD subcommands (prompt, agent, swarm, schedule, trigger). Per-command flag (not global). Implemented across command handlers in pu-cli/src/commands/.

Implemented Commands

CommandArgs/FlagsDescription
pu init--jsonRegister current project with daemon
pu spawn [prompt]--agent, --name, --base, --root, --worktree, --template, --file, --command, --var KEY=VALUE, --no-auto, --agent-args, --plan, --no-trigger, --jsonSpawn an agent (in worktree or root)
pu status--agent <id>, --jsonShow project/agent status
pu bench [agent_id]--all, --jsonSuspend (bench) agents
pu play <agent_id>--jsonResume a benched agent
pu kill--agent, --worktree, --all (mutually exclusive), --include-root (requires --all), --jsonKill agent(s)
pu attach <agent_id>Interactive PTY attach to agent
pu logs <agent_id>--tail <n> (default 500), --jsonTail agent output buffer
pu send <agent_id> [text]--no-enter, --keys <key>, --jsonSend text or control keys to agent terminal
pu health--jsonCheck daemon health
pu pulse--jsonWorkspace overview (agents, runtimes, git stats)
pu diff--worktree <id>, --stat, --jsonShow git diffs across worktrees
pu watch--interval <ms> (default 800)Live TUI dashboard
pu clean--worktree <id>, --all, --jsonRemove worktrees, agents, and branches
pu prompt list--jsonList saved prompt templates
pu prompt show <name>--jsonShow prompt template details
pu prompt create <name>--body, --description, --agent, --scope, --jsonCreate prompt template
pu prompt delete <name>--scope, --jsonDelete prompt template
pu agent list--jsonList agent definitions
pu agent show <name>--jsonShow agent definition details
pu agent create <name>--agent-type, --template, --inline-prompt, --command, --tags, --scope, --jsonCreate agent definition
pu agent delete <name>--scope, --jsonDelete agent definition
pu swarm list--jsonList swarm definitions
pu swarm show <name>--jsonShow swarm definition details
pu swarm create <name>--worktrees, --worktree-template, --roster AGENT:ROLE:QTY, --include-terminal, --scope, --jsonCreate swarm definition
pu swarm delete <name>--scope, --jsonDelete swarm definition
pu swarm run <name>--var KEY=VALUE, --jsonExecute a swarm
pu schedule list--jsonList schedules
pu schedule show <name>--jsonShow schedule details
pu schedule create <name>--recurrence, --start-at, --trigger, --trigger-name, --trigger-prompt, --agent, --var KEY=VALUE, --scope, --jsonCreate schedule
pu schedule delete <name>--scope, --jsonDelete schedule
pu schedule enable <name>--jsonEnable schedule
pu schedule disable <name>--jsonDisable schedule
pu grid show--jsonShow current pane grid layout
pu grid split--axis <v|h>, --leaf <id>Split a pane
pu grid close--leaf <id>Close a pane
pu grid focus--direction <up|down|left|right>, --leaf <id>Move focus to another pane
pu grid assign <agent_id>--leaf <id>Assign an agent to a pane
pu trigger list--jsonList trigger definitions
pu trigger show <name>--jsonShow trigger details
pu trigger create <name>--on <event>, --inject, --gate, --description, --scope, --jsonCreate trigger definition
pu trigger delete <name>--scope, --jsonDelete trigger definition
pu gate <event>--project-rootEvaluate git hook gates (pre-commit, pre-push)

Research Notes

Client implementation (pu-cli/src/client.rs): Connects to Unix socket, writes {json}\n, reads one newline-terminated response. 30-second request timeout. ConnectionRefused/NotFound errors converted to DaemonNotRunning error type.

Daemon discovery: Socket path resolved from pu_core::paths::daemon_socket_path()~/.pu/daemon.sock. No environment variable override currently.