Help us improve
Share bugs, ideas, or general feedback.
From ai-brain-starter
Creates per-session git worktrees (~/dev/<repo>-<slug/>) to prevent concurrent Claude Code sessions from colliding on .git/HEAD. Ships a wrapper script + hookify rule. Useful when multiple sessions write code in the same repo.
npx claudepluginhub adelaidasofia/ai-brain-starterHow this skill is triggered — by the user, by Claude, or both
Slash command
/ai-brain-starter:dev-repo-worktreesThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Per-session git worktree pattern for `~/dev/<repo>/` code repos that prevents concurrent Claude Code sessions from colliding on the shared `.git/HEAD`.
Sets up Git worktrees for running multiple parallel Claude sessions on the same repo without conflicts. Use for review, refactor, test, and docs workflows with isolated directories.
Isolates parallel Claude Code workers in separate git worktrees to prevent file collisions during concurrent edits.
Creates a git worktree for isolated parallel development — new branch in a separate directory with project setup and test baseline. Enables multiple Claude Code sessions on different tasks simultaneously.
Share bugs, ideas, or general feedback.
Per-session git worktree pattern for ~/dev/<repo>/ code repos that prevents concurrent Claude Code sessions from colliding on the shared .git/HEAD.
The failure mode (CONCURRENT-SESSION-HEAD-DRIFT): Two Claude Code sessions both editing code in ~/dev/<repo>/ share one physical checkout, which means one .git/HEAD + one index + one working tree. When session A checks out their feature branch, session B's next git commit lands on session A's branch by accident. Recovery requires branch-label manipulation + git stash dances + branch-switch-safety hook overrides. Observed multiple times in long-running multi-session workflows.
The cause: Bash cd is per-command, not per-session. Every invocation re-cds; HEAD-state from prior commands is whatever the last command left it. Bash sessions cannot share filesystem state with other Bash sessions — but git operations on the same checkout absolutely DO share state, and the model can't observe that.
The fix: every Claude Code session that writes code in ~/dev/<repo>/ works in its own per-session git worktree at ~/dev/<repo>-<slug>/. Each worktree has its own HEAD + own index + own working tree, while sharing the underlying object store. Zero collision possible.
~/dev/<repo>/ NEVER write here in a session
~/dev/<repo>-<slug>/ YES — session checkout, isolated HEAD
The main checkout stays as the maintenance + reference path — fetches + integration view. Session writes go through the worktree.
~/dev/<repo>/git commit or git push from the sessioncat, grep, git log, git diff) — no HEAD writessuperpowers:using-git-worktrees)Copy claude-dev-worktree to ~/.local/bin/claude-dev-worktree:
cp skills/dev-repo-worktrees/claude-dev-worktree ~/.local/bin/claude-dev-worktree
chmod +x ~/.local/bin/claude-dev-worktree
Verify on PATH: which claude-dev-worktree.
Copy hookify.warn-dev-repo-shared-checkout.local.md to your vault's .claude/ directory and customize the (your-repo-1|your-repo-2|...) capture group in the pattern to match your actual high-concurrency repos.
The hookify rule fires on cd ~/dev/<known-shared-repo> (no worktree suffix) and surfaces the pattern. Action is warn, not block — false-positive rate is acceptable because every miss-as-warn-only is just a reminder, never a block of legitimate work.
Add to your CLAUDE.md # Rules section:
- **External-repo worktrees** (`<your-rules-dir>/external-repo-worktrees.md`):
every Claude session that writes code in `~/dev/<repo>/` MUST work in a
per-session git worktree at `~/dev/<repo>-<slug>/`, NEVER in the main
checkout. Wrapper script `~/.local/bin/claude-dev-worktree start <repo>
<slug>` automates creation; `cleanup <repo> <slug>` removes after PR
merges. Bypass: `DEV_WORKTREE_BYPASS=1` for read-only audit work.
The rule file itself is documented in this SKILL.md — the wrapper + hookify are the enforcement layers; the CLAUDE.md entry is the discoverability layer.
At session start, BEFORE first edit on a ~/dev/<repo> issue:
claude-dev-worktree start <repo> <slug> # creates ~/dev/<repo>-<slug>/
cd ~/dev/<repo>-<slug>
# all work happens here — isolated HEAD, no collision
At session close (after PR merges):
claude-dev-worktree cleanup <repo> <slug> # removes worktree + local branch
Inspect every active worktree across all repos under ~/dev/:
claude-dev-worktree list
| Pattern | Mechanism | When it fires |
|---|---|---|
This skill (dev-repo-worktrees) | Per-session git worktree add | Session start, BEFORE first write |
dev-repo-checkpoints skill | Auto-stash on Stop event | Session end, AFTER work would have been lost |
branch-switch-safety rule | PreToolUse block on destructive ops with untracked work | When a destructive op is attempted |
The three patterns are complementary:
dev-repo-worktrees PREVENTS the collision by structural isolationdev-repo-checkpoints RECOVERS lost work via auto-stashbranch-switch-safety BLOCKS the destructive op when work would be lostA robust setup runs all three. Worktree-per-session is the cheapest insurance — disk cost is ~500MB per worktree (typical Node + Cargo project), trivially less than the cost of one corruption incident.
hooks/)The worktree convention above is the structural fix; two PreToolUse / SessionStart hooks enforce it so discipline doesn't silently lapse under load. Both ship in this starter's hooks/ directory.
check-cd-outside-worktree.py — blocks the cd-into-main moveA worktree has its own HEAD; the main checkout has a different HEAD shared with every other main-checkout session. The classic recurrence is a worktree-rooted session that cds back into the main checkout and then commits — landing the commit on the wrong branch. This PreToolUse(Bash) hook detects a worktree-rooted session (cwd under <repo>/.claude/worktrees/<slug>) and blocks any cd/pushd whose resolved target lands in the main tree but outside the worktrees subtree. Use git -C <path> … for read-only queries against the main checkout instead. Bypass: WORKTREE_CD_BYPASS=1.
session-lock.py — sibling-session coordinationWorktree isolation prevents the shared-HEAD collision structurally, but two sessions can still pick the SAME repo and clobber each other's in-flight work (e.g. a sibling commits a broken state, CI fails, it reverts, and ~45 min of work is wiped). The coordination layer:
git rev-parse --git-common-dir, shared across every worktree of the repo), reads <main_root>/.claude/.session-lock.json, and warns if a DIFFERENT session was active in the repo within the last 5 min. Then writes / refreshes this session's lock.last_activity_at so an actively-working session keeps the slot warm and a later sibling still sees it as live.SIBLING_SESSION_LOCK_BYPASS=1 (intentional parallel / collaborative work).Install both (canonical runtime location is ~/.claude/hooks/):
cp hooks/check-cd-outside-worktree.py hooks/check-py-import-precommit.py hooks/session-lock.py ~/.claude/hooks/
Then wire them in ~/.claude/settings.json — check-cd-outside-worktree.py + check-py-import-precommit.py under PreToolUse (matcher Bash), and session-lock.py under both SessionStart and Stop:
{ "type": "command", "command": "python3 ~/.claude/hooks/session-lock.py" }
check-py-import-precommit.py is the third companion: it runs ruff check --select F821 on staged .py before a git commit and warn-blocks on undefined-name findings (the missing-import class that triggers the broken-commit-then-revert collision). Requires ruff on PATH (uv tool install ruff); it nudges once/day if absent rather than failing silently. Bypass: PRECOMMIT_F821_BYPASS=1.
Each worktree is a full checkout. With 3 concurrent sessions on a typical fullstack repo (~500MB working tree with build-tool caches like target/, .next/, .gradle/, etc.), worktrees add ~1.5GB. Some package managers share their store across worktrees automatically (e.g. pnpm via node_modules/.pnpm); language build caches (cargo target/, gradle .gradle/) are typically per-worktree and cannot easily share without symlink tricks.
Not a legitimate blocker. Disk is cheap; mid-build corruption is not.
CONCURRENT-SESSION-HEAD-DRIFT. Parent class: ARTIFACT-WITHOUT-ISOLATION-WIRING — siblings include ARTIFACT-WITHOUT-UMBRELLA-WIRING (skill installs without routing wires) and ARTIFACT-WITHOUT-DEPENDENCY-WIRING (Linear issues created without blocker relations). All share the same shape: a thing gets created without its required structural connection wired in the same beat.
DEV_WORKTREE_BYPASS=1 for legitimate single-session work in the main checkout — rare, typically only when fetching + reading without writes.
Originally codified in a personal Claude vault as external-repo-worktrees.md after the second concurrent-session HEAD-drift collision in 16 hours. The pattern is universal — published to the public substrate so anyone running multi-session Claude Code workflows can install it without rediscovering the failure mode.