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

Configuration

git-paw uses TOML configuration files at two levels, with repo-level settings overriding global ones.

Config File Locations

LevelPathPurpose
Global~/.config/git-paw/config.tomlDefault CLI, custom CLIs, global presets
Per-repo.git-paw/config.toml (in repo root)Repo-specific overrides

Both files are optional. git-paw works with sensible defaults when no config exists.

Full Config Example

# Default CLI used when --cli flag is not provided
default_cli = "my-cli"

# Default CLI for spec-mode launches (--from-all-specs, --specs); bypasses picker when set
# default_spec_cli = "my-cli"

# Prefix for spec-derived branch names (default: "spec/")
# branch_prefix = "spec/"

# Enable mouse mode in tmux sessions (default: true)
mouse = true

# Custom CLI definitions
[clis.my-agent]
command = "/usr/local/bin/my-agent"
display_name = "My Agent"

[clis.local-llm]
command = "ollama-code"
display_name = "Local LLM"

# Named presets for quick launch
[presets.backend]
branches = ["feature/api", "fix/db"]
cli = "claude"

[presets.frontend]
branches = ["feature/ui", "feature/styles"]
cli = "codex"

# Spec scanning configuration
# [specs]
# dir = "specs"
# type = "openspec"    # "openspec", "markdown", or "speckit"

# Session logging
# [logging]
# enabled = false

# Agent coordination broker
# [broker]
# enabled = false
# port = 9119
# bind = "127.0.0.1"

# Pointers to user-maintained governance docs (all optional)
# [governance]
# adr = "docs/adr"
# test_strategy = "docs/test-strategy.md"
# security = "docs/security-checklist.md"
# dod = "docs/definition-of-done.md"
# constitution = ".specify/memory/constitution.md"

Settings Reference

default_cli

The AI CLI to use when --cli is not passed and you want to skip the CLI picker.

default_cli = "my-cli"

default_spec_cli

The AI CLI to use by default when launching with --from-all-specs or --specs. When set, skips the CLI picker for any specs that don’t have a paw_cli override.

default_spec_cli = "my-cli"

See Spec-Driven Launch for the full CLI resolution chain.

branch_prefix

Prefix prepended to spec-derived branch names. Defaults to "spec/".

branch_prefix = "spec/"

For example, a spec with ID add-auth produces branch spec/add-auth.

mouse

Enable or disable tmux mouse mode for git-paw sessions. When enabled, you can click panes to switch, drag borders to resize, and scroll with the mouse wheel. This is set per-session and does not affect your other tmux sessions.

mouse = true  # default

Custom CLIs

Register custom AI CLIs that aren’t in git-paw’s built-in detection list.

Via config file

[clis.my-agent]
command = "/usr/local/bin/my-agent"   # absolute path
display_name = "My Agent"              # optional, shown in prompts

[clis.local-llm]
command = "ollama-code"               # binary name (resolved via PATH)
display_name = "Local LLM"

Via command line

# Add with absolute path
git paw add-cli my-agent /usr/local/bin/my-agent

# Add with binary name on PATH
git paw add-cli my-agent my-agent

# Add with display name
git paw add-cli my-agent my-agent --display-name "My Agent"

# Remove
git paw remove-cli my-agent

The add-cli and remove-cli commands modify the global config at ~/.config/git-paw/config.toml.

Listing CLIs

git paw list-clis

Shows both auto-detected and custom CLIs with their source:

Name       Path                         Source
claude     /usr/local/bin/claude        detected
codex      /usr/local/bin/codex         detected
my-agent   /usr/local/bin/my-agent      custom

Presets

Presets save branch + CLI combinations for one-command launch.

Defining presets

[presets.backend]
branches = ["feature/api", "fix/db-migration"]
cli = "claude"

[presets.full-stack]
branches = ["feature/api", "feature/ui", "feature/styles"]
cli = "gemini"

Using presets

git paw start --preset backend

This skips all interactive prompts and launches with the preset’s branches and CLI.

Specs

Configure spec file scanning for --from-all-specs and --specs mode.

[specs]
dir = "specs"         # Directory containing spec files (relative to repo root)
type = "openspec"     # "openspec" (OpenSpec changes), "markdown" (flat .md files), or "speckit" (GitHub Spec Kit)
FieldDefaultDescription
dir"specs"Directory to scan for spec files
type"openspec"Spec backend: "openspec" (directory-based OpenSpec changes), "markdown" (flat .md files with YAML frontmatter), or "speckit" (GitHub Spec Kit .specify/specs/<feature>/)

When [specs] is omitted and .specify/specs/ exists at the repo root, the spec backend auto-detects to type = "speckit" with dir = ".specify/specs". Use the --specs-format CLI flag to override both the config value and the auto-detection for a single launch.

See Spec-Driven Launch for format details.

Logging

Configure session output logging.

[logging]
enabled = true
FieldDefaultDescription
enabledfalseWhether to capture pane output to log files

When enabled, logs are written to .git-paw/logs/<session>/ using tmux pipe-pane. See Session Logging for details.

Broker

Configure the HTTP broker for agent coordination. When enabled, git-paw starts a lightweight HTTP server that lets agents share status updates, artifacts, and blocked requests.

[broker]
enabled = true
port = 9119
bind = "127.0.0.1"
FieldDefaultDescription
enabledfalseWhether to start the coordination broker
port9119HTTP port for the broker server
bind"127.0.0.1"Bind address – never bind to 0.0.0.0 on shared machines

When the broker is enabled, git-paw injects the GIT_PAW_BROKER_URL environment variable into each agent pane, pointing to http://<bind>:<port>. Agents use this URL to communicate with the broker.

Multi-repo port assignment

If you run git-paw sessions for multiple repositories at the same time, each session needs a different port. Set a unique port in each repo’s .git-paw/config.toml:

# Repo A
[broker]
enabled = true
port = 9119

# Repo B (in its own .git-paw/config.toml)
[broker]
enabled = true
port = 9120

See Agent Coordination for usage details.

Supervisor

Configure the supervisor agent for orchestrating parallel coding sessions. When enabled, the supervisor monitors agents, runs tests, verifies work, and coordinates merges.

[supervisor]
enabled = true
cli = "claude"
test_command = "just check"
lint_command = "cargo clippy -- -D warnings"
build_command = "cargo build"
fmt_check_command = "cargo fmt --check"
doc_build_command = "mdbook build docs/"
spec_validate_command = "openspec validate {{CHANGE_ID}} --strict"
security_audit_command = "cargo audit"
agent_approval = "auto"
FieldDefaultDescription
enabledfalseWhether to use supervisor mode by default (can also use --supervisor flag, or override with --no-supervisor for a single session)
cli(uses default_cli)CLI binary for the supervisor agent
test_command(none)Test runner — gate 1 (e.g. "just check", "cargo test", "npm test", "pytest")
lint_command(none)Lint check — gate 1 (e.g. "cargo clippy -- -D warnings", "npm run lint", "ruff check .", "golangci-lint run")
build_command(none)Compile step — gate 1 when build is distinct from test (e.g. "cargo build", "npm run build", "mvn package", "go build ./...")
fmt_check_command(none)Formatter check — gate 1 (e.g. "cargo fmt --check", "prettier --check .", "gofmt -l .", "black --check .")
doc_build_command(none)Documentation build — gate 4 (e.g. "mdbook build docs/", "sphinx-build", "mkdocs build")
spec_validate_command(none)Spec validator — gate 3 (e.g. "openspec validate {{CHANGE_ID}} --strict" for OpenSpec). {{CHANGE_ID}} is substituted by the supervisor agent at verification time with the change name being audited; it is not expanded at config load
security_audit_command(none)Security audit tooling — gate 5 (e.g. "cargo audit", "npm audit", "bandit -r .", "gosec ./...")
agent_approval"auto"Permission level for coding agents: "manual", "auto", or "full-auto"

Gate-command templating. The seven *_command keys feed the supervisor skill’s five verification gates (testing, regression analysis, spec audit, doc audit, security audit). For each key set on this section, the supervisor skill substitutes the matching {{...}} placeholder at session boot and the supervisor agent runs the literal command during that gate. For each key omitted, the placeholder renders as (not configured) and the supervisor agent skips that tooling step — the gate’s manual review still applies (e.g. the OWASP-category diff scan for the security gate, the spec scenario coverage check for the spec gate). Pre-v0.5.x configs that did not name any of the six new keys continue to work; they just run a less-rigorous verification cycle until the keys are filled in. A user wanting to explicitly opt out of a single gate’s tooling can set the field to "(not configured)" verbatim — the supervisor agent recognises that as the same skip token.

Resolution chain — git-paw picks supervisor mode using the first matching rule:

  1. --no-supervisor → off (highest precedence; overrides everything below).
  2. --supervisor → on.
  3. [supervisor] enabled = true → on.
  4. [supervisor] enabled = false → off.
  5. No [supervisor] section + --dry-run → off.
  6. No [supervisor] section + interactive TTY → prompts you.
  7. No [supervisor] section + non-TTY → off.

--supervisor and --no-supervisor are mutually exclusive — passing both produces a parse error.

Approval levels:

LevelBehavior
manualAgents prompt for every action (safest, slowest)
autoCLI default behavior — some prompts, some auto-approved
full-autoSkip all permission prompts (fastest, agents run unattended)

The supervisor translates the approval level into CLI-specific flags at launch (e.g. --dangerously-skip-permissions for Claude in full-auto mode).

Auto-approve safe permission prompts

When supervisor mode is enabled, git-paw can automatically approve common, known-safe permission prompts (cargo test, git commit, broker curl calls, etc.) in stalled agent panes so the supervisor does not have to dismiss every prompt by hand.

[supervisor.auto_approve]
enabled = true
safe_commands = ["just lint", "just test"]
stall_threshold_seconds = 30
approval_level = "safe"
FieldDefaultDescription
enabledtrueMaster switch for auto-approval. Set to false to disable.
safe_commands[]Project-specific command prefixes appended to the built-in defaults.
stall_threshold_seconds30Seconds an agent’s last_seen must lag before its pane is polled (minimum 5).
approval_level"safe"Coarse preset: "off", "conservative", or "safe".

Built-in safe commands: cargo fmt, cargo clippy, cargo test, cargo build, git commit, git push, curl http://127.0.0.1:.

Approval-level presets:

PresetBehavior
offForces enabled = false. No detection or approval runs.
conservativeDrops git push and curl from the effective whitelist.
safe (default)Approve every entry in the built-in whitelist plus configured extras.

How it works: when an agent’s status is non-terminal (done, verified, blocked, committed are skipped) and its last_seen exceeds the threshold, git-paw runs tmux capture-pane, classifies the pending command, and either dispatches BTab Down Enter (if safe) or publishes an agent.question to the supervisor inbox (if not).

git-paw also seeds .claude/settings.json::allowed_bash_prefixes with the broker endpoints (/publish, /status, /poll, /feedback) so the first broker call never hits a permission prompt. Existing entries in that file are preserved.

Common dev-command allowlist

On every supervisor session start, git-paw seeds a curated preset of dev-loop prefix patterns into .claude/settings.json::allowed_bash_prefixes so agents do not hit a permission prompt for each variant of cargo build, git commit, just check, mdbook build, etc. The mechanism is the same one Claude uses for its “Yes, don’t ask again” flow — but seeded up-front rather than approved one-by-one.

[supervisor.common_dev_allowlist]
enabled = true
extra = ["pnpm test", "deno fmt"]
FieldDefaultDescription
enabledtrueMaster switch for the seeder. Set to false to skip seeding entirely.
extra[]Additional project-specific prefix patterns appended to the built-in preset.

Built-in preset (all v0.5.0 entries):

  • Cargo: cargo build, cargo test, cargo clippy, cargo fmt, cargo check, cargo tree, cargo deny, cargo update
  • Git (read): git status, git log, git diff, git show, git fetch
  • Git (write, non-destructive): git commit, git push, git pull, git merge, git stash, git add, git restore, git rm
  • Just: just (any recipe)
  • mdBook: mdbook build
  • OpenSpec: openspec validate, openspec new, openspec archive, openspec list, openspec status, openspec instructions
  • Search (read-only): find, grep, sed -n

Intentional exclusions: cargo install, cargo run, cargo bench, git rebase, git reset, git checkout, git push --force, sed without -n, and non-cargo package managers (npm, pnpm, yarn, deno, bun, uv, pip, pipx, gem). Add them via extra if you accept the wider surface for your project.

Behaviour:

  • Independent of broker status — non-broker supervisor sessions still benefit.
  • Idempotent: re-seeding on session re-attach never duplicates entries.
  • Non-fatal: write failures log a warning to stderr and session start continues.
  • Targets <repo>/.claude/settings.json always; also writes ~/.claude-oss/settings.json when that directory pre-exists (the alt-config dogfood pattern) but never creates the directory.
  • Entries persist after git paw stop — prune .claude/settings.json manually if you want a clean slate.

Conflict detector tuning

When supervisor mode is enabled, the broker runs an in-process conflict detector that auto-emits agent.feedback (and optionally agent.question) on forward, in-flight, and ownership conflicts. See Agent Coordination § Automatic Conflict Detection for the runtime semantics; the table below documents the configuration surface.

[supervisor.conflict]
window_seconds = 120
warn_on_intent_overlap = true
escalate_on_violation = true
FieldDefaultDescription
window_seconds120Seconds the detector waits before escalating an unresolved in-flight conflict to the supervisor inbox via agent.question.
warn_on_intent_overlaptrueMaster switch for forward-conflict feedback. When false, two agents declaring overlapping agent.intent files no longer trigger agent.feedback, but the intent tracker still records them (so in-flight and ownership detection continue to work).
escalate_on_violationtrueWhether ownership violations escalate to the supervisor inbox. When false, the violator still receives agent.feedback, but no follow-up agent.question lands in the supervisor inbox.

The [supervisor.conflict] table is fully optional. A v0.4 config with [supervisor] and no [supervisor.conflict] loads cleanly with every field at the defaults above. Setting [supervisor] enabled = false (or omitting the section) disables the detector subsystem entirely — no auto-emitted warnings fire regardless of the values here.

Learnings mode tuning

When supervisor mode is active, the parent [supervisor] learnings = true flag (default false) activates the learnings subsystem. Entries are appended to .git-paw/session-learnings.md covering the five deterministic categories tracked in v0.5.0 (stuck duration, recovery-cycle count, forward conflicts, in-flight conflicts, ownership violations). The [supervisor.learnings_config] sub-table tunes the flush cadence; the master switch lives on the parent table.

[supervisor]
learnings = true

[supervisor.learnings_config]
flush_interval_seconds = 60
FieldDefaultDescription
flush_interval_seconds60How often the learnings aggregator flushes accumulated entries from memory to .git-paw/session-learnings.md. The file is append-only across sessions; a longer interval batches more entries per write.

See the Learnings Mode chapter for the category-by-category walkthrough, the output-file format, and the v0.6.0 roadmap for programmatic access via the agent.learning broker variant.

Governance

Point git-paw at your project’s existing governance documents so the supervisor can read them as context. All fields are optional — list only the docs you have.

[governance]
adr = "docs/adr"                          # directory of ADR files
test_strategy = "docs/test-strategy.md"   # single Markdown file
security = "docs/security-checklist.md"   # single Markdown file
dod = "docs/definition-of-done.md"        # single Markdown file
constitution = ".specify/memory/constitution.md"  # single Markdown file
FieldKindDescription
adrdirectoryArchitecture Decision Records. git-paw does not care which convention (Nygard, MADR, adr-tools) — point at the folder where they live.
test_strategyfileThe team’s test-strategy document.
securityfileSecurity checklist (OWASP-style, project-specific, whatever the team uses).
dodfileDefinition of Done for completed work.
constitutionfileProject constitution. Spec Kit users normally let this auto-wire (see below).

git-paw does not dictate the structure, format, or rubric of any of these documents. The supervisor LLM reads them as context and applies judgment during its existing audit flow. There is no [governance.gates] table and no per-doc enforcement switch — gating-per-doc would require git-paw to define “failure” for each doc type, and that is a process choice your team owns.

Paths are stored verbatim and resolved against the repository root at use time. Relative paths point at files inside the repo; absolute paths are accepted as-is. A path that does not exist still loads cleanly — git-paw does not stat the filesystem at config-load. If you point at a missing file, the runtime consumer flags it.

Spec Kit constitution auto-wiring

When governance.constitution is unset AND [specs] type = "speckit", git-paw probes for <specs_dir>/../memory/constitution.md and, if present, populates governance.constitution automatically. This means a typical Spec Kit project (with .specify/specs/ and .specify/memory/constitution.md) gets the constitution wired up without any [governance] entry.

Explicit values always win. If governance.constitution is set to anything — including a path that does not exist or an empty string — auto-wiring is skipped:

[governance]
constitution = ""   # disables auto-wiring without deleting the slot

Auto-wiring only runs for the Spec Kit backend. With [specs] type = "openspec", type = "markdown", or no [specs] section, governance.constitution stays whatever the TOML says (defaulting to None).

What the supervisor does with these paths

This [governance] table is the storage slot. The runtime consumer — boot-prompt injection so the supervisor can read each doc and apply it to its audit — lives in the parallel governance-context capability. See the Governance chapter of the user guide for what that looks like end-to-end.

Dashboard

Configure the dashboard TUI rendered in pane 0 when the broker is enabled.

[dashboard]
show_message_log = true
FieldDefaultDescription
show_message_logfalseWhen true, the dashboard renders a scrolling broker-message panel above the prompts section. Useful for watching live agent traffic; leave false for a more compact layout.

See Dashboard for details.

Multi-repo configuration

Each repository can have its own dashboard settings in .git-paw/config.toml. The repo-level config overrides the global config.

Merging Rules

When both global and repo configs exist, they merge with these rules:

FieldMerge behavior
default_cliRepo wins
default_spec_cliRepo wins
branch_prefixRepo wins
mouseRepo wins
clisMaps merge (repo overrides per-key)
presetsMaps merge (repo overrides per-key)
specsRepo wins
loggingRepo wins
brokerRepo wins
supervisorRepo wins
dashboardRepo wins
governancePer-field merge (repo wins on each set field, unset fields fall back to global)

Example: If global config defines [clis.my-agent] and repo config defines [clis.my-agent] with a different command, the repo version wins. But a [clis.other-tool] in global config still appears — maps are merged, not replaced.

Graceful Absence

If no config files exist, git-paw uses defaults:

  • No default CLI (prompts for selection)
  • Mouse mode enabled
  • No custom CLIs
  • No presets