Use when reviewing PR comments, responding to code review feedback, or addressing reviewer suggestions on the current branch. Triggered by "respond to PR comments", "address review feedback", or /pr-respond.
From casaflownpx claudepluginhub casaperks/casaflow --plugin casaflowThis skill uses the workspace's default tool permissions.
Designs and optimizes AI agent action spaces, tool definitions, observation formats, error recovery, and context for higher task completion rates.
Enables AI agents to execute x402 payments with per-task budgets, spending controls, and non-custodial wallets via MCP tools. Use when agents pay for APIs, services, or other agents.
Compares coding agents like Claude Code and Aider on custom YAML-defined codebase tasks using git worktrees, measuring pass rate, cost, time, and consistency.
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.
| 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