clud-bug 0.5.5 → 0.5.7
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 +48 -4
- package/bin/clud-bug.js +15 -3
- package/lib/update.js +73 -6
- package/package.json +1 -1
- package/templates/audit.yml.tmpl +2 -5
- package/templates/self-update.yml.tmpl +2 -4
- package/templates/skills/baseline/clud-bug-collaboration.md +49 -0
- package/templates/workflow-py.yml.tmpl +3 -3
- package/templates/workflow-ts.yml.tmpl +3 -3
- package/templates/workflow.yml.tmpl +3 -3
package/README.md
CHANGED
|
@@ -164,20 +164,64 @@ If you want clud-bug to review fork PRs too, you have two options:
|
|
|
164
164
|
1. **Maintainer re-pushes the branch** to your repo as a non-fork branch, and the review runs.
|
|
165
165
|
2. **Switch the trigger to `pull_request_target`** (advanced) — this gives the workflow access to secrets but runs against the *base* ref, not the PR's code. To safely review the PR's actual code, follow [`anthropics/claude-code-action` security.md](https://github.com/anthropics/claude-code-action/blob/main/docs/security.md): check out the PR head into a **subdirectory** (not the workspace root) and pass it via `--add-dir`. Skipping this is a code-execution risk.
|
|
166
166
|
|
|
167
|
-
|
|
167
|
+
Concretely, the safe shape:
|
|
168
|
+
|
|
169
|
+
```yaml
|
|
170
|
+
on:
|
|
171
|
+
pull_request_target:
|
|
172
|
+
types: [opened, synchronize]
|
|
173
|
+
|
|
174
|
+
jobs:
|
|
175
|
+
clud-bug-review:
|
|
176
|
+
steps:
|
|
177
|
+
- uses: actions/checkout@v6 # base ref — trusted
|
|
178
|
+
- uses: actions/checkout@v6 # PR head — UNTRUSTED, into a subdir
|
|
179
|
+
with:
|
|
180
|
+
ref: ${{ github.event.pull_request.head.sha }}
|
|
181
|
+
path: pr-head
|
|
182
|
+
- uses: anthropics/claude-code-action@v1
|
|
183
|
+
with:
|
|
184
|
+
claude_args: --add-dir pr-head
|
|
185
|
+
# ... rest of args
|
|
186
|
+
```
|
|
187
|
+
|
|
188
|
+
The key invariant: the base checkout (with secrets in scope) lives at the workspace root; the PR head (untrusted user code) only ever lives in a subdirectory the action explicitly opts into via `--add-dir`. Any deviation — checking out the PR head at the root, running `npm install` from the subdir, etc. — re-opens the code-execution risk.
|
|
189
|
+
|
|
190
|
+
clud-bug's generated workflow uses `pull_request` (not `pull_request_target`) by default. If you understand the trade-offs and want to handle fork PRs, edit the trigger yourself using the shape above.
|
|
168
191
|
|
|
169
192
|
## When you edit the workflow
|
|
170
193
|
|
|
171
|
-
|
|
194
|
+
> **TL;DR:** if you see `App token exchange failed: Workflow validation failed (401)` on a PR that edits a clud-bug workflow file, that's **expected and protective** — not a bug in your PR. Read on.
|
|
195
|
+
|
|
196
|
+
clud-bug uses [`anthropics/claude-code-action`](https://github.com/anthropics/claude-code-action), which **refuses to run when the PR being reviewed modifies the action's own workflow file**. That's a security guard: without it, a PR could neuter the reviewer or exfiltrate secrets via prompt injection in the workflow file itself.
|
|
197
|
+
|
|
198
|
+
### What you'll see
|
|
199
|
+
|
|
200
|
+
When you push a PR that touches `.github/workflows/clud-bug-review.yml` (or any other clud-bug workflow):
|
|
201
|
+
|
|
202
|
+
- The `clud-bug-review` check fails with `App token exchange failed: 401 Unauthorized — Workflow validation failed. The workflow file must exist and have identical content to the version on the repository's default branch.`
|
|
203
|
+
- You'll get a GitHub email titled something like **"[thrillmot/your-repo] Run failed: Clud Bug 🐛 Crawls Your Code — `<branch-name>`"** — same wording for every workflow failure, so it doesn't visually distinguish "this is the expected self-mod guard" from "real failure."
|
|
204
|
+
|
|
205
|
+
### How to merge
|
|
206
|
+
|
|
207
|
+
If the PR contains **only** workflow edits, this is the expected path:
|
|
208
|
+
|
|
209
|
+
1. A maintainer reviews the diff directly (the bot can't).
|
|
210
|
+
2. Merge via admin override (`gh pr merge --admin` or the "Merge without waiting for requirements" button) — the failing `clud-bug-review` check is the bot refusing to review *itself*, not a real defect.
|
|
211
|
+
3. Subsequent PRs on the new workflow work normally — the validation gate compares against `main`, so once your edit is on `main`, the gate passes.
|
|
212
|
+
|
|
213
|
+
If the PR contains workflow edits **mixed with other code changes**, split them. The bot can't review either half while the workflow edit is in the diff, so any real findings get masked.
|
|
214
|
+
|
|
215
|
+
### The helper command
|
|
172
216
|
|
|
173
|
-
|
|
217
|
+
`clud-bug edit-workflow` packages the workflow change into a clean PR for you, refusing to run if your working tree has any non-workflow changes:
|
|
174
218
|
|
|
175
219
|
```bash
|
|
176
220
|
# Edit .github/workflows/clud-bug-*.yml as you like, then:
|
|
177
221
|
clud-bug edit-workflow
|
|
178
222
|
```
|
|
179
223
|
|
|
180
|
-
|
|
224
|
+
This keeps the merge ceremony scoped to just the workflow edit.
|
|
181
225
|
|
|
182
226
|
## Verifying it works
|
|
183
227
|
|
package/bin/clud-bug.js
CHANGED
|
@@ -608,16 +608,28 @@ async function runUpdateCmd(_args) {
|
|
|
608
608
|
return;
|
|
609
609
|
}
|
|
610
610
|
|
|
611
|
-
|
|
611
|
+
const skipped = result.skipped ?? [];
|
|
612
|
+
|
|
613
|
+
if (result.changed.length === 0 && skipped.length === 0) {
|
|
612
614
|
log(' Already current. Nothing to update.');
|
|
613
615
|
return;
|
|
614
616
|
}
|
|
615
617
|
|
|
616
|
-
|
|
617
|
-
|
|
618
|
+
if (result.changed.length > 0) {
|
|
619
|
+
log(` ✓ Updated ${result.changed.length} file${result.changed.length === 1 ? '' : 's'}:`);
|
|
620
|
+
for (const c of result.changed) {
|
|
621
|
+
const versionNote = c.from && c.to && c.from !== c.to ? ` (${c.label}, ${c.from} → ${c.to})` : ` (${c.label})`;
|
|
622
|
+
log(` • ${rel(cwd, c.path)}${versionNote}`);
|
|
623
|
+
}
|
|
624
|
+
}
|
|
618
625
|
if (result.unchanged.length > 0) {
|
|
619
626
|
log(` ${result.unchanged.length} file${result.unchanged.length === 1 ? ' was' : 's were'} already current.`);
|
|
620
627
|
}
|
|
628
|
+
if (skipped.length > 0) {
|
|
629
|
+
log('');
|
|
630
|
+
log(` ! Skipped ${skipped.length} markerless file${skipped.length === 1 ? '' : 's'} (treated as user-customized):`);
|
|
631
|
+
for (const s of skipped) log(` • ${rel(cwd, s.path)} — ${s.reason}`);
|
|
632
|
+
}
|
|
621
633
|
log('');
|
|
622
634
|
log('Commit + push to apply the refreshed kit on the next PR.');
|
|
623
635
|
}
|
package/lib/update.js
CHANGED
|
@@ -8,14 +8,18 @@ import { applyToRepo as applyAgentDocs } from './agents-md.js';
|
|
|
8
8
|
// Re-render the user's workflow + refresh baseline skills using the
|
|
9
9
|
// templates / baseline shipped with the currently-installed clud-bug.
|
|
10
10
|
//
|
|
11
|
-
// Honors
|
|
11
|
+
// Honors four protections:
|
|
12
12
|
// - Custom skills (anything in .claude/skills/ not in the manifest) are
|
|
13
13
|
// never modified.
|
|
14
14
|
// - Remote skills (from skills.sh, kind: 'remote' in manifest) are left
|
|
15
15
|
// alone unless { refreshRemote: true }.
|
|
16
|
-
// - The audit
|
|
16
|
+
// - The audit + self-update workflows are also refreshed if installed.
|
|
17
|
+
// - Markerless workflow files (no `# clud-bug-template-version:` header)
|
|
18
|
+
// are treated as user-customized and left alone — the user gets a
|
|
19
|
+
// printed warning + the documented "delete + clud-bug init" recovery
|
|
20
|
+
// path. Mirrors logmind v0.2.1's refresh-mode pattern.
|
|
17
21
|
//
|
|
18
|
-
// Returns
|
|
22
|
+
// Returns { changed, unchanged, skipped, ourVersion }.
|
|
19
23
|
export async function runUpdate({
|
|
20
24
|
cwd,
|
|
21
25
|
templatesDir,
|
|
@@ -35,6 +39,7 @@ export async function runUpdate({
|
|
|
35
39
|
|
|
36
40
|
const changed = [];
|
|
37
41
|
const unchanged = [];
|
|
42
|
+
const skipped = [];
|
|
38
43
|
|
|
39
44
|
// 1. Re-render review workflow with the latest template.
|
|
40
45
|
const signals = await detect(cwd);
|
|
@@ -43,13 +48,20 @@ export async function runUpdate({
|
|
|
43
48
|
PROJECT_DESCRIPTION: buildDescriptionLine(signals),
|
|
44
49
|
LANGUAGE_HINTS: '',
|
|
45
50
|
});
|
|
46
|
-
await
|
|
51
|
+
await maybeRefreshVersioned(join(cwd, '.github/workflows/clud-bug-review.yml'), newReview, changed, unchanged, skipped, 'review workflow');
|
|
47
52
|
|
|
48
53
|
// 2. Re-render audit workflow if it's installed (init from v0.3+ ships it).
|
|
49
54
|
const auditPath = join(cwd, '.github/workflows/clud-bug-audit.yml');
|
|
50
55
|
if (await pathExists(auditPath)) {
|
|
51
56
|
const newAudit = await readFile(join(templatesDir, 'audit.yml.tmpl'), 'utf8');
|
|
52
|
-
await
|
|
57
|
+
await maybeRefreshVersioned(auditPath, newAudit, changed, unchanged, skipped, 'audit workflow');
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
// 2b. Re-render self-update workflow if installed (init from v0.4+ ships it).
|
|
61
|
+
const selfUpdatePath = join(cwd, '.github/workflows/clud-bug-self-update.yml');
|
|
62
|
+
if (await pathExists(selfUpdatePath)) {
|
|
63
|
+
const newSelfUpdate = await readFile(join(templatesDir, 'self-update.yml.tmpl'), 'utf8');
|
|
64
|
+
await maybeRefreshVersioned(selfUpdatePath, newSelfUpdate, changed, unchanged, skipped, 'self-update workflow');
|
|
53
65
|
}
|
|
54
66
|
|
|
55
67
|
// 3. Refresh baseline skills (always controlled by clud-bug).
|
|
@@ -88,7 +100,7 @@ export async function runUpdate({
|
|
|
88
100
|
manifest.lastUpdateVersion = ourVersion;
|
|
89
101
|
await writeManifest(skillsDir, manifest);
|
|
90
102
|
|
|
91
|
-
return { changed, unchanged, ourVersion };
|
|
103
|
+
return { changed, unchanged, skipped, ourVersion };
|
|
92
104
|
}
|
|
93
105
|
|
|
94
106
|
async function maybeWrite(path, contents, changed, unchanged, label) {
|
|
@@ -102,6 +114,61 @@ async function maybeWrite(path, contents, changed, unchanged, label) {
|
|
|
102
114
|
changed.push({ path, label });
|
|
103
115
|
}
|
|
104
116
|
|
|
117
|
+
// Refresh a versioned template (one that carries `# clud-bug-template-version:`
|
|
118
|
+
// on line 1). If the installed file lacks that marker, treat it as
|
|
119
|
+
// user-customized and leave it alone — recovery path is delete + `clud-bug init`.
|
|
120
|
+
// Mirrors logmind v0.2.1's refresh-mode contract.
|
|
121
|
+
async function maybeRefreshVersioned(path, contents, changed, unchanged, skipped, label) {
|
|
122
|
+
const tmplVersion = extractTemplateVersion(contents);
|
|
123
|
+
if (!tmplVersion) {
|
|
124
|
+
// Defensive: every versioned template is supposed to carry a marker.
|
|
125
|
+
// Falling back to byte-compare write here would silently mass-overwrite
|
|
126
|
+
// every installed file (including marker-bearing ones) the moment a
|
|
127
|
+
// future template regressed — the inverse of the protection contract
|
|
128
|
+
// this function exists to enforce. Throw so the regression surfaces
|
|
129
|
+
// in CI instead.
|
|
130
|
+
throw new Error(`Template for ${label} has no # clud-bug-template-version marker — refusing to refresh (templates must declare a marker so refresh-mode can reason about ownership).`);
|
|
131
|
+
}
|
|
132
|
+
const prior = await readSafe(path);
|
|
133
|
+
if (prior === null) {
|
|
134
|
+
// First time writing here; nothing to preserve.
|
|
135
|
+
await mkdir(dirname(path), { recursive: true });
|
|
136
|
+
await writeFile(path, contents);
|
|
137
|
+
changed.push({ path, label });
|
|
138
|
+
return;
|
|
139
|
+
}
|
|
140
|
+
const priorVersion = extractTemplateVersion(prior);
|
|
141
|
+
if (priorVersion === null) {
|
|
142
|
+
// Markerless installed file = customized. Preserve and warn.
|
|
143
|
+
skipped.push({
|
|
144
|
+
path,
|
|
145
|
+
label,
|
|
146
|
+
reason: 'markerless (user-customized); delete the file + run `clud-bug init` to refresh',
|
|
147
|
+
});
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
if (prior === contents) {
|
|
151
|
+
unchanged.push({ path, label });
|
|
152
|
+
return;
|
|
153
|
+
}
|
|
154
|
+
// Marker present (current or stale) AND content drifted: refresh.
|
|
155
|
+
await mkdir(dirname(path), { recursive: true });
|
|
156
|
+
await writeFile(path, contents);
|
|
157
|
+
changed.push({ path, label, from: priorVersion, to: tmplVersion });
|
|
158
|
+
}
|
|
159
|
+
|
|
160
|
+
// Extract the template-version marker. Templates put it on line 1, but
|
|
161
|
+
// scan the first 5 lines so a leading blank or stray header doesn't hide it.
|
|
162
|
+
// Anchoring near the top means a stray `# clud-bug-template-version:` lower
|
|
163
|
+
// in the file (in a comment inside a heredoc, say) can't be mistaken for the
|
|
164
|
+
// authoritative marker. Returns null if not present.
|
|
165
|
+
function extractTemplateVersion(text) {
|
|
166
|
+
if (!text) return null;
|
|
167
|
+
const head = text.split('\n', 5).join('\n');
|
|
168
|
+
const m = head.match(/^# clud-bug-template-version:\s*(\S+)/m);
|
|
169
|
+
return m ? m[1] : null;
|
|
170
|
+
}
|
|
171
|
+
|
|
105
172
|
async function readSafe(path) {
|
|
106
173
|
try { return await readFile(path, 'utf8'); } catch { return null; }
|
|
107
174
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clud-bug",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.7",
|
|
4
4
|
"description": "Claude PR review with project-aware skills. CLI installs a working GitHub Actions workflow and curates skills from skills.sh.",
|
|
5
5
|
"homepage": "https://cludbug.dev",
|
|
6
6
|
"bugs": "https://github.com/thrillmot/clud-bug/issues",
|
package/templates/audit.yml.tmpl
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# clud-bug-template-version: v1
|
|
1
2
|
name: Clud Bug 🐛 Audit
|
|
2
3
|
|
|
3
4
|
# A scheduled / on-demand walk through the whole habitat (or a recent slice).
|
|
@@ -28,14 +29,11 @@ permissions:
|
|
|
28
29
|
pull-requests: write
|
|
29
30
|
id-token: write
|
|
30
31
|
|
|
31
|
-
env:
|
|
32
|
-
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true'
|
|
33
|
-
|
|
34
32
|
jobs:
|
|
35
33
|
audit:
|
|
36
34
|
runs-on: ubuntu-latest
|
|
37
35
|
steps:
|
|
38
|
-
- uses: actions/checkout@
|
|
36
|
+
- uses: actions/checkout@v6
|
|
39
37
|
with:
|
|
40
38
|
fetch-depth: 0 # full history needed for git --since
|
|
41
39
|
|
|
@@ -96,7 +94,6 @@ jobs:
|
|
|
96
94
|
env:
|
|
97
95
|
AUDIT_DATE: ${{ steps.prep.outputs.date }}
|
|
98
96
|
AUDIT_BRANCH: ${{ steps.prep.outputs.branch }}
|
|
99
|
-
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true'
|
|
100
97
|
with:
|
|
101
98
|
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
102
99
|
track_progress: true
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# clud-bug-template-version: v1
|
|
1
2
|
name: Clud Bug 🐛 Self-Update
|
|
2
3
|
|
|
3
4
|
# Weekly check for a newer published clud-bug. If one exists, runs
|
|
@@ -19,14 +20,11 @@ permissions:
|
|
|
19
20
|
contents: write
|
|
20
21
|
pull-requests: write
|
|
21
22
|
|
|
22
|
-
env:
|
|
23
|
-
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true'
|
|
24
|
-
|
|
25
23
|
jobs:
|
|
26
24
|
check:
|
|
27
25
|
runs-on: ubuntu-latest
|
|
28
26
|
steps:
|
|
29
|
-
- uses: actions/checkout@
|
|
27
|
+
- uses: actions/checkout@v6
|
|
30
28
|
|
|
31
29
|
- uses: actions/setup-node@v5
|
|
32
30
|
with:
|
|
@@ -71,6 +71,55 @@ When you write a custom skill, follow the SKILL.md frontmatter format
|
|
|
71
71
|
Generic advice gets ignored; rules with examples and quoted-line evidence
|
|
72
72
|
move the bot's behavior.
|
|
73
73
|
|
|
74
|
+
### Example: a good custom skill
|
|
75
|
+
|
|
76
|
+
Don't write generic prose like "be careful with database code." That's
|
|
77
|
+
not actionable. Instead, anchor to specific files + behaviors:
|
|
78
|
+
|
|
79
|
+
````markdown
|
|
80
|
+
---
|
|
81
|
+
name: db-query-review
|
|
82
|
+
description: How to review changes under lib/db/. Always flag missing parameterization, N+1 query patterns, and missing transaction boundaries on multi-statement writes.
|
|
83
|
+
---
|
|
84
|
+
|
|
85
|
+
# Reviewing lib/db/ changes
|
|
86
|
+
|
|
87
|
+
When the diff touches `lib/db/queries.ts` or any file under `lib/db/`,
|
|
88
|
+
apply these rules:
|
|
89
|
+
|
|
90
|
+
## Always flag
|
|
91
|
+
|
|
92
|
+
1. **SQL string interpolation** — anything that builds a query via `+`,
|
|
93
|
+
template literals, or `string.format` rather than parameterized
|
|
94
|
+
queries. Example to flag:
|
|
95
|
+
|
|
96
|
+
```ts
|
|
97
|
+
// BAD — flag this
|
|
98
|
+
db.query(`SELECT * FROM users WHERE id = ${userId}`)
|
|
99
|
+
// GOOD — uses parameterization
|
|
100
|
+
db.query('SELECT * FROM users WHERE id = ?', [userId])
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
2. **N+1 patterns** — flag any `await` inside a `for`/`map` loop that
|
|
104
|
+
calls `db.query` or `db.queryOne`. The fix is usually a single
|
|
105
|
+
`WHERE id IN (...)` query or a join.
|
|
106
|
+
|
|
107
|
+
3. **Multi-statement writes without `db.transaction`** — if a diff
|
|
108
|
+
adds two or more `db.query` calls that all write, demand a
|
|
109
|
+
transaction wrapper. Quote the lines.
|
|
110
|
+
|
|
111
|
+
## Style of finding
|
|
112
|
+
|
|
113
|
+
Cite the specific line. "This is a SQL injection risk" alone isn't
|
|
114
|
+
enough — quote the unsafe interpolation directly and propose the
|
|
115
|
+
parameterized alternative.
|
|
116
|
+
````
|
|
117
|
+
|
|
118
|
+
That's what "evidence-anchored" looks like: specific file paths, runnable
|
|
119
|
+
code examples for both bad and good, and explicit instructions on what
|
|
120
|
+
to quote in the finding. The bot loads this and uses it as concrete
|
|
121
|
+
review criteria, not vague guidance.
|
|
122
|
+
|
|
74
123
|
## When you edit `.github/workflows/clud-bug-*.yml`
|
|
75
124
|
|
|
76
125
|
`anthropics/claude-code-action` **refuses to run on PRs that modify its
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# clud-bug-template-version: v1
|
|
1
2
|
name: Clud Bug 🐛 Crawls Your Code
|
|
2
3
|
|
|
3
4
|
on:
|
|
@@ -13,7 +14,7 @@ jobs:
|
|
|
13
14
|
id-token: write
|
|
14
15
|
|
|
15
16
|
steps:
|
|
16
|
-
- uses: actions/checkout@
|
|
17
|
+
- uses: actions/checkout@v6
|
|
17
18
|
with:
|
|
18
19
|
fetch-depth: 0 # strict-mode gate reads base ref's manifest
|
|
19
20
|
|
|
@@ -51,12 +52,11 @@ jobs:
|
|
|
51
52
|
if: steps.guard.outputs.skip != 'true'
|
|
52
53
|
env:
|
|
53
54
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
54
|
-
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true'
|
|
55
55
|
with:
|
|
56
56
|
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
57
57
|
track_progress: true
|
|
58
58
|
claude_args: |
|
|
59
|
-
--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(cat .claude/skills/.clud-bug.json)"
|
|
59
|
+
--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(cat .claude/skills/.clud-bug.json)"
|
|
60
60
|
prompt: |
|
|
61
61
|
{{PROJECT_DESCRIPTION}}
|
|
62
62
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# clud-bug-template-version: v1
|
|
1
2
|
name: Clud Bug 🐛 Crawls Your Code
|
|
2
3
|
|
|
3
4
|
on:
|
|
@@ -13,7 +14,7 @@ jobs:
|
|
|
13
14
|
id-token: write
|
|
14
15
|
|
|
15
16
|
steps:
|
|
16
|
-
- uses: actions/checkout@
|
|
17
|
+
- uses: actions/checkout@v6
|
|
17
18
|
with:
|
|
18
19
|
fetch-depth: 0 # strict-mode gate reads base ref's manifest
|
|
19
20
|
|
|
@@ -51,12 +52,11 @@ jobs:
|
|
|
51
52
|
if: steps.guard.outputs.skip != 'true'
|
|
52
53
|
env:
|
|
53
54
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
54
|
-
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true'
|
|
55
55
|
with:
|
|
56
56
|
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
57
57
|
track_progress: true
|
|
58
58
|
claude_args: |
|
|
59
|
-
--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(cat .claude/skills/.clud-bug.json)"
|
|
59
|
+
--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(cat .claude/skills/.clud-bug.json)"
|
|
60
60
|
prompt: |
|
|
61
61
|
{{PROJECT_DESCRIPTION}}
|
|
62
62
|
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
# clud-bug-template-version: v1
|
|
1
2
|
name: Clud Bug 🐛 Crawls Your Code
|
|
2
3
|
|
|
3
4
|
on:
|
|
@@ -13,7 +14,7 @@ jobs:
|
|
|
13
14
|
id-token: write
|
|
14
15
|
|
|
15
16
|
steps:
|
|
16
|
-
- uses: actions/checkout@
|
|
17
|
+
- uses: actions/checkout@v6
|
|
17
18
|
with:
|
|
18
19
|
# fetch-depth: 0 so the strict-mode gate can `git show
|
|
19
20
|
# origin/<base_ref>:.claude/skills/.clud-bug.json` to read the base
|
|
@@ -75,12 +76,11 @@ jobs:
|
|
|
75
76
|
if: steps.guard.outputs.skip != 'true'
|
|
76
77
|
env:
|
|
77
78
|
PR_NUMBER: ${{ github.event.pull_request.number }}
|
|
78
|
-
FORCE_JAVASCRIPT_ACTIONS_TO_NODE24: 'true'
|
|
79
79
|
with:
|
|
80
80
|
anthropic_api_key: ${{ secrets.ANTHROPIC_API_KEY }}
|
|
81
81
|
track_progress: true
|
|
82
82
|
claude_args: |
|
|
83
|
-
--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(cat .claude/skills/.clud-bug.json)"
|
|
83
|
+
--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(cat .claude/skills/.clud-bug.json)"
|
|
84
84
|
prompt: |
|
|
85
85
|
{{PROJECT_DESCRIPTION}}
|
|
86
86
|
|