From harness-worktrees
Set up parallel git worktrees of the same repo, one per coding harness (Claude Code, Codex CLI, Cursor, etc.), so multiple AI tools can edit, typecheck, and test in parallel without trampling each other's node_modules, build artifacts, or branches. USE WHEN user says 'set up worktrees for my coding tools', 'I want a Claude / Codex / pi worktree of this repo', 'parallel worktrees per harness', 'harness worktrees', 'split this repo per coding agent', or wants one-checkout-per-tool isolation. Also handles Mode C: reset the current worktree to latest main after a PR merge.
How this skill is triggered — by the user, by Claude, or both
Slash command
/harness-worktrees:harness-worktreesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Set up sibling git worktrees of the current repo, one per coding harness, so Claude Code, Codex CLI, Cursor, and any other AI coding tool can work on the same codebase in parallel without stepping on each other's branches, `node_modules`, or build artifacts.
Set up sibling git worktrees of the current repo, one per coding harness, so Claude Code, Codex CLI, Cursor, and any other AI coding tool can work on the same codebase in parallel without stepping on each other's branches, node_modules, or build artifacts.
Users running multiple coding harnesses on the same repo want each tool to have its own checkout so:
node_modules, target/, dist/, .next/, __pycache__/ are isolated per worktree (this happens automatically — git worktree gives each its own working directory)work/claude, work/codex, work/pi, etc.) make it obvious which session owns which workThe skill has three modes. Pick before doing anything else, by asking the user explicitly if it's not already clear from the conversation.
Three (or N) worktrees can edit, typecheck, lint, and run tests simultaneously. Only one worktree may run a live dev session (bun run dev, npm run dev, cargo run, uv run, etc.) at a time, because the repo's bootstrap code typically hardcodes ports / DB paths that would collide.
Setup cost: ~5 minutes. No code edits to the repo.
All N worktrees can run live dev simultaneously, each on its own port and its own DB / data dir. Requires the repo to thread environment overrides (PORT, DB_PATH, etc.) through its bootstrap. The skill does NOT make those code changes. It surfaces the exact files that would need editing and stops, asking the user to either (a) make the changes and rerun, or (b) downgrade to Mode A.
Use when the user says they want the current worktree refreshed, reset, or synced to the latest main after a PR merge.
Run scripts/reset-worktree-to-main.sh from this plugin's skill directory. It dry-runs by default and only mutates the repo with --confirm.
Rules:
git switch main; in multi-worktree repos, main may be checked out elsewhere.origin/main by default, and the current branch name is preserved.--confirm --stash.Commands (run from the repo where you want the reset):
# dry run
${CLAUDE_PLUGIN_ROOT}/skills/harness-worktrees/scripts/reset-worktree-to-main.sh
# execute when the user explicitly wants this worktree reset
${CLAUDE_PLUGIN_ROOT}/skills/harness-worktrees/scripts/reset-worktree-to-main.sh --confirm
# execute while preserving dirty local changes in a stash
${CLAUDE_PLUGIN_ROOT}/skills/harness-worktrees/scripts/reset-worktree-to-main.sh --confirm --stash
Refuse to proceed if any of these are true (state the reason and stop):
git rev-parse --is-inside-work-tree fails)git status --porcelain is non-empty) — offer to stash or abortConfirm with the user:
["claude", "codex", "pi"]. Accept any names; they're free-form (e.g. cursor, windsurf, aider).main or master).Run scripts/audit-hazards.sh <repo-path> from this plugin's skill directory. The script greps for:
localhost:\d+, :3000, :3001, :5173, process.env.PORT, Bun.env.PORT, Number(...) || \d+ patterns in .ts, .tsx, .js, .rs, .py, .go~/.<app>/, data.db, *.sqlite, chroma, pgdata, redis.sock, database.url, DB_PATH, DATABASE_URL defaults.sock, IPC, Unix domainnode_modules/, target/, dist/, .next/, build/, .venv/ exist and would be per-worktree (they will be, but flag any that are NOT in .gitignore and are committed)The script outputs a structured report. Read it, and:
This is the most important step. Append a Gotcha block to the cold-start brief at repo root (CLAUDE.md if present; otherwise AGENTS.md; otherwise create CLAUDE.md).
The block must be specific to this repo's hazards, not a generic warning. Use the audit output to fill in the file paths and resource names. Template:
N. **Multi-worktree shared-state risk.** This repo is checked out as parallel `git worktree`s (`<repo>-claude/`, `<repo>-codex/`, `<repo>-pi/`) so different coding harnesses can work in parallel. The following resources are **shared across every worktree** because the bootstrap code uses fixed values:
- <hazard 1: e.g. SQLite DB at `~/.appname/data.db` — `packages/core/src/server.ts:143` calls `initDatabase()` with no arg>
- <hazard 2: e.g. dev server port 3001 — `packages/core/src/server.ts:107`>
- <hazard 3: ...>
Code-only work (typecheck, tests, lint, edits, commits) is safe to run in parallel — only one worktree may run a *live* dev session (`<dev-command>`) at a time. Before starting a live session, confirm no other worktree's process is up: `<port-check-command>`.
Until `<env-vars>` are threaded through the bootstrap, treat parallel live sessions as forbidden — they will corrupt shared state.
After appending, commit with a focused message (one line: docs: document multi-worktree shared-state gotcha) and push to origin so the worktrees, once created, all inherit the gotcha at the same commit.
If the user declined to push in Step 1, commit locally and warn them that worktrees created from the local commit will diverge from origin until they push.
For each tool name (default claude, codex, pi):
git branch work/<tool> <integration-branch> — long-lived integration branch per toolgit worktree add <repo-parent>/<repo-name>-<tool> work/<tool> — sibling directory<repo-parent> is the parent of the current repo's working directory. <repo-name> is the basename of the working directory. Example: if current repo is ~/Projects/my-app/, the worktrees go at ~/Projects/my-app-claude/, ~/Projects/my-app-codex/, etc.
If a tool name conflicts with an existing branch, append a numeric suffix (work/claude-2) and warn the user.
In each new worktree, run the install command appropriate to the detected stack(s). Detect stacks by checking for these files in the worktree root:
| File present | Install command |
|---|---|
bun.lock or bun.lockb | bun install |
pnpm-lock.yaml | pnpm install |
yarn.lock | yarn install |
package-lock.json | npm install |
package.json (no lockfile) | npm install (warn no lockfile) |
Cargo.toml | cargo fetch (do NOT cargo build — that's slow, fetch is enough to populate target/ index) |
pyproject.toml + uv.lock | uv sync |
pyproject.toml (no uv.lock) | warn — let user choose uv sync, pip install -e ., or skip |
requirements.txt | warn — let user choose pip/uv/poetry |
Gemfile | bundle install |
go.mod | go mod download |
Run installs in parallel across worktrees (they're independent — no shared state). Capture exit codes and report any failures, but don't abort the other installs.
If a worktree has multiple stacks (e.g. a Tauri repo with both bun.lock and Cargo.toml), run all applicable install commands. The Rust install can be slow; consider running it last or in the background and reporting completion separately.
End with a structured summary that the user can copy into a notes doc. Format:
WORKTREE MAP — <repo-name>
<repo-parent>/
├── <repo-name>/ ← primary, branch: <integration-branch>
│ (only place to git pull / merge to)
│
├── <repo-name>-claude/ ← worktree, branch: work/claude
├── <repo-name>-codex/ ← worktree, branch: work/codex
└── <repo-name>-pi/ ← worktree, branch: work/pi
Gotchas (now in CLAUDE.md gotcha #N):
- <hazard 1 one-liner>
- <hazard 2 one-liner>
- ...
Rule: only one worktree runs a live dev session at a time.
Before `<dev-command>`, run `<port-check-command>`.
Workflow:
1. work in <repo>-{tool}/ on branch work/{tool}
2. push → PR → merge to <integration-branch> on GitHub
3. in primary <repo>/: git pull
4. in each worktree: git rebase origin/<integration-branch>
.gitmodules, git worktree add won't auto-init them in the new worktree. After creating each worktree, cd in and run git submodule update --init --recursive. Surface this in the audit step so the user knows it'll happen.git worktree add refuses to check out a branch already in use elsewhere. If work/<tool> exists from a prior run, either pick up the existing worktree (verify it's at the right path) or fail with a clear message.<repo-parent> is not writable, abort and ask the user where to put the worktrees instead. Don't silently fall back to any default location.node_modules — the parallel installs duplicate disk usage by N. On a 1.5GB node_modules, three worktrees adds ~4.5GB. Surface the cost in the pre-flight check so the user can decide.process.env.SIDECAR_PORT ?? 3001 and similar patterns are already pervasive, mention Mode B is genuinely available to the user without code changes. Don't gate on Mode A reflexively.CLAUDE.md with just the gotcha block and a one-line header. Don't fabricate other content. If the user objects, move the block to a project-local docs/MULTI-WORKTREE.md instead.The friction this skill removes is real: switching coding harnesses on the same repo without isolation means every tool fights over the working tree, branch HEAD, install state, and editor caches. With per-tool worktrees, each session has stable identity — work/claude is "the Claude session's branch," and any agent that wakes up in <repo>-claude/ knows it's the Claude worktree. The gotcha-doc step is what makes the layout discoverable to future agents in future sessions: any Claude or Codex spawned in any of the worktrees reads the cold-start brief and sees the rule about not running parallel live dev. Without that, a fresh agent has no way to know.
The skill deliberately stays in its lane:
.git/config global settingsCreates, edits, and verifies skills using a test-driven development approach with pressure scenarios and subagents.
npx claudepluginhub aojdevstudio/agentic-utilities --plugin harness-worktrees