From claude-resources
End-of-workflow audit of GitHub issues, PRs, and branches. Verifies every touched resource is in the right state (closed when done, kept when ongoing, deleted when dead) via a Sonnet subagent, then executes safe actions and prints a report.
How this skill is triggered — by the user, by Claude, or both
Slash command
/claude-resources:cleanup-resources [workflow:big-plan|x-as-pr|x-wt-teams] [-a|--auto-merged] [extra context][workflow:big-plan|x-as-pr|x-wt-teams] [-a|--auto-merged] [extra context]The summary Claude sees in its skill listing — used to decide when to auto-load this skill
End-of-workflow audit for GitHub issues, PRs, and branches the calling workflow touched. Long workflows (big-plan, x-as-pr, x-wt-teams) tend to drop the trailing "close the source issue" / "delete the dead local branch" steps because context drifts. This skill forces an explicit checkpoint: gather a manifest of every touched resource, hand it to a fresh Sonnet agent for audit, then execute the ...
End-of-workflow audit for GitHub issues, PRs, and branches the calling workflow touched. Long workflows (big-plan, x-as-pr, x-wt-teams) tend to drop the trailing "close the source issue" / "delete the dead local branch" steps because context drifts. This skill forces an explicit checkpoint: gather a manifest of every touched resource, hand it to a fresh Sonnet agent for audit, then execute the safe actions and report.
On Claude Code on the web (
$CLAUDE_CODE_REMOTE=true): followweb/web-mode.md. Gather the manifest and execute closes / merges / branch deletes via the GitHub MCP (issue_read/issue_write,pull_request_read,list_pull_requests,merge_pull_request), notgh. Spawn the audit step as a Claude subagent (no agent teams).
This skill is invoked at the end of a parent workflow — never mid-flight. Typical callers:
/big-plan — at Step 10 (Close source issues). Manifest: source issues passed to the planning session./x-as-pr — after Session Report / Requirements Verification. Manifest: tracking issue (if --make-issue), the working branch (if the PR was auto-merged via -m / Merge Mode), unrelated-findings issues raised mid-workflow./x-wt-teams — replaces the old "Close Tracking Issue" + Step 16 cleanup. Manifest: tracking issue, sub-issues (if epic), root PR, base branch, topic branches, auto-merged status (the caller's -m flag).Note on flag naming: this skill's own -a / --auto-merged flag means "the caller auto-merged the root PR." In the calling workflows that signal is their -m / --merge flag (their -a is the autonomy/auto-chain flag and does NOT imply a merge) — callers pass -a here iff -m was on their invocation.
Other callers can use it the same way: build a manifest, invoke, execute the returned plan.
Before invoking the Sonnet agent, gather every resource the parent workflow created or touched. The manager (you) already knows these from session state — you do not need to grep git or scan the org. Build the manifest from memory of what the workflow did.
Structure the manifest as a single markdown block. Use this exact shape so the agent can parse consistently:
## Workflow context
- workflow: <big-plan | x-as-pr | x-wt-teams>
- auto-flag (-a): <true | false>
- epic-mode: <true | false> # true when the parent dealt with a [Epic] issue from /big-plan
- root-PR: <url-or-"none">
- root-PR-merged: <true | false>
- parent-branch: <branch-name-or-"none">
## Resources
### Issues
- #<number> — <role> — <one-line context>
- ...
### PRs
- <url> — <role> — <merged|open|draft>
- ...
### Branches
- <branch-name> — <role> — <local|remote|both> — <pr-merged: true|false>
- ...
## Notes for the agent
<any free-form context: e.g. "issue #45 has follow-up work tracked separately, KEEP it open">
Roles to use (consistent vocabulary helps the agent):
source (existed before; the workflow superseded it), tracking (created by the workflow as a spec/log), epic, sub (under an epic), fix (review-fix issue), unrelated-finding (side-effect issue raised mid-workflow), claimed-existing (user-supplied, not created here).root (the main PR for the workflow), topic (sub-PR merged into a base branch), fix (delegated fix PR).base (the base branch of an x-wt-teams session), topic (child branch under a base), working (the single x-as-pr working branch), fix (an agent-fix/<slug> branch from the -fix auto-fix step), parent (the branch the parent workflow targeted).If a resource doesn't fit, invent a short role label and explain in Notes for the agent.
Use the Agent tool to spawn a general-purpose agent with model: sonnet. The agent's job is analysis only — it must NOT close, delete, or edit anything. The manager executes actions in Step 3.
Prompt template (substitute the manifest):
You are auditing resources from a just-completed Claude Code workflow. The manager (parent session) handed you a manifest of every issue, PR, and branch touched during the workflow. Your job is to decide which should be CLOSED, KEPT, or DELETED, and return a structured plan. **Do not take any action yourself — only propose.**
Manifest:
<paste the full markdown manifest here>
Audit procedure:
1. For every issue in the manifest, run `gh issue view <number>` to read its current state, body, and recent comments. Check:
- Is it already closed? → action: keep, reason: "already closed".
- Does its body declare a TODO checklist with unchecked items? → action: keep, reason: "TODO checklist has open items".
- Was its work superseded by another issue/PR in the manifest (e.g. source issue replaced by an epic, fix issue replaced by a merged PR)? → action: close, with a one-line comment referencing the superseder.
- Is it an `unrelated-finding`? → action: keep, UNLESS it was already closed by `-fix` (the `/x-as-pr` or `/x-wt-teams` auto-fix step closes the ones it fixed and links the fix PR). An already-closed `unrelated-finding` stays closed (action: keep, reason: "already closed by -fix"). Open ones are intentional follow-ups — never close them here.
- Is it a `tracking` issue whose root PR is now merged (or the workflow ended cleanly)? → action: close.
- Is it a `sub` issue whose corresponding PR is merged into the base? → action: close.
- Is it an `epic` whose root PR is merged AND all sub-issues are closed? → action: close. Otherwise → keep.
2. For every PR in the manifest, run `gh pr view <url>` to read its state. PRs that are still open and intentional → keep. PRs already merged → keep (no action; they're done). PRs closed without merge (`state: CLOSED`, `merged: false`) → also keep, but add reason "manually closed without merge — investigate if the workflow expected it to merge". Do NOT propose closing open PRs unless the manifest's "Notes for the agent" explicitly asks for it.
3. For every branch in the manifest:
- Check remote state: `gh api repos/{owner}/{repo}/branches/{name}` or `git ls-remote --heads origin <branch>`.
- Check local state: assume the manager will check with `git branch --list <name>` before deleting.
- **On web (`$CLAUDE_CODE_REMOTE=true`, web-mode.md §5): a branch whose role is `session-web`, or whose name matches the manifest's `protected-session-branch`, is the session branch the platform owns → action: keep, reason "web session branch — platform-owned", ALWAYS, even when pr-merged=true. Never propose delete (local or remote) for it. This protects the session branch by exact name, NOT by the `claude/*` prefix — `claude/agent-fix-*` fix branches are still deletable below.**
- If pr-merged=true and the branch's role is `topic`, `working`, `base`, or `fix` → action: delete (both local and remote where applicable). Reason: "PR merged, branch is a dead pointer."
- If the remote has already been deleted (e.g. by `gh pr merge --delete-branch`) but the local still exists → action: delete-local-only.
- If pr-merged=false → action: keep.
- NEVER propose deleting `parent` branches — those belong to other work.
4. When the workflow's `auto-flag` is true (the caller auto-merged via its `-m` / `--merge` flag, passed to this skill as `-a` / `--auto-merged`) AND root-PR-merged is true, be more aggressive about deleting working/base/topic branches. The user explicitly opted into full auto-cleanup.
5. When in doubt about any resource, choose KEEP and explain in the reason. The manager will surface ambiguous cases to the user.
Return the plan as a single markdown block in this exact shape:
## Cleanup plan
### Close
- issue #<n> — <reason> — comment: "<one-line supersedes comment, or omit if no comment needed>"
- ...
### Delete (branches)
- <branch-name> — scope: <local|remote|both> — <reason>
- ...
### Keep
- <resource> — <reason>
- ...
### Ambiguous (manager: surface to user)
- <resource> — <why it's unclear>
- ...
End the response with one line: `Audit complete. <N> close / <M> delete / <K> keep / <A> ambiguous.`
Spawn the agent via the Agent tool with:
subagent_type: general-purposemodel: sonnetdescription: Audit workflow resources for cleanupprompt: the prompt above with the manifest filled inWait for the agent to return.
Read the agent's plan. Execute each action only when it is unambiguously safe. The agent already filtered out unsafe cases into "Ambiguous", but the manager re-checks before acting.
Close issues:
for each "Close" entry:
# Skip if already closed (defensive — agent may have raced with an external close)
state=$(gh issue view <n> --json state -q '.state')
if [ "$state" = "OPEN" ]; then
if [ -n "<comment>" ]; then
gh issue comment <n> --body "<comment>"
fi
gh issue close <n>
fi
Delete branches:
for each "Delete (branches)" entry:
case "<scope>" in
local)
# Use -d (NOT -D). If unmerged, surface as a loud failure rather than silently destroy work.
git branch -d <branch> 2>&1 || echo "WARN: local branch <branch> not deleted — unmerged commits or already gone"
;;
remote)
git push origin --delete <branch> 2>/dev/null || echo "WARN: remote branch <branch> not deleted — already gone"
;;
both)
git branch -d <branch> 2>&1 || echo "WARN: local branch <branch> not deleted — unmerged commits or already gone"
git push origin --delete <branch> 2>/dev/null || echo "WARN: remote branch <branch> not deleted — already gone"
;;
esac
Currently checked-out branch — switch off before deleting. git branch -d cannot delete the current branch. If the manager is on a branch that's in the delete list, check out a safe parent (the parent-branch from the manifest, or the repo default) first:
CURRENT=$(git branch --show-current)
# On web (web-mode.md §5): NEVER check out off the session branch to delete it — the session branch
# is protected (role: session-web / protected-session-branch) and is not in the delete list, so this
# block never fires for it. Do not git checkout the default branch on web (it is not pushable).
if [ "$CURRENT" = "<branch-to-delete>" ]; then
git fetch origin --prune
git checkout <parent-branch>
git pull origin <parent-branch>
fi
Never use -D (force delete). If -d refuses, that's the safety net working — surface the warning, do not retry with -D.
Print a concise human-readable summary to the chat. Format:
## Cleanup complete
### Closed
- #<n> — <title> — <reason>
- ...
### Deleted branches
- <branch-name> (local + remote) — <reason>
- ...
### Kept
- #<n> — <title> — <reason>
- ...
### Warnings
- <any failed close/delete with the warning message>
- ...
### Ambiguous (please review)
- <resource> — <agent's reason>
- ...
If there are no actions (everything was already in the right state), print just: Cleanup audit: all resources in expected state — nothing to do.
If the Ambiguous section is non-empty, do NOT auto-resolve. Surface to the user and let them decide. The agent's job was to filter the obvious cases; the manager's job is to act on those AND show the unclear ones.
gh issue reopen exists. Default to closing when the agent is confident.git branch -d (without force) refuses, trust the refusal — there are unmerged commits.-fix. They are explicitly opt-in follow-up work, so the audit never closes an open one. The exception is the -fix / --auto-fix auto-fix step in /x-as-pr / /x-wt-teams: it closes the agent-found issues it actually fixed (linking the fix PR) before cleanup runs. The audit leaves those already-closed and keeps every still-open one. The agent's prompt enforces this; the manager doesn't second-guess.role: session-web with protected-session-branch: <name>. The audit ALWAYS keeps it (even pr-merged=true), and the manager never checks out off it to delete it. Protect by name, not by the claude/* prefix — dead claude/agent-fix-* branches must still be deleted.-m / --merge flag (passed here as -a / --auto-merged) is the signal for aggressive cleanup. Without it, prefer keeping branches around — the user may want to inspect locally before deleting. With it and root-PR-merged, the user opted in to full cleanup including local dead branches (this is the specific bug the skill fixes: --delete-branch removes remote, the old workflow left local behind)./x-as-pr with --no-issue and no merged PR) — the manifest would be empty.In all other cases, the parent skill should invoke /cleanup-resources at its STOP point. The audit either confirms everything is already correct (nothing to do, fast) or it catches a missed close/delete.
Skill tool: skill="cleanup-resources", args="workflow:x-wt-teams -a"
The manager (parent skill) then continues in the same turn by building the manifest and following Steps 1–4 above. The args are advisory — they tell the cleanup skill which workflow flavor invoked it, so any workflow-specific hints in this SKILL.md apply.
npx claudepluginhub takazudo/claude-resources --plugin claude-resourcesOrchestrates GitHub issues/PRs/branches as knowledge graph for traceability in planning, brainstorming, designs, architectural decisions, session resumption. /shiplog.
Creates a branch and draft PR before implementation or turns existing work into a PR. Supports issue-driven workflows, review loops, and optional merge. Works on Claude Code web and local environments.