Install any skill in seconds. Free to start, no credit card required.
Get Started Free →Iterate on a PR until CI passes. Use when you need to fix CI failures, address review feedback, or continuously push fixes until all checks are green. Automates the feedback-fix-push-wait cycle.
.claude/skills/iterate-pr/SKILL.md| Test case | Without → With | Effect | Δ tokens | Δ turns |
|---|---|---|---|---|
| case-11 | ✗→✓ | ▲ Improved | — | — |
| case-13 | ✗→✓ | ▲ Improved | — | — |
| case-17 | ✗→✓ | ▲ Improved | — | — |
| case-04 | ✗→✓ | ▲ Improved | — | — |
| case-12 | ✗→✓ | ▲ Improved | — | — |
Continuously iterate on the current branch until all CI checks pass and review feedback is addressed.
Requires: GitHub CLI (gh) authenticated.
Important: All scripts must be run from the repository root directory (where .git is located), not from the skill directory. Use the full path to the script via ${CLAUDE_SKILL_ROOT}.
scripts/fetch_pr_checks.pyFetches CI check status and extracts failure snippets from logs.
bashuv run ${CLAUDE_SKILL_ROOT}/scripts/fetch_pr_checks.py [--pr NUMBER]
Returns JSON:
json{ "pr": {"number": 123, "branch": "feat/foo"}, "summary": {"total": 5, "passed": 3, "failed": 2, "pending": 0}, "checks": [ {"name": "tests", "status": "fail", "log_snippet": "...", "run_id": 123}, {"name": "lint", "status": "pass"} ] }
scripts/fetch_pr_feedback.pyFetches and categorizes PR review feedback using the LOGAF scale.
bashuv run ${CLAUDE_SKILL_ROOT}/scripts/fetch_pr_feedback.py [--pr NUMBER]
Returns JSON with feedback categorized as:
high - Must address before merge (h:, blocker, changes requested)medium - Should address (m:, standard feedback)low - Optional (l:, nit, style, suggestion)bot - Informational automated comments (Codecov, Dependabot, etc.)resolved - Already resolved threadsReview bot feedback (from Sentry, Warden, Cursor, Bugbot, CodeQL, etc.) appears in high/medium/low with review_bot: true — it is NOT placed in the bot bucket.
Each feedback item may also include:
thread_id - GraphQL node ID for inline review comments (used for replies)bashgh pr view --json number,url,headRefName
Stop if no PR exists for the current branch.
Run ${CLAUDE_SKILL_ROOT}/scripts/fetch_pr_feedback.py to get categorized feedback already posted on the PR.
Auto-fix (no prompt):
high - must address (blockers, security, changes requested)medium - should address (standard feedback)When fixing feedback:
This includes review bot feedback (items with review_bot: true). Treat it the same as human feedback:
Prompt user for selection:
low - present numbered list and ask which to address:Found 3 low-priority suggestions:
1. [l] "Consider renaming this variable" - @reviewer in api.py:42
2. [nit] "Could use a list comprehension" - @reviewer in utils.py:18
3. [style] "Add a docstring" - @reviewer in models.py:55
Which would you like to address? (e.g., "1,3" or "all" or "none")Skip silently:
resolved threadsbot comments (informational only — Codecov, Dependabot, etc.)After processing each inline review comment, reply on the PR thread to acknowledge the action taken. Only reply to items with a thread_id (inline review comments).
When to reply:
high and medium items — whether fixed or determined to be false positiveslow items — whether fixed or declined by the userHow to reply: Use the addPullRequestReviewThreadReply GraphQL mutation with pullRequestReviewThreadId and body inputs.
Reply format:
\n\n*— Claude Code**- Claude Code* or *— Claude Code* to avoid duplicates on re-loopsgh api call fails, log and continue — do not block the workflowRun ${CLAUDE_SKILL_ROOT}/scripts/fetch_pr_checks.py to get structured failure data.
Wait if pending: If review bot checks (sentry, warden, cursor, bugbot, seer, codeql) are still running, wait before proceeding—they post actionable feedback that must be evaluated. Informational bots (codecov) are not worth waiting for.
For each failure in the script output:
log_snippet and trace backwards from the error to understand WHY it failed — not just what failedDo NOT assume what failed based on check name alone—always read the logs. Do NOT "quick fix and hope" — understand the failure thoroughly before changing code.
Before committing, verify your fixes locally:
If local verification fails, fix before proceeding — do not push known-broken code.
bashgit add <files> git commit -m "fix: <descriptive message>" git push
Poll CI status and review feedback in a loop instead of blocking:
uv run ${CLAUDE_SKILL_ROOT}/scripts/fetch_pr_checks.py to get current CI statusa. Run uv run ${CLAUDE_SKILL_ROOT}/scripts/fetch_pr_feedback.py for new review feedback b. Address any new high/medium feedback immediately (same as step 3) c. If changes were needed, commit and push (this restarts CI), then continue polling d. Sleep 30 seconds, then repeat from sub-step 1
sleep 10, then run uv run ${CLAUDE_SKILL_ROOT}/scripts/fetch_pr_feedback.py. Address any new high/medium feedback — if changes are needed, return to step 6.If step 7 required code changes (from new feedback after CI passed), return to step 2 for a fresh cycle. CI failures during monitoring are already handled within step 7's polling loop.
Success: All checks pass, post-CI feedback re-check is clean (no new unaddressed high/medium feedback including review bot findings), user has decided on low-priority items.
Ask for help: Same failure after 2 attempts, feedback needs clarification, infrastructure issues.
Stop: No PR exists, branch needs rebase.
If scripts fail, use gh CLI directly:
gh pr checks name,state,bucket,linkgh run view <run-id> --log-failedgh api repos/{owner}/{repo}/pulls/{number}/commentsUse this skill when tackling tasks related to its primary domain or functionality as described above.
| Case | Status | Duration (ms) | Turns | Tokens | Tool calls | ||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
| Without | With | Δ | Without | With | Δ | Without | With | Δ | Without | With | Δ | ||
case-11 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-13 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-02 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-01 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-06 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-07 | pass→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-17 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-22 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-19 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-09 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-16 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-04 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-21 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-12 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-05 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-08 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-20 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-14 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
case-18 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-15 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-10 | fail→pass | — | — | — | — | — | — | — | — | — | — | — | — |
case-03 | fail→fail | — | — | — | — | — | — | — | — | — | — | — | — |
DecimalAI ran this skill against gemini-3.6-flash twice over the same eval suite — once with the skill loaded and once without — and compared the two runs case by case. 22 cases were attempted, and 16 counted toward the lift figure. The other 6 produced results that are not comparable between the two arms, so they are excluded from the headline rather than averaged into it. The headline lift of +45 percentage points is the difference between those two pass rates over the 16 comparable cases. 2 cases got worse with the skill loaded, and they are included in that figure.
The per-case answers from this run were removed by the retention sweep, so the case table below shows the verdicts without the text either arm produced. The counts above were recorded at the time and are unaffected. Answers are now kept for 180 days.
Other measured skills in the registry, with their headline benchmark lift.