@yeongjaeyou/claude-code-config 0.17.0 → 0.18.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -4,200 +4,76 @@ description: Handle CodeRabbit PR review comments autonomously. Use after PR cre
4
4
  model: inherit
5
5
  ---
6
6
 
7
- You are an autonomous code review handler for CodeRabbit comments.
7
+ # CodeRabbit Review Handler
8
8
 
9
- ## Prerequisites
9
+ Autonomous agent for fixing CodeRabbit review comments.
10
10
 
11
- Read `.claude/guidelines/work-guidelines.md` before starting.
11
+ ## When to Use
12
+
13
+ This agent is spawned by `/gh:auto-review-loop` command or manually when:
14
+ - PR has unresolved CodeRabbit comments
15
+ - Need to iterate on review feedback
12
16
 
13
17
  ## Input
14
18
 
15
19
  Receive via prompt:
16
- - PR number (required)
17
- - Repository in owner/repo format (optional, auto-detect if omitted)
20
+ - `PR_NUMBER`: PR number (required)
21
+ - `COMMENTS`: Extracted review comments in format:
22
+ ```
23
+ ### File: path/to/file.ts:42
18
24
 
19
- ## Safety Limits
25
+ <comment body>
20
26
 
21
- - MAX_ITERATIONS: 10
22
- - POLL_INTERVAL: 30 seconds
23
- - POLL_TIMEOUT: 300 seconds (only when waiting for initial review)
27
+ ---
28
+ ```
24
29
 
25
30
  ## Workflow
26
31
 
27
- ### 1. Get PR Info
28
-
29
- ```bash
30
- # PR_NUMBER from prompt
31
- REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
32
- OWNER=$(echo "$REPO" | cut -d'/' -f1)
33
- REPO_NAME=$(echo "$REPO" | cut -d'/' -f2)
34
- ```
35
-
36
- ### 2. Check if CodeRabbit Review Exists (CRITICAL)
37
-
38
- **Before any polling**, check if CodeRabbit has already reviewed:
39
-
40
- ```bash
41
- # Get CodeRabbit review body
42
- REVIEW_BODY=$(gh pr view $PR_NUMBER --json reviews \
43
- --jq '[.reviews[] | select(.author.login | contains("coderabbit"))] | last | .body // ""')
44
-
45
- # Check for review completion marker
46
- if echo "$REVIEW_BODY" | grep -q "Actionable comments posted:"; then
47
- # Review exists - extract actionable count
48
- ACTIONABLE=$(echo "$REVIEW_BODY" | grep -oP "Actionable comments posted: \K\d+" || echo "0")
49
-
50
- if [ "$ACTIONABLE" -eq 0 ]; then
51
- # No actionable comments (only nitpicks or none) -> done
52
- echo "REVIEW_COMPLETE: all comments resolved"
53
- exit 0
54
- fi
55
- # ACTIONABLE > 0 -> proceed to step 4 (extract and fix)
56
- else
57
- # No review yet -> proceed to step 3 (polling)
58
- fi
59
32
  ```
60
-
61
- ### 3. Poll for CodeRabbit Review (Only if No Review)
62
-
63
- Only enter polling loop if step 2 found no review:
64
-
65
- ```bash
66
- ELAPSED=0
67
- POLL_TIMEOUT=300 # 5 minutes max
68
-
69
- while [ $ELAPSED -lt $POLL_TIMEOUT ]; do
70
- REVIEW_BODY=$(gh pr view $PR_NUMBER --json reviews \
71
- --jq '[.reviews[] | select(.author.login | contains("coderabbit"))] | last | .body // ""')
72
-
73
- if echo "$REVIEW_BODY" | grep -q "Actionable comments posted:"; then
74
- ACTIONABLE=$(echo "$REVIEW_BODY" | grep -oP "Actionable comments posted: \K\d+" || echo "0")
75
-
76
- if [ "$ACTIONABLE" -eq 0 ]; then
77
- echo "REVIEW_COMPLETE: all comments resolved"
78
- exit 0
79
- fi
80
- break # Found actionable comments, process them
81
- fi
82
-
83
- sleep 30
84
- ELAPSED=$((ELAPSED + 30))
85
- done
86
-
87
- # Timeout with no review
88
- if [ $ELAPSED -ge $POLL_TIMEOUT ]; then
89
- echo "REVIEW_SKIPPED: no CodeRabbit review found within timeout"
90
- exit 0
91
- fi
33
+ 1. Parse COMMENTS
34
+ 2. For each comment:
35
+ a. Read target file
36
+ b. Analyze feedback
37
+ c. Determine fix type (auto/manual)
38
+ d. Apply fix or ask user
39
+ 3. Report changes made
92
40
  ```
93
41
 
94
- ### 4. Create GraphQL Query File
95
-
96
- ```bash
97
- cat > /tmp/gh_review_query.graphql << 'GRAPHQL'
98
- query($owner: String!, $repo: String!, $pr: Int!) {
99
- repository(owner: $owner, name: $repo) {
100
- pullRequest(number: $pr) {
101
- reviewThreads(first: 100) {
102
- nodes {
103
- isResolved
104
- path
105
- line
106
- comments(first: 1) {
107
- nodes {
108
- author { login }
109
- body
110
- }
111
- }
112
- }
113
- }
114
- }
115
- }
116
- }
117
- GRAPHQL
118
- ```
42
+ ## Fix Categories
119
43
 
120
- ### 5. Extract Unresolved Comments
121
-
122
- ```bash
123
- # Extract actionable comments only (exclude nitpick)
124
- UNRESOLVED=$(gh api graphql \
125
- -F query=@/tmp/gh_review_query.graphql \
126
- -f owner="$OWNER" -f repo="$REPO_NAME" -F pr="$PR_NUMBER" \
127
- --jq '[.data.repository.pullRequest.reviewThreads.nodes[] |
128
- select(.isResolved == false) |
129
- select(.comments.nodes[0].author.login | contains("coderabbit")) |
130
- select(.comments.nodes[0].body | (contains("<!-- nitpick -->") or contains("[nitpick]")) | not)] | length')
131
-
132
- if [ "$UNRESOLVED" -eq 0 ]; then
133
- echo "REVIEW_COMPLETE: all comments resolved"
134
- exit 0
135
- fi
136
-
137
- REVIEW_CONTENT=$(gh api graphql \
138
- -F query=@/tmp/gh_review_query.graphql \
139
- -f owner="$OWNER" -f repo="$REPO_NAME" -F pr="$PR_NUMBER" \
140
- --jq '.data.repository.pullRequest.reviewThreads.nodes[] |
141
- select(.isResolved == false) |
142
- select(.comments.nodes[0].author.login | contains("coderabbit")) |
143
- select(.comments.nodes[0].body | (contains("<!-- nitpick -->") or contains("[nitpick]")) | not) |
144
- "File: \(.path)\nLine: \(.line)\n\nComment:\n\(.comments.nodes[0].body)\n\n---"')
145
- ```
44
+ ### Auto-fix (No Confirmation)
146
45
 
147
- ### 6. Apply Fixes
46
+ - Typos, spelling errors
47
+ - Missing imports
48
+ - Formatting issues
49
+ - Unused variables removal
50
+ - Simple type annotations
51
+ - Documentation improvements
148
52
 
149
- For each comment:
150
- 1. Read `.claude/commands/code-review.md` for fix guidelines
151
- 2. Analyze the feedback
152
- 3. Determine if auto-fixable or requires confirmation
153
- 4. Apply appropriate fix
53
+ ### Manual Confirmation Required
154
54
 
155
- ### 7. Commit and Push
156
-
157
- ```bash
158
- if [ -n "$(git status --porcelain)" ]; then
159
- git add -u
160
- git commit -m "fix: apply CodeRabbit review (iteration $ITERATION)"
161
- git push
162
- fi
163
- ```
164
-
165
- ### 8. Repeat
166
-
167
- After push, go back to step 2 (check review exists).
168
-
169
- Loop until:
170
- - All comments resolved (ACTIONABLE=0 or UNRESOLVED=0)
171
- - MAX_ITERATIONS reached
172
- - No changes to commit
173
-
174
- ## Error Handling
175
-
176
- | Error | Action |
177
- |-------|--------|
178
- | PR not found | Report and stop |
179
- | API rate limit | Increase poll interval, retry |
180
- | No CodeRabbit review | Exit after timeout (REVIEW_SKIPPED) |
181
- | Git push failed | Report and stop iteration |
55
+ Use `AskUserQuestion` for:
56
+ - Logic changes
57
+ - Architecture decisions
58
+ - API modifications
59
+ - Security-related changes
60
+ - Performance trade-offs
182
61
 
183
62
  ## Guidelines
184
63
 
185
- - Use AskUserQuestion for architecture/logic changes
186
- - Never auto-fix business logic without confirmation
187
- - Commit only changed files (no `git add -A`)
64
+ - Read `.claude/guidelines/work-guidelines.md` first
65
+ - Never auto-fix business logic
66
+ - Commit only changed files (`git add -u`, not `git add -A`)
67
+ - One logical change per commit when possible
188
68
 
189
- ## Output Format (CRITICAL)
69
+ ## Output
190
70
 
191
- End your response with exactly one of:
192
-
193
- ```
194
- REVIEW_COMPLETE: all comments resolved
195
- ```
196
-
197
- ```
198
- REVIEW_INCOMPLETE: max iterations reached, N comments remaining
71
+ Report summary:
199
72
  ```
73
+ Fixed N comments:
74
+ - file1.ts:42 - <brief description>
75
+ - file2.ts:15 - <brief description>
200
76
 
201
- ```
202
- REVIEW_SKIPPED: no CodeRabbit review found within timeout
77
+ Skipped M comments (require manual review):
78
+ - file3.ts:88 - <reason>
203
79
  ```
@@ -14,56 +14,75 @@ Automatically fix and push until CodeRabbit review comments reach zero.
14
14
 
15
15
  ## Safety Limits
16
16
 
17
- - **MAX_ITERATIONS**: 10 (prevent infinite loops)
18
- - **POLL_INTERVAL**: 30 seconds (API rate limit consideration)
19
- - **POLL_TIMEOUT**: 300 seconds (max wait time for review)
17
+ | Limit | Value | Purpose |
18
+ |-------|-------|---------|
19
+ | MAX_ITERATIONS | 10 | Prevent infinite loops |
20
+ | POLL_TIMEOUT | 300s | Wait for CodeRabbit analysis |
21
+ | POLL_INTERVAL | 30s | Status check frequency |
20
22
 
21
- ## Workflow
23
+ ## Workflow (2-API Design)
22
24
 
23
- ### 1. Get PR Info
25
+ ```
26
+ ┌─────────────────────────────────────────────────────────────┐
27
+ │ 1. Init → 2. Wait (Status API) → 3. Check (GraphQL) → 4. Fix │
28
+ │ ↑ ↓ │
29
+ │ └──────────── push & loop ───────────────┘ │
30
+ └─────────────────────────────────────────────────────────────┘
31
+ ```
32
+
33
+ ### Step 1: Initialize
24
34
 
25
35
  ```bash
26
- # Get PR number and repo info
36
+ # Get PR info
27
37
  PR_NUMBER=${ARGUMENTS:-$(gh pr view --json number -q .number 2>/dev/null)}
28
38
  REPO=$(gh repo view --json nameWithOwner -q .nameWithOwner)
29
- OWNER=$(echo "$REPO" | cut -d'/' -f1)
30
- REPO_NAME=$(echo "$REPO" | cut -d'/' -f2)
39
+ SHA=$(gh pr view $PR_NUMBER --json commits --jq '.commits[-1].oid')
31
40
 
32
- echo "Target PR: #${PR_NUMBER} in ${REPO}"
41
+ ITERATION=1
33
42
  ```
34
43
 
35
- ### 2. Start Iteration Loop
44
+ ### Step 2: Wait for CodeRabbit (Status API)
36
45
 
37
- ```
38
- MAX_ITERATIONS=10
39
- ITERATION=0
46
+ CodeRabbit uses Commit Status API, not Check Runs.
40
47
 
41
- while [ $ITERATION -lt $MAX_ITERATIONS ]; do
42
- ITERATION=$((ITERATION + 1))
43
- echo "=== Iteration $ITERATION/$MAX_ITERATIONS ==="
48
+ ```bash
49
+ wait_for_coderabbit() {
50
+ local sha=$1 elapsed=0
51
+
52
+ while [ $elapsed -lt 300 ]; do
53
+ STATE=$(gh api repos/$REPO/commits/$sha/status \
54
+ --jq '.statuses[] | select(.context=="CodeRabbit") | .state' 2>/dev/null)
55
+
56
+ case "$STATE" in
57
+ success) return 0 ;; # Review complete
58
+ pending) ;; # Still analyzing
59
+ *) # No status yet or error
60
+ # Check if CodeRabbit review exists at all
61
+ HAS_REVIEW=$(gh pr view $PR_NUMBER --json reviews \
62
+ --jq '[.reviews[] | select(.author.login | contains("coderabbit"))] | length')
63
+ [ "$HAS_REVIEW" -gt 0 ] && return 0
64
+ ;;
65
+ esac
66
+
67
+ sleep 30
68
+ elapsed=$((elapsed + 30))
69
+ done
70
+
71
+ return 1 # Timeout
72
+ }
73
+
74
+ wait_for_coderabbit "$SHA" || {
75
+ echo "REVIEW_SKIPPED: CodeRabbit not responding within timeout"
76
+ exit 0
77
+ }
44
78
  ```
45
79
 
46
- ### 3. Poll for Unresolved CodeRabbit Comments
80
+ ### Step 3: Check Unresolved Threads (GraphQL)
47
81
 
48
- Use GraphQL API with file-based query (inline `$` causes bash variable expansion issues):
82
+ Single query for count + content. This is the ground truth.
49
83
 
50
84
  ```bash
51
- # Timeout settings: first iteration waits longer for initial review
52
- POLL_TIMEOUT_INITIAL=300 # First iteration: 5 minutes
53
- POLL_TIMEOUT_SUBSEQUENT=120 # Subsequent iterations: 2 minutes (wait for new review)
54
- POLL_INTERVAL=30
55
- MIN_WAIT_BEFORE_EXIT=60 # Minimum wait before declaring "all resolved"
56
-
57
- if [ $ITERATION -eq 1 ]; then
58
- CURRENT_TIMEOUT=$POLL_TIMEOUT_INITIAL
59
- else
60
- CURRENT_TIMEOUT=$POLL_TIMEOUT_SUBSEQUENT
61
- fi
62
-
63
- ELAPSED=0
64
-
65
- # Create GraphQL query file (avoids $ variable expansion in bash)
66
- cat > /tmp/gh_review_query.graphql << 'GRAPHQL'
85
+ GRAPHQL_QUERY='
67
86
  query($owner: String!, $repo: String!, $pr: Int!) {
68
87
  repository(owner: $owner, name: $repo) {
69
88
  pullRequest(number: $pr) {
@@ -82,120 +101,78 @@ query($owner: String!, $repo: String!, $pr: Int!) {
82
101
  }
83
102
  }
84
103
  }
85
- }
86
- GRAPHQL
87
-
88
- echo "Waiting for CodeRabbit review... (timeout: ${CURRENT_TIMEOUT}s)"
89
- while [ $ELAPSED -lt $CURRENT_TIMEOUT ]; do
90
- # Query unresolved review threads from CodeRabbit
91
- # Filter: unresolved + coderabbit + NOT nitpick (actionable only)
92
- UNRESOLVED=$(gh api graphql \
93
- -F query=@/tmp/gh_review_query.graphql \
94
- -f owner="$OWNER" -f repo="$REPO_NAME" -F pr="$PR_NUMBER" \
95
- --jq '[.data.repository.pullRequest.reviewThreads.nodes[] |
96
- select(.isResolved == false) |
97
- select(.comments.nodes[0].author.login | contains("coderabbit")) |
98
- select(.comments.nodes[0].body | (contains("<!-- nitpick -->") or contains("[nitpick]")) | not)] | length')
99
-
100
- if [ "$UNRESOLVED" -gt 0 ]; then
101
- echo "Found $UNRESOLVED unresolved CodeRabbit comments"
102
- break
103
- fi
104
-
105
- # For subsequent iterations: require minimum wait before exit
106
- if [ $ITERATION -gt 1 ] && [ $ELAPSED -ge $MIN_WAIT_BEFORE_EXIT ]; then
107
- echo "No new comments after ${MIN_WAIT_BEFORE_EXIT}s wait. All resolved!"
108
- exit 0
109
- fi
110
-
111
- sleep $POLL_INTERVAL
112
- ELAPSED=$((ELAPSED + POLL_INTERVAL))
113
- echo "Still waiting... ($ELAPSED/$CURRENT_TIMEOUT seconds)"
114
- done
115
-
116
- # Handle timeout
104
+ }'
105
+
106
+ # Filter: unresolved + coderabbit + not nitpick
107
+ JQ_FILTER='[.data.repository.pullRequest.reviewThreads.nodes[] |
108
+ select(.isResolved == false) |
109
+ select(.comments.nodes[0].author.login | contains("coderabbit")) |
110
+ select(.comments.nodes[0].body | (contains("<!-- nitpick -->") or contains("[nitpick]")) | not)]'
111
+
112
+ RESULT=$(gh api graphql -f query="$GRAPHQL_QUERY" \
113
+ -f owner="${REPO%/*}" -f repo="${REPO#*/}" -F pr="$PR_NUMBER")
114
+
115
+ UNRESOLVED=$(echo "$RESULT" | jq "$JQ_FILTER | length")
116
+
117
117
  if [ "$UNRESOLVED" -eq 0 ]; then
118
- if [ $ITERATION -eq 1 ]; then
119
- echo "No CodeRabbit review received within timeout. Exiting."
120
- exit 0
121
- else
122
- echo "All CodeRabbit comments resolved!"
123
- exit 0
124
- fi
118
+ echo "REVIEW_COMPLETE: all comments resolved"
119
+ exit 0
125
120
  fi
121
+
122
+ # Extract comments for fixing
123
+ COMMENTS=$(echo "$RESULT" | jq -r "$JQ_FILTER | .[] |
124
+ \"### File: \(.path):\(.line)\n\n\(.comments.nodes[0].body)\n\n---\n\"")
126
125
  ```
127
126
 
128
- ### 4. Extract Unresolved Comments
127
+ ### Step 4: Fix, Commit, Loop
129
128
 
130
129
  ```bash
131
- # Extract actionable comments only (exclude nitpick)
132
- REVIEW_CONTENT=$(gh api graphql \
133
- -F query=@/tmp/gh_review_query.graphql \
134
- -f owner="$OWNER" -f repo="$REPO_NAME" -F pr="$PR_NUMBER" \
135
- --jq '.data.repository.pullRequest.reviewThreads.nodes[] |
136
- select(.isResolved == false) |
137
- select(.comments.nodes[0].author.login | contains("coderabbit")) |
138
- select(.comments.nodes[0].body | (contains("<!-- nitpick -->") or contains("[nitpick]")) | not) |
139
- "File: \(.path)\nLine: \(.line)\n\nComment:\n\(.comments.nodes[0].body)\n\n---"')
140
-
141
- echo "=== Unresolved CodeRabbit Comments ==="
142
- echo "$REVIEW_CONTENT"
143
- ```
130
+ # For each comment: analyze and fix
131
+ # Follow code-review.md guidelines for auto-fix vs manual
144
132
 
145
- ### 5. Apply Fixes
133
+ # After fixes applied:
134
+ if [ -z "$(git status --porcelain)" ]; then
135
+ echo "REVIEW_COMPLETE: no changes needed"
136
+ exit 0
137
+ fi
146
138
 
147
- Read `.claude/commands/code-review.md` and process each comment following its Auto-fix vs Checklist criteria.
139
+ git add -u
140
+ git commit -m "fix: address CodeRabbit review (iteration $ITERATION)"
141
+ git push
148
142
 
149
- ### 6. Commit & Push
143
+ ITERATION=$((ITERATION + 1))
144
+ [ $ITERATION -gt 10 ] && {
145
+ echo "REVIEW_INCOMPLETE: max iterations (10) reached, $UNRESOLVED comments remaining"
146
+ exit 1
147
+ }
150
148
 
151
- ```bash
152
- # Check for changes
153
- if [ -n "$(git status --porcelain)" ]; then
154
- git add -u
155
- git commit -m "fix: apply CodeRabbit review (iteration $ITERATION)"
156
- git push
157
- echo "Changes pushed. Waiting for next review..."
158
- sleep 60 # Wait for new review
159
- else
160
- echo "No changes to commit"
161
- break
162
- fi
149
+ # Update SHA and loop back to Step 2
150
+ SHA=$(git rev-parse HEAD)
151
+ # Go to Step 2
163
152
  ```
164
153
 
165
- ### 7. Loop Termination
154
+ ## Output Format
166
155
 
167
- ```
168
- done # end while loop
156
+ End with exactly one of:
169
157
 
170
- if [ $ITERATION -ge $MAX_ITERATIONS ]; then
171
- echo "Max iterations reached. Manual review may be required."
172
- exit 1
173
- fi
174
- ```
158
+ | Output | Meaning |
159
+ |--------|---------|
160
+ | `REVIEW_COMPLETE: all comments resolved` | Success |
161
+ | `REVIEW_INCOMPLETE: max iterations reached, N comments remaining` | Hit limit |
162
+ | `REVIEW_SKIPPED: CodeRabbit not responding within timeout` | No review |
175
163
 
176
- ## Output Format
164
+ ## Fix Guidelines
177
165
 
178
- Each iteration outputs:
179
- ```
180
- === Iteration N/10 ===
181
- - Unresolved comments: X
182
- - Auto-fixed: Y
183
- - Requires confirmation: Z
184
- - Pushed commit: abc1234
185
- ```
166
+ Read `.claude/commands/code-review.md` for:
167
+ - Auto-fix criteria (typos, imports, formatting)
168
+ - Manual confirmation criteria (logic changes, architecture)
169
+ - Never auto-fix business logic
186
170
 
187
171
  ## Error Handling
188
172
 
189
173
  | Error | Response |
190
174
  |-------|----------|
191
- | PR not found | Exit with error message |
192
- | API rate limit | Increase poll interval, retry |
193
- | No CodeRabbit review | Exit after timeout |
194
- | Git push failed | Report error, stop iteration |
195
-
196
- ## Guidelines
197
-
198
- - Follow `@CLAUDE.md` project conventions
199
- - Use `AskUserQuestion` for architecture/logic changes
200
- - Never auto-fix business logic without confirmation
201
- - Commit only issue-relevant files (no `git add -A`)
175
+ | PR not found | Exit with error |
176
+ | API rate limit | Increase interval, retry |
177
+ | Git push failed | Report and stop |
178
+ | GraphQL error | Fall back to pr view |
@@ -156,6 +156,35 @@ When Built-in LSP returns "No LSP server available" error:
156
156
  3. Prefer symbolic editing over file-based editing when modifying functions/classes
157
157
  4. Always check `find_referencing_symbols` before renaming/removing symbols
158
158
 
159
+ ### Self-Verification (MANDATORY)
160
+
161
+ #### Execution Requirement
162
+ - **MUST** execute code after writing, not just write and report
163
+ - For Python scripts: run with appropriate interpreter
164
+ - For tests: run pytest or equivalent
165
+ - For notebooks: execute cells via `mcp__ide__executeCode`
166
+
167
+ #### Error-Free Loop
168
+ 1. Write code
169
+ 2. Execute
170
+ 3. Error? → Analyze → Fix → Re-execute
171
+ 4. Repeat until success
172
+ 5. Only then proceed or report
173
+
174
+ **NEVER:**
175
+ - Report "code written" without executing it
176
+ - Move to next step while errors exist
177
+ - Ask user to run code that you should verify yourself
178
+
179
+ #### Result Sanity Check
180
+ After successful execution, verify output makes sense:
181
+ - Data types/shapes as expected
182
+ - No unexpected NaN/None/empty values
183
+ - Numeric ranges reasonable
184
+ - Visualizations render correctly
185
+
186
+ If results look wrong → investigate and fix, don't just report the anomaly.
187
+
159
188
  ### Large File Handling
160
189
  - Files exceeding 25000 tokens cannot be read at once (Claude Code internal limit)
161
190
  - When encountering "exceeds maximum allowed tokens" error: