Systematically handle GitHub PR review feedback: fetch comments, plan responses, make code changes, and reply to reviewers with explicit approval at each stage.
90
90%
Does it follow best practices?
Impact
Pending
No eval scenarios have been run
Advisory
Suggest reviewing before use
Handle GitHub PR review feedback systematically: fetch comments, plan responses, make code changes, and reply to reviewers — all with explicit user approval at each stage.
gh CLI must be authenticated (gh auth status)If the user provided a PR URL, extract the owner, repo, and PR number from it.
If no URL was provided, detect the PR from the current branch:
gh pr view --json number,url,title,headRefNameIf no PR is found for the current branch, stop and tell the user — you cannot proceed without a PR.
Gather all three sources of PR feedback: inline review threads, review-body comments, and PR-level issue comments.
gh api graphql -f query='
query($owner: String!, $repo: String!, $number: Int!) {
repository(owner: $owner, name: $repo) {
pullRequest(number: $number) {
reviewThreads(first: 100) {
nodes {
id
isResolved
isOutdated
path
line
comments(first: 50) {
nodes {
id
databaseId
author { login }
body
path
line
startLine
createdAt
url
}
}
}
}
reviews(first: 50) {
nodes {
id
databaseId
author { login }
body
state
createdAt
url
}
}
}
}
}' -f owner=OWNER -f repo=REPO -F number=NUMBERReview bodies are a distinct feedback source — reviewers often put feedback in the top-level review body rather than on specific lines. Parse each review body to extract individual actionable items and treat each separately in Phase 3.
gh pr view NUMBER --json comments --jq '.comments[] | {author: .author.login, body: .body, createdAt: .createdAt, url: .url}'gh pr diff NUMBERFilter out threads where isResolved is true. This is critical for subsequent runs — some feedback may have already been handled.
Filter out threads where isOutdated is true. Mention how many were excluded (e.g. "Excluded 3 outdated threads where the referenced code has since changed").
Skip review bodies that are empty, contain only a summary with no actionable feedback, or are in DISMISSED state.
For reviews with actionable items, parse the body to extract individual feedback items. Each extracted item should carry:
id, databaseId, and url (needed for replies in Phase 8)[bot] (e.g. coderabbitai[bot]).Assign each item one of: Blocking / change request, Suggestion, Nitpick / minor (labeled "nit:", "minor:", etc.), Question, or Praise / informational. Use the review state (CHANGES_REQUESTED) and language cues to determine weight. Blocking items should almost always be actioned; nitpicks only if low-effort and genuinely beneficial.
Before making ANY changes or posting ANYTHING to GitHub, present a structured plan to the user. Group by file when it makes sense.
For each piece of actionable feedback, include:
[posted by agent]If multiple pieces of feedback conflict with each other, flag the conflict to the user.
The user will review your plan. They may approve it as-is, ask you to change how you handle specific items, or discuss trade-offs. Update the plan based on their input and re-present if needed. Do NOT proceed until the user explicitly gives the go-ahead.
Implement all approved code changes.
Rules for this phase:
When done, summarize what was changed and tell the user the code is ready for their review. Iterate until they're satisfied.
Once the user confirms they're happy with the code changes and are about to commit, ask for explicit confirmation to post replies and resolve threads on GitHub.
Do NOT post or resolve anything until this second confirmation.
Execute the approved GitHub actions.
gh api repos/OWNER/REPO/pulls/NUMBER/comments/COMMENT_ID/replies -f body="[posted by agent] Your reply here"Use the databaseId from the GraphQL response as the COMMENT_ID for this REST endpoint.
There is no direct "reply to review body" API. Post a PR-level comment that references the review, including a link so readers can trace context. If the review body contained multiple actionable items, batch all responses into a single comment with each item addressed under its own heading or quote block.
gh pr comment NUMBER --body "[posted by agent] Responding to [AUTHOR's review](REVIEW_URL):
Your reply here"gh pr comment NUMBER --body "[posted by agent] Your reply here"gh api graphql -f query='
mutation($threadId: ID!) {
resolveReviewThread(input: {threadId: $threadId}) {
thread { isResolved }
}
}' -f threadId=THREAD_IDUse the thread id from the Phase 2 GraphQL response as THREAD_ID.
[posted by agent]This is non-negotiable. It must be clear to anyone reading the PR that the comment was written by an AI agent, not the user directly.
The user may invoke this skill multiple times as new feedback rounds arrive. On subsequent runs:
gh is not authenticated: tell the user to run gh auth logingh api repos/OWNER/REPO/pulls/NUMBER/comments (note: this won't include thread resolution status, so warn the user)