Address PR Comments (Human-in-the-Loop)
Argument Parsing
Parse $ARGUMENTS to determine the mode.
Codex: if the invocation text above is not populated, use the text after the skill name. If unavailable, infer the PR number or comment URL from the current request.
- Specific comment URL — matches pattern
https://github.com/{owner}/{repo}/pull/{number}#discussion_r{id}or#pullrequestreview-{id}- Extract:
owner,repo,pr_number, andcomment_anchor(the fragment after#) - This is single-comment mode: only address the targeted comment/review
- Extract:
- PR number (plain numeric) — address all unresolved comments on the PR
Do NOT push commits or post replies until the user approves. Write drafts first, then after approval: push and post.
Step 1: Gather PR Comments
Use GraphQL to get the true resolution status of every thread. Do NOT guess resolution based on replies.
- Get the PR details:
gh pr view {pr_number}(use-R {owner}/{repo}if the URL points to a different repo than cwd) - Fetch all review threads with resolution status using GraphQL:
gh api graphql -f query=' query($owner: String!, $repo: String!, $pr: Int!) { repository(owner: $owner, name: $repo) { pullRequest(number: $pr) { reviews(last: 50) { nodes { id, databaseId, state, author { login }, body, url } } reviewThreads(last: 100) { nodes { isResolved comments(first: 50) { nodes { id, databaseId, author { login }, body, path, line, url } } } } } } } ' -f owner='{owner}' -f repo='{repo}' -F pr={pr_number} - Also fetch general issue-style comments:
gh api repos/{owner}/{repo}/issues/{pr_number}/comments -
Filter to actionable items:
If single-comment mode (URL with
#discussion_r{id}or#pullrequestreview-{id}):- Find the specific thread/review matching the anchor ID from the URL
- For
discussion_r{id}: match against commentdatabaseIdfields inreviewThreads— the target thread is the one containing a comment with thatdatabaseId - For
pullrequestreview-{id}: match against reviewdatabaseIdfields inreviews - Only address that single thread/review — ignore everything else
- Still skip if
isResolved == true(tell the user it’s already resolved)
If all-comments mode (PR number only):
- SKIP threads where
isResolved == true— these are already resolved in GitHub - SKIP your own comments (not replies to others)
- INCLUDE all unresolved review threads — from human reviewers and bots alike (Copilot, sentry[bot], etc. can surface real issues)
- INCLUDE general issue-style PR comments from other authors that request a change or response
- INCLUDE top-level reviews with state
CHANGES_REQUESTEDthat have not been superseded by a newerAPPROVEDorDISMISSEDreview from the same author - INCLUDE unresolved review threads even if you previously replied — a reply does NOT mean resolved
Classify each actionable item as review_thread_comment, issue_comment, or top_level_review. Retain its author, URL, database ID, and any file/line metadata. Do not assume every item has a pull-request review comment ID.
Step 2: Create Beads Tasks
For each comment that needs addressing, create a beads (bd create) task.
Include in the description:
- The comment author
- The file and line referenced
- The full comment text
- A link to the comment (use the
html_urlfield)
Step 3: Load Project Conventions
Load project conventions (if available):
If the CODE_CONVENTIONS environment variable is set and points to a readable file, read it now. These are project-specific patterns and gotchas to keep in mind when implementing fixes — they prevent introducing new violations while fixing old ones.
Step 4: Address Each Comment
For each task (one at a time, in order):
- Mark the task in progress:
bd update <task-id> --status=in_progress - Read the code at the file and line referenced in the comment
- Evaluate the comment:
- Is this a valid issue? Understand the reviewer’s concern fully.
- If valid and worth fixing now: implement the fix
- If valid but low priority: note it as acknowledged but deferred
- If not valid: prepare a clear, respectful explanation of why the current code is correct
- If a fix was made:
- Stage only the affected files
- Commit with a message referencing the PR comment (e.g.,
Fix: address review feedback on <file> — <what changed>) - Do NOT push yet
- Reply to the reviewer — every comment MUST get a reply, regardless of outcome:
- If fixed: draft a reply explaining what you changed
- If low priority / deferred: draft a reply acknowledging the feedback, explaining why it’s being deferred, and note any follow-up plans (e.g., “Good catch — this is lower priority so we’ll track it separately”)
- If not valid: draft a respectful explanation of why no change is needed
- Write the review draft to
human-in-loop-drafts/pr-{number}/{item_type}-{database_id}.mdand the exact proposed reply body to a siblinghuman-in-loop-drafts/pr-{number}/{item_type}-{database_id}-reply.md. Do NOT post viagh api. - Draft file format:
# Comment by @{author} **Item Type:** {review_thread_comment|issue_comment|top_level_review} **Database ID:** {database_id} **File:** {file}:{line} **Comment:** {comment text} **Link:** {html_url} ## Code Changes {`git show --stat` output for the commit, or "No changes — explanation only"} ## Commit Message {full commit message} ## Proposed Reply {the reply you would post}
- Mark the task complete:
bd close <task-id>
Step 5: Present for Approval
- Run
bd dolt push - Present the user with:
- Path to
human-in-loop-drafts/pr-{number}/ - Summary table: comment ID, author, file, resolution type (fix/explanation)
- Full commit log:
git log --oneline origin/HEAD..HEAD
- Path to
- Ask the user to review the drafts and confirm before proceeding.
Step 6: After User Approves
When the user approves (or asks you to proceed):
- Run
git push - Post each approved reply from its reply-body file:
- For a
review_thread_comment:gh api --method POST repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_id}/replies -F body=@<reply-file> - For an
issue_commentortop_level_review: ensure the reply mentions the author and links the original item, then rungh api --method POST repos/{owner}/{repo}/issues/{pr_number}/comments -F body=@<reply-file>
- For a
- Verify every API response. Then remove only the validated
human-in-loop-drafts/pr-{number}/directory (prefer moving it to trash when practical). Removehuman-in-loop-drafts/itself only if it is empty, and report what was removed.