---
name: stale-worktree-cleaner
description: Identifies stale git worktrees in .claude/worktrees/ and the workspace, including [gone] tracking refs and merged branches. Produces a per-worktree cleanup plan; user confirms each git worktree remove individually before any destructive operation.
---

# Foxhunt Stale Worktree Cleaner

Destructive op — explicit invoke only, with per-action user confirmation.

## When to invoke

- "Clean stale worktrees".
- Periodically when `.claude/worktrees/` has many entries.

## What this skill does

1. **Enumerate** all worktrees:
   ```bash
   git worktree list
   ls -la .claude/worktrees/
   ```

2. **For each worktree**, classify staleness:

   | Class | Detection |
   |---|---|
   | NO-COMMITS | No commits in N days (default 30); branch unchanged |
   | GONE | Tracking ref `[gone]` (deleted upstream) — `git fetch -p` then `git branch -vv` |
   | MERGED | Branch fully merged into `main` (`git merge-base --is-ancestor`) |
   | UNCOMMITTED | Has uncommitted changes — DO NOT propose cleanup; flag only |
   | ACTIVE | Recent commits, not merged, tracking ref alive |

3. **Produce a per-worktree cleanup plan**:

   ```
   [stale-worktree-cleaner] enumerated <N> worktrees

   Class NO-COMMITS (<K> entries):
   1. <path> — branch <name>, last commit <date>, status <merged|alive>
      Action: git worktree remove <path>; git branch -d <name>

   Class GONE (<K> entries):
   ...

   Class UNCOMMITTED (<K> entries — flag only, no action proposed):
   ...
   ```

4. **Confirm each action individually** before running. Never bulk-execute.

## Discipline

- **NEVER `git worktree remove --force` without confirmation.** `--force` discards uncommitted work.
- **NEVER `git branch -D`** (force delete) — only `git branch -d` (allows refusal on unmerged).
- **Compose the existing `commit-commands:clean_gone` skill** when applicable (it handles GONE-class branches).
- **NetBird/Tailscale/CI worktrees** (if any) — leave alone unless explicitly named by the user.
- **Worktrees referenced by a running agent** must not be removed. Check `.claude/worktrees/*` against any active session metadata.

## Output format

```
[stale-worktree-cleaner] proposal:

Will remove (after your per-item confirmation):
- <path 1> [<class>] — <why>
- <path 2> [<class>] — <why>

Skipped (require manual review):
- <path 3> [UNCOMMITTED] — has unstaged changes
```

User confirms each removal individually before any destructive command runs.
