claudemd-cli 0.104.1 → 0.106.0

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.
Files changed (2) hide show
  1. package/README.md +10 -4
  2. package/package.json +1 -1
package/README.md CHANGED
@@ -57,7 +57,7 @@ Verify in one command (Linux): `node --version && jq --version && gh --version &
57
57
 
58
58
  | Layer | Contents |
59
59
  |---|---|
60
- | 24 shell hooks | `banned-vocab-check` · `pre-bash-safety-check` · `ship-baseline-check` · `residue-audit` · `memory-read-check` · `memory-prompt-hint` · `spec-module-inject` · `spec-module-gate` · `sandbox-disposal-check` · `session-start-check` · `session-extended-read` · `session-summary` · `session-end-check` · `transcript-vocab-scan` · `rework-breaker` · `cross-repo-write-check` · `tmp-sweep` · `branch-prune` · `evidence-gate` · `ledger-staleness` · `reply-language-check` · `transcript-structure-scan` · `version-sync` · `mem-audit` |
60
+ | 27 shell hooks | `banned-vocab-check` · `pre-bash-safety-check` · `ship-baseline-check` · `residue-audit` · `memory-read-check` · `memory-prompt-hint` · `spec-module-inject` · `deferred-notice` · `spec-module-gate` · `sandbox-disposal-check` · `session-start-check` · `session-extended-read` · `session-summary` · `session-end-check` · `transcript-vocab-scan` · `rework-breaker` · `test-failure-debug` · `cross-repo-write-check` · `tmp-sweep` · `branch-prune` · `verify-log` · `evidence-gate` · `ledger-staleness` · `reply-language-check` · `transcript-structure-scan` · `version-sync` · `mem-audit` |
61
61
  | 16 slash commands | `/claudemd-install` · `/claudemd-status` · `/claudemd-update` · `/claudemd-refresh` · `/claudemd-audit` · `/claudemd-toggle` · `/claudemd-doctor` · `/claudemd-analyze` · `/claudemd-uninstall` · `/claudemd-rules` · `/claudemd-clean-residue` · `/claudemd-sparkline` · `/claudemd-sampling-audit` · `/claudemd-bypass-audit` · `/claudemd-design-adopt` · `/claudemd-statusline` |
62
62
  | 1 standalone CLI | `claudemd-cli lint` · `claudemd-cli audit` ([npm: `claudemd-cli`](https://www.npmjs.com/package/claudemd-cli)) |
63
63
  | Spec v7.1 | `~/.claude/CLAUDE.md` · `CLAUDE-extended.md` · `CLAUDE-changelog.md` · `OPERATOR.md` (backup-before-overwrite) · `spec-modules/*.md` (mirrored from the plugin) |
@@ -86,13 +86,16 @@ Once installed, hooks run silently in the background. Verbose log: `~/.claude/lo
86
86
  | New session start with GitHub remote tag newer than local cache max version | `session-start-check` (v0.4.0+) | Shows an "upgrade available" notice to the user via `systemMessage`. Rate-limited to once per 24h via `~/.claude/.claudemd-state/upstream-check.lastrun` sentinel. 3-second `git ls-remote` timeout, fail-open. |
87
87
  | New session start with a `~/.claude/CLAUDE*.md` / `OPERATOR.md` that is edited, or **missing** | `session-start-check` (v0.84.0+ for the missing half) | Two banners, because the fixes differ: an edited file says `/claudemd-update`, a deleted one says `/claudemd-install`. A deleted spec is the louder case — Claude Code reads these as your user-global instructions, so its absence silently unloads the spec. Silence both with `DISABLE_SPEC_DRIFT_BANNER=1`. |
88
88
  | New session start with a `~/.claude/.claudemd-manifest.json` that exists but does not parse | `session-start-check` (v0.84.0+) | Re-runs the bootstrap, which rewrites the manifest atomically. Previously this state exited silently on every session, forever. |
89
- | `UserPromptSubmit` whose text matches a spec module's `triggers:` (a module not yet injected this session) | `spec-module-inject` (v0.101.0+) | Adds the module's body from `~/.claude/spec-modules/` as context: at most two modules per prompt, `ship` first, each once per session and again after a compaction. On by default; `DISABLE_SPEC_MODULE_INJECT_HOOK=1` turns it off. |
89
+ | `UserPromptSubmit` whose text matches a spec module's `triggers:` (a module not yet injected this session) | `spec-module-inject` (v0.101.0+) | Adds the module's body from `~/.claude/spec-modules/` as context: at most two modules per prompt, `ship` first, each once per session and again after a compaction. A second module that would take the text past a 9,800-character budget, kept under Claude Code's 10,000-character context cap, waits for a later prompt from a person. On by default; `DISABLE_SPEC_MODULE_INJECT_HOOK=1` turns it off. |
90
+ | `UserPromptSubmit` when a Stop hook left an observation for this session (today only `evidence-gate`) | `deferred-notice` (v0.105.0+) | Adds the observation to the model's context with the next prompt, once, capped at 2,000 bytes. Delivering at the next prompt instead of from the Stop hook costs no extra model turn. Nothing to do unless a notice is queued, and `evidence-gate` queues one only when opted in twice (Opt-in: `EVIDENCE_GATE_DELIVER=1` on top of `EVIDENCE_GATE=1`, default OFF), because its verdict has not passed the 0.8 precision gate the G1b pre-registration sets for any channel into the model. |
90
91
  | Bash release command (`git tag v1.2.3`, `git push --tags`, `gh release create`, `npm publish`) in a session that never received `ship.md` | `spec-module-gate` (v0.101.0+) | Default `log`: one `module-unread` rule-hits row, no output. `SPEC_MODULE_GATE=advisory` adds a note; `deny` refuses the command; `off` or `DISABLE_SPEC_MODULE_GATE_HOOK=1` silences it. |
91
92
  | First `UserPromptSubmit` after a mid-session `/plugin install` upgrade | `version-sync` (v0.3.1+) | Backgrounds `install.js` once per session when the manifest version diverges from the active plugin's `package.json`. Sentinel-gated; fail-open. |
92
- | Session stop with a completion claim in the last assistant message and no verification output behind it | `evidence-gate` (v0.90.0+) | Stop advisory — judges the TRANSCRIPT (is there a non-error Bash result after the last code edit whose command names a runner, or whose output looks like one) rather than the prose, which is what the prose-reading detector closed in the 2026-07-24 labeling pass, one of six closed there at a pooled precision bound of 0.17 were doing. Opt-in (`EVIDENCE_GATE=1`, default OFF) for FP signal collection. |
93
+ | Session stop with a completion claim in the last assistant message and no verification output behind it | `evidence-gate` (v0.90.0+) | Stop advisory — judges the TRANSCRIPT (is there a non-error Bash result after the last code edit whose command names a runner, or whose output looks like one) rather than the prose, which is what the prose-reading detector closed in the 2026-07-24 labeling pass, one of six closed there at a pooled precision bound of 0.17 were doing. Opt-in (`EVIDENCE_GATE=1`, default OFF) for FP signal collection; with `EVIDENCE_GATE_DELIVER=1` as well (v0.105.0+), `deferred-notice` also hands the model a short version with the next prompt. |
93
94
  | Session stop after code edits, with a long-task ledger under `cwd` that nothing wrote to | `ledger-staleness` (v0.91.0+) | Stop advisory — the third G7 arm, beside the `SessionStart` re-injection. Both halves are transcript structure over the same tail window: a code-file `Edit`/`Write` in it, and no `Edit`/`Write` on the resolved `tasks/<slug>-ledger.md` in it. The window is a staleness threshold rather than a scanning budget, so a ledger written more than a window ago reads as behind. No ledger means the convention is not in use in this project; a ledger older than `CLAUDEMD_LEDGER_MAX_AGE_DAYS` (default 14) means a finished task. Either way it stays silent — and the age bound is skipped rather than guessed if `hooks/lib/platform.sh` is unavailable, so on that path an old ledger can still draw the advisory. Opt-in (`LEDGER_STALENESS=1`, default OFF) for FP signal collection. |
94
95
  | Session stop whose last reply is English while the human writes 中文 | `reply-language-check` (v0.96.0+) | Stop, returning `{"decision":"block"}` (as `sandbox-disposal-check` does under its opt-in): the turn continues for one more message, asking for the same content in 中文 (no new work, no tools); the English text already shown stays. The human's language comes from the human's own messages only — task notifications, teammate messages, meta rows and tool results never count; a slash command counts by its arguments; a message typed mid-turn counts. The majority language of the human's newest 20 messages decides, so one pasted English log does not flip a 中文 session. What the human says about language is not parsed: a 中文 request for English replies, a translation or an `英文版` still gets a 中文 restatement — turn the hook off or set it to `log` for that. A reply whose first line is a conventional-commit subject is not judged. Headless `claude -p` runs are skipped, and it asks at most once per turn (`stop_hook_active`). Opt-in: `REPLY_LANGUAGE_CHECK=1`, or `=log` to record without asking; default OFF. |
95
96
  | `PostToolUse` on `Edit`/`Write`/`Bash`, at each 8th edit of one file in one session (a Bash command counts once per code file its `bashEditDiff` lists; one changing more than 20 is skipped as bulk, v0.99.0+) | `rework-breaker` (v0.90.0+) | Advisory; injects one line naming the count (§1 Root cause over patch). Opt-in (`REWORK_BREAKER=1`, default OFF) for FP signal collection — a large legitimate refactor looks identical from here. |
97
+ | `PostToolUse` on `Bash`, when a verification command succeeds (a smoke entry, a test / typecheck / lint / build runner, or runner output) | `verify-log` (v0.105.0+) | Log only: records the working-tree content fingerprint the command ran on, and `evidence-gate` records the fingerprint at each completion claim, for an offline comparison (`scripts/offline-eval/wtree-verdicts.mjs`). Opt-in (`EVIDENCE_WTREE=1`, with `EVIDENCE_GATE=1` for the claim side). A run whose output reports failures is not logged, since a runner piped into `tail` exits 0 when it fails. The fingerprint stages the tree into a temporary index, so modified and untracked, non-ignored file contents (and tree objects) enter `.git/objects` as unreachable objects until `git gc` prunes them, by default after two weeks. |
98
+ | `PostToolUseFailure` on `Bash`, when a test runner (`npm test`, `pytest`, `node --test`, `bash tests/…`, …) exits non-zero and `debug.md` is not yet in this session (a runner piped into `tail` exits 0 when it fails, and is not seen) | `test-failure-debug` (v0.105.0+) | Adds the `debug` spec module as context, once per session, shared with `spec-module-inject`'s once-per-session list. Opt-in (`DEBUG_ON_TEST_FAILURE=1`, default OFF). |
96
99
  | `PreToolUse` on `Edit`/`Write`/`NotebookEdit`/`Bash`, when the target is a git repo other than the session's project | `cross-repo-write-check` (v0.95.0+) | Advisory, never a verdict; injects one line per target repo per session: stop and ask unless the user asked for that repo, and use `git worktree add` rather than switching branches in its shared tree. Bash side sees git writes after a literal `cd` or `git -C` only. Opt-in (`CROSS_REPO_WRITE=1`, default OFF); `CROSS_REPO_WRITE_ALLOW` takes colon-separated absolute repo roots (a leading `~/` or `$HOME/` is expanded). |
97
100
  | `PostToolUse` on any `Bash` call, at most once per 10 min | `tmp-sweep` (v0.93.0+) | Deletes, detached, the per-run dirs vitest leaves in the temp root and never removes (`<tmp>/<21-char id>/ssr/<sha1>`, 13-45 MB each; on a tmpfs `/tmp` that is RAM). Only the exact vitest signature, only when idle 60 min (24 h while a vitest watcher runs), across `$TMPDIR`, `/tmp` and `~/.cache/tmp`. Also injects one line when the temp root (`$TMPDIR`, else `/tmp`) is ≥ 80% full. Parallel Bash calls claim the slot atomically, so one sweep runs (a few can overlap only while a lock left by a killed hook is being cleared). **On by default.** |
98
101
  | `PostToolUse` after `git merge` / `pull` / `fetch` / `push` or `gh pr merge` | `branch-prune` (v0.93.0+) | Advisory. Lists the local branches whose remote branch was deleted (`[gone]`) and whose tip is on the default branch, plus `worktree-agent-*` branches on it, with the `git branch -d` command that deletes them; git re-checks merged-ness and use at the moment of deletion. Never lists the default branch, a worktree checkout or a symbolic ref, nor (`worktree-agent-*` aside) a branch whose upstream still exists or one with no upstream. Deletes nothing. Local git only. **On by default.** |
@@ -200,6 +203,9 @@ export DISABLE_SESSION_SUMMARY_HOOK=1 # v0.8.0+ — Stop hook writing
200
203
  export DISABLE_USER_PROMPT_SUBMIT_HOOK=1 # version-sync (mid-session upgrade re-install)
201
204
  export DISABLE_TRANSCRIPT_VOCAB_SCAN_HOOK=1 # PostToolUse §10-V advisory scan
202
205
  export DISABLE_REWORK_BREAKER_HOOK=1 # v0.90.0+ — PostToolUse:Edit|Write|Bash G2 rework advisory (§1 root-cause; opt-in REWORK_BREAKER=1)
206
+ export DISABLE_DEFERRED_NOTICE_HOOK=1 # v0.105.0+ — UserPromptSubmit delivery of observations a Stop hook queued (evidence-gate under EVIDENCE_GATE=1 + EVIDENCE_GATE_DELIVER=1)
207
+ export DISABLE_VERIFY_LOG_HOOK=1 # v0.105.0+ — PostToolUse:Bash working-tree fingerprint log for verification runs (opt-in EVIDENCE_WTREE=1)
208
+ export DISABLE_TEST_FAILURE_DEBUG_HOOK=1 # v0.105.0+ — PostToolUseFailure:Bash debug.md on a failing test run (opt-in DEBUG_ON_TEST_FAILURE=1)
203
209
  export DISABLE_CROSS_REPO_WRITE_HOOK=1 # v0.95.0+ — PreToolUse cross-repo write advisory (§5 scope; opt-in CROSS_REPO_WRITE=1)
204
210
  export DISABLE_TMP_SWEEP_HOOK=1 # v0.93.0+ — PostToolUse:Bash vitest tmp-dir sweep + temp-root pressure advisory
205
211
  export DISABLE_BRANCH_PRUNE_HOOK=1 # v0.93.0+ — PostToolUse:Bash hint listing local branches that are merged and whose remote branch is gone
@@ -438,7 +444,7 @@ claudemd/
438
444
  ├── .claude-plugin/
439
445
  │ ├── plugin.json # minimal manifest (name, version, author, license, keywords)
440
446
  │ └── marketplace.json # marketplace catalog entry
441
- ├── hooks/ # 24 shell hooks + hooks/lib/ (hook-common, rule-hits, platform, memory-tags)
447
+ ├── hooks/ # 27 shell hooks + hooks/lib/ (hook-common, rule-hits, platform, memory-tags, spec-module, verify-cmd, wtree)
442
448
  │ └── hooks.json # authoritative hook registration (v0.1.5+); CC expands ${CLAUDE_PLUGIN_ROOT} here
443
449
  ├── commands/ # 16 slash-command markdown files
444
450
  ├── bin/ # standalone CLI entrypoint (claudemd-lint.js → `npx claudemd-cli` on npmjs.org)
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudemd-cli",
3
- "version": "0.104.1",
3
+ "version": "0.106.0",
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": {