| name | lfx-pr-resolve |
| description | Address PR review comments, fetches unresolved threads, makes code changes, commits with a summary, responds to each comment, resolves threads, posts a follow-up summary, dismisses stale "changes requested" reviews, and re-requests review. Use whenever someone wants to address PR feedback, fix review comments, resolve PR threads, or iterate on a pull request after review.
|
| allowed-tools | Bash, Read, Write, Edit, Glob, Grep, AskUserQuestion, Skill |
PR Review Comment Resolver
You address PR review feedback end-to-end: read the comments, make the code changes, commit, respond to each reviewer, resolve the threads, and post a summary. The goal is to close the feedback loop completely, reviewers should see exactly what was done and why.
Step 1: Identify the PR
Determine which PR to work on. The user may provide:
- A PR number (e.g.,
#142)
- A PR URL (e.g.,
https://github.com/org/repo/pull/142)
- Nothing, auto-detect from the current branch
Verify GitHub CLI Authentication
Before making any gh calls, verify authentication:
gh auth status 2>&1
If auth fails, stop and tell the user to run gh auth login.
Auto-detection
BRANCH=$(git branch --show-current)
gh pr list --head "$BRANCH" --state open --json number,url,title --jq '.[0]'
If no PR is found for the current branch, ask:
"I don't see an open PR for this branch. Which PR would you like to address? (Give me a number or URL)"
Step 2: Fetch PR Details and Review Threads
Derive Repository Variables
Extract the owner, repo, and PR number from the identified PR. If the user provided a URL, parse it. If auto-detected, derive from the current repo:
OWNER=$(gh repo view --json owner -q '.owner.login')
REPO=$(gh repo view --json name -q '.name')
Fetch Review Threads
Fetch the PR metadata and all review threads in a single GraphQL call. The query body lives in references/graphql-queries.md (section "Fetch PR review threads"). Run it with $OWNER, $REPO, and $NUMBER bound.
The query caps at 100 review threads and 20 comments per thread. If a PR exceeds these limits, paginate via pageInfo { hasNextPage endCursor } and the after parameter.
Identify AI Bot Reviewers
Before processing threads, identify which reviewers are AI bots. Common bot indicators:
- Username ends with
[bot] (e.g., copilot[bot], coderabbitai[bot], github-actions[bot])
- Username matches known AI review bots:
copilot, coderabbitai, codeclimate, sonarcloud, deepsource, sourcery-ai, ellipsis-dev, korbit-ai, bito-ai, pr-agent
- User type from the API is
Bot rather than User
Maintain a list of bot reviewer logins for this PR. These reviewers must never be @mentioned in any content posted to GitHub (comments, commit messages, summary). Tagging bots causes them to re-trigger and attempt to act on already-resolved feedback.
Bot comments are still actionable, address their feedback like any other reviewer. The restriction is only on @mentioning them in GitHub-posted content.
Filter to Actionable Threads
From the response, collect only unresolved threads (isResolved == false). Skip threads that are already resolved, someone else handled them or they were resolved in a previous iteration.
For each unresolved thread, extract:
| Field | Source |
|---|
| Thread ID | id (needed for resolving later) |
| File path | path |
| Line(s) | line, startLine |
| Reviewer | First comment's author.login |
| Comment body | All comments in the thread (the conversation) |
| Outdated? | isOutdated (file has changed since the comment was made) |
Edge Cases
- No unresolved threads: Tell the user, "All review threads are already resolved! Nothing to address." Stop here.
- Outdated threads: Include them but flag them, the code may have shifted since the comment was made. Read the current file to determine if the feedback still applies.
- General PR review comments (not attached to a specific line): These appear as reviews with a
body but no associated thread path. Collect these separately, they need responses but may not require code changes. You will respond to each of these later via a PR-level comment that references the reviewer and the commit that addresses their feedback (if any). When referencing reviewers, @mention human reviewers but use plain names (no @ prefix) for bot reviewers to avoid re-triggering them.
Step 3: Validate Each Comment Against Repo Patterns
Before categorizing or acting on any comment, validate whether the reviewer's feedback is actually correct. Reviewers can make mistakes; blindly implementing every comment can introduce regressions.
For each unresolved thread, follow the four-step validation flow in references/validation-heuristics.md:
- Read the actual code at the referenced location (with 20-30 lines of surrounding context).
- Check the repo's existing patterns via
grep.
- Cross-reference with project conventions (CLAUDE.md, eslint, style guides).
- Assign one of four assessments: Valid, Likely false positive, Partially valid, or Outdated, and act accordingly.
Lean toward implementing when in doubt, but always surface your assessment to the user.
Step 4: Categorize Comments
After validation, categorize each thread:
| Category | Description | Action |
|---|
| Code change | Reviewer requests a specific modification and the suggestion is valid | Make the change |
| Question | Reviewer asks "why did you...?" or "what about...?" | Respond with explanation |
| Nitpick / style | Minor formatting, naming suggestion, or preference | Make the change (quick wins build goodwill) |
| Approval with comment | "Looks good, but consider..." or "Nit: ..." with no blocking intent | Assess, fix if trivial, explain if not |
| False positive | Reviewer's suggestion conflicts with repo patterns or is based on a misread | Flag for user, recommend a polite response explaining why |
| Discussion | Architectural debate, trade-off, or open-ended feedback | Flag for user decision |
Present the Plan
Before making any changes, present the categorized comments to the user. Include your validation assessment for each item so the user can make an informed decision:
═══════════════════════════════════════════
PR #[number], REVIEW COMMENTS TO ADDRESS
═══════════════════════════════════════════
[N] unresolved threads from [reviewers]
CODE CHANGES NEEDED
───────────────────
1. ✓ @[reviewer] on [file]:[line], "[summary of what they want]"
Validated: [brief reason, e.g., "matches pattern in other components"]
2. ✓ @[reviewer] on [file]:[line], "[summary of what they want]"
Validated: [brief reason]
QUESTIONS TO ANSWER
───────────────────
3. @[reviewer] on [file]:[line], "[the question]"
LIKELY FALSE POSITIVES
──────────────────────
4. ⚠ @[reviewer] on [file]:[line], "[what they suggested]"
Assessment: [why this appears incorrect, e.g., "Reviewer suggests
BehaviorSubject but this repo uses signals for component-local state.
Found 12 components using signal() vs 3 legacy BehaviorSubjects."]
Recommendation: Respond explaining the repo convention. No code change.
NEEDS YOUR INPUT
────────────────
5. @[reviewer] on [file]:[line], "[the discussion point]"
→ What would you like me to do here?
═══════════════════════════════════════════
Shall I proceed with items 1-2? Items 4-5 need your direction.
═══════════════════════════════════════════
Wait for user approval before making changes. The user has final say on whether to implement, push back, or discuss further, especially for items flagged as potential false positives.
Responding to False Positives
When the user confirms a comment is a false positive, draft a respectful response (acknowledge intent, explain the repo convention with evidence, offer to discuss). See references/validation-heuristics.md, "Responding to a confirmed false positive" for the response template and tone.
Step 5: Address Each Comment
Work through the approved comments systematically.
For Code Changes and Nitpicks
- Read the current file at the relevant location to understand the context
- Make the change using Edit, keep changes minimal and focused on what the reviewer asked
- Verify the change, re-read the modified area to confirm it addresses the feedback
- Track what was done, keep a running log of changes for the commit message and responses
For Questions
- Read the relevant code to understand the context
- Draft a response that explains the reasoning, be specific, reference the code
- Ask the user to review the draft response if the question touches on architectural decisions or trade-offs the user should weigh in on
For Discussion Items
Only address these after the user provides direction in Step 4.
Delegation to Builder Skills
For complex changes that span multiple files or require repo-specific pattern
knowledge (e.g., "refactor this to use signals instead of BehaviorSubject"),
route to the owning repo's local workflow. Use /lfx-skills:lfx when the
owner is unclear, then use that repo's CLAUDE.md and local skills.
Skill(skill: "<repo-local-skill>", args: "FIX PR REVIEW: [description of the change needed]. File: [path]. Context: reviewer asked for [what they said]. Follow the existing pattern in [example file].")
Skill(skill: "<repo-local-skill>", args: "FIX PR REVIEW: [description of the change needed]. Repo: [path]. Context: reviewer asked for [what they said].")
For simple, targeted fixes (rename a variable, add a null check, fix an import), make the change directly, no need to delegate.
Step 6: Validate Changes
After all code changes are made, run validation. Delegate to preflight with --skip-review since this is an iteration, not a fresh PR:
yarn format && yarn lint && yarn build
go vet ./... && go build ./...
If validation fails, fix the issues before proceeding. Do not commit broken code.
Step 7: Commit with Detailed Summary
Create a single commit that summarizes all changes made to address the review feedback.
Commit Message Format
The commit message must clearly state what review feedback was addressed, so that both git history readers and PR reviewers can understand what happened:
fix(review): address PR #[number] review feedback
Address review comments from @[human-reviewer], botname[bot]:
- [file]: [what was changed and why] (per @[human-reviewer])
- [file]: [what was changed and why] (per botname[bot])
- [file]: responded to question about [topic]
Resolves [N] review threads.
Note: The --signoff flag automatically appends the Signed-off-by: trailer, do not include it manually in the message body.
Commit Rules
- One commit per review iteration, don't create separate commits per comment. Reviewers want to see a single cohesive response to their feedback.
- Reference the PR number in the commit subject.
- Credit human reviewers, mention who asked for each change. This helps when reading git blame later. Never
@mention bot reviewers in commit messages, use their plain name without the @ prefix (e.g., copilot[bot] not @copilot[bot]).
- Include
--signoff and -S, --signoff is required for DCO compliance, -S for GPG-signed commits. Both are enforced on LFX repos.
- List every change, the commit body should be a complete record. Someone reading the commit message should know exactly what review feedback was addressed without needing to read the diff.
git add [specific files that were changed]
git commit -S --signoff -m "$(cat <<'EOF'
fix(review): address PR #[number] review feedback
Address review comments from @[human-reviewer], botname[bot]:
- path/to/file.ts: renamed variable per reviewer suggestion (per @alice)
- path/to/component.html: added loading guard for stats display (per copilot[bot])
- path/to/service.ts: explained error handling approach (no code change)
Resolves 3 review threads.
EOF
)"
Step 8: Push Changes
Push the commit to the remote branch before posting any comments, resolving threads, or posting summaries. This ensures that when bots and reviewers are notified of your responses, the code changes are already available for them to validate.
git push
If the push fails due to remote changes, pull and rebase first:
git pull --rebase origin $(git branch --show-current)
yarn lint && yarn build
git push
Step 9: Respond to Each Comment Thread
After pushing, respond to each review thread on GitHub. This is the critical feedback loop, reviewers need to know their comments were heard and addressed.
Response Format by Category
Post each reply with the addPullRequestReviewThreadReply mutation in references/graphql-queries.md (section "Reply to a review thread"), bound to $THREAD_ID and $RESPONSE_BODY.
For code changes made:
Response body:
Done, [specific description of the change made].
See commit [short SHA]: [one-line summary of what changed in this file].
For questions answered (no code change):
[Clear, specific answer to the question with code references where helpful].
No code change needed, [brief explanation of why the current approach is correct].
For nitpicks fixed:
Fixed, [what was changed]. Good catch!
For discussion items where user provided direction:
[Explanation of the decision and reasoning].
[Description of what was changed, or why no change was made].
For false positives (user confirmed no change needed):
Thanks for flagging this, I can see why it looks [wrong/inconsistent/off].
[Explanation with evidence: "This repo uses [pattern X] for [reason]. You can see
the same approach in [file1], [file2], etc."]
[If applicable: "Happy to discuss further if you think we should reconsider."]
Response Rules
- Be specific, don't say "Fixed." Say what was fixed and how.
- Reference the commit, include the short SHA so reviewers can jump to the exact change.
- Keep it concise, one or two sentences for simple fixes, a short paragraph for questions or discussions.
- Be professional and appreciative, reviewers spent time reading the code. Acknowledge good catches.
- Never
@mention bot reviewers, when replying to a bot's thread, do not include @botname in the response body. Tagging bots causes them to re-trigger and attempt to re-review or act on already-resolved feedback.
Step 10: Resolve Review Threads
After responding to each thread, resolve it with the resolveReviewThread mutation in references/graphql-queries.md (section "Resolve a review thread"), bound to $THREAD_ID. Only resolve threads where the feedback has been fully addressed, if a thread required user input and the user chose not to address it, leave it unresolved.
Do NOT Resolve If
- The comment was a discussion point and no conclusion was reached
- The user explicitly said to skip or defer a comment
- The change couldn't be made due to a technical constraint (explain why in the response, leave unresolved)
- You're unsure whether your change fully addresses the feedback, leave unresolved and let the reviewer confirm
Step 11: Post Summary Comment
After all threads are responded to and resolved, post a single summary comment on the PR. This gives reviewers a one-stop overview of everything that was addressed in this iteration:
gh pr comment $NUMBER --repo $OWNER/$REPO --body "$(cat <<'EOF'
## Review Feedback Addressed
Commit: [full SHA]
### Changes Made
- **[file]**: [what changed] (per @[human-reviewer])
- **[file]**: [what changed] (per botname[bot])
### Questions Answered
- **[file]:[line]**: [brief answer] (asked by @[human-reviewer])
[If any comments were identified as false positives:]
### No Change Needed
- **[file]:[line]**: [brief explanation of why the current code is correct and what repo pattern it follows] (flagged by botname[bot])
### Threads Resolved
[N] of [M] unresolved threads addressed in this iteration.
[If any threads were left unresolved:]
### Still Open
- **[file]:[line]**: [why it was left open, e.g., "deferred to follow-up PR", "awaiting reviewer confirmation"]
EOF
)"
Summary Rules
- List every thread that was addressed, not just code changes
- Group by action type, changes made, questions answered, deferred
- Include the commit SHA so reviewers can see the full diff
- Call out anything left open, don't hide unresolved items
- Credit human reviewers by
@mentioning them next to their feedback (e.g., write (per @alice) or (asked by @bob))
- Never
@mention bot reviewers in the summary, use their plain name without the @ prefix (e.g., write (per copilot[bot]) not (per @copilot[bot])). Tagging bots in the summary causes them to re-trigger and attempt to act on already-resolved feedback.
Step 12: Dismiss Stale Reviews and Re-request
If changes were pushed in Step 8, dismiss any CHANGES_REQUESTED reviews from reviewers whose feedback was fully addressed in this iteration, then re-request their review so they receive a notification. If no code changes were made (e.g., only questions answered), skip this step.
See references/dismiss-rerequest.md for the full flow (identify reviews, dismiss, re-request, edge cases).
Step 13: Report to User
Present the final status:
═══════════════════════════════════════════
PR #[number], REVIEW FEEDBACK ADDRESSED
═══════════════════════════════════════════
Commit: [SHA], [commit subject]
Pushed to: [branch]
Threads addressed: [N] of [M]
✓ [N] code changes made
✓ [N] questions answered
✓ [N] threads resolved on GitHub
[- [N] left open (needs reviewer input)]
[If reviews were dismissed:]
Reviews refreshed:
✓ Dismissed "changes requested" from @[reviewer1], @[reviewer2]
✓ Re-requested review from @[reviewer1], @[reviewer2]
Summary comment posted: [PR URL]
What's next:
- Reviewers have been re-requested and will be notified
- Check back with /lfx-pr-catchup to monitor the PR
[- [N] threads still need discussion, follow up with the reviewer]
═══════════════════════════════════════════
Idempotency, Safe to Re-run
If the user runs this skill again on the same PR:
- Re-fetch threads, only pick up threads that are still unresolved
- Skip already-resolved threads, don't re-address or re-respond
- New comments since last run, treat them as fresh feedback
- Tell the user: "Found [N] new/remaining unresolved threads since the last iteration."
Scope Boundaries
This skill DOES:
- Fetch and analyze PR review threads
- Categorize comments by type (code change, question, discussion)
- Make targeted code changes to address review feedback
- Commit with a detailed summary of what was addressed
- Respond to each review thread on GitHub
- Resolve addressed threads
- Post a summary comment on the PR
- Push changes to the remote branch
- Dismiss stale "changes requested" reviews after addressing feedback
- Re-request review from reviewers whose feedback was addressed
- Route complex changes to the owning repo's local skills and
CLAUDE.md
This skill does NOT:
- Create new PRs (use the owning repo's local preflight/readiness flow first)
- Build new features from scratch (use the owning repo's local development skill)
- Review code (use the configured reviewer agents or repo-local review workflow)
- Merge PRs (the reviewer does that)
- Resolve threads where the feedback wasn't fully addressed