원클릭으로
monitor-pr
Monitor a PR for CI failures and reviewer comments, fix issues, and respond thoughtfully.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
메뉴
Monitor a PR for CI failures and reviewer comments, fix issues, and respond thoughtfully.
Codex 또는 Claude로 설치 이 Prompt를 복사해 Codex, Claude 또는 다른 어시스턴트에 붙여 넣으면 Skill 페이지를 검토하고 설치를 진행할 수 있습니다.
SOC 직업 분류 기준
Manage a PR stacked on another unmerged branch, and re-point it onto main after the base merges. Use when the user says "stack this PR", "restack", "re-point the PR base", "rebase onto main after the base merged", or has a PR whose base branch just merged.
Run `/code-review` in a fresh-context subagent, triage and address findings, then re-review — looping until no significant findings remain. Use when the user says "subagent review loop", "review loop", "loop until clean", or asks to harden a branch/PR with iterative independent review. Argument is passed through to `/code-review` (default `high`).
Drive native Windows desktop GUI apps with cua-driver (cua-computer-use MCP) — read the screen, click, type, navigate menus/forms. Use when automating a Windows application's UI, ESPECIALLY when pixel clicks land in the wrong place on a high-DPI / scaled display, or when a legacy (Delphi/VCL/Win32) app's clicks "do nothing." Covers the DPI click-offset fix and headless foreground control.
Run a self-perpetuating, multi-agent improvement loop on ANY codebase (chat, ingest, a UI, infra — anything with tests). A committed backlog of file-disjoint, waved tasks is implemented in parallel by a background Workflow, verified, adversarially reviewed, fixed, committed, and then re-scouted into the next round's backlog. Use when the user wants to iteratively harden/improve a project across many tasks ("improve X", "run a round", "keep iterating on Y", "set up an improvement loop"), to continue an existing loop ("run the next round"), or to fold a fresh ask into the next round. Requires the Workflow tool (multi-agent orchestration).
Browse any web app in a real browser using Playwright CLI. Use when asked to "check the app", "open the site", "look at the UI", "verify this page", "browse", or diagnose frontend behavior. General-purpose — not tied to any specific app.
Commit, push, and open a PR with a compelling title. Use when the user says "pr", "open a pr", "push and create pr", "commit and pr", wants to ship their branch, or before running "gh pr create".
| name | monitor-pr |
| description | Monitor a PR for CI failures and reviewer comments, fix issues, and respond thoughtfully. |
| argument-hint | [hint] — optional natural language hint, e.g. 'focus on API changes', 'skip CI' |
Monitor an open PR through CI and code review, fixing failures and addressing reviewer feedback in a loop until the PR is approved or the iteration cap is reached.
Uses background process chaining — a cheap bash script sleeps and polls gh, running in the background via run_in_background. Claude only wakes up on <task-notification>, spending zero tokens while waiting.
Set PR_REVIEWER_BOTS to a comma-separated list of bot login names whose approval gates exit. Defaults to claude[bot] if unset.
# Examples
export PR_REVIEWER_BOTS="claude[bot]"
export PR_REVIEWER_BOTS="claude[bot],my-project-reviewer[bot]"
The list is passed to poll_pr.sh and used wherever bot reviewers are checked below.
gh pr view --json number,url,title,reviewDecision,state,reviewRequests,headRefName,reviews,latestReviews
If no PR exists on the current branch, tell the user and stop.
Record the PR number, URL, head branch, owner/repo, and current state.
The primary reviewers are bots configured via $PR_REVIEWER_BOTS (default: claude[bot]). Their approval is the gate — required before exit.
Bot reviewers post verdicts in two ways:
gh api repos/.../pulls/.../reviews with states like APPROVED, CHANGES_REQUESTED✅ = approved, 🧌 = changes requested. These show up in gh api repos/.../issues/.../comments, NOT in the PR reviews API.Check both sources. The issue comment pattern is common for claude[bot] action-based reviewers.
Note the current PR state for your own reference (comment counts, CI status, review decision, bot reviewer status). You don't need to write a state file — poll_pr.sh is self-initializing and gathers its own baseline on startup.
If the user provided a hint, interpret it semantically. Examples:
Initialize: cycle = 0, max_cycles = 20
Launch poll_pr.sh in the background using the Bash tool with run_in_background: true:
/path/to/monitor-pr/poll_pr.sh "owner/repo" 42 <poll_interval_secs> [max_wait_secs]
The script is self-initializing — it gathers its own baseline state via gh API calls on startup, then loops with sleep <poll_interval_secs> until a change is detected. It does NOT exit on a timer. The optional max_wait_secs (default: 3600) is a safety net for orphaned processes, not a normal exit path.
Then idle — do nothing until <task-notification> fires. Do NOT poll, sleep, or check the task output proactively. Claude spends zero tokens while the script sleeps.
| Cycle | poll_interval_secs |
|---|---|
| 0 (initial) | 300 |
| 1 | 180 |
| 2+ | 60 |
<task-notification> FiresThe script only exits when something changed (or on safety timeout). So every notification means there's work to do.
BOT_REVIEW_CHANGED → fetch the full review comments, go to Addressing Comments. If state is APPROVED, also fetch the latest sticky comment and apply the same "top-level Medium+ findings?" check described under BOT_COMMENT_REVIEW_CHANGED below before treating this as a clean approve.BOT_COMMENT_REVIEW_CHANGED → the bot updated its sticky comment verdict:
Verdict: APPROVED → clean approve, no unresolved Medium-or-higher findings. Check exit conditions.Verdict: APPROVED_WITH_FINDINGS:<severities> → the bot approved overall but flagged one or more top-level Critical/High/Medium findings in the body. This is NOT an exit condition — fetch the full comment body (gh api repos/{owner}/{repo}/issues/{number}/comments --jq '.[-1].body') and address the listed-severity findings like any other review comment. The convention is that top-level severity markers (### Medium headings or bold **Medium** lines, ditto High/Critical) mean "fix this in this PR or as a same-day follow-up"; Minors under <details> are explicitly OK to defer.Verdict: CHANGES_REQUESTED → fetch the full comment body and address the feedback.CI_FAILURES → go to CI Failure HandlingNEW_REVIEW_COMMENTS or NEW_ISSUE_COMMENTS → go to Addressing CommentsCI_STATUS_CHANGED (all passing) → note it, check exit conditionsREVIEW_DECISION_CHANGED → check exit conditionsPR_STATE_CHANGED → check exit conditionsEvery notification handler MUST end by launching the next poll, unless an exit condition was met. This is the mechanism that keeps monitoring alive — if you skip it, monitoring silently dies.
Re-chain = launch poll_pr.sh again with run_in_background: true, using the poll interval for the current cycle:
/path/to/monitor-pr/poll_pr.sh "owner/repo" 42 <poll_interval_secs>
Then idle until the next <task-notification>. Never ask "should I keep monitoring?" — the user already opted in.
Stop the loop and announce the result when:
$PR_REVIEWER_BOTS have approved AND there are no top-level Critical/High/Medium findings in their latest sticky comment (see "What counts as a clean approve" below) AND all CI checks pass. "No reviewers requested" is NOT an exit condition — if no bot review exists yet, keep waiting.The bot's sticky comment can carry both a top-level verdict AND findings. The verdict alone is not enough — read the body.
Bot convention (commonly observed across reviewer-bot stickies):
| Body shape | Means | Counts as clean approve? |
|---|---|---|
### ✅ Approve + body has zero ### Medium-style headings or **Medium**-style bold lines (ditto High/Critical) outside <details> blocks | Clean approve | ✅ Yes |
### ✅ Approve + body has <details><summary>Minor</summary>…</details> | Approved with minors (deferrable) | ✅ Yes |
### ✅ Approve + body has a top-level ### Medium/**Medium** marker (ditto High/Critical) | Approved overall, BUT the bot wants the listed-severity items fixed in this PR or as a same-day follow-up | ❌ No — keep going |
### 🧌 Request changes (any body) | Not approved | ❌ No |
The poll_pr.sh script encodes this rule and emits APPROVED_WITH_FINDINGS:<severities> instead of APPROVED when the body has top-level severity findings. If you ever read a sticky directly (e.g. from BOT_REVIEW_CHANGED with formal-review state APPROVED), apply the same check yourself before declaring exit-ready: strip <details>...</details> blocks, then grep for ^(?:###\s+|\*\*)(Critical|High|Medium)\b — bots render severity markers both as headings (### Medium) and as bold lines (**Medium**), sometimes within the same review series.
This rule exists because the bot uses APPROVE+Medium-in-body to mean "I'd merge this, but please address X first or same-day." Treating it as a clean approve and exiting silently misses real work the reviewer wants done.
Bot reviewers may post verdicts via formal PR reviews or issue comments (sticky comment pattern). Check both.
Build the bot login filter from $PR_REVIEWER_BOTS:
# Construct a jq `or` expression: .user.login == "a" or .user.login == "b" ...
bots="${PR_REVIEWER_BOTS:-claude[bot]}"
bot_filter=$(echo "$bots" | tr ',' '\n' | awk '{printf "%s.user.login == \"%s\"", (NR>1?" or ":""), $0}')
Formal PR reviews:
gh api repos/{owner}/{repo}/pulls/{number}/reviews \
--jq "[.[] | select($bot_filter) | {user: .user.login, state: .state}]"
Possible states: APPROVED, CHANGES_REQUESTED, COMMENTED, PENDING. Only APPROVED from all configured bot reviewers satisfies the exit condition.
Issue comment verdicts (sticky comment pattern):
gh api repos/{owner}/{repo}/issues/{number}/comments \
--jq "[.[] | select($bot_filter)] | last | .body"
The bot edits a single sticky comment with its verdict. Look for emoji markers in the comment body:
✅ = approved (equivalent to APPROVED)🧌 = changes requested (equivalent to CHANGES_REQUESTED)Either source counts. The bot is satisfied only when:
APPROVED OR the sticky comment contains ✅, AND### heading or **bold** line form) outside a <details> block.poll_pr.sh checks both — when it would have emitted APPROVED based on ✅ alone but the body has top-level Medium+ headings, it emits APPROVED_WITH_FINDINGS:<severities> instead. See "What counts as a clean approve" above for the full rule.
The poll output includes failed run IDs and log tails. Read them.
To distinguish flaky from real: check if the failing test touches code we changed. If not, likely flaky.
Fix: missing import in UserService after extracting helper
CRITICAL: Evaluate every comment on its technical merits. Do not blindly implement suggestions. Do not performatively agree.
Default bias: implement. Minor suggestions (naming, small refactors, style improvements) should be implemented if they make the code better — think about what you'd wish you'd done a month from now. Only push back when a suggestion is actively harmful or introduces real complexity. "It's minor" is not a reason to skip it.
1. Read and understand the full context
2. Evaluate on its merits
3. Decide: implement, partially implement, or respectfully disagree
| Severity | Default action |
|---|---|
| Critical/High (bugs, security) | Always implement |
| Medium (design, maintainability) | Implement unless actively harmful |
| Minor (naming, style, small cleanup) | Implement — context is fresh now, cost is low |
| Disagree | Push back with reasoning (see below) |
Address review: extract validation into helper per @reviewer
gh api repos/{owner}/{repo}/pulls/{number}/comments/{comment-id}/replies \
-f body="Done — extracted into \`validateInput()\` in abc1234."
Reply on the PR thread. The tone is two engineers working through a design together:
gh api repos/{owner}/{repo}/pulls/{number}/comments/{comment-id}/replies \
-f body="Good catch — I considered that approach but went with X because [reason]. The trade-off is [trade-off]. Happy to reconsider if you think [alternative] handles [edge case] better — what do you think?"
Never reply with "I won't do this" or dismiss the feedback.
For comments on the PR itself (not inline on code):
gh pr comment {number} --body "..."
After pushing, briefly report to the user what was done this cycle:
git push
The poll script is self-initializing — it gathers baseline state via gh API on startup, then polls for changes. This avoids sharing state files between foreground and background Bash processes, which fails because run_in_background tasks run in a sandboxed /tmp.