Keyboard shortcuts

Press ← or → to navigate between chapters

Press S or / to search in the book

Press ? to show this help

Press Esc to hide this help

CLI Reference

git-paw is invoked as git paw (or git-paw). Below is the reference for all subcommands and flags.

git paw

Running with no subcommand is equivalent to git paw start.

Parallel AI Worktrees — orchestrate multiple AI coding CLI sessions across git worktrees

Usage: git-paw [COMMAND]

Commands:
  start        Launch a new session or reattach to an existing one
  add          Attach a new worktree + agent pane to a running session
  remove       Detach a single agent from a running session
  pause        Pause the session (detaches client, stops broker, leaves CLIs running)
  stop         Stop the session (kills tmux, keeps worktrees and state)
  purge        Remove all worktrees and session state; keeps branches with unmerged commits
  status       Show session state for the current repo
  attach       Reattach the current terminal to the running session for this repo
  list-clis    List detected and custom AI CLIs
  add-cli      Register a custom AI CLI
  remove-cli   Unregister a custom AI CLI
  setup-cli    Apply git-paw's setup items to one AI CLI's own settings
  init         Initialize .git-paw/ directory and configuration
  replay       View captured session logs
  approvals    Report manually-approved command patterns for a session
  mcp          Run a Model Context Protocol (MCP) server over stdio
  doctor       Diagnose the environment, configuration, and repository state
  completions  Print a shell completion script to stdout
  help         Print this message or the help of the given subcommand(s)

Options:
  -h, --help     Print help
  -V, --version  Print version

git paw init

Initializes a repository for git-paw. Creates the .git-paw/ directory, a default config.toml, the logs directory, the bundled helpers and the exported orchestrator skills, adds the orchestrator pointer to AGENTS.md, and sets up .gitignore.

Usage: git-paw init

Options:
  -h, --help  Print help

Running init is idempotent — it’s safe to run multiple times.

When it writes a fresh config.toml, init asks which spec system the project uses (recorded in [specs]; git-paw never auto-detects it) and whether to enable supervisor mode by default. A non-interactive run writes a commented [specs] template and [supervisor] enabled = false instead. Re-running init on an existing config is the upgrade path after a version bump — see Upgrading an Existing Config.

What it creates:

  • .git-paw/config.toml — default configuration
  • .git-paw/logs/ — log directory (added to .gitignore)
  • .git-paw/tmp/ — repo-local scratch for isolated verify worktrees and self-test sessions (added to .gitignore; preferred over OS temp because it is OS-independent)
  • .git-paw/scripts/sweep.sh — bundled supervisor helper
  • .git-paw/scripts/broker.sh — bundled agent-broker helper (the agent side of sweep.sh); the agent boot block calls it to self-report to the broker. See Coordination → Broker helper
  • .git-paw/scripts/docs-fetch.sh — bundled agent helper that fetches documentation on demand (see Docs Fetch Skill)
  • .git-paw/scripts/_paw_common.sh — shared preamble the bundled helpers source for repository-root resolution, Python 3 detection, and broker / docs URL discovery. Binary-managed like the helpers themselves: it is overwritten on every git paw init, and a helper cannot run without it
  • .git-paw/skills/orchestrator/SKILL.md — the orchestrator skill, rendered with your [supervisor] gate commands and configured spec format, for the agent you drive the session with; .git-paw/skills/cli-setup/SKILL.md beside it. git paw start re-renders both. See Quick Start: Orchestrator Mode
  • an orchestrator pointer section in the root AGENTS.md, between <!-- git-paw-orchestrator:start --> and <!-- git-paw-orchestrator:end --> (the file is created when absent; see AGENTS.md)
  • .gitignore entries for .git-paw/logs/, .git-paw/tmp/, .git-paw/worktrees/ (where agent worktrees live under the default child placement), .git-paw/skills/, .git-paw/session-summary.md, and .git-paw/session-learnings.md

A re-run reports a binary-managed file (a helper, an exported skill, the pointer section) as Updated only when its content changed, and closes with Already initialized. Nothing to do. only when nothing was created or changed.

Example:

git paw init

git paw start

Smart start: reattaches if a session is active, recovers if stopped/crashed, or launches a new interactive session. Reattach is checked before anything else — including entering supervisor mode — so re-running start against a repository that already has a live session never forks a second, parallel one; see Reattaching instead of forking.

Usage: git-paw start [OPTIONS]

Options:
      --cli <CLI>                    AI CLI to use (skips CLI picker)
      --branches <BRANCHES>          Comma-separated branches (skips branch picker)
      --from-all-specs               Launch from every discovered spec across all configured formats
      --specs [<SPECS>...]           Comma-separated spec names; bare flag opens picker (TTY required)
      --specs-format <SPECS_FORMAT>  Override spec format (openspec, markdown, speckit, superpowers) [possible values: openspec, markdown, speckit, superpowers]
      --dry-run                      Preview the session plan without executing
      --preset <PRESET>              Use a named preset from config
      --supervisor                   Enable supervisor mode for this session
      --no-supervisor                Disable supervisor for this session, overriding any [supervisor] enabled = true in config
      --force                        Bypass uncommitted-spec validation warning
      --no-rebase                    Skip rebasing existing agent branches onto the default branch before opening worktrees
      --unattended                   Drive the supervisor wave to completion unattended: escalate every permission prompt for a human decision without blocking the wave, detect completion, exit with a summary (approves nothing). On a repo with a live supervised session, binds a new drive loop to it instead of launching
  -h, --help                         Print help
FlagAccepted valuesPurpose
--cliname of a detected or custom CLISkip the interactive CLI picker; assign this CLI to every agent that doesn’t otherwise pin one.
--branchescomma-separated branchesSkip the interactive branch picker; launch one worktree per branch.
--from-all-specs(flag)Launch every discovered spec across the configured backend. Mutually exclusive with --specs.
--specscomma-separated spec names; bare flag opens a multi-select picker (TTY required)Narrow the session to named specs or open the picker. Mutually exclusive with --from-all-specs.
--specs-formatopenspec, markdown, speckit, superpowersSelect the spec system for this launch (overrides [specs] type in config). git-paw does not auto-detect the spec system from the filesystem.
--dry-run(flag)Print the session plan; create no worktrees and run no tmux commands.
--presetpreset name from configUse a named [presets.<name>] entry.
--supervisor(flag)Force supervisor mode on. Mutually exclusive with --no-supervisor.
--no-supervisor(flag)Force supervisor mode off (highest precedence in the resolution chain). Mutually exclusive with --supervisor.
--force(flag)Bypass the uncommitted-spec validation warning when launching from specs.
--no-rebase(flag)Skip the default-on rebase of existing agent branches onto the repository’s default branch.
--unattended(flag)Run the supervisor wave to completion with no human in the seat: engages supervisor mode and drives an in-process loop that escalates every live permission prompt for a human decision without blocking the wave, detects completion, and exits with a summary. It approves nothing. On a repository that already has a live supervised session, binds a new drive loop to it instead of launching. Mutually exclusive with --no-supervisor.

--from-all-specs and --specs are mutually exclusive — one launches every discovered spec, the other narrows to a subset or opens the picker.

--unattended engages supervisor mode (equivalent to also passing --supervisor) and then drives the wave to completion in-process instead of returning with an attach hint: it polls the panes on a ~15-second cadence, escalates every live permission prompt it finds — on a coding pane or the supervisor’s own — for a human decision WITHOUT blocking the rest of the wave, and exits with a summary on completion, a stuck signal, or a heartbeat after ~25 minutes without progress (no new commit on a coding branch and no agent phase advance). It is designed for detached operation and needs no attached terminal. It is mutually exclusive with --no-supervisor.

It approves nothing. git-paw sends no approval keystroke on its own initiative; whether a command runs without a prompt is decided by the agent CLI’s own permission system. For a run that truly does not stop, pre-approve the commands in that CLI’s own allow rules, or use [supervisor] agent_approval = "full-auto" inside the documented sandbox. See Supervisor → Unattended mode.

On a repository that already has a live supervised session, --unattended binds a new drive loop to that session instead of launching or refusing: an active session is driven as it stands (no pane rebuilt, no worktree touched, nothing injected), a paused one is revived first, a stopped one recovered first. The terminal is never attached. Launch-selection flags are not applied to a live session, so re-running the command that launched a wave is what drives it again after its loop exits. The loop drives the session’s own roster and reaches the broker at the endpoint recorded for that session, not the configured one. A session launched without supervisor mode is refused — it leaves its prompts for a human to submit. At most one drive loop may drive a session at a time; a second --unattended refuses, naming the holding process, before changing anything. See Re-attaching a drive loop to a live session.

No orchestrator runs inside the session — it drives from your own agent session, pointed at .git-paw/AGENTS.local.md — so the loop sweeps and types into coding-agent panes only and records every judgment call (a live prompt, a worker’s question, a merge decision, a non-converging branch) as a broker review item, injecting nothing into any pane. The loop never waits on a reply. Nudges aimed at a worker pane stop once that worker has finished (done/verified) — but not while it is merely quiet at blocked/committed, where the correction loop must still reach it. See the loop is a pump, the supervisor is the brain.

The selection flags compose with --supervisor: git paw start --supervisor --specs a,b launches a supervisor session for only the named subset (a and b), exactly matching the non-supervisor --specs behaviour. --supervisor --from-all-specs launches every discovered spec, and --supervisor --specs (bare) opens the multi-select picker.

Examples:

git paw start
git paw start --cli claude
git paw start --cli claude --branches feat/auth,feat/api
git paw start --dry-run
git paw start --preset backend

# Launch every discovered spec
git paw start --from-all-specs
git paw start --from-all-specs --cli claude
git paw start --from-all-specs --dry-run

# Narrow to specific specs or open the multi-select picker
git paw start --specs add-auth,fix-session
git paw start --specs   # interactive picker (requires a TTY)

# Supervisor mode honours the same selection flags
git paw start --supervisor --specs add-auth        # one agent, for add-auth only
git paw start --supervisor --from-all-specs        # one agent per discovered spec

# Skip supervisor for this session even when `[supervisor] enabled = true` is set
git paw start --no-supervisor
git paw start --from-all-specs --no-supervisor

# Run the whole wave to completion with no human in the seat (detached)
git paw start --unattended --from-all-specs
git paw start --unattended --branches feat/auth,feat/api

# After the loop exits (heartbeat, stuck, interrupted): the same command again
# binds a new loop to the still-live session
git paw start --unattended --from-all-specs

Every launch path refuses, before creating any worktree or pane, a session whose branches do not all derive distinct broker agent_ids. The id is the slugified branch name, so two different branches can map to one: git paw start --branches feat/x,feat-x fails naming both branches and the shared id feat-x, because the two agents would otherwise share an inbox and receive each other’s feedback and verdicts. Rename one branch so the ids differ. (Only when the broker is enabled; with it off, nothing addresses agents by id and the launch proceeds as before.)

Supervisor mode resolution chain

git-paw decides whether to enter supervisor mode using this order (first match wins):

  1. --no-supervisor flag present → supervisor disabled (no prompt, regardless of config).
  2. --supervisor flag present → supervisor enabled (no prompt).
  3. [supervisor] enabled = true in config → supervisor enabled (no prompt).
  4. [supervisor] enabled = false in config → supervisor disabled (no prompt).
  5. No [supervisor] section + --dry-run → supervisor disabled (skip prompt).
  6. No [supervisor] section + interactive TTY → prompt “Start in supervisor mode?”.
  7. No [supervisor] section + non-TTY → supervisor disabled (fallback).

--supervisor and --no-supervisor are mutually exclusive at parse time; passing both is rejected by clap before any command runs.

See Spec-Driven Launch for details on spec formats and configuration.

git paw add

Hot-attaches a worktree and agent pane to a running session — bare, spec-driven or supervisor-mode — without a stop/purge/restart. The agent grid re-tiles to the layout a start of that many agents would produce, the new branch is registered in the session, and the agent boots with the same broker boot block + initial prompt a start-time agent receives. The orchestrator discovers it passively on its next broker poll, and an in-process drive loop picks it up on its next sweep — no restart.

Provide a branch name, or use --from-spec to derive the branch (and CLI) from a spec discovered in the configured spec system — OpenSpec, Markdown, Spec Kit, or Superpowers (same resolution as start --specs NAME). Adding past the 25-agent cap is rejected with the same “split into multiple sessions” message start uses. Adding to a paused session leaves the new pane paused until git paw start.

Usage: git-paw add [OPTIONS] [BRANCH]

Arguments:
  [BRANCH]  Branch to attach (omit when using --from-spec)

Options:
      --cli <CLI>              AI CLI for the new pane (defaults to the session's default CLI)
      --from-spec <FROM_SPEC>  Derive branch + CLI from a spec (OpenSpec change, Markdown spec, Spec Kit feature, or Superpowers plan)
  -h, --help                   Print help

Examples:

git paw add feat/new-thing
git paw add feat/api --cli codex
git paw add --from-spec add-export

Validation happens before any side effect: an unknown --cli errors with the detected CLI ids, and an unknown --from-spec errors with the discovered spec candidates — no worktree or pane is created in either case.

A branch whose broker agent_id is already taken by an agent in the session is refused the same way: the id is the slugified branch name, so git paw add feat-x against a session already running feat/x fails naming both branches and the shared id feat-x rather than attaching a second agent to one inbox. (Only when the broker is enabled; with it off nothing addresses agents by id.)

git paw remove

Detaches a single agent from any active session: closes its tmux pane, re-tiles the grid for the smaller agent count, removes its worktree (reusing git paw purge’s per-worktree teardown), and drops it from the session. The other agents are untouched; the orchestrator notices the departure on its next poll (the agent stops heartbeating) and a running drive loop stops driving it on its next sweep.

Safe by default: remove refuses to delete a worktree with uncommitted changes — listing the changed files — unless --force is passed. --keep-worktree detaches the pane and session entry but leaves the worktree and branch on disk (and skips the uncommitted-work check, since nothing is deleted). git paw remove supervisor is refused — use git paw stop to end the whole session.

Usage: git-paw remove [OPTIONS] <BRANCH>

Arguments:
  <BRANCH>  Branch of the agent to remove

Options:
      --keep-worktree  Leave the worktree + branch on disk; only detach the pane and session entry
      --force          Remove even with uncommitted changes (bypass the safety check)
  -h, --help           Print help

Examples:

git paw remove feat/done-thing
git paw remove feat/wip --force
git paw remove feat/keep --keep-worktree

Both add and remove operate on every session git-paw builds — every one uses the agent grid, which is the layout that can be re-tiled incrementally. One branch per invocation.

A live session started by an earlier git-paw with the whole-window tiled layout is the one exception: it is refused before any worktree, pane or session entry is touched, with an error naming the tiled layout. Stop the session and run git paw start to relaunch it in the grid layout, after which add and remove work normally.

git paw pause

Soft-stops the session: detaches the tmux client, stops the broker, and leaves every CLI pane running in the background. Preserves agent conversation state for instant resume via git paw start. RAM stays allocated (~300 MB per Claude pane).

Use pause for short breaks (lunch, meetings, end-of-day). For longer breaks, use git paw stop to kill the CLIs and release RAM. See Pause and Resume for the full trade-off discussion.

Usage: git-paw pause

Options:
  -h, --help  Print help

Example:

git paw pause

Idempotent: pausing an already-paused or already-stopped session is a friendly no-op.

git paw stop

Kills the tmux session and every CLI pane process, but preserves worktrees and session state on disk. CLI conversation context is lost. Run git paw start later to recover the session with fresh CLI processes.

stop never prompts for confirmation. Stopping is recoverable: worktrees and session state survive, and git paw start recovers the session with fresh processes. Therefore, a confirmation prompt would protect nothing and is not rendered.

Usage: git-paw stop

Options:
  -h, --help  Print help

Example:

git paw stop

git paw purge

Nuclear option: kills the tmux session, removes all worktrees (including any uncommitted changes in them), and deletes session state. When the broker was enabled, also removes that session’s <session_name>.broker.log. Requires confirmation unless --force is used.

Remove all worktrees and session state; keeps branches with unmerged commits

Usage: git-paw purge [OPTIONS]

Options:
      --force      Skip the confirmation prompt; never deletes a branch with unmerged commits
      --stale      Purge only stale sessions (receipt claims active but tmux is gone); live sessions untouched
      --all-repos  With --stale, sweep every repository's stale receipts instead of just the current one
  -h, --help       Print help (see more with '--help')

Which branches purge deletes

Purge deletes a branch only when git-paw created it (so a branch that existed before the session is never touched) and its tip is an ancestor of the default branch — or of the branch it was created from, see below. Each deletion prints the SHA the branch was at:

Deleted branch feat/done-thing (was 1a2b3c4)

A branch carrying commits that are in neither — or one whose merge state cannot be determined, for instance because the default branch cannot be resolved — is kept, with or without --force. Only its worktree (including any uncommitted changes) and the session state go away. Each retained branch is reported with its tip and the two ways to finish the job by hand:

Kept branch feat/wip at 9f8e7d6 (3 commit(s) not in main)
  resume it with: git worktree add '/path/to/worktree' feat/wip
  discard it with: git branch -D feat/wip

The discard command is git branch -d when git would accept the safe delete (the branch is already contained in whatever you have checked out) and git branch -D otherwise, so the suggestion always runs.

Every comparison names refs explicitly (refs/heads/<branch>). A tag that happens to share a branch’s name therefore cannot answer the merge question on the tag’s history, which would otherwise let a merged tag clear the way for deleting an unmerged branch.

Branches created from an integration branch

git worktree add -b takes no start point, so a branch git-paw creates starts at whatever the main checkout has checked out. Launch a wave from an integration branch and every agent branch inherits that branch’s commits. git-paw records the start point on the session entry, and teardown asks whether the branch is contained in the default branch or in that recorded base — so work merged into the integration branch is recognised as finished, and a branch that really is unmerged is counted against the base rather than being reported with the whole integration backlog folded into its number.

Sessions written before this was recorded carry no base and are compared against the default branch alone, exactly as they were before.

Before the confirmation prompt, purge lists every branch it is going to keep, so you see the outcome before agreeing to it. --force skips the prompt, not the retention rule.

--stale purges only sessions whose tmux session no longer exists (a stale receipt). By default the sweep is scoped to the current repository — it never touches a stale receipt belonging to a different repository. Pass --all-repos to broaden the sweep to every repository’s stale receipts on the machine (meaningful only together with --stale; used alone it is rejected with an error). When nothing is stale in scope it exits 0 with a “No stale sessions to purge.” message. Pairing --stale with --force is a no-op (--force is redundant since a stale entry is never prompted for).

In every case the live guarantee is fail-safe: a session that is live per the liveness probe — or whose liveness cannot be positively confirmed (e.g. the tmux binary is unavailable) — is never purged by --stale, in the current repository or any other.

Examples:

git paw purge
git paw purge --force
git paw purge --stale               # current repository only
git paw purge --stale --all-repos   # every repository on the machine

git paw status

Displays the current session status, branches, CLIs, and worktree paths for the repository in the current directory. When the session was launched with the broker, also shows the broker URL and whether it is running (with its agent count and uptime), paused, not responding, or held by another repository’s git-paw broker (see Multi-repo port assignment). The broker is reported running only when this repository’s broker answers and the session’s broker host is alive; a process still answering on the port after git paw stop is reported as a leftover broker with no live session host, never as running.

Usage: git-paw status [OPTIONS]

Options:
      --json  Emit machine-readable JSON
  -h, --help  Print help

The status line shows one of:

DisplayMeaning
🟢 activeReceipt says active and the tmux session is alive
🔵 pausedReceipt says paused and the tmux session is alive
🟡 stoppedReceipt says stopped, a paused session whose tmux server died, or a session whose tmux session is up but whose agent panes have all exited
🔴 staleReceipt claims active but the tmux session is gone (a crash or a release-boundary carry-over)

When every agent pane has exited — the CLIs died and the panes fell back to a bare shell — the session is 🟡 stopped, not stale: the tmux session itself is still running. Status says so with a hint under the status line (agent panes exited — run 'git paw start' to recover them), reports Tmux: running, and sets "tmux_running": true in JSON. git paw start recovers such a session; git paw purge --stale deliberately leaves it alone.

🔴 stale (and the JSON "stale" value) means only that the tmux session is gone. When the status is 🔴 stale, run git paw start to self-heal (the stale receipt is invalidated automatically before launching) or git paw purge --stale to clear it. The --json output is an object with session, status, tmux_running, and worktrees fields, plus wave when the session’s own broker is reachable (just { "session": null } when the repository has no session); its status field carries the matching lowercase value (active, paused, stopped, or stale).

When the session’s broker reports the wave as stalled, status prints one extra line under the Broker: line naming how long nothing has progressed:

  ↳ wave stalled — no progress for 3h12m

Nothing extra is printed when the wave is not stalled. “Progress” is a wave phase advancing or a branch tip moving, and nothing else — see Wave staleness for the full rule and [broker] wave_stall_minutes for the threshold.

--json is not conditional: whenever a broker is reachable, its wave object (last_progress_unix_secs, idle_seconds, stall_threshold_seconds, stalled) is always included, stalled or not.

Each entry in --json’s worktrees array carries:

FieldTypeMeaning
branchstringThe agent’s branch name.
clistringThe CLI id assigned to this worktree.
worktree_pathstringAbsolute path to the worktree.
cli_session_idstring or nullThe session identifier git-paw assigned this worker’s CLI at launch, or null when the CLI has no assignment template. Resume it by hand with the CLI’s own resume flag (e.g. claude --resume <id>), or let git paw start do it automatically on recovery.

The human-readable table (no --json) never shows cli_session_id — it is operator/tooling data surfaced only in JSON.

Example:

git paw status
git paw status --json

git paw attach

Reattaches the current terminal to the tmux session running for the repository in the current directory, resolving the session the same way git paw status does (by repository path). Equivalent to tmux attach -t paw-<project>, without needing to know or type the exact session name.

Usage: git-paw attach

Options:
  -h, --help  Print help

Exits with an actionable error when no session is running for this repo — run git paw start to launch one.

Example:

git paw attach

Note the distinction from session revival: attach reattaches to an already-running session; git paw start is what recovers a stopped/crashed session or launches a new one.

git paw list-clis

Shows all AI CLIs found on PATH (auto-detected) and any custom CLIs registered in your config.

Usage: git-paw list-clis

Options:
  -h, --help  Print help

Example:

git paw list-clis

git paw add-cli

Adds a custom CLI to your global config (~/.config/git-paw/config.toml on Linux, ~/Library/Application Support/git-paw/config.toml on macOS — see Config File Locations). The command can be an absolute path or a binary name on PATH; a binary name is resolved to its absolute path when it is registered.

Usage: git-paw add-cli [OPTIONS] <NAME> <COMMAND>

Arguments:
  <NAME>     Name to register the CLI as
  <COMMAND>  Command or path to the CLI binary

Options:
      --display-name <DISPLAY_NAME>  Display name shown in prompts
  -h, --help                         Print help

Examples:

git paw add-cli my-agent /usr/local/bin/my-agent
git paw add-cli my-agent my-agent --display-name "My Agent"

git paw remove-cli

Removes a custom CLI from your global config. Only custom CLIs can be removed — auto-detected CLIs cannot.

Usage: git-paw remove-cli <NAME>

Arguments:
  <NAME>  Name of the custom CLI to remove

Options:
  -h, --help  Print help

Example:

git paw remove-cli my-agent

git paw setup-cli

Writes git-paw’s setup items into an AI CLI’s own settings, so the CLI stops prompting for git-paw’s helper-script calls. Running this command is the consent — nothing else in git-paw ever writes those settings. See Per-CLI Setup for the grant table, the protection rules and the residual risks.

Usage: git-paw setup-cli [OPTIONS] <--allowlist|--trust|--hooks|--undo> <CLI>

Arguments:
  <CLI>  CLI identity to set up (a detected CLI or a [clis.<name>] key)

Options:
      --allowlist  Pre-approve git-paw's own helper-script calls, with the rules
                   that stop an agent rewriting what they run
      --trust      Pre-accept the repository as a trusted folder (not supported
                   by any CLI yet)
      --hooks      Install git-paw's lifecycle hooks (not supported by any CLI yet)
      --dry-run    Print the plan and exit without writing anything, even with --yes
      --yes        Apply the printed plan without asking for confirmation
      --undo       Remove the entries git-paw recorded for this CLI, limited to the
                   named items when item flags are given
  -h, --help       Print help

At least one of --allowlist, --trust, --hooks or --undo is required. Run it from the repository’s main checkout; it refuses to run from a linked worktree.

Exit codes:

CodeMeaning
0The plan was applied, there was nothing to do, or --dry-run printed it.
1Refused: an unknown CLI, a linked worktree, an unsafe target (tracked, symlinked, malformed JSON, a wrong-typed key), or a target that changed between planning and writing.
2Nothing attempted: no item flag, a requested item that is not supported, an item whose facts are unverified, a declined confirmation, or no terminal and no --yes.

Examples:

# Print the plan and write nothing
git paw setup-cli claude --allowlist --dry-run

# Apply it, confirming on a terminal
git paw setup-cli claude --allowlist

# Apply it without a prompt
git paw setup-cli claude --allowlist --yes

# Remove exactly what git-paw added
git paw setup-cli claude --undo --yes

git paw replay

Replay captured session logs. Requires logging to be enabled.

Usage: git-paw replay [OPTIONS] [BRANCH]

Arguments:
  [BRANCH]  Branch to replay

Options:
      --list               List available log sessions and branches
      --color              Display with colors via less -R
      --session <SESSION>  Session to replay from (defaults to most recent)
  -h, --help               Print help

The branch argument matches either the original branch name or its log filename (/ becomes --), so feat/add-auth and feat--add-auth select the same log. An unmatched name errors with the list of available branches.

Examples:

# List all logged sessions and branches
git paw replay --list

# Replay a branch (stripped of ANSI codes)
git paw replay feat/add-auth

# Replay with colors
git paw replay feat/add-auth --color

# Replay from a specific session
git paw replay feat/add-auth --session paw-my-project

git paw approvals

Report the permission prompts the --unattended drive loop escalated for a human decision during a session, sorted by how often each recurred. Attended sessions run no drive loop and record nothing, though this command still reads any log an earlier unattended run left behind. See Manual approvals for the full workflow.

Usage: git-paw approvals [OPTIONS]

Options:
      --session <SESSION>  Session to read from (defaults to the active session)
      --limit <LIMIT>      Show at most N patterns (top N by count)
      --json               Emit machine-readable JSON
  -h, --help               Print help

Each row carries a SUGGEST hint naming which of the agent CLI’s own allowlists could absorb the pattern — project allowlist for project-specific patterns (a ./-rooted script, or the project/branch name), user allowlist otherwise. The hint is a starting point; the command never edits any settings file for you.

Examples:

# Active session, text table
git paw approvals

# Machine-readable JSON
git paw approvals --json

# A specific session
git paw approvals --session paw-my-project

# Top 5 patterns by count
git paw approvals --limit 5

The --json output is a { "session", "approvals": [...] } object where each entry carries pattern, count, suggested_target, first_seen, and last_seen. An empty or missing log yields { "session": "...", "approvals": [] }.

git paw mcp

Starts a Model Context Protocol (MCP) server on stdin/stdout so any MCP-aware client (Claude Desktop, Cursor, ChatGPT Desktop, Windsurf, VS Code MCP) can query this repository’s read-only state: agent coordination intents/conflicts, governance docs, specs and tasks, session status and learnings, agent skills, git context, source browsing (list_files, read_file, search_code over the local working tree), and the repository’s own README and documentation.

The write surface is bounded: four publish tools for an agent’s boot events, publishing as the calling session only; and, for a server started in the repository’s main working tree only, the session lifecycle tools (start_session, pause_session, stop_session, purge_session) and the verdict tools (publish_verified, publish_feedback). A server in an agent’s worktree neither lists nor runs those. See the MCP Server guide.

The server is client-spawned and one-shot: the MCP client owns the process lifecycle and the server exits when stdin is closed. It runs standalone — no tmux session, broker, or supervisor is required. When a data source is unavailable (no broker, no session, no governance config) tools return well-formed empty/null results rather than errors.

Usage: git-paw mcp [OPTIONS]

Options:
      --repo <PATH>      Repository to serve (overrides current-directory discovery; required for Claude Desktop)
      --log-file <PATH>  Also write tracing output to this file (stderr is always used)
  -h, --help             Print help

Repository resolution: --repo wins; otherwise the nearest ancestor of the current directory containing .git is used (worktrees resolve to their own root). Clients that spawn servers from a fixed directory — notably Claude Desktop, which launches from its app-support directory — must pass --repo with an absolute path.

--log-file tees tracing diagnostics to a file in addition to stderr; stdout always stays reserved for the JSON-RPC stream.

Claude Desktop config (claude_desktop_config.json):

{
  "mcpServers": {
    "git-paw": {
      "command": "git",
      "args": ["paw", "mcp", "--repo", "/absolute/path/to/your/repo"]
    }
  }
}

Examples:

git paw mcp
git paw mcp --repo /path/to/repo
git paw mcp --repo /path/to/repo --log-file /tmp/git-paw-mcp.log

git paw doctor

Runs read-only preflight checks over the environment, configuration, and repository state and prints a grouped report answering “why won’t it launch?”.

Usage: git-paw doctor [OPTIONS]

Options:
      --json  Emit machine-readable JSON
      --live  Also run the live session-lifecycle smoke check (slower; needs tmux)
  -h, --help  Print help

Checks are grouped under Environment, CLIs, Config, Spec system, Bundled scripts, Broker, Supervisor, and Hygiene. Each reports ✓ (pass), ⚠ (warning), or ✗ (failure), and every non-✓ check prints an actionable remedy on its own ↳ line.

Doctor diagnoses but never repairs — no file, config, session, or other persistent state is created, modified, or deleted. There is deliberately no --fix flag.

Exit behaviour:

  • Exits non-zero when any check is ✗.
  • Exits 0 when the worst status is ⚠ or better — a warning alone never blocks, so doctor works as a pre-launch or CI gate that fails only on true blockers.
  • --json shares the identical exit-code contract and suppresses the human rendering; stdout is a single JSON document with a top-level status and a checks array whose entries carry group, name, status, detail, and remedy.

--live appends a Live smoke group carrying the verdict of the full session lifecycle (start → add → remove → stop) run against an isolated throwaway repository and a dummy CLI — the same harness git paw selftest drives. It is the only arm that writes anything, and only inside its own .git-paw/tmp/ sandbox, which it removes afterwards.

Examples:

git paw doctor
git paw doctor --json
git paw doctor --live

See the Doctor chapter for the full check catalogue.

git paw completions

Generates a shell-completion script from the clap command definition and prints it to stdout, for installation through the shell’s standard completion mechanism.

Usage: git-paw completions <SHELL>

Arguments:
  <SHELL>  Shell to generate completions for [possible values: bash, elvish, fish, powershell, zsh]

Options:
  -h, --help  Print help

An unsupported shell argument is rejected by clap with an actionable error naming the supported values.

Examples:

git paw completions bash > /etc/bash_completion.d/git-paw
git paw completions zsh > "${fpath[1]}/_git-paw"
git paw completions fish > ~/.config/fish/completions/git-paw.fish

See Installation for shell-specific setup.

git paw selftest

Internal diagnostic (hidden from the command list). selftest is the live arm of git paw doctor — reachable directly for dogfooding and CI, or through git paw doctor --live, which folds its verdict into the grouped report.

Runs an isolated, end-to-end session-lifecycle smoke check — the shipped form of the dogfood isolation recipe — so the orchestration plumbing can be verified anywhere, including CI, without a real LLM backend or an interactive terminal.

Usage: git-paw selftest

Options:
  -h, --help  Print help

The harness drives start → add → remove → stop against a throwaway repository and a dummy CLI (cat), observing that the agent roster grows on add and shrinks on remove. It takes no arguments.

Every external resource is isolated so the run never disturbs live work:

  • a private tmux socket (a per-run TMUX_TMPDIR, with TMUX/TMUX_PANE stripped from every child) — your default tmux socket is untouched;
  • an OS-assigned ephemeral broker port (bind 127.0.0.1:0), so concurrent runs never collide on the broker port;
  • an isolated HOME, so your real sessions directory is never written;
  • a throwaway git repository under .git-paw/tmp/, swept clean before the run and removed on both the success and failure paths.

Exit behaviour:

  • Exits 0 and prints selftest passed when the full lifecycle completes.
  • Skips with selftest skipped: tmux not available and exits 0 when tmux is not on PATH (CI runners have tmux, so a skip never silently passes there).
  • Exits non-zero and names the failing step (e.g. selftest failed at step 'add': …) only on an actual lifecycle failure.

Example:

git paw selftest

See the Selftest chapter for the full isolation recipe and how the harness closes the deferred live-verification of add/remove roster transitions.

Exit Codes

CodeMeaning
0Success
1Error (git, tmux, config, or other failure)
2User cancelled (Ctrl+C or empty selection)

Internal subcommands

git-paw also has hidden subcommands that it runs itself; they are not listed in git paw --help and are not meant to be invoked by hand:

  • __broker --session <name> --log-path <path> — hosts a session’s broker in its detached broker tmux window. start, recovery and resume launch it; pause closes its window and stop ends it with the session.
  • __dashboard — renders the dashboard in pane 0 as a thin client of that broker.
  • __prompt-profile — prints one resolved prompt-shape profile field for the bundled sweep.sh helper.