skills/github-pr-review-comments/SKILL.md
Comprehensive workflow for managing GitHub PR review comments using gh CLI and GraphQL API. Use when asked to address review comments, find unreplied comments, reply to review threads, or resolve/unresolve review conversations. Supports finding ALL comments across pagination boundaries, replying to threads, and resolving conversations.
npx skillsauth add straub/agent-skills github-pr-review-commentsInstall this skill globally with one command. Works with Claude Code, Cursor, and Windsurf.
3 of 9 scanners reported clean
Some scanners were skipped, did not run, or reported a non-clean status. Review each row below.
This skill provides a comprehensive workflow for managing PR review comments using the gh CLI and GitHub's GraphQL API.
Use this skill when:
CRITICAL: PR review comments are paginated and span multiple review rounds. Simple queries will miss comments. Use this comparison approach:
gh api repos/{owner}/{repo}/pulls/{pr}/comments --paginate \
--jq '[.[] | select(.in_reply_to_id == null)] | .[].id' \
| sort -n > /tmp/all_original_comments.txt
This finds all "top-level" review comments (not replies).
gh api user -q .login
gh api repos/{owner}/{repo}/pulls/{pr}/comments --paginate \
--jq '[.[] | select(.user.login == "{your_username}" and .in_reply_to_id != null)] | .[].in_reply_to_id' \
| sort -n > /tmp/replied_comments.txt
comm -23 /tmp/all_original_comments.txt /tmp/replied_comments.txt
This shows comment IDs that don't have your reply yet.
Once you have unreplied comment IDs, get full details:
gh api repos/{owner}/{repo}/pulls/{pr}/comments --paginate \
--jq '[.[] | select(.id == {id1} or .id == {id2})] | .[] | {id, path, line, body}'
Replace {id1}, {id2} with actual comment IDs.
gh api repos/{owner}/{repo}/pulls/{pr}/comments/{comment_id}/replies \
-X POST -f body='Your response here'
**FIXED** in commit abc1234# Fixed issue
gh api repos/owner/repo/pulls/123/comments/456/replies \
-X POST -f body='✅ **FIXED** in commit abc1234 - Refactored to use async/await pattern'
# Acknowledged
gh api repos/owner/repo/pulls/123/comments/789/replies \
-X POST -f body='🔄 Good catch! Will fix in next commit'
The GitHub GraphQL API provides powerful capabilities for managing review threads.
gh api graphql -f query='
{
repository(owner: "OWNER", name: "REPO") {
pullRequest(number: PR_NUMBER) {
reviewThreads(first: 100) {
nodes {
id
isResolved
comments(first: 100) {
nodes {
id
body
author { login }
path
line
}
}
}
}
}
}
}'
Use the thread ID from reviewThreads.nodes[].id (format: PRRT_kwDO...), NOT the comment ID:
gh api graphql -f query='
mutation {
addPullRequestReviewThreadReply(input: {
pullRequestReviewThreadId: "PRRT_kwDO..."
body: "Your reply here"
}) {
comment { id }
}
}'
gh api graphql -f query='
mutation {
resolveReviewThread(input: {threadId: "PRRT_kwDO..."}) {
thread { id isResolved }
}
}'
Thread IDs are in the id field of each thread node (format: PRRT_kwDO...).
gh api graphql -f query='
mutation {
unresolveReviewThread(input: {threadId: "PRRT_kwDO..."}) {
thread { id isResolved }
}
}'
# Set variables
OWNER="myorg"
REPO="myrepo"
PR="42"
# Step 1: Get all original comment IDs
gh api repos/$OWNER/$REPO/pulls/$PR/comments --paginate \
--jq '[.[] | select(.in_reply_to_id == null)] | .[].id' \
| sort -n > /tmp/all_original_comments.txt
# Step 2: Get your username
USERNAME=$(gh api user -q .login)
# Step 3: Get comment IDs you've replied to
gh api repos/$OWNER/$REPO/pulls/$PR/comments --paginate \
--jq "[.[] | select(.user.login == \"$USERNAME\" and .in_reply_to_id != null)] | .[].in_reply_to_id" \
| sort -n > /tmp/replied_comments.txt
# Step 4: Find unreplied comment IDs
UNREPLIED=$(comm -23 /tmp/all_original_comments.txt /tmp/replied_comments.txt)
# Step 5: Get details for unreplied comments
for id in $UNREPLIED; do
gh api repos/$OWNER/$REPO/pulls/$PR/comments --paginate \
--jq "[.[] | select(.id == $id)] | .[] | {id, path, line, body, author: .user.login}"
done
OWNER="myorg"
REPO="myrepo"
PR="42"
COMMIT="abc1234"
# Reply to comment about async refactoring
gh api repos/$OWNER/$REPO/pulls/$PR/comments/111/replies \
-X POST -f body="✅ **FIXED** in commit $COMMIT - Refactored to use async/await"
# Reply to comment about error handling
gh api repos/$OWNER/$REPO/pulls/$PR/comments/222/replies \
-X POST -f body="✅ **FIXED** in commit $COMMIT - Added try/catch with proper error logging"
OWNER="myorg"
REPO="myrepo"
PR="42"
# Fetch unresolved threads
THREADS=$(gh api graphql -f query="
{
repository(owner: \"$OWNER\", name: \"$REPO\") {
pullRequest(number: $PR) {
reviewThreads(first: 100) {
nodes {
id
isResolved
comments(first: 1) {
nodes { body path }
}
}
}
}
}
}")
echo "$THREADS" | jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)'
# Reply to a specific thread and resolve it
THREAD_ID="PRRT_kwDOAbc123"
gh api graphql -f query="
mutation {
addPullRequestReviewThreadReply(input: {
pullRequestReviewThreadId: \"$THREAD_ID\"
body: \"✅ Fixed in latest commit\"
}) {
comment { id }
}
}"
gh api graphql -f query="
mutation {
resolveReviewThread(input: {threadId: \"$THREAD_ID\"}) {
thread { id isResolved }
}
}"
--paginate flagREST API (gh api repos/.../pulls/.../comments):
GraphQL API (gh api graphql):
PRRT_kwDO...123456789)PRRT_kwDOAbc123...)For coding agents and automation:
When gh pr review-thread command becomes available (gh cli #12419), it will provide:
gh pr review-thread resolve <thread-id>gh pr review-thread unresolve <thread-id>gh pr review-thread list --unresolvedUntil then, use the GraphQL mutations shown above.
testing
A template for creating new agent skills. Replace this description with a clear explanation of what your skill does and when agents should use it. Include specific keywords that help agents identify relevant tasks.
development
Enforce Test-Driven Development (TDD) workflow for all code changes. Apply PROACTIVELY by default using Red-Green-Refactor cycles for features, bug fixes, and refactoring.
testing
Use ANY TIME running tests (npm test, node --test, pytest, etc.) to capture output and prevent context overflow.
tools
Interact with Jira using the jira-cli command-line tool to manage issues, sprints, epics, and boards. Use when working with Jira tickets, sprint planning, issue tracking, or when the user mentions Jira, tickets, sprints, epics, or issue management.