@supa-media/claude 1.0.2
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.
- package/LICENSE +21 -0
- package/README.md +102 -0
- package/package.json +30 -0
- package/src/sync.js +319 -0
- package/templates/CLAUDE.md +391 -0
- package/templates/commands/auto-worker.md +596 -0
- package/templates/commands/feature-validate.md +189 -0
- package/templates/commands/fix-ci.md +304 -0
- package/templates/commands/ios-build.md +188 -0
- package/templates/commands/isolate.md +364 -0
- package/templates/commands/lock-up.md +189 -0
- package/templates/commands/review-cycle.md +817 -0
- package/templates/hooks.json +4 -0
- package/templates/settings.json +44 -0
|
@@ -0,0 +1,817 @@
|
|
|
1
|
+
# PR Review Cycle Agent
|
|
2
|
+
|
|
3
|
+
Comprehensive PR processor that handles ALL blockers: review comments, CI failures, merge conflicts, and unresolved threads. Loops until the PR is fully mergeable.
|
|
4
|
+
|
|
5
|
+
## Usage
|
|
6
|
+
|
|
7
|
+
```
|
|
8
|
+
/review-cycle <pr-number>
|
|
9
|
+
```
|
|
10
|
+
|
|
11
|
+
Example:
|
|
12
|
+
```
|
|
13
|
+
/review-cycle 50
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
## Agent Instructions
|
|
17
|
+
|
|
18
|
+
You are a PR Review Cycle agent. Your job is to get a PR into a fully mergeable state by addressing ALL issues: bot comments, CI failures, merge conflicts, and unresolved threads.
|
|
19
|
+
|
|
20
|
+
### Configuration
|
|
21
|
+
|
|
22
|
+
- **Poll interval:** 30 seconds
|
|
23
|
+
- **Max poll attempts:** 30 (about 15 minutes max wait for bot review)
|
|
24
|
+
- **Max total cycles:** 20 (to prevent infinite loops)
|
|
25
|
+
- **Max bot review rounds:** 3 (after 3 rounds of bot review, resolve remaining Low severity threads without fixing)
|
|
26
|
+
- **Bot reviewers:** `cursor` (Bugbot), `greptile-apps[bot]`, or any other configured code review bot
|
|
27
|
+
- **Autofix check names:** `Cursor Bugbot Autofix` (or equivalent autofix check from other bots)
|
|
28
|
+
- **Review policy:** Every PR must receive at least one bot code review. If reviews aren't triggered automatically, explicitly request one (see Phase 1.3).
|
|
29
|
+
|
|
30
|
+
---
|
|
31
|
+
|
|
32
|
+
## CRITICAL: Fetch EVERYTHING Each Cycle
|
|
33
|
+
|
|
34
|
+
Every cycle, fetch the COMPLETE PR state. Do not rely on cached data or assumptions.
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
# Fetch comprehensive PR state - ALL fields
|
|
38
|
+
gh pr view <PR_NUMBER> --json \
|
|
39
|
+
number,title,state,mergeable,mergeStateStatus,\
|
|
40
|
+
reviewDecision,reviews,comments,\
|
|
41
|
+
statusCheckRollup,commits,files,\
|
|
42
|
+
headRefName,baseRefName,url
|
|
43
|
+
```
|
|
44
|
+
|
|
45
|
+
This gives you:
|
|
46
|
+
- `state`: OPEN, CLOSED, MERGED
|
|
47
|
+
- `mergeable`: MERGEABLE, CONFLICTING, UNKNOWN
|
|
48
|
+
- `mergeStateStatus`: BLOCKED, BEHIND, CLEAN, DIRTY, HAS_HOOKS, UNKNOWN, UNSTABLE
|
|
49
|
+
- `reviewDecision`: APPROVED, CHANGES_REQUESTED, REVIEW_REQUIRED, null
|
|
50
|
+
- `statusCheckRollup`: CI/CD check statuses
|
|
51
|
+
- `reviews`: All reviews from all users
|
|
52
|
+
- `comments`: PR-level comments (not just review threads!)
|
|
53
|
+
|
|
54
|
+
---
|
|
55
|
+
|
|
56
|
+
## Phase 1: Comprehensive State Check
|
|
57
|
+
|
|
58
|
+
### 1.1 Fetch Full PR State
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
PR_STATE=$(gh pr view <PR_NUMBER> --json \
|
|
62
|
+
number,state,mergeable,mergeStateStatus,reviewDecision,\
|
|
63
|
+
headRefName,baseRefName \
|
|
64
|
+
--jq '{
|
|
65
|
+
state: .state,
|
|
66
|
+
mergeable: .mergeable,
|
|
67
|
+
mergeStatus: .mergeStateStatus,
|
|
68
|
+
reviewDecision: .reviewDecision,
|
|
69
|
+
branch: .headRefName,
|
|
70
|
+
base: .baseRefName
|
|
71
|
+
}')
|
|
72
|
+
echo "$PR_STATE"
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### 1.2 Check if Already Merged/Closed
|
|
76
|
+
|
|
77
|
+
```bash
|
|
78
|
+
gh pr view <PR_NUMBER> --json state --jq '.state'
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
- If `MERGED` or `CLOSED`: Exit with success message
|
|
82
|
+
- If `OPEN`: Continue
|
|
83
|
+
|
|
84
|
+
### 1.3 Ensure Bot Review is Requested
|
|
85
|
+
|
|
86
|
+
Check if a bot reviewer has already been requested or has reviewed. If not, request one:
|
|
87
|
+
|
|
88
|
+
```bash
|
|
89
|
+
# Check existing reviews/requested reviewers
|
|
90
|
+
gh pr view <PR_NUMBER> --json reviews,reviewRequests \
|
|
91
|
+
--jq '{reviews: [.reviews[].author.login], requested: [.reviewRequests[].login]}'
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
If no bot reviewer (`cursor`, `greptile-apps[bot]`, etc.) appears in reviews or requests, request one:
|
|
95
|
+
|
|
96
|
+
```bash
|
|
97
|
+
# Request Cursor Bugbot (primary), fall back to others if unavailable
|
|
98
|
+
gh pr edit <PR_NUMBER> --add-reviewer cursor
|
|
99
|
+
```
|
|
100
|
+
|
|
101
|
+
Some bots trigger automatically on PR creation — that's fine, skip this step if a review is already pending or complete.
|
|
102
|
+
|
|
103
|
+
### 1.4 Sync Local Branch
|
|
104
|
+
|
|
105
|
+
```bash
|
|
106
|
+
git fetch origin
|
|
107
|
+
BRANCH=$(gh pr view <PR_NUMBER> --json headRefName --jq '.headRefName')
|
|
108
|
+
git checkout $BRANCH
|
|
109
|
+
git pull origin $BRANCH
|
|
110
|
+
```
|
|
111
|
+
|
|
112
|
+
---
|
|
113
|
+
|
|
114
|
+
## Phase 2: Handle Merge Conflicts
|
|
115
|
+
|
|
116
|
+
**ALWAYS check and fix merge conflicts before anything else.**
|
|
117
|
+
|
|
118
|
+
### 2.1 Check for Conflicts
|
|
119
|
+
|
|
120
|
+
```bash
|
|
121
|
+
gh pr view <PR_NUMBER> --json mergeable --jq '.mergeable'
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
- `MERGEABLE`: No conflicts, continue
|
|
125
|
+
- `CONFLICTING`: Fix conflicts (see below)
|
|
126
|
+
- `UNKNOWN`: Wait and re-check
|
|
127
|
+
|
|
128
|
+
### 2.2 Fix Merge Conflicts
|
|
129
|
+
|
|
130
|
+
If conflicting:
|
|
131
|
+
|
|
132
|
+
```bash
|
|
133
|
+
# Fetch and merge base branch
|
|
134
|
+
git fetch origin main
|
|
135
|
+
git merge origin/main --no-edit
|
|
136
|
+
|
|
137
|
+
# If conflicts occur, they'll be shown
|
|
138
|
+
git status
|
|
139
|
+
```
|
|
140
|
+
|
|
141
|
+
**For each conflicted file:**
|
|
142
|
+
1. Read the file to understand the conflict markers
|
|
143
|
+
2. Understand both sides of the conflict
|
|
144
|
+
3. Resolve by keeping the correct version (usually merge both changes intelligently)
|
|
145
|
+
4. Stage the resolved file: `git add <file>`
|
|
146
|
+
|
|
147
|
+
**After resolving all conflicts:**
|
|
148
|
+
```bash
|
|
149
|
+
git commit -m "chore: resolve merge conflicts with main
|
|
150
|
+
|
|
151
|
+
Co-Authored-By: Claude <noreply@anthropic.com>"
|
|
152
|
+
git push
|
|
153
|
+
```
|
|
154
|
+
|
|
155
|
+
**Wait 30 seconds and re-check mergeable status before continuing.**
|
|
156
|
+
|
|
157
|
+
---
|
|
158
|
+
|
|
159
|
+
## Phase 3: Handle CI/CD Failures
|
|
160
|
+
|
|
161
|
+
### 3.1 Fetch All Check Statuses
|
|
162
|
+
|
|
163
|
+
```bash
|
|
164
|
+
gh pr checks <PR_NUMBER> --json name,state,conclusion
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
Or via API for more detail:
|
|
168
|
+
|
|
169
|
+
```bash
|
|
170
|
+
gh pr view <PR_NUMBER> --json statusCheckRollup --jq '.statusCheckRollup[] | {name: .name, status: .status, conclusion: .conclusion}'
|
|
171
|
+
```
|
|
172
|
+
|
|
173
|
+
### 3.2 Check Status Meanings
|
|
174
|
+
|
|
175
|
+
- `SUCCESS` / `NEUTRAL` / `SKIPPED`: OK
|
|
176
|
+
- `PENDING` / `QUEUED` / `IN_PROGRESS`: Wait and re-poll
|
|
177
|
+
- `FAILURE` / `ERROR` / `TIMED_OUT`: Needs fixing
|
|
178
|
+
|
|
179
|
+
**Bot-specific statuses (e.g. Cursor Bugbot, or equivalent):**
|
|
180
|
+
- Bot review check: `NEUTRAL` = found issues (check threads), `SUCCESS` = no issues
|
|
181
|
+
- Bot autofix check: `IN_PROGRESS` = actively fixing issues, may push commits at any time. **Do not process review comments (Phase 4) while this is running** — wait for it to finish first. CI fixes (Phase 3.3) may proceed independently since they address different concerns.
|
|
182
|
+
|
|
183
|
+
### 3.3 Fix CI Failures
|
|
184
|
+
|
|
185
|
+
For each failing check:
|
|
186
|
+
|
|
187
|
+
1. **Get failure details:**
|
|
188
|
+
```bash
|
|
189
|
+
gh run view <run-id> --log-failed
|
|
190
|
+
```
|
|
191
|
+
Or check the GitHub Actions URL in the check details.
|
|
192
|
+
|
|
193
|
+
2. **Common failures and fixes:**
|
|
194
|
+
|
|
195
|
+
**Type errors:**
|
|
196
|
+
```bash
|
|
197
|
+
pnpm typecheck
|
|
198
|
+
# Fix any type errors shown
|
|
199
|
+
```
|
|
200
|
+
|
|
201
|
+
**Test failures:**
|
|
202
|
+
```bash
|
|
203
|
+
pnpm test
|
|
204
|
+
# Fix failing tests
|
|
205
|
+
```
|
|
206
|
+
|
|
207
|
+
**Build failures:**
|
|
208
|
+
```bash
|
|
209
|
+
pnpm build
|
|
210
|
+
# Fix build errors
|
|
211
|
+
```
|
|
212
|
+
|
|
213
|
+
**Lint failures:**
|
|
214
|
+
```bash
|
|
215
|
+
pnpm lint --fix
|
|
216
|
+
```
|
|
217
|
+
|
|
218
|
+
3. **Commit fixes:**
|
|
219
|
+
```bash
|
|
220
|
+
git add .
|
|
221
|
+
git commit -m "fix: resolve CI failures
|
|
222
|
+
|
|
223
|
+
Co-Authored-By: Claude <noreply@anthropic.com>"
|
|
224
|
+
```
|
|
225
|
+
|
|
226
|
+
4. **Wait for Bugbot Autofix before pushing:**
|
|
227
|
+
|
|
228
|
+
Before pushing, check if Autofix is running:
|
|
229
|
+
```bash
|
|
230
|
+
gh pr view <PR_NUMBER> --json statusCheckRollup \
|
|
231
|
+
--jq '.statusCheckRollup[] | select(.name == "Cursor Bugbot Autofix") | {status: .status}'
|
|
232
|
+
```
|
|
233
|
+
If `IN_PROGRESS`, poll every 30 seconds until complete, then pull and push:
|
|
234
|
+
```bash
|
|
235
|
+
git pull --rebase origin $BRANCH
|
|
236
|
+
git push
|
|
237
|
+
```
|
|
238
|
+
|
|
239
|
+
5. **Wait for CI to re-run (poll every 30 seconds)**
|
|
240
|
+
|
|
241
|
+
---
|
|
242
|
+
|
|
243
|
+
## Phase 3.5: Wait for Bot Autofix Before Processing Comments
|
|
244
|
+
|
|
245
|
+
**CRITICAL:** Bot autofix (e.g. Cursor Bugbot Autofix) runs concurrently and may fix the same issues you're about to fix. Always wait for it to complete before processing review threads. This prevents:
|
|
246
|
+
- Push rejections (Autofix pushed while you were committing)
|
|
247
|
+
- Rebase conflicts (your fix overlaps with Autofix's fix on the same lines)
|
|
248
|
+
- Redundant work (fixing something Autofix already fixed)
|
|
249
|
+
|
|
250
|
+
### 3.5.1 Wait for Bot Review and Autofix Checks
|
|
251
|
+
|
|
252
|
+
Poll until bot review AND autofix checks have completed:
|
|
253
|
+
|
|
254
|
+
```bash
|
|
255
|
+
# Poll every 30 seconds until bot checks are done
|
|
256
|
+
gh pr view <PR_NUMBER> --json statusCheckRollup \
|
|
257
|
+
--jq '.statusCheckRollup[] | select(.name | test("Cursor Bugbot|Greptile|Codex"; "i")) | {name: .name, status: .status, conclusion: .conclusion}'
|
|
258
|
+
```
|
|
259
|
+
|
|
260
|
+
**Wait until:**
|
|
261
|
+
- Bot review check status is `COMPLETED`
|
|
262
|
+
- Bot autofix check status is `COMPLETED` (or doesn't appear, meaning no autofix was triggered)
|
|
263
|
+
|
|
264
|
+
**Do NOT proceed to Phase 4 while any bot check is `IN_PROGRESS`.**
|
|
265
|
+
|
|
266
|
+
### 3.5.2 Pull Autofix Commits
|
|
267
|
+
|
|
268
|
+
After bot autofix completes, it may have pushed commits. Always pull before processing:
|
|
269
|
+
|
|
270
|
+
```bash
|
|
271
|
+
git pull origin $BRANCH
|
|
272
|
+
```
|
|
273
|
+
|
|
274
|
+
### 3.5.3 Track Bot Review Round
|
|
275
|
+
|
|
276
|
+
Increment a `bot_review_round` counter each time you enter this phase. After **3 rounds** of bot review:
|
|
277
|
+
- Only fix **Medium** or higher severity issues
|
|
278
|
+
- **Resolve Low severity threads without fixing** — these are usually nitpicks about theoretical edge cases
|
|
279
|
+
- This prevents infinite loops where the bot keeps finding new low-severity issues after each fix
|
|
280
|
+
|
|
281
|
+
---
|
|
282
|
+
|
|
283
|
+
## Phase 4: Handle ALL Comments and Reviews
|
|
284
|
+
|
|
285
|
+
### 4.1 Fetch ALL Unresolved Review Threads
|
|
286
|
+
|
|
287
|
+
```bash
|
|
288
|
+
# NOTE: Replace OWNER and REPO with the actual GitHub owner and repository name
|
|
289
|
+
gh api graphql -f query='query {
|
|
290
|
+
repository(owner: "OWNER", name: "REPO") {
|
|
291
|
+
pullRequest(number: <PR_NUMBER>) {
|
|
292
|
+
reviewThreads(first: 100) {
|
|
293
|
+
nodes {
|
|
294
|
+
id
|
|
295
|
+
isResolved
|
|
296
|
+
isOutdated
|
|
297
|
+
path
|
|
298
|
+
line
|
|
299
|
+
comments(first: 10) {
|
|
300
|
+
nodes {
|
|
301
|
+
id
|
|
302
|
+
body
|
|
303
|
+
author { login }
|
|
304
|
+
createdAt
|
|
305
|
+
}
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
}'
|
|
312
|
+
```
|
|
313
|
+
|
|
314
|
+
**Process ALL unresolved threads** - not just from bots:
|
|
315
|
+
|
|
316
|
+
```bash
|
|
317
|
+
# Filter unresolved, non-outdated threads
|
|
318
|
+
--jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false and .isOutdated == false)'
|
|
319
|
+
```
|
|
320
|
+
|
|
321
|
+
### 4.2 Fetch PR-Level Comments (Not Review Threads)
|
|
322
|
+
|
|
323
|
+
Bot comments sometimes appear as PR comments, not review threads:
|
|
324
|
+
|
|
325
|
+
```bash
|
|
326
|
+
gh pr view <PR_NUMBER> --json comments --jq '.comments[] | {author: .author.login, body: .body, createdAt: .createdAt}'
|
|
327
|
+
```
|
|
328
|
+
|
|
329
|
+
Check for any actionable comments from:
|
|
330
|
+
- `cursor`
|
|
331
|
+
- `greptile-apps[bot]`
|
|
332
|
+
- Any bot with actionable feedback
|
|
333
|
+
|
|
334
|
+
### 4.3 Fetch Review States
|
|
335
|
+
|
|
336
|
+
```bash
|
|
337
|
+
gh pr view <PR_NUMBER> --json reviews --jq '.reviews[] | {author: .author.login, state: .state, body: .body, submittedAt: .submittedAt}'
|
|
338
|
+
```
|
|
339
|
+
|
|
340
|
+
Check for:
|
|
341
|
+
- `CHANGES_REQUESTED` from any reviewer
|
|
342
|
+
- `COMMENTED` with actionable feedback
|
|
343
|
+
|
|
344
|
+
### 4.4 Process Each Issue
|
|
345
|
+
|
|
346
|
+
For EACH unresolved thread or actionable comment:
|
|
347
|
+
|
|
348
|
+
1. **Read the comment carefully** — note the severity level (if from a bot reviewer)
|
|
349
|
+
2. **Check if bot autofix already fixed it:**
|
|
350
|
+
- Read the file at the mentioned path and line
|
|
351
|
+
- Compare the current code against the issue described in the comment
|
|
352
|
+
- If the issue is already resolved (autofix pushed a commit), **skip straight to section 4.5 (resolve thread)** — do not commit
|
|
353
|
+
- Check git log for recent autofix commits: `git log --oneline -5 --author="cursor"`
|
|
354
|
+
3. **If bot_review_round >= 3 and severity is Low:** **skip straight to section 4.5 (resolve thread without fixing)** — do not commit
|
|
355
|
+
4. **Make the fix** - Edit the file to address the concern
|
|
356
|
+
5. **Verify the fix doesn't break anything:**
|
|
357
|
+
```bash
|
|
358
|
+
pnpm typecheck
|
|
359
|
+
pnpm test 2>/dev/null || true
|
|
360
|
+
```
|
|
361
|
+
6. **Commit the fix:**
|
|
362
|
+
```bash
|
|
363
|
+
git add <files>
|
|
364
|
+
git commit -m "fix: <description>
|
|
365
|
+
|
|
366
|
+
Addresses review comment.
|
|
367
|
+
|
|
368
|
+
Co-Authored-By: Claude <noreply@anthropic.com>"
|
|
369
|
+
```
|
|
370
|
+
|
|
371
|
+
### 4.5 ALWAYS Resolve Threads After Fixing
|
|
372
|
+
|
|
373
|
+
**THIS IS CRITICAL** - Unresolved threads block merge.
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
gh api graphql -f query='mutation {
|
|
377
|
+
resolveReviewThread(input: {threadId: "<THREAD_ID>"}) {
|
|
378
|
+
thread { isResolved }
|
|
379
|
+
}
|
|
380
|
+
}'
|
|
381
|
+
```
|
|
382
|
+
|
|
383
|
+
**Verify it resolved:**
|
|
384
|
+
```bash
|
|
385
|
+
# NOTE: Replace OWNER and REPO with the actual GitHub owner and repository name
|
|
386
|
+
gh api graphql -f query='query {
|
|
387
|
+
repository(owner: "OWNER", name: "REPO") {
|
|
388
|
+
pullRequest(number: <PR_NUMBER>) {
|
|
389
|
+
reviewThreads(first: 100) {
|
|
390
|
+
nodes {
|
|
391
|
+
id
|
|
392
|
+
isResolved
|
|
393
|
+
}
|
|
394
|
+
}
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
}' --jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)] | length'
|
|
398
|
+
# Should return 0
|
|
399
|
+
```
|
|
400
|
+
|
|
401
|
+
### 4.6 Handle False Positives
|
|
402
|
+
|
|
403
|
+
If a comment is a false positive or not actionable:
|
|
404
|
+
|
|
405
|
+
1. **Reply explaining why:**
|
|
406
|
+
```bash
|
|
407
|
+
gh api graphql -f query='mutation {
|
|
408
|
+
addPullRequestReviewComment(input: {
|
|
409
|
+
pullRequestReviewId: "<REVIEW_ID>",
|
|
410
|
+
body: "This is intentional because [reason]. The current implementation [explanation].",
|
|
411
|
+
inReplyTo: "<COMMENT_ID>"
|
|
412
|
+
}) {
|
|
413
|
+
comment { id }
|
|
414
|
+
}
|
|
415
|
+
}'
|
|
416
|
+
```
|
|
417
|
+
|
|
418
|
+
2. **Still resolve the thread** - Don't leave it open:
|
|
419
|
+
```bash
|
|
420
|
+
gh api graphql -f query='mutation {
|
|
421
|
+
resolveReviewThread(input: {threadId: "<THREAD_ID>"}) {
|
|
422
|
+
thread { isResolved }
|
|
423
|
+
}
|
|
424
|
+
}'
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
---
|
|
428
|
+
|
|
429
|
+
## Phase 4.7: Documentation and Onboarding Sync Check
|
|
430
|
+
|
|
431
|
+
If your project maintains user-facing documentation (onboarding guides, feature docs, etc.), check whether any PR changes require documentation updates.
|
|
432
|
+
|
|
433
|
+
### 4.7.1 Get the PR's Changed Files
|
|
434
|
+
|
|
435
|
+
```bash
|
|
436
|
+
gh pr view <PR_NUMBER> --json files --jq '.files[].path'
|
|
437
|
+
```
|
|
438
|
+
|
|
439
|
+
### 4.7.2 Identify Documentation Requirements
|
|
440
|
+
|
|
441
|
+
For your project, determine:
|
|
442
|
+
1. Which documentation files exist (guides, API docs, user manuals, etc.)
|
|
443
|
+
2. Which features or user-facing components they cover
|
|
444
|
+
3. Create a mapping of: "If code change touches X, docs file Y may need updates"
|
|
445
|
+
|
|
446
|
+
Example mapping:
|
|
447
|
+
- If changed: user authentication paths → Update: Auth guide documentation
|
|
448
|
+
- If changed: API endpoints → Update: API reference documentation
|
|
449
|
+
- If changed: UI labels or workflows → Update: User guide documentation
|
|
450
|
+
|
|
451
|
+
### 4.7.3 Check for Documentation Updates
|
|
452
|
+
|
|
453
|
+
For each changed file in the PR:
|
|
454
|
+
|
|
455
|
+
1. **Inspect the change** — does it alter something user-facing (labels, flows, screens, API contracts)?
|
|
456
|
+
2. **Check if related docs were updated** — are the corresponding documentation files in the PR's changed files list?
|
|
457
|
+
3. **Decide and act:**
|
|
458
|
+
- **If user-facing change AND docs updated** ✓ Continue normally
|
|
459
|
+
- **If internal-only change** ✓ No docs needed, continue
|
|
460
|
+
- **If user-facing change BUT docs NOT updated:**
|
|
461
|
+
- If the impact is small and contained: update the docs yourself in this branch
|
|
462
|
+
- If the impact is large/ambiguous: post a PR comment flagging it for the author to decide
|
|
463
|
+
|
|
464
|
+
### 4.7.4 Comment If Docs Are Missing
|
|
465
|
+
|
|
466
|
+
If documentation is out of sync:
|
|
467
|
+
```bash
|
|
468
|
+
gh pr comment <PR_NUMBER> --body "📝 Heads up: this PR changes user-facing behavior but doesn't update the related documentation. Please review and update the docs to match the new behavior, or let me know if the change is internal-only."
|
|
469
|
+
```
|
|
470
|
+
|
|
471
|
+
---
|
|
472
|
+
|
|
473
|
+
## Phase 5: Push and Wait for Re-Review
|
|
474
|
+
|
|
475
|
+
### 5.1 Pull Before Push (Bot Autofix Safety)
|
|
476
|
+
|
|
477
|
+
**ALWAYS pull before pushing** to pick up any bot autofix commits that landed while you were working:
|
|
478
|
+
|
|
479
|
+
```bash
|
|
480
|
+
# Pull with rebase to put your fixes on top of any Autofix commits
|
|
481
|
+
git pull --rebase origin $BRANCH
|
|
482
|
+
```
|
|
483
|
+
|
|
484
|
+
**If rebase conflicts occur:**
|
|
485
|
+
1. Check if Autofix already fixed the same issue (common case)
|
|
486
|
+
2. If so, drop your commit: `git rebase --skip`
|
|
487
|
+
3. If different changes, resolve conflicts, `git add <files>`, `git rebase --continue`
|
|
488
|
+
|
|
489
|
+
### 5.2 Push All Fixes
|
|
490
|
+
|
|
491
|
+
```bash
|
|
492
|
+
git push origin $BRANCH
|
|
493
|
+
```
|
|
494
|
+
|
|
495
|
+
**If push is rejected** (Autofix pushed while you were rebasing):
|
|
496
|
+
```bash
|
|
497
|
+
git pull --rebase origin $BRANCH
|
|
498
|
+
git push origin $BRANCH
|
|
499
|
+
```
|
|
500
|
+
|
|
501
|
+
### 5.3 Wait for CI and Bot Checks
|
|
502
|
+
|
|
503
|
+
Poll every 30 seconds. **Wait for ALL checks to complete:**
|
|
504
|
+
|
|
505
|
+
```bash
|
|
506
|
+
# Check ALL statuses including bot review and autofix
|
|
507
|
+
gh pr view <PR_NUMBER> --json statusCheckRollup \
|
|
508
|
+
--jq '.statusCheckRollup[] | {name: .name, status: .status, conclusion: .conclusion}'
|
|
509
|
+
```
|
|
510
|
+
|
|
511
|
+
**Do not proceed until:**
|
|
512
|
+
- All CI checks are `COMPLETED`
|
|
513
|
+
- Bot review check is `COMPLETED`
|
|
514
|
+
- Bot autofix check is `COMPLETED` (or absent)
|
|
515
|
+
|
|
516
|
+
Also check:
|
|
517
|
+
```bash
|
|
518
|
+
# Check unresolved thread count
|
|
519
|
+
# NOTE: Replace OWNER and REPO with the actual GitHub owner and repository name
|
|
520
|
+
gh api graphql -f query='query {
|
|
521
|
+
repository(owner: "OWNER", name: "REPO") {
|
|
522
|
+
pullRequest(number: <PR_NUMBER>) {
|
|
523
|
+
reviewThreads(first: 100) {
|
|
524
|
+
nodes { isResolved }
|
|
525
|
+
}
|
|
526
|
+
}
|
|
527
|
+
}
|
|
528
|
+
}' --jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)] | length'
|
|
529
|
+
```
|
|
530
|
+
|
|
531
|
+
### 5.4 Pull After Autofix Completes
|
|
532
|
+
|
|
533
|
+
After bot autofix finishes, always pull to get any new commits it pushed:
|
|
534
|
+
|
|
535
|
+
```bash
|
|
536
|
+
git pull origin $BRANCH
|
|
537
|
+
```
|
|
538
|
+
|
|
539
|
+
### 5.5 Re-Check Everything
|
|
540
|
+
|
|
541
|
+
After each push, go back to Phase 1 and re-fetch EVERYTHING. Don't assume previous state. (The `bot_review_round` counter is incremented in Phase 3.5.3 when the bot completes a new review.)
|
|
542
|
+
|
|
543
|
+
---
|
|
544
|
+
|
|
545
|
+
## Phase 6: Final Merge Check
|
|
546
|
+
|
|
547
|
+
Before attempting merge, verify ALL conditions:
|
|
548
|
+
|
|
549
|
+
```bash
|
|
550
|
+
# 1. No merge conflicts
|
|
551
|
+
gh pr view <PR_NUMBER> --json mergeable --jq '.mergeable'
|
|
552
|
+
# Must be: MERGEABLE
|
|
553
|
+
|
|
554
|
+
# 2. CI passing
|
|
555
|
+
gh pr checks <PR_NUMBER> --json conclusion --jq 'all(.conclusion == "success" or .conclusion == "neutral" or .conclusion == "skipped")'
|
|
556
|
+
# Must be: true
|
|
557
|
+
|
|
558
|
+
# 3. No unresolved threads
|
|
559
|
+
# NOTE: Replace OWNER and REPO with the actual GitHub owner and repository name
|
|
560
|
+
gh api graphql -f query='query {
|
|
561
|
+
repository(owner: "OWNER", name: "REPO") {
|
|
562
|
+
pullRequest(number: <PR_NUMBER>) {
|
|
563
|
+
reviewThreads(first: 100) {
|
|
564
|
+
nodes { isResolved }
|
|
565
|
+
}
|
|
566
|
+
}
|
|
567
|
+
}
|
|
568
|
+
}' --jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)] | length'
|
|
569
|
+
# Must be: 0
|
|
570
|
+
|
|
571
|
+
# 4. Merge state is clean
|
|
572
|
+
gh pr view <PR_NUMBER> --json mergeStateStatus --jq '.mergeStateStatus'
|
|
573
|
+
# Should be: CLEAN or HAS_HOOKS
|
|
574
|
+
```
|
|
575
|
+
|
|
576
|
+
---
|
|
577
|
+
|
|
578
|
+
## Phase 7: Merge
|
|
579
|
+
|
|
580
|
+
### 7.1 Update Branch if Behind
|
|
581
|
+
|
|
582
|
+
```bash
|
|
583
|
+
MERGE_STATUS=$(gh pr view <PR_NUMBER> --json mergeStateStatus --jq '.mergeStateStatus')
|
|
584
|
+
if [ "$MERGE_STATUS" = "BEHIND" ]; then
|
|
585
|
+
git fetch origin main
|
|
586
|
+
git merge origin/main --no-edit
|
|
587
|
+
git push
|
|
588
|
+
# Wait for CI to pass again
|
|
589
|
+
fi
|
|
590
|
+
```
|
|
591
|
+
|
|
592
|
+
### 7.2 Attempt Merge
|
|
593
|
+
|
|
594
|
+
```bash
|
|
595
|
+
# Try direct merge
|
|
596
|
+
gh pr merge <PR_NUMBER> --squash --delete-branch
|
|
597
|
+
|
|
598
|
+
# If that fails, try with auto-merge
|
|
599
|
+
gh pr merge <PR_NUMBER> --squash --delete-branch --auto
|
|
600
|
+
```
|
|
601
|
+
|
|
602
|
+
### 7.3 Verify Merge
|
|
603
|
+
|
|
604
|
+
```bash
|
|
605
|
+
gh pr view <PR_NUMBER> --json state --jq '.state'
|
|
606
|
+
# Should be: MERGED
|
|
607
|
+
```
|
|
608
|
+
|
|
609
|
+
---
|
|
610
|
+
|
|
611
|
+
## Phase 8: Post-Merge CI Verification
|
|
612
|
+
|
|
613
|
+
**CRITICAL:** A merged PR can break the main branch CI even if PR CI passed. Always verify CI after merge.
|
|
614
|
+
|
|
615
|
+
### 8.1 Wait for Main Branch CI to Start
|
|
616
|
+
|
|
617
|
+
After merge, wait for the main branch CI to trigger:
|
|
618
|
+
|
|
619
|
+
```bash
|
|
620
|
+
# Wait 30 seconds for CI to start
|
|
621
|
+
sleep 30
|
|
622
|
+
|
|
623
|
+
# Get the latest workflow run on main
|
|
624
|
+
gh run list --branch main --limit 1 --json databaseId,status,conclusion,createdAt
|
|
625
|
+
```
|
|
626
|
+
|
|
627
|
+
### 8.2 Poll Main Branch CI Status
|
|
628
|
+
|
|
629
|
+
Poll every 30 seconds until CI completes:
|
|
630
|
+
|
|
631
|
+
```bash
|
|
632
|
+
# Get the run ID from the latest main run
|
|
633
|
+
RUN_ID=$(gh run list --branch main --limit 1 --json databaseId --jq '.[0].databaseId')
|
|
634
|
+
|
|
635
|
+
# Check status
|
|
636
|
+
gh run view $RUN_ID --json status,conclusion --jq '{status: .status, conclusion: .conclusion}'
|
|
637
|
+
```
|
|
638
|
+
|
|
639
|
+
**Status meanings:**
|
|
640
|
+
- `status: completed` + `conclusion: success` -> Continue to completion report
|
|
641
|
+
- `status: completed` + `conclusion: failure` -> Fix CI (see below)
|
|
642
|
+
- `status: in_progress` / `queued` -> Keep polling
|
|
643
|
+
|
|
644
|
+
**Max wait time:** 15 minutes (30 polls x 30 seconds)
|
|
645
|
+
|
|
646
|
+
### 8.3 Handle Main Branch CI Failure
|
|
647
|
+
|
|
648
|
+
If main branch CI fails after merge:
|
|
649
|
+
|
|
650
|
+
1. **Get the failed run details:**
|
|
651
|
+
```bash
|
|
652
|
+
RUN_ID=$(gh run list --branch main --limit 1 --json databaseId --jq '.[0].databaseId')
|
|
653
|
+
gh run view $RUN_ID --log-failed 2>&1 | head -200
|
|
654
|
+
```
|
|
655
|
+
|
|
656
|
+
2. **Invoke the fix-ci skill:**
|
|
657
|
+
```
|
|
658
|
+
Use Skill tool: /fix-ci $RUN_ID
|
|
659
|
+
```
|
|
660
|
+
|
|
661
|
+
This will:
|
|
662
|
+
- Investigate the failure
|
|
663
|
+
- Create a fix branch
|
|
664
|
+
- Add regression tests to prevent recurrence
|
|
665
|
+
- Create a PR
|
|
666
|
+
- Run review-cycle on that PR
|
|
667
|
+
- Merge the fix
|
|
668
|
+
|
|
669
|
+
3. **Wait for the fix to merge and verify main CI again:**
|
|
670
|
+
- After /fix-ci completes, go back to step 8.1
|
|
671
|
+
- Poll main branch CI again
|
|
672
|
+
- Repeat until CI passes
|
|
673
|
+
|
|
674
|
+
### 8.4 Max Fix Attempts
|
|
675
|
+
|
|
676
|
+
If main branch CI fails 3 times in a row after fixes:
|
|
677
|
+
1. Stop the cycle
|
|
678
|
+
2. Report the persistent failure
|
|
679
|
+
3. Flag for human intervention
|
|
680
|
+
|
|
681
|
+
```markdown
|
|
682
|
+
## MAIN BRANCH CI FAILURE - Manual Intervention Required
|
|
683
|
+
|
|
684
|
+
**Original PR:** #<number>
|
|
685
|
+
**Main CI Runs Failed:** 3
|
|
686
|
+
**Last Error:** <error summary>
|
|
687
|
+
|
|
688
|
+
Attempted fixes:
|
|
689
|
+
1. PR #<fix-1> - <description>
|
|
690
|
+
2. PR #<fix-2> - <description>
|
|
691
|
+
3. PR #<fix-3> - <description>
|
|
692
|
+
|
|
693
|
+
The issue persists. Please investigate manually.
|
|
694
|
+
```
|
|
695
|
+
|
|
696
|
+
---
|
|
697
|
+
|
|
698
|
+
## Phase 9: Completion Report
|
|
699
|
+
|
|
700
|
+
```markdown
|
|
701
|
+
## Review Cycle Complete
|
|
702
|
+
|
|
703
|
+
**PR:** #<number>
|
|
704
|
+
**Final State:** MERGED / BLOCKED
|
|
705
|
+
**Total Cycles:** X
|
|
706
|
+
**Total Comments Fixed:** Y
|
|
707
|
+
**Total PR CI Fixes:** Z
|
|
708
|
+
**Main CI:** PASSED / FIXED (N attempts)
|
|
709
|
+
|
|
710
|
+
### Issues Resolved
|
|
711
|
+
| Type | Count | Details |
|
|
712
|
+
|------|-------|---------|
|
|
713
|
+
| Merge Conflicts | X | Resolved with main |
|
|
714
|
+
| PR CI Failures | Y | Type errors, test fixes |
|
|
715
|
+
| Review Comments (manual fix) | Z | See list below |
|
|
716
|
+
| Bot autofix commits | A | Issues auto-resolved by bot |
|
|
717
|
+
| Low-severity resolved without fix | L | Resolved after round cap |
|
|
718
|
+
| Main CI Fixes | N | Post-merge fixes via /fix-ci |
|
|
719
|
+
|
|
720
|
+
### Comments Addressed
|
|
721
|
+
1. `path/file.ts:42` - [cursor] Fixed type annotation
|
|
722
|
+
2. `path/other.ts:15` - [greptile] Added error handling
|
|
723
|
+
3. `path/file.ts:100` - [autofix] Fixed automatically by bot
|
|
724
|
+
|
|
725
|
+
### Post-Merge CI Fixes (if any)
|
|
726
|
+
1. PR #<fix-pr> - <description of fix>
|
|
727
|
+
- Root cause: <explanation>
|
|
728
|
+
- Test added: `<test-file.ts>`
|
|
729
|
+
|
|
730
|
+
### Final Verification
|
|
731
|
+
- [x] No merge conflicts
|
|
732
|
+
- [x] All PR CI checks passing
|
|
733
|
+
- [x] All review threads resolved
|
|
734
|
+
- [x] Documentation synced or flagged (Phase 4.7)
|
|
735
|
+
- [x] PR merged to main
|
|
736
|
+
- [x] Main branch CI passing
|
|
737
|
+
- [x] Regression tests added (if CI was fixed)
|
|
738
|
+
```
|
|
739
|
+
|
|
740
|
+
---
|
|
741
|
+
|
|
742
|
+
## Error Recovery
|
|
743
|
+
|
|
744
|
+
### Thread Won't Resolve
|
|
745
|
+
|
|
746
|
+
Sometimes the GraphQL mutation fails silently. Force resolve:
|
|
747
|
+
|
|
748
|
+
```bash
|
|
749
|
+
# Get all thread IDs
|
|
750
|
+
# NOTE: Replace OWNER and REPO with the actual GitHub owner and repository name
|
|
751
|
+
THREADS=$(gh api graphql -f query='query {
|
|
752
|
+
repository(owner: "OWNER", name: "REPO") {
|
|
753
|
+
pullRequest(number: <PR_NUMBER>) {
|
|
754
|
+
reviewThreads(first: 100) {
|
|
755
|
+
nodes { id isResolved }
|
|
756
|
+
}
|
|
757
|
+
}
|
|
758
|
+
}
|
|
759
|
+
}' --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false) | .id')
|
|
760
|
+
|
|
761
|
+
# Resolve each one
|
|
762
|
+
for THREAD in $THREADS; do
|
|
763
|
+
gh api graphql -f query="mutation { resolveReviewThread(input: {threadId: \"$THREAD\"}) { thread { isResolved } } }"
|
|
764
|
+
sleep 1
|
|
765
|
+
done
|
|
766
|
+
```
|
|
767
|
+
|
|
768
|
+
### CI Keeps Failing
|
|
769
|
+
|
|
770
|
+
If CI fails repeatedly:
|
|
771
|
+
1. Read the FULL error log
|
|
772
|
+
2. Check if it's a flaky test (re-run once)
|
|
773
|
+
3. If still failing, investigate more deeply
|
|
774
|
+
4. Consider if the fix is actually correct
|
|
775
|
+
|
|
776
|
+
### Bot Doesn't Review
|
|
777
|
+
|
|
778
|
+
If bot review doesn't appear after 15 minutes:
|
|
779
|
+
1. Check if the bot is configured for this repo
|
|
780
|
+
2. Try requesting review from available bots:
|
|
781
|
+
```bash
|
|
782
|
+
# Try Cursor Bugbot first, then others
|
|
783
|
+
gh pr edit <PR_NUMBER> --add-reviewer cursor
|
|
784
|
+
```
|
|
785
|
+
3. If no bot is available, continue with other checks — but flag to the user that no bot review was obtained
|
|
786
|
+
|
|
787
|
+
### Merge Still Blocked
|
|
788
|
+
|
|
789
|
+
If merge is blocked after all fixes:
|
|
790
|
+
```bash
|
|
791
|
+
# Check what's blocking
|
|
792
|
+
gh pr view <PR_NUMBER> --json mergeStateStatus,reviewDecision,mergeable
|
|
793
|
+
|
|
794
|
+
# Check branch protection rules
|
|
795
|
+
gh api repos/OWNER/REPO/branches/main/protection
|
|
796
|
+
```
|
|
797
|
+
|
|
798
|
+
Report the specific blocker for manual intervention.
|
|
799
|
+
|
|
800
|
+
---
|
|
801
|
+
|
|
802
|
+
## Safety Rules
|
|
803
|
+
|
|
804
|
+
1. **Fetch fresh state EVERY cycle** - Never trust cached data
|
|
805
|
+
2. **Fix merge conflicts FIRST** - Before any other work
|
|
806
|
+
3. **Wait for bot autofix BEFORE fixing comments** - It may already fix the issue for you
|
|
807
|
+
4. **Always pull before push** - Bot autofix pushes concurrently; `git pull --rebase` prevents rejections
|
|
808
|
+
5. **Check if already fixed before fixing** - Read the code at the thread location; if autofix already addressed it, just resolve the thread
|
|
809
|
+
6. **Always resolve threads** - Unresolved threads block merge
|
|
810
|
+
7. **Verify fixes compile** - Run type-check before committing
|
|
811
|
+
8. **Don't skip CI** - Wait for it to pass
|
|
812
|
+
9. **Commit atomically** - One fix per commit when possible
|
|
813
|
+
10. **Push after each batch of fixes** - Let CI and bots re-check
|
|
814
|
+
11. **Cap bot review rounds at 3** - After 3 rounds, resolve Low severity threads without fixing to prevent infinite loops
|
|
815
|
+
12. **Always get a bot review** - If reviews aren't triggered automatically, explicitly request one from available bots
|
|
816
|
+
13. **Keep documentation in sync** - Run the Phase 4.7 docs check every cycle; if a PR changes user-facing behavior, update docs or flag it
|
|
817
|
+
14. **Log everything** - Track what was fixed for the report
|