Skip to content
Back to skills

Cleanup Worktrees

ASecurity

Remove finished agent worktrees, prune their branches, and surface anything still in flight. Run at the end of a multi-agent session and weekly as hygiene.

  • 7 stars
  • 0 votes
  • 0 copies
  • 0 views
  • Added September 23, 2026
ai-agentsgobashnodegit

Security analysis

A100/100

Scanned September 23, 2026

npx -y skills add mcorbett51090/RavenClaude --skill cleanup-worktrees --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Cleanup Worktrees?

Add the live security badge to your README. It updates with every re-scan.

Security grade badge for Cleanup Worktrees
[![Security: A — Skills Directory](https://www.skillsdirectory.com/api/skills/mcorbett51090-cleanup-worktrees/badge)](https://www.skillsdirectory.com/skills/mcorbett51090-cleanup-worktrees)

More formats (shields.io, HTML) on the badges page. Keep it an A: scan every change in CI with Pro.

Download with Pro
SKILL.md
---
name: cleanup-worktrees
description: Remove finished agent worktrees, prune their branches, and surface anything still in flight. Run at the end of a multi-agent session and weekly as hygiene.
---

# Skill: cleanup-worktrees

> **Labeling (Sleipnir):** worktrees are "Sleipnir's stables" in user-facing prose (see `ravenclaude-core/CLAUDE.md` → "Sleipnir"); this skill returns Sleipnir to the stable. Labeling only; the mechanics below are unchanged.

## Procedure
1. **List.** `git worktree list --porcelain`. Show the user a short table: path, branch, HEAD, dirty?
2. **Classify each worktree.**
   - **Merged** — its branch is fully reachable from `main` (or the configured base). Safe to remove.
   - **Open PR** — branch has an open PR. Don't remove.
   - **Dirty** — uncommitted changes. Surface and stop; the Team Lead must decide.
   - **UNKNOWN** — the tree could not be inspected. ⛔ This is **not** a third
     flavour of clean: an un-inspected tree produces empty output, byte-identical
     to a clean one, so treating it as clean deletes work nobody looked at.
     `worktree-clean.sh` refuses it — and refuses it **even with `--force`**,
     because `--force` discards uncommitted work and here we do not know whether
     there is any.

     There are **two causes**, and only one of them involves an error:
     - *`git status` failed* — a stale linked worktree whose admin dir under
       `.git/worktrees/` is gone, a corrupt `.git`, permission denied. Empty
       stdout, non-zero exit.
     - *`git status` **succeeded**, but against an ANCESTOR* — the directory is
       not a worktree, or its `.git` file is missing, so git's discovery walked
       up and reported the parent repo. Since `.claude/worktrees/` is gitignored,
       the parent reports nothing about it, so this also comes back empty — with
       **exit 0**. This is the more common shape, and it is why a successful
       `git status` is not by itself evidence that anything was inspected.

     ⛔ Do **not** reach for `git worktree repair` / `git worktree prune` as a
     reflex. Both were measured to be no-ops on every UNKNOWN shape tested, so
     that advice sends you in a loop — and loop pressure is what makes people
     tunnel to a manual delete. Read the specific cause, fix that, or move the
     tree aside. Never delete it to make the message go away.
   - **IGNORED** — nothing tracked is modified and nothing is untracked, but the
     tree still holds **ignored** files (`.env`, `node_modules/`, a local db).
     ⛔ `git status --porcelain` is **silent on ignored files by design**, so this
     tree used to report empty output and classify `clean` — with git working
     perfectly. The `.env` case is the one that hurts: a file is ignored
     *precisely because* it is not in git, so the rule that hides it from the
     probe is the same rule that guarantees no other copy exists.
     `worktree-clean.sh` skips it under `--all` and names what is there. Unlike
     UNKNOWN, it **does** honour `--force` — the difference is knowledge, not
     danger: here we can see exactly what would be destroyed, so `--force` is a
     considered choice rather than a blind one.
   - **DETACHED** — the tree is clean by every measure above, but its HEAD is
     detached at a commit **no branch or tag contains**. ⛔ This is the first
     state where the work is *committed*: `git status` is rightly silent, and
     removing the worktree makes that commit unreachable. The reflog does **not**
     rescue it — `.git/worktrees/<name>/logs/HEAD` is deleted with the admin dir
     (controlled 2026-08-17: before removal the file exists; after, it is gone,
     the commit is contained by 0 refs, and only `git fsck --unreachable` still
     finds it). Recovery is `git fsck --lost-found` until gc prunes.
     `worktree-clean.sh` skips it under `--all`, names the SHA, and prints the
     one-command rescue: `git branch <name> <sha>`. It honours `--force`, like
     IGNORED. **The discriminator is reachability, not detachment** — a worktree
     detached at an existing ref tip is common and harmless, still reads `clean`,
     and is removed normally.
   - **Stale** — last commit > 14 days old, no PR. Flag for the user, don't remove without confirmation.
3. **Close the lane first.** Close the VS Code window / end the Chat session for that worktree before `git worktree remove`, or the next session can reuse an Agents-window conversation from the removed tree.
4. **Remove the safe ones.**
   ```bash
   git worktree remove .claude/worktrees/<role>-<slug>
   git branch -d agent/<role>/<slug>     # only if fully merged
   ```
   Use `-d` (safe), never `-D` (force) without explicit user approval.
5. **Prune metadata.** `git worktree prune`.
6. **Report.** What was removed, what was kept, what needs attention.

## Output format
```
Removed (3):
  agent/coder/auth-refresh   merged into main 2 days ago
  agent/tester/auth-refresh  merged into main 2 days ago
  agent/coder/nav-typo       merged into main 5 days ago

Kept (2):
  agent/coder/billing-page   open PR #142
  agent/coder/exp-feature    dirty — uncommitted changes

Needs review (1):
  agent/coder/old-spike      stale, last commit 23 days ago, no PR
```

## Don'ts
- Never delete a worktree with uncommitted changes without explicit user approval.
- Never `git branch -D` (force-delete) without approval. `-d` will refuse to delete unmerged branches; that's the correct behavior.
- Never delete the worktree you're currently running inside.


## Codex managed worktrees (DOC adapt 2026-09-20 — UNVERIFIED)
This skill targets RavenClaude / Sleipnir agent worktrees under `.claude/worktrees/`. Codex 0.155 agents overview owns **managed** worktree hide/archive/confirmed-delete. If `git worktree list` shows a Codex-managed path still owned by the overview, prefer the overview confirmed-delete path; do not silently remove it here. Do not conflate Sleipnir hygiene with Codex managed-worktree lifecycle. Guardian approval evidence KEEP elsewhere is unchanged by this note.

## Why a skill, when the Agent tool has built-in `isolation: "worktree"`?
The Agent tool's native worktree isolation auto-cleans up its own ephemeral worktrees. This skill cleans up the *managed* worktrees created by [`new-worktree`](../new-worktree/SKILL.md) — predictable paths, predictable branch names, persisting across multiple sub-agent runs so the Team Lead can hand a worktree off between agents. Those won't be cleaned by the harness, so the Team Lead runs this skill at the end of a multi-agent session and weekly as hygiene.

Attribution

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments

Loading comments…