claudemd-cli 0.69.0 → 0.70.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.
package/README.md CHANGED
@@ -76,7 +76,7 @@ Once installed, hooks run silently in the background. Verbose log: `~/.claude/lo
76
76
  | Trigger | Hook | What happens |
77
77
  |---|---|---|
78
78
  | `git commit` with banned vocab (e.g. `significantly`, `70% faster`, `should work`) | `banned-vocab-check` | Blocks the commit with a message pointing to the §10-V spec rule. |
79
- | Bash command with `rm -rf $VAR` (unvalidated expansion) or unpinned `npx <pkg>` | `pre-bash-safety-check` (v0.5.0+) | Blocks at PreToolUse:Bash per §8 SAFETY. Bypass via `[allow-rm-rf-var]` / `[allow-npx-unpinned]` token in the command, or pin/validate the variable. |
79
+ | Bash command with `rm -rf $VAR` (unvalidated expansion), unpinned `npx <pkg>`, or a fetch piped into an interpreter (`curl … \| sh`) | `pre-bash-safety-check` (v0.5.0+) | Blocks at PreToolUse:Bash per §8 SAFETY. Bypass via `[allow-rm-rf-var]` / `[allow-npx-unpinned]` / `[allow-curl-sh]` token in the command, or pin/validate the variable. |
80
80
  | `git push` while base-branch CI is red | `ship-baseline-check` | Blocks the push (2-second `gh run list` timeout; fail-open if `gh` absent or times out). |
81
81
  | Bash command matching ship/push/deploy/release with an unread matched `MEMORY.md` entry | `memory-read-check` | Blocks the command with a list of memory files to Read first. |
82
82
  | Session end with `~/.claude/tmp/` growth > 20 entries | `residue-audit` | Advisory stderr warning; never blocks. |
@@ -99,22 +99,22 @@ CC runs all configured PreToolUse hooks for `Bash` sequentially in declaration o
99
99
 
100
100
  Per-hook timeout (3-5s in `hooks.json`); timeout = treated as exit 0 (pass) per fail-open contract. Stop / SessionStart / UserPromptSubmit / PostToolUse hooks run all declared hooks regardless (none can block; advisories accumulate). Internal hook errors (missing `jq`, malformed event JSON, unreadable patterns file) fail-open; failures do NOT propagate to subsequent hooks.
101
101
 
102
- **Readonly fast-path** (v0.8.3 introduced opt-in default-OFF; **v0.20.0 promoted to default-ON** via §13.3 advisory→enforce gate): hooks 1, 2, and 4 short-circuit when the command is a definitely-read-only shape (no shell-meta, first token in safe-reader whitelist — `ls`, `cat`, `git log`, `git status`, `git diff`, `git rev-parse`, `pwd`, `echo`, `head`, `tail`, etc.). Hook 3 only fires on `git push` so the fast-path doesn't apply. Opt-out: `export BASH_READONLY_FAST_PATH=0` (or any other value than the literal `0` is treated as ON).
102
+ **Readonly fast-path** (v0.8.3 introduced opt-in default-OFF; **v0.20.0 promoted to default-ON** via §13.3 advisory→enforce gate): all four Bash hooks short-circuit when the command is a definitely-read-only shape (no shell-meta, first token in safe-reader whitelist — `ls`, `cat`, `git log`, `git status`, `git diff`, `git rev-parse`, `pwd`, `echo`, `head`, `tail`, etc.). Opt-out: `export BASH_READONLY_FAST_PATH=0` (or any other value than the literal `0` is treated as ON).
103
103
 
104
104
  ## Commands
105
105
 
106
106
  | Command | Purpose |
107
107
  |---|---|
108
108
  | `/claudemd-install` | Bootstrap the current session right after `/plugin install` (copy spec into `~/.claude/`, write manifest, evict legacy entries). Idempotent. CC does not fire `postInstall`, so without this command `install.js` waits until the next `SessionStart`. |
109
- | `/claudemd-status [--verbose]` | Plugin version + spec version + kill-switch state + logs line count. `--verbose` adds per-hook env-var × event × effective vs persisted state table + 5 escape-token reference. |
109
+ | `/claudemd-status [--verbose]` | Plugin version + spec version + kill-switch state + logs line count. `--verbose` adds per-hook env-var × event × effective vs persisted state table, the sub-feature toggle group, and the escape-token reference. |
110
110
  | `/claudemd-update` | Interactive diff against plugin-shipped spec, then apply-all or cancel (4-file spec set is lockstep — per-file select would dangle §EXT cross-references). |
111
111
  | `/claudemd-refresh` | v0.48.0 — one-shot plugin refresh (marketplace update → uninstall → install via the `claude` CLI). Restart Claude Code afterwards; spec + manifest sync is automatic. Fired by the SessionStart upgrade banner. |
112
112
  | `/claudemd-audit [N]` | Aggregate rule-hits over last N days (default 30). Top banned-vocab patterns, per-hook deny counts. Slash form takes a bare number (`/claudemd-audit 90`); direct script invocation takes `--days=N` (= form only). |
113
113
  | `/claudemd-toggle <hook-name>` | Enable/disable a specific hook by toggling `DISABLE_*_HOOK` in `settings.json` env. |
114
- | `/claudemd-doctor [--prune-backups=N]` | Health checks; optionally prune each backup namespace (`~/.claude/backup-*`, `spec-backup-*`, `handhook-backup-*`) to its N newest. v0.7.1+ also flags rule sections whose bypass:deny ratio > 50% (R-N6 §0.1 demotion candidates). |
114
+ | `/claudemd-doctor [--prune-backups=N]` | Health checks; optionally prune each backup namespace (`~/.claude/backup-*`, `spec-backup-*`, `handhook-backup-*`) to its N newest. Dirs the `backup-namespace-legacy` check reports (pre-0.68.3 spec backups sitting in the personal namespace) are skipped — neither deleted nor counted toward N — and echoed under `pruneSkippedLegacy`. v0.7.1+ also flags rule sections whose bypass:deny ratio > 50% (R-N6 §0.1 demotion candidates). |
115
115
  | `/claudemd-rules [N]` | v0.8.0+ — audit `spec/hard-rules.json` manifest over last N days (default 30 — lowered from 90d in v0.13.1 after the 90d gate was structurally unreachable under typical log retention). Surfaces `demoteCandidates` (hook-enforced rules with 0 hits) and `staleReviews` (rules whose `last_demote_review` is null/old). |
116
116
  | `/claudemd-sparkline [--days=A,B,C]` | v0.8.4+ R-N9 — per-`spec_section` cumulative counts of signal events across 3 windows (default 30/60/90d). Trend arrow compares per-period rate; `(newly active)` / `(silenced)` annotations flag activation/deactivation transitions. Markdown block suitable for CHANGELOG header pre-release. |
117
- | `/claudemd-clean-residue [--apply]` | Dry-run-by-default cleanup of stale `claudemd-sync-*` sentinels and historical `claudemd-(mockgh\|work).*` test sandboxes. |
117
+ | `/claudemd-clean-residue [--apply]` | Dry-run-by-default cleanup across three scopes: `$TMPDIR` (`claudemd-sync-*` / `claudemd-memtags-hay-*` sentinels, historical `claudemd-(mockgh\|work).*` sandboxes), `~/.claude/tmp` tool-exhaust past the §EXT §7-EXT retention window, and the seven ephemeral classes in `~/.claude/.claudemd-state`. Exits 3 if `--apply` leaves targets behind. |
118
118
  | `/claudemd-design-adopt [check\|remove]` | v0.24.0 — for a UI project, generate a thin, fact-based `DESIGN.md` from its real design-token sources (deterministic detector `scripts/design-detect.js`; evidence-gated rules menu; never invents values) and wire a sentinel block into project CLAUDE.md. `check` verifies pointers resolve; `remove` unwires. Always shows the diff and asks before writing. Manual/opt-in — no SessionStart hook, nothing auto-fires. |
119
119
  | `/claudemd-statusline [check\|remove] [--force]` | v0.25.0 — register claudemd's PS1-style statusLine into `~/.claude/settings.json`. Default adopts into an empty slot; `check` reports the current owner with no writes; `remove` restores the prior statusline (or clears the slot) and deletes `~/.claude/claudemd-statusline.sh`; `--force` takes over another provider's slot, saving its command so `remove` can restore it. Always shows the diff and asks before writing. Install-time auto-adopt is empty-slot-only (opt-out: `CLAUDEMD_NO_STATUSLINE=1`). When another composite provider (e.g. code-graph) owns the slot, claudemd registers as a guest so both segments render; `--supersede=<id>` replaces a named provider. |
120
120
  | `/claudemd-uninstall` | Pre-uninstall cleanup: clears manifest + legacy `settings.json` hook entries; add `CLAUDEMD_PURGE=1` to also drop `~/.claude/.claudemd-state/` + the rule-hits log. Run BEFORE `/plugin uninstall claudemd@claudemd` (see [Uninstall](#uninstall)). |
@@ -262,6 +262,7 @@ export CLAUDEMD_PATH2_DRY_RUN=1 # v0.21.1+ — Path 2 observability m
262
262
  | `[skip-memory-check]` | bash command string | `memory-read-check` |
263
263
  | `[allow-rm-rf-var]` | bash command string | `pre-bash-safety-check` (rm-with-var path only) |
264
264
  | `[allow-npx-unpinned]` | bash command string | `pre-bash-safety-check` (unpinned npx path only) |
265
+ | `[allow-curl-sh]` | bash command string | `pre-bash-safety-check` (fetch-into-interpreter path only) |
265
266
 
266
267
  ---
267
268
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claudemd-cli",
3
- "version": "0.69.0",
3
+ "version": "0.70.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": {
@@ -10,7 +10,7 @@
10
10
  "type": "git",
11
11
  "url": "git+https://github.com/sdsrss/claudemd.git"
12
12
  },
13
- "homepage": "https://github.com/sdsrss/claudemd#standalone-cli-v090-r-n7",
13
+ "homepage": "https://github.com/sdsrss/claudemd#standalone-cli",
14
14
  "bugs": "https://github.com/sdsrss/claudemd/issues",
15
15
  "keywords": [
16
16
  "lint",
@@ -41,7 +41,12 @@ export function parsePositiveInt(raw) {
41
41
  if (raw == null) return null;
42
42
  const s = String(raw).trim();
43
43
  // Plain base-10 notation only — rejects hex ('0x1e'), exponential ('1e2'),
44
- // signs, and interior junk that `Number()` would coerce. A trailing-zero
44
+ // signs, and interior junk that `Number()` would coerce. Leading zeros ARE
45
+ // accepted ('007' → 7): the header above cites a `/^[1-9][0-9]*$/` guard as
46
+ // the model, but this pattern is `[0-9]+` and never rejected them
47
+ // (2026-08-29 audit R10-20). Left as-is rather than tightened — '007' is
48
+ // unambiguous base-10 here and no caller distinguishes it — but the comment
49
+ // no longer claims otherwise. A trailing-zero
45
50
  // decimal ('30.0', '30.00') is allowed through the shape gate so the
46
51
  // integer-valued-float check below can accept it (existing contract: callers
47
52
  // / scripts may pass '30.0'); a true fraction ('1.5') passes the shape gate