Help us improve
Share bugs, ideas, or general feedback.
From jig
Processes PR review feedback by analyzing comments, implementing fixes, committing, pushing, replying on GitHub, and resolving threads. Triggered by /pr-respond or relevant queries.
npx claudepluginhub duronext/jig --plugin jigHow this skill is triggered — by the user, by Claude, or both
Slash command
/jig:pr-respondThe summary Claude sees in its skill listing — used to decide when to auto-load this skill
**PURPOSE**: Process reviewer feedback into fixes, replies, and resolved threads. Every unresolved PR comment thread should end this session resolved.
Reads open GitHub PR review comments, triages by severity and type, applies code fixes, and drafts replies. Use for addressing PR feedback, fixing review issues, and responding to code reviews.
Respond to pull request review feedback interactively by verifying each item with the codebase, making changes, and posting responses on GitHub. Useful for systematically addressing PR comments.
Fetches GitHub PR review feedback, triages comments as valid/stale/incorrect, implements fixes, verifies with tests, and drafts replies.
Share bugs, ideas, or general feedback.
PURPOSE: Process reviewer feedback into fixes, replies, and resolved threads. Every unresolved PR comment thread should end this session resolved.
GIT HOST: Commands in this skill use GitHub (gh) as the default. If git-host in jig.config.md is not github, read framework/GIT_HOST.md for the platform-specific command equivalents.
Analyze. Fix. Commit. Push. Reply. Resolve. That's the job.
FETCH unresolved comments + thread IDs
|
ANALYZE each comment (valid fix? false positive? needs clarification?)
|
For unclear ones --> ASK the user (this should be rare)
|
IMPLEMENT code fixes for valid feedback
|
BUILD + TEST to verify nothing broke
|
COMMIT the fixes
|
PUSH to remote
|
REPLY to each comment on GitHub
|
RESOLVE every addressed thread
The pipeline is not optional. Do not stop after implementing fixes. Do not stop after committing. The job is not done until replies are posted and threads are resolved on GitHub. A comment without a reply and resolution is unfinished work.
Most comments have obvious solutions. Act on them directly:
| Comment Type | Action |
|---|---|
| Valid bug / missing guard | Fix it, reply with commit ref |
| Style / pattern suggestion | Fix it, reply confirming |
| False positive / intentional design | Reply explaining why, resolve |
| Question about approach | Reply with explanation, resolve |
| Genuinely ambiguous or risky | Ask user before acting (rare) |
Default to action. Only ask the user when the fix would be architecturally risky, when you genuinely do not understand the feedback, or when the commenter's suggestion conflicts with existing patterns.
GitHub CLI (gh) must be installed and authenticated. Verify with gh auth status.
Run these in parallel. You need REST comment IDs (for replying) and GraphQL thread IDs (for resolving).
Get PR info:
gh pr view --json number,url,title,body
Extract owner/repo from git remote get-url origin. Use in all gh api calls below.
Fetch PR comments (REST -- for replying):
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments \
--jq '.[] | {id: .id, path: .path, line: .line, body: .body, user: .user.login, created_at: .created_at}'
Fetch unresolved thread IDs (GraphQL -- for resolving):
The REST API gives you comment IDs (for replying), but resolving threads requires GraphQL thread IDs. Fetch both.
gh api graphql -f query='
{
repository(owner: "OWNER", name: "REPO") {
pullRequest(number: PR_NUM) {
reviewThreads(first: 50) {
nodes {
id
isResolved
comments(first: 1) {
nodes {
databaseId
body
author { login }
}
}
}
}
}
}
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false) | {threadId: .id, commentId: .comments.nodes[0].databaseId, author: .comments.nodes[0].author.login, body: (.comments.nodes[0].body | split("\n")[0][:100])}'
Mapping threads to comments: The commentId from GraphQL matches the id from the REST comments endpoint. Use this to build a map of commentId -> threadId so you can resolve each thread after replying.
Fetch a single comment's full body:
The GraphQL query above truncates comment bodies to 100 chars. To get the full body of a specific comment:
# IMPORTANT: The path is /pulls/comments/{id} -- NOT /pulls/{pr_number}/comments/{id}
gh api repos/{owner}/{repo}/pulls/comments/{comment_id} \
--jq '{id: .id, path: .path, line: .line, body: .body, user: .user.login}'
The single-comment endpoint drops the PR number from the path. Using /pulls/{pr_number}/comments/{id} will return a 404.
If there are no unresolved comments, say so and stop.
For each unresolved comment:
| Bot | Typical Comments | Validation Approach |
|---|---|---|
cursor[bot] | Bug predictions, missing guards | ~50% false positive rate. Validate against actual code paths |
sentry[bot] | Security concerns, bug predictions | Deep dive required. Often valid |
github-actions[bot] | CI/CD status, test results | Check actual test failures |
dependabot[bot] | Dependency updates | Review changelog and breaking changes |
CRITICAL: Never trust a bot's factual claims. Always verify.
Bots make assertions about code structure ("this entity doesn't have field X", "this method returns Y") that are frequently wrong. Before accepting ANY bot claim as valid:
name column," READ the entity file and check.The cost of a false fix is higher than the cost of extra verification. A wrong "fix" introduces a real bug where none existed.
These patterns have burned maintainers. Recognize them so you don't skip the actual verification step.
1. Elaborate reasoning is NOT evidence.
Some reviewers (especially LLM-based ones) provide step-by-step proofs, "Extended reasoning" blocks, or multi-paragraph justifications. A confident, detailed argument for a factual claim still needs primary-source verification. Reasoning quality and correctness are not correlated — a wrong claim dressed in careful logic is more dangerous than a wrong claim stated flatly, because the elaboration lowers your skepticism instead of raising it.
<tool> --help and read the flag description yourself. Don't trust the reviewer's summary of what the flag does."ran 'gh api --help': -F = typed, -f = raw-field" is worth more than any amount of reasoning.2. Conflicting reviewers → verify, don't average.
When two reviewers give opposing factual claims (e.g., Bot A says "the correct flag is -F", Bot B says "the correct flag is -f"), the resolution is primary-source verification, not "pick the one with better reasoning" or "go with the majority." Treat a disagreement as a strong signal that verification is mandatory, not optional.
| Pattern | Example | Response |
|---|---|---|
| Style suggestion | "Use design tokens here" | Implement and confirm |
| Performance tip | "Consider memoizing this" | Implement and confirm |
| Question | "Is this intentional?" | Explain the reasoning |
| Bug report | "This will fail when..." | Fix and confirm |
For each valid fix:
Do both. Always. A local commit without a push means the reply will reference a commit the reviewer cannot see.
# Commit the fixes (use commit agent)
# Then push immediately
git push
For EACH addressed comment, do both. This is the finish line -- do not skip it.
Reply to a comment:
gh api repos/{owner}/{repo}/pulls/{pr_number}/comments/{comment_id}/replies \
-X POST \
-f body='Your response message here'
Important:
-X POST to specify POST method-f body='...' for the response bodyResolve all addressed threads (AFTER replying):
for thread_id in PRRT_abc123 PRRT_def456 PRRT_ghi789; do
gh api graphql -f query="mutation { resolveReviewThread(input: {threadId: \"$thread_id\"}) { thread { isResolved } } }" --jq '.data.resolveReviewThread.thread.isResolved'
done
Rules:
isResolved: true can be skippedPost top-level PR comment (optional):
Use for summarizing multiple changes across many comments:
gh pr comment {pr_number} --body "### Summary of Changes
All feedback has been addressed:
- Updated design tokens
- Fixed the race condition
- Added error handling"
Acknowledging a fix:
good call! updated to use the design token instead of the hardcoded value
Explaining a decision:
thanks for flagging! looked into this -- the inner join is actually intentional here. this method only returns records that have the associated data. records without it have nothing to display or match against.
Simple acknowledgment:
done!
With commit reference:
fixed in abc1234. added the null check as suggested.
Multi-point fix:
addressed both points:
- added guard for self-reference prevention
- wrapped empty state in droppable for drop zone coverage fixed in abc1234.
/pulls/comments/{id} NOT /pulls/{pr}/comments/{id} -- the PR number is NOT in the path for single-comment lookups/pulls/{pr}/comments/{id}/replies -- the PR number IS in the path for replies-X POST for repliesgh auth login
gh auth status
gh api rate_limitCalled by:
pr-create when reviewers provide feedbackRelated skills:
pr-create -- creates the PR that this skill responds toreview -- the automated review swarm (catches issues before humans do)postmortem -- analyzes PR feedback patterns for skill improvement