@yeongjaeyou/claude-code-config 0.17.0 → 0.17.1
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
|
-
|
|
7
|
+
# CodeRabbit Review Handler
|
|
8
8
|
|
|
9
|
-
|
|
9
|
+
Autonomous agent for fixing CodeRabbit review comments.
|
|
10
10
|
|
|
11
|
-
|
|
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
|
-
-
|
|
20
|
+
- `PR_NUMBER`: PR number (required)
|
|
21
|
+
- `COMMENTS`: Extracted review comments in format:
|
|
22
|
+
```
|
|
23
|
+
### File: path/to/file.ts:42
|
|
18
24
|
|
|
19
|
-
|
|
25
|
+
<comment body>
|
|
20
26
|
|
|
21
|
-
|
|
22
|
-
|
|
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
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
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
|
-
|
|
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
|
-
###
|
|
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
|
-
|
|
46
|
+
- Typos, spelling errors
|
|
47
|
+
- Missing imports
|
|
48
|
+
- Formatting issues
|
|
49
|
+
- Unused variables removal
|
|
50
|
+
- Simple type annotations
|
|
51
|
+
- Documentation improvements
|
|
148
52
|
|
|
149
|
-
|
|
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
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
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
|
-
-
|
|
186
|
-
- Never auto-fix business logic
|
|
187
|
-
- Commit only changed files (
|
|
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
|
|
69
|
+
## Output
|
|
190
70
|
|
|
191
|
-
|
|
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
|
-
|
|
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
|
-
|
|
18
|
-
|
|
19
|
-
|
|
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
|
-
|
|
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
|
|
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
|
-
|
|
30
|
-
REPO_NAME=$(echo "$REPO" | cut -d'/' -f2)
|
|
39
|
+
SHA=$(gh pr view $PR_NUMBER --json commits --jq '.commits[-1].oid')
|
|
31
40
|
|
|
32
|
-
|
|
41
|
+
ITERATION=1
|
|
33
42
|
```
|
|
34
43
|
|
|
35
|
-
### 2
|
|
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
|
-
|
|
42
|
-
|
|
43
|
-
|
|
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
|
|
80
|
+
### Step 3: Check Unresolved Threads (GraphQL)
|
|
47
81
|
|
|
48
|
-
|
|
82
|
+
Single query for count + content. This is the ground truth.
|
|
49
83
|
|
|
50
84
|
```bash
|
|
51
|
-
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
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
|
-
|
|
119
|
-
|
|
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
|
|
127
|
+
### Step 4: Fix, Commit, Loop
|
|
129
128
|
|
|
130
129
|
```bash
|
|
131
|
-
#
|
|
132
|
-
|
|
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
|
-
|
|
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
|
-
|
|
139
|
+
git add -u
|
|
140
|
+
git commit -m "fix: address CodeRabbit review (iteration $ITERATION)"
|
|
141
|
+
git push
|
|
148
142
|
|
|
149
|
-
|
|
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
|
-
|
|
152
|
-
|
|
153
|
-
|
|
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
|
-
|
|
154
|
+
## Output Format
|
|
166
155
|
|
|
167
|
-
|
|
168
|
-
done # end while loop
|
|
156
|
+
End with exactly one of:
|
|
169
157
|
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
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
|
-
##
|
|
164
|
+
## Fix Guidelines
|
|
177
165
|
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
-
|
|
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
|
|
192
|
-
| API rate limit | Increase
|
|
193
|
-
|
|
|
194
|
-
|
|
|
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 |
|