claude-mem-lite 2.71.2 → 2.71.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.
- package/.claude-plugin/marketplace.json +1 -1
- package/.claude-plugin/plugin.json +1 -1
- package/bash-utils.mjs +17 -1
- package/install.mjs +13 -52
- package/lib/binding-probe.mjs +63 -0
- package/mem-cli.mjs +7 -0
- package/package.json +2 -1
- package/scripts/launch.mjs +22 -0
- package/source-files.mjs +5 -0
package/bash-utils.mjs
CHANGED
|
@@ -15,9 +15,25 @@ export function detectBashSignificance(input, response) {
|
|
|
15
15
|
// Skip error keyword matching when the command is a read/search operation
|
|
16
16
|
// (grep output naturally contains matched keywords like "error")
|
|
17
17
|
const isSearchCmd = /\b(grep|rg|ag|ack|cat|head|tail|less|more|find|locate|wc|file|which|type)\b/i.test(cmd);
|
|
18
|
-
const
|
|
18
|
+
const looksLikeError = !isSearchCmd
|
|
19
19
|
&& /\berror\b|\bERR!|fail(ed|ure)?|exception|panic|traceback|errno|enoent|command not found/i.test(response)
|
|
20
20
|
&& response.length > 15;
|
|
21
|
+
// Green test summary exemption — "0 fail/failed/failures" in test-runner
|
|
22
|
+
// output (bun/jest/pytest) gets matched by the broad `fail(ed|ure)?` token
|
|
23
|
+
// above, driving episode.isError=true for passing runs. A live cluster-merge
|
|
24
|
+
// audit found 5 noise observations with "Error: <test>.ts ... 0 fail" titles
|
|
25
|
+
// from this path. Flip back to non-error iff a "0 fail" marker is present
|
|
26
|
+
// AND no hard-error signal (panic / ENOENT / AssertionError / TypeError /
|
|
27
|
+
// explicit FAIL banner / npm ERR!) coexists in the output.
|
|
28
|
+
const hasGreenTestSummary = looksLikeError
|
|
29
|
+
&& /\b0\s+(fail|failed|failures)\b/i.test(response);
|
|
30
|
+
// NOTE: do not add `\bFAIL\s` here — with /i flag it would re-match the
|
|
31
|
+
// very `0 fail\n` token green-summary is trying to exempt. A real test
|
|
32
|
+
// failure produces "N fail" (N≥1) which never triggers hasGreenTestSummary,
|
|
33
|
+
// so a uppercase-FAIL fingerprint isn't needed for correctness.
|
|
34
|
+
const hasHardErrorSignal = hasGreenTestSummary
|
|
35
|
+
&& /\bERR!|panic|traceback|enoent|command not found|exception|AssertionError|TypeError:|SyntaxError:/i.test(response);
|
|
36
|
+
const isError = looksLikeError && !(hasGreenTestSummary && !hasHardErrorSignal);
|
|
21
37
|
// Match actual test runner invocations, not commands that merely reference "test" as a keyword
|
|
22
38
|
const isTest = /\b(npm\s+test|npm\s+run\s+test|yarn\s+test|pnpm\s+test|pnpm\s+run\s+test|bun\s+test|go\s+test|cargo\s+test)\b/i.test(cmd)
|
|
23
39
|
|| /\b(jest|pytest|vitest|mocha|cypress|playwright)\b/i.test(cmd);
|
package/install.mjs
CHANGED
|
@@ -25,11 +25,10 @@ const MARKETPLACE_KEY = 'sdsrss';
|
|
|
25
25
|
const PLUGIN_KEY = `claude-mem-lite@${MARKETPLACE_KEY}`;
|
|
26
26
|
const NPM_INSTALL_CMD = 'npm install --omit=dev --no-audit --no-fund';
|
|
27
27
|
|
|
28
|
-
import { createRequire } from 'module';
|
|
29
|
-
|
|
30
28
|
import { RESOURCE_METADATA } from './install-metadata.mjs';
|
|
31
29
|
import { scanPluginCacheHookPollution } from './plugin-cache-guard.mjs';
|
|
32
30
|
import { SOURCE_FILES, HOOK_SCRIPT_FILES } from './source-files.mjs';
|
|
31
|
+
import { probeBetterSqlite3Binding, ensureBetterSqlite3Working } from './lib/binding-probe.mjs';
|
|
33
32
|
|
|
34
33
|
// Re-export for backward compatibility — tests/install-hook-scripts.test.mjs
|
|
35
34
|
// and any external consumers still import HOOK_SCRIPT_FILES from install.mjs.
|
|
@@ -37,6 +36,12 @@ import { SOURCE_FILES, HOOK_SCRIPT_FILES } from './source-files.mjs';
|
|
|
37
36
|
// can share it without a static cycle.
|
|
38
37
|
export { HOOK_SCRIPT_FILES };
|
|
39
38
|
|
|
39
|
+
// Re-export for backward compatibility — tests/install-bsqlite-probe.test.mjs
|
|
40
|
+
// imports these from install.mjs. The implementation moved to lib/binding-probe.mjs
|
|
41
|
+
// so scripts/launch.mjs can share the probe without importing install.mjs (which
|
|
42
|
+
// pulls heavy install-only deps).
|
|
43
|
+
export { probeBetterSqlite3Binding, ensureBetterSqlite3Working };
|
|
44
|
+
|
|
40
45
|
export function copyHookScripts(srcDir, destDir) {
|
|
41
46
|
for (const name of HOOK_SCRIPT_FILES) {
|
|
42
47
|
const src = join(srcDir, name);
|
|
@@ -75,55 +80,6 @@ export function migrateLegacyClaudeMemData(oldDir, newDir, opts = {}) {
|
|
|
75
80
|
return { action: 'backed-up', backupPath };
|
|
76
81
|
}
|
|
77
82
|
|
|
78
|
-
/**
|
|
79
|
-
* Probe better-sqlite3's native binding by importing it from `installDir`'s
|
|
80
|
-
* node_modules and opening an in-memory DB. Returns {ok, error?}. `npm install`
|
|
81
|
-
* exits 0 even when the prebuilt .node binary mismatches the running Node ABI
|
|
82
|
-
* (e.g. NODE_MODULE_VERSION 137 on Node v24), so install must verify before
|
|
83
|
-
* declaring success — otherwise the next launch FATALs with "Could not locate
|
|
84
|
-
* the bindings file".
|
|
85
|
-
*/
|
|
86
|
-
export async function probeBetterSqlite3Binding(installDir) {
|
|
87
|
-
try {
|
|
88
|
-
const localRequire = createRequire(join(installDir, 'package.json'));
|
|
89
|
-
const Database = localRequire('better-sqlite3');
|
|
90
|
-
const db = new Database(':memory:');
|
|
91
|
-
db.close();
|
|
92
|
-
return { ok: true };
|
|
93
|
-
} catch (e) {
|
|
94
|
-
return { ok: false, error: e.message };
|
|
95
|
-
}
|
|
96
|
-
}
|
|
97
|
-
|
|
98
|
-
/**
|
|
99
|
-
* Verify better-sqlite3 binding works in `installDir`; if not, run
|
|
100
|
-
* `npm rebuild better-sqlite3` and re-probe. Returns
|
|
101
|
-
* { ok: true, action: 'verified' | 'rebuilt' } on success or
|
|
102
|
-
* { ok: false, error } if rebuild can't fix it. The `probe` and `rebuild`
|
|
103
|
-
* deps are injectable so this can be unit-tested without a real npm
|
|
104
|
-
* subprocess.
|
|
105
|
-
*/
|
|
106
|
-
export async function ensureBetterSqlite3Working(installDir, deps = {}) {
|
|
107
|
-
const probe = deps.probe || (() => probeBetterSqlite3Binding(installDir));
|
|
108
|
-
const rebuild = deps.rebuild || (async () => {
|
|
109
|
-
execSync('npm rebuild better-sqlite3', { cwd: installDir, stdio: 'pipe' });
|
|
110
|
-
});
|
|
111
|
-
|
|
112
|
-
const first = await probe();
|
|
113
|
-
if (first.ok) return { ok: true, action: 'verified' };
|
|
114
|
-
|
|
115
|
-
try {
|
|
116
|
-
await rebuild();
|
|
117
|
-
} catch (e) {
|
|
118
|
-
return { ok: false, error: `rebuild failed: ${e.message}` };
|
|
119
|
-
}
|
|
120
|
-
|
|
121
|
-
const second = await probe();
|
|
122
|
-
if (second.ok) return { ok: true, action: 'rebuilt' };
|
|
123
|
-
|
|
124
|
-
return { ok: false, error: second.error || first.error };
|
|
125
|
-
}
|
|
126
|
-
|
|
127
83
|
/**
|
|
128
84
|
* Derive invocation_name from resource name when metadata doesn't provide one.
|
|
129
85
|
* Rules:
|
|
@@ -421,7 +377,12 @@ async function install() {
|
|
|
421
377
|
} else {
|
|
422
378
|
log('Ensuring dependencies installed...');
|
|
423
379
|
try {
|
|
424
|
-
|
|
380
|
+
// stderr inherited so users see real-time progress (network slowness,
|
|
381
|
+
// node-gyp compile spinner, prebuild-install fallback messages). With
|
|
382
|
+
// `stdio: 'pipe'` the install appeared to hang under the 5-min Bash
|
|
383
|
+
// timeout when better-sqlite3 had no Node v24 prebuild and had to
|
|
384
|
+
// compile from source — see bug audit 2026-05.
|
|
385
|
+
execSync(NPM_INSTALL_CMD, { cwd: INSTALL_DIR, stdio: ['ignore', 'pipe', 'inherit'] });
|
|
425
386
|
ok('Dependencies installed');
|
|
426
387
|
} catch (e) {
|
|
427
388
|
fail('npm install failed: ' + e.message);
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
// lib/binding-probe.mjs — better-sqlite3 native binding probe + auto-rebuild.
|
|
2
|
+
//
|
|
3
|
+
// Shared by install.mjs (verify after `npm install`) and scripts/launch.mjs
|
|
4
|
+
// (verify before launching the MCP server). `npm install` exits 0 even when
|
|
5
|
+
// the prebuilt .node binary mismatches the running Node ABI (e.g. ABI v137 on
|
|
6
|
+
// Node v24), and the presence of node_modules/better-sqlite3/ on disk is not
|
|
7
|
+
// sufficient — the binding can be present-but-stale after a Node upgrade.
|
|
8
|
+
|
|
9
|
+
import { execSync } from 'node:child_process';
|
|
10
|
+
import { createRequire } from 'node:module';
|
|
11
|
+
import { join } from 'node:path';
|
|
12
|
+
|
|
13
|
+
/**
|
|
14
|
+
* Probe better-sqlite3's native binding by importing it from `installDir`'s
|
|
15
|
+
* node_modules and opening an in-memory DB. Returns {ok, error?}.
|
|
16
|
+
*
|
|
17
|
+
* @param {string} installDir Directory containing node_modules/better-sqlite3
|
|
18
|
+
* @returns {Promise<{ok: true} | {ok: false, error: string}>}
|
|
19
|
+
*/
|
|
20
|
+
export async function probeBetterSqlite3Binding(installDir) {
|
|
21
|
+
try {
|
|
22
|
+
const localRequire = createRequire(join(installDir, 'package.json'));
|
|
23
|
+
const Database = localRequire('better-sqlite3');
|
|
24
|
+
const db = new Database(':memory:');
|
|
25
|
+
db.close();
|
|
26
|
+
return { ok: true };
|
|
27
|
+
} catch (e) {
|
|
28
|
+
return { ok: false, error: e.message };
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
/**
|
|
33
|
+
* Verify better-sqlite3 binding works in `installDir`; if not, run
|
|
34
|
+
* `npm rebuild better-sqlite3` and re-probe. Returns
|
|
35
|
+
* { ok: true, action: 'verified' | 'rebuilt' } on success or
|
|
36
|
+
* { ok: false, error } if rebuild can't fix it. The `probe` and `rebuild`
|
|
37
|
+
* deps are injectable so this can be unit-tested without a real npm
|
|
38
|
+
* subprocess.
|
|
39
|
+
*
|
|
40
|
+
* @param {string} installDir Directory containing node_modules/better-sqlite3
|
|
41
|
+
* @param {{probe?: () => Promise<{ok: boolean, error?: string}>, rebuild?: () => Promise<void>}} [deps]
|
|
42
|
+
* @returns {Promise<{ok: true, action: 'verified' | 'rebuilt'} | {ok: false, error: string}>}
|
|
43
|
+
*/
|
|
44
|
+
export async function ensureBetterSqlite3Working(installDir, deps = {}) {
|
|
45
|
+
const probe = deps.probe || (() => probeBetterSqlite3Binding(installDir));
|
|
46
|
+
const rebuild = deps.rebuild || (async () => {
|
|
47
|
+
execSync('npm rebuild better-sqlite3', { cwd: installDir, stdio: 'pipe' });
|
|
48
|
+
});
|
|
49
|
+
|
|
50
|
+
const first = await probe();
|
|
51
|
+
if (first.ok) return { ok: true, action: 'verified' };
|
|
52
|
+
|
|
53
|
+
try {
|
|
54
|
+
await rebuild();
|
|
55
|
+
} catch (e) {
|
|
56
|
+
return { ok: false, error: `rebuild failed: ${e.message}` };
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const second = await probe();
|
|
60
|
+
if (second.ok) return { ok: true, action: 'rebuilt' };
|
|
61
|
+
|
|
62
|
+
return { ok: false, error: second.error || first.error };
|
|
63
|
+
}
|
package/mem-cli.mjs
CHANGED
|
@@ -2421,6 +2421,13 @@ Commands:
|
|
|
2421
2421
|
import-jsonl <file-or-dir> Import Claude Code JSONL transcripts (cold-start backfill)
|
|
2422
2422
|
--project P Project name (default: inferred from cwd)
|
|
2423
2423
|
|
|
2424
|
+
import <github-url> Import skills/agents into the resource registry from a GitHub repo
|
|
2425
|
+
--enrich Auto-enrich each imported resource with a Haiku capability summary
|
|
2426
|
+
|
|
2427
|
+
enrich <name> Re-enrich a single registry resource (Haiku capability summary)
|
|
2428
|
+
--all Enrich every active resource missing or failed enrichment
|
|
2429
|
+
--batch Skip the inter-call delay (use only with low rate-limit risk)
|
|
2430
|
+
|
|
2424
2431
|
activity <action> Non-memdir event log (v2.31) — bugfix/lesson/bug/discovery/etc.
|
|
2425
2432
|
save --type T "<title>" [--body "<text>"] [--files f1,f2] [--file path] [--importance 1-3] [--project P]
|
|
2426
2433
|
search "<query>" Search events [--type T] [--limit N] [--project P]
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "claude-mem-lite",
|
|
3
|
-
"version": "2.71.
|
|
3
|
+
"version": "2.71.4",
|
|
4
4
|
"description": "Lightweight persistent memory system for Claude Code",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"packageManager": "npm@10.9.2",
|
|
@@ -61,6 +61,7 @@
|
|
|
61
61
|
"lib/id-routing.mjs",
|
|
62
62
|
"lib/err-sampler.mjs",
|
|
63
63
|
"lib/metrics.mjs",
|
|
64
|
+
"lib/binding-probe.mjs",
|
|
64
65
|
"lib/mem-override.mjs",
|
|
65
66
|
"lib/save-observation.mjs",
|
|
66
67
|
"lib/deferred-work.mjs",
|
package/scripts/launch.mjs
CHANGED
|
@@ -30,6 +30,28 @@ if (!existsSync(join(ROOT, 'node_modules', 'better-sqlite3'))) {
|
|
|
30
30
|
}
|
|
31
31
|
}
|
|
32
32
|
|
|
33
|
+
// Verify better-sqlite3 native binding matches the current Node ABI. The
|
|
34
|
+
// directory-presence check above is necessary but not sufficient: a Node
|
|
35
|
+
// version change (e.g. v22 → v24, ABI v127 → v137) leaves node_modules
|
|
36
|
+
// intact but the .node binary stale → server FATALs with "Could not locate
|
|
37
|
+
// the bindings file" on first DB open. Probe + auto-rebuild before launching.
|
|
38
|
+
try {
|
|
39
|
+
const { ensureBetterSqlite3Working } = await import('../lib/binding-probe.mjs');
|
|
40
|
+
const verify = await ensureBetterSqlite3Working(ROOT);
|
|
41
|
+
if (!verify.ok) {
|
|
42
|
+
process.stderr.write(`[claude-mem-lite] better-sqlite3 binding unusable: ${verify.error}\n`);
|
|
43
|
+
process.stderr.write(`[claude-mem-lite] Repair: cd "${ROOT}" && npm rebuild better-sqlite3 --build-from-source\n`);
|
|
44
|
+
process.exit(1);
|
|
45
|
+
}
|
|
46
|
+
if (verify.action === 'rebuilt') {
|
|
47
|
+
process.stderr.write('[claude-mem-lite] Rebuilt better-sqlite3 binding for current Node ABI\n');
|
|
48
|
+
}
|
|
49
|
+
} catch (e) {
|
|
50
|
+
// Probe module itself failed to load — fall through to server import and let
|
|
51
|
+
// the native FATAL surface as before. Don't block launch on a probe regression.
|
|
52
|
+
process.stderr.write(`[claude-mem-lite] binding probe skipped: ${e.message}\n`);
|
|
53
|
+
}
|
|
54
|
+
|
|
33
55
|
// Verify MCP SDK is importable (exports mapping intact).
|
|
34
56
|
// Incomplete installs can leave the directory present but package.json missing,
|
|
35
57
|
// causing Node.js to fail resolving subpath exports like /server/mcp.js.
|
package/source-files.mjs
CHANGED
|
@@ -44,6 +44,11 @@ export const SOURCE_FILES = [
|
|
|
44
44
|
'lib/id-routing.mjs',
|
|
45
45
|
'lib/err-sampler.mjs',
|
|
46
46
|
'lib/metrics.mjs',
|
|
47
|
+
// v2.71.x: better-sqlite3 ABI probe + auto-rebuild. Shared by install.mjs
|
|
48
|
+
// (post-`npm install` verify) and scripts/launch.mjs (pre-server-launch
|
|
49
|
+
// self-heal after Node ABI changes). Missing from manifest → auto-update
|
|
50
|
+
// ships a stale install that FATALs on first DB open after Node upgrade.
|
|
51
|
+
'lib/binding-probe.mjs',
|
|
47
52
|
// v2.41 god-module split — mem-cli.mjs router + per-cmd handlers under cli/
|
|
48
53
|
'cli/common.mjs',
|
|
49
54
|
'cli/fts-check.mjs',
|