claude-mem-lite 4.0.1 → 4.0.2

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": "4.0.1",
13
+ "version": "4.0.2",
14
14
  "source": "./",
15
15
  "description": "Persistent long-term memory for Claude Code via MCP — captures coding decisions, bugfixes, and context across sessions. Hybrid FTS5 + TF-IDF search with episode batching. Single SQLite DB, no external services. A lighter, lower-cost alternative to claude-mem (episode batching + a smaller model; cost savings are an internal estimate, not a measured benchmark)."
16
16
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-mem-lite",
3
- "version": "4.0.1",
3
+ "version": "4.0.2",
4
4
  "description": "Persistent long-term memory for Claude Code via MCP — captures coding decisions, bugfixes, and context across sessions. Hybrid FTS5 + TF-IDF search with episode batching. Single SQLite DB, no external services. A lighter, lower-cost alternative to claude-mem (episode batching + a smaller model; cost savings are an internal estimate, not a measured benchmark).",
5
5
  "author": {
6
6
  "name": "sdsrss"
package/README.md CHANGED
@@ -145,7 +145,7 @@ How claude-mem-lite differs from the major neighbors in the LLM-memory space (ve
145
145
 
146
146
  ## Requirements
147
147
 
148
- - **Node.js** >= 20
148
+ - **Node.js** >= 22
149
149
  - **Claude Code** CLI installed and configured (`claude` command available)
150
150
  - **SQLite3** support (provided by `better-sqlite3`, compiled on install)
151
151
  - **Platform**: Linux or macOS (see [Platform Support](#platform-support))
@@ -53,7 +53,9 @@ export const NATIVE_BINDING_SOURCE_BUILD_CMD = 'npm run --prefix node_modules/be
53
53
  * @returns {string}
54
54
  */
55
55
  export function nativeBindingRepairHint(root) {
56
- return `cd ${root} && ${NATIVE_BINDING_REBUILD_CMD} && ${NATIVE_BINDING_SOURCE_BUILD_CMD}`;
56
+ // Quoted: INSTALL_DIR / a plugin-cache root can contain spaces, and an unquoted `cd`
57
+ // hands the user a command that fails on exactly the machines least able to debug it.
58
+ return `cd "${root}" && ${NATIVE_BINDING_REBUILD_CMD} && ${NATIVE_BINDING_SOURCE_BUILD_CMD}`;
57
59
  }
58
60
 
59
61
  // Set on a re-exec'd child so one failed heal cannot fork-bomb the CLI.
@@ -270,9 +272,24 @@ export async function ensureBetterSqlite3Working(installDir, deps = {}) {
270
272
  // get it appended — otherwise an injected strategy would silently grow a step its owner
271
273
  // never asked for, and (as the stub tests caught) a test that stubs `rebuild` without
272
274
  // stubbing `exec` would shell out for real.
275
+ //
276
+ // `sourceBuild: false` is the EXPLICIT opt-out, and it exists because the `deps.rebuild`
277
+ // test above was the wrong proxy for "this caller has a budget" (A20260906-R8b-P0-1, found
278
+ // by independent review). The one caller that is genuinely time-boxed — the SessionStart
279
+ // hook probe — injects `exec` with a 20 s cap and does NOT inject `rebuild`, so it landed
280
+ // outside the guard. That matters because this step is `node-gyp clean && node-gyp rebuild`:
281
+ // it DELETES build/ before compiling, so a truncated attempt is not a no-op, it is
282
+ // destructive. Measured on a tree whose compiled binding opened a DB — 20 s cap, SIGTERM at
283
+ // 20.02 s, no `.node` left, `DB opens: YES` → `NO`, repeating on every SessionStart because
284
+ // setup.sh writes its marker only on success. Callers with a time budget must opt out and
285
+ // leave the compile to a foreground path (`rebuild-binding`, `healAndReexec`) that has none.
273
286
  const sourceBuild =
274
- deps.sourceBuild ||
275
- (deps.rebuild ? null : () => exec(NATIVE_BINDING_SOURCE_BUILD_CMD, { cwd: installDir, stdio: 'pipe' }));
287
+ deps.sourceBuild === false
288
+ ? null
289
+ : deps.sourceBuild ||
290
+ (deps.rebuild
291
+ ? null
292
+ : () => exec(NATIVE_BINDING_SOURCE_BUILD_CMD, { cwd: installDir, stdio: 'pipe' }));
276
293
  if (!sourceBuild) return { ok: false, error: second.error || first.error };
277
294
 
278
295
  try {
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "claude-mem-lite",
3
- "version": "4.0.1",
3
+ "version": "4.0.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "claude-mem-lite",
9
- "version": "4.0.1",
9
+ "version": "4.0.2",
10
10
  "dependencies": {
11
11
  "@modelcontextprotocol/sdk": "^1.30.0",
12
12
  "better-sqlite3": "^13.0.3",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-mem-lite",
3
- "version": "4.0.1",
3
+ "version": "4.0.2",
4
4
  "description": "Persistent long-term memory for Claude Code via MCP — captures coding decisions, bugfixes, and context across sessions. Hybrid FTS5 + TF-IDF search with episode batching. Single SQLite DB, no external services. A lighter, lower-cost alternative to claude-mem (episode batching + a smaller model; cost savings are an internal estimate, not a measured benchmark).",
5
5
  "type": "module",
6
6
  "packageManager": "npm@10.9.2",
@@ -132,6 +132,14 @@ try {
132
132
  probe: () => first,
133
133
  exec: (cmd, opts) => execSync(cmd, { ...opts, timeout: 20000 }),
134
134
  verify: () => helpers.probeBindingInFreshProcess(ROOT, { timeoutMs: 8000 }),
135
+ // NOT on this path (A20260906-R8b-P0-1). The source build is
136
+ // `node-gyp clean && node-gyp rebuild`: it deletes build/ before compiling, and a full
137
+ // compile takes ~41 s against the 20 s cap above — so under this budget it does not fail
138
+ // harmlessly, it destroys a binding that was working (measured: DB opens YES → NO, .node
139
+ // gone, SIGTERM at 20.02 s), and repeats every SessionStart because setup.sh writes its
140
+ // marker only on success. The compile belongs on a foreground path with no cap:
141
+ // `claude-mem-lite rebuild-binding`, which is what the repair hints now print.
142
+ sourceBuild: false,
135
143
  });
136
144
  } finally {
137
145
  // process.exit skips finally blocks — every exit below this point, so the
@@ -107,7 +107,7 @@ try {
107
107
  }
108
108
  if (!verify.ok) {
109
109
  process.stderr.write(`[claude-mem-lite] better-sqlite3 binding unusable: ${verify.error}\n`);
110
- process.stderr.write(`[claude-mem-lite] Repair: ${nativeBindingRepairHint(`"${ROOT}"`)}\n`);
110
+ process.stderr.write(`[claude-mem-lite] Repair: ${nativeBindingRepairHint(ROOT)}\n`);
111
111
  process.exit(1);
112
112
  }
113
113
  if (verify.action === 'rebuilt') {