agentsys 5.3.0 → 5.3.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.
Files changed (137) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/.cursor/commands/audit-project-agents.md +454 -0
  4. package/.cursor/commands/audit-project-github.md +141 -0
  5. package/.cursor/commands/audit-project.md +330 -0
  6. package/.cursor/commands/consult.md +417 -0
  7. package/.cursor/commands/debate.md +381 -0
  8. package/.cursor/commands/delivery-approval.md +334 -0
  9. package/.cursor/commands/deslop.md +142 -0
  10. package/.cursor/commands/drift-detect.md +259 -0
  11. package/.cursor/commands/enhance.md +172 -0
  12. package/.cursor/commands/learn.md +165 -0
  13. package/.cursor/commands/next-task.md +519 -0
  14. package/.cursor/commands/perf.md +464 -0
  15. package/.cursor/commands/repo-map.md +124 -0
  16. package/.cursor/commands/ship-ci-review-loop.md +468 -0
  17. package/.cursor/commands/ship-deployment.md +348 -0
  18. package/.cursor/commands/ship-error-handling.md +265 -0
  19. package/.cursor/commands/ship.md +517 -0
  20. package/.cursor/commands/sync-docs.md +171 -0
  21. package/.cursor/commands/web-ctl.md +101 -0
  22. package/.cursor/skills/consult/SKILL.md +425 -0
  23. package/.cursor/skills/debate/SKILL.md +316 -0
  24. package/.cursor/skills/deslop/SKILL.md +204 -0
  25. package/.cursor/skills/discover-tasks/SKILL.md +297 -0
  26. package/.cursor/skills/drift-analysis/SKILL.md +324 -0
  27. package/.cursor/skills/enhance-agent-prompts/SKILL.md +277 -0
  28. package/.cursor/skills/enhance-claude-memory/SKILL.md +387 -0
  29. package/.cursor/skills/enhance-cross-file/SKILL.md +110 -0
  30. package/.cursor/skills/enhance-docs/SKILL.md +298 -0
  31. package/.cursor/skills/enhance-hooks/SKILL.md +554 -0
  32. package/.cursor/skills/enhance-orchestrator/SKILL.md +255 -0
  33. package/.cursor/skills/enhance-plugins/SKILL.md +319 -0
  34. package/.cursor/skills/enhance-prompts/SKILL.md +340 -0
  35. package/.cursor/skills/enhance-skills/SKILL.md +436 -0
  36. package/.cursor/skills/learn/SKILL.md +349 -0
  37. package/.cursor/skills/orchestrate-review/SKILL.md +260 -0
  38. package/.cursor/skills/perf-analyzer/SKILL.md +37 -0
  39. package/.cursor/skills/perf-baseline-manager/SKILL.md +30 -0
  40. package/.cursor/skills/perf-benchmarker/SKILL.md +52 -0
  41. package/.cursor/skills/perf-code-paths/SKILL.md +32 -0
  42. package/.cursor/skills/perf-investigation-logger/SKILL.md +41 -0
  43. package/.cursor/skills/perf-profiler/SKILL.md +42 -0
  44. package/.cursor/skills/perf-theory-gatherer/SKILL.md +35 -0
  45. package/.cursor/skills/perf-theory-tester/SKILL.md +36 -0
  46. package/.cursor/skills/repo-mapping/SKILL.md +83 -0
  47. package/.cursor/skills/sync-docs/SKILL.md +351 -0
  48. package/.cursor/skills/validate-delivery/SKILL.md +186 -0
  49. package/.cursor/skills/web-auth/SKILL.md +177 -0
  50. package/.cursor/skills/web-browse/SKILL.md +516 -0
  51. package/.kiro/agents/agent-enhancer.json +12 -0
  52. package/.kiro/agents/ci-fixer.json +13 -0
  53. package/.kiro/agents/ci-monitor.json +12 -0
  54. package/.kiro/agents/claudemd-enhancer.json +12 -0
  55. package/.kiro/agents/consult-agent.json +13 -0
  56. package/.kiro/agents/cross-file-enhancer.json +12 -0
  57. package/.kiro/agents/debate-orchestrator.json +13 -0
  58. package/.kiro/agents/delivery-validator.json +12 -0
  59. package/.kiro/agents/deslop-agent.json +12 -0
  60. package/.kiro/agents/docs-enhancer.json +12 -0
  61. package/.kiro/agents/exploration-agent.json +12 -0
  62. package/.kiro/agents/hooks-enhancer.json +11 -0
  63. package/.kiro/agents/implementation-agent.json +13 -0
  64. package/.kiro/agents/learn-agent.json +12 -0
  65. package/.kiro/agents/map-validator.json +11 -0
  66. package/.kiro/agents/perf-analyzer.json +12 -0
  67. package/.kiro/agents/perf-code-paths.json +11 -0
  68. package/.kiro/agents/perf-investigation-logger.json +12 -0
  69. package/.kiro/agents/perf-orchestrator.json +13 -0
  70. package/.kiro/agents/perf-theory-gatherer.json +12 -0
  71. package/.kiro/agents/perf-theory-tester.json +13 -0
  72. package/.kiro/agents/plan-synthesizer.json +12 -0
  73. package/.kiro/agents/planning-agent.json +12 -0
  74. package/.kiro/agents/plugin-enhancer.json +12 -0
  75. package/.kiro/agents/prompt-enhancer.json +12 -0
  76. package/.kiro/agents/reviewer-perf-test.json +11 -0
  77. package/.kiro/agents/reviewer-quality-security.json +11 -0
  78. package/.kiro/agents/simple-fixer.json +13 -0
  79. package/.kiro/agents/skills-enhancer.json +11 -0
  80. package/.kiro/agents/sync-docs-agent.json +13 -0
  81. package/.kiro/agents/task-discoverer.json +12 -0
  82. package/.kiro/agents/test-coverage-checker.json +12 -0
  83. package/.kiro/agents/web-session.json +12 -0
  84. package/.kiro/agents/worktree-manager.json +13 -0
  85. package/.kiro/skills/consult/SKILL.md +425 -0
  86. package/.kiro/skills/debate/SKILL.md +316 -0
  87. package/.kiro/skills/deslop/SKILL.md +204 -0
  88. package/.kiro/skills/discover-tasks/SKILL.md +297 -0
  89. package/.kiro/skills/drift-analysis/SKILL.md +324 -0
  90. package/.kiro/skills/enhance-agent-prompts/SKILL.md +277 -0
  91. package/.kiro/skills/enhance-claude-memory/SKILL.md +387 -0
  92. package/.kiro/skills/enhance-cross-file/SKILL.md +110 -0
  93. package/.kiro/skills/enhance-docs/SKILL.md +298 -0
  94. package/.kiro/skills/enhance-hooks/SKILL.md +554 -0
  95. package/.kiro/skills/enhance-orchestrator/SKILL.md +255 -0
  96. package/.kiro/skills/enhance-plugins/SKILL.md +319 -0
  97. package/.kiro/skills/enhance-prompts/SKILL.md +340 -0
  98. package/.kiro/skills/enhance-skills/SKILL.md +436 -0
  99. package/.kiro/skills/learn/SKILL.md +349 -0
  100. package/.kiro/skills/orchestrate-review/SKILL.md +260 -0
  101. package/.kiro/skills/perf-analyzer/SKILL.md +37 -0
  102. package/.kiro/skills/perf-baseline-manager/SKILL.md +30 -0
  103. package/.kiro/skills/perf-benchmarker/SKILL.md +52 -0
  104. package/.kiro/skills/perf-code-paths/SKILL.md +32 -0
  105. package/.kiro/skills/perf-investigation-logger/SKILL.md +41 -0
  106. package/.kiro/skills/perf-profiler/SKILL.md +42 -0
  107. package/.kiro/skills/perf-theory-gatherer/SKILL.md +35 -0
  108. package/.kiro/skills/perf-theory-tester/SKILL.md +36 -0
  109. package/.kiro/skills/repo-mapping/SKILL.md +83 -0
  110. package/.kiro/skills/sync-docs/SKILL.md +351 -0
  111. package/.kiro/skills/validate-delivery/SKILL.md +186 -0
  112. package/.kiro/skills/web-auth/SKILL.md +177 -0
  113. package/.kiro/skills/web-browse/SKILL.md +516 -0
  114. package/.kiro/steering/audit-project-agents.md +459 -0
  115. package/.kiro/steering/audit-project-github.md +146 -0
  116. package/.kiro/steering/audit-project.md +330 -0
  117. package/.kiro/steering/consult.md +422 -0
  118. package/.kiro/steering/debate.md +386 -0
  119. package/.kiro/steering/delivery-approval.md +339 -0
  120. package/.kiro/steering/deslop.md +149 -0
  121. package/.kiro/steering/drift-detect.md +264 -0
  122. package/.kiro/steering/enhance.md +177 -0
  123. package/.kiro/steering/learn.md +166 -0
  124. package/.kiro/steering/next-task.md +481 -0
  125. package/.kiro/steering/perf.md +469 -0
  126. package/.kiro/steering/repo-map.md +126 -0
  127. package/.kiro/steering/ship-ci-review-loop.md +473 -0
  128. package/.kiro/steering/ship-deployment.md +353 -0
  129. package/.kiro/steering/ship-error-handling.md +270 -0
  130. package/.kiro/steering/ship.md +522 -0
  131. package/.kiro/steering/sync-docs.md +178 -0
  132. package/.kiro/steering/web-ctl.md +106 -0
  133. package/CHANGELOG.md +15 -0
  134. package/bin/cli.js +2 -2
  135. package/lib/adapter-transforms.js +34 -2
  136. package/package.json +1 -1
  137. package/site/content.json +1 -1
@@ -0,0 +1,473 @@
1
+ ---
2
+ inclusion: manual
3
+ name: "ship-ci-review-loop"
4
+ description: "Use when monitoring CI and handling review comments during /ship. Details mandatory wait periods, auto-reviewer handling, and comment resolution."
5
+ ---
6
+
7
+ <ci-review-loop>
8
+ # Phase 4: CI & Review Monitor Loop - Reference
9
+
10
+ This file contains detailed implementation for the CI & Review Monitor Loop phase of `/ship`.
11
+
12
+ **Parent document**: `ship.md`
13
+
14
+ ---
15
+
16
+ <mandatory-requirements>
17
+ ## This Phase Is Mandatory
18
+
19
+ This is not optional. You must:
20
+ 1. Wait the full 3 minutes for auto-reviewers
21
+ 2. Run the monitor loop (not just check once)
22
+ 3. Address all comments before merge
23
+ </mandatory-requirements>
24
+
25
+ ---
26
+
27
+ <pr-auto-review>
28
+ ## PR Auto-Review Process
29
+
30
+ PRs receive automatic reviews from configured auto-reviewers (Copilot, Gemini, CodeRabbit, etc.).
31
+
32
+ **Mandatory workflow:**
33
+ 1. After PR creation, wait **at least 3 minutes** for first review round
34
+ 2. Read **all comments** from all reviewers
35
+ 3. Address **every comment** - no exceptions
36
+ 4. Iterate until **zero unresolved threads** (typically 2-4 rounds)
37
+
38
+ **Rules:**
39
+ - Always address all comments, including "minor" or "nit" suggestions
40
+ - Do not skip a comment unless factually wrong or user-approved
41
+ - Treat all feedback as **required changes**, not suggestions
42
+ </pr-auto-review>
43
+
44
+ ---
45
+
46
+ <overview>
47
+ ## Overview
48
+
49
+ The monitor loop must wait for:
50
+ 1. CI to pass
51
+ 2. All comments resolved (addressed or replied to)
52
+ 3. No "changes requested" reviews remain
53
+
54
+ ## Why All Comments Matter
55
+
56
+ **Every comment must be addressed:**
57
+ - Critical/High issues: Fix immediately
58
+ - Medium issues: Fix (don't defer)
59
+ - Minor/Nit issues: Fix (shows attention to quality)
60
+ - Style suggestions: Fix (maintains codebase consistency)
61
+ - Questions: Answer with explanation
62
+ - False positives: Reply explaining why, then resolve
63
+ - Not relevant: Reply explaining why, then resolve
64
+
65
+ Do not ignore comments. Do not leave comments unresolved. A clean PR has zero unresolved conversations.
66
+ </overview>
67
+
68
+ ## The Monitor Loop Algorithm
69
+
70
+ > **Note:** The JavaScript below is **conceptual pseudocode** showing the algorithm flow.
71
+ > Implement using bash functions defined in this file.
72
+
73
+ ```javascript
74
+ const MAX_ITERATIONS = 10; // Safety limit
75
+ const INITIAL_WAIT_MS = 180000; // 3 minutes - wait for auto-reviews
76
+ const ITERATION_WAIT_MS = 30000; // 30 seconds between iterations
77
+ let iteration = 0;
78
+
79
+ while (iteration < MAX_ITERATIONS) {
80
+ iteration++;
81
+ console.log(`\n## CI & Review Monitor - Iteration ${iteration}`);
82
+
83
+ // Step 1: Wait for CI to complete
84
+ const ciStatus = await waitForCI();
85
+ if (ciStatus === 'failed') {
86
+ await fixCIFailures();
87
+ continue; // Push fix, re-run CI
88
+ }
89
+
90
+ // Step 1.5: First iteration only - wait for auto-reviews
91
+ if (iteration === 1) {
92
+ console.log("Waiting 3 minutes for auto-reviews...");
93
+ await sleep(INITIAL_WAIT_MS);
94
+ }
95
+
96
+ // Step 2: Check for PR comments and reviews
97
+ const feedback = await checkPRFeedback();
98
+
99
+ if (feedback.unresolvedCount === 0 && !feedback.changesRequested) {
100
+ console.log("[OK] CI passed, all comments resolved");
101
+ break; // Ready to merge!
102
+ }
103
+
104
+ // Step 3: Address ALL feedback
105
+ await addressAllFeedback(PR_NUMBER);
106
+
107
+ // Step 4: Push fixes
108
+ if (feedback.hasCodeChanges) {
109
+ await commitAndPush(`fix: address review feedback (iteration ${iteration})`);
110
+ }
111
+
112
+ // Step 5: Sleep before next check
113
+ await sleep(ITERATION_WAIT_MS);
114
+ }
115
+ ```
116
+
117
+ ## Step 1: Wait for CI
118
+
119
+ ```bash
120
+ wait_for_ci() {
121
+ echo "Waiting for CI checks..."
122
+
123
+ while true; do
124
+ CHECKS=$(gh pr checks $PR_NUMBER --json name,state 2>/dev/null || echo "[]")
125
+
126
+ PENDING=$(echo "$CHECKS" | jq '[.[] | select(.state | IN("PENDING", "QUEUED", "IN_PROGRESS"))] | length')
127
+ FAILED=$(echo "$CHECKS" | jq '[.[] | select(.state | IN("FAILURE", "CANCELLED"))] | length')
128
+ PASSED=$(echo "$CHECKS" | jq '[.[] | select(.state=="SUCCESS")] | length')
129
+
130
+ if [ "$FAILED" -gt 0 ]; then
131
+ echo "[ERROR] CI failed ($FAILED checks)"
132
+ gh pr checks $PR_NUMBER
133
+ return 1
134
+ elif [ "$PENDING" -eq 0 ] && [ "$PASSED" -gt 0 ]; then
135
+ echo "[OK] CI passed ($PASSED checks)"
136
+ return 0
137
+ elif [ "$PENDING" -eq 0 ] && [ "$PASSED" -eq 0 ]; then
138
+ echo "[WARN] No CI checks found, proceeding..."
139
+ return 0
140
+ fi
141
+
142
+ echo " Waiting... ($PENDING pending, $PASSED passed)"
143
+ sleep 15
144
+ done
145
+ }
146
+ ```
147
+
148
+ ## Step 2: Check PR Feedback
149
+
150
+ ```bash
151
+ check_pr_feedback() {
152
+ local pr_number=$1
153
+
154
+ echo "Checking PR feedback..."
155
+
156
+ # Extract owner and repo from git remote
157
+ REPO_INFO=$(gh repo view --json owner,name --jq '"\(.owner.login)/\(.name)"')
158
+ OWNER=$(echo "$REPO_INFO" | cut -d'/' -f1)
159
+ REPO=$(echo "$REPO_INFO" | cut -d'/' -f2)
160
+
161
+ # Get review state
162
+ REVIEWS=$(gh pr view $pr_number --json reviews --jq '.reviews')
163
+ CHANGES_REQUESTED=$(echo "$REVIEWS" | jq '[.[] | select(.state=="CHANGES_REQUESTED")] | length')
164
+
165
+ # Get unresolved review threads
166
+ # NOTE: Fetches first 100 threads. For PRs with >100 threads, implement pagination.
167
+ UNRESOLVED_THREADS=$(gh api graphql -f query='
168
+ query($owner: String!, $repo: String!, $pr: Int!) {
169
+ repository(owner: $owner, name: $repo) {
170
+ pullRequest(number: $pr) {
171
+ reviewThreads(first: 100) {
172
+ nodes {
173
+ isResolved
174
+ }
175
+ }
176
+ }
177
+ }
178
+ }
179
+ ' -f owner="$OWNER" -f repo="$REPO" -F pr=$pr_number \
180
+ --jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)] | length')
181
+
182
+ echo " Unresolved threads: $UNRESOLVED_THREADS"
183
+ echo " Changes requested: $CHANGES_REQUESTED"
184
+
185
+ echo "{\"unresolvedThreads\": $UNRESOLVED_THREADS, \"changesRequested\": $CHANGES_REQUESTED}"
186
+ }
187
+ ```
188
+
189
+ ### Get Full Thread Details
190
+
191
+ ```bash
192
+ get_unresolved_threads() {
193
+ local pr_number=$1
194
+
195
+ REPO_INFO=$(gh repo view --json owner,name --jq '"\(.owner.login)/\(.name)"')
196
+ OWNER=$(echo "$REPO_INFO" | cut -d'/' -f1)
197
+ REPO=$(echo "$REPO_INFO" | cut -d'/' -f2)
198
+
199
+ # NOTE: Fetches first 100 threads. For PRs with >100, implement pagination.
200
+ gh api graphql -f query='
201
+ query($owner: String!, $repo: String!, $pr: Int!) {
202
+ repository(owner: $owner, name: $repo) {
203
+ pullRequest(number: $pr) {
204
+ reviewThreads(first: 100) {
205
+ nodes {
206
+ id
207
+ isResolved
208
+ path
209
+ line
210
+ diffHunk
211
+ comments(first: 1) {
212
+ nodes {
213
+ id
214
+ body
215
+ }
216
+ }
217
+ }
218
+ }
219
+ }
220
+ }
221
+ }
222
+ ' -f owner="$OWNER" -f repo="$REPO" -F pr=$pr_number \
223
+ --jq '.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false)'
224
+ }
225
+ ```
226
+
227
+ ## Step 3: Address ALL Feedback
228
+
229
+ > **Note:** This is **conceptual pseudocode** showing the algorithm flow.
230
+ > Implement using: gh api, Read, Edit, Task (ci-fixer), etc.
231
+
232
+ ```javascript
233
+ async function addressAllFeedback(prNumber) {
234
+ const threads = await getUnresolvedThreads(prNumber);
235
+
236
+ console.log(`\nAddressing ${threads.length} unresolved threads...`);
237
+
238
+ for (const thread of threads) {
239
+ console.log(`\n--- Thread: ${thread.path}:${thread.line} ---`);
240
+ const analysis = analyzeComment(thread);
241
+
242
+ switch (analysis.type) {
243
+ case 'code_fix_required':
244
+ console.log(`Action: Fixing code issue`);
245
+ await implementFix(thread); // Use Task(ci-fixer) or Edit tool
246
+ break;
247
+
248
+ case 'style_suggestion':
249
+ console.log(`Action: Applying style fix`);
250
+ await implementFix(thread);
251
+ break;
252
+
253
+ case 'question':
254
+ console.log(`Action: Answering question`);
255
+ await replyToComment(prNumber, thread.commentId, generateAnswer(thread));
256
+ await resolveThread(thread.id);
257
+ break;
258
+
259
+ case 'false_positive':
260
+ console.log(`Action: Explaining false positive`);
261
+ await replyToComment(prNumber, thread.commentId,
262
+ `This is a false positive because: ${analysis.reason}\n\n` +
263
+ `Resolving. Please reopen if you disagree.`
264
+ );
265
+ await resolveThread(thread.id);
266
+ break;
267
+
268
+ case 'not_relevant':
269
+ console.log(`Action: Explaining out of scope`);
270
+ await replyToComment(prNumber, thread.commentId,
271
+ `Outside scope of this PR: ${analysis.reason}\n\n` +
272
+ `Resolving. Please reopen if needed.`
273
+ );
274
+ await resolveThread(thread.id);
275
+ break;
276
+
277
+ case 'already_addressed':
278
+ console.log(`Action: Confirming addressed`);
279
+ await replyToComment(prNumber, thread.commentId,
280
+ `Addressed in commit ${gitRevParseHead}.`
281
+ );
282
+ await resolveThread(thread.id);
283
+ break;
284
+ }
285
+ }
286
+
287
+ // Request re-review from those who requested changes
288
+ const changesRequestedReviews = await getChangesRequestedReviews(prNumber);
289
+ for (const review of changesRequestedReviews) {
290
+ await requestReReview(prNumber, review.author);
291
+ }
292
+ }
293
+ ```
294
+
295
+ ## Comment Analysis Heuristics
296
+
297
+ > **Note:** Classification heuristics for comment handling.
298
+
299
+ ```javascript
300
+ function analyzeComment(thread) {
301
+ const body = thread.body.toLowerCase();
302
+
303
+ // Question patterns
304
+ if (body.includes('?') || body.startsWith('why') || body.startsWith('how') ||
305
+ body.startsWith('what') || body.startsWith('could you explain')) {
306
+ return { type: 'question', reason: 'Comment is a question' };
307
+ }
308
+
309
+ // Style/nit patterns
310
+ if (body.includes('nit:') || body.includes('nitpick') || body.includes('minor:') ||
311
+ body.includes('style:') || body.includes('consider') || body.includes('optional')) {
312
+ return { type: 'style_suggestion', reason: 'Style or minor suggestion' };
313
+ }
314
+
315
+ // Out of scope patterns
316
+ if (!thread.diffHunk || commentRefersToUnchangedCode(thread)) {
317
+ return { type: 'not_relevant', reason: 'Comment refers to unchanged code' };
318
+ }
319
+
320
+ // Default: treat as code fix required
321
+ return { type: 'code_fix_required', reason: 'Valid code feedback' };
322
+ }
323
+ ```
324
+
325
+ ## Implementing Fixes
326
+
327
+ Use the ci-fixer agent for code changes:
328
+
329
+ ```javascript
330
+ Task({
331
+ subagent_type: "ci-fixer",
332
+ prompt: `Fix the following review comment:
333
+
334
+ **File**: ${thread.path}
335
+ **Line**: ${thread.line}
336
+ **Comment**: ${thread.body}
337
+ **Code Context**:
338
+ \`\`\`
339
+ ${thread.diffHunk}
340
+ \`\`\`
341
+
342
+ Requirements:
343
+ 1. Make the minimal change to address the feedback
344
+ 2. Do NOT over-engineer or add unrelated changes
345
+ 3. Ensure tests still pass after the fix`
346
+ });
347
+ ```
348
+
349
+ ## Resolving Threads
350
+
351
+ ```bash
352
+ resolve_thread() {
353
+ local thread_id=$1
354
+
355
+ gh api graphql -f query='
356
+ mutation($threadId: ID!) {
357
+ resolveReviewThread(input: {threadId: $threadId}) {
358
+ thread {
359
+ isResolved
360
+ }
361
+ }
362
+ }
363
+ ' -f threadId="$thread_id"
364
+ }
365
+
366
+ reply_to_comment() {
367
+ local pr_number=$1
368
+ local comment_id=$2
369
+ local body=$3
370
+
371
+ REPO_INFO=$(gh repo view --json owner,name --jq '"\(.owner.login)/\(.name)"')
372
+ OWNER=$(echo "$REPO_INFO" | cut -d'/' -f1)
373
+ REPO=$(echo "$REPO_INFO" | cut -d'/' -f2)
374
+
375
+ gh api -X POST "repos/$OWNER/$REPO/pulls/$pr_number/comments" \
376
+ -f body="$body" \
377
+ -F in_reply_to="$comment_id"
378
+ }
379
+ ```
380
+
381
+ ## Step 4: Commit and Push
382
+
383
+ ```bash
384
+ commit_and_push_fixes() {
385
+ local message=$1
386
+ local branch=${2:-$(git branch --show-current)}
387
+
388
+ if [ -n "$(git status --porcelain)" ]; then
389
+ git add -A
390
+ git commit -m "$message"
391
+ git push origin "$branch"
392
+ echo "[OK] Pushed fixes"
393
+ return 0
394
+ else
395
+ echo "No code changes to commit (only comment replies)"
396
+ return 1
397
+ fi
398
+ }
399
+ ```
400
+
401
+ ## Complete Loop Script
402
+
403
+ ```bash
404
+ #!/bin/bash
405
+ # Phase 4: CI & Review Monitor Loop
406
+
407
+ MAX_ITERATIONS=10
408
+ INITIAL_WAIT=${SHIP_INITIAL_WAIT:-180} # Configurable via env var
409
+ ITERATION_WAIT=30
410
+ iteration=0
411
+
412
+ while [ $iteration -lt $MAX_ITERATIONS ]; do
413
+ iteration=$((iteration + 1))
414
+ echo "[CI Monitor] Iteration $iteration"
415
+
416
+ # Step 1: Wait for CI
417
+ if ! wait_for_ci; then
418
+ echo "CI failed - launching ci-fixer agent..."
419
+ continue
420
+ fi
421
+
422
+ # Step 1.5: First iteration - wait for auto-reviews
423
+ if [ $iteration -eq 1 ] && [ "$INITIAL_WAIT" -gt 0 ]; then
424
+ echo "First iteration - waiting ${INITIAL_WAIT}s for auto-reviews..."
425
+ sleep $INITIAL_WAIT
426
+ fi
427
+
428
+ # Step 2: Check feedback
429
+ FEEDBACK=$(check_pr_feedback $PR_NUMBER)
430
+ UNRESOLVED=$(echo "$FEEDBACK" | jq -r '.unresolvedThreads')
431
+ CHANGES_REQ=$(echo "$FEEDBACK" | jq -r '.changesRequested')
432
+
433
+ if [ "$UNRESOLVED" -eq 0 ] && [ "$CHANGES_REQ" -eq 0 ]; then
434
+ echo "[OK] ALL CHECKS PASSED"
435
+ echo "[OK] ALL COMMENTS RESOLVED"
436
+ echo "Ready to merge!"
437
+ break
438
+ fi
439
+
440
+ # Step 3: Address all feedback
441
+ echo "Addressing $UNRESOLVED unresolved threads..."
442
+
443
+ # Step 4: Commit and push
444
+ commit_and_push_fixes "fix: address review feedback (iteration $iteration)"
445
+
446
+ # Step 5: Wait before next iteration
447
+ echo "Waiting ${ITERATION_WAIT}s..."
448
+ sleep $ITERATION_WAIT
449
+ done
450
+
451
+ if [ $iteration -ge $MAX_ITERATIONS ]; then
452
+ echo "[ERROR] Max iterations reached - manual intervention required"
453
+ exit 1
454
+ fi
455
+ ```
456
+
457
+ <iteration-summary>
458
+ ## Iteration Summary Output
459
+
460
+ ```markdown
461
+ ## Iteration ${iteration} Summary
462
+
463
+ **CI Status**: [OK] Passed
464
+ **Comments Addressed**: ${addressedCount}
465
+ - Code fixes: ${codeFixCount}
466
+ - Answered questions: ${questionCount}
467
+ - Resolved as not applicable: ${notApplicableCount}
468
+ **Remaining Unresolved**: ${remainingCount}
469
+
470
+ ${remainingCount > 0 ? 'Continuing...' : 'Ready to merge!'}
471
+ ```
472
+ </iteration-summary>
473
+ </ci-review-loop>