Manage PRs
Use
for all operations. Stop and ask the user on: 401, 403, 422, or network timeout.
Default merge:
. Check
if it exists — it overrides merge defaults.
DO NOT
- Explore the repo (, , , check directories) — irrelevant to PR management
- Do exploratory research before triaging — go straight to gathering PRs
- Ask the user to confirm or choose a merge strategy — write the plan, then execute it
- Mark a PR "diff verified" without running — read every diff before classifying
- Re-fetch individual PR metadata via when already has the data
- Merge when mergeable is — re-query until it resolves (see gotchas below)
Gotchas
mergeability is a hard block. GitHub computes this async. Re-query up to 3×:
gh pr view <n> --json mergeable
— wait a few seconds between. Never merge
.
crashes . Use
— not the
flag.
does not exist. Use the API instead:
gh api repos/{owner}/{repo}/pulls/{n}/update-branch -f merge_method=squash
silently caps at 100. Always use
. Warn user if count hits 100.
Always comment when closing. gh pr close <n> --comment "Closing because..."
— never silently.
body must use . Write body to a tmpfile, pass
. Never inline
.
"Base branch was modified" on merge. Each merge changes the base branch, so the next merge may fail.
Merge PRs one at a time. On this error, simply retry the same merge command.
Single-PR Workflow
Use when the user names a specific PR (e.g. "merge PR #42", "close PR #7").
- Health check:
gh pr view <n> --json number,title,author,isDraft,mergeable,reviewDecision,statusCheckRollup,body
— Verify mergeable is . If , re-query up to 3×.
- Read diff: — verify logic, imports, API usage. For bot/AI PRs, grep unfamiliar identifiers.
- Act: merge (
gh pr merge <n> --squash --delete-branch
), close with comment, or hand off to .
Batch Triage Workflow
Use when managing multiple PRs (e.g. "triage PRs", "clean up PR queue").
Step 1: Gather and detect overlaps
bash
gh pr list --json number,title,author,isDraft,mergeable,reviewDecision,statusCheckRollup,baseRefName,files \
--limit 100 | tee prs.json | python3 -c "
import json, sys, collections
data = json.load(sys.stdin)
by_file = collections.defaultdict(list)
for pr in data:
for f in pr.get('files', []):
if isinstance(f, dict) and 'path' in f:
by_file[f['path']].append(pr['number'])
overlaps = [(p, ns) for p, ns in by_file.items() if len(ns) > 1]
if overlaps:
print('OVERLAPPING FILES:')
for p, ns in sorted(overlaps, key=lambda x: -len(x[1])):
print(f' {p}: PRs {ns}')
else:
print('No file overlaps detected.')
"
This saves
AND pipes to overlap detection in one shot.
Overlapping PRs need sequenced merging — merge the simpler one first, re-check conflicts on the other.
Also read
for merge overrides if it exists.
Step 2: Read every diff
For each PR, run
and verify logic, imports, no obvious breakage.
For bot/AI PRs, grep unfamiliar identifiers in the codebase.
Do NOT skip this step — a PR cannot be classified as merge-ready without a diff read.
Step 3: Triage report
Use data from
(mergeability, CI, review) plus your diff reads to classify each PR.
Write results to a plan file:
- ✅ Merge-ready — , CI green, diff read and verified
- ⚠️ Needs action — blocked by conflict / CI / review
- 🔁 Stale — no activity >14 days
- 🔀 Overlapping — file conflict risk with merge order specified
- ❌ Close candidates — superseded, duplicate, or abandoned
After writing the plan, proceed to merge — do not stop and ask for confirmation.
Cross-Skill Routing
| Situation | Hand off to |
|---|
| PR needs structured code review before merge | |
| PR has unresolved review threads to address | |