claude-mem-lite 2.32.2 → 2.32.4

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.
@@ -10,7 +10,7 @@
10
10
  "plugins": [
11
11
  {
12
12
  "name": "claude-mem-lite",
13
- "version": "2.32.2",
13
+ "version": "2.32.4",
14
14
  "source": "./",
15
15
  "description": "Lightweight persistent memory system for Claude Code — FTS5 search, episode batching, error-triggered recall"
16
16
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-mem-lite",
3
- "version": "2.32.2",
3
+ "version": "2.32.4",
4
4
  "description": "Lightweight persistent memory system for Claude Code — FTS5 search, episode batching, error-triggered recall",
5
5
  "author": {
6
6
  "name": "sdsrss"
package/README.md CHANGED
@@ -279,6 +279,15 @@ Slash commands `/adopt` and `/unadopt` wrap the same CLI.
279
279
  / `Key Context` sections. `#ID` references and the `Recent` table still fire
280
280
  so `mem_get` remains reachable.
281
281
 
282
+ **When does it take effect?**
283
+ - The MEMORY.md sentinel and the hook-layer trim (`File Lessons` / `Key Context` /
284
+ lesson suffix) apply on the **next SessionStart** (any new Claude Code session
285
+ in the adopted project).
286
+ - The MCP server instructions are built once at server boot and MCP has no
287
+ "push" protocol — the `WHEN TO USE` / `Decision rules` trim only applies
288
+ after Claude Code restarts and re-spawns the mem MCP server. A single
289
+ `/exit` + fresh session is enough. Same caveat applies to `unadopt`.
290
+
282
291
  **Safety:**
283
292
  - Hash-guarded: editing the sentinel body yourself blocks automatic rewrites
284
293
  unless you pass `--force`.
package/README.zh-CN.md CHANGED
@@ -264,6 +264,14 @@ Slash 命令 `/adopt` 和 `/unadopt` 是上述 CLI 的包装。
264
264
  SessionStart 注入去掉 `File Lessons` / `Key Context`。`#ID` 引用与 `Recent`
265
265
  表保留,`mem_get` 仍可随时展开。
266
266
 
267
+ **什么时候生效?**
268
+ - MEMORY.md sentinel 和 hook 层瘦身(`File Lessons` / `Key Context` / lesson
269
+ 后缀)**下一次 SessionStart** 生效(adopt 的项目下任一新会话)。
270
+ - MCP server instructions 是**服务启动时构建一次**,MCP 协议无 "push" 机制,
271
+ 所以 `WHEN TO USE` / `Decision rules` 两段的瘦身**只在 Claude Code 重启后**
272
+ 才生效(mem MCP 服务被重新 spawn)。`/exit` 一次再开新会话即可。`unadopt`
273
+ 同理。
274
+
267
275
  **安全性:**
268
276
  - Hash 守护:你手动改了 sentinel 段 → 下一次 adopt 报 `UserEditedError`,
269
277
  除非显式 `--force`。
package/cli.mjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const CLI_COMMANDS = new Set(['search', 'recent', 'recall', 'get', 'timeline', 'save', 'stats', 'context', 'browse', 'delete', 'update', 'export', 'compress', 'maintain', 'optimize', 'fts-check', 'registry', 'import', 'enrich', 'activity', 'help']);
2
+ const CLI_COMMANDS = new Set(['search', 'recent', 'recall', 'get', 'timeline', 'save', 'stats', 'context', 'browse', 'delete', 'update', 'export', 'compress', 'maintain', 'optimize', 'fts-check', 'registry', 'import', 'enrich', 'activity', 'adopt', 'unadopt', 'help']);
3
3
  const INSTALL_COMMANDS = new Set(['install', 'uninstall', 'status', 'doctor', 'cleanup', 'cleanup-hooks', 'self-update', 'release']);
4
4
 
5
5
  const cmd = process.argv[2];
package/commands/adopt.md CHANGED
@@ -41,4 +41,20 @@ Code versions. Post-adopt the MCP `WHEN TO USE` section + the `File Lessons` /
41
41
  `Key Context` sections auto-trim since the sentinel line already carries the
42
42
  triggers at higher authority.
43
43
 
44
+ ## Restart required for MCP trim to take effect
45
+
46
+ The MCP server builds its instructions once at server boot and the protocol
47
+ has no way to push updated instructions to an already-connected Claude Code
48
+ session. After running `adopt`:
49
+
50
+ - The **MEMORY.md sentinel** appears on the **next SessionStart** automatically.
51
+ - Hook-layer trim (`File Lessons` / `Key Context` / lesson suffix) applies
52
+ on the next SessionStart.
53
+ - MCP-instructions trim (`WHEN TO USE` / `Decision rules` sections) only
54
+ takes effect after Claude Code itself restarts (or at least re-attaches
55
+ the mem MCP server). If you still see the verbose MCP instructions after
56
+ adopt, a `/exit` + fresh session is enough.
57
+
58
+ Same caveat applies in reverse for `/unadopt`.
59
+
44
60
  !claude-mem-lite adopt $ARGUMENTS
package/memdir.mjs CHANGED
@@ -17,6 +17,18 @@ import { createHash } from 'crypto';
17
17
  const MEMORY_LINE_BUDGET = 180;
18
18
  const SECTION_HEADER = '## 插件契约';
19
19
 
20
+ /**
21
+ * POSIX-accurate line count. `str.split('\n').length` overcounts by 1 when the
22
+ * file ends with a trailing newline (almost always true for markdown), which
23
+ * caused an off-by-one budget trip at the 180-line boundary (code review
24
+ * finding for v2.32.3).
25
+ */
26
+ function countLines(raw) {
27
+ if (raw.length === 0) return 0;
28
+ const nl = (raw.match(/\n/g) || []).length;
29
+ return nl + (raw.endsWith('\n') ? 0 : 1);
30
+ }
31
+
20
32
  export class UserEditedError extends Error {
21
33
  constructor(message) { super(message); this.name = 'UserEditedError'; }
22
34
  }
@@ -123,7 +135,7 @@ export function readMemoryIndex(memdir, slug) {
123
135
  }
124
136
  const raw = readFileSync(path, 'utf8');
125
137
  const m = raw.match(sentinelRegex(slug));
126
- const lineCount = raw.length === 0 ? 0 : raw.split('\n').length;
138
+ const lineCount = countLines(raw);
127
139
  if (!m) return { exists: true, raw, lineCount, section: null, body: null, version: null };
128
140
  return { exists: true, raw, lineCount, section: m[0], body: m[2], version: m[1] };
129
141
  }
@@ -159,7 +171,7 @@ export function writePluginSection(memdir, { slug, version, contentLine, force =
159
171
 
160
172
  if (!match) {
161
173
  // Insert: enforce the 180-line budget so we never get truncated at 200.
162
- const existingLines = raw.length === 0 ? 0 : raw.split('\n').length;
174
+ const existingLines = countLines(raw);
163
175
  if (existingLines > MEMORY_LINE_BUDGET) {
164
176
  throw new BudgetExceededError(
165
177
  `MEMORY.md has ${existingLines} lines (> ${MEMORY_LINE_BUDGET}); refuse to add new sentinel section for ${slug}.`,
@@ -223,7 +235,13 @@ export function removePluginSection(memdir, slug) {
223
235
  let end = match.index + match[0].length;
224
236
  if (raw[end] === '\n') end++;
225
237
  if (start > 0 && raw.slice(0, start).endsWith('\n\n')) start--;
226
- const next = raw.slice(0, start) + raw.slice(end);
238
+ let next = raw.slice(0, start) + raw.slice(end);
239
+ // Edge case (code review v2.32.3): when the sentinel was the first content
240
+ // (e.g. two invited-memory plugins coexist and we remove the earlier one),
241
+ // the tail can still start with a stranded blank line / doubled newlines.
242
+ // Normalize leading whitespace and collapse any ≥3 consecutive newlines
243
+ // so the remaining content looks hand-authored.
244
+ next = next.replace(/^\s+/, '').replace(/\n{3,}/g, '\n\n');
227
245
  atomicWrite(path, next);
228
246
  return { action: 'removed' };
229
247
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-mem-lite",
3
- "version": "2.32.2",
3
+ "version": "2.32.4",
4
4
  "description": "Lightweight persistent memory system for Claude Code",
5
5
  "type": "module",
6
6
  "engines": {