A manager for creating and syncing git worktrees across multiple projects to enable parallel development.
Install
mkdir -p .claude/skills/worktree-manager-wirasm && curl -L -o skill.zip "https://agentskills.codes/api/skills/download/11876" && unzip -o skill.zip -d .claude/skills/worktree-manager-wirasm && rm skill.zipInstalls to .claude/skills/worktree-manager-wirasm
Activation
This is the description your AI agent reads to decide when to run this skill — the better it matches your request, the more reliably it fires.
Create, manage, and cleanup git worktrees with Claude Code agents across all projects. USE THIS SKILL when user says "create worktree", "spin up worktrees", "new worktree for X", "worktree status", "cleanup worktrees", "sync worktrees", or wants parallel development branches. Also use when creating PRs from a worktree branch (to update registry with PR number). Handles worktree creation, dependency installation, validation, agent launching in Ghostty, and global registry management.Key capabilities
- →Create Git worktrees for parallel development
- →Manage a global registry of worktrees across projects
- →Allocate unique port numbers for each worktree
- →Install dependencies within new worktrees
- →Clean up merged or orphaned worktrees
How it works
The skill creates and manages Git worktrees, tracks them in a global registry, allocates unique ports, and installs dependencies to facilitate parallel development.
Inputs & outputs
When to use worktree-manager
- →Spin up multiple worktrees for parallel work
- →Clean up merged worktrees
- →Launch agents in a specific worktree
- →Sync worktree registry
About this skill
Global Worktree Manager
Manage parallel development across ALL projects using git worktrees with Claude Code agents. Each worktree is an isolated copy of the repo on a different branch, stored centrally at ~/tmp/worktrees/.
IMPORTANT: You (Claude) can perform ALL operations manually using standard tools (jq, git, bash). Scripts are helpers, not requirements. If a script fails, fall back to manual operations described in this document.
When This Skill Activates
Trigger phrases:
- "spin up worktrees for X, Y, Z"
- "create 3 worktrees for features A, B, C"
- "new worktree for feature/auth"
- "what's the status of my worktrees?"
- "show all worktrees" / "show worktrees for this project"
- "clean up merged worktrees"
- "clean up the auth worktree"
- "launch agent in worktree X"
- "sync worktrees" / "sync worktree registry"
- "create PR" (when in a worktree - updates registry with PR number)
File Locations
| File | Purpose |
|---|---|
~/.claude/worktree-registry.json | Global registry - tracks all worktrees across all projects |
~/.claude/skills/worktree-manager/config.json | Skill config - terminal, shell, port range settings |
~/.claude/skills/worktree-manager/scripts/ | Helper scripts - optional, can do everything manually |
~/tmp/worktrees/ | Worktree storage - all worktrees live here |
.claude/worktree.json (per-project) | Project config - optional custom settings |
Core Concepts
Centralized Worktree Storage
All worktrees live in ~/tmp/worktrees/<project-name>/<branch-slug>/
~/tmp/worktrees/
├── obsidian-ai-agent/
│ ├── feature-auth/ # branch: feature/auth
│ ├── feature-payments/ # branch: feature/payments
│ └── fix-login-bug/ # branch: fix/login-bug
└── another-project/
└── feature-dark-mode/
Branch Slug Convention
Branch names are slugified for filesystem safety by replacing / with -:
feature/auth→feature-authfix/login-bug→fix-login-bugfeat/user-profile→feat-user-profile
Slugify manually: echo "feature/auth" | tr '/' '-' → feature-auth
Port Allocation Rules
- Global pool: 8100-8199 (100 ports total)
- Per worktree: 2 ports allocated (for API + frontend patterns)
- Globally unique: Ports are tracked globally to avoid conflicts across projects
- Check before use: Always verify port isn't in use by system:
lsof -i :<port>
Global Registry
Location
~/.claude/worktree-registry.json
Schema
{
"worktrees": [
{
"id": "unique-uuid",
"project": "obsidian-ai-agent",
"repoPath": "/Users/rasmus/Projects/obsidian-ai-agent",
"branch": "feature/auth",
"branchSlug": "feature-auth",
"worktreePath": "/Users/rasmus/tmp/worktrees/obsidian-ai-agent/feature-auth",
"ports": [8100, 8101],
"createdAt": "2025-12-04T10:00:00Z",
"validatedAt": "2025-12-04T10:02:00Z",
"agentLaunchedAt": "2025-12-04T10:03:00Z",
"task": "Implement OAuth login",
"prNumber": null,
"status": "active"
}
],
"portPool": {
"start": 8100,
"end": 8199,
"allocated": [8100, 8101]
}
}
Field Descriptions
Worktree entry fields:
| Field | Type | Description |
|---|---|---|
id | string | Unique identifier (UUID) |
project | string | Project name (from git remote or directory) |
repoPath | string | Absolute path to original repository |
branch | string | Full branch name (e.g., feature/auth) |
branchSlug | string | Filesystem-safe name (e.g., feature-auth) |
worktreePath | string | Absolute path to worktree |
ports | number[] | Allocated port numbers (usually 2) |
createdAt | string | ISO 8601 timestamp |
validatedAt | string|null | When validation passed |
agentLaunchedAt | string|null | When agent was launched |
task | string|null | Task description for the agent |
prNumber | number|null | Associated PR number if exists |
status | string | active, orphaned, or merged |
Port pool fields:
| Field | Type | Description |
|---|---|---|
start | number | First port in pool (default: 8100) |
end | number | Last port in pool (default: 8199) |
allocated | number[] | Currently allocated ports |
Manual Registry Operations
Read entire registry:
cat ~/.claude/worktree-registry.json | jq '.'
List all worktrees:
cat ~/.claude/worktree-registry.json | jq '.worktrees[]'
List worktrees for specific project:
cat ~/.claude/worktree-registry.json | jq '.worktrees[] | select(.project == "my-project")'
Get allocated ports:
cat ~/.claude/worktree-registry.json | jq '.portPool.allocated'
Find worktree by branch (partial match):
cat ~/.claude/worktree-registry.json | jq '.worktrees[] | select(.branch | contains("auth"))'
Add worktree entry manually:
TMP=$(mktemp)
jq '.worktrees += [{
"id": "'$(uuidgen)'",
"project": "my-project",
"repoPath": "/path/to/repo",
"branch": "feature/auth",
"branchSlug": "feature-auth",
"worktreePath": "/Users/me/tmp/worktrees/my-project/feature-auth",
"ports": [8100, 8101],
"createdAt": "'$(date -u +%Y-%m-%dT%H:%M:%SZ)'",
"validatedAt": null,
"agentLaunchedAt": null,
"task": "My task",
"prNumber": null,
"status": "active"
}]' ~/.claude/worktree-registry.json > "$TMP" && mv "$TMP" ~/.claude/worktree-registry.json
Add ports to allocated pool:
TMP=$(mktemp)
jq '.portPool.allocated += [8100, 8101] | .portPool.allocated |= unique | .portPool.allocated |= sort_by(.)' \
~/.claude/worktree-registry.json > "$TMP" && mv "$TMP" ~/.claude/worktree-registry.json
Remove worktree entry:
TMP=$(mktemp)
jq 'del(.worktrees[] | select(.project == "my-project" and .branch == "feature/auth"))' \
~/.claude/worktree-registry.json > "$TMP" && mv "$TMP" ~/.claude/worktree-registry.json
Release ports from pool:
TMP=$(mktemp)
jq '.portPool.allocated = (.portPool.allocated | map(select(. != 8100 and . != 8101)))' \
~/.claude/worktree-registry.json > "$TMP" && mv "$TMP" ~/.claude/worktree-registry.json
Initialize empty registry (if missing):
mkdir -p ~/.claude
cat > ~/.claude/worktree-registry.json << 'EOF'
{
"worktrees": [],
"portPool": {
"start": 8100,
"end": 8199,
"allocated": []
}
}
EOF
Manual Port Allocation
If scripts/allocate-ports.sh fails, allocate ports manually:
Step 1: Get currently allocated ports
ALLOCATED=$(cat ~/.claude/worktree-registry.json | jq -r '.portPool.allocated[]' | sort -n)
echo "Currently allocated: $ALLOCATED"
Step 2: Find first available port (not in allocated list AND not in use by system)
for PORT in $(seq 8100 8199); do
# Check if in registry
if ! echo "$ALLOCATED" | grep -q "^${PORT}$"; then
# Check if in use by system
if ! lsof -i :"$PORT" &>/dev/null; then
echo "Available: $PORT"
break
fi
fi
done
Step 3: Add to allocated pool
TMP=$(mktemp)
jq '.portPool.allocated += [8100] | .portPool.allocated |= unique | .portPool.allocated |= sort_by(.)' \
~/.claude/worktree-registry.json > "$TMP" && mv "$TMP" ~/.claude/worktree-registry.json
What You (Claude) Do vs What Scripts Do
| Task | Script Available | Manual Fallback |
|---|---|---|
| Determine project name | No | Parse git remote get-url origin or basename $(pwd) |
| Detect package manager | No | Check for lockfiles (see Detection section) |
| Create git worktree | No | git worktree add <path> -b <branch> |
| Copy .agents/ directory | No | cp -r .agents <worktree-path>/ |
| Install dependencies | No | Run detected install command |
| Validate (health check) | No | Start server, curl endpoint, stop server |
| Allocate ports | scripts/allocate-ports.sh 2 | Manual (see above) |
| Register worktree | scripts/register.sh | Manual jq (see above) |
| Launch agent in terminal | scripts/launch-agent.sh | Manual (see below) |
| Show status | scripts/status.sh | cat ~/.claude/worktree-registry.json | jq ... |
| Cleanup worktree | scripts/cleanup.sh | Manual (see Cleanup section) |
Workflows
1. Create Multiple Worktrees with Agents
User says: "Spin up 3 worktrees for feature/auth, feature/payments, and fix/login-bug"
You do (can parallelize with subagents):
For EACH branch (can run in parallel):
1. SETUP
a. Get project name:
PROJECT=$(basename $(git remote get-url origin 2>/dev/null | sed 's/\.git$//') 2>/dev/null || basename $(pwd))
b. Get repo root:
REPO_ROOT=$(git rev-parse --show-toplevel)
c. Slugify branch:
BRANCH_SLUG=$(echo "feature/auth" | tr '/' '-')
d. Determine worktree path:
WORKTREE_PATH=~/tmp/worktrees/$PROJECT/$BRANCH_SLUG
2. ALLOCATE PORTS
Option A (script): ~/.claude/skills/worktree-manager/scripts/allocate-ports.sh 2
Option B (manual): Find 2 unused ports from 8100-8199, add to registry
3. CREATE WORKTREE
mkdir -p ~/tmp/worktrees/$PROJECT
git worktree add $WORKTREE_PATH -b $BRANCH
# If branch exists already, omit -b flag
4. COPY UNCOMMITTED RESOURCES
cp -r .agents $WORKTREE_PATH/ 2>/dev/null || true
cp .env.example $WORKTREE_PATH/.env 2>/dev/null || true
5. INSTALL DEPENDENCIES
cd $WORKTREE_PATH
# Detect and run: npm install / uv sync / etc.
6. VALIDATE (start server, health check, stop)
a. Start server with allocated port
b. Wait and health check: curl -sf http://localhost:$PORT/health
c. Stop server
d. If FAILS: report error but continue with other worktrees
7. REGISTER IN GLOBAL REGISTRY
Option A (script): ~/.claude/skills/worktree-manager/scripts/register.sh ...
Option B (manual): Update ~/.claude/worktree-registry.json with jq
8. LAUNCH AGENT
Option A (s
---
*Content truncated.*
When not to use it
- →When only a single development branch is needed
- →When manual worktree management is preferred
- →When port allocation is not required for worktrees
Limitations
- →All worktrees are stored in `~/tmp/worktrees/`.
- →Port allocation is from a global pool of 8100-8199.
- →Branch names are slugified for filesystem safety.
How it compares
This skill centralizes worktree management, including global registry tracking and automated port allocation, providing a more organized and efficient way to handle parallel development than manual Git commands.
Compared to similar skills
worktree-manager side by side with the closest alternatives in the catalog.
| Skill | Installs | Updated | Safety | Difficulty |
|---|---|---|---|---|
| worktree-manager (this skill) | 0 | 7mo | Caution | Advanced |
| bash-linux | 7 | 6mo | Review | Intermediate |
| create-worktree-skill | 2 | 9mo | No flags | Intermediate |
| domain-dns-ops | 2 | 2mo | Review | Intermediate |
Try saying
Example prompts that trigger this skill in your AI assistant.
You might also like
bash-linux
davila7
Bash/Linux terminal patterns. Critical commands, piping, error handling, scripting. Use when working on macOS or Linux systems.
create-worktree-skill
disler
Use when the user explicitly asks for a SKILL to create a worktree. If the user does not mention "skill" or explicitly request skill invocation, do NOT trigger this. Only use when user says things like "use a skill to create a worktree" or "invoke the worktree skill". Creates isolated git worktrees with parallel-running configuration.
domain-dns-ops
steipete
Domain/DNS ops across Cloudflare, DNSimple, Namecheap for Peter. Use for onboarding zones to Cloudflare, flipping nameservers, setting redirects (Page Rules/Rulesets/Workers), updating redirect-worker mappings, and verifying DNS/HTTP. Source of truth: ~/Projects/manager.
moai-workflow-worktree
modu-ai
Git worktree management for parallel SPEC development with isolated workspaces, automatic registration, and seamless MoAI-ADK integration
k8s-operations
rohitg00
kubectl operations for applying, patching, deleting, and executing commands on Kubernetes resources. Use when modifying resources, running commands in pods, or managing resource lifecycle.
makefile-dev-workflow
raphaelmansuy
Unified development workflow for EdgeQuake using Makefile commands. Use when starting services, running tests, or managing the full development stack (database, backend, frontend). Provides simplified alternatives to raw cargo/npm commands.