SKILL.md
$2c
Inline review comments - filter out replies (keep only originals)
gh api repos/$REPO/pulls/$PR/comments?per_page=100 --jq '
[.[] | select(.in_reply_to_id == null) |
{id, path, user: .user.login, created_at, body: .body[0:200]}]
'
PR-level reviews with non-empty body (CodeRabbit sections, Gemini, etc.)
gh api repos/$REPO/pulls/$PR/reviews?per_page=100 --jq '
[.[] | select(.body | length > 0) |
{id, user: .user.login, state, submitted_at, body: .body[0:500]}]
'
**Cross-check review-attached comments**: CodeRabbit's review body states "Actionable comments posted: N". If the general `pulls/$PR/comments` endpoint returns fewer than N new originals from that reviewer, some comments are only available via the review-specific endpoint. Fetch them and merge by comment ID:
$REVIEW_ID from the reviews fetch above; $EXPECTED from parsing "Actionable comments posted: N"
gh api repos/$REPO/pulls/$PR/reviews/$REVIEW_ID/comments?per_page=100 --jq '
[.[] | select(.in_reply_to_id == null) |
{id, path, user: .user.login, created_at, body: .body[0:200]}]
'
Deduplicate by `id` before continuing. Comments found only via the review-specific endpoint are valid inline comments and should be treated identically (same classification, same `in_reply_to` reply mechanism).
**Filter new vs already-seen**: compare `created_at`/`submitted_at` with `$LAST_PUSH`. Comments posted after the last push are new. Mark older comments as "previous round" in the summary table.
**Parse CodeRabbit review bodies**: the initial fetch truncates bodies for classification. For reviews from CodeRabbit (`user.login` starts with `coderabbitai`), fetch the full body separately:
gh api repos/$REPO/pulls/$PR/reviews?per_page=100 --jq '
[.[] | select(.user.login | startswith("coderabbitai")) |
{id, submitted_at, body}]
'
CodeRabbit posts structured `<details>` blocks containing outside-diff, duplicate, and nitpick comments. Each block includes file path, line range, severity, and optionally a "Prompt for AI Agents" with pre-built context. See `references/coderabbit_parsing.md` for full parsing guide.
**Use CodeRabbit AI prompts when available**: if a comment (or the review body) contains a "Prompt for AI Agents" `<details>` block, use it to understand the issue and suggested approach. Always read the actual code before proposing a fix. If the review body contains a "Prompt for all review comments with AI agents" block, read it first for cross-comment context before processing individual comments.
Classify all comments by severity and process in order: CRITICAL > HIGH > MEDIUM > LOW.
Severity
Indicators
Action
CRITICAL
`critical.svg`, `_π Security_`, `_π¨ Critical_`, `_π΄ Critical_`, "security", "vulnerability"
Must fix
HIGH
`high-priority.svg`, `_β οΈ Potential issue_`, `_π Bug_`, `_β‘ Performance_`, `_π Major_`, "High Severity"
Should fix
MEDIUM
`medium-priority.svg`, `_π οΈ Refactor suggestion_`, `_π‘ Suggestion_`, "Medium Severity"
Recommended
LOW
`low-priority.svg`, `_π§Ή Nitpick_`, `_π§ Optional_`, `_π‘ Minor_`, `_π΅ Trivial_`, `_βͺ Info_`, "style", "nit"
Optional
When a comment has both a type label and a secondary color badge (e.g., `_π‘ Suggestion_ | _π Major_`), the color badge is the **binding** severity and overrides the type-based default.
See `references/severity_guide.md` for full detection patterns (Gemini badges, CodeRabbit emoji, Cursor comments, keyword fallback, related comments heuristics).
### 2. Show review summary table
Before processing, display a structured overview of all comments:
| # | ID | Severity | File:Line | Type | Status | Summary |
|---|---|---|---|---|---|---|
| 1 | 123456789 | CRITICAL | src/auth.py:45 | inline | new | SQL injection risk |
| 2 | 987654321 | HIGH | src/db.py:346-350 | outside | new | Missing join cond |
| 3 | 555555555 | HIGH | src/chunk.py:188 | duplicate | previous | Stale metadata |
| 4 | 444444444 | LOW | tests/test_q.py:12 | nitpick | previous | Naming convention |
- **Type**: `inline`, `outside` (outside diff), `duplicate`, `minor`, `nitpick` (from CodeRabbit sections), or `review` (generic PR-level)
- **Status**: `new` (posted after last push) or `previous` (from earlier rounds)
- Group related comments (same file, same root cause, "also applies to" ranges) and note clusters
- Deduplicate: if the same issue appears both as an inline comment and in a CodeRabbit review body section (e.g., duplicate), keep one entry and note both sources
If there are **more than 10 comments**, suggest saving a review summary to Claude's memory for tracking across sessions. The summary should include: PR number, comment IDs, severity, status (new/addressed/deferred/won't fix), and brief description. This helps maintain continuity when new comments arrive after subsequent pushes.
### 3. Process each comment
For each comment, in severity order:
- **Show context**: comment ID, severity, file:line, quote
- **Check for AI prompt**: if CodeRabbit "Prompt for AI Agents" is available for this comment, use it to understand the issue and suggested approach
- **Check for proposed fix**: if CodeRabbit includes a "Proposed fix" or "Suggested fix" code block, use it as a starting point (but verify correctness)
- **Read affected code** and propose fix (always read the actual code, even when an AI prompt or proposed fix provides context)
- **Handle "also applies to"**: if the comment references additional line ranges, include all locations in the fix
- **Confirm with user** before applying
- **Apply fix** if approved
- **Verify ALL issues** in the comment are addressed (multi-issue comments are common)
### 4. Commit changes
Use git-commit skill format. Functional fixes get separate commits, cosmetic fixes are batched:
Change type
Strategy
Functional (CRITICAL/HIGH)
Separate commit per fix
Cosmetic (MEDIUM/LOW)
Single batch `style:` commit
Reference the comment ID in the commit body.
### 5. Reply to threads
#### Inline comments
**Important**: use `--input -` with JSON. The `-f in_reply_to=...` syntax does NOT work.
COMMIT=$(git rev-parse --short HEAD)
gh api repos/$REPO/pulls/$PR/comments \
--input - <<< '{"body": "Fixed in '"$COMMIT"'. Brief explanation.", "in_reply_to": 123456789}'
#### Non-inline comments (CodeRabbit review body)
Comments embedded in the review body (outside diff, duplicate, nitpick) do not have inline threads. The GitHub API does not support replying to a review body directly. Post a general PR comment referencing the specific issue:
gh pr comment $PR --body "Fixed in $COMMIT. Addresses outside-diff comment on file/path.py:346-350."
**Reply templates** (no emojis, minimal and professional):
Situation
Template
Fixed
`Fixed in [hash]. [brief description of fix]`
Won't fix
`Won't fix: [reason]`
By design
`By design: [explanation]`
Deferred
`Deferred to [issue/task]. Will address in future iteration.`
Acknowledged
`Acknowledged. [brief note]`
### 6. Run tests and push
Run the project test suite. All tests must pass before pushing. Push all fixes together to minimize review loops.
### 7. Submit review (optional)
After addressing all comments, formally submit a review:
- `gh pr review $PR --approve --body "..."` - all comments addressed, PR is ready
- `gh pr review $PR --request-changes --body "..."` - critical issues remain
- `gh pr review $PR --comment --body "..."` - progress update, no decision yet
### 8. Verify milestone
gh pr view $PR --json milestone -q '.milestone.title // "none"'
If the PR has no milestone, check for open milestones:
REPO=$(gh repo view --json nameWithOwner -q '.nameWithOwner')
gh api repos/$REPO/milestones --jq '[.[] | select(.state=="open")] | .[] | "\(.number): \(.title)"'
If open milestones exist, inform the user and suggest assigning:
gh pr edit $PR --milestone "[milestone-title]"