with one click
coderabbit-respond
// When CodeRabbit has posted comments on the current PR and the user wants to triage each comment with apply-or-Won't-fix decisions, use this skill.
// When CodeRabbit has posted comments on the current PR and the user wants to triage each comment with apply-or-Won't-fix decisions, use this skill.
[HINT] Download the complete skill directory including SKILL.md and all related files
| name | coderabbit-respond |
| description | When CodeRabbit has posted comments on the current PR and the user wants to triage each comment with apply-or-Won't-fix decisions, use this skill. |
Bulk-collect CodeRabbit comments on the current PR, classify each, then either apply (commit fix) or post a "Won't fix" reply with rationale.
PR=$(gh pr view --json number -q .number)
REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
BRANCH=$(git branch --show-current)
BRANCH is required for the docs/.local/$BRANCH/coderabbit.md write target
in Step 2 — without it, the path is templated (<branch>) but never resolved
at runtime.
docs/.local/<branch>/coderabbit.mdCodeRabbit posts findings to two distinct endpoints — the skill must hit both, otherwise outside-diff-range items are silently missed.
2a. Inline review comments (/comments) — diff-line-anchored findings:
gh api "repos/$REPO/pulls/$PR/comments" --paginate \
| jq -s '
map(.[]) as $all
| {
actionable: [$all[] | select(.user.login == "coderabbitai[bot]" and .position != null)],
outdated: [$all[] | select(.user.login == "coderabbitai[bot]" and .position == null)]
}'
Why jq -s (slurp): --paginate emits one JSON array per page, so a plain jq '[.[] | ...]' filters each page independently and yields multiple arrays — counting and grouping break for PRs with > 30 CodeRabbit comments. -s flattens the page stream into a single array first, then partitions into actionable / outdated so step 2c can count both.
Why each filter:
user.login == "coderabbitai[bot]" — strips human comments and other bots.position != null — non-null position = the diff line still exists in the latest commit; null = the comment is outdated because the line was rewritten or deleted by a later push. Outdated comments are typically resolved by the very fix that invalidated them — surfacing them again forces the user to re-triage stale findings.2b. Review submissions with "Outside diff range" sections (/reviews) —
findings on lines NOT in the current diff (CodeRabbit cannot post inline
because the line is unchanged in this PR):
gh api "repos/$REPO/pulls/$PR/reviews" --paginate \
| jq -s '
map(.[])
| [.[] | select(.user.login == "coderabbitai[bot]" and (.body | contains("Outside diff range")))]'
Same -s slurp as 2a — --paginate emits per-page arrays; without -s the filter runs per page and yields fragments.
For each matching review, parse the body markdown for <details><summary>⚠️ Outside diff range comments (N)</summary> blocks. Each item inside has <file> + line range + finding body — extract and add to triage list with a synthetic id (e.g. <review-id>-outside-N) since these aren't tied to a comments row.
2c. Print one summary line: N inline actionable / M outdated (skipped) / K outside-diff by counting (a) the filtered output of 2a, (b) the unfiltered minus filtered count, (c) the parsed items from 2b.
User can override and ask to include outdated ones if a finding still applies conceptually.
Group by file path + line. Read each comment body in full so you can summarise
it accurately for the user. Write the collected comments to
docs/.local/<branch>/coderabbit.md with the same item shape used by
apply-critic:
- [<id>] <file>:<line> — <CodeRabbit comment body>
Suggestion: <CodeRabbit's suggested fix, if any>
This file is the source-of-truth for triage.
Skip rule on re-runs:
[applied @ ...] / [wont-fix: ...] / [apply-defer].[discuss] (re-ask until the user resolves the discussion).position == null from step 2) are silently dropped — they're
no longer attached to a current diff line.Note: GitHub's REST /comments endpoint does not expose the
"Resolve conversation" UI state — that lives on GraphQL
pullRequestReviewThread.isResolved. If a finding has been UI-resolved but
the diff line still exists, REST will return it. Treat REST output as the
SoT for actionable items; UI resolution is a courtesy display only.
After the file is written, present every CodeRabbit comment in a single message and ask the user to answer all of them in one reply. Do not ask one-by-one. Before listing the menu for each item, make your own apply/skip judgment first so the user sees how you would resolve it without their input. For each comment include:
Trivial / Minor / Major / Critical)plan.md decisions or other comments — name the conflict explicitlyApply / Apply (defer) / Won't fix / Discuss) with a one-clause reason. This is your call, not just a recommendation; the user overrides it by picking a different number.Use this format per comment:
**Q<n>. #<id>** — `<file>:<line>` (<Trivial|Minor|Major|Critical>)
요약: <1-3 line paraphrase of the CodeRabbit finding>
제안: <suggested fix>
[충돌/메모: <plan.md 결정 충돌, 중복 코멘트 등 — 해당 시>]
**Claude 판단: <Apply | Apply (defer) | Won't fix | Discuss>** — <한 줄 근거>
1) Apply — 코드 수정 후 stage
2) Apply (defer) — 따로 후속 TODO로 빼고 PR에 반영 X
3) Won't fix — 사유 한 줄 입력 후 reply
4) Discuss — @coderabbitai 추가 질문 또는 사람과 상의
End the message with: 각 항목에 번호로 답하거나, 내 판단대로 진행하려면 'OK' 라고 답해줘 (예: Q1=3 사유..., Q2=OK, Q3=2). Allow the user to delegate to your verdict in bulk via OK (all items) or per-item via Q<n>=OK.
Wait for the user's batched reply. Never auto-pick. Map every comment to one class — no comment is left unanswered (PR review checklist item 5). If the user's reply is partial, re-ask only the missing items.
After the user answers, append a marker to the coderabbit.md item: [applied @ <unstaged>] / [apply-defer] / [wont-fix: <reason>] / [discuss].
Group apply-now fixes by file. Edit + stage + commit with subject like:
fix(<scope>): address coderabbit comments on <file>
Branch by the comment id type:
Real inline COMMENT_ID (from Step 2a) — threaded reply on the line:
gh api repos/$REPO/pulls/$PR/comments/$COMMENT_ID/replies \
-f body="<your reply>"
Body shell-quoting: avoid backticks in -f body=... (zsh/bash interprets ` as command substitution and silently drops the contents). Use --input <(cat <<'EOF' ... EOF) or a JSON file via gh api -X POST ... --input /tmp/reply.json instead.
Synthetic outside-diff id (from Step 2b — <review-id>-outside-N) — there is no /comments row, so the replies endpoint returns 404. Post a PR-level issue comment that quotes the original outside-diff finding for traceability:
gh pr comment $PR --body-file /tmp/reply.md
Where /tmp/reply.md contains:
> Re: outside-diff finding in review #<review-id> on `<file>:<line-range>`:
> <one-line paraphrase of the finding>
<Apply | Apply (defer) | Won't fix | Discuss> — <reason>.
This puts the verdict in the PR conversation thread (visible to CodeRabbit + reviewers) without needing a synthetic-id-aware endpoint.
git push
CodeRabbit re-reviews on push (auto_incremental_review: true). Repeat this skill if new comments arrive.
wont-fix — don't let assertive noise block merges. Genuine CLAUDE.md Rule E violations (English in user-facing copy / log) are a separate category — those are typically Apply.Apply. The verdict carries weight — the user may approve all items in bulk via OK, so a lazy Apply default ships unwanted changes.