timschoch/skilly

cleanup-merged-branches

Delete remote branches whose PR was merged. Read-only dry-run, then confirm, then delete.

Trending #6392

Installation

$ npx skills add https://github.com/timschoch/skilly
Feature your product here Skill page unit · reach builders installing agent skills View pricing →

Similar popular skills

Related neighbors and high-traction skills in the same topics — useful to compare before installing.

Also in this package

Other skills from timschoch/skilly · top by installs.

npx skills add https://github.com/timschoch/skilly

Browse all from timschoch/skilly

More details

Agent compatibility

Declared targets from SKILL.md / docs. Unmarked agents are not listed — the skill may still install via the CLI.

Claude Code Not declared
Cursor Not declared
Codex Not declared
GitHub Copilot Not declared
Windsurf Not declared
Gemini CLI Not declared
Cline Not declared
OpenCode Not declared

Repository health

Default branch main
Open issues 6
Status Active

History

  1. First recorded snapshot · 45 installs

SKILL.md

Delete remote branches that belong to a merged PR. Destructive, so it runs as a dry-run first and never deletes without explicit confirmation.

Delete rule

A branch is deletable iff all hold — encoded in scripts/plan.sh, the single source of truth:

  • it still exists on the remote,
  • it has a merged PR,
  • it has no open PR,
  • it is not protected.

Protected = the default branch + staging. Never delete these, even if a merged PR points at them. A branch with no PR, or only a closed-unmerged PR, is not deletable (it never "belongs to a merged PR"). Extend the protected set in is_protected() inside scripts/plan.sh, nowhere else.

Steps

  1. Dry-run. Run bash scripts/plan.sh (pass a remote name as $1 if not origin). It prints deletable branches as <branch> #<pr> <title>, and deletes nothing. Done when you have the list. Empty output → report "nothing to clean up" and stop.
  2. Show + confirm. Show the full list to the user and ask for explicit go. Do not delete on a vague reply — only on a clear yes. This gate is mandatory every run.
  3. Delete. For each confirmed branch: git push origin --delete <branch>. Nothing outside the plan's list may be deleted.
  4. Report. List what was deleted; note any push that failed.

Also: stale claims (the reaper)

Releases abandoned in-progress claims (agent crashed / session died / no PR ever opened) so a dead claim doesn't pin an issue as "taken" forever. See docs/agents/triage-labels.md for the label; /implement sets it, PR-open removes it, this reaps the leftovers.

Stale rule. An in-progress issue is stale iff all hold — encoded in scripts/stale-claims.sh, the single source of truth:

  • it is open and labeled in-progress,
  • it has no open linked PR (linked = an open PR referencing #N in title/body, or whose head branch == the branch named in the claim comment), and
  • the in-progress label is older than the threshold (latest labeled timeline event): default 24h, override via $1/$STALECLAIMHOURS.

Steps (fold into the same run, on the same confirm gate as branch deletion):

  1. Dry-run. Run bash scripts/stale-claims.sh [hours]. It prints stale claims as #<n> <title> and changes nothing. Empty → nothing to reap. (Logic proof: bash scripts/stale-claims.test.sh.)
  2. Show + confirm. Show the list; reap only on explicit go. Same mandatory gate.
  3. Reap. For each confirmed issue: gh issue edit N --remove-label in-progress --add-label ready-for-agent (abandoned work re-enters the free queue). Nothing outside the printed list is touched.

Also: stale-open issues

Closes #N only auto-closes on merge into the default branch — a PR merged into an integration branch (e.g. rebuild/v1) leaves #N open forever. For each merged PR you clean up here, check its linked issue: if the work is on the default branch but the issue is still open, hand-close it (gh issue close #N --reason completed --comment "merged via #<pr>"). Same misfire hides "done" issues as open — this is where to catch them.