From claude-commands
Iteratively drives a pull request to meet all 6 green conditions (CI passing, no merge conflicts, CodeRabbit approval, resolved comments, etc.) via fix-and-verify loops. Does not merge.
How this command is triggered — by the user, by Claude, or both
Slash command
/claude-commands:polishcommands/The summary Claude sees in its command listing — used to decide when to auto-load this command
## ⚡ EXECUTION INSTRUCTIONS FOR CLAUDE **When this command is invoked, YOU (Claude) must execute these steps immediately.** **This is NOT documentation - these are COMMANDS to execute right now.** **Use TodoWrite to track progress through multi-phase workflows.** **Usage:** `/polish [N] [PR_NUMBER]` - `N` = max iterations (default: 5) - `PR_NUMBER` = target PR (default: auto-detect from current branch) **Goal:** Drive the PR to all 6 green conditions, looping up to N times. **CRITICAL — DO NOT MERGE:** This command evaluates and fixes PR readiness. It NEVER executes merge commands (`gh ...
When this command is invoked, YOU (Claude) must execute these steps immediately. This is NOT documentation - these are COMMANDS to execute right now. Use TodoWrite to track progress through multi-phase workflows.
Usage: /polish [N] [PR_NUMBER]
N = max iterations (default: 5)PR_NUMBER = target PR (default: auto-detect from current branch)Goal: Drive the PR to all 6 green conditions, looping up to N times.
CRITICAL — DO NOT MERGE: This command evaluates and fixes PR readiness. It NEVER executes merge commands (gh pr merge, gh api .../merge). Merging requires explicit human "MERGE APPROVED" in the conversation. Reporting "6-green" is the terminal state — not merging. This rule is enforced by PreToolUse hook block-merge-worldarchitect.sh for your-project.com.
status: IN_PROGRESS → not pass — poll/retry until all are COMPLETED, then verify conclusions.mergeable: MERGEABLE (handle UNKNOWN by retrying/poll)APPROVEDstatusCheckRollup → acceptable (not configured). If present: conclusion SUCCESS/NEUTRAL/SKIPPED → pass. If present with conclusion: null and status: IN_PROGRESS → poll/retry until complete. Treat FAILURE, ERROR, TIMED_OUT, CANCELLED, ACTION_REQUIRED as red, consistent with condition 1./er returns PASS (skip if no evidence bundle)# Derive repo context once before the loop
REPO_FULL="$(gh repo view --json nameWithOwner --jq '.nameWithOwner')"
OWNER="${REPO_FULL%%/*}"
NAME="${REPO_FULL##*/}"
PR="<PR_NUMBER>"
for iteration in 1..N:
1. Run /copilot <PR_NUMBER> # fetch + triage all comments, fix blocking issues
2. Run /fixpr <PR_NUMBER> # fix any remaining inline PR blockers
3. Run /er # check evidence bundle (skip if none present)
4. If changes made → commit + push with /pushl
5. Wait for CI to settle (gh run watch or poll statusCheckRollup)
6. Evaluate 6 green conditions:
# Fetch CI status and mergeability
gh pr view <PR_NUMBER> --json statusCheckRollup,mergeable,mergeStateStatus
# Use GraphQL to get bot-specific reviews and thread resolution.
# Paginate reviewThreads: real PRs can exceed 100 threads (see automation/jleechanorg_pr_automation).
# reviewThreads uses cursor-based pagination: on first call omit cursor entirely (pass no cursor param — not even empty string);
# read pageInfo { hasNextPage endCursor }; if hasNextPage is true, re-run with -f cursor=<endCursor>,
# accumulating all nodes until hasNextPage is false. Do NOT pass cursor="" — GitHub GraphQL rejects empty string cursors.
# If any thread may have >20 comments, page through that thread's comments connection using its pageInfo until all comments are collected.
# Note: the reviews connection uses last:100 ordered chronologically by submittedAt — sufficient for most PRs; if CR has >100 reviews, accumulate in reverse order. Add pageInfo to all paginated connections for cursor-based navigation.
gh api graphql \
-f query='
query($owner:String!, $name:String!, $pr:Int!, $cursor:String) {
repository(owner:$owner, name:$name) {
pullRequest(number:$pr) {
reviews(last:100) {
pageInfo { hasNextPage endCursor }
nodes { author { login } state bodyText submittedAt }
}
reviewThreads(first:100, after:$cursor) {
pageInfo { hasNextPage endCursor }
nodes {
isResolved
comments(last:20) {
pageInfo { hasNextPage endCursor }
nodes { author { login } body }
}
}
}
}
}
}
' \
-f owner="$OWNER" -f name="$NAME" -F pr="$PR"
- Check CI: statusCheckRollup shows no FAILURE/ERROR/TIMED_OUT/CANCELLED/ACTION_REQUIRED
- Check mergeable: MERGEABLE (handle UNKNOWN state by polling)
- Filter reviews by author.login matching "coderabbitai" (GitHub GraphQL may return bot logins with or without the `[bot]` suffix — test both `coderabbitai` and `coderabbitai[bot]`) → sort chronologically using `submittedAt`, find most recent APPROVED. If the most recent CR review is NOT APPROVED, fail. Additionally: if the most recent APPROVED has a more recent CHANGES_REQUESTED or COMMENTED after it, the APPROVED is stale — fail in that case too. Only pass when the latest CR review IS APPROVED and no newer CHANGES_REQUESTED/COMMENTED exists after it.
- Filter statusCheckRollup by name containing "Bugbot" → if absent from statusCheckRollup entirely → acceptable (Bugbot not configured for this repo). If present with conclusion SUCCESS/NEUTRAL/SKIPPED → pass. If present with conclusion null AND status IN_PROGRESS → poll/retry (not pass). Treat FAILURE, ERROR, TIMED_OUT, CANCELLED, ACTION_REQUIRED as red.
- Check reviewThreads: verify no unresolved Major/Critical comments
- Check evidence: /er PASS or no bundle
7. If ALL 6 green → STOP, report success
8. Continue to next iteration
Note on CI evaluation timing: Each iteration pushes (step 4) then waits for CI to settle (step 5), so fixes land before the next iteration's evaluation. With N=1 and fixes needed, CI must complete and re-run before the loop can report green.
Use TodoWrite to track progress through each iteration.
# Parse N (first numeric arg) and PR_NUMBER (second arg or auto-detect)
gh pr view --json number,title,url,headRefName --jq '{number, title, url, headRefName}'
Run the loop algorithm above up to N times (default 5).
Apply intelligence: if /copilot finds no blocking issues and CI is already green, skip to evaluation immediately rather than making unnecessary changes.
IMPORTANT — Uncommitted changes guard: Before evaluating green conditions (Step 6), verify there are no uncommitted changes with git status --porcelain (covers staged, unstaged, AND untracked files). If any output exists, do NOT report the PR as green — commit first with /pushl before Step 7 evaluation.
Report final status:
Print a final status table with all 6 conditions and their current state.
npx claudepluginhub jleechanorg/claude-commands --plugin claude-commands/handle-pr-commentsIterates through all PR review comments, fixes issues, responds to threads, and ensures CI passes before marking the PR complete.
/pr-review-fix-loopRuns iterative PR review and autofix loop: reviews code, fixes issues above criticality threshold with auto-detected test/lint commands, repeats until clean. Supports Ruby, Node, Python, Go, Rust.
/address-pr-commentsTriages and addresses PR comments from code review bots: analyzes feedback, prioritizes issues, fixes valid concerns, and declines incorrect suggestions.
/self-reviewSelf-reviews a GitHub PR via <PR_URL>: checks CI status, merge conflicts, diff noise, description consistency, commits, reviewability; identifies issues and suggests fixes.
/shepherdShepherds pull requests through CI checks and code reviews to merge readiness. Iteratively assesses stack, fixes issues, resubmits, and requests approval.
/pr-reviewReviews GitHub PR comments by priority, applies fixes via code edits, commits and pushes changes, verifies CI status, and outputs a markdown summary.