AgentStack
Browse Sign in
Browse Why AgentStack Sell Docs
Sign in
SKILL verified MIT Self-run

Worktree Cleanup

skill-marcoskichel-empire-worktree-cleanup · by marcoskichel

>

No reviews yet
0 installs
8 views
0.0% view→install

Install

$ agentstack add skill-marcoskichel-empire-worktree-cleanup

✓ scanned · ✓ verified, works with Claude Code, Cursor, and more.

Security review

✓ Passed

No issues found. Passed automated security review. · v0.1.0 How review works →

  • Prompt-injection patterns
  • Secret / credential exfiltration
  • Dangerous shell & filesystem operations
  • Untrusted network calls
  • Known-malicious package signatures

What it can access

  • Network access No
  • Filesystem access No
  • Shell / process execution No
  • Environment & secrets No
  • Dynamic code execution No

From automated source analysis of v0.1.0. “Used” means the capability is present in the source — more access means more to trust, not that it’s unsafe.

View the full security report →

Verified badge

Passed review? Show it. Paste this badge into your README, it links to the public security report.

AgentStack Verified badge Links to your public security report.
[![AgentStack Verified](https://agentstack.voostack.com/badges/verified.svg)](https://agentstack.voostack.com/security/report/skill-marcoskichel-empire-worktree-cleanup)

Reliability & compatibility

Security review passed
0 installs to date
no reviews yet
1mo ago

Declared compatibility

Claude CodeClaude Desktop

Compatibility is declared by the source manifest. End-to-end runtime verification is coming, see below.

Preview Execution monitoring

We're building live execution health for every listing: tool-call success rate, median latency, uptime, and last-checked timestamps, measured, not self-reported. It isn't live yet, so we don't show numbers we can't stand behind.

How agent discovery & health will work →
Are you the author of Worktree Cleanup? Claim this listing to set pricing, connect Stripe payouts, and keep 70% of every sale.
Sign up to claim

About

Worktree Cleanup

Scan for stale worktrees and orphaned branches, then let the user decide what to clean up. This is the batch housekeeping counterpart to /empire-git:worktree-close (which handles one worktree at a time).

User input: $ARGUMENTS

If --dry-run is in the arguments, report what would be cleaned up without making any changes.

If --days N is in the arguments (e.g. --days 14), use N as the staleness threshold. Otherwise default to 7 days. Note: worktree-list uses a softer 3-day threshold (informational warning); cleanup uses 7 days because removal is the action and the longer window reduces false positives.

Step 1 — Inventory worktrees

git worktree list --porcelain

For each worktree (excluding the main working tree), gather:

  • Branch name
  • Path on disk — verify the directory still exists
  • Last commit date:

``bash git -C "" log -1 --format="%ct" 2>/dev/null ``

  • Dirty/clean status:

``bash git -C "" status --porcelain 2>/dev/null | wc -l | tr -d ' ' ``

Classify each worktree:

| Status | Criteria | | ----------- | ------------------------------------------------------------------------------ | | Stale | Last commit more than --days (default 7) ago and clean (no uncommitted work) | | Missing | Directory no longer exists on disk (stale git metadata) | | Active | Recent commits or has uncommitted changes |

Step 2 — Find stale local branches

First, prune remote-tracking references so git knows which remote branches are gone:

git fetch --prune

Determine which branches must never be flagged as orphans:

# The repo's default branch (main, master, develop, trunk, …) — detected, not assumed
DEFAULT_BRANCH=$(git symbolic-ref --short refs/remotes/origin/HEAD 2>/dev/null | sed 's|^origin/||')
# Fallback 1: check well-known branch names
[ -z "$DEFAULT_BRANCH" ] && DEFAULT_BRANCH=$(git for-each-ref --format='%(refname:short)' refs/heads/main refs/heads/master refs/heads/trunk refs/heads/develop | head -n1)
# Fallback 2: use current HEAD (guaranteed as long as we are in a git repo)
[ -z "$DEFAULT_BRANCH" ] && DEFAULT_BRANCH=$(git symbolic-ref --short HEAD 2>/dev/null)
# Fallback 3: pick the most-recently-committed local branch
[ -z "$DEFAULT_BRANCH" ] && DEFAULT_BRANCH=$(git for-each-ref --sort=-committerdate --format='%(refname:short)' refs/heads | head -n1)

# Guard: if DEFAULT_BRANCH is still empty we cannot safely run merged checks
if [ -z "$DEFAULT_BRANCH" ]; then
  echo "Warning: could not determine default branch — merged-check classification will be skipped."
fi

# The branch currently checked out in the main working tree
CURRENT_BRANCH=$(git -C "$(git rev-parse --show-toplevel)" branch --show-current)

# Branches checked out in any worktree (these are "in use" — git won't let you delete them anyway)
git worktree list --porcelain | awk '/^branch / { sub("refs/heads/", "", $2); print $2 }'

Then list candidate local branches, excluding the default branch, the current branch, and any branch that has a worktree:

git branch --format='%(refname:short)'

Filter that list in your head (or with grep -v) against $DEFAULT_BRANCH, $CURRENT_BRANCH, and the worktree branches above. Do not hardcode main|master — many repos use develop, trunk, or custom default branches, and the user may currently be checked out on a branch that isn't the default.

For each remaining local branch, check:

  • Is it merged into the default branch?

``bash git branch --merged "$DEFAULT_BRANCH" | grep -w "" ``

  • Was its remote deleted? (common after merging a PR on GitHub)

``bash git branch -vv --format='%(refname:short) %(upstream:track)' | grep '\[gone\]' ` The [gone]` marker means the branch once tracked a remote that no longer exists — a strong signal the PR was merged and the remote branch deleted.

  • Does it have an open PR? (if gh is available)

``bash gh pr list --head "" --state open --json number 2>/dev/null ``

Classify:

| Status | Criteria | | ------------------- | --------------------------------------------------------------------------------- | | Remote deleted | Tracked a remote that's gone (PR likely merged and branch deleted on GitHub) | | Merged orphan | Merged into $DEFAULT_BRANCH, no worktree, no remote — safe to delete | | Unmerged orphan | Not merged into $DEFAULT_BRANCH, no worktree, no remote — may be abandoned work | | Has open PR | Skip — still in use |

Step 3 — Present findings

Show a summary grouped by action:

Worktree Cleanup Report
═══════════════════════

Stale worktrees (no commits in 7+ days, clean):
  feat/old-experiment    .claude/worktrees/feat-old-experiment-1a2b3c4d    12d ago
  fix/typo-header        .claude/worktrees/fix-typo-header-5e6f7a8b         8d ago

Missing worktrees (directory gone, metadata remains):
  feat/deleted-thing     (path no longer exists)

Branches with deleted remote (PR likely merged on GitHub):
  feat/auth-refactor     remote gone — safe to delete locally
  fix/login-bug          remote gone — safe to delete locally

Orphaned branches (no worktree, no remote):
  feat/abandoned-idea    merged into $DEFAULT_BRANCH — safe to delete
  fix/half-done          NOT merged — review before deleting

Active worktrees (no action needed):
  feat/current-work      .claude/worktrees/feat-current-work-9c0d1e2f       2h ago

If --dry-run, stop here.

Step 4 — Let the user choose

Present cleanup options as a checklist — the user picks what to clean up:

  • Prune missing worktrees — run git worktree prune to clear stale metadata
  • Close stale worktrees — remove worktree directories for stale entries
  • Delete branches with deleted remotegit branch -d for each (their PRs were merged)
  • Delete merged orphan branchesgit branch -d for each
  • Skip unmerged orphans — list them but don't touch (inform the user of git branch -D if they want to force)

Ask which of these the user wants to proceed with. Don't auto-execute anything — the user confirms first.

Step 5 — Execute

For each action the user approved:

# Prune stale metadata
git worktree prune

# Close stale worktrees
git worktree remove ""

# Delete merged orphan branches
git branch -d ""

Print a summary of what was done:

Cleanup complete:
  2 stale worktrees removed
  1 missing worktree pruned
  3 merged orphan branches deleted
  1 unmerged orphan branch kept (fix/half-done)

After the cleanup actions complete, prune the session registry so it forgets any worktree directories that were removed:

bash "${CLAUDE_PLUGIN_ROOT}/scripts/worktree-registry.sh" prune

If the call fails, print a warning and continue — registry hygiene is best-effort.

Guiding principles

This is a housekeeping tool, not a destructive one. The default posture is conservative — show what could be cleaned up, let the user decide. The --dry-run flag makes it completely safe to explore.

Merged branches are safe to delete. Their commits live in the target branch. Unmerged branches might contain work the user forgot about — flag them but don't delete without explicit confirmation.

Use git worktree remove, not rm -rf. And use git branch -d (safe delete), not -D. If something refuses to delete, that's useful information — surface it.

Source & license

This open-source skill is cataloged on AgentStack and links to its original source — we do not rehost the code.

Install and usage instructions live in the source repository linked above.

Reviews

No reviews yet, be the first.

Versions

  • v0.1.0 Imported from the upstream source.