PR Resolve Review
Address PR review comments: analyze feedback, make code fixes, reply to reviewers, commit, push, and update the PR.
When to Use
- When a PR has review comments that need to be addressed
- When invoked from
pr-monitorskill after detecting review feedback
Input
Arguments: $ARGUMENTS
Expected form:
- (no arguments) — auto-detect the PR from the current branch
<PR-number>— optional explicit PR number (e.g.,42)
Input resolution
Arguments are optional. Resolve each field:
- PR number —
$ARGUMENTS→ auto-detect from current branch viagh pr view --json number,url,baseRefName,headRefName,author. Abort with a clear message if no PR exists. Do NOT prompt.
Phase 1: Detect PR and Load Context
1.1 Detect PR
Auto-detect the PR from the current branch:
gh pr view --json number,title,url,baseRefName,headRefName,author,mergeable
If no PR found, abort: "No pull request found for the current branch. Create one first with /autopilot:pr-create."
Store the PR number, repo owner/name (extract from url), and author login.
If mergeable is CONFLICTING, abort — fixes pushed onto a conflicting branch stay unmergeable, so resolving review feedback here only buries the reason the pull request is stuck:
PR #N conflicts with <base-branch> and cannot merge. Resolve the conflict first — the Conflict Sweep in the pr-monitor skill rebases the branch onto its base the sanctioned way.
mergeable is UNKNOWN while GitHub is still computing mergeability, and this skill reads it once rather than in a poll loop, so a cold pull request very often answers UNKNOWN on the first read. Re-read it once after a few seconds; if it is still UNKNOWN, proceed and say so rather than treating a pending answer as a clean one. Without that re-read the guard would silently pass in exactly the case it exists for. When pr-monitor invokes this skill it has already swept, so this branch is reached mainly on a standalone invocation.
1.2 Check Working Tree
git status --porcelain
If uncommitted changes exist, use AskUserQuestion:
Tool parameters:
question: "You have uncommitted changes.\n\nReview fixes will create new commits. Stash or commit changes first?"header: "Uncommitted"options: [ { label: "Continue anyway", description: "Proceed with uncommitted changes present" }, { label: "Cancel", description: "Stop so I can handle changes first" } ]multiSelect: false
If "Cancel", stop.
1.3 Load PR Diff
gh pr diff <PR_NUMBER>
1.4 Load Review Comments
Read github-review-fetch.md for the review-thread helper invocation and its output contract, then run it via Bash with <OWNER>/<REPO>, <PR_NUMBER>, and <AUTHOR_LOGIN>.
After it completes:
- Codebase reads during Phase 3 (code fixes) are targeted
Grep/Readof the code a comment points at — never a sweep of the tree - Store the helper's JSON —
reviewState, the severity-taggedcomments(each carrying thecommentIdused for replies in Phase 5 and theauthorReplied/lastAuthorReplyfields for judging in-model whether a comment is already addressed), andnote— use in Phase 2; surface a non-nullfetchErrorper the shared block instead of treating the fetch as empty
1.5 Project Rules
- CLAUDE.md - Apply project rules when making fixes
- context7/Ref/Exa - Look up docs for unfamiliar APIs referenced in review comments
- Perplexity - Web search for general info
Phase 2: Present Findings to User
Formatting Note: Read askuserquestion-format.md and apply it before composing the question parameter.
Build a summary of all findings, grouping the agent's comments by severity:
Review Comments for PR #<N>
Blockers (N):
<file>:<line> - @<reviewer>: <comment summary>
<file>:<line> - @<reviewer>: <comment summary>
Suggestions (N):
<file>:<line> - @<reviewer>: <comment summary>
Nitpicks (N):
<file>:<line> - @<reviewer>: <comment summary>
Questions to answer (N):
<file>:<line> - @<reviewer>: <comment summary>
If the agent returned comments: [] with note: "no-comments":
- Output: "No unresolved review comments found on PR #N."
- Stop
If it returned comments: [] with note: "all-resolved":
- Output: "All review comments on PR #N are already resolved."
- Stop
Present using AskUserQuestion:
Tool parameters:
question: The summary text above (plain text, no markdown)header: "Review"options: [ { label: "Address all", description: "Fix blockers, suggestions, and nitpicks; reply to questions" }, { label: "Review individually", description: "Approve each fix one by one (replies always post)" }, { label: "Cancel", description: "Exit without changes" } ]multiSelect: false
If "Cancel", stop without changes.
Phase 3: Address Comments (Code Fixes)
Process in priority order: Blockers → Suggestions → Nitpicks.
ALL categories (Blockers, Suggestions, Nitpicks) must be processed. For each comment: fix the code if the suggestion is reasonable, or draft a reply explaining why the current approach is correct. No category may be silently skipped regardless of PR approval status.
For each comment requiring a code change:
Read the file at the commented location and surrounding context (at least 20 lines before and after)
Understand the reviewer's intent — what specifically needs to change and why
Look up documentation if the fix involves unfamiliar APIs (using context7/Ref/Exa/Perplexity)
Make the code change using the Edit tool
If "Review individually" was selected, present each fix with AskUserQuestion before applying:
Tool parameters:
question: ":\n\nReviewer: \n\nProposed fix: "header: "Fix"options: [ { label: "Apply fix", description: "Make this change" }, { label: "Decline with reply", description: "Draft a reply explaining why this won't be addressed" } ]multiSelect: false
For comments that do not require code changes (questions, misunderstandings):
- Evaluate the comment against the actual codebase — read the code, check if the reviewer's concern is valid
- Draft a reply — concise, direct, 1-3 sentences; format references per [RFC-0001](/rfc/0001-reference-formatting.md) (the Reference formatting & readability rules inlined at the end of this skill; see Phase 5). A
CHECK-rule code you cite — e.g. when you echo the finding you are answering — is a reference, not a code specimen: render it as a link to the rule's anchor exactly as Phase 5 prescribes, never bare text. Reply shapes:- If reviewer is wrong: "You're right that [X looks concerning], but [reason it's correct]. [Evidence from code]."
- If needs discussion: "[Acknowledge point], however [concern or alternative]."
- If question: "[Direct answer with reference to code]."
- Store the reply for Phase 5
Phase 4: Commit and Push
4.1 Check for Changes
git status --porcelain
If no changes (only replies needed, no code fixes), skip to Phase 5.
4.2 Commit
Before invoking commits-create, compile a modification list from the changes made in Phase 3. For each code change, write one bullet naming the concrete modification (file, function, value, or behavior that changed).
Example modification list:
- Replace 30s timeout with 60s in releaseClient.ts
- Remove try-catch wrapper from fetchRelease()
- Change notes parameter type from string to string[]
- Remove redundant null guard in parseVersion()
FORBIDDEN in context passed to commits-create: The words "review", "reviewer", "feedback", "comment", "suggestion", "nitpick", or any reference to the review-resolution origin of changes. The context must not contain any of these words.
Invoke Skill(autopilot:commits-create). Pass the modification list as the commit context in conversation text. Do NOT include any other context about why changes were made.
4.3 Push
git push
Read git-history-policy.md before running anything else here. The push above is a plain fast-forward and needs nothing more; a rejection is the case that matters. If it is rejected as non-fast-forward, report that and stop — never reconcile by merging the base branch, and never retry with a force push.
Phase 5: Reply to Review Threads
Compose replies for all processed comments. Always mention the reviewer with @<username> at the start of each reply.
- Fixed comments (commit pushed): "@<reviewer> Fixed in — [brief description of what changed]."
- Fixed comments (no commit to cite): "@<reviewer> Fixed — [brief description of what changed]."
- Not applicable / misunderstood: "@<reviewer> [Explanation of why the current code is correct or why the change isn't needed]."
- Partially addressed: "@<reviewer> [What was changed and why, plus what was intentionally kept]."
- Declined by user: "@<reviewer> Considered — [explanation of why this suggestion was not applied]."
Format every reply per [RFC-0001](/rfc/0001-reference-formatting.md) — the Reference formatting & readability rules inlined at the end of this skill. The reference kind that recurs here is the commit SHA: when a reply cites the commit that resolved a thread (the HEAD commit after Phase 4's push, post-rebase/squash), render the SHA as a markdown link [<sha>](<repo-commit-url>/<sha>) built from the repo owner/name resolved in Phase 1 — never a bare or backticked SHA. Because replies post as GitHub comments, link any file, doc, skill, agent, or section you cite as an absolute <repo-blob-url>/path#anchor URL built from the same repo owner/name — never a bare name or a repo-relative path (relative paths do not resolve in a comment). A CHECK- rule code (e.g. CHECK-PR-009) is a reference, not a code specimen: render it as a link exactly as the pr-review skill's §2.5 prescribes — [CHECK-PR-009](<rules-doc-url>#check-pr-009), the fragment being the rule code lowercased — never the bare code. Build <rules-doc-url> as the absolute blob URL to the pr-review SKILL.md from the repo owner/name resolved in Phase 1 — <repo-blob-url>/claude-plugins/autopilot/skills/pr-review/SKILL.md, whose lowercase #check-... fragment lands on the <a id="..."> anchor above each rule (GitHub renders those ids lowercased, and fragment lookup is case-sensitive) — falling back to the bare code in plain text only when no such URL is resolvable. Replies that cite no commit (e.g. questions, declines) skip the SHA rule; all other reference kinds still follow the inlined rules. Before posting, self-check every drafted reply: a bare 7–40-char hex token or a bare tracker id ([A-Z][A-Z0-9]*-[0-9]+) is a violation — link it per the rules above.
Build a summary of all drafted replies:
Drafted replies for PR #<N>
Fixed (N):
<file>:<line> - "Fixed - [description]"
Explained (N):
<file>:<line> - "[reply text]"
Output the summary above as plain text, then post every drafted reply immediately — do not ask for approval. Before posting, resolve your login with gh api user --jq .login and fetch the existing comments — inline threads via gh api repos/<OWNER>/<REPO>/pulls/<PR_NUMBER>/comments, top-level via gh api repos/<OWNER>/<REPO>/issues/<PR_NUMBER>/comments; skip an inline thread whose latest comment (matching by in_reply_to_id) is already yours, and skip a top-level reply whose body you already posted — this keeps re-runs idempotent. If a post fails, continue with the remaining replies and list the failures under Failed in the Phase 6 summary.
Post replies using the GitHub API:
For inline review comment threads:
gh api repos/<OWNER>/<REPO>/pulls/<PR_NUMBER>/comments/<COMMENT_ID>/replies -f body="<reply>"
For top-level review comments:
gh api repos/<OWNER>/<REPO>/issues/<PR_NUMBER>/comments -f body="<reply>"
Phase 6: Update PR and Summary
6.1 Update PR
Invoke Skill(autopilot:pr-update) — refreshes the PR description reflecting the new state.
6.2 Summary
Output results:
Resolve Review Complete
Fixed (N comments):
<file>:<line> - <description of fix>
Replied (N comments):
<file>:<line> - <reply summary>
Declined (N comments):
<file>:<line> - <reply summary>
Failed (N replies):
<file>:<line> - <post error>
Commit: <commit message>
Pushed to origin/<branch>
PR #<N> updated: <url>
If no code changes were made (only replies):
Resolve Review Complete
Replied (N comments):
<file>:<line> - <reply summary>
Failed (N replies):
<file>:<line> - <post error>
No code changes needed.
PR #<N>: <url>
Edge Cases
- No PR found → abort with suggestion to create one
- PR conflicts with its base (
mergeableisCONFLICTING) → abort and name the Conflict Sweep as the fix; fixes pushed onto a conflicting branch stay unmergeable - Mergeability still
UNKNOWNafter the re-read → proceed, saying that mergeability could not be confirmed - No review comments → "No unresolved review comments found on PR #N"
- All comments resolved → "All review comments on PR #N are already resolved"
- No code changes needed → skip commit/push, only post replies
- Uncommitted changes → warn user before starting
- Push fails → report error, suggest
git pull --rebaseor manual resolution - Multiple reviewers → group comments by reviewer within each severity category
Reference formatting
Before writing any output that mentions a file, standard, section, commit, or issue, read reference-formatting.md (RFC-0001) and apply it verbatim — link files, docs, skills, agents, and sections, and never leave a reference as bare text.