clud-bug 0.6.14 → 0.6.15
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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clud-bug",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.15",
|
|
4
4
|
"description": "Skill-driven Claude PR review. Ship a brand-voice skill, get brand reviews. Each finding cites the skill that motivated it. CLI installs the workflow + a baseline kit; add more from skills.sh.",
|
|
5
5
|
"homepage": "https://cludbug.dev",
|
|
6
6
|
"bugs": "https://github.com/thrillmade/clud-bug/issues",
|
|
@@ -6,7 +6,7 @@ on:
|
|
|
6
6
|
types: [opened, synchronize]
|
|
7
7
|
|
|
8
8
|
jobs:
|
|
9
|
-
# Pre-flight (v0.6.14 / 0.0.W) — see workflow.yml.tmpl
|
|
9
|
+
# Pre-flight (v0.6.14 / 0.0.W + v0.6.15 / 0.0.R) — see workflow.yml.tmpl.
|
|
10
10
|
paths-check:
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
permissions:
|
|
@@ -14,6 +14,7 @@ jobs:
|
|
|
14
14
|
pull-requests: read
|
|
15
15
|
outputs:
|
|
16
16
|
is_workflow_only: ${{ steps.classify.outputs.is_workflow_only }}
|
|
17
|
+
model: ${{ steps.classify.outputs.model }}
|
|
17
18
|
steps:
|
|
18
19
|
- name: Classify PR diff
|
|
19
20
|
id: classify
|
|
@@ -21,9 +22,15 @@ jobs:
|
|
|
21
22
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
22
23
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
23
24
|
REPO: ${{ github.repository }}
|
|
25
|
+
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
|
|
24
26
|
run: |
|
|
25
27
|
CHANGED=$(gh pr diff "$PR_NUMBER" -R "$REPO" --name-only)
|
|
26
|
-
|
|
28
|
+
MODEL=claude-sonnet-4-6
|
|
29
|
+
if [ -z "$CHANGED" ]; then
|
|
30
|
+
echo "is_workflow_only=false" >> "$GITHUB_OUTPUT"
|
|
31
|
+
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
32
|
+
exit 0
|
|
33
|
+
fi
|
|
27
34
|
IS_WORKFLOW_ONLY=true
|
|
28
35
|
while IFS= read -r f; do
|
|
29
36
|
case "$f" in
|
|
@@ -35,7 +42,38 @@ jobs:
|
|
|
35
42
|
echo "is_workflow_only=$IS_WORKFLOW_ONLY" >> "$GITHUB_OUTPUT"
|
|
36
43
|
if [ "$IS_WORKFLOW_ONLY" = "true" ]; then
|
|
37
44
|
echo "::notice title=Clud Bug 🐛::Skipping LLM review — workflow-only PR."
|
|
45
|
+
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
46
|
+
exit 0
|
|
47
|
+
fi
|
|
48
|
+
# Triviality (0.0.R): dep-bumping bot OR small dep-manifest diff.
|
|
49
|
+
IS_TRIVIAL=false
|
|
50
|
+
case "$PR_AUTHOR" in
|
|
51
|
+
dependabot\[bot\]|renovate\[bot\]) IS_TRIVIAL=true ;;
|
|
52
|
+
esac
|
|
53
|
+
if [ "$IS_TRIVIAL" = "false" ]; then
|
|
54
|
+
DIFF_SIZE=$(gh pr diff "$PR_NUMBER" -R "$REPO" | wc -c | tr -d ' ')
|
|
55
|
+
if [ "$DIFF_SIZE" -lt 2048 ]; then
|
|
56
|
+
ALL_TRIVIAL=true
|
|
57
|
+
while IFS= read -r f; do
|
|
58
|
+
case "$f" in
|
|
59
|
+
package.json|*/package.json|package-lock.json|*/package-lock.json) ;;
|
|
60
|
+
pnpm-lock.yaml|*/pnpm-lock.yaml|yarn.lock|*/yarn.lock) ;;
|
|
61
|
+
requirements*.txt|*/requirements*.txt) ;;
|
|
62
|
+
pyproject.toml|*/pyproject.toml|poetry.lock|*/poetry.lock|uv.lock|*/uv.lock) ;;
|
|
63
|
+
Gemfile|*/Gemfile|Gemfile.lock|*/Gemfile.lock) ;;
|
|
64
|
+
go.mod|*/go.mod|go.sum|*/go.sum) ;;
|
|
65
|
+
Cargo.toml|*/Cargo.toml|Cargo.lock|*/Cargo.lock) ;;
|
|
66
|
+
*) ALL_TRIVIAL=false; break ;;
|
|
67
|
+
esac
|
|
68
|
+
done <<< "$CHANGED"
|
|
69
|
+
[ "$ALL_TRIVIAL" = "true" ] && IS_TRIVIAL=true
|
|
70
|
+
fi
|
|
71
|
+
fi
|
|
72
|
+
if [ "$IS_TRIVIAL" = "true" ]; then
|
|
73
|
+
MODEL=claude-haiku-4-5-20251001
|
|
74
|
+
echo "::notice title=Clud Bug 🐛::Trivial PR — routing to Haiku."
|
|
38
75
|
fi
|
|
76
|
+
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
39
77
|
|
|
40
78
|
clud-bug-review:
|
|
41
79
|
needs: paths-check
|
|
@@ -106,7 +144,7 @@ jobs:
|
|
|
106
144
|
track_progress: true
|
|
107
145
|
show_full_output: true
|
|
108
146
|
claude_args: |
|
|
109
|
-
--model
|
|
147
|
+
--model ${{ needs.paths-check.outputs.model }}
|
|
110
148
|
--max-turns 15
|
|
111
149
|
--allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh api graphql:*),Bash(gh api repos/:*),Bash(git show:*),Bash(git diff:*),Bash(git merge-base:*),Bash(cat .claude/skills/.clud-bug.json),Bash(cat .claude/skills/*/SKILL.md),Bash(head:*)"
|
|
112
150
|
prompt: |
|
|
@@ -118,6 +156,6 @@ jobs:
|
|
|
118
156
|
# Strict-mode gate — composite action; see workflow.yml.tmpl for design notes.
|
|
119
157
|
- name: Strict mode — fail check on critical findings
|
|
120
158
|
if: success()
|
|
121
|
-
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.
|
|
159
|
+
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.15
|
|
122
160
|
with:
|
|
123
161
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -6,7 +6,7 @@ on:
|
|
|
6
6
|
types: [opened, synchronize]
|
|
7
7
|
|
|
8
8
|
jobs:
|
|
9
|
-
# Pre-flight (v0.6.14 / 0.0.W) — see workflow.yml.tmpl
|
|
9
|
+
# Pre-flight (v0.6.14 / 0.0.W + v0.6.15 / 0.0.R) — see workflow.yml.tmpl.
|
|
10
10
|
paths-check:
|
|
11
11
|
runs-on: ubuntu-latest
|
|
12
12
|
permissions:
|
|
@@ -14,6 +14,7 @@ jobs:
|
|
|
14
14
|
pull-requests: read
|
|
15
15
|
outputs:
|
|
16
16
|
is_workflow_only: ${{ steps.classify.outputs.is_workflow_only }}
|
|
17
|
+
model: ${{ steps.classify.outputs.model }}
|
|
17
18
|
steps:
|
|
18
19
|
- name: Classify PR diff
|
|
19
20
|
id: classify
|
|
@@ -21,9 +22,15 @@ jobs:
|
|
|
21
22
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
22
23
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
23
24
|
REPO: ${{ github.repository }}
|
|
25
|
+
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
|
|
24
26
|
run: |
|
|
25
27
|
CHANGED=$(gh pr diff "$PR_NUMBER" -R "$REPO" --name-only)
|
|
26
|
-
|
|
28
|
+
MODEL=claude-sonnet-4-6
|
|
29
|
+
if [ -z "$CHANGED" ]; then
|
|
30
|
+
echo "is_workflow_only=false" >> "$GITHUB_OUTPUT"
|
|
31
|
+
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
32
|
+
exit 0
|
|
33
|
+
fi
|
|
27
34
|
IS_WORKFLOW_ONLY=true
|
|
28
35
|
while IFS= read -r f; do
|
|
29
36
|
case "$f" in
|
|
@@ -35,7 +42,38 @@ jobs:
|
|
|
35
42
|
echo "is_workflow_only=$IS_WORKFLOW_ONLY" >> "$GITHUB_OUTPUT"
|
|
36
43
|
if [ "$IS_WORKFLOW_ONLY" = "true" ]; then
|
|
37
44
|
echo "::notice title=Clud Bug 🐛::Skipping LLM review — workflow-only PR."
|
|
45
|
+
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
46
|
+
exit 0
|
|
47
|
+
fi
|
|
48
|
+
# Triviality (0.0.R): dep-bumping bot OR small dep-manifest diff.
|
|
49
|
+
IS_TRIVIAL=false
|
|
50
|
+
case "$PR_AUTHOR" in
|
|
51
|
+
dependabot\[bot\]|renovate\[bot\]) IS_TRIVIAL=true ;;
|
|
52
|
+
esac
|
|
53
|
+
if [ "$IS_TRIVIAL" = "false" ]; then
|
|
54
|
+
DIFF_SIZE=$(gh pr diff "$PR_NUMBER" -R "$REPO" | wc -c | tr -d ' ')
|
|
55
|
+
if [ "$DIFF_SIZE" -lt 2048 ]; then
|
|
56
|
+
ALL_TRIVIAL=true
|
|
57
|
+
while IFS= read -r f; do
|
|
58
|
+
case "$f" in
|
|
59
|
+
package.json|*/package.json|package-lock.json|*/package-lock.json) ;;
|
|
60
|
+
pnpm-lock.yaml|*/pnpm-lock.yaml|yarn.lock|*/yarn.lock) ;;
|
|
61
|
+
requirements*.txt|*/requirements*.txt) ;;
|
|
62
|
+
pyproject.toml|*/pyproject.toml|poetry.lock|*/poetry.lock|uv.lock|*/uv.lock) ;;
|
|
63
|
+
Gemfile|*/Gemfile|Gemfile.lock|*/Gemfile.lock) ;;
|
|
64
|
+
go.mod|*/go.mod|go.sum|*/go.sum) ;;
|
|
65
|
+
Cargo.toml|*/Cargo.toml|Cargo.lock|*/Cargo.lock) ;;
|
|
66
|
+
*) ALL_TRIVIAL=false; break ;;
|
|
67
|
+
esac
|
|
68
|
+
done <<< "$CHANGED"
|
|
69
|
+
[ "$ALL_TRIVIAL" = "true" ] && IS_TRIVIAL=true
|
|
70
|
+
fi
|
|
71
|
+
fi
|
|
72
|
+
if [ "$IS_TRIVIAL" = "true" ]; then
|
|
73
|
+
MODEL=claude-haiku-4-5-20251001
|
|
74
|
+
echo "::notice title=Clud Bug 🐛::Trivial PR — routing to Haiku."
|
|
38
75
|
fi
|
|
76
|
+
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
39
77
|
|
|
40
78
|
clud-bug-review:
|
|
41
79
|
needs: paths-check
|
|
@@ -106,7 +144,7 @@ jobs:
|
|
|
106
144
|
track_progress: true
|
|
107
145
|
show_full_output: true
|
|
108
146
|
claude_args: |
|
|
109
|
-
--model
|
|
147
|
+
--model ${{ needs.paths-check.outputs.model }}
|
|
110
148
|
--max-turns 15
|
|
111
149
|
--allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh api graphql:*),Bash(gh api repos/:*),Bash(git show:*),Bash(git diff:*),Bash(git merge-base:*),Bash(cat .claude/skills/.clud-bug.json),Bash(cat .claude/skills/*/SKILL.md),Bash(head:*)"
|
|
112
150
|
prompt: |
|
|
@@ -118,6 +156,6 @@ jobs:
|
|
|
118
156
|
# Strict-mode gate — composite action; see workflow.yml.tmpl for design notes.
|
|
119
157
|
- name: Strict mode — fail check on critical findings
|
|
120
158
|
if: success()
|
|
121
|
-
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.
|
|
159
|
+
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.15
|
|
122
160
|
with:
|
|
123
161
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -6,15 +6,21 @@ on:
|
|
|
6
6
|
types: [opened, synchronize]
|
|
7
7
|
|
|
8
8
|
jobs:
|
|
9
|
-
# Pre-flight
|
|
10
|
-
#
|
|
11
|
-
#
|
|
12
|
-
# (
|
|
13
|
-
#
|
|
14
|
-
#
|
|
15
|
-
#
|
|
16
|
-
#
|
|
17
|
-
#
|
|
9
|
+
# Pre-flight: classify the PR diff to decide (a) whether to skip the
|
|
10
|
+
# LLM review entirely, and (b) which model to route to.
|
|
11
|
+
#
|
|
12
|
+
# (a) Workflow-only PRs (v0.6.14 / 0.0.W): if every changed file
|
|
13
|
+
# matches `.github/workflows/clud-bug-*.yml` or
|
|
14
|
+
# `.github/actions/strict-mode-gate/**`, the LLM call is skipped
|
|
15
|
+
# entirely — claude-code-action would refuse anyway (self-modification
|
|
16
|
+
# guard), and template re-renders have no useful review surface.
|
|
17
|
+
# Skipping converts what were admin-bypass merges into normal ones.
|
|
18
|
+
#
|
|
19
|
+
# (b) Trivial PRs (v0.6.15 / 0.0.R): if the PR author is a dep-bumping
|
|
20
|
+
# bot (dependabot, renovate) OR the diff is small (<2KB) AND only
|
|
21
|
+
# touches dependency-manifest files, route the review to Haiku
|
|
22
|
+
# ($0.80/MTok input vs Sonnet's $3) — another ~75% cost reduction on
|
|
23
|
+
# this PR class. Sonnet remains the default for everything else.
|
|
18
24
|
paths-check:
|
|
19
25
|
runs-on: ubuntu-latest
|
|
20
26
|
permissions:
|
|
@@ -22,6 +28,7 @@ jobs:
|
|
|
22
28
|
pull-requests: read
|
|
23
29
|
outputs:
|
|
24
30
|
is_workflow_only: ${{ steps.classify.outputs.is_workflow_only }}
|
|
31
|
+
model: ${{ steps.classify.outputs.model }}
|
|
25
32
|
steps:
|
|
26
33
|
- name: Classify PR diff
|
|
27
34
|
id: classify
|
|
@@ -29,12 +36,17 @@ jobs:
|
|
|
29
36
|
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
|
30
37
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
31
38
|
REPO: ${{ github.repository }}
|
|
39
|
+
PR_AUTHOR: ${{ github.event.pull_request.user.login }}
|
|
32
40
|
run: |
|
|
33
41
|
CHANGED=$(gh pr diff "$PR_NUMBER" -R "$REPO" --name-only)
|
|
42
|
+
MODEL=claude-sonnet-4-6 # default
|
|
34
43
|
if [ -z "$CHANGED" ]; then
|
|
35
44
|
echo "is_workflow_only=false" >> "$GITHUB_OUTPUT"
|
|
45
|
+
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
36
46
|
exit 0
|
|
37
47
|
fi
|
|
48
|
+
|
|
49
|
+
# --- (a) workflow-only classifier ---
|
|
38
50
|
IS_WORKFLOW_ONLY=true
|
|
39
51
|
while IFS= read -r f; do
|
|
40
52
|
case "$f" in
|
|
@@ -45,8 +57,50 @@ jobs:
|
|
|
45
57
|
done <<< "$CHANGED"
|
|
46
58
|
echo "is_workflow_only=$IS_WORKFLOW_ONLY" >> "$GITHUB_OUTPUT"
|
|
47
59
|
if [ "$IS_WORKFLOW_ONLY" = "true" ]; then
|
|
48
|
-
echo "::notice title=Clud Bug 🐛::Skipping LLM review — PR only touches workflow files
|
|
60
|
+
echo "::notice title=Clud Bug 🐛::Skipping LLM review — PR only touches workflow files."
|
|
61
|
+
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
62
|
+
exit 0
|
|
63
|
+
fi
|
|
64
|
+
|
|
65
|
+
# --- (b) triviality classifier ---
|
|
66
|
+
IS_TRIVIAL=false
|
|
67
|
+
# Bot authors that exclusively open dep-bump PRs go straight
|
|
68
|
+
# to Haiku regardless of diff size — lockfile churn can be huge
|
|
69
|
+
# but the review surface is shallow.
|
|
70
|
+
case "$PR_AUTHOR" in
|
|
71
|
+
dependabot\[bot\]|renovate\[bot\]) IS_TRIVIAL=true ;;
|
|
72
|
+
esac
|
|
73
|
+
# Otherwise: diff < 2KB AND every file matches the dep-manifest
|
|
74
|
+
# allow-list. Manual lockfile fixes / small version pins
|
|
75
|
+
# qualify; real feature work does not.
|
|
76
|
+
if [ "$IS_TRIVIAL" = "false" ]; then
|
|
77
|
+
DIFF_SIZE=$(gh pr diff "$PR_NUMBER" -R "$REPO" | wc -c | tr -d ' ')
|
|
78
|
+
if [ "$DIFF_SIZE" -lt 2048 ]; then
|
|
79
|
+
ALL_TRIVIAL=true
|
|
80
|
+
while IFS= read -r f; do
|
|
81
|
+
case "$f" in
|
|
82
|
+
package.json|*/package.json) ;;
|
|
83
|
+
package-lock.json|*/package-lock.json) ;;
|
|
84
|
+
pnpm-lock.yaml|*/pnpm-lock.yaml) ;;
|
|
85
|
+
yarn.lock|*/yarn.lock) ;;
|
|
86
|
+
requirements*.txt|*/requirements*.txt) ;;
|
|
87
|
+
pyproject.toml|*/pyproject.toml) ;;
|
|
88
|
+
poetry.lock|*/poetry.lock) ;;
|
|
89
|
+
uv.lock|*/uv.lock) ;;
|
|
90
|
+
Gemfile|*/Gemfile|Gemfile.lock|*/Gemfile.lock) ;;
|
|
91
|
+
go.mod|*/go.mod|go.sum|*/go.sum) ;;
|
|
92
|
+
Cargo.toml|*/Cargo.toml|Cargo.lock|*/Cargo.lock) ;;
|
|
93
|
+
*) ALL_TRIVIAL=false; break ;;
|
|
94
|
+
esac
|
|
95
|
+
done <<< "$CHANGED"
|
|
96
|
+
[ "$ALL_TRIVIAL" = "true" ] && IS_TRIVIAL=true
|
|
97
|
+
fi
|
|
98
|
+
fi
|
|
99
|
+
if [ "$IS_TRIVIAL" = "true" ]; then
|
|
100
|
+
MODEL=claude-haiku-4-5-20251001
|
|
101
|
+
echo "::notice title=Clud Bug 🐛::Trivial PR detected (dep bump / bot author) — routing to Haiku for ~75% cost reduction."
|
|
49
102
|
fi
|
|
103
|
+
echo "model=$MODEL" >> "$GITHUB_OUTPUT"
|
|
50
104
|
|
|
51
105
|
clud-bug-review:
|
|
52
106
|
needs: paths-check
|
|
@@ -164,8 +218,12 @@ jobs:
|
|
|
164
218
|
# cache_creation_input_tokens in the run's result JSON so we can
|
|
165
219
|
# measure caching effectiveness post-rollout (per v0.6.3 plan).
|
|
166
220
|
show_full_output: true
|
|
221
|
+
# v0.6.15 / 0.0.R: --model is dynamic. paths-check classifies
|
|
222
|
+
# the PR as trivial (Haiku) or default (Sonnet). Override
|
|
223
|
+
# per-repo by editing the rendered workflow if you want a
|
|
224
|
+
# specific model for a specific repo.
|
|
167
225
|
claude_args: |
|
|
168
|
-
--model
|
|
226
|
+
--model ${{ needs.paths-check.outputs.model }}
|
|
169
227
|
--max-turns 15
|
|
170
228
|
--allowedTools "mcp__github_inline_comment__create_inline_comment,Bash(gh pr comment:*),Bash(gh pr diff:*),Bash(gh pr view:*),Bash(gh api graphql:*),Bash(gh api repos/:*),Bash(git show:*),Bash(git diff:*),Bash(git merge-base:*),Bash(cat .claude/skills/.clud-bug.json),Bash(cat .claude/skills/*/SKILL.md),Bash(head:*)"
|
|
171
229
|
prompt: |
|
|
@@ -189,6 +247,6 @@ jobs:
|
|
|
189
247
|
# Letting the action's own failure fail the check is louder and right.
|
|
190
248
|
- name: Strict mode — fail check on critical findings
|
|
191
249
|
if: success()
|
|
192
|
-
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.
|
|
250
|
+
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.15
|
|
193
251
|
with:
|
|
194
252
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|