clud-bug 0.6.18 → 0.6.19
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/lib/agents-md.js
CHANGED
|
@@ -86,6 +86,35 @@ export function upsertBlock(content, block) {
|
|
|
86
86
|
return `${content}${sep}${block}\n`;
|
|
87
87
|
}
|
|
88
88
|
|
|
89
|
+
// 0.0.I.1 (v0.6.X): true if `content` has Claude Code's `@AGENTS.md`
|
|
90
|
+
// @-import — the canonical AGENTS.md content gets eager-loaded.
|
|
91
|
+
//
|
|
92
|
+
// Matches at start-of-line (a literal `@AGENTS.md` mentioned in prose
|
|
93
|
+
// won't fire; only the import directive does). Allows trailing space
|
|
94
|
+
// (some editors trim it; some don't) and optional newline terminator.
|
|
95
|
+
export function hasAgentsMdImport(content) {
|
|
96
|
+
if (typeof content !== 'string') return false;
|
|
97
|
+
return /^@AGENTS\.md\s*$/m.test(content);
|
|
98
|
+
}
|
|
99
|
+
|
|
100
|
+
// 0.0.I.1: strip a clud-bug block (markers + body) AND the blank line
|
|
101
|
+
// that precedes it, if any. Used when an @AGENTS.md import is detected
|
|
102
|
+
// — the AGENTS.md content covers the block, so keeping it in CLAUDE.md
|
|
103
|
+
// (or any tool stub) is duplication.
|
|
104
|
+
//
|
|
105
|
+
// Returns the cleaned content. If no block exists, returns content
|
|
106
|
+
// unchanged. Idempotent.
|
|
107
|
+
export function removeBlock(content) {
|
|
108
|
+
if (typeof content !== 'string') return content;
|
|
109
|
+
// Strip the block. Match \n+ before the marker so we also eat the
|
|
110
|
+
// preceding blank line — otherwise we'd leave a "stub line + blank
|
|
111
|
+
// + block" structure as "stub line + blank line".
|
|
112
|
+
const re = new RegExp(
|
|
113
|
+
`\\n*${escapeRe(START_MARKER)}[\\s\\S]*?${escapeRe(END_MARKER)}\\n?`,
|
|
114
|
+
);
|
|
115
|
+
return content.replace(re, '');
|
|
116
|
+
}
|
|
117
|
+
|
|
89
118
|
function escapeRe(s) {
|
|
90
119
|
return s.replace(/[.*+?^${}()|[\]\\]/g, '\\$&');
|
|
91
120
|
}
|
|
@@ -116,7 +145,7 @@ export async function applyToRepo(cwd, blockOpts = {}) {
|
|
|
116
145
|
const full = join(cwd, path);
|
|
117
146
|
if (!(await fileExists(full))) continue;
|
|
118
147
|
const prior = await readFile(full, 'utf8');
|
|
119
|
-
const next =
|
|
148
|
+
const next = nextContentFor(prior, block);
|
|
120
149
|
if (next !== prior) {
|
|
121
150
|
await writeFile(full, next);
|
|
122
151
|
touched.push(path);
|
|
@@ -132,7 +161,7 @@ export async function applyToRepo(cwd, blockOpts = {}) {
|
|
|
132
161
|
if (!name.endsWith('.md')) continue;
|
|
133
162
|
const full = join(cursorRulesDir, name);
|
|
134
163
|
const prior = await readFile(full, 'utf8');
|
|
135
|
-
const next =
|
|
164
|
+
const next = nextContentFor(prior, block);
|
|
136
165
|
if (next !== prior) {
|
|
137
166
|
await writeFile(full, next);
|
|
138
167
|
touched.push(`.cursor/rules/${name}`);
|
|
@@ -143,6 +172,18 @@ export async function applyToRepo(cwd, blockOpts = {}) {
|
|
|
143
172
|
return { touched, created };
|
|
144
173
|
}
|
|
145
174
|
|
|
175
|
+
// 0.0.I.1: decide what content a TOUCH_IF_PRESENT file should have.
|
|
176
|
+
// If it already imports AGENTS.md via Claude Code's @-syntax, skip the
|
|
177
|
+
// block entirely (and clean up any pre-existing block — the content is
|
|
178
|
+
// duplicated via @-import, so the AGENTS.md block is the only authority).
|
|
179
|
+
// Otherwise, upsert as before.
|
|
180
|
+
//
|
|
181
|
+
// AGENTS.md itself is NOT routed through here — it always gets the
|
|
182
|
+
// block (it's the canonical source).
|
|
183
|
+
function nextContentFor(prior, block) {
|
|
184
|
+
return hasAgentsMdImport(prior) ? removeBlock(prior) : upsertBlock(prior, block);
|
|
185
|
+
}
|
|
186
|
+
|
|
146
187
|
function seedFile(name) {
|
|
147
188
|
// When AGENTS.md doesn't exist (no logmind, no prior tooling), seed with a
|
|
148
189
|
// minimal canonical header so the clud-bug block has context.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clud-bug",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.19",
|
|
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",
|
|
@@ -156,6 +156,6 @@ jobs:
|
|
|
156
156
|
# Strict-mode gate — composite action; see workflow.yml.tmpl for design notes.
|
|
157
157
|
- name: Strict mode — fail check on critical findings
|
|
158
158
|
if: success()
|
|
159
|
-
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.
|
|
159
|
+
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.19
|
|
160
160
|
with:
|
|
161
161
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -156,6 +156,6 @@ jobs:
|
|
|
156
156
|
# Strict-mode gate — composite action; see workflow.yml.tmpl for design notes.
|
|
157
157
|
- name: Strict mode — fail check on critical findings
|
|
158
158
|
if: success()
|
|
159
|
-
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.
|
|
159
|
+
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.19
|
|
160
160
|
with:
|
|
161
161
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -247,6 +247,6 @@ jobs:
|
|
|
247
247
|
# Letting the action's own failure fail the check is louder and right.
|
|
248
248
|
- name: Strict mode — fail check on critical findings
|
|
249
249
|
if: success()
|
|
250
|
-
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.
|
|
250
|
+
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.19
|
|
251
251
|
with:
|
|
252
252
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|