TimZander / TimZander/claude

skill: /tidy-worktrees — audit and remove worktrees whose PRs have merged

Open
#215 1 comment 0 reactions 0 assignees View on GitHub

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:

  1. The decision needs a gh fan-out that docs cannot perform. Under squash-merge git branch --merged reports every merged branch as unmerged (see #214), so the only reliable signal is one gh pr list --head <branch> call per worktree. That is a multi-step tool sequence, which is the skill trigger.
  2. A documented manual procedure demonstrably does not get run. The repo above documents worktree discipline carefully — mandating worktrees, giving the exact git worktree add invocation, warning about nesting — and still reached 11 stale worktrees.
  3. 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 main or the pinned core.hooksPath stops resolving); never remove a dirty tree; use -D deliberately rather than habitually.

Proposed behaviour

/tidy-worktrees [--yes] [--include-closed]

Default is a dry-run report — never destructive without confirmation.

  1. Enumerate via git worktree list --porcelain, resolving each to its branch.
  2. Skip the primary checkout and the current worktree, always, and say so in the output.
  3. For each remaining worktree, resolve PR state: gh pr list --head <branch> --state all --json number,state.
  4. Check git -C <worktree> status --porcelain; anything dirty is excluded and reported, never force-removed.
  5. Classify:
    • MERGED → proposed for removal
    • CLOSED → listed but not proposed unless --include-closed (abandoned work may still be wanted)
    • OPEN / no PR → listed as active, never proposed
  6. Print a table, confirm via AskUserQuestion, then per approved entry: git worktree removegit branch -Dgit worktree prune once at the end.

Acceptance criteria

  • Dry-run by default; no destructive command runs before explicit confirmation
  • Correctly identifies squash-merged branches that git branch --merged misses
  • 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 prune runs 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

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.