Part of #1.
forgectl pr — select open PRs and drive them to merge
Context
Getting a batch of open PRs "across the finish line" today means hand-running gh, watching CI and CodeRabbit, and dodging a pile of documented gh/git traps. The logic already exists as the cadence-forge:review-loop skill + poll-prs.sh; this issue ports that proven flow into a forgectl command so it's a one-shot, repeatable tool rather than a skill-driven session.
Scope
forgectl pr lists open PRs (gh pr list --json), offers a multi-select (huh multiselect / bubbletea list) of which to drive.
- For the selected set, run a poll → triage → (optionally fix) → merge loop to completion, with a status table (TUI or repeating table render).
- Merge when green + approved; surface findings otherwise. Respect a round cap and stale timeout (mirror review-loop's defaults: 10 rounds / 10 min).
- CodeRabbit-aware: treat "no actionable comments" + incremental silent-review acks as approval-equivalent (see
using-coderabbit).
Must bake in the documented gotchas (from CLAUDE.md)
- Reading a file at a ref:
gh api --method GET … -f ref=<branch> (-f alone flips the verb to POST).
- Pre-merge check must include
isDraft — draft PRs silently block merge even when mergeable/mergeStateStatus look clean (or run gh pr ready first).
- After
gh pr merge, verify with gh pr view <n> --json mergedAt,mergeCommit — a local post-merge step can fail while the server-side merge succeeded.
- Branch-existence checks use the singular
git/ref/heads/<branch> (plural refs returns [] with 200, masking deletion).
- Stacked PRs: merging one re-bases
main and turns siblings CONFLICTING — re-check each after every merge; retarget dependents before deleting any base branch (deleting a base branch closes its dependent PR).
--delete-branch fails locally when main (or the PR branch) is checked out in another worktree — verify merge, then git push origin --delete manually.
Acceptance criteria
- Select N PRs, command merges all that are mergeable and reports precisely why each non-merged one was skipped.
- Never merges a draft; never deletes a branch an open PR depends on; always verifies the merge landed server-side.
- Hard stops on round cap / stale timeout instead of looping forever.
Reuse / pointers
cadence-forge/skills/review-loop/ (state machine, scripts/poll-prs.sh — consolidated gh api poll emitting NDJSON, fail-soft).
cadence-forge/skills/using-coderabbit/SKILL.md (green-check-≠-done, approval signals).
- Gotchas:
~/.claude/CLAUDE.md GitHub CLI section.
- All
gh/git calls through internal/exec Runner for testability.
Open question
- Should
forgectl pr fix findings (spawn an agent) or stay merge-only and leave fixing to a Claude session? Recommend merge-only v1 (orchestrate, don't author).
Re-scope (2026-06-22) — pr is now a sub-epic
Tracked under the umbrella EPIC cameronsjo/claude-configurations#206; full flagship spec in cameronsjo/claude-configurations#202 ("pr — PR Review (the flagship)"). The pr surface is larger than one issue and decomposes into:
Sub-issues
Folded into the above (checklist, not separate issues yet)
Dependencies
The reviewer (#29) consumes quarantine #20 (clean-room isolation), net #19 (network posture), and launch #2 (gateway auth). Build #29 first; #30/#31/#32 build on it.
Relationship to the original merge-loop scope (above)
The original forgectl pr scope — multi-select open PRs and drive them to merge (a review-loop port) — remains valid and folds into this sub-epic as the dashboard + merge path alongside #31's discovery surfaces. The v1 recommendation (merge-only; orchestrate, don't author) still holds. The #202 flagship adds the clean-room review-session facet (#29–#32) on top of that merge-driving facet.
Part of #1.
forgectl pr— select open PRs and drive them to mergeContext
Getting a batch of open PRs "across the finish line" today means hand-running
gh, watching CI and CodeRabbit, and dodging a pile of documentedgh/gittraps. The logic already exists as thecadence-forge:review-loopskill +poll-prs.sh; this issue ports that proven flow into a forgectl command so it's a one-shot, repeatable tool rather than a skill-driven session.Scope
forgectl prlists open PRs (gh pr list --json), offers a multi-select (huh multiselect / bubbletea list) of which to drive.using-coderabbit).Must bake in the documented gotchas (from CLAUDE.md)
gh api --method GET … -f ref=<branch>(-falone flips the verb to POST).isDraft— draft PRs silently block merge even whenmergeable/mergeStateStatuslook clean (or rungh pr readyfirst).gh pr merge, verify withgh pr view <n> --json mergedAt,mergeCommit— a local post-merge step can fail while the server-side merge succeeded.git/ref/heads/<branch>(pluralrefsreturns[]with 200, masking deletion).mainand turns siblingsCONFLICTING— re-check each after every merge; retarget dependents before deleting any base branch (deleting a base branch closes its dependent PR).--delete-branchfails locally whenmain(or the PR branch) is checked out in another worktree — verify merge, thengit push origin --deletemanually.Acceptance criteria
Reuse / pointers
cadence-forge/skills/review-loop/(state machine,scripts/poll-prs.sh— consolidatedgh apipoll emitting NDJSON, fail-soft).cadence-forge/skills/using-coderabbit/SKILL.md(green-check-≠-done, approval signals).~/.claude/CLAUDE.mdGitHub CLI section.gh/gitcalls throughinternal/execRunnerfor testability.Open question
forgectl prfix findings (spawn an agent) or stay merge-only and leave fixing to a Claude session? Recommend merge-only v1 (orchestrate, don't author).Re-scope (2026-06-22) —
pris now a sub-epicTracked under the umbrella EPIC cameronsjo/claude-configurations#206; full flagship spec in cameronsjo/claude-configurations#202 ("
pr— PR Review (the flagship)"). Theprsurface is larger than one issue and decomposes into:Sub-issues
pr <ref>clean-room worktree review (core: temp worktree + tmux window + human approval gate + selectable agent + deny-by-default allowlist)pr localoffline clean-room review of LOCAL committed changespr prs/dash/pickdiscovery surfaces + reviewed-state dimming (reviewedAtmap)pr pollauto-review daemon + macOS LaunchAgent + menu-bar trayFolded into the above (checklist, not separate issues yet)
pr teardown [path](aliasclose) — scalpel teardown of one review; exact-match allow-entry (no glob)pr cleanup— date-wide worktree discardpr keys— tmux review-workflow keyboard cheatsheetpr list/attach/open— session management (lands with feat(forgectl): pr <ref> — clean-room worktree review #29)Dependencies
The reviewer (#29) consumes quarantine #20 (clean-room isolation), net #19 (network posture), and launch #2 (gateway auth). Build #29 first; #30/#31/#32 build on it.
Relationship to the original merge-loop scope (above)
The original
forgectl prscope — multi-select open PRs and drive them to merge (areview-loopport) — remains valid and folds into this sub-epic as the dashboard + merge path alongside #31's discovery surfaces. The v1 recommendation (merge-only; orchestrate, don't author) still holds. The #202 flagship adds the clean-room review-session facet (#29–#32) on top of that merge-driving facet.