skills/drain-pr-queue/SKILL.md
--- name: drain-pr-queue description: Merge a stack of open PRs sequentially without babysitting each one. Discovers (or accepts) a list of PRs, arms auto-merge on all of them, then update-branches in a loop as each one lands so the next becomes mergeable. Handles BEHIND, DIRTY, and CI-failure cases. Use when you have several PRs ready to ship and don't want to merge them one at a time. Sibling to /ro:gh-ship (that one drives a single feature; this one drains a queue). category: development argu
npx skillsauth add RonanCodes/ronan-skills skills/drain-pr-queueInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
Merge a stack of N open PRs to main without manual hand-holding. Each merge invalidates the others (BEHIND main), so the loop keeps update-branching the rest until the queue is empty.
/ro:drain-pr-queue # all open PRs by current user
/ro:drain-pr-queue --prs 37,39,40 # explicit list
/ro:drain-pr-queue --author app/dependabot # drain dependabot's queue
/ro:drain-pr-queue --dry-run # show plan, don't merge
main, all CI-green, all reviewed.gh pr merge directly).Unless --prs is given, list candidates:
gh pr list --state open --author "${AUTHOR:-@me}" \
--json number,title,headRefName,mergeStateStatus,mergeable,statusCheckRollup,autoMergeRequest \
--limit 50
Filter out:
Show the user the filtered list and confirm before proceeding (unless --dry-run, in which case just print and stop).
For each PR, get the changed files:
gh pr view N --json files -q '.files[].path'
Sort the queue so:
pnpm-lock.yaml, package-lock.json, yarn.lock, Cargo.lock) go LAST. They invalidate every other PR's lockfile when they land, but landing first means everyone behind needs a lockfile rebase.for pr in "${QUEUE[@]}"; do
gh pr merge "$pr" --squash --delete-branch --auto
done
If gh pr merge --auto fails with "Auto merge is not allowed for this repository", run once:
gh repo edit "$REPO" --enable-auto-merge
Then retry.
Do NOT change merge strategy without checking. Default to squash; respect the repo if it enforces a different strategy (look at branch protection: gh api repos/$REPO/branches/main/protection).
for pr in "${QUEUE[@]}"; do
gh api -X PUT "repos/$REPO/pulls/$pr/update-branch" 2>&1 | head -c 200
done
This kicks off CI on the rebased commits. As each one passes, auto-merge fires.
Cache-aware sleep is critical. Anthropic prompt cache TTL is 5min:
Default to 240s between checks during a drain (CI on this codebase is ~3min per cycle, so 240s usually catches the next batch of merges).
Each cycle:
gh api -X PUT .../update-branch to bring current.gh run view --log-failed. Don't try to fix; that's outside scope.For dependabot PRs:
gh pr comment "$pr" --body "@dependabot rebase"
Wait one cycle (240s), then re-check. Dependabot typically rebases within 1-3min.
For user-authored PRs (or if dependabot rebase failed):
git fetch origin "pull/$pr/head:pr-$pr-tmp" --force
git checkout "pr-$pr-tmp"
# Reset to current main and re-apply just the PR's logical change.
# This works when the conflict is purely lockfile/generated noise. For
# semantic conflicts, BAIL and tell the user — don't guess.
git reset --hard origin/main
# <re-apply the change manually here, OR cherry-pick the original head>
git push origin "pr-$pr-tmp:$BRANCH" --force
git checkout main
git branch -D "pr-$pr-tmp"
Auto-merge stays armed across force-pushes (verify with gh pr view N --json autoMergeRequest).
When the queue empties:
Drained N PRs in ~M minutes:
✅ #N1 — <title>
✅ #N2 — <title>
...
⚠️ #N3 — BLOCKED on <reason> (left open)
--no-verify, --admin, force-push to main).main/master. Force-push only to feature branches you control.A typical drain of 5 PRs on a repo with ~3min CI is ~50min wall clock. Most of that is CI wait. The watch loop should NOT busy-poll under 60s.
Without the skill: merge → wait for CI on next → realise it's BEHIND → update-branch → wait again → merge → repeat. You're context-switching every 3min.
With the skill: arm auto-merge once, then update-branch + sleep loop. You get notified at the end.
/ro:gh-ship ships ONE feature branch (PR open + watch + merge)./ro:drain-pr-queue ships N already-open PRs in sequence./ro:gh-ship per feature, then /ro:drain-pr-queue once you have a backlog.testing
--- name: linear-pipeline description: The Fable orchestrator for a single dispatched Linear ticket. Holds almost no context itself; it receives `--issue <ID> --detached`, decides the stage sequence, and fans out a sub-agent per stage, passing forward only each stage's artifact (never re-derived, never inlined into its own context). Step zero, before any planning or stage routing, is a boundary triage against `canon/security-boundary.md` (#199): a match tags Ronan Connolly and stops the run, no
development
--- name: in-your-face description: Capture a chat-only answer into a durable artifact (markdown + HTML, PDF when cheap) and launch it automatically so the user cannot miss it. Use when user says "in your face", "don't let me lose this", "save that answer", "make that durable", or right after answering a substantive side question (a recipe, comparison, how-to, or generated prompt) that would otherwise die with the context. category: workflow argument-hint: [--no-open] [--vault <short>] [hint of
tools
One-shot headless OpenAI Codex CLI calls for background/admin AI tasks — summaries, classification, extraction, admin glue. The default engine for anything that runs AI constantly in the background (daemon-driven, per-event), because it bills the flat ChatGPT subscription instead of Claude usage or per-token API spend, and it keeps working while Claude is rate-limited. NEVER for coding — coding stays Claude. Use when a skill or daemon needs a cheap always-on AI call, when the user says "use codex", "ask codex", "codex as backup", or when building a background summarizer/classifier into a listener or loop. Reads auth from ~/.codex/auth.json (ChatGPT account, no API key).
research
Turn a warranty rejection, repair quote, or RMA email into a cited decision brief — legal read (NL/EU consumer law), is the part user-serviceable, live part and new-unit prices, repair-vs-DIY-vs-new economics, before-you-send-it checklist, deadlines. Use when the user pastes or screenshots a repair quote, warranty rejection, "not covered" email, onderzoekskosten fee, or asks "should I repair or replace this".