claude-mem-lite 3.70.1 → 3.70.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": "3.70.1",
13
+ "version": "3.70.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": "3.70.1",
3
+ "version": "3.70.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"
@@ -51,6 +51,29 @@ export function isNativeBindingError(err) {
51
51
  return NATIVE_BINDING_PATTERNS.some((re) => re.test(msg));
52
52
  }
53
53
 
54
+ /**
55
+ * Render a binding error as ONE line without losing the diagnosis.
56
+ *
57
+ * Every surface used to do `String(err).split('\n')[0]`, which is exactly wrong for
58
+ * the ABI-mismatch family this subsystem exists to detect. Node's message puts the
59
+ * filename on line 0 and the `NODE_MODULE_VERSION 127 … requires 137` on lines 2-3,
60
+ * so first-line truncation printed a bare path and dropped the only part that says
61
+ * what is wrong. (The comment in probeBindingInFreshProcess below called that string
62
+ * "the highest-value line doctor prints"; for a stale binding it carried no diagnosis
63
+ * at all.) Collapsing whitespace keeps both the path and the numbers while staying
64
+ * safe for a JSON envelope, a JSONL log record and a one-line hook receipt.
65
+ *
66
+ * @param {unknown} err Error, string, or anything thrown.
67
+ * @param {number} [max] Hard cap; a probe must not be able to flood a receipt.
68
+ * @returns {string}
69
+ */
70
+ export function flattenBindingError(err, max = 240) {
71
+ const raw = err instanceof Error ? err.message : err;
72
+ const s = String(raw ?? '').replace(/\s+/g, ' ').trim();
73
+ if (!s) return 'unknown';
74
+ return s.length > max ? `${s.slice(0, max - 1)}…` : s;
75
+ }
76
+
54
77
  /**
55
78
  * Probe better-sqlite3's native binding by importing it from `installDir`'s
56
79
  * node_modules and opening an in-memory DB. Returns {ok, error?}.
@@ -34,7 +34,7 @@ import { existsSync, readdirSync, realpathSync } from 'node:fs';
34
34
  import { join } from 'node:path';
35
35
  import { homedir } from 'node:os';
36
36
 
37
- import { probeBindingInFreshProcess, NATIVE_BINDING_REBUILD_CMD } from './binding-probe.mjs';
37
+ import { probeBindingInFreshProcess, NATIVE_BINDING_REBUILD_CMD, flattenBindingError } from './binding-probe.mjs';
38
38
 
39
39
  // Module-private: nothing outside needs these, and a new unused export is a
40
40
  // review signal against the knip baseline recorded in CLAUDE.md.
@@ -216,7 +216,10 @@ export function probeRuntimeRoots(roots, deps = {}) {
216
216
  // not installed exits 0 and heals nothing, so an unowned tree that also cannot
217
217
  // resolve from an ancestor needs an install; a present-but-unloadable tree needs
218
218
  // the rebuild.
219
- const error = String(r.error || 'unknown').split('\n')[0];
219
+ // NOT `.split('\n')[0]`: Node puts the filename on line 0 and the
220
+ // `NODE_MODULE_VERSION 127 … requires 137` on lines 2-3, so first-line truncation
221
+ // showed a bare path for the one fault family this check exists for.
222
+ const error = flattenBindingError(r.error);
220
223
  return ownDeps
221
224
  ? { label, root, ok: false, error, repair: `cd ${root} && ${NATIVE_BINDING_REBUILD_CMD}` }
222
225
  : {
@@ -24,7 +24,7 @@
24
24
  import { join } from 'node:path';
25
25
  import { readFileSync, writeFileSync, mkdirSync, renameSync, unlinkSync } from 'node:fs';
26
26
  import { fileURLToPath } from 'node:url';
27
- import { isNativeBindingError } from './binding-probe.mjs';
27
+ import { isNativeBindingError, flattenBindingError } from './binding-probe.mjs';
28
28
 
29
29
  export const NATIVE_BINDING_HINT_COOLDOWN_MS = 6 * 60 * 60 * 1000; // 6h
30
30
  const MARKER_NAME = 'native-binding-hint-last';
@@ -136,7 +136,7 @@ export function recordNativeBindingBreakage(runtimeDir, { reason = '', event = '
136
136
  const tmp = `${marker}.tmp-${process.pid}`;
137
137
  // First line only: the ABI error is multi-line and the marker is read by the
138
138
  // launcher (pure node:, no parser beyond JSON.parse) and by `doctor`.
139
- writeFileSync(tmp, JSON.stringify({ reason: String(reason).split('\n')[0], event, ts: now }));
139
+ writeFileSync(tmp, JSON.stringify({ reason: flattenBindingError(reason), event, ts: now }));
140
140
  renameSync(tmp, marker);
141
141
  } catch { /* best-effort */ }
142
142
  }
@@ -1,12 +1,12 @@
1
1
  {
2
2
  "name": "claude-mem-lite",
3
- "version": "3.70.1",
3
+ "version": "3.70.2",
4
4
  "lockfileVersion": 3,
5
5
  "requires": true,
6
6
  "packages": {
7
7
  "": {
8
8
  "name": "claude-mem-lite",
9
- "version": "3.70.1",
9
+ "version": "3.70.2",
10
10
  "dependencies": {
11
11
  "@modelcontextprotocol/sdk": "^1.26.0",
12
12
  "better-sqlite3": "^12.6.2",
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "claude-mem-lite",
3
- "version": "3.70.1",
3
+ "version": "3.70.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",
@@ -42,8 +42,16 @@ function bareProbe(root) {
42
42
  const r = spawnSync(process.execPath, ['-e', script], { stdio: 'pipe', timeout: 8000 });
43
43
  if (!r.error && r.status === 0) return true;
44
44
  // Say WHY. The inline predecessor printed the cause here; dropping it left the
45
- // user with setup.sh's generic "binding unusable" and nothing to act on.
46
- const why = String(r.stdout || '').trim().split('\n')[0]
45
+ // user with setup.sh's generic "binding unusable" and nothing to act on. Flattened
46
+ // rather than first-lined: Node's ABI message puts the filename on line 0 and the
47
+ // NODE_MODULE_VERSION pair on lines 2-3, so `.split('\n')[0]` said WHERE but never
48
+ // WHY — for the exact fault this probe exists to find.
49
+ //
50
+ // Flattening is inlined, NOT lib/binding-probe.mjs::flattenBindingError, because
51
+ // this function is the fallback for a tree where lib/ failed to import — `helpers`
52
+ // is still null on every path that reaches here. Duplicated deliberately; keep the
53
+ // two in step.
54
+ const why = String(r.stdout || '').replace(/\s+/g, ' ').trim().slice(0, 240)
47
55
  || (r.error && r.error.message)
48
56
  || `probe exited ${r.status ?? `on signal ${r.signal}`}`;
49
57
  process.stderr.write(`[claude-mem-lite] binding probe: ${why}\n`);
@@ -82,9 +90,9 @@ try {
82
90
  }
83
91
  const release = helpers.acquireLock(lockPath);
84
92
  if (!release) {
85
- const firstLine = String(first.error).split('\n')[0];
86
93
  process.stderr.write(
87
- `[claude-mem-lite] binding probe: ${firstLine} (another install/repair in flight — deferring heal)\n`,
94
+ `[claude-mem-lite] binding probe: ${helpers.flattenBindingError(first.error)} `
95
+ + '(another install/repair in flight — deferring heal)\n',
88
96
  );
89
97
  process.exit(1);
90
98
  }