From amolk
Safely remove stale git worktrees under ~/work/**/.claude/worktrees behind data-loss guardrails (clean tree, not active, not locked, PR merged or zero unique commits). Use for worktree cleanup, pruning merged/finished worktrees, or running a nightly worktree-cleanup routine.
How this skill is triggered — by the user, by Claude, or both
Slash command
/amolk:worktree-cleanupThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
Prunes git worktrees created under `<repo>/.claude/worktrees/` that are finished
Prunes git worktrees created under <repo>/.claude/worktrees/ that are finished
and safe to delete. Branch refs are always kept, so every removal is reversible.
The deterministic work lives in worktree-cleanup.sh.
Do not reimplement the logic inline; call the script. It is the single source of
truth so an unattended routine and an interactive run behave identically.
A worktree is removed only if all of these hold; otherwise it is kept:
.../.claude/worktrees/. The primary
working tree, and anything outside that dir, is never touched.git worktree's locked flag is respected.lsof -d cwd). This is what stops you from deleting a worktree another
Claude/editor/dev-server session is sitting in.--min-idle-hours hours (default 72).
"Touched" is the newest of: its top-level file mtimes, its per-worktree git
activity (index/reflog/checkout/fetch), and its HEAD commit time. Catches
"finished and clean, but someone was just in it." No full-tree walk, so
node_modules neither slows it down nor falsely keeps it alive.git status --porcelain is empty, untracked files included.
Uncommitted work is the only truly unrecoverable loss, so a dirty tree is an
automatic keep.gh, whose headRefOid is frozen at merge time,
so this is exact even under squash-merge), or the branch has zero unique
commits vs the default branch. A branch whose session continued after a
merge — commits sitting past the last merged PR with no newer PR yet — is
kept, because that's unreviewed in-progress work, not finished work.Never --force. Never delete branches. If git worktree remove itself refuses
(its own dirty/lock backstop), the worktree is kept and the refusal is logged.
Failure mode is conservative by design. If gh is unreachable or auth fails,
a branch with commits falls through to "unmerged, kept" — a gh outage can only
cause under-deletion, never data loss.
Recover a wrongly-removed worktree: git -C <repo> worktree add <path> <branch>.
| Decision | Worktree | Reason |. Whole tree, or one repo:
${CLAUDE_SKILL_DIR}/worktree-cleanup.sh
${CLAUDE_SKILL_DIR}/worktree-cleanup.sh --repo ~/work/karta
--dry-run is an explicit no-mutation alias producing the same table (it wins
if combined with --remove). In --remove mode the Decision column reads
REMOVED / REFUSED so the same table doubles as the action log.PR #N MERGED but K commit(s) added since are kept on
purpose — that's a session continued after its merge; resolve those by opening
the follow-up PR (or dropping the commits), not by deleting the worktree.--remove:
${CLAUDE_SKILL_DIR}/worktree-cleanup.sh --repo ~/work/karta --remove
--remove re-evaluates every guardrail fresh, so nothing that became dirty or
active between preview and removal is touched.KEEP=… REMOVE=… removed=… refused=…).Run with --remove directly; the table is the action log (Decision = REMOVED/REFUSED):
${CLAUDE_SKILL_DIR}/worktree-cleanup.sh --remove
Safe without sign-off: it only removes clean, inactive, idle, merged-or-empty worktrees, and keeps branch refs.
To run it on a schedule, create a LaunchAgent (the scheduled-jobs skill in this
plugin does this for you). Two things matter for an unattended run:
/opt/homebrew/bin) — a
launchd job's default PATH omits it, and a missing gh makes every merged branch
look un-merged. (scheduled-jobs create bakes this in.)gh token in the macOS keychain is reachable. Outside a session pass GH_TOKEN.
Either way the failure mode is conservative: no gh = under-deletion, never data loss.macOS only (lsof, BSD date/stat).
origin/HEAD, falling back to main/master.Creates, edits, and optimizes skills for Claude Code, including drafting, evaluating with test prompts, iterating on performance, and improving skill descriptions for better triggering accuracy.
npx claudepluginhub amolk/claude-skills --plugin amolk