clud-bug 0.6.22 → 0.6.24

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.22",
3
+ "version": "0.6.24",
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",
@@ -15,6 +15,7 @@ jobs:
15
15
  outputs:
16
16
  is_workflow_only: ${{ steps.classify.outputs.is_workflow_only }}
17
17
  model: ${{ steps.classify.outputs.model }}
18
+ max_turns: ${{ steps.classify.outputs.max_turns }}
18
19
  steps:
19
20
  - name: Classify PR diff
20
21
  id: classify
@@ -27,8 +28,13 @@ jobs:
27
28
  CHANGED=$(gh pr diff "$PR_NUMBER" -R "$REPO" --name-only)
28
29
  MODEL=claude-sonnet-4-6
29
30
  if [ -z "$CHANGED" ]; then
30
- echo "is_workflow_only=false" >> "$GITHUB_OUTPUT"
31
- echo "model=$MODEL" >> "$GITHUB_OUTPUT"
31
+ # v0.6.23 / §5: max_turns must always be emitted — see workflow.yml.tmpl for design notes.
32
+ # Grouped redirect (v0.6.24) silences the SC2129 style warning.
33
+ {
34
+ echo "is_workflow_only=false"
35
+ echo "model=$MODEL"
36
+ echo "max_turns=15"
37
+ } >> "$GITHUB_OUTPUT"
32
38
  exit 0
33
39
  fi
34
40
  IS_WORKFLOW_ONLY=true
@@ -75,6 +81,23 @@ jobs:
75
81
  fi
76
82
  echo "model=$MODEL" >> "$GITHUB_OUTPUT"
77
83
 
84
+ # Adaptive max-turns (v0.6.23 / §5) — see workflow.yml.tmpl for design notes.
85
+ MAX_TURNS=15
86
+ if [ "$IS_TRIVIAL" = "true" ]; then
87
+ MAX_TURNS=10
88
+ else
89
+ FILE_COUNT=$(echo "$CHANGED" | wc -l | tr -d ' ')
90
+ THREAD_COUNT=$(gh api graphql -f query='{repository(owner:"'"$(echo "$REPO" | cut -d/ -f1)"'",name:"'"$(echo "$REPO" | cut -d/ -f2)"'"){pullRequest(number:'"$PR_NUMBER"'){reviewThreads(first:50){nodes{isResolved comments(first:1){nodes{author{login}}}}}}}}' --jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false and (.comments.nodes[0].author.login == "claude" or .comments.nodes[0].author.login == "claude[bot]"))] | length' 2>/dev/null || echo 0)
91
+ THREAD_COUNT=${THREAD_COUNT:-0}
92
+ if [ "$FILE_COUNT" -ge 30 ] || [ "$THREAD_COUNT" -ge 6 ]; then
93
+ MAX_TURNS=40
94
+ elif [ "$FILE_COUNT" -ge 10 ] || [ "$THREAD_COUNT" -ge 3 ]; then
95
+ MAX_TURNS=25
96
+ fi
97
+ echo "::notice title=Clud Bug 🐛::Turn budget: $MAX_TURNS ($FILE_COUNT files, $THREAD_COUNT prior threads)."
98
+ fi
99
+ echo "max_turns=$MAX_TURNS" >> "$GITHUB_OUTPUT"
100
+
78
101
  clud-bug-review:
79
102
  needs: paths-check
80
103
  if: needs.paths-check.outputs.is_workflow_only != 'true'
@@ -85,6 +108,9 @@ jobs:
85
108
  id-token: write
86
109
  # checks: write — composite emits per-skill check-runs (BB.3).
87
110
  checks: write
111
+ # v0.6.24: `actions: read` (added in v0.6.23) backed out — broke
112
+ # `pull_request` trigger firing on private consumer repos. See
113
+ # workflow.yml.tmpl for the diagnosis.
88
114
 
89
115
  steps:
90
116
  - uses: actions/checkout@v6
@@ -147,7 +173,7 @@ jobs:
147
173
  # structured output; post-step renders + posts. See workflow.yml.tmpl for design notes.
148
174
  claude_args: |
149
175
  --model ${{ needs.paths-check.outputs.model }}
150
- --max-turns 15
176
+ --max-turns ${{ needs.paths-check.outputs.max_turns }}
151
177
  --allowedTools "mcp__github_inline_comment__create_inline_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:*)"
152
178
  --json-schema '{{REVIEW_SCHEMA}}'
153
179
  prompt: |
@@ -190,7 +216,7 @@ jobs:
190
216
  # Strict-mode gate — composite action; see workflow.yml.tmpl for design notes.
191
217
  - name: Strict mode — fail check on critical findings
192
218
  if: success()
193
- uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.22
219
+ uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.24
194
220
  with:
195
221
  github-token: ${{ secrets.GITHUB_TOKEN }}
196
222
  # v0.6.22 / 0.0.O: summary now posted by github-actions[bot].
@@ -15,6 +15,7 @@ jobs:
15
15
  outputs:
16
16
  is_workflow_only: ${{ steps.classify.outputs.is_workflow_only }}
17
17
  model: ${{ steps.classify.outputs.model }}
18
+ max_turns: ${{ steps.classify.outputs.max_turns }}
18
19
  steps:
19
20
  - name: Classify PR diff
20
21
  id: classify
@@ -27,8 +28,13 @@ jobs:
27
28
  CHANGED=$(gh pr diff "$PR_NUMBER" -R "$REPO" --name-only)
28
29
  MODEL=claude-sonnet-4-6
29
30
  if [ -z "$CHANGED" ]; then
30
- echo "is_workflow_only=false" >> "$GITHUB_OUTPUT"
31
- echo "model=$MODEL" >> "$GITHUB_OUTPUT"
31
+ # v0.6.23 / §5: max_turns must always be emitted — see workflow.yml.tmpl for design notes.
32
+ # Grouped redirect (v0.6.24) silences the SC2129 style warning.
33
+ {
34
+ echo "is_workflow_only=false"
35
+ echo "model=$MODEL"
36
+ echo "max_turns=15"
37
+ } >> "$GITHUB_OUTPUT"
32
38
  exit 0
33
39
  fi
34
40
  IS_WORKFLOW_ONLY=true
@@ -75,6 +81,23 @@ jobs:
75
81
  fi
76
82
  echo "model=$MODEL" >> "$GITHUB_OUTPUT"
77
83
 
84
+ # Adaptive max-turns (v0.6.23 / §5) — see workflow.yml.tmpl for design notes.
85
+ MAX_TURNS=15
86
+ if [ "$IS_TRIVIAL" = "true" ]; then
87
+ MAX_TURNS=10
88
+ else
89
+ FILE_COUNT=$(echo "$CHANGED" | wc -l | tr -d ' ')
90
+ THREAD_COUNT=$(gh api graphql -f query='{repository(owner:"'"$(echo "$REPO" | cut -d/ -f1)"'",name:"'"$(echo "$REPO" | cut -d/ -f2)"'"){pullRequest(number:'"$PR_NUMBER"'){reviewThreads(first:50){nodes{isResolved comments(first:1){nodes{author{login}}}}}}}}' --jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false and (.comments.nodes[0].author.login == "claude" or .comments.nodes[0].author.login == "claude[bot]"))] | length' 2>/dev/null || echo 0)
91
+ THREAD_COUNT=${THREAD_COUNT:-0}
92
+ if [ "$FILE_COUNT" -ge 30 ] || [ "$THREAD_COUNT" -ge 6 ]; then
93
+ MAX_TURNS=40
94
+ elif [ "$FILE_COUNT" -ge 10 ] || [ "$THREAD_COUNT" -ge 3 ]; then
95
+ MAX_TURNS=25
96
+ fi
97
+ echo "::notice title=Clud Bug 🐛::Turn budget: $MAX_TURNS ($FILE_COUNT files, $THREAD_COUNT prior threads)."
98
+ fi
99
+ echo "max_turns=$MAX_TURNS" >> "$GITHUB_OUTPUT"
100
+
78
101
  clud-bug-review:
79
102
  needs: paths-check
80
103
  if: needs.paths-check.outputs.is_workflow_only != 'true'
@@ -85,6 +108,9 @@ jobs:
85
108
  id-token: write
86
109
  # checks: write — composite emits per-skill check-runs (BB.3).
87
110
  checks: write
111
+ # v0.6.24: `actions: read` (added in v0.6.23) backed out — broke
112
+ # `pull_request` trigger firing on private consumer repos. See
113
+ # workflow.yml.tmpl for the diagnosis.
88
114
 
89
115
  steps:
90
116
  - uses: actions/checkout@v6
@@ -147,7 +173,7 @@ jobs:
147
173
  # structured output; post-step renders + posts. See workflow.yml.tmpl for design notes.
148
174
  claude_args: |
149
175
  --model ${{ needs.paths-check.outputs.model }}
150
- --max-turns 15
176
+ --max-turns ${{ needs.paths-check.outputs.max_turns }}
151
177
  --allowedTools "mcp__github_inline_comment__create_inline_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:*)"
152
178
  --json-schema '{{REVIEW_SCHEMA}}'
153
179
  prompt: |
@@ -190,7 +216,7 @@ jobs:
190
216
  # Strict-mode gate — composite action; see workflow.yml.tmpl for design notes.
191
217
  - name: Strict mode — fail check on critical findings
192
218
  if: success()
193
- uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.22
219
+ uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.24
194
220
  with:
195
221
  github-token: ${{ secrets.GITHUB_TOKEN }}
196
222
  # v0.6.22 / 0.0.O: summary now posted by github-actions[bot].
@@ -29,6 +29,7 @@ jobs:
29
29
  outputs:
30
30
  is_workflow_only: ${{ steps.classify.outputs.is_workflow_only }}
31
31
  model: ${{ steps.classify.outputs.model }}
32
+ max_turns: ${{ steps.classify.outputs.max_turns }}
32
33
  steps:
33
34
  - name: Classify PR diff
34
35
  id: classify
@@ -41,8 +42,18 @@ jobs:
41
42
  CHANGED=$(gh pr diff "$PR_NUMBER" -R "$REPO" --name-only)
42
43
  MODEL=claude-sonnet-4-6 # default
43
44
  if [ -z "$CHANGED" ]; then
44
- echo "is_workflow_only=false" >> "$GITHUB_OUTPUT"
45
- echo "model=$MODEL" >> "$GITHUB_OUTPUT"
45
+ # v0.6.23 / §5: max_turns must always be emitted because
46
+ # clud-bug-review runs (is_workflow_only=false). Without
47
+ # this, --max-turns $-{{ ... }} expands to '--max-turns '
48
+ # (empty), failing the CLI invocation. Empty-CHANGED fires
49
+ # on gh pr diff auth/network failures + the (theoretical)
50
+ # no-changed-files PR. Grouped redirect (v0.6.24) silences
51
+ # the SC2129 style warning.
52
+ {
53
+ echo "is_workflow_only=false"
54
+ echo "model=$MODEL"
55
+ echo "max_turns=15"
56
+ } >> "$GITHUB_OUTPUT"
46
57
  exit 0
47
58
  fi
48
59
 
@@ -102,6 +113,38 @@ jobs:
102
113
  fi
103
114
  echo "model=$MODEL" >> "$GITHUB_OUTPUT"
104
115
 
116
+ # --- (c) adaptive max-turns (v0.6.23 / §5) ---
117
+ # Scope-based turn budget so large PRs (many files OR many prior
118
+ # unresolved threads to walk in FIX-PUSH FLOW) don't exhaust the
119
+ # default 15-turn budget. Concrete failure that motivated this:
120
+ # tokenomics PR #18 (23 docs files + 6 prior claude[bot] threads)
121
+ # exhausted the cap under v0.6.12 AND under v0.6.22's
122
+ # structured-output flow.
123
+ #
124
+ # Buckets:
125
+ # Trivial (Haiku) → 10
126
+ # Standard (<10 files AND <3 prior threads) → 15 (current default)
127
+ # Larger (≥10 files OR ≥3 prior threads) → 25
128
+ # Very large (≥30 files OR ≥6 prior threads) → 40
129
+ MAX_TURNS=15
130
+ if [ "$IS_TRIVIAL" = "true" ]; then
131
+ MAX_TURNS=10
132
+ else
133
+ FILE_COUNT=$(echo "$CHANGED" | wc -l | tr -d ' ')
134
+ # Count unresolved claude-bot threads. Best-effort: rate-limit
135
+ # or auth failures default to 0 (no escalation, fall back to
136
+ # file-count tier).
137
+ THREAD_COUNT=$(gh api graphql -f query='{repository(owner:"'"$(echo "$REPO" | cut -d/ -f1)"'",name:"'"$(echo "$REPO" | cut -d/ -f2)"'"){pullRequest(number:'"$PR_NUMBER"'){reviewThreads(first:50){nodes{isResolved comments(first:1){nodes{author{login}}}}}}}}' --jq '[.data.repository.pullRequest.reviewThreads.nodes[] | select(.isResolved == false and (.comments.nodes[0].author.login == "claude" or .comments.nodes[0].author.login == "claude[bot]"))] | length' 2>/dev/null || echo 0)
138
+ THREAD_COUNT=${THREAD_COUNT:-0}
139
+ if [ "$FILE_COUNT" -ge 30 ] || [ "$THREAD_COUNT" -ge 6 ]; then
140
+ MAX_TURNS=40
141
+ elif [ "$FILE_COUNT" -ge 10 ] || [ "$THREAD_COUNT" -ge 3 ]; then
142
+ MAX_TURNS=25
143
+ fi
144
+ echo "::notice title=Clud Bug 🐛::Turn budget: $MAX_TURNS ($FILE_COUNT files, $THREAD_COUNT prior unresolved claude threads)."
145
+ fi
146
+ echo "max_turns=$MAX_TURNS" >> "$GITHUB_OUTPUT"
147
+
105
148
  clud-bug-review:
106
149
  needs: paths-check
107
150
  if: needs.paths-check.outputs.is_workflow_only != 'true'
@@ -114,6 +157,15 @@ jobs:
114
157
  # the GitHub Checks API for any skill in .clud-bug.json's strictSkills
115
158
  # list (BB.3, v0.5.10+). No-op when strictSkills is unset.
116
159
  checks: write
160
+ # v0.6.23 attempted to add `actions: read` here for the github_ci
161
+ # MCP server bundled with claude-code-action. v0.6.24 backed it
162
+ # out: on private consumer repos the `pull_request` trigger
163
+ # silently stopped firing the workflow after the permissions
164
+ # block changed (validated against tokenomics — public agent-skills
165
+ # kept firing, private tokenomics/rezgen did not). claude-code-action
166
+ # warns about the missing `actions: read` but reviews still run
167
+ # correctly. Re-add via a separate path once we understand the
168
+ # private-repo trigger-registration semantics.
117
169
 
118
170
  steps:
119
171
  - uses: actions/checkout@v6
@@ -229,7 +281,7 @@ jobs:
229
281
  # this template at `clud-bug init` time via {{REVIEW_SCHEMA}}.
230
282
  claude_args: |
231
283
  --model ${{ needs.paths-check.outputs.model }}
232
- --max-turns 15
284
+ --max-turns ${{ needs.paths-check.outputs.max_turns }}
233
285
  --allowedTools "mcp__github_inline_comment__create_inline_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:*)"
234
286
  --json-schema '{{REVIEW_SCHEMA}}'
235
287
  prompt: |
@@ -290,7 +342,7 @@ jobs:
290
342
  # Letting the action's own failure fail the check is louder and right.
291
343
  - name: Strict mode — fail check on critical findings
292
344
  if: success()
293
- uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.22
345
+ uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.24
294
346
  with:
295
347
  github-token: ${{ secrets.GITHUB_TOKEN }}
296
348
  # v0.6.22 / 0.0.O: the summary is now posted by the workflow