clud-bug 0.5.0 → 0.5.2
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 +3 -1
- package/bin/clud-bug.js +27 -1
- package/lib/agents-md.js +183 -0
- package/lib/skills.js +1 -1
- package/lib/update.js +17 -1
- package/package.json +1 -1
- package/templates/skills/baseline/clud-bug-collaboration.md +124 -0
package/README.md
CHANGED
|
@@ -28,12 +28,14 @@ The naturalist arrives at your repo, surveys the habitat, and assembles a field
|
|
|
28
28
|
|
|
29
29
|
1. **Surveys habitat.** Reads `package.json`, `pyproject.toml`, `go.mod`, `Cargo.toml`, etc., to learn what your stack is.
|
|
30
30
|
2. **Consults [skills.sh](https://skills.sh).** Pulls review skills relevant to your dependencies (e.g. a Next.js project gets Next.js review specimens).
|
|
31
|
-
3. **Pins
|
|
31
|
+
3. **Pins baseline specimens** that enforce review discipline regardless of stack:
|
|
32
32
|
- `critical-issues-only` — flag bugs, security, perf only. Skip nits.
|
|
33
33
|
- `evidence-based-review` — every claim must quote the line being criticized.
|
|
34
34
|
- `respect-existing-conventions` — don't suggest fights with the codebase's patterns.
|
|
35
|
+
- `clud-bug-collaboration` — guidance for any other Claude Code agents working in your repo: how to coexist with bot review threads, how to read the gate, why workflow self-mods break the action, etc.
|
|
35
36
|
4. **Writes** the chosen specimens to `.claude/skills/<name>/SKILL.md` (Claude Code auto-loads them in the GitHub Action).
|
|
36
37
|
5. **Drafts the field kit** at `.github/workflows/clud-bug-review.yml` with your project description filled in and the right permissions/tool allowlist for `gh pr comment` to actually post.
|
|
38
|
+
6. **Briefs other agents** by adding a `<!-- clud-bug-start -->` block to `AGENTS.md` (creating it if missing — it's the cross-tool canonical), and idempotently to `CLAUDE.md`, `GEMINI.md`, `.github/copilot-instructions.md`, `.cursorrules`, `.windsurfrules`, `.clinerules`, `.continuerules`, and `.cursor/rules/*.md` where they already exist. Re-runs replace the prior block in place. Files you didn't already have are left uncreated — no proliferating stubs.
|
|
37
39
|
|
|
38
40
|
## CLI options
|
|
39
41
|
|
package/bin/clud-bug.js
CHANGED
|
@@ -15,6 +15,7 @@ import {
|
|
|
15
15
|
import { computeAuditFileSet, renderAuditHeader } from '../lib/audit.js';
|
|
16
16
|
import { runUpdate } from '../lib/update.js';
|
|
17
17
|
import { getPendingWorkflowEdits, makeBranchName, git as gitCmd } from '../lib/edit-workflow.js';
|
|
18
|
+
import { applyToRepo as applyAgentDocs } from '../lib/agents-md.js';
|
|
18
19
|
|
|
19
20
|
const PKG_ROOT = dirname(dirname(fileURLToPath(import.meta.url)));
|
|
20
21
|
const TEMPLATES = join(PKG_ROOT, 'templates');
|
|
@@ -204,9 +205,34 @@ async function runInit(args) {
|
|
|
204
205
|
}
|
|
205
206
|
await writeManifest(skillsDirPath, manifest);
|
|
206
207
|
|
|
208
|
+
// Tell other agents what's installed and how to coexist with the bot.
|
|
209
|
+
// Idempotent — re-runs replace the prior block in place. AGENTS.md is the
|
|
210
|
+
// canonical home (cross-tool); CLAUDE.md / GEMINI.md / Cursor / Windsurf
|
|
211
|
+
// / Cline / Continue rules files get the same block appended IF they
|
|
212
|
+
// already exist (we don't proliferate stubs the user didn't ask for).
|
|
213
|
+
log(' briefing other agents (AGENTS.md / CLAUDE.md)...');
|
|
214
|
+
// Pass `=== true` (not `!== false`) so the rendered block matches the
|
|
215
|
+
// workflow's gate predicate exactly. A v0.3 advisory upgrade where
|
|
216
|
+
// strictMode is undefined renders "off" — which is what the workflow
|
|
217
|
+
// actually does on that manifest.
|
|
218
|
+
const agentDocs = await applyAgentDocs(cwd, {
|
|
219
|
+
version: manifest.lastUpdateVersion,
|
|
220
|
+
strictMode: manifest.strictMode === true,
|
|
221
|
+
});
|
|
222
|
+
for (const p of agentDocs.created) log(` created ${p}`);
|
|
223
|
+
for (const p of agentDocs.touched) log(` updated ${p}`);
|
|
224
|
+
|
|
207
225
|
if (args.commit) {
|
|
208
226
|
log(' committing...');
|
|
209
|
-
|
|
227
|
+
const toAdd = [
|
|
228
|
+
'.claude',
|
|
229
|
+
'.github/workflows/clud-bug-review.yml',
|
|
230
|
+
'.github/workflows/clud-bug-audit.yml',
|
|
231
|
+
'.github/workflows/clud-bug-self-update.yml',
|
|
232
|
+
...agentDocs.created,
|
|
233
|
+
...agentDocs.touched,
|
|
234
|
+
];
|
|
235
|
+
spawnSync('git', ['add', ...toAdd], { cwd, stdio: 'inherit' });
|
|
210
236
|
spawnSync('git', ['commit', '-m', 'Add clud-bug 🐛 — a field guide to specimens crawling your code'], { cwd, stdio: 'inherit' });
|
|
211
237
|
}
|
|
212
238
|
|
package/lib/agents-md.js
ADDED
|
@@ -0,0 +1,183 @@
|
|
|
1
|
+
import { readFile, writeFile, stat, readdir } from 'node:fs/promises';
|
|
2
|
+
import { join } from 'node:path';
|
|
3
|
+
|
|
4
|
+
// Manages a clud-bug-owned section inside AGENTS.md / CLAUDE.md and adjacent
|
|
5
|
+
// agent-instruction files. Mirrors the well-established `<!-- logmind-start -->`
|
|
6
|
+
// pattern: a marked block that other agents can read for collaboration rules,
|
|
7
|
+
// idempotently rewritten on each `clud-bug init` so the content stays current.
|
|
8
|
+
|
|
9
|
+
const START_MARKER = '<!-- clud-bug-start -->';
|
|
10
|
+
const END_MARKER = '<!-- clud-bug-end -->';
|
|
11
|
+
const BLOCK_VERSION = 'v1';
|
|
12
|
+
|
|
13
|
+
// Files we'll touch when present, plus files we'll create if missing.
|
|
14
|
+
// AGENTS.md is the cross-tool canonical (logmind made it canonical too).
|
|
15
|
+
// CLAUDE.md, GEMINI.md, .cursorrules, .windsurfrules etc. are tool-specific
|
|
16
|
+
// stubs/instructions; we append the same block where they exist but don't
|
|
17
|
+
// create them (logmind already creates the ones it knows about).
|
|
18
|
+
const ALWAYS_TOUCH = ['AGENTS.md']; // create if missing
|
|
19
|
+
const TOUCH_IF_PRESENT = [
|
|
20
|
+
'CLAUDE.md',
|
|
21
|
+
'GEMINI.md',
|
|
22
|
+
'.github/copilot-instructions.md',
|
|
23
|
+
'.cursorrules',
|
|
24
|
+
'.windsurfrules',
|
|
25
|
+
'.clinerules',
|
|
26
|
+
'.continuerules',
|
|
27
|
+
];
|
|
28
|
+
|
|
29
|
+
// Render the clud-bug block. Bundled here rather than in a template file so
|
|
30
|
+
// updates ship with the CLI itself.
|
|
31
|
+
//
|
|
32
|
+
// `strictMode` MUST match the workflow's gate predicate exactly so the block
|
|
33
|
+
// can't lie about repo state. The workflow at `templates/workflow*.yml.tmpl`
|
|
34
|
+
// reads the manifest with `JSON.parse(s).strictMode === true` — meaning the
|
|
35
|
+
// gate fires ONLY on an explicit `true`, and anything else (missing field,
|
|
36
|
+
// `false`, `null`) is advisory. Mirror that here: render "on" only when the
|
|
37
|
+
// caller explicitly passes `true`. Anything else is "off".
|
|
38
|
+
//
|
|
39
|
+
// Why this matters: a v0.3-era install (no `strictMode` field, `lastUpdate`
|
|
40
|
+
// set) is a documented advisory upgrade path — `clud-bug init` deliberately
|
|
41
|
+
// preserves that state. If the block rendered "on" for that case, other
|
|
42
|
+
// agents reading AGENTS.md would get a wrong model of the gate.
|
|
43
|
+
export function renderBlock({ version, strictMode } = {}) {
|
|
44
|
+
const versionLine = version ? `_Installed at clud-bug v${version}._` : '';
|
|
45
|
+
const strictNote = strictMode === true
|
|
46
|
+
? 'Strict mode is **on** in this repo (workflow check fails on critical findings).'
|
|
47
|
+
: 'Strict mode is **off** in this repo (advisory only).';
|
|
48
|
+
return `${START_MARKER}
|
|
49
|
+
<!-- clud-bug-block-version: ${BLOCK_VERSION} -->
|
|
50
|
+
## clud-bug — Claude PR review
|
|
51
|
+
|
|
52
|
+
This repository uses [clud-bug](https://cludbug.dev) to review pull requests
|
|
53
|
+
automatically. Three things matter when other agents (or future-you) work
|
|
54
|
+
in this repo:
|
|
55
|
+
|
|
56
|
+
### When you push fixes addressing prior Clud Bug review threads
|
|
57
|
+
|
|
58
|
+
The bot resolves its own prior review threads on the next pass when it can
|
|
59
|
+
verify the fix in the diff. You don't need to manually resolve threads it
|
|
60
|
+
opened — push the fix, wait ~2 minutes, and check the PR. If a thread it
|
|
61
|
+
left isn't auto-resolved after a fix, the bot judged the issue still open;
|
|
62
|
+
read its latest review comment for what it's still flagging.
|
|
63
|
+
|
|
64
|
+
### Strict mode
|
|
65
|
+
|
|
66
|
+
${strictNote} Toggle by editing \`.claude/skills/.clud-bug.json\`:
|
|
67
|
+
|
|
68
|
+
\`\`\`json
|
|
69
|
+
{ "strictMode": true | false, ... }
|
|
70
|
+
\`\`\`
|
|
71
|
+
|
|
72
|
+
The setting is read from the **base ref** of any open PR, so PRs cannot
|
|
73
|
+
disable strict mode on themselves. Changes take effect on PRs opened after
|
|
74
|
+
they merge to the base branch.
|
|
75
|
+
|
|
76
|
+
### Where the skills live
|
|
77
|
+
|
|
78
|
+
Project-aware review rules live in \`.claude/skills/<name>/SKILL.md\`. A
|
|
79
|
+
small baseline kit ships with every install — see
|
|
80
|
+
\`.claude/skills/.clud-bug.json\` for the current set. Add more via
|
|
81
|
+
\`clud-bug add <source/name>\` (from skills.sh) or by dropping your own
|
|
82
|
+
\`.md\` files there. They auto-load into the reviewer.
|
|
83
|
+
|
|
84
|
+
### Editing the workflow
|
|
85
|
+
|
|
86
|
+
Anthropic's \`claude-code-action\` refuses to run on PRs that modify its own
|
|
87
|
+
workflow file. Use \`clud-bug edit-workflow\` to bundle workflow tweaks into
|
|
88
|
+
their own isolated PR — see [README](https://github.com/thrillmot/clud-bug#when-you-edit-the-workflow).
|
|
89
|
+
|
|
90
|
+
${versionLine}
|
|
91
|
+
${END_MARKER}`;
|
|
92
|
+
}
|
|
93
|
+
|
|
94
|
+
// Replace an existing clud-bug block in `content`, OR append if absent.
|
|
95
|
+
// Idempotent: running multiple times leaves a single block.
|
|
96
|
+
export function upsertBlock(content, block) {
|
|
97
|
+
const startRe = new RegExp(escapeRe(START_MARKER));
|
|
98
|
+
const endRe = new RegExp(escapeRe(END_MARKER));
|
|
99
|
+
if (startRe.test(content) && endRe.test(content)) {
|
|
100
|
+
// Replace from START_MARKER through END_MARKER (greedy multi-line).
|
|
101
|
+
const re = new RegExp(`${escapeRe(START_MARKER)}[\\s\\S]*?${escapeRe(END_MARKER)}`);
|
|
102
|
+
return content.replace(re, block);
|
|
103
|
+
}
|
|
104
|
+
// Append with a separating blank line, no trailing newline duplication.
|
|
105
|
+
const sep = content.endsWith('\n') ? '\n' : '\n\n';
|
|
106
|
+
return `${content}${sep}${block}\n`;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
function escapeRe(s) {
|
|
110
|
+
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
111
|
+
}
|
|
112
|
+
|
|
113
|
+
// Touches all relevant agent-instruction files in `cwd`.
|
|
114
|
+
// Creates AGENTS.md if it doesn't exist (it's the canonical home).
|
|
115
|
+
// Updates other files only if they already exist (don't proliferate stubs;
|
|
116
|
+
// logmind or the user owns those creation decisions).
|
|
117
|
+
//
|
|
118
|
+
// Returns { touched: string[], created: string[] } for the caller to log.
|
|
119
|
+
export async function applyToRepo(cwd, blockOpts = {}) {
|
|
120
|
+
const block = renderBlock(blockOpts);
|
|
121
|
+
const touched = [];
|
|
122
|
+
const created = [];
|
|
123
|
+
|
|
124
|
+
for (const path of ALWAYS_TOUCH) {
|
|
125
|
+
const full = join(cwd, path);
|
|
126
|
+
const existed = await fileExists(full);
|
|
127
|
+
const prior = existed ? await readFile(full, 'utf8') : seedFile(path);
|
|
128
|
+
const next = upsertBlock(prior, block);
|
|
129
|
+
if (next !== prior) {
|
|
130
|
+
await writeFile(full, next);
|
|
131
|
+
(existed ? touched : created).push(path);
|
|
132
|
+
}
|
|
133
|
+
}
|
|
134
|
+
|
|
135
|
+
for (const path of TOUCH_IF_PRESENT) {
|
|
136
|
+
const full = join(cwd, path);
|
|
137
|
+
if (!(await fileExists(full))) continue;
|
|
138
|
+
const prior = await readFile(full, 'utf8');
|
|
139
|
+
const next = upsertBlock(prior, block);
|
|
140
|
+
if (next !== prior) {
|
|
141
|
+
await writeFile(full, next);
|
|
142
|
+
touched.push(path);
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
// .cursor/rules/*.md — append to every file that exists.
|
|
147
|
+
const cursorRulesDir = join(cwd, '.cursor', 'rules');
|
|
148
|
+
if (await fileExists(cursorRulesDir)) {
|
|
149
|
+
let entries = [];
|
|
150
|
+
try { entries = await readdir(cursorRulesDir); } catch {}
|
|
151
|
+
for (const name of entries) {
|
|
152
|
+
if (!name.endsWith('.md')) continue;
|
|
153
|
+
const full = join(cursorRulesDir, name);
|
|
154
|
+
const prior = await readFile(full, 'utf8');
|
|
155
|
+
const next = upsertBlock(prior, block);
|
|
156
|
+
if (next !== prior) {
|
|
157
|
+
await writeFile(full, next);
|
|
158
|
+
touched.push(`.cursor/rules/${name}`);
|
|
159
|
+
}
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
|
|
163
|
+
return { touched, created };
|
|
164
|
+
}
|
|
165
|
+
|
|
166
|
+
function seedFile(name) {
|
|
167
|
+
// When AGENTS.md doesn't exist (no logmind, no prior tooling), seed with a
|
|
168
|
+
// minimal canonical header so the clud-bug block has context.
|
|
169
|
+
if (name === 'AGENTS.md') {
|
|
170
|
+
return `# AGENTS.md
|
|
171
|
+
|
|
172
|
+
This file is the canonical instruction file for AI coding agents working in
|
|
173
|
+
this repository. Tools that understand AGENTS.md (Cursor, Codex, Windsurf,
|
|
174
|
+
Claude Code, Cline, Continue, Aider, ...) read it directly.
|
|
175
|
+
|
|
176
|
+
`;
|
|
177
|
+
}
|
|
178
|
+
return '';
|
|
179
|
+
}
|
|
180
|
+
|
|
181
|
+
async function fileExists(path) {
|
|
182
|
+
try { await stat(path); return true; } catch { return false; }
|
|
183
|
+
}
|
package/lib/skills.js
CHANGED
|
@@ -15,7 +15,7 @@ const MANIFEST_VERSION = 1;
|
|
|
15
15
|
// skill content, bump BASELINE_SKILLS_REF below in the same clud-bug PR
|
|
16
16
|
// that ships the corresponding bundled fallback update.
|
|
17
17
|
// See thrillmot/agent-skills — skills.sh `skills/<name>/SKILL.md` layout.
|
|
18
|
-
const BASELINE_SKILLS_REF = '
|
|
18
|
+
const BASELINE_SKILLS_REF = 'a44559770686e6c51d08ba5bb842d78f85876fb2';
|
|
19
19
|
const AGENT_SKILLS_BASE = process.env.CLUD_BUG_AGENT_SKILLS_BASE
|
|
20
20
|
?? `https://raw.githubusercontent.com/thrillmot/agent-skills/${BASELINE_SKILLS_REF}/skills`;
|
|
21
21
|
const SKILL_FETCH_TIMEOUT_MS = 5000;
|
package/lib/update.js
CHANGED
|
@@ -3,6 +3,7 @@ import { join, dirname } from 'node:path';
|
|
|
3
3
|
import { renderFile, pickTemplate } from './render.js';
|
|
4
4
|
import { detect, buildDescriptionLine } from './detect.js';
|
|
5
5
|
import { loadBaseline, readManifest, writeManifest } from './skills.js';
|
|
6
|
+
import { applyToRepo as applyAgentDocs } from './agents-md.js';
|
|
6
7
|
|
|
7
8
|
// Re-render the user's workflow + refresh baseline skills using the
|
|
8
9
|
// templates / baseline shipped with the currently-installed clud-bug.
|
|
@@ -67,7 +68,22 @@ export async function runUpdate({
|
|
|
67
68
|
// `clud-bug refresh`. We just emit an advisory.
|
|
68
69
|
}
|
|
69
70
|
|
|
70
|
-
// 5.
|
|
71
|
+
// 5. Refresh the AGENTS.md / CLAUDE.md clud-bug block. The block embeds
|
|
72
|
+
// the version + strict-mode state, so an update with a new version
|
|
73
|
+
// rewrites it. Files that don't already exist (other than AGENTS.md)
|
|
74
|
+
// are left alone, so this never silently creates instruction stubs.
|
|
75
|
+
// `=== true` mirrors the workflow's gate predicate at
|
|
76
|
+
// templates/workflow*.yml.tmpl. A v0.3 advisory manifest (strictMode
|
|
77
|
+
// undefined, lastUpdate set) renders "off" — matching the gate, not the
|
|
78
|
+
// default-on behavior of fresh v0.4+ installs.
|
|
79
|
+
const agentDocs = await applyAgentDocs(cwd, {
|
|
80
|
+
version: ourVersion,
|
|
81
|
+
strictMode: manifest.strictMode === true,
|
|
82
|
+
});
|
|
83
|
+
for (const p of agentDocs.created) changed.push({ path: join(cwd, p), label: `agent docs: created ${p}` });
|
|
84
|
+
for (const p of agentDocs.touched) changed.push({ path: join(cwd, p), label: `agent docs: ${p}` });
|
|
85
|
+
|
|
86
|
+
// 6. Stamp the manifest with the version that ran the update.
|
|
71
87
|
manifest.lastUpdate = new Date().toISOString();
|
|
72
88
|
manifest.lastUpdateVersion = ourVersion;
|
|
73
89
|
await writeManifest(skillsDir, manifest);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clud-bug",
|
|
3
|
-
"version": "0.5.
|
|
3
|
+
"version": "0.5.2",
|
|
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",
|
|
@@ -0,0 +1,124 @@
|
|
|
1
|
+
---
|
|
2
|
+
name: clud-bug-collaboration
|
|
3
|
+
description: How Claude Code agents working in a clud-bug-installed repo should interact with the bot's review threads, strict-mode gate, and skill set. Use this skill whenever you're about to push a commit, address a clud-bug PR review comment, edit anything under .claude/skills/, modify .github/workflows/clud-bug-*.yml, or wonder why a PR check is red. Also use when planning work in a repo that has a `clud-bug-review` workflow installed — even if the user didn't mention clud-bug by name.
|
|
4
|
+
---
|
|
5
|
+
|
|
6
|
+
# Working in a clud-bug-installed repo
|
|
7
|
+
|
|
8
|
+
Clud Bug reviews every PR via `anthropics/claude-code-action`. As another
|
|
9
|
+
Claude Code agent working alongside it, here's what to know — these aren't
|
|
10
|
+
arbitrary rules, they're the consequences of how the gate is wired.
|
|
11
|
+
|
|
12
|
+
## When you push fixes to a clud-bug-reviewed PR
|
|
13
|
+
|
|
14
|
+
The bot reviews on `pull_request: synchronize` (every push). When you push
|
|
15
|
+
a commit that addresses an issue Clud Bug flagged in a prior review, the bot
|
|
16
|
+
will re-review the PR within ~2 minutes and **resolve its own prior
|
|
17
|
+
unresolved inline review threads** where the flagged issue is verifiably
|
|
18
|
+
fixed in the current diff. You don't have to resolve threads manually.
|
|
19
|
+
|
|
20
|
+
If a thread it left isn't auto-resolved after your fix:
|
|
21
|
+
- The bot judged the issue still open (read its latest comment for why).
|
|
22
|
+
- Or the resolution call hit a transient API issue (re-push to retry).
|
|
23
|
+
|
|
24
|
+
Don't manually resolve clud-bug threads on its behalf. The check
|
|
25
|
+
(`required_conversation_resolution` branch protection) will block merge if
|
|
26
|
+
unresolved threads remain — and the right fix is usually "fix the actual
|
|
27
|
+
issue and re-push," not "mark the conversation resolved."
|
|
28
|
+
|
|
29
|
+
## When you read the PR's `clud-bug-review` check status
|
|
30
|
+
|
|
31
|
+
- **Green** = Clud Bug ran and either found no critical issues OR strict
|
|
32
|
+
mode is off (advisory).
|
|
33
|
+
- **Red** = either the action errored OR strict mode is on AND Clud Bug
|
|
34
|
+
flagged a critical issue. Read the latest `## 🐛 Clud Bug review` comment
|
|
35
|
+
on the PR — the body indicates "critical findings" or "clean."
|
|
36
|
+
- **Skipped/green-with-comment** = bot- or fork-authored PR (Dependabot,
|
|
37
|
+
Renovate, fork contributor). GitHub deliberately doesn't pass repo
|
|
38
|
+
secrets to those workflows. The bot posts a one-line "Clud Bug skipped"
|
|
39
|
+
comment and exits 0. Review the diff manually.
|
|
40
|
+
|
|
41
|
+
## Strict mode
|
|
42
|
+
|
|
43
|
+
Read `.claude/skills/.clud-bug.json` to check this repo's setting.
|
|
44
|
+
`strictMode: true` means the workflow check fails on critical findings.
|
|
45
|
+
The setting is read from the **base ref**, so a PR cannot disable strict
|
|
46
|
+
mode on itself by editing the manifest. Changes take effect for PRs opened
|
|
47
|
+
after the change merges to the base branch.
|
|
48
|
+
|
|
49
|
+
To disable strict mode for a repo, edit the manifest on the base branch:
|
|
50
|
+
|
|
51
|
+
```json
|
|
52
|
+
{ "strictMode": false, ... }
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
## When you modify a clud-bug skill
|
|
56
|
+
|
|
57
|
+
Skills live in `.claude/skills/<slug>/SKILL.md`. Three groups:
|
|
58
|
+
|
|
59
|
+
- **Baseline** (`critical-issues-only`, `evidence-based-review`,
|
|
60
|
+
`respect-existing-conventions`) — managed by clud-bug; if you edit them
|
|
61
|
+
in-place they'll be overwritten on the next `clud-bug update`. To
|
|
62
|
+
customize behavior for this repo, write a NEW skill rather than mutating
|
|
63
|
+
a baseline.
|
|
64
|
+
- **From skills.sh** — installed via `clud-bug add <source/name>`. Tracked
|
|
65
|
+
in `.claude/skills/.clud-bug.json`. Use `clud-bug refresh` to sync.
|
|
66
|
+
- **Custom** (anything not in the manifest) — yours, never touched by any
|
|
67
|
+
clud-bug command. Drop a new `.md` here and it auto-loads on the next PR.
|
|
68
|
+
|
|
69
|
+
When you write a custom skill, follow the SKILL.md frontmatter format
|
|
70
|
+
(`name`, `description`) and write specific, evidence-anchored guidance.
|
|
71
|
+
Generic advice gets ignored; rules with examples and quoted-line evidence
|
|
72
|
+
move the bot's behavior.
|
|
73
|
+
|
|
74
|
+
## When you edit `.github/workflows/clud-bug-*.yml`
|
|
75
|
+
|
|
76
|
+
`anthropics/claude-code-action` **refuses to run on PRs that modify its
|
|
77
|
+
own workflow file** (App token exchange fails with 401, "Workflow
|
|
78
|
+
validation failed"). This is a security guard against PRs that try to
|
|
79
|
+
neuter the reviewer or exfiltrate secrets.
|
|
80
|
+
|
|
81
|
+
Consequence: if you bundle a workflow tweak with other work, the
|
|
82
|
+
`clud-bug-review` check on that PR will fail and not actually review your
|
|
83
|
+
other changes either.
|
|
84
|
+
|
|
85
|
+
The fix: split workflow edits into their own PR. The CLI helps:
|
|
86
|
+
|
|
87
|
+
```bash
|
|
88
|
+
# After editing .github/workflows/clud-bug-*.yml locally:
|
|
89
|
+
clud-bug edit-workflow
|
|
90
|
+
```
|
|
91
|
+
|
|
92
|
+
It refuses to run if your working tree has non-workflow changes, so the
|
|
93
|
+
isolation guarantee is enforced. Branches from `origin/main`, not HEAD —
|
|
94
|
+
unrelated commits on a feature branch can't leak in.
|
|
95
|
+
|
|
96
|
+
## When the secret is missing
|
|
97
|
+
|
|
98
|
+
`ANTHROPIC_API_KEY` must be set in the repo's Actions secrets. Without it,
|
|
99
|
+
the workflow's guard step fails loudly with an `::error::` annotation
|
|
100
|
+
explaining how to set it. (For bot/fork PRs where the secret legitimately
|
|
101
|
+
isn't passed, the guard posts a one-line advisory comment and exits 0
|
|
102
|
+
instead of failing red.)
|
|
103
|
+
|
|
104
|
+
## Updating clud-bug itself
|
|
105
|
+
|
|
106
|
+
`clud-bug-self-update.yml` runs weekly (Mondays 12:00 UTC) and opens a PR
|
|
107
|
+
when a newer clud-bug version is published to npm. Pin to a specific
|
|
108
|
+
version by adding `pinVersion: "x.y.z"` to `.claude/skills/.clud-bug.json`.
|
|
109
|
+
|
|
110
|
+
To trigger an update on demand:
|
|
111
|
+
|
|
112
|
+
```bash
|
|
113
|
+
clud-bug update
|
|
114
|
+
```
|
|
115
|
+
|
|
116
|
+
Re-renders workflow templates and refreshes baseline skills from the
|
|
117
|
+
currently-installed clud-bug version. Custom and skills.sh-installed
|
|
118
|
+
skills are left untouched.
|
|
119
|
+
|
|
120
|
+
## Where to find more
|
|
121
|
+
|
|
122
|
+
- Site: https://cludbug.dev
|
|
123
|
+
- Repo: https://github.com/thrillmot/clud-bug
|
|
124
|
+
- Skill catalog: https://github.com/thrillmot/agent-skills
|