@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.
@@ -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