Create worktrees and launch Claude Code agents. USE THIS SKILL when user says "create worktree", "spin up worktree", "new worktree", "worktree for X", or wants parallel development branches...
This skill helps manage parallel development using git worktrees with AI coding agents. Each worktree is an isolated copy of the repo on a different branch, allowing multiple Claude Code agents to work simultaneously without conflicts.
Trigger phrases:
The user wants to:
All worktrees MUST be created in the worktrees/ subdirectory relative to the repo root.
repo-root/
āāā worktrees/ # All worktrees go here
ā āāā feature/auth/ # Branch: feature/auth
ā āāā feature/payments/ # Branch: feature/payments
ā āāā fix/login-bug/ # Branch: fix/login-bug
āāā src/
āāā .claude/
āāā ...
NEVER create worktrees as sibling directories (e.g., ../repo-feature-auth). This breaks:
Correct:
git worktree add worktrees/feature/auth -b feature/auth
Wrong:
git worktree add ../repo-feature-auth -b feature/auth # NO!
.claude/skills/worktree-agents/
āāā SKILL.md # This file - instructions for Claude
āāā config.json # User preferences (terminal, shell, ports)
āāā scripts/
āāā launch-agent.sh # Opens terminal with Claude Code
āāā status.sh # Shows worktree overview
āāā register.sh # Adds worktree to registry
āāā unregister.sh # Removes from registry
āāā cleanup.sh # Full cleanup workflow
.claude/worktree-registry.json # Tracks active worktrees (in repo root)
| Task | Who Does It | How |
|---|---|---|
| Create git worktree | You | git worktree add worktrees/<branch> -b <branch> |
| Copy .agents/ directory | You | cp -r .agents worktrees/<branch>/ (for plans, RCAs, etc.) |
| Install dependencies | You | cd worktrees/<branch> && npm install |
| Run validation | You | npm run type-check && npm run lint && npm test |
| Pick next available port | You | Look at registry, find unused port in range |
| Register worktree | Script | scripts/register.sh <branch> <path> <port> [task] |
| Launch agent in terminal | Script | scripts/launch-agent.sh <path> [task] |
| Show status | Script | scripts/status.sh |
| Full cleanup | Script | scripts/cleanup.sh <branch> [--delete-branch] |
| Check PR status | You | gh pr list --head <branch> --json number,state |
| Decide what to clean | You | Check if PR merged, ask user if unsure |
Why: Uncommitted files (plans, RCA reports, PRPs) only exist in the source worktree. New worktrees start clean from git, so these files won't be there.
Always copy the .agents/ directory to new worktrees so the agent has access to:
.agents/plans/ - Implementation plans to execute.agents/rca-reports/ - Root cause analysis reports.agents/PRPs/ - Product requirement plans# After creating worktree, copy .agents/
cp -r .agents worktrees/<branch>/.agents
Ports are assigned from the configured range (default: 8124-8128).
To find next available port:
.claude/worktree-registry.jsonjq '.worktrees[].port' .claude/worktree-registry.jsonPort range (from config.json):
User says: "Spin up worktrees for feature/auth and feature/payments"
You do:
1. For each branch:
a. Find next available port (check registry)
b. Create worktree:
git worktree add worktrees/<branch> -b <branch>
c. Copy .agents/ directory (plans, RCAs, PRPs):
cp -r .agents worktrees/<branch>/.agents
d. Install dependencies:
cd worktrees/<branch> && npm install
e. Run validation (optional but recommended):
npm run type-check && npm run lint && npm test
f. Register:
scripts/register.sh <branch> worktrees/<branch> <port> "[task]"
g. Launch agent:
scripts/launch-agent.sh worktrees/<branch> "[task]"
2. Report summary to user
Example commands:
# Create worktrees
git worktree add worktrees/feature/auth -b feature/auth
git worktree add worktrees/feature/payments -b feature/payments
# Copy .agents/ directory (uncommitted plans, RCAs, etc.)
cp -r .agents worktrees/feature/auth/.agents
cp -r .agents worktrees/feature/payments/.agents
# Install deps
cd worktrees/feature/auth && npm install
cd worktrees/feature/payments && npm install
# Register (finds script in .claude/skills/worktree-agents/scripts/)
.claude/skills/worktree-agents/scripts/register.sh feature/auth worktrees/feature/auth 8124 "Implement OAuth"
.claude/skills/worktree-agents/scripts/register.sh feature/payments worktrees/feature/payments 8125 "Add Stripe"
# Launch agents
.claude/skills/worktree-agents/scripts/launch-agent.sh worktrees/feature/auth "Implement OAuth"
.claude/skills/worktree-agents/scripts/launch-agent.sh worktrees/feature/payments "Add Stripe"
User says: "What's the status?" or "Show my worktrees"
You do:
.claude/skills/worktree-agents/scripts/status.sh
This shows:
User says: "Launch an agent in the auth worktree"
You do:
# Find the worktree path
git worktree list | grep auth
# Launch
.claude/skills/worktree-agents/scripts/launch-agent.sh worktrees/feature/auth "Continue auth work"
User says: "Clean up the auth worktree" or "Clean up merged worktrees"
For single worktree:
# Check if PR is merged first
gh pr list --head feature/auth --state merged
# If merged (or user confirms), clean up
.claude/skills/worktree-agents/scripts/cleanup.sh feature/auth
# To also delete the git branch:
.claude/skills/worktree-agents/scripts/cleanup.sh feature/auth --delete-branch
For "merged" worktrees:
# Get list of registered worktrees
cat .claude/worktree-registry.json
# For each, check if PR is merged
gh pr list --head <branch> --state merged --json number
# Clean up those with merged PRs
.claude/skills/worktree-agents/scripts/cleanup.sh <branch> --delete-branch
Cleanup script handles:
Location: .claude/worktree-registry.json
{
"worktrees": [
{
"branch": "feature/auth",
"path": "worktrees/feature/auth",
"port": 8124,
"createdAt": "2025-12-02T10:00:00Z",
"agentLaunchedAt": "2025-12-02T10:05:00Z",
"task": "Implement OAuth login",
"prNumber": null
}
]
}
You update agentLaunchedAt after launching by re-running register.sh (it updates existing entries).
You update prNumber when you discover a PR exists:
# Check for PR
PR_NUM=$(gh pr list --head feature/auth --json number --jq '.[0].number')
# Update registry with jq
jq ".worktrees |= map(if .branch == \"feature/auth\" then .prNumber = $PR_NUM else . end)" \
.claude/worktree-registry.json > tmp.json && mv tmp.json .claude/worktree-registry.json
Location: .claude/skills/worktree-agents/config.json
{
"terminal": "ghostty", // ghostty, iterm2, or tmux
"shell": "fish", // fish, bash, or zsh
"claudeCommand": "cc", // command to launch Claude Code
"portRange": {
"start": 8124,
"end": 8128
}
}
Terminal options:
ghostty - Opens new Ghostty window (macOS)iterm2 - Opens new iTerm2 window (macOS)tmux - Creates new tmux session (cross-platform)./scripts/launch-agent.sh <worktree-path> [task-description]
# Examples:
./scripts/launch-agent.sh worktrees/feature/auth
./scripts/launch-agent.sh worktrees/feature/auth "Implement OAuth login"
./scripts/register.sh <branch> <path> <port> [task]
# Examples:
./scripts/register.sh feature/auth worktrees/feature/auth 8124
./scripts/register.sh feature/auth worktrees/feature/auth 8124 "Implement OAuth"
./scripts/unregister.sh <branch>
# Example:
./scripts/unregister.sh feature/auth
./scripts/cleanup.sh <branch> [--delete-branch]
# Examples:
./scripts/cleanup.sh feature/auth # Keep git branch
./scripts/cleanup.sh feature/auth --delete-branch # Delete branch too
./scripts/status.sh
Before cleaning up, check PR status:
Before deleting branches, confirm with user if:
Port conflicts: If a port is in use by a non-worktree process, pick a different port
Max 5 worktrees: The default port range only supports 5 concurrent worktrees
# Find what's using it
lsof -i :8124
# Kill if it's a stale process
kill -9 <PID>
# Check existing worktrees
git worktree list
# Remove if stale
git worktree remove worktrees/<branch> --force
git worktree prune
The git worktree command handles this:
# This tries -b (new branch) first, falls back to existing
git worktree add worktrees/<branch> -b <branch> 2>/dev/null || git worktree add worktrees/<branch> <branch>
# Compare registry to actual worktrees
cat .claude/worktree-registry.json
git worktree list
# Manually clean up stale entries
.claude/skills/worktree-agents/scripts/unregister.sh <stale-branch>
User: "Spin up 2 worktrees for feature/dark-mode and fix/login-bug, then launch agents"
You:
git worktree add worktrees/feature/dark-mode -b feature/dark-mode
git worktree add worktrees/fix/login-bug -b fix/login-bug
cp -r .agents worktrees/feature/dark-mode/.agents
cp -r .agents worktrees/fix/login-bug/.agents
cd worktrees/feature/dark-mode && npm install
cd worktrees/fix/login-bug && npm install
.claude/skills/worktree-agents/scripts/register.sh feature/dark-mode worktrees/feature/dark-mode 8124 "Implement dark mode toggle"
.claude/skills/worktree-agents/scripts/register.sh fix/login-bug worktrees/fix/login-bug 8125 "Fix login redirect bug"
.claude/skills/worktree-agents/scripts/launch-agent.sh worktrees/feature/dark-mode "Implement dark mode toggle"
.claude/skills/worktree-agents/scripts/launch-agent.sh worktrees/fix/login-bug "Fix login redirect bug"
Created 2 worktrees with agents:
| Branch | Port | Task |
|--------|------|------|
| feature/dark-mode | 8124 | Implement dark mode toggle |
| fix/login-bug | 8125 | Fix login redirect bug |
Both agents are now running in separate Ghostty windows.
.agents/ directory copied to each worktree.