clud-bug 0.6.6 → 0.6.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/bin/clud-bug.js
CHANGED
|
@@ -27,7 +27,7 @@ function parseArgs(argv) {
|
|
|
27
27
|
const args = {
|
|
28
28
|
_: [], offline: false, acceptAll: false, commit: false, help: false, version: false,
|
|
29
29
|
since: null, changedIn: null, scopes: [], out: null,
|
|
30
|
-
setProtection: true,
|
|
30
|
+
setProtection: true, quiet: false,
|
|
31
31
|
};
|
|
32
32
|
for (let i = 0; i < argv.length; i++) {
|
|
33
33
|
const a = argv[i];
|
|
@@ -36,6 +36,7 @@ function parseArgs(argv) {
|
|
|
36
36
|
else if (a === '--commit') args.commit = true;
|
|
37
37
|
else if (a === '--help' || a === '-h') args.help = true;
|
|
38
38
|
else if (a === '--version' || a === '-v') args.version = true;
|
|
39
|
+
else if (a === '--quiet' || a === '-q') args.quiet = true;
|
|
39
40
|
else if (a === '--since') args.since = argv[++i];
|
|
40
41
|
else if (a === '--changed-in') args.changedIn = argv[++i];
|
|
41
42
|
else if (a === '--scope') args.scopes.push(argv[++i]);
|
|
@@ -68,6 +69,11 @@ Options:
|
|
|
68
69
|
--offline Skip skills.sh; pin only the bundled baseline specimens.
|
|
69
70
|
--accept-all,-y Accept the recommended specimens without prompting.
|
|
70
71
|
--commit git add + commit the generated kit when done (init only).
|
|
72
|
+
--quiet,-q Token-frugal mode for agent invocations. Suppresses
|
|
73
|
+
progress chatter; emits exactly one final
|
|
74
|
+
\`ok <key-value>\` summary line per command. Errors
|
|
75
|
+
and warnings still print. Also honored via the
|
|
76
|
+
CLUD_BUG_QUIET=1 env var.
|
|
71
77
|
--no-set-protection Skip the prompt that offers to enable
|
|
72
78
|
required_conversation_resolution on the default
|
|
73
79
|
branch (init only). Use for repos that manage
|
|
@@ -89,6 +95,7 @@ async function main() {
|
|
|
89
95
|
const args = parseArgs(process.argv.slice(2));
|
|
90
96
|
if (args.help) { process.stdout.write(HELP); return; }
|
|
91
97
|
if (args.version) { process.stdout.write((await readPkgVersion()) + '\n'); return; }
|
|
98
|
+
if (args.quiet) setQuiet(true);
|
|
92
99
|
|
|
93
100
|
const cmd = args._[0];
|
|
94
101
|
switch (cmd) {
|
|
@@ -275,6 +282,10 @@ async function runInit(args) {
|
|
|
275
282
|
log('Strict mode is ON by default (clud-bug-review fails the check on critical findings).');
|
|
276
283
|
log(' • Add `clud-bug-review` to your branch protection required checks for full enforcement.');
|
|
277
284
|
log(' • Opt out by setting "strictMode": false in .claude/skills/.clud-bug.json.');
|
|
285
|
+
|
|
286
|
+
// Final agent-friendly summary line (always emitted, even with --quiet).
|
|
287
|
+
const version = await readPkgVersion();
|
|
288
|
+
ok(`initialized: .claude/skills/ ${chosen.length} specimens, workflow @v${version}`);
|
|
278
289
|
}
|
|
279
290
|
|
|
280
291
|
async function promptForSkills(recommended) {
|
|
@@ -413,6 +424,7 @@ async function runList(_args) {
|
|
|
413
424
|
const total = groups.baseline.length + groups.remote.length + groups.custom.length;
|
|
414
425
|
if (total === 0) {
|
|
415
426
|
log('Empty collection. Run `clud-bug init` to open field season.');
|
|
427
|
+
ok('list: 0 skills installed (run `clud-bug init` first)');
|
|
416
428
|
return;
|
|
417
429
|
}
|
|
418
430
|
log(`🐛 ${total} specimen${total === 1 ? '' : 's'} pinned in .claude/skills/`);
|
|
@@ -433,6 +445,7 @@ async function runList(_args) {
|
|
|
433
445
|
log(` • ${s.slug}${s.description ? ` — ${s.description}` : ''}`);
|
|
434
446
|
}
|
|
435
447
|
}
|
|
448
|
+
ok(`list: ${total} skills (baseline=${groups.baseline.length}, remote=${groups.remote.length}, custom=${groups.custom.length})`);
|
|
436
449
|
}
|
|
437
450
|
|
|
438
451
|
async function runAdd(args) {
|
|
@@ -457,6 +470,7 @@ async function runAdd(args) {
|
|
|
457
470
|
await writeManifest(skillsDir, manifest);
|
|
458
471
|
log(` ✓ pinned ${entry.slug} → .claude/skills/${entry.slug}/SKILL.md`);
|
|
459
472
|
log(' Commit + push to apply on the next PR.');
|
|
473
|
+
ok(`added: .claude/skills/${entry.slug}/SKILL.md`);
|
|
460
474
|
}
|
|
461
475
|
|
|
462
476
|
async function runRemove(args) {
|
|
@@ -468,6 +482,7 @@ async function runRemove(args) {
|
|
|
468
482
|
const skillsDir = join(process.cwd(), '.claude', 'skills');
|
|
469
483
|
const entry = await removeSkill(skillsDir, slug);
|
|
470
484
|
log(` ✓ unpinned ${entry.slug}${entry.kind === 'baseline' ? ' (baseline — returns on next init)' : ''}`);
|
|
485
|
+
ok(`removed: ${entry.slug}${entry.kind === 'baseline' ? ' (baseline)' : ''}`);
|
|
471
486
|
}
|
|
472
487
|
|
|
473
488
|
async function runRefresh(args) {
|
|
@@ -476,6 +491,7 @@ async function runRefresh(args) {
|
|
|
476
491
|
const manifest = await readManifest(skillsDir);
|
|
477
492
|
if (manifest.installed.length === 0) {
|
|
478
493
|
log('No clud-bug-managed specimens found. Run `clud-bug init` first.');
|
|
494
|
+
ok('refreshed: 0 skills installed (run `clud-bug init` first)');
|
|
479
495
|
return;
|
|
480
496
|
}
|
|
481
497
|
|
|
@@ -520,6 +536,7 @@ async function runRefresh(args) {
|
|
|
520
536
|
if (diff.add.length === 0 && diff.remove.length === 0) {
|
|
521
537
|
log('');
|
|
522
538
|
log('Collection in sync with skills.sh — nothing to update.');
|
|
539
|
+
ok(`refreshed: ${diff.unchanged.length} skills in sync, 0 changes`);
|
|
523
540
|
return;
|
|
524
541
|
}
|
|
525
542
|
|
|
@@ -541,6 +558,7 @@ async function runRefresh(args) {
|
|
|
541
558
|
if (diff.add.length) await writeSkills(skillsDir, diff.add, client);
|
|
542
559
|
for (const entry of diff.remove) await removeSkill(skillsDir, entry.slug);
|
|
543
560
|
log(' ✓ collection updated. Commit + push to apply on the next PR.');
|
|
561
|
+
ok(`refreshed: +${diff.add.length} -${diff.remove.length} (${diff.unchanged.length} unchanged)`);
|
|
544
562
|
}
|
|
545
563
|
|
|
546
564
|
async function runEditWorkflow(_args) {
|
|
@@ -557,6 +575,7 @@ async function runEditWorkflow(_args) {
|
|
|
557
575
|
|
|
558
576
|
if (pending.files.length === 0) {
|
|
559
577
|
log('Nothing to commit. Edit your .github/workflows/clud-bug-*.yml file(s) first, then re-run.');
|
|
578
|
+
ok('branch: (none — no pending workflow edits)');
|
|
560
579
|
return;
|
|
561
580
|
}
|
|
562
581
|
if (!pending.allWorkflow) {
|
|
@@ -596,6 +615,7 @@ async function runEditWorkflow(_args) {
|
|
|
596
615
|
log('');
|
|
597
616
|
log('Done. Open the PR:');
|
|
598
617
|
log(` gh pr create --title "Edit clud-bug workflow" --body "Workflow tweak. The clud-bug-review check on this PR will fail with a 401 (Anthropic's self-protection against PRs that modify the reviewer's own workflow); merge once and subsequent PRs work normally."`);
|
|
618
|
+
ok(`branch: ${branch} (${pending.files.length} file${pending.files.length === 1 ? '' : 's'})`);
|
|
599
619
|
}
|
|
600
620
|
|
|
601
621
|
async function runUpdateCmd(_args) {
|
|
@@ -612,6 +632,7 @@ async function runUpdateCmd(_args) {
|
|
|
612
632
|
|
|
613
633
|
if (result.missing === 'init') {
|
|
614
634
|
log(' No clud-bug installation detected. Run `clud-bug init` first.');
|
|
635
|
+
ok('updated: 0 changes (no clud-bug install detected)');
|
|
615
636
|
return;
|
|
616
637
|
}
|
|
617
638
|
|
|
@@ -619,6 +640,7 @@ async function runUpdateCmd(_args) {
|
|
|
619
640
|
|
|
620
641
|
if (result.changed.length === 0 && skipped.length === 0) {
|
|
621
642
|
log(' Already current. Nothing to update.');
|
|
643
|
+
ok(`updated: @v${ourVersion}, 0 changes`);
|
|
622
644
|
return;
|
|
623
645
|
}
|
|
624
646
|
|
|
@@ -639,6 +661,7 @@ async function runUpdateCmd(_args) {
|
|
|
639
661
|
}
|
|
640
662
|
log('');
|
|
641
663
|
log('Commit + push to apply the refreshed kit on the next PR.');
|
|
664
|
+
ok(`updated: @v${ourVersion}, ${result.changed.length} changed, ${result.unchanged.length} unchanged${skipped.length ? `, ${skipped.length} skipped` : ''}`);
|
|
642
665
|
}
|
|
643
666
|
|
|
644
667
|
async function runAudit(args) {
|
|
@@ -670,6 +693,7 @@ async function runAudit(args) {
|
|
|
670
693
|
|
|
671
694
|
if (files.length === 0) {
|
|
672
695
|
log(' Nothing in scope. Try widening --scope or --changed-in.');
|
|
696
|
+
ok(`audit: 0 files in scope`);
|
|
673
697
|
return;
|
|
674
698
|
}
|
|
675
699
|
|
|
@@ -680,12 +704,25 @@ async function runAudit(args) {
|
|
|
680
704
|
log('');
|
|
681
705
|
log('Stub is empty findings — populated by the GitHub Action.');
|
|
682
706
|
log('Run locally without the workflow if you want — Clud Bug review needs the action runner + ANTHROPIC_API_KEY.');
|
|
707
|
+
ok(`audit: ${files.length} file${files.length === 1 ? '' : 's'} surveyed; stub at ${rel(cwd, outPath)}`);
|
|
683
708
|
}
|
|
684
709
|
|
|
685
710
|
function rel(from, to) {
|
|
686
711
|
return to.startsWith(from + '/') ? to.slice(from.length + 1) : to;
|
|
687
712
|
}
|
|
688
|
-
|
|
713
|
+
|
|
714
|
+
// Quiet-mode mechanism (v0.6.7+):
|
|
715
|
+
// - Default: log() emits progress to stdout (today's behavior).
|
|
716
|
+
// - When CLUD_BUG_QUIET=1 OR --quiet/-q is passed: log() is suppressed.
|
|
717
|
+
// ok() ALWAYS emits its single-line summary so agents get positive
|
|
718
|
+
// confirmation with a chainable key-value (commit SHA, file count,
|
|
719
|
+
// branch name) regardless of quiet state.
|
|
720
|
+
// - warn() / die() emit unconditionally — quiet must not silence real
|
|
721
|
+
// problems.
|
|
722
|
+
let QUIET = process.env.CLUD_BUG_QUIET === '1';
|
|
723
|
+
function setQuiet(flag) { QUIET = !!flag; }
|
|
724
|
+
function log(msg) { if (!QUIET) process.stdout.write(msg + '\n'); }
|
|
725
|
+
function ok(msg) { process.stdout.write('ok ' + msg + '\n'); }
|
|
689
726
|
function warn(msg) { process.stderr.write(` ! ${msg}\n`); }
|
|
690
727
|
|
|
691
728
|
main().catch(err => {
|
package/lib/agents-md.js
CHANGED
|
@@ -63,6 +63,10 @@ Read that skill before pushing fixes addressing prior review threads.
|
|
|
63
63
|
Strict mode is ${strictNote}. Toggle via \`.claude/skills/.clud-bug.json\`
|
|
64
64
|
(read from PR **base ref**, so PRs can't disable strict-mode on themselves).
|
|
65
65
|
|
|
66
|
+
For agent invocations of the \`clud-bug\` CLI, prefer \`CLUD_BUG_QUIET=1\`
|
|
67
|
+
(or pass \`--quiet\`) — suppresses progress chatter and emits a single
|
|
68
|
+
\`ok <key-value>\` summary line per command.
|
|
69
|
+
|
|
66
70
|
${versionLine}
|
|
67
71
|
${END_MARKER}`;
|
|
68
72
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "clud-bug",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.7",
|
|
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",
|
|
@@ -79,6 +79,6 @@ jobs:
|
|
|
79
79
|
# Strict-mode gate — composite action; see workflow.yml.tmpl for design notes.
|
|
80
80
|
- name: Strict mode — fail check on critical findings
|
|
81
81
|
if: success()
|
|
82
|
-
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.
|
|
82
|
+
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.7
|
|
83
83
|
with:
|
|
84
84
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -79,6 +79,6 @@ jobs:
|
|
|
79
79
|
# Strict-mode gate — composite action; see workflow.yml.tmpl for design notes.
|
|
80
80
|
- name: Strict mode — fail check on critical findings
|
|
81
81
|
if: success()
|
|
82
|
-
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.
|
|
82
|
+
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.7
|
|
83
83
|
with:
|
|
84
84
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -130,6 +130,6 @@ jobs:
|
|
|
130
130
|
# Letting the action's own failure fail the check is louder and right.
|
|
131
131
|
- name: Strict mode — fail check on critical findings
|
|
132
132
|
if: success()
|
|
133
|
-
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.
|
|
133
|
+
uses: thrillmade/clud-bug/.github/actions/strict-mode-gate@v0.6.7
|
|
134
134
|
with:
|
|
135
135
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|