Agent Skills: Clean worktrees

Reclaim worktrees after features land — remove every merged worktree in the repo (ca/sa/ha and any other, regardless of location) and delete their merged branches. Use once a ca PR is merged. Safe by default — never removes a worktree with uncommitted changes, never deletes an unmerged branch, and never touches the main checkout (it removes the current worktree too, but only if its branch is merged). Invoke explicitly with /ca:clean-worktrees.

UncategorizedID: ken2403/.claude-paralell-dev-plugin/clean-worktrees

Install this agent skill to your local

pnpm dlx add-skill https://github.com/ken2403/claude-parallel-dev-plugin/tree/HEAD/ha/skills/clean-worktrees

Skill Files

Browse the full folder contents for clean-worktrees.

Download Skill

Loading file tree…

ha/skills/clean-worktrees/SKILL.md

Skill Metadata

Name
clean-worktrees
Description
Reclaim worktrees after features land — remove every merged worktree in the repo (ha/sa/ca and any other, regardless of location) and delete their merged branches. Use once a feature PR is merged. Safe by default — never removes a worktree with uncommitted changes, never deletes an unmerged branch, and never touches the main checkout (it removes the current worktree too, but only if its branch is merged). Invoke explicitly with /ha:clean-worktrees.

Clean worktrees

Input

$ARGUMENTS

Worktrees accumulate and each consumes disk, so reclaim them once their work has landed. This command is repo-wide: it cleans every merged worktree in git worktree list regardless of location (ha/sa/ca and any other), so a single run reclaims them all. The hard rule: never destroy work that hasn't been merged. A leftover worktree is cheap; a deleted unmerged branch is lost work. The main checkout is always preserved; the current worktree is removed too if its branch is merged.

Context (auto-injected)

  • Worktrees: !git worktree list 2>/dev/null
  • Merged branches: !gh pr list --state merged --json number,headRefName --jq '.[].headRefName' 2>/dev/null

Step 1 — Decide the scope

Default is repo-wide. Unless the user named specific feature ids/branches in $ARGUMENTS, clean every merged worktree in the whole repo — ha, sa, ca, and any other, regardless of location. Do not narrow to .claude/worktrees/ha/ just because this is the ha command; a single run of any of the three cleans them all. Only when $ARGUMENTS names specific targets do you scope to those.

A worktree/branch is cleanable only if its PR is MERGED (confirm via gh pr list --state merged, or, after CLAUDE_SKILL_HA_DIR="${CLAUDE_SKILL_DIR}", bash "$CLAUDE_SKILL_HA_DIR/scripts/merge-check.sh"), or there is no PR and the user explicitly asked to abandon it. If a PR is still OPEN, skip it and say why.

Step 2 — Remove (delegate to the script — single source of truth)

Don't run removals inline; the script owns the guardrails in one place. With no $ARGUMENTS, pass all-merged so it sweeps the entire repo; pass a specific <branch>/name only when the user named one:

CLAUDE_SKILL_HA_DIR="${CLAUDE_SKILL_DIR}"
# no target given → clean EVERY merged worktree repo-wide (ha/sa/ca and any other):
bash "$CLAUDE_SKILL_HA_DIR/scripts/clean.sh" all-merged
# or, only when the user named specific targets:
# bash "$CLAUDE_SKILL_HA_DIR/scripts/clean.sh" "<branch>"

clean.sh considers every worktree in git worktree list (any path), uses git worktree remove without --force (uncommitted changes ⇒ skip + report), and git branch -d (never -D). It never removes the main checkout (it removes the current worktree too, only if merged), syncs the base branch with origin before deciding, and git worktree prunes at the end — the cleanup guardrails from superpowers:finishing-a-development-branch.

Two more rules the script owns: a merged worktree still locked by a dead claude session (claude session ... (pid N) whose pid is gone) is unlocked and removed — any other lock is an absolute barrier and is only reported. And orphan directories under .claude/worktrees/ that are no longer registered worktrees are removed when empty, reported (never deleted) when they still have content.

Step 3 — Report

| feature | branch | PR | action | skipped (reason) |
|---------|--------|----|--------|------------------|

result: cleaned <n> landed features; skipped <m> (unmerged / changes present).