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
| Command | Args/Flags | Description |
|---|---|---|
pu init | --json | Register 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, --json | Spawn an agent (in worktree or root) |
pu status | --agent <id>, --json | Show project/agent status |
pu bench [agent_id] | --all, --json | Suspend (bench) agents |
pu play <agent_id> | --json | Resume a benched agent |
pu kill | --agent, --worktree, --all (mutually exclusive), --include-root (requires --all), --json | Kill agent(s) |
pu attach <agent_id> | — | Interactive PTY attach to agent |
pu logs <agent_id> | --tail <n> (default 500), --json | Tail agent output buffer |
pu send <agent_id> [text] | --no-enter, --keys <key>, --json | Send text or control keys to agent terminal |
pu health | --json | Check daemon health |
pu pulse | --json | Workspace overview (agents, runtimes, git stats) |
pu diff | --worktree <id>, --stat, --json | Show git diffs across worktrees |
pu watch | --interval <ms> (default 800) | Live TUI dashboard |
pu clean | --worktree <id>, --all, --json | Remove worktrees, agents, and branches |
pu prompt list | --json | List saved prompt templates |
pu prompt show <name> | --json | Show prompt template details |
pu prompt create <name> | --body, --description, --agent, --scope, --json | Create prompt template |
pu prompt delete <name> | --scope, --json | Delete prompt template |
pu agent list | --json | List agent definitions |
pu agent show <name> | --json | Show agent definition details |
pu agent create <name> | --agent-type, --template, --inline-prompt, --command, --tags, --scope, --json | Create agent definition |
pu agent delete <name> | --scope, --json | Delete agent definition |
pu swarm list | --json | List swarm definitions |
pu swarm show <name> | --json | Show swarm definition details |
pu swarm create <name> | --worktrees, --worktree-template, --roster AGENT:ROLE:QTY, --include-terminal, --scope, --json | Create swarm definition |
pu swarm delete <name> | --scope, --json | Delete swarm definition |
pu swarm run <name> | --var KEY=VALUE, --json | Execute a swarm |
pu schedule list | --json | List schedules |
pu schedule show <name> | --json | Show schedule details |
pu schedule create <name> | --recurrence, --start-at, --trigger, --trigger-name, --trigger-prompt, --agent, --var KEY=VALUE, --scope, --json | Create schedule |
pu schedule delete <name> | --scope, --json | Delete schedule |
pu schedule enable <name> | --json | Enable schedule |
pu schedule disable <name> | --json | Disable schedule |
pu grid show | --json | Show 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 | --json | List trigger definitions |
pu trigger show <name> | --json | Show trigger details |
pu trigger create <name> | --on <event>, --inject, --gate, --description, --scope, --json | Create trigger definition |
pu trigger delete <name> | --scope, --json | Delete trigger definition |
pu gate <event> | --project-root | Evaluate 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.