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.
- package/README.md +20 -0
- package/data/canonical-v1.json +37 -0
- package/dist/cli/configure-github.d.ts +58 -0
- package/dist/cli/configure-github.d.ts.map +1 -0
- package/dist/cli/configure-github.js +242 -0
- package/dist/cli/configure-github.js.map +1 -0
- package/dist/cli/hooks.d.ts +51 -0
- package/dist/cli/hooks.d.ts.map +1 -0
- package/dist/cli/hooks.js +138 -0
- package/dist/cli/hooks.js.map +1 -0
- package/dist/cli/index.d.ts +1 -0
- package/dist/cli/index.d.ts.map +1 -1
- package/dist/cli/index.js +1 -0
- package/dist/cli/index.js.map +1 -1
- package/dist/cli/main.d.ts.map +1 -1
- package/dist/cli/main.js +949 -35
- package/dist/cli/main.js.map +1 -1
- package/dist/cli/post-check-run.d.ts +16 -0
- package/dist/cli/post-check-run.d.ts.map +1 -0
- package/dist/cli/post-check-run.js +93 -0
- package/dist/cli/post-check-run.js.map +1 -0
- package/dist/cli/review-prompt.d.ts +43 -0
- package/dist/cli/review-prompt.d.ts.map +1 -0
- package/dist/cli/review-prompt.js +287 -0
- package/dist/cli/review-prompt.js.map +1 -0
- package/dist/cli/skills.d.ts +7 -0
- package/dist/cli/skills.d.ts.map +1 -1
- package/dist/cli/skills.js +42 -2
- package/dist/cli/skills.js.map +1 -1
- package/dist/cli/update-notifier.d.ts +17 -0
- package/dist/cli/update-notifier.d.ts.map +1 -0
- package/dist/cli/update-notifier.js +88 -0
- package/dist/cli/update-notifier.js.map +1 -0
- package/dist/cli/update.d.ts.map +1 -1
- package/dist/cli/update.js +60 -11
- package/dist/cli/update.js.map +1 -1
- package/dist/core/auto-resolve.d.ts +235 -0
- package/dist/core/auto-resolve.d.ts.map +1 -0
- package/dist/core/auto-resolve.js +293 -0
- package/dist/core/auto-resolve.js.map +1 -0
- package/dist/core/budget-plan.d.ts +125 -0
- package/dist/core/budget-plan.d.ts.map +1 -0
- package/dist/core/budget-plan.js +211 -0
- package/dist/core/budget-plan.js.map +1 -0
- package/dist/core/check-verdict.d.ts +31 -0
- package/dist/core/check-verdict.d.ts.map +1 -0
- package/dist/core/check-verdict.js +66 -0
- package/dist/core/check-verdict.js.map +1 -0
- package/dist/core/configure-github.d.ts +179 -0
- package/dist/core/configure-github.d.ts.map +1 -0
- package/dist/core/configure-github.js +289 -0
- package/dist/core/configure-github.js.map +1 -0
- package/dist/core/design.d.ts +37 -0
- package/dist/core/design.d.ts.map +1 -0
- package/dist/core/design.js +47 -0
- package/dist/core/design.js.map +1 -0
- package/dist/core/diff-findings.d.ts +96 -0
- package/dist/core/diff-findings.d.ts.map +1 -0
- package/dist/core/diff-findings.js +261 -0
- package/dist/core/diff-findings.js.map +1 -0
- package/dist/core/formal-review.d.ts +79 -0
- package/dist/core/formal-review.d.ts.map +1 -0
- package/dist/core/formal-review.js +71 -0
- package/dist/core/formal-review.js.map +1 -0
- package/dist/core/index.d.ts +15 -2
- package/dist/core/index.d.ts.map +1 -1
- package/dist/core/index.js +53 -1
- package/dist/core/index.js.map +1 -1
- package/dist/core/inline-threads.d.ts +160 -0
- package/dist/core/inline-threads.d.ts.map +1 -0
- package/dist/core/inline-threads.js +369 -0
- package/dist/core/inline-threads.js.map +1 -0
- package/dist/core/multi-pass-aggregate.d.ts +161 -0
- package/dist/core/multi-pass-aggregate.d.ts.map +1 -0
- package/dist/core/multi-pass-aggregate.js +457 -0
- package/dist/core/multi-pass-aggregate.js.map +1 -0
- package/dist/core/plan-review.d.ts +57 -0
- package/dist/core/plan-review.d.ts.map +1 -0
- package/dist/core/plan-review.js +77 -0
- package/dist/core/plan-review.js.map +1 -0
- package/dist/core/prompt-builder.d.ts +18 -0
- package/dist/core/prompt-builder.d.ts.map +1 -1
- package/dist/core/prompt-builder.js +24 -2
- package/dist/core/prompt-builder.js.map +1 -1
- package/dist/core/render.d.ts.map +1 -1
- package/dist/core/render.js +1 -19
- package/dist/core/render.js.map +1 -1
- package/dist/core/resolve-verifier.d.ts +53 -0
- package/dist/core/resolve-verifier.d.ts.map +1 -0
- package/dist/core/resolve-verifier.js +204 -0
- package/dist/core/resolve-verifier.js.map +1 -0
- package/dist/core/review-context.d.ts +39 -0
- package/dist/core/review-context.d.ts.map +1 -0
- package/dist/core/review-context.js +99 -0
- package/dist/core/review-context.js.map +1 -0
- package/dist/core/review-plan.d.ts +219 -0
- package/dist/core/review-plan.d.ts.map +1 -0
- package/dist/core/review-plan.js +274 -0
- package/dist/core/review-plan.js.map +1 -0
- package/dist/core/review-writeback.d.ts +74 -0
- package/dist/core/review-writeback.d.ts.map +1 -1
- package/dist/core/review-writeback.js +71 -4
- package/dist/core/review-writeback.js.map +1 -1
- package/dist/core/skills.d.ts +25 -0
- package/dist/core/skills.d.ts.map +1 -1
- package/dist/core/skills.js +100 -4
- package/dist/core/skills.js.map +1 -1
- package/dist/core/version.d.ts +2 -0
- package/dist/core/version.d.ts.map +1 -0
- package/dist/core/version.js +4 -0
- package/dist/core/version.js.map +1 -0
- package/package.json +11 -5
- package/src/cli/configure-github.ts +329 -0
- package/src/cli/hooks.ts +155 -0
- package/src/cli/index.ts +6 -0
- package/src/cli/main.ts +1031 -37
- package/src/cli/post-check-run.ts +115 -0
- package/src/cli/review-prompt.ts +355 -0
- package/src/cli/skills.ts +42 -2
- package/src/cli/update-notifier.ts +100 -0
- package/src/cli/update.ts +60 -11
- package/src/core/auto-resolve.ts +488 -0
- package/src/core/budget-plan.ts +324 -0
- package/src/core/check-verdict.ts +93 -0
- package/src/core/configure-github.ts +497 -0
- package/src/core/design.ts +73 -0
- package/src/core/diff-findings.ts +323 -0
- package/src/core/formal-review.ts +168 -0
- package/src/core/index.ts +188 -0
- package/src/core/inline-threads.ts +471 -0
- package/src/core/multi-pass-aggregate.ts +591 -0
- package/src/core/plan-review.ts +136 -0
- package/src/core/prompt-builder.ts +44 -2
- package/src/core/render.ts +10 -16
- package/src/core/resolve-verifier.ts +254 -0
- package/src/core/review-context.ts +106 -0
- package/src/core/review-plan.ts +485 -0
- package/src/core/review-writeback.ts +161 -4
- package/src/core/skills.ts +128 -5
- package/src/core/version.ts +3 -0
- package/templates/clud-bug-review.md.tmpl +115 -0
- package/templates/skills/design/design-system-consistency.md +41 -0
- package/templates/skills/design/frontend-a11y.md +41 -0
- package/templates/skills/design/visual-polish.md +41 -0
- package/templates/workflow-py.yml.tmpl +92 -2
- package/templates/workflow-ts.yml.tmpl +92 -2
- package/templates/workflow.yml.tmpl +173 -2
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
# clud-bug-template-version:
|
|
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.
|
|
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:
|
|
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.
|
|
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:
|
|
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.
|
|
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."
|