skill: /tidy-worktrees — audit and remove worktrees whose PRs have merged
Nobody has claimed this yet.
- Dominant language
- Python
- Stars
- 0
- Forks
- 1
- Avg merge
- 1d 3h
- Merged PRs (30d)
- 7
Description
Problem
Nothing closes the loop after a PR merges. /start-work creates a worktree and branch; /craft-pr is described as its bookend but ships the work rather than cleaning up after it. The result is unbounded accumulation.
Measured in TimZander/AudioClassifier on 2026-08-05, right after merging a PR:
12 worktrees: 10 MERGED PRs, 1 CLOSED PR, 1 OPEN PR (55 MB)
11 of 12 stale. All clean — no uncommitted work anywhere — so cleanup was safe the whole time and simply never happened.
Why a skill rather than documentation
Companion issue #214 adds the rule to standards/CLAUDE.md. This issue is the execution, and they are not substitutes:
- The decision needs a
ghfan-out that docs cannot perform. Under squash-mergegit branch --mergedreports every merged branch as unmerged (see #214), so the only reliable signal is onegh pr list --head <branch>call per worktree. That is a multi-step tool sequence, which is the skill trigger. - A documented manual procedure demonstrably does not get run. The repo above documents worktree discipline carefully — mandating worktrees, giving the exact
git worktree addinvocation, warning about nesting — and still reached 11 stale worktrees. - The safety conditions are easy to get wrong by hand. Never remove the current worktree; never remove the primary (in that repo the primary must stay on
mainor the pinnedcore.hooksPathstops resolving); never remove a dirty tree; use-Ddeliberately rather than habitually.
Proposed behaviour
/tidy-worktrees [--yes] [--include-closed]
Default is a dry-run report — never destructive without confirmation.
- Enumerate via
git worktree list --porcelain, resolving each to its branch. - Skip the primary checkout and the current worktree, always, and say so in the output.
- For each remaining worktree, resolve PR state:
gh pr list --head <branch> --state all --json number,state. - Check
git -C <worktree> status --porcelain; anything dirty is excluded and reported, never force-removed. - Classify:
MERGED→ proposed for removalCLOSED→ listed but not proposed unless--include-closed(abandoned work may still be wanted)OPEN/ no PR → listed as active, never proposed
- Print a table, confirm via
AskUserQuestion, then per approved entry:git worktree remove→git branch -D→git worktree pruneonce at the end.
Acceptance criteria
- Dry-run by default; no destructive command runs before explicit confirmation
- Correctly identifies squash-merged branches that
git branch --mergedmisses - Refuses to touch the current worktree, the primary checkout, or any dirty worktree — each refusal reported with its reason
-
CLOSED-PR and no-PR worktrees are never removed by default -
git worktree pruneruns once after removals, not per-iteration - Output names each worktree, its branch, its PR number and state, and the action taken or why it was skipped
- Handles the no-
gh/unauthenticated case by reporting rather than falling back to a guess - Works from inside a worktree (the common case — you have just merged and are still standing in it)
Non-goals
- Deleting remote branches. Hosts auto-delete on merge, and this should not race that.
- Anything touching a branch with no merged PR. Discovering abandoned work is a different job.
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start by reading the existing /start-work and /craft-pr entry points and the worktree guidance in standards/CLAUDE.md. Trace how a new /tidy-worktrees skill can use git worktree list --porcelain, git status, and gh pr list. Done means the acceptance criteria are met, including dry-run confirmation, safety skips, PR-state reporting, and one final prune.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- git, github
- Domain
- developer-experience, tooling
- Issue type
- Feature
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Mostly clear
- Newbie friendliness
- 52/100