The worktree primitive your AI agents and you share.
ww is a Git worktree workflow with two interfaces over one set of worktrees: ww for humans (fzf-driven, changes your shell directory) and ww-helper --json for AI agents and orchestrators — backed by a versioned wire protocol you can depend on.
A one-minute workflow overview ending with a short ww-helper --json tail:
- switch into an existing worktree with the
fzffast path - inspect the current workspace set with
ww list - create a fresh branch workspace with
ww new feat-demo - remove a workspace with safe
ww rm - end with a quick machine-readable
ww-helper --jsonpass
One mental model for you and your agent. Both ww and ww-helper operate on the same worktrees, with the same metadata (labels, TTL, last-used). When a Claude / Codex / Cursor agent creates a worktree, your ww list sees it immediately. When you create one, the agent sees it too.
Shell-first for humans, contract-first for agents. ww changes your current shell directory — switching worktrees feels like cd-ing, not launching a side tool. ww-helper --json emits a versioned, stable JSON envelope so an MCP server, orchestrator, or shell script can depend on the wire format without guessing.
Safe by default. ww rm shows what will be removed, what will be kept, and what looks risky before you confirm. ww new copies your git-ignored config files (.env, local configs) into the new worktree so it's runnable on first cd.
Install with Homebrew tap:
brew tap unix2dos/ww https://github.com/unix2dos/ww
brew install ww
printf 'eval "$("%s/bin/ww-helper" init zsh)"\n' "$(brew --prefix ww)" >> ~/.zshrc
source ~/.zshrcww-helper init zsh prints the activation snippet if you want to inspect it before adding it to your shell rc file.
Or install the latest release for your shell:
curl -fsSL https://github.com/unix2dos/ww/releases/latest/download/install-release.sh | bash
source ~/.zshrcThen try the loop inside any Git repository:
ww # interactive switch
ww new feat-demo # create + cd into a new worktree
ww list # see all worktrees with status
ww rm feat-demo # remove with safety previewFor the fastest interactive switch, install fzf. If fzf is not on PATH, ww falls back to a built-in selector — the workflow still works without extra setup.
Two ways to call ww-helper from an agent — pick whichever fits the agent's plumbing.
Add one block to your MCP config and every worktree command becomes a typed tool. No subprocess marshalling, no JSON parsing in the agent.
{
"mcpServers": {
"ww": {
"command": "ww-helper",
"args": ["mcp", "serve"]
}
}
}The server exposes six tools backed by the same v1.0 wire protocol the CLI uses: ww_list, ww_new, ww_remove, ww_gc, ww_switch_path, ww_version. Schemas are generated from the same Go structs the CLI marshals, so the data shape is identical across both transports.
Every --json command emits a single-line envelope conforming to the versioned wire protocol:
ww-helper version --json
ww-helper list --json
ww-helper new-path --json --label agent:codex --ttl 24h -m "Fix login redirect" feat-demo
ww-helper gc --ttl-expired --dry-run --json
ww-helper rm --json feat-demoEnvelope shape:
{"protocol":"1.0","ok":true,"command":"list","data":[...],"warnings":[]}
{"protocol":"1.0","ok":false,"command":"list","error":{"code":"git.repo_missing","message":"...","context":{}}}The protocol field, the field names inside data, and the domain.subcode error codes (worktree.dirty, git.repo_missing, selector.fzf_not_installed, …) are stable within v1.x — additive changes only. See docs/protocol.md for the complete contract, including per-command schemas, exit codes, and what is explicitly not covered (switch-path is raw stdout for shell-eval; list --filter grammar is not yet frozen).
Repository-level instructions for coding agents live in AGENTS.md.
README.md stays in landing-page mode. Detailed install, usage, release, and command reference live in:
- Wire Protocol — for anyone scripting
ww-helper - Reference Guide
- Demo Script Notes