Repository navigation
Added
-
Claude Code hooks: file-triggered injection, JSONL guard, usage log (mulch-7164):
ml setup claudenow also installs a PreToolUseml hookhandler. On Read/Edit/Write/MultiEdit/NotebookEdit it returns the records anchored to that file asadditionalContext(failures first, ~500-token budget, stale last, each record once per session; silent when nothing is anchored). Write/Edit and best-effort Bash writes to.mulch/expertise/*.jsonlare denied with a pointer toml record/ml edit/ml delete. Each injection appends{ts, session, tool, files, ids}to.mulch/state/usage.jsonl(self-gitignored). Install is idempotent, keeps unrelated hooks, and refuses malformed settings;--removestrips only mulch handlers. -
ml record --descriptionworks for every built-in type (mulch-7164): missing type-specific fields are filled from it (convention content, a derived pattern/reference/guide name, decision title + rationale). Explicit flags win; failures still need--resolution. Derived names end in a 6-char content hash (mulch-9f0f), so distinct records sharing their first six words no longer silently upsert-merge; explicit--namekeeps upsert semantics. -
Write-time quality gate on
ml record(mulch-a378): near-duplicate detection (BM25 shortlist + token-set Jaccard, lower bar when file/dir anchors overlap) blocks records that restate an existing one and prints it with--supersedes <id>/ml edit/ml outcome/--forcesuggestions. Soft checks warn on conventions/patterns with no file/dir anchor or evidence (an auto-populated commit does not count) and on conventions that read like code restatement (theml auditrule-signal heuristic). Newquality.levelconfig knob:warn(default),error(block unless--force),off. -
Git-based staleness:
ml stale+ prime demotion (mulch-094a):ml stale [domains...]lists live records whose file/dir anchors changed in 5+ commits since the record's evidence commit, whose anchors no longer exist, or that are tactical/observational past shelf life with no confirmations (--jsonreturns ids + structured reasons).ml primeranks stale records last within their budget tier and marks them(stale?)in the index (; stale?in the why-surfaced suffix for--full/ xml / plain). Two batched git calls cover all records (git log --name-onlybounded at the oldest record), so the editor-hook path stays fast. Advisory only; nothing is deleted. -
ml show <ids...>(mulch-bffe): prints full record bodies by ID (full id, bare hash, or unique prefix) across every domain;--jsonreturns{ domain, record }pairs. -
ml prime --records-only(mulch-bffe): emits only the record lines (no project contract, quick reference, or session-close footer, and nothing at all when no record matches) for editor hooks such asml prime --files <path> --budget 500 --records-only.
Changed
-
Prime staleness uses anchor evidence only (mulch-7164):
ml primedemotes and marks(stale?)only foranchors_changed/anchors_missing.shelf_life(old, never confirmed) flagged most real corpora and is now reported byml staleonly. -
BREAKING:
ml primedefaults to a record index (mulch-bffe): the default (compact) output is one line per record (id, type, summary truncated to ~100 chars, up to 3 file/dir anchors, ★ score), grouped by domain, with a short quick reference; bodies, links, and why-surfaced suffixes moved behindml show <id>/--full. Ranking is failures first, then confirmation score, classification, and recency; with--files/--context, failures anchored to those paths survive any--budgetand other anchored records outrank unanchored ones. Records superseded by a live record'ssupersedesare hidden. The v0.10 size-based auto-flip to manifest is retired (the budget keeps large corpora small);prime.default_mode: manifestand--manifeststill work.ml query/ml search --format compactshare the index line. The per-typeformatCompactLineregistry hook is removed;formatIndexLine(src/utils/format.ts) renders every type and drives budget estimates. -
Exact duplicates are hard-blocked (mulch-a378): dedup now compares normalized text (case, punctuation, whitespace folded), so trivially reworded copies no longer slip through, and
content_hashcustom types dedup on their normalized body instead of never matching.ml recordexits 1 on an exact duplicate of a convention/failure (previously a successful "skipped"), and--forceno longer re-creates one in any record path; named types still upsert. -
Session-close and onboard prose (mulch-a378): the default session-close footer and the onboard snippet now say "record only what a future agent would get wrong without it", steer toward
failurerecords (symptom -> root cause -> preventive check) andml outcomeconfirmations, and drop the 🚨 banner from every preset. The package description is now plain: "Git-native expertise records for AI agents". -
ml --version --jsonnow emits 2-space-indented JSON (closes mulch-6d8a): the early-exit--version --jsonpath insrc/cli.tspreviously emitted a single-lineJSON.stringify(...)payload while every other--json-mode response in mulch is 2-space-indented viaoutputJson. The output is now formatted withJSON.stringify(..., null, 2)so machine consumers see one consistent JSON shape across the CLI. Fields (name,version,runtime,platform) and values are unchanged; consumers thatJSON.parsethe output are unaffected. -
ml upgrade --jsonkey canonicalized toup_to_date(closes mulch-4ca6): theupgradeJSON output previously emittedupToDate(camelCase) whileml onboard --jsonemitted the same concept as the snake_case action valueup_to_date. Theupgradepayload now usesup_to_dateto match the rest of mulch's snake_case JSON convention (e.g.not_installed,default_mode,extracts_files). Consumers that readparsed.upToDatemust switch toparsed.up_to_date; the boolean semantics are unchanged.