Superpowers automatically manages the lifecycle of git worktrees, ensuring they're cleaned up when no longer needed.
When using-git-worktrees creates a worktree, it registers it in ~/.config/superpowers/worktree-registry.json:
{
"id": "wt_1234567890_feature_auth",
"path": "/tmp/worktrees/feature-auth",
"branch": "feature/auth-system",
"project_root": "/Users/jason/myapp",
"created_at": "2026-03-10T10:00:00Z",
"status": "active"
}Worktrees progress through these states:
- active - Currently in development
- pr_opened - Pull request has been opened
- merged - Branch has been merged to main
- abandoned - Branch was deleted without merging
- cleanup_pending - Scheduled for garbage collection
The garbage collection daemon (or manual detection) checks:
- Does the branch still exist?
- Is there an open PR for this branch?
- Has the PR been merged?
Cleanup only happens when:
- Status is
cleanup_pending - Worktree has no uncommitted changes
- Delay period has passed (default: 1 hour for merged, immediate for abandoned)
# macOS: Create a proper LaunchAgent plist
cat > ~/Library/LaunchAgents/com.superpowers.worktree-gc.plist << 'EOF'
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>Label</key>
<string>com.superpowers.worktree-gc</string>
<key>ProgramArguments</key>
<array>
<string>/bin/bash</string>
<string>-c</string>
<string>$HOME/.config/superpowers/lib/worktree-gc-daemon</string>
</array>
<key>RunAtLoad</key>
<true/>
<key>KeepAlive</key>
<false/>
</dict>
</plist>
EOF
launchctl load ~/Library/LaunchAgents/com.superpowers.worktree-gc.plist
# Linux: Append to existing crontab (preserves existing entries)
(crontab -l 2>/dev/null; echo "@reboot $HOME/.config/superpowers/lib/worktree-gc-daemon") | crontab -To prevent log file growth, add this to /etc/logrotate.d/superpowers-worktree-gc:
$HOME/.config/superpowers/worktree-gc.log {
weekly
rotate 4
compress
missingok
notifempty
}
For automatic cleanup after merge:
# In your repository
cp ~/.config/superpowers/lib/hooks/post-merge .git/hooks/
chmod +x .git/hooks/post-merge# List worktrees for current project
~/.config/superpowers/lib/worktree-manager list
# Check for status changes
~/.config/superpowers/lib/worktree-manager detect
# Run garbage collection manually
~/.config/superpowers/lib/worktree-manager gc
# Force cleanup of specific worktree
~/.config/superpowers/lib/worktree-manager unregister <id>Edit ~/.config/superpowers/worktree-registry.json:
{
"metadata": {
"gc_policy": {
"enabled": true,
"interval_hours": 1,
"cleanup_delay_hours": 24,
"max_age_days": 30
}
}
}- enabled: Turn GC on/off
- interval_hours: How often to check for cleanup
- cleanup_delay_hours: Grace period after merge
- max_age_days: Auto-cleanup worktrees older than this
- Never deletes worktrees with uncommitted changes
- Never deletes active worktrees
- Always provides grace period for merged branches
- Logs all cleanup actions to
~/.config/superpowers/worktree-gc.log
When you use the finishing-a-development-branch skill:
- If merging locally, post-merge hook triggers cleanup
- If creating PR, worktree status updates to
pr_opened - When PR is merged, GitHub webhook (future) or GC daemon detects and schedules cleanup
# Check status
~/.config/superpowers/lib/worktree-manager find <branch>
# Manually mark for cleanup
~/.config/superpowers/lib/worktree-manager update <id> cleanup_pending
# Run GC
~/.config/superpowers/lib/worktree-manager gcCheck logs:
cat ~/.config/superpowers/worktree-gc.logThe registry maintains history of all worktrees created.