clud-bug 0.7.0-rc.2 → 0.7.0-rc.21

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 (147) hide show
  1. package/README.md +20 -0
  2. package/data/canonical-v1.json +37 -0
  3. package/dist/cli/configure-github.d.ts +58 -0
  4. package/dist/cli/configure-github.d.ts.map +1 -0
  5. package/dist/cli/configure-github.js +242 -0
  6. package/dist/cli/configure-github.js.map +1 -0
  7. package/dist/cli/hooks.d.ts +51 -0
  8. package/dist/cli/hooks.d.ts.map +1 -0
  9. package/dist/cli/hooks.js +138 -0
  10. package/dist/cli/hooks.js.map +1 -0
  11. package/dist/cli/index.d.ts +1 -0
  12. package/dist/cli/index.d.ts.map +1 -1
  13. package/dist/cli/index.js +1 -0
  14. package/dist/cli/index.js.map +1 -1
  15. package/dist/cli/main.d.ts.map +1 -1
  16. package/dist/cli/main.js +949 -35
  17. package/dist/cli/main.js.map +1 -1
  18. package/dist/cli/post-check-run.d.ts +16 -0
  19. package/dist/cli/post-check-run.d.ts.map +1 -0
  20. package/dist/cli/post-check-run.js +93 -0
  21. package/dist/cli/post-check-run.js.map +1 -0
  22. package/dist/cli/review-prompt.d.ts +43 -0
  23. package/dist/cli/review-prompt.d.ts.map +1 -0
  24. package/dist/cli/review-prompt.js +287 -0
  25. package/dist/cli/review-prompt.js.map +1 -0
  26. package/dist/cli/skills.d.ts +7 -0
  27. package/dist/cli/skills.d.ts.map +1 -1
  28. package/dist/cli/skills.js +42 -2
  29. package/dist/cli/skills.js.map +1 -1
  30. package/dist/cli/update-notifier.d.ts +17 -0
  31. package/dist/cli/update-notifier.d.ts.map +1 -0
  32. package/dist/cli/update-notifier.js +88 -0
  33. package/dist/cli/update-notifier.js.map +1 -0
  34. package/dist/cli/update.d.ts.map +1 -1
  35. package/dist/cli/update.js +60 -11
  36. package/dist/cli/update.js.map +1 -1
  37. package/dist/core/auto-resolve.d.ts +235 -0
  38. package/dist/core/auto-resolve.d.ts.map +1 -0
  39. package/dist/core/auto-resolve.js +293 -0
  40. package/dist/core/auto-resolve.js.map +1 -0
  41. package/dist/core/budget-plan.d.ts +125 -0
  42. package/dist/core/budget-plan.d.ts.map +1 -0
  43. package/dist/core/budget-plan.js +211 -0
  44. package/dist/core/budget-plan.js.map +1 -0
  45. package/dist/core/check-verdict.d.ts +31 -0
  46. package/dist/core/check-verdict.d.ts.map +1 -0
  47. package/dist/core/check-verdict.js +66 -0
  48. package/dist/core/check-verdict.js.map +1 -0
  49. package/dist/core/configure-github.d.ts +179 -0
  50. package/dist/core/configure-github.d.ts.map +1 -0
  51. package/dist/core/configure-github.js +289 -0
  52. package/dist/core/configure-github.js.map +1 -0
  53. package/dist/core/design.d.ts +37 -0
  54. package/dist/core/design.d.ts.map +1 -0
  55. package/dist/core/design.js +47 -0
  56. package/dist/core/design.js.map +1 -0
  57. package/dist/core/diff-findings.d.ts +96 -0
  58. package/dist/core/diff-findings.d.ts.map +1 -0
  59. package/dist/core/diff-findings.js +261 -0
  60. package/dist/core/diff-findings.js.map +1 -0
  61. package/dist/core/formal-review.d.ts +79 -0
  62. package/dist/core/formal-review.d.ts.map +1 -0
  63. package/dist/core/formal-review.js +71 -0
  64. package/dist/core/formal-review.js.map +1 -0
  65. package/dist/core/index.d.ts +15 -2
  66. package/dist/core/index.d.ts.map +1 -1
  67. package/dist/core/index.js +53 -1
  68. package/dist/core/index.js.map +1 -1
  69. package/dist/core/inline-threads.d.ts +160 -0
  70. package/dist/core/inline-threads.d.ts.map +1 -0
  71. package/dist/core/inline-threads.js +369 -0
  72. package/dist/core/inline-threads.js.map +1 -0
  73. package/dist/core/multi-pass-aggregate.d.ts +161 -0
  74. package/dist/core/multi-pass-aggregate.d.ts.map +1 -0
  75. package/dist/core/multi-pass-aggregate.js +457 -0
  76. package/dist/core/multi-pass-aggregate.js.map +1 -0
  77. package/dist/core/plan-review.d.ts +57 -0
  78. package/dist/core/plan-review.d.ts.map +1 -0
  79. package/dist/core/plan-review.js +77 -0
  80. package/dist/core/plan-review.js.map +1 -0
  81. package/dist/core/prompt-builder.d.ts +18 -0
  82. package/dist/core/prompt-builder.d.ts.map +1 -1
  83. package/dist/core/prompt-builder.js +24 -2
  84. package/dist/core/prompt-builder.js.map +1 -1
  85. package/dist/core/render.d.ts.map +1 -1
  86. package/dist/core/render.js +1 -19
  87. package/dist/core/render.js.map +1 -1
  88. package/dist/core/resolve-verifier.d.ts +53 -0
  89. package/dist/core/resolve-verifier.d.ts.map +1 -0
  90. package/dist/core/resolve-verifier.js +204 -0
  91. package/dist/core/resolve-verifier.js.map +1 -0
  92. package/dist/core/review-context.d.ts +39 -0
  93. package/dist/core/review-context.d.ts.map +1 -0
  94. package/dist/core/review-context.js +99 -0
  95. package/dist/core/review-context.js.map +1 -0
  96. package/dist/core/review-plan.d.ts +219 -0
  97. package/dist/core/review-plan.d.ts.map +1 -0
  98. package/dist/core/review-plan.js +274 -0
  99. package/dist/core/review-plan.js.map +1 -0
  100. package/dist/core/review-writeback.d.ts +74 -0
  101. package/dist/core/review-writeback.d.ts.map +1 -1
  102. package/dist/core/review-writeback.js +71 -4
  103. package/dist/core/review-writeback.js.map +1 -1
  104. package/dist/core/skills.d.ts +25 -0
  105. package/dist/core/skills.d.ts.map +1 -1
  106. package/dist/core/skills.js +100 -4
  107. package/dist/core/skills.js.map +1 -1
  108. package/dist/core/version.d.ts +2 -0
  109. package/dist/core/version.d.ts.map +1 -0
  110. package/dist/core/version.js +4 -0
  111. package/dist/core/version.js.map +1 -0
  112. package/package.json +11 -5
  113. package/src/cli/configure-github.ts +329 -0
  114. package/src/cli/hooks.ts +155 -0
  115. package/src/cli/index.ts +6 -0
  116. package/src/cli/main.ts +1031 -37
  117. package/src/cli/post-check-run.ts +115 -0
  118. package/src/cli/review-prompt.ts +355 -0
  119. package/src/cli/skills.ts +42 -2
  120. package/src/cli/update-notifier.ts +100 -0
  121. package/src/cli/update.ts +60 -11
  122. package/src/core/auto-resolve.ts +488 -0
  123. package/src/core/budget-plan.ts +324 -0
  124. package/src/core/check-verdict.ts +93 -0
  125. package/src/core/configure-github.ts +497 -0
  126. package/src/core/design.ts +73 -0
  127. package/src/core/diff-findings.ts +323 -0
  128. package/src/core/formal-review.ts +168 -0
  129. package/src/core/index.ts +188 -0
  130. package/src/core/inline-threads.ts +471 -0
  131. package/src/core/multi-pass-aggregate.ts +591 -0
  132. package/src/core/plan-review.ts +136 -0
  133. package/src/core/prompt-builder.ts +44 -2
  134. package/src/core/render.ts +10 -16
  135. package/src/core/resolve-verifier.ts +254 -0
  136. package/src/core/review-context.ts +106 -0
  137. package/src/core/review-plan.ts +485 -0
  138. package/src/core/review-writeback.ts +161 -4
  139. package/src/core/skills.ts +128 -5
  140. package/src/core/version.ts +3 -0
  141. package/templates/clud-bug-review.md.tmpl +115 -0
  142. package/templates/skills/design/design-system-consistency.md +41 -0
  143. package/templates/skills/design/frontend-a11y.md +41 -0
  144. package/templates/skills/design/visual-polish.md +41 -0
  145. package/templates/workflow-py.yml.tmpl +92 -2
  146. package/templates/workflow-ts.yml.tmpl +92 -2
  147. package/templates/workflow.yml.tmpl +173 -2
@@ -1,4 +1,4 @@
1
- # clud-bug-template-version: v12
1
+ # clud-bug-template-version: v14
2
2
  name: Clud Bug 🐛 Crawls Your Code
3
3
 
4
4
  on:
@@ -213,6 +213,19 @@ jobs:
213
213
  echo "::error::Set it: Settings → Secrets and variables → Actions → New repository secret."
214
214
  exit 1
215
215
 
216
+ # ── Design-critic (optional, opt-in) ─────────────────────────────────
217
+ # clud-bug can also review the *rendered* UI of your PR's preview deploy.
218
+ # The hosted clud-bug[bot] does this for you on Team installs (Browserless).
219
+ # To run it here on the Action reviewer instead — Claude drives a real
220
+ # browser on this runner, no paid render service — enable it in 3 steps:
221
+ # 1. clud-bug init --with-design (installs the design kit + flips the
222
+ # `design` block in .claude/skills/.clud-bug.json to enabled: true)
223
+ # 2. add a browser MCP to claude_args below, e.g.:
224
+ # --mcp-config '{"mcpServers":{"playwright":{"command":"npx","args":["-y","@playwright/mcp@latest"]}}}'
225
+ # 3. append the browser tools to --allowedTools, e.g.:
226
+ # ,mcp__playwright__browser_navigate,mcp__playwright__browser_take_screenshot
227
+ # Off by default. See the §3b design step in `clud-bug review-prompt`.
228
+ # ──────────────────────────────────────────────────────────────────────
216
229
  - uses: anthropics/claude-code-action@{{CCA_VERSION}}
217
230
  if: steps.guard.outputs.skip != 'true'
218
231
  env:
@@ -283,6 +296,40 @@ jobs:
283
296
 
284
297
  $CALIBRATION"
285
298
 
299
+ # Wave 5a (D.2.X) — see workflow.yml.tmpl for design notes.
300
+ - name: Post inline review threads
301
+ if: success() && steps.clud-bug-review.outputs.structured_output != ''
302
+ continue-on-error: true
303
+ env:
304
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
305
+ REPO: ${{ github.repository }}
306
+ PR_NUMBER: ${{ github.event.pull_request.number }}
307
+ HEAD_SHA: ${{ github.event.pull_request.head.sha }}
308
+ STRUCTURED: ${{ steps.clud-bug-review.outputs.structured_output }}
309
+ run: |
310
+ set -euo pipefail
311
+ RESULT=$(printf '%s\n' "$STRUCTURED" | npx --yes clud-bug@{{CLUD_BUG_VERSION}} post-inline-threads --stdin)
312
+ echo "::notice title=inline-threads::$RESULT"
313
+
314
+ # Wave 5b (D.2.6) — see workflow.yml.tmpl for design notes.
315
+ - name: Auto-resolve fixed threads
316
+ if: success() && github.event.action == 'synchronize'
317
+ continue-on-error: true
318
+ env:
319
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
320
+ ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
321
+ REPO: ${{ github.repository }}
322
+ PR_NUMBER: ${{ github.event.pull_request.number }}
323
+ # Optional fine-grained PAT (Pull requests: write). Present → the
324
+ # workflow resolves fixed threads like the hosted App. Absent (the
325
+ # default; an unset secret renders empty) → graceful "verified fixed"
326
+ # reply only, since the Actions GITHUB_TOKEN can't resolve threads.
327
+ CLUD_BUG_RESOLVE_PAT: ${{ secrets.CLUD_BUG_RESOLVE_PAT }}
328
+ run: |
329
+ set -euo pipefail
330
+ RESULT=$(npx --yes clud-bug@{{CLUD_BUG_VERSION}} resolve-threads)
331
+ echo "::notice title=auto-resolve::$RESULT"
332
+
286
333
  # v0.6.29 / Component 4 — see workflow.yml.tmpl for design notes.
287
334
  - name: Update skill-usage tracking
288
335
  if: success() && steps.clud-bug-review.outputs.structured_output != ''
@@ -366,9 +413,52 @@ jobs:
366
413
  # Strict-mode gate — composite action; see workflow.yml.tmpl for design notes.
367
414
  - name: Strict mode — fail check on critical findings
368
415
  if: success()
369
- uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.7.0-rc.2
416
+ uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.7.0-rc.21
370
417
  with:
371
418
  github-token: ${{ secrets.GITHUB_TOKEN }}
372
419
  # v0.6.22 / 0.0.O: summary now posted by github-actions[bot].
373
420
  # See workflow.yml.tmpl for design notes.
374
421
  bot-login: 'github-actions[bot]'
422
+
423
+ # v0.7.0-rc.3 — SPEC §7.2.1 formal-review event poster.
424
+ # See workflow.yml.tmpl for full design rationale; this step
425
+ # bridges the canonical-ruleset `required_approving_review_count: 1`
426
+ # floor on the npm workflow path. Best-effort: never fails the
427
+ # workflow (continue-on-error). Drive-by exploit guard: external
428
+ # contributors NEVER get APPROVE.
429
+ - name: Formal review — APPROVE / REQUEST_CHANGES / COMMENT
430
+ if: always() && steps.clud-bug-review.outputs.structured_output != ''
431
+ continue-on-error: true
432
+ env:
433
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
434
+ PR_NUMBER: ${{ github.event.pull_request.number }}
435
+ REPO: ${{ github.repository }}
436
+ HEAD_SHA: ${{ github.event.pull_request.head.sha }}
437
+ STRUCTURED: ${{ steps.clud-bug-review.outputs.structured_output }}
438
+ PR_AUTHOR_LOGIN: ${{ github.event.pull_request.user.login }}
439
+ PR_AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association }}
440
+ BASE_REF: ${{ github.event.pull_request.base.ref }}
441
+ run: |
442
+ set -uo pipefail
443
+ STRICT_MODE=false
444
+ if git show "origin/${BASE_REF}:.claude/skills/.clud-bug.json" > /tmp/base-manifest.json 2>/dev/null; then
445
+ if jq -e '.strictMode == true' /tmp/base-manifest.json > /dev/null 2>&1; then
446
+ STRICT_MODE=true
447
+ fi
448
+ fi
449
+ export STRICT_MODE
450
+ VERDICT=$(printf '%s\n' "$STRUCTURED" \
451
+ | npx --yes clud-bug@{{CLUD_BUG_VERSION}} select-review-event --stdin \
452
+ | tail -n1)
453
+ VERDICT="${VERDICT:-skip}"
454
+ echo "::notice title=Clud Bug 🐛::Formal review verdict: $VERDICT (strictMode=$STRICT_MODE, author_assoc=$PR_AUTHOR_ASSOCIATION)"
455
+ if [ "$VERDICT" = "skip" ]; then
456
+ exit 0
457
+ fi
458
+ BODY=$(printf 'Automated formal review by clud-bug — see the summary comment for the substantive findings.\n\nVerdict: **%s**\n\n<!-- clud-bug-formal-review: workflow-path v0.7.0-rc.3 -->' "$VERDICT")
459
+ gh api -X POST "/repos/$REPO/pulls/$PR_NUMBER/reviews" \
460
+ -f event="$VERDICT" \
461
+ -f commit_id="$HEAD_SHA" \
462
+ -f body="$BODY" \
463
+ > /dev/null \
464
+ || echo "::warning title=Clud Bug 🐛::Formal review POST failed (likely 422 self-PR or missing perms); degrading to comment-only."
@@ -1,4 +1,4 @@
1
- # clud-bug-template-version: v12
1
+ # clud-bug-template-version: v14
2
2
  name: Clud Bug 🐛 Crawls Your Code
3
3
 
4
4
  on:
@@ -213,6 +213,19 @@ jobs:
213
213
  echo "::error::Set it: Settings → Secrets and variables → Actions → New repository secret."
214
214
  exit 1
215
215
 
216
+ # ── Design-critic (optional, opt-in) ─────────────────────────────────
217
+ # clud-bug can also review the *rendered* UI of your PR's preview deploy.
218
+ # The hosted clud-bug[bot] does this for you on Team installs (Browserless).
219
+ # To run it here on the Action reviewer instead — Claude drives a real
220
+ # browser on this runner, no paid render service — enable it in 3 steps:
221
+ # 1. clud-bug init --with-design (installs the design kit + flips the
222
+ # `design` block in .claude/skills/.clud-bug.json to enabled: true)
223
+ # 2. add a browser MCP to claude_args below, e.g.:
224
+ # --mcp-config '{"mcpServers":{"playwright":{"command":"npx","args":["-y","@playwright/mcp@latest"]}}}'
225
+ # 3. append the browser tools to --allowedTools, e.g.:
226
+ # ,mcp__playwright__browser_navigate,mcp__playwright__browser_take_screenshot
227
+ # Off by default. See the §3b design step in `clud-bug review-prompt`.
228
+ # ──────────────────────────────────────────────────────────────────────
216
229
  - uses: anthropics/claude-code-action@{{CCA_VERSION}}
217
230
  if: steps.guard.outputs.skip != 'true'
218
231
  env:
@@ -283,6 +296,40 @@ jobs:
283
296
 
284
297
  $CALIBRATION"
285
298
 
299
+ # Wave 5a (D.2.X) — see workflow.yml.tmpl for design notes.
300
+ - name: Post inline review threads
301
+ if: success() && steps.clud-bug-review.outputs.structured_output != ''
302
+ continue-on-error: true
303
+ env:
304
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
305
+ REPO: ${{ github.repository }}
306
+ PR_NUMBER: ${{ github.event.pull_request.number }}
307
+ HEAD_SHA: ${{ github.event.pull_request.head.sha }}
308
+ STRUCTURED: ${{ steps.clud-bug-review.outputs.structured_output }}
309
+ run: |
310
+ set -euo pipefail
311
+ RESULT=$(printf '%s\n' "$STRUCTURED" | npx --yes clud-bug@{{CLUD_BUG_VERSION}} post-inline-threads --stdin)
312
+ echo "::notice title=inline-threads::$RESULT"
313
+
314
+ # Wave 5b (D.2.6) — see workflow.yml.tmpl for design notes.
315
+ - name: Auto-resolve fixed threads
316
+ if: success() && github.event.action == 'synchronize'
317
+ continue-on-error: true
318
+ env:
319
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
320
+ ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
321
+ REPO: ${{ github.repository }}
322
+ PR_NUMBER: ${{ github.event.pull_request.number }}
323
+ # Optional fine-grained PAT (Pull requests: write). Present → the
324
+ # workflow resolves fixed threads like the hosted App. Absent (the
325
+ # default; an unset secret renders empty) → graceful "verified fixed"
326
+ # reply only, since the Actions GITHUB_TOKEN can't resolve threads.
327
+ CLUD_BUG_RESOLVE_PAT: ${{ secrets.CLUD_BUG_RESOLVE_PAT }}
328
+ run: |
329
+ set -euo pipefail
330
+ RESULT=$(npx --yes clud-bug@{{CLUD_BUG_VERSION}} resolve-threads)
331
+ echo "::notice title=auto-resolve::$RESULT"
332
+
286
333
  # v0.6.29 / Component 4 — see workflow.yml.tmpl for design notes.
287
334
  - name: Update skill-usage tracking
288
335
  if: success() && steps.clud-bug-review.outputs.structured_output != ''
@@ -366,9 +413,52 @@ jobs:
366
413
  # Strict-mode gate — composite action; see workflow.yml.tmpl for design notes.
367
414
  - name: Strict mode — fail check on critical findings
368
415
  if: success()
369
- uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.7.0-rc.2
416
+ uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.7.0-rc.21
370
417
  with:
371
418
  github-token: ${{ secrets.GITHUB_TOKEN }}
372
419
  # v0.6.22 / 0.0.O: summary now posted by github-actions[bot].
373
420
  # See workflow.yml.tmpl for design notes.
374
421
  bot-login: 'github-actions[bot]'
422
+
423
+ # v0.7.0-rc.3 — SPEC §7.2.1 formal-review event poster.
424
+ # See workflow.yml.tmpl for full design rationale; this step
425
+ # bridges the canonical-ruleset `required_approving_review_count: 1`
426
+ # floor on the npm workflow path. Best-effort: never fails the
427
+ # workflow (continue-on-error). Drive-by exploit guard: external
428
+ # contributors NEVER get APPROVE.
429
+ - name: Formal review — APPROVE / REQUEST_CHANGES / COMMENT
430
+ if: always() && steps.clud-bug-review.outputs.structured_output != ''
431
+ continue-on-error: true
432
+ env:
433
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
434
+ PR_NUMBER: ${{ github.event.pull_request.number }}
435
+ REPO: ${{ github.repository }}
436
+ HEAD_SHA: ${{ github.event.pull_request.head.sha }}
437
+ STRUCTURED: ${{ steps.clud-bug-review.outputs.structured_output }}
438
+ PR_AUTHOR_LOGIN: ${{ github.event.pull_request.user.login }}
439
+ PR_AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association }}
440
+ BASE_REF: ${{ github.event.pull_request.base.ref }}
441
+ run: |
442
+ set -uo pipefail
443
+ STRICT_MODE=false
444
+ if git show "origin/${BASE_REF}:.claude/skills/.clud-bug.json" > /tmp/base-manifest.json 2>/dev/null; then
445
+ if jq -e '.strictMode == true' /tmp/base-manifest.json > /dev/null 2>&1; then
446
+ STRICT_MODE=true
447
+ fi
448
+ fi
449
+ export STRICT_MODE
450
+ VERDICT=$(printf '%s\n' "$STRUCTURED" \
451
+ | npx --yes clud-bug@{{CLUD_BUG_VERSION}} select-review-event --stdin \
452
+ | tail -n1)
453
+ VERDICT="${VERDICT:-skip}"
454
+ echo "::notice title=Clud Bug 🐛::Formal review verdict: $VERDICT (strictMode=$STRICT_MODE, author_assoc=$PR_AUTHOR_ASSOCIATION)"
455
+ if [ "$VERDICT" = "skip" ]; then
456
+ exit 0
457
+ fi
458
+ BODY=$(printf 'Automated formal review by clud-bug — see the summary comment for the substantive findings.\n\nVerdict: **%s**\n\n<!-- clud-bug-formal-review: workflow-path v0.7.0-rc.3 -->' "$VERDICT")
459
+ gh api -X POST "/repos/$REPO/pulls/$PR_NUMBER/reviews" \
460
+ -f event="$VERDICT" \
461
+ -f commit_id="$HEAD_SHA" \
462
+ -f body="$BODY" \
463
+ > /dev/null \
464
+ || echo "::warning title=Clud Bug 🐛::Formal review POST failed (likely 422 self-PR or missing perms); degrading to comment-only."
@@ -1,4 +1,4 @@
1
- # clud-bug-template-version: v13
1
+ # clud-bug-template-version: v14
2
2
  name: Clud Bug 🐛 Crawls Your Code
3
3
 
4
4
  on:
@@ -383,6 +383,19 @@ jobs:
383
383
  echo "::error::Without it, Clud Bug review is a silent no-op."
384
384
  exit 1
385
385
 
386
+ # ── Design-critic (optional, opt-in) ─────────────────────────────────
387
+ # clud-bug can also review the *rendered* UI of your PR's preview deploy.
388
+ # The hosted clud-bug[bot] does this for you on Team installs (Browserless).
389
+ # To run it here on the Action reviewer instead — Claude drives a real
390
+ # browser on this runner, no paid render service — enable it in 3 steps:
391
+ # 1. clud-bug init --with-design (installs the design kit + flips the
392
+ # `design` block in .claude/skills/.clud-bug.json to enabled: true)
393
+ # 2. add a browser MCP to claude_args below, e.g.:
394
+ # --mcp-config '{"mcpServers":{"playwright":{"command":"npx","args":["-y","@playwright/mcp@latest"]}}}'
395
+ # 3. append the browser tools to --allowedTools, e.g.:
396
+ # ,mcp__playwright__browser_navigate,mcp__playwright__browser_take_screenshot
397
+ # Off by default. See the §3b design step in `clud-bug review-prompt`.
398
+ # ──────────────────────────────────────────────────────────────────────
386
399
  - uses: anthropics/claude-code-action@{{CCA_VERSION}}
387
400
  # Skip the action when guard already posted the bot/fork advisory.
388
401
  if: steps.guard.outputs.skip != 'true'
@@ -503,6 +516,69 @@ jobs:
503
516
 
504
517
  $CALIBRATION"
505
518
 
519
+ # v0.7.0-rc.7 / Wave 5a (D.2.X): post per-finding inline review
520
+ # threads alongside the summary comment. Each thread is anchored
521
+ # to a file + line in the diff and is a first-class GitHub review
522
+ # thread users can reply to. Each thread body carries a hidden
523
+ # `<!-- finding-id: <hash> -->` marker so Wave 5b (rc.8) auto-
524
+ # resolve can re-match findings on subsequent fix-pushes without
525
+ # any persistent state.
526
+ #
527
+ # Posted IN ADDITION TO the summary comment above — they serve
528
+ # different UX needs: the summary is the at-a-glance digest; the
529
+ # inline threads are where conversation + resolution happens.
530
+ #
531
+ # `continue-on-error` so a partial GraphQL/REST failure doesn't
532
+ # fail the whole review; the verb itself swallows errors into its
533
+ # stdout JSON and exits 0.
534
+ - name: Post inline review threads
535
+ if: success() && steps.clud-bug-review.outputs.structured_output != ''
536
+ continue-on-error: true
537
+ env:
538
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
539
+ REPO: ${{ github.repository }}
540
+ PR_NUMBER: ${{ github.event.pull_request.number }}
541
+ HEAD_SHA: ${{ github.event.pull_request.head.sha }}
542
+ STRUCTURED: ${{ steps.clud-bug-review.outputs.structured_output }}
543
+ run: |
544
+ set -euo pipefail
545
+ RESULT=$(printf '%s\n' "$STRUCTURED" | npx --yes clud-bug@{{CLUD_BUG_VERSION}} post-inline-threads --stdin)
546
+ echo "::notice title=inline-threads::$RESULT"
547
+
548
+ # v0.7.0-rc.8 / Wave 5b (D.2.6): on fix-push events
549
+ # (pull_request.synchronize), ask the Anthropic Messages API per
550
+ # bot-authored unresolved inline thread whether the new commit
551
+ # addressed the original finding. ADDRESSED → resolve the thread
552
+ # + post a marker reply; UNCERTAIN / NOT_ADDRESSED → leave open.
553
+ # Fail-closed: verifier errors route to UNCERTAIN (never silently
554
+ # dismiss).
555
+ #
556
+ # Gated on `synchronize` because:
557
+ # - `opened` events have no prior threads to resolve.
558
+ # - Re-running on every event would waste verifier $ on unchanged
559
+ # state.
560
+ #
561
+ # The verb re-derives prior-finding context from the
562
+ # `<!-- finding-id: ... -->` markers Wave 5a embeds in each
563
+ # comment body, so no persistent state is needed across pushes.
564
+ - name: Auto-resolve fixed threads
565
+ if: success() && github.event.action == 'synchronize'
566
+ continue-on-error: true
567
+ env:
568
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
569
+ ANTHROPIC_API_KEY: ${{ secrets.ANTHROPIC_API_KEY }}
570
+ REPO: ${{ github.repository }}
571
+ PR_NUMBER: ${{ github.event.pull_request.number }}
572
+ # Optional fine-grained PAT (Pull requests: write). Present → the
573
+ # workflow resolves fixed threads like the hosted App. Absent (the
574
+ # default; an unset secret renders empty) → graceful "verified fixed"
575
+ # reply only, since the Actions GITHUB_TOKEN can't resolve threads.
576
+ CLUD_BUG_RESOLVE_PAT: ${{ secrets.CLUD_BUG_RESOLVE_PAT }}
577
+ run: |
578
+ set -euo pipefail
579
+ RESULT=$(npx --yes clud-bug@{{CLUD_BUG_VERSION}} resolve-threads)
580
+ echo "::notice title=auto-resolve::$RESULT"
581
+
506
582
  # v0.6.29 / Component 4: pipe structured_output through
507
583
  # `clud-bug update-skill-usage` to compute the per-skill loads +
508
584
  # citations delta from this one review. Writes to the ephemeral
@@ -641,7 +717,7 @@ jobs:
641
717
  # Letting the action's own failure fail the check is louder and right.
642
718
  - name: Strict mode — fail check on critical findings
643
719
  if: success()
644
- uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.7.0-rc.2
720
+ uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.7.0-rc.21
645
721
  with:
646
722
  github-token: ${{ secrets.GITHUB_TOKEN }}
647
723
  # v0.6.22 / 0.0.O: the summary is now posted by the workflow
@@ -651,3 +727,98 @@ jobs:
651
727
  # never matches the new summary author → strict mode falls
652
728
  # open advisory for every install that opted in.
653
729
  bot-login: 'github-actions[bot]'
730
+
731
+ # v0.7.0-rc.3 — SPEC §7.2.1 formal-review event poster.
732
+ #
733
+ # Why this step exists: the canonical ruleset (SPEC §7.2) pins
734
+ # `required_approving_review_count: 1`. Before this step, the
735
+ # workflow path posted only a summary issue comment + a
736
+ # `clud-bug-review` check-run — neither of which counts as an
737
+ # approving review. So every PR on the workflow path required a
738
+ # human to click Approve, even when the bot's verdict was clean.
739
+ #
740
+ # This step bridges that gap: it pipes the same structured_output
741
+ # the render step consumed through `clud-bug select-review-event`
742
+ # (SPEC §7.2.1 rule table) and, on org-trusted authors, posts a
743
+ # formal `pulls.createReview` with `event=APPROVE` so the
744
+ # `required_approving_review_count: 1` floor flips automatically.
745
+ #
746
+ # Drive-by exploit guard: external contributors NEVER get APPROVE.
747
+ # The select-review-event verdict for any author in
748
+ # {NONE, FIRST_TIME_CONTRIBUTOR, FIRST_TIMER, MANNEQUIN} is forced
749
+ # to COMMENT — a human reviewer must explicitly Approve. See
750
+ # SPEC §7.2.1 precondition #3.
751
+ #
752
+ # Best-effort contract: this step MUST NEVER fail the workflow.
753
+ # `continue-on-error: true` ensures a malformed payload, network
754
+ # blip, or rate-limit on the formal-review API can't undo the
755
+ # already-posted summary comment. Worst case: no formal review is
756
+ # posted, falling back to today's comment-only behavior (= the
757
+ # pre-rc.3 status quo).
758
+ #
759
+ # Self-PR guard: when the PR author is `clud-bug[bot]` (D.7
760
+ # migration fan-out path that clud-bug-app authors), the verdict
761
+ # is "skip" — GitHub returns 422 on self-review, so we short-
762
+ # circuit before the network call.
763
+ - name: Formal review — APPROVE / REQUEST_CHANGES / COMMENT
764
+ if: always() && steps.clud-bug-review.outputs.structured_output != ''
765
+ continue-on-error: true
766
+ env:
767
+ GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
768
+ PR_NUMBER: ${{ github.event.pull_request.number }}
769
+ REPO: ${{ github.repository }}
770
+ HEAD_SHA: ${{ github.event.pull_request.head.sha }}
771
+ STRUCTURED: ${{ steps.clud-bug-review.outputs.structured_output }}
772
+ # SPEC §7.2.1 fields. The select-review-event command reads
773
+ # these from env (NOT stdin) so the workflow doesn't have to
774
+ # construct a nested JSON shape.
775
+ PR_AUTHOR_LOGIN: ${{ github.event.pull_request.user.login }}
776
+ PR_AUTHOR_ASSOCIATION: ${{ github.event.pull_request.author_association }}
777
+ BASE_REF: ${{ github.event.pull_request.base.ref }}
778
+ run: |
779
+ set -uo pipefail
780
+
781
+ # Resolve strictMode from the BASE ref's manifest — same
782
+ # discipline as strict-mode-gate (a PR can't opt itself out
783
+ # of strict mode by editing its own .clud-bug.json). Best-
784
+ # effort: any error here falls through to STRICT_MODE=false.
785
+ STRICT_MODE=false
786
+ if git show "origin/${BASE_REF}:.claude/skills/.clud-bug.json" > /tmp/base-manifest.json 2>/dev/null; then
787
+ if jq -e '.strictMode == true' /tmp/base-manifest.json > /dev/null 2>&1; then
788
+ STRICT_MODE=true
789
+ fi
790
+ fi
791
+ export STRICT_MODE
792
+
793
+ # Compute the verdict (one of: APPROVE / REQUEST_CHANGES /
794
+ # COMMENT / skip). The command degrades to "skip" on any
795
+ # caller-side error (malformed JSON, missing env), so we never
796
+ # need a fallback in shell.
797
+ VERDICT=$(printf '%s\n' "$STRUCTURED" \
798
+ | npx --yes clud-bug@{{CLUD_BUG_VERSION}} select-review-event --stdin \
799
+ | tail -n1)
800
+ VERDICT="${VERDICT:-skip}"
801
+
802
+ echo "::notice title=Clud Bug 🐛::Formal review verdict: $VERDICT (strictMode=$STRICT_MODE, author_assoc=$PR_AUTHOR_ASSOCIATION)"
803
+
804
+ if [ "$VERDICT" = "skip" ]; then
805
+ # Self-PR or caller-error case. No formal review posted;
806
+ # the summary comment + check-run remain the visible review
807
+ # surface. This is the pre-rc.3 status quo.
808
+ exit 0
809
+ fi
810
+
811
+ # Body is short + machine-pingable: human reviewers see the
812
+ # summary issue comment for the substantive review surface;
813
+ # the formal-review body is a cross-link.
814
+ BODY=$(printf 'Automated formal review by clud-bug — see the summary comment for the substantive findings.\n\nVerdict: **%s**\n\n<!-- clud-bug-formal-review: workflow-path v0.7.0-rc.3 -->' "$VERDICT")
815
+
816
+ # gh api fires `pulls.createReview` with the verdict event.
817
+ # commit_id pins the review to the exact SHA we reviewed so a
818
+ # later push doesn't auto-extend the approval scope.
819
+ gh api -X POST "/repos/$REPO/pulls/$PR_NUMBER/reviews" \
820
+ -f event="$VERDICT" \
821
+ -f commit_id="$HEAD_SHA" \
822
+ -f body="$BODY" \
823
+ > /dev/null \
824
+ || echo "::warning title=Clud Bug 🐛::Formal review POST failed (likely 422 self-PR or missing perms); degrading to comment-only."