claudemd-cli 0.23.11 → 0.23.13
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/CHANGELOG.md +23 -0
- package/README.md +5 -4
- package/bin/claudemd-lint.js +17 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -8,6 +8,29 @@ All notable changes to the `claudemd` plugin. This changelog tracks plugin artif
|
|
|
8
8
|
- **Canonical spec version source**: `spec/CLAUDE.md` top-line title (`# AI-CODING-SPEC vX.Y.Z — Core`) + `spec/CLAUDE-changelog.md` top `##` entry.
|
|
9
9
|
- **Plugin semver vs spec semver** are independent: plugin patch (0.2.0 → 0.2.1) may ship when spec is unchanged (this release); plugin minor (0.1.9 → 0.2.0) ships when spec minor updates (v0.2.0 shipped spec v6.10.0).
|
|
10
10
|
|
|
11
|
+
## [0.23.13] - 2026-06-10
|
|
12
|
+
|
|
13
|
+
**Patch — 4 bugfixes from a 3-round end-to-end user-test sweep (Stop hooks, standalone CLI, sampling audit).** Spec content (`spec/CLAUDE*.md`) unchanged (stays v6.14.1). Each fix carries a reproduction + regression test; node suite 513 → 515, plus added bash hook regression cases (transcript-structure-scan +3, session-end-check +2); all suites + integration green.
|
|
14
|
+
|
|
15
|
+
### Fixed — §11-session-exit safety net was silently dead in production
|
|
16
|
+
|
|
17
|
+
- `hooks/session-end-check.sh`: the "last user-input message" detector ran `(.message.content // []) | any(.type=="text")`, but a human-typed prompt is **string** content in a CC transcript (only tool_results are arrays). `any()` over a string throws jq `Cannot iterate over string`; the surrounding `2>/dev/null` swallowed it, the filter returned empty, and the hook hit its `[[ -n "$RESULT" ]] || exit 0` guard — a silent no-op. Because every real session has ≥1 string-content prompt in its last 200 transcript lines, the §11 session-exit `paused.md` safety net (a §5.1 Never-downgrade rule) never fired live; the array-only test fixtures masked it. Fix: guard the iterate by content type (string → input; array → check for a text block), matching the `mid-spine-yield-scan.sh` pattern. Verified end-to-end: a string-prompt + Edit + no-validate transcript wrote no `paused.md` pre-fix, writes it post-fix. Added a string-content fixture + 2 regression cases.
|
|
18
|
+
|
|
19
|
+
### Fixed — §10-honesty false positive on 中文 / non-`because` rationale
|
|
20
|
+
|
|
21
|
+
- `hooks/transcript-structure-scan.sh`: the `uncertain-hedge` detector accepted only `because/since/reason:/因为` as rationale connectors, so an Uncertain line written with `由于` / `鉴于` (canonical 中文 equivalents) or English `due to` / `owing to` was flagged as a reasonless hedge though it states a reason. Widened the connector set. Added 3 cases (中文 `由于`, English `due to`, and a still-flagged reasonless line — no false-negative regression).
|
|
22
|
+
|
|
23
|
+
### Fixed — standalone CLI + sampling audit
|
|
24
|
+
|
|
25
|
+
- `bin/claudemd-lint.js` `audit`: a JSON-parseable file that is not a CC transcript (e.g. a `{role,content}` export or coerced log) yielded 0 assistant turns and exited 0 with "OK" — a silent false-pass for CI gates. Now exits 2 when parseable rows carry no `type` field (every real CC row has one; confirmed 0/900+ rows lacking it across 4 transcripts). Added 2 cases (wrong-shape → exit 2; legit transcript with only non-assistant rows → exit 0).
|
|
26
|
+
- `scripts/sampling-audit.js`: `--sample N` used `arr.sort(() => Math.random() - 0.5)`, a non-uniform shuffle (the comparator violates total-order; V8 biases toward input order — the first element stayed at position 0 32% of trials vs 20% uniform), skewing the sample toward whichever transcripts `readdir` lists first. Replaced with a partial Fisher-Yates; inclusion rate is now ~40% per element at sample=2/N=5 (uniform baseline 40%).
|
|
27
|
+
|
|
28
|
+
## [0.23.12] - 2026-06-05
|
|
29
|
+
|
|
30
|
+
**Patch — remove the `memory-coverage-scan` Stop hook (17 → 16 hooks).** The save-side "should-have-saved" advisory shipped default-OFF since v0.13.0 and never earned its keep: 9 advisory events in 30 days, all from a single opt-in repo (this one), against a HARD-blocking read-side already in place. Cutting it resolves the only open item from the 2026-06-03 maturity audit and ends the internal-feature backlog. No spec change (`spec/CLAUDE*.md` stays v6.14.1; the hook was never a `hard-rules.json` rule). Removed: `hooks/memory-coverage-scan.sh` + its test; the `hooks.json` Stop registration; the `hook-registry.js` entry (drops the `MEMORY_COVERAGE` kill-switch + `MEMORY_COVERAGE_SCAN` / `DISABLE_MEMORY_COVERAGE_HOOK` env vars — now no-ops if still set); references in README, ARCHITECTURE.md, RULE-HITS-SCHEMA.md, `claudemd-toggle.md`, `mid-spine-yield-scan.sh` header, and the contract / full-lifecycle / hook-registry / install test count assertions (all moved 17 → 16 together).
|
|
31
|
+
|
|
32
|
+
**Docs (same day, no version bump).** Repositioned the project framing from a general-purpose enforcement product to a *personal AI-coding discipline harness*: a single-maintainer, dogfooded tool encoding one developer's opinionated spec — fork-and-adapt, not turnkey. Touched the README tagline + a new "Status & scope" note and the three manifest descriptions (`plugin.json` + `marketplace.json` ×2; the `v6.14` spec-version token is preserved in all three). No code or version change. This is the closing half of the 2026-06-03 maturity-audit follow-through — the `memory-coverage-scan` cut above ended the internal-feature backlog; this reframe pivots from internal polish to honest external positioning.
|
|
33
|
+
|
|
11
34
|
## [0.23.11] - 2026-06-05
|
|
12
35
|
|
|
13
36
|
**Patch — batched bugfix release from a 5-round end-to-end user-test sweep + an adversarial re-audit.** 39 confirmed bugs fixed across hooks, scripts, and the standalone CLI; spec content (`spec/CLAUDE*.md`) is unchanged (stays v6.14.1). Every fix carries a reproduction + a regression test; suite 484 → 513 node tests + integration, all green. Highlights grouped by class.
|
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# claudemd
|
|
2
2
|
|
|
3
|
-
>
|
|
3
|
+
> A **personal AI-coding discipline harness**: one developer's opinionated **AI-CODING-SPEC v6.14**, encoded as Claude Code shell hooks and shipped with the plugin. Built and dogfooded on my own repos — fork and adapt, don't adopt wholesale.
|
|
4
4
|
|
|
5
5
|
[](https://github.com/sdsrss/claudemd/actions/workflows/ci.yml)
|
|
6
6
|
[](https://www.npmjs.com/package/claudemd-cli)
|
|
@@ -10,6 +10,8 @@ claudemd plugs into the Claude Code hook system to **block commits, pushes, and
|
|
|
10
10
|
|
|
11
11
|
A standalone CLI (`npx claudemd-cli`) reuses the same `banned-vocab.patterns` source for git pre-commit hooks, GitHub Actions, and other agents that don't run inside Claude Code.
|
|
12
12
|
|
|
13
|
+
> **Status & scope.** This is a single-maintainer tool that encodes one developer's working discipline — not a general-purpose product. It's exercised almost entirely on my own repositories, the spec is opinionated, and the defaults reflect my preferences rather than a consensus. If you install it, expect to fork `CLAUDE.md` and tune the rules to your own workflow. Treat it as a reference implementation of "spec-as-enforced-hooks," not a turnkey solution. Issues and PRs are welcome.
|
|
14
|
+
|
|
13
15
|
---
|
|
14
16
|
|
|
15
17
|
## Quick start
|
|
@@ -55,7 +57,7 @@ Verify in one command (Linux): `node --version && jq --version && gh --version &
|
|
|
55
57
|
|
|
56
58
|
| Layer | Contents |
|
|
57
59
|
|---|---|
|
|
58
|
-
|
|
|
60
|
+
| 16 shell hooks | `banned-vocab-check` · `pre-bash-safety-check` · `ship-baseline-check` · `residue-audit` · `memory-read-check` · `memory-prompt-hint` · `mid-spine-yield-scan` · `sandbox-disposal-check` · `session-start-check` · `session-extended-read` · `session-summary` · `session-end-check` · `transcript-vocab-scan` · `transcript-structure-scan` · `version-sync` · `mem-audit` |
|
|
59
61
|
| 13 slash commands | `/claudemd-install` · `/claudemd-status` · `/claudemd-update` · `/claudemd-audit` · `/claudemd-toggle` · `/claudemd-doctor` · `/claudemd-analyze` · `/claudemd-uninstall` · `/claudemd-rules` · `/claudemd-clean-residue` · `/claudemd-sparkline` · `/claudemd-sampling-audit` · `/claudemd-bypass-audit` |
|
|
60
62
|
| 1 standalone CLI | `claudemd-cli lint` · `claudemd-cli audit` ([npm: `claudemd-cli`](https://www.npmjs.com/package/claudemd-cli)) |
|
|
61
63
|
| Spec v6.14 | `~/.claude/CLAUDE.md` · `CLAUDE-extended.md` · `CLAUDE-changelog.md` · `OPERATOR.md` (backup-before-overwrite) |
|
|
@@ -177,7 +179,6 @@ export DISABLE_TRANSCRIPT_STRUCTURE_SCAN_HOOK=1 # v0.9.10+ — Stop §10 four-s
|
|
|
177
179
|
export DISABLE_MEM_AUDIT_HOOK=1 # v0.9.4+ — Stop Why:-less citation advisory
|
|
178
180
|
export DISABLE_SESSION_END_CHECK_HOOK=1 # v0.9.27+ — SessionEnd §11-session-exit mid-SPINE check
|
|
179
181
|
export DISABLE_SESSION_EXTENDED_READ_HOOK=1 # v0.10.1+ — PreToolUse:Read §13.1-extended-read denominator signal
|
|
180
|
-
export DISABLE_MEMORY_COVERAGE_HOOK=1 # v0.13.0+ — Stop §11-mem-coverage advisory (opt-in via MEMORY_COVERAGE_SCAN=1)
|
|
181
182
|
export DISABLE_MID_SPINE_YIELD_HOOK=1 # v0.15.0+ — Stop §11-mid-spine-yield advisory (opt-in via MID_SPINE_YIELD_SCAN=1)
|
|
182
183
|
```
|
|
183
184
|
|
|
@@ -324,7 +325,7 @@ claudemd/
|
|
|
324
325
|
├── .claude-plugin/
|
|
325
326
|
│ ├── plugin.json # minimal manifest (name, version, author, license, keywords)
|
|
326
327
|
│ └── marketplace.json # marketplace catalog entry
|
|
327
|
-
├── hooks/ #
|
|
328
|
+
├── hooks/ # 16 shell hooks + hooks/lib/ (hook-common, rule-hits, platform)
|
|
328
329
|
│ └── hooks.json # authoritative hook registration (v0.1.5+); CC expands ${CLAUDE_PLUGIN_ROOT} here
|
|
329
330
|
├── commands/ # 12 slash-command markdown files
|
|
330
331
|
├── bin/ # standalone CLI entrypoint (claudemd-lint.js → `npx claudemd-cli` on npmjs.org)
|
package/bin/claudemd-lint.js
CHANGED
|
@@ -303,13 +303,29 @@ function auditCmd(rawArgs) {
|
|
|
303
303
|
const nonEmptyLines = jsonl.split('\n').filter(l => l.trim().length > 0);
|
|
304
304
|
if (nonEmptyLines.length > 0) {
|
|
305
305
|
let parsedAny = false;
|
|
306
|
+
let sawTypeField = false;
|
|
306
307
|
for (const l of nonEmptyLines) {
|
|
307
|
-
|
|
308
|
+
let row;
|
|
309
|
+
try { row = JSON.parse(l); } catch { continue; }
|
|
310
|
+
parsedAny = true;
|
|
311
|
+
if (row && typeof row === 'object' && row.type !== undefined) { sawTypeField = true; break; }
|
|
308
312
|
}
|
|
309
313
|
if (!parsedAny) {
|
|
310
314
|
process.stderr.write(`audit: no parseable JSON rows in ${transcriptPath} (expected JSONL transcript with one JSON object per line)\n`);
|
|
311
315
|
process.exit(2);
|
|
312
316
|
}
|
|
317
|
+
// Parseable JSON but NO row carries a `type` field → not a Claude Code
|
|
318
|
+
// transcript (wrong file, other-agent export, or a coerced CSV/log). Every
|
|
319
|
+
// real CC row carries `type` (assistant / user / system / summary / …).
|
|
320
|
+
// Without this, parseTranscript yields 0 turns and audit prints
|
|
321
|
+
// "OK: no §10-V hits across 0 assistant turn(s)" exit 0 — a silent
|
|
322
|
+
// false-pass in CI, same silent-success family as the v0.9.14 / v0.9.21
|
|
323
|
+
// literal-string-scan bugs. A legit transcript whose only rows are
|
|
324
|
+
// non-assistant still has `type`, so it passes this gate and exits 0.
|
|
325
|
+
if (!sawTypeField) {
|
|
326
|
+
process.stderr.write(`audit: ${transcriptPath} parses as JSON but no row has a 'type' field — does not look like a Claude Code transcript (expected rows like {"type":"assistant",...}). Wrong file?\n`);
|
|
327
|
+
process.exit(2);
|
|
328
|
+
}
|
|
313
329
|
}
|
|
314
330
|
|
|
315
331
|
const turns = parseTranscript(jsonl);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claudemd-cli",
|
|
3
|
-
"version": "0.23.
|
|
3
|
+
"version": "0.23.13",
|
|
4
4
|
"description": "Standalone CLI for §10-V banned-vocab + transcript scanning. Companion to the claudemd Claude Code plugin (github.com/sdsrss/claudemd) for use in git pre-commit hooks, GitHub Actions, and other agents.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"bin": {
|