Skip to content
Back to skills

Session Cleanup

BSecurity

End-of-session housekeeping for git repositories. Use when the user asks to 'end of session', 'clean up session', 'session housekeeping', 'clean up branches', 'clean up worktrees', or 'clean up remote branches'.

  • 4 stars
  • 0 votes
  • 0 copies
  • 1 view
  • Added May 26, 2026
devopsrustgoshellbashnodedockergit

Security analysis

B85/100
  • highPerforms destructive filesystem operations

Pro scans all 4 files and shows the line behind each finding

Scanned September 22, 2026

npx -y skills add wrsmith108/session-cleanup-skill --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Session Cleanup?

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

Security grade badge for Session Cleanup
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/wrsmith108-session-cleanup/badge)](https://www.skillsdirectory.com/skills/wrsmith108-session-cleanup)

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: "Session Cleanup"
description: "End-of-session housekeeping for git repositories. Use when the user asks to 'end of session', 'clean up session', 'session housekeeping', 'clean up branches', 'clean up worktrees', or 'clean up remote branches'."
version: "1.7.1"
---

# Session Cleanup

Structured end-of-session housekeeping: doc review, branch audit, worktree removal, and remote sync.

## Behavioral Classification

**Type**: Guided Decision

**Directive**: ASK, THEN EXECUTE

Audits each category and presents findings before taking any destructive action. Deletions always follow an explicit audit phase.

## Execution Context Requirements

This skill spawns a general-purpose subagent that performs git operations and file edits.

**Foreground execution required**: Yes

**Required tools**: Read, Write, Edit, Bash, Grep, Glob

**Fallback**: If tools are denied, the subagent returns a checklist of recommended actions for the coordinator to apply manually.

**AskUserQuestion may not be available to the dispatched subagent** (found in practice, 2026-08-12): a `general-purpose` subagent spawned via the Task/Agent tool does not reliably have `AskUserQuestion` in its toolset in every harness, even though this skill's confirmation gates (Phase 2f, Phase 3, Phase 4c) assume it does. When this happens, the subagent should not guess or skip the gate — it should stop, return its full categorized findings as a condensed, decision-ready summary (counts + names + recommended action per bucket, not a raw dump of hundreds of items) to the coordinator, and let the coordinator either relay to the user via its own `AskUserQuestion` or (if the coordinator has independently gathered enough context to judge the scope safe) approve directly. The coordinator then sends the scoped go-ahead back to the SAME subagent (resume via `SendMessage` to its agent ID, not a fresh dispatch) to execute — this preserves the subagent's already-built audit state (scratch files, full branch lists) instead of re-doing the audit from scratch.

## Usage

Invoke at the end of a working session:

```
/session-cleanup
```

Or trigger via phrases: "end of session", "clean up branches", "clean up worktrees", "session cleanup"

**Out of scope**: PR creation/merge (`/ship`), production deploys, Linear issue updates (`/linear`), resolving merge conflicts.

## Five Phases

1. **Doc Review** — CLAUDE.md staleness, MEMORY.md updates, MEMORY.md TTL pruning (class-4 entries past their expiry), submodule dirty state
2. **Branch Audit** — PR status check, unpushed commit detection, squash-merge artifact filtering
3. **Branch Cleanup** — Push unreleased content, cherry-pick docs to main, delete merged branches
4. **Worktree Cleanup** — Remove stale worktrees via project script or `git worktree remove`; audit project-provided container inventory separately for live-old/excessive advisories and safe orphan-cleanup candidates
5. **Backlog Sweep** — Query Linear for issues in Backlog state with no activity in 30+ days. For each, check if the work was completed by a related commit (search git log for issue ID or title keywords). Present findings for user to mark Done or re-prioritize. Monthly cadence; also consider a scheduled remote trigger (`/schedule`) to enforce.
6. **Final State** — Sync main, confirm clean working tree, report summary

## Pre-Dispatch Check (REQUIRED — run before spawning agent)

Before launching the cleanup agent, run these two commands via Bash:

```bash
git status --porcelain
git branch --list | grep -v "^\* main$"
```

**If both return empty** (working tree clean AND only `main` branch exists locally), cleanup has almost certainly already run this session. Do NOT spawn the agent. Instead, tell the user:

> "The repo looks clean already — only `main`, nothing uncommitted. Cleanup appears to have already run this session. Run it again anyway?"

Only proceed to Dispatch if the user confirms, or if either check returns output (there is real work to do).

## Dispatch

```
Use the Task tool with subagent_type="general-purpose" and pass the full contents
of ~/.claude/skills/session-cleanup/agent-prompt.md as the prompt.
```

---

## Changelog

### v1.7.1 (2026-08-28)
- **Fixed**: Phase 3b's batched `git push origin --delete` guidance now warns that a batch mixing
  already-gone remote refs with real ones can fail atomically — the whole push is rejected with
  no refs deleted, even though the per-ref error output only names the already-gone ones, making
  it look like the rest succeeded. Found in practice: a 19-branch batch where 16 refs no longer
  existed remotely (delete-branch-on-merge) printed 16 "remote ref does not exist" errors and
  exited 1; the other 3 refs, never named in any error, were also not deleted. Guidance now says
  to re-run `git ls-remote --heads origin` after any non-zero exit and retry with exactly the
  refs still actually present, rather than trusting the error output's named subset.

### v1.7.0 (2026-08-25)
- **Added**: Phase 4c no longer trusts a project's orphan-prune script alone — it now always
  runs a manual cross-check too (`docker volume ls`'s `com.docker.compose.project` labels
  against `git worktree list`, plus a dangling-volume/live-container confirmation before
  calling anything orphaned). Also extends 4c's scope to two categories the script-only
  approach never covered at all: build-cache pruning (`docker builder prune`, low-risk, doesn't
  touch any current image) and superseded same-repository image tags (moderate-risk, ask
  first). Explicitly excludes volumes/images belonging to unrelated Docker Compose projects
  sharing the same daemon. Found via a real cleanup run: this project's own
  `prune-orphaned-docker-volumes.sh --dry-run --include-unlabeled` reported zero candidates,
  but the manual cross-check found ~2.7GB across 6 fully orphaned volume groups the script's
  ownership predicate didn't recognize (a newer per-package `<slug>_<package>-node-modules`
  naming shape postdated the script's pattern matching). Total reclaim across all three
  categories that run: ~37GB (orphaned volumes + build cache + superseded images).

### v1.6.1 (2026-08-12)
- **Fixed**: Phase 3b/3c's batched-delete guidance now warns explicitly about zsh vs. bash unquoted-`$VAR` word-splitting — building the branch list in a shell variable and expanding it unquoted silently no-ops the delete under zsh (no error, just doesn't work) while working fine under bash. Guidance now recommends writing the list to a file and piping through `xargs`, which is shell-agnostic, plus verifying the delete landed via a live `git ls-remote --heads origin` rather than trusting the push command's exit code. Found via a real cleanup run (187-branch batch): the first attempt partially no-op'd under zsh with no visible error before the executing agent diagnosed the shell-specific cause and switched to the `xargs` form mid-run.

### v1.6.0 (2026-07-25)
- **Added**: Phase 4 container-inventory review distinguishes advisory live-old/excessive findings from orphaned cleanup candidates. It recommends confirming resource pressure with `docker stats`, and never treats age/count alone as deletion authority.

### v1.5.0 (2026-07-23)
- **Added**: Phase 4c — orphaned Docker resource sweep. The routine per-worktree-removal path (Phase 4b's project script, when it also tears down Docker resources) only fires when a worktree is removed *through* that script. Worktrees that disappear another way — crash, manual `rm -rf`, a bare `git worktree remove` — never trigger it, so orphaned per-worktree volumes/images silently accumulate with nothing to catch them. 4c looks for a project-specific orphan-prune script (if one exists), runs it in dry-run/report-only mode, cross-checks reported project slugs against Phase 4a's `git worktree list` output as a second safety check, and presents the count + reclaimable space to the user before deleting anything — same Guided Decision pattern as the rest of the skill. Silently skipped if the project has no such script. Found via a real backlog: 300 orphaned volumes/images (~49GB) had accumulated on one machine, none of it caught by the routine per-removal path because they predated it or were removed out-of-band.

### v1.4.1 (2026-07-22)
- **Fixed**: Phase 5 Reset Guard checked working-tree cleanliness only, not which branch was checked out — a clean-but-non-main checkout (e.g. a docs/feature branch with an open PR) would have its own tip discarded by `git reset --hard origin/main`. Guard now also confirms `git branch --show-current` is `main`, checking out `main` first if not, before any reset. Found via a real near-miss: the main checkout was on a branch with 5 unmerged commits backing an open PR when Phase 5 was about to run.

### v1.4.0 (2026-07-06)
- **Fixed**: Phase 2 Category-A gating no longer relies on two-dot diff file count for branches with a merged PR — that diff measures drift against *today's* main, not unreleased content, and misclassifies old-but-merged branches in high-merge-velocity repos. `gh pr` MERGED state is now authoritative for Category A; the two-dot diff is only used as a gate for no-PR/open-PR branches. Found and fixed after `chore/smi-5359-quarantine-deliverables` (1 real unmerged commit) showed ~400 files in a raw two-dot diff during a cleanup pass. (SMI-5554 session)

### v1.3.0 (2026-04-23)
- **Added**: Phase 1b now scans `MEMORY.md` for `TTL: YYYY-MM-DD` markers and surfaces entries whose date has passed for user-approved pruning. Pairs with the `memory-governance` skill's class-4 (project state with TTL) classification. (SMI-4432 Pass 4)

### v1.2.1 (2026-03-28)
- **Fixed**: Phase 3b remote branch deletion now batches all deletes into a single `git push origin --delete b1 b2 ... bN` invocation instead of a per-branch loop. Eliminates O(N) pre-push hook runs and avoids partial-deletion state from mid-loop hook failures. (SMI-3710)

### v1.2.0
- Initial structured release with five-phase workflow and pre-dispatch idempotency check

Files in this skill

  • .skillsmith-publish.json211 B
  • CHANGELOG.md2.6 KB
  • SKILL.md2.9 KB
  • agent-prompt.md10.5 KB

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…

Newsletter

Get the weekly list of safe new skills, and the ones we pulled.