claude-mem-lite 6.29.2 → 6.30.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 (47) hide show
  1. package/.claude-plugin/marketplace.json +1 -1
  2. package/.claude-plugin/plugin.json +1 -1
  3. package/README.md +9 -11
  4. package/README.zh-CN.md +18 -14
  5. package/adopt-cli.mjs +56 -20
  6. package/adopt-content.mjs +1 -2
  7. package/claudemd.mjs +31 -5
  8. package/cli/activity.mjs +3 -2
  9. package/cli/common.mjs +35 -4
  10. package/cli/fts-check.mjs +2 -1
  11. package/cli/verify-apply.mjs +4 -4
  12. package/cli.mjs +5 -1
  13. package/commands/adopt.md +7 -7
  14. package/commands/bug.md +3 -3
  15. package/commands/lesson.md +3 -3
  16. package/commands/mem.md +2 -2
  17. package/commands/unadopt.md +2 -2
  18. package/commands/update.md +2 -2
  19. package/commands/verify.md +2 -4
  20. package/haiku-client.mjs +6 -1
  21. package/hook-context.mjs +2 -2
  22. package/hook-llm.mjs +22 -16
  23. package/hook-optimize.mjs +180 -176
  24. package/hook-shared.mjs +7 -0
  25. package/hook.mjs +18 -11
  26. package/install.mjs +12 -10
  27. package/lib/activity.mjs +1 -1
  28. package/lib/db-unusable.mjs +43 -12
  29. package/lib/edge-attribution.mjs +1 -1
  30. package/lib/get-core.mjs +3 -3
  31. package/lib/local-steering.mjs +14 -3
  32. package/lib/maintain-core.mjs +35 -1
  33. package/lib/project-rekey.mjs +6 -2
  34. package/lib/quiet-scope.mjs +6 -2
  35. package/lib/save-nudge.mjs +6 -3
  36. package/lib/schema-skew.mjs +4 -2
  37. package/lib/startup-dashboard.mjs +3 -2
  38. package/lib/stats-quality.mjs +6 -4
  39. package/lib/upgrade-banner.mjs +2 -1
  40. package/mem-cli.mjs +58 -36
  41. package/memdir.mjs +1 -1
  42. package/npm-shrinkwrap.json +5 -5
  43. package/package.json +1 -1
  44. package/search-scoring.mjs +6 -6
  45. package/secret-scrub.mjs +4 -1
  46. package/server.mjs +24 -9
  47. package/tool-schemas.mjs +2 -2
package/commands/adopt.md CHANGED
@@ -6,10 +6,10 @@ description: "Use when: user asks to put the claude-mem-lite steering block into
6
6
  # /adopt
7
7
 
8
8
  Install the claude-mem-lite **steering block** into the current project's
9
- `CLAUDE.md` (the canonical home for project instructions — loaded by Claude Code
10
- at system-prompt authority). It does not go in the project's memory-dir
11
- `MEMORY.md`: that index belongs to the user's own memories, and it carries no
12
- more weight than `CLAUDE.md`.
9
+ `CLAUDE.md` (the canonical home for project instructions — Claude Code loads it
10
+ into every session, in a message after the system prompt). It does not go
11
+ in the project's memory-dir `MEMORY.md`: that index belongs to the user's own
12
+ memories.
13
13
 
14
14
  Auto-adopt does not add the block to `CLAUDE.md`: in a git repository it keeps the same block
15
15
  in `CLAUDE.local.md` at the repository root, excluded from git through `.git/info/exclude`.
@@ -59,10 +59,10 @@ doc). Other plugins' blocks (e.g. `code-graph-mcp:*`) and your own prose survive
59
59
  - `/unadopt` removes the CLAUDE.md block + `.claude/` detail doc (your prose stays),
60
60
  and the local block. The next session writes a local file if the plugin never
61
61
  created one in this repository; one it created before is not written back (the
62
- text is injected instead) until `claude-mem-lite adopt --enable`. Beside an
62
+ text is injected instead) until `node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" adopt --enable`. Beside an
63
63
  `AGENTS.md` that `CLAUDE.local.md` would switch off, no file is written unless
64
64
  `CLAUDE_MEM_RULES_STEERING=1`.
65
- - `claude-mem-lite adopt --disable` permanently stops auto-adopt for this project
65
+ - `node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" adopt --disable` permanently stops auto-adopt for this project
66
66
  (also for sessions started in its subdirectories) and removes the local block; a
67
67
  `CLAUDE.md` block stays until `/unadopt`.
68
68
  - `MEM_NO_AUTO_ADOPT=1` disables auto-adopt globally; blocks already written stay.
@@ -74,7 +74,7 @@ doc). Other plugins' blocks (e.g. `code-graph-mcp:*`) and your own prose survive
74
74
  Adoption does NOT remove the hook-based injection (SessionStart context,
75
75
  UserPromptSubmit related-memory). Those remain as fallback. Post-adopt the MCP
76
76
  `WHEN TO USE` section + the `File Lessons` / `Key Context` sections auto-trim,
77
- since the CLAUDE.md block already carries the triggers at higher authority.
77
+ since the CLAUDE.md block already carries the triggers.
78
78
 
79
79
  ## Restart caveat for the MCP-instructions trim
80
80
 
package/commands/bug.md CHANGED
@@ -3,7 +3,7 @@ name: bug
3
3
  description: "Use when: logging a known bug + repro steps you can't fix right now. Writes a searchable observation (findable via mem_search + surfaced by recall hooks; still NOT memdir). Skip for bugs you're actively fixing in the current turn — just fix them."
4
4
  ---
5
5
 
6
- # /bug
6
+ # /claude-mem-lite:bug
7
7
 
8
8
  Record a known bug + reproduction steps. Writes a searchable **observation**
9
9
  (`type=bugfix`, description in `lesson_learned`) so future sessions can find it
@@ -59,5 +59,5 @@ Confirm to user with: `Bug logged: #<id>`.
59
59
 
60
60
  ## Examples
61
61
 
62
- - `/bug intermittent test flake when DB is under load --repro "run pnpm test -- --retry=0; fails ~1 in 20 runs when CPU is busy"`.
63
- - `/bug --file src/auth.mjs --severity high "session refresh drops the X-Forwarded-For header"` — no repro steps, just a high-severity note.
62
+ - `/claude-mem-lite:bug intermittent test flake when DB is under load --repro "run pnpm test -- --retry=0; fails ~1 in 20 runs when CPU is busy"`.
63
+ - `/claude-mem-lite:bug --file src/auth.mjs --severity high "session refresh drops the X-Forwarded-For header"` — no repro steps, just a high-severity note.
@@ -8,9 +8,9 @@ description: "Use when: capturing a non-obvious lesson/gotcha/workaround after a
8
8
  Record a lesson / gotcha / workaround. Writes a searchable **observation**
9
9
  (`type=discovery` with the text as `lesson_learned`) so future sessions can
10
10
  find it via `mem_search` and the PreToolUse recall hooks surface it on the
11
- relevant files. Does NOT touch memdir — so lessons never end up in the L1
12
- system-prompt memory section and do not conflict with Claude Code's auto-memory
13
- rules on what not to save there.
11
+ relevant files. Does NOT touch memdir — so lessons never end up in the
12
+ auto-memory index Claude Code loads into every session, and do not conflict with
13
+ Claude Code's auto-memory rules on what not to save there.
14
14
 
15
15
  ## When to use
16
16
 
package/commands/mem.md CHANGED
@@ -30,8 +30,8 @@ When the user invokes `/mem`, parse their intent:
30
30
  - `/mem save <text>` → call `mem_save` MCP tool with the text as content
31
31
  - `/mem stats` → run `node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" stats` via Bash
32
32
  - `/mem get <ids>` → run `node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" get <ids>` via Bash
33
- - `/mem cleanup` → run `node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" maintain scan` via Bash, report pending purge count and stale items to user, ask for confirmation, then run `node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" maintain execute --ops purge_stale --confirm` via Bash if confirmed. **`--confirm` is required and is not optional politeness:** without it the command prints a dry-run PREVIEW and deletes nothing, while still succeeding — so you would report a cleanup that never happened.
34
- - `/mem cleanup Nd` (e.g. `60d`) → same as above but add `--retain-days N` to only purge items older than N days. **`--retain-days` must be between 7 and 365**; the CLI rejects anything outside that range, so `/mem cleanup 3d` cannot be honoured — say so rather than silently substituting the default.
33
+ - `/mem cleanup` → run `node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" maintain scan` via Bash and report the pending purge and stale counts to the user. Then run the purge command below without `--confirm` first: it prints how many rows it would delete and deletes nothing. If that count is 0, tell the user nothing is old enough to purge yet and stop. Otherwise report that count, not the scan's pending count, which includes rows too recent to purge. Ask for confirmation, and if confirmed run `node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" maintain execute --ops purge_stale --confirm` via Bash. **`--confirm` is required and is not optional politeness:** without it the command prints a dry-run PREVIEW and deletes nothing, while still succeeding — so you would report a cleanup that never happened.
34
+ - `/mem cleanup Nd` (e.g. `60d`) → same as above but add `--retain-days N` to both purge runs to only purge items older than N days. **`--retain-days` must be between 7 and 365**; the CLI rejects anything outside that range, so `/mem cleanup 3d` cannot be honoured — say so rather than silently substituting the default.
35
35
  - `/mem cleanup keep Nd` (e.g. `keep 14d`) → same as above with `--retain-days N`, same 7–365 range.
36
36
  - `/mem <query>` (no subcommand) → treat as search, run `node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" search <query>` via Bash
37
37
 
@@ -43,10 +43,10 @@ project (slug-scoped — other plugins' blocks survive).
43
43
 
44
44
  `/unadopt` removes files, not the steering. A local block the plugin created is not
45
45
  written back; the text is added to each session's context instead
46
- (`claude-mem-lite adopt --enable` lets it write the file again). A project whose
46
+ (`node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" adopt --enable` lets it write the file again). A project whose
47
47
  `CLAUDE.md` block you removed gets a local file on the next session, unless the
48
48
  plugin created one there before. Beside an `AGENTS.md` that `CLAUDE.local.md` would
49
- switch off, no file is written unless `CLAUDE_MEM_RULES_STEERING=1`. To stop the steering: `claude-mem-lite adopt --disable`
49
+ switch off, no file is written unless `CLAUDE_MEM_RULES_STEERING=1`. To stop the steering: `node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" adopt --disable`
50
50
  (per project) or `MEM_NO_AUTO_ADOPT=1` (global).
51
51
 
52
52
  ## Aftermath
@@ -22,9 +22,9 @@ Run each command below via Bash; the CLI reaches the maintenance operations whet
22
22
 
23
23
  1. Run `node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" maintain scan` to analyze maintenance candidates
24
24
  2. Report scan results to the user (duplicates, stale items, broken items, boostable items, **pending purge** items)
25
- 3. **If pending purge items > 0**: first run the purge command below without `--confirm`: it prints how many rows it would delete and deletes nothing. Report that count to the user and ask for confirmation. If confirmed, run `node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" maintain execute --ops purge_stale --confirm`. **`--confirm` is required:** without it the command prints a dry-run preview and deletes nothing while still succeeding, so you would report a purge that never happened. User may optionally add `--retain-days N` (default 30, allowed range 7–365) to both runs to control how many days of data to keep; the CLI rejects a value outside that range, so tell the user instead of substituting the default. Do NOT purge without explicit user confirmation. The purge comes before the next step on purpose: decay there queues more rows for purge, and those wait for a later run, so what gets deleted is what the user approved.
25
+ 3. **If pending purge items > 0**: first run the purge command below without `--confirm`: it prints how many rows it would delete and deletes nothing. If that count is 0, tell the user nothing is old enough to purge yet and go on to the next step. Otherwise report that count to the user and ask for confirmation. If confirmed, run `node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" maintain execute --ops purge_stale --confirm`. **`--confirm` is required:** without it the command prints a dry-run preview and deletes nothing while still succeeding, so you would report a purge that never happened. User may optionally add `--retain-days N` (default 30, allowed range 7–365) to both runs to control how many days of data to keep; the CLI rejects a value outside that range, so tell the user instead of substituting the default. Do NOT purge without explicit user confirmation. The purge comes before the next step on purpose: decay there queues more rows for purge, and those wait for a later run instead of joining the purge the user approved.
26
26
  4. Run `node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" maintain execute` to apply safe automatic changes — with no `--ops` it runs the default set: cleanup, decay, boost, then demote_pinned (left out when `CLAUDE_MEM_SKIP_DEMOTE_PINNED=1`)
27
- 5. If duplicates were found in scan, review them and run `node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" maintain execute --ops dedup --merge-ids keepId:removeId,...` — keep the more important/recent observation in each pair. Groups are comma-separated and the first id in each is kept (`10:11,20:21:22`). For pairs similar enough to merge without review the scan prints a ready-made list after `--merge-ids`; pass it to the command above, since the command the scan prints uses a bare `claude-mem-lite`, which may not be installed
27
+ 5. If duplicates were found in scan, review them and run `node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" maintain execute --ops dedup --merge-ids keepId:removeId,...` — keep the more important/recent observation in each pair. Groups are comma-separated and the first id in each is kept (`10:11,20:21:22`). For pairs similar enough to merge without review the scan prints a ready-to-run command after `Ready-to-use:`; run it as printed. Judge each pair under `Needs review:` from the two lines the scan prints below it; do not read them with `get`: that counts as an access and can raise a row's importance
28
28
  6. Run `node "${CLAUDE_PLUGIN_ROOT}/cli.mjs" compress --execute` for old low-value observations (without `--execute` it only previews)
29
29
 
30
30
  ### Phase 2: Summary
@@ -1,9 +1,9 @@
1
1
  ---
2
2
  name: verify
3
- description: "Use when: the user explicitly asks to verify, audit or correct their stored memories against the current code (e.g. \"check my memories for stale ones\", /verify). You check each memory with read-only repo tools and propose corrections; nothing is written until the user approves the exact plan. Not for routine recall or saving."
3
+ description: "Use when: the user explicitly asks to verify, audit or correct their stored memories against the current code (e.g. \"check my memories for stale ones\", /claude-mem-lite:verify). You check each memory with read-only repo tools and propose corrections; nothing is written until the user approves the exact plan. Not for routine recall or saving."
4
4
  ---
5
5
 
6
- # /verify — check memories against the code, then correct the stale ones
6
+ # /claude-mem-lite:verify — check memories against the code, then correct the stale ones
7
7
 
8
8
  Memories go stale: a bug recorded as open gets fixed, a measurement gets retracted, a
9
9
  mechanism is replaced. Measured on 118 live memories across 7 repos, ~10% were STALE and
@@ -12,8 +12,6 @@ this — cheap single-shot models misjudged it (precision 0.36) and model-writte
12
12
  were false in 28 of 72 cases. What works is YOU reading the code: you propose, the user
13
13
  approves the exact plan, and `verify-apply` is the only thing that writes.
14
14
 
15
- (If another plugin also defines `/verify`, this one is `/claude-mem-lite:verify`.)
16
-
17
15
  ## Arguments
18
16
 
19
17
  - `--from <YYYY-MM-DD>`: only memories saved on or after this date (default: all live).
package/haiku-client.mjs CHANGED
@@ -832,7 +832,11 @@ function claudeArgs(modelName) {
832
832
  * their output tokens and latency (measured above, 2026-09-29; the model the CLI ran then was
833
833
  * not recorded). Claude Code 2.1.301 does not change its request for Claude Haiku 5.5 on this
834
834
  * variable: the body carries adaptive thinking either way (D#334). Earlier versions were not
835
- * checked.
835
+ * checked. CLAUDE_CODE_DISABLE_AUTO_MEMORY=1 drops Claude Code's auto-memory section, about 2.2 KB
836
+ * of every system prompt that tells the model about a memory directory these calls never use
837
+ * (stub-probed on 2.1.304: system 8,964 -> 6,688 B). The 2026-10-20 A/B on the cli leg, gate set
838
+ * before the run (D#483): usable 8/8, 8/8, 7/8 against the same without it; kept lessons 3 vs 4
839
+ * at n=8, inside floor(0.9 x 4).
836
840
  */
837
841
  function cliSpawnEnv() {
838
842
  return {
@@ -840,6 +844,7 @@ function cliSpawnEnv() {
840
844
  CLAUDE_MEM_HOOK_RUNNING: '1',
841
845
  DISABLE_CLAUDEMD_HOOKS: '1',
842
846
  MAX_THINKING_TOKENS: '0',
847
+ CLAUDE_CODE_DISABLE_AUTO_MEMORY: '1',
843
848
  };
844
849
  }
845
850
 
package/hook-context.mjs CHANGED
@@ -690,8 +690,8 @@ export function buildSessionContextLines(
690
690
 
691
691
  // Phase A (QUIET_HOOKS) + Phase D (adopted sentinel): drop descriptive
692
692
  // File Lessons / Key Context sections when the user has opted into low-noise
693
- // hooks OR adopted invited-memory (MEMORY.md sentinel carries the triggers
694
- // at higher system-prompt authority). The Recent table still fires so #IDs
693
+ // hooks OR adopted invited-memory (the steering block carries the triggers
694
+ // in the project's instructions). The Recent table still fires so #IDs
695
695
  // remain reachable via mem_get. The collector sees only rows that survive
696
696
  // BOTH the quiet gate and the per-section slice — rendered rows, nothing else.
697
697
  const quiet = effectiveQuiet();
package/hook-llm.mjs CHANGED
@@ -93,15 +93,19 @@ export function retractPreSavedObs(db, obsId, where) {
93
93
  // Both statements run in one transaction so a crash between them cannot leave that state
94
94
  // either; nesting under persistHaikuSummary's transaction is safe (better-sqlite3 uses
95
95
  // savepoints).
96
- return db.transaction(() => {
97
- const live = db.prepare(`SELECT 1 FROM observations WHERE id = ? AND ${liveObsFilterSql('')}`).get(obsId);
98
- if (!live) {
99
- debugLog('DEBUG', 'llm-episode', `${where}: pre-saved obs #${obsId} no longer live — left in place`);
100
- return false;
101
- }
102
- recoverChildrenOf(db, [obsId]);
103
- return db.prepare('DELETE FROM observations WHERE id = ?').run(obsId).changes > 0;
104
- })();
96
+ return db
97
+ .transaction(() => {
98
+ const live = db
99
+ .prepare(`SELECT 1 FROM observations WHERE id = ? AND ${liveObsFilterSql('')}`)
100
+ .get(obsId);
101
+ if (!live) {
102
+ debugLog('DEBUG', 'llm-episode', `${where}: pre-saved obs #${obsId} no longer live — left in place`);
103
+ return false;
104
+ }
105
+ recoverChildrenOf(db, [obsId]);
106
+ return db.prepare('DELETE FROM observations WHERE id = ?').run(obsId).changes > 0;
107
+ })
108
+ .immediate();
105
109
  }
106
110
  // T9: memdir-incompatible types live in the `events` table, not `observations`.
107
111
  // Set lookup is O(1) — authoritative source is lib/activity.mjs::EVENT_TYPES.
@@ -544,13 +548,15 @@ export function persistHaikuSummary(db, summary, ctx) {
544
548
  });
545
549
 
546
550
  if (ctx.preSavedObsId) {
547
- const id = db.transaction(() => {
548
- // Same live-row guard as the in-place upgrade (FLOW-7); the event gets written
549
- // either way. Shared helper since audit 2026-09-02 P0-6 — this was the only one
550
- // of the three retraction sites that carried the guard.
551
- retractPreSavedObs(db, ctx.preSavedObsId, 'upgrade-delete');
552
- return insertEvent();
553
- })();
551
+ const id = db
552
+ .transaction(() => {
553
+ // Same live-row guard as the in-place upgrade (FLOW-7); the event gets written
554
+ // either way. Shared helper since audit 2026-09-02 P0-6 — this was the only one
555
+ // of the three retraction sites that carried the guard.
556
+ retractPreSavedObs(db, ctx.preSavedObsId, 'upgrade-delete');
557
+ return insertEvent();
558
+ })
559
+ .immediate();
554
560
  return { table: 'events', id };
555
561
  }
556
562