@lotargo/memory_plugin 1.6.0 → 1.6.1
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/CHANGELOG.md +30 -0
- package/README.md +28 -5
- package/mcp-server/boot.js +43 -0
- package/mcp-server/cli_boot.js +37 -0
- package/mcp-server/preinstall.js +23 -2
- package/package.json +7 -4
package/CHANGELOG.md
CHANGED
|
@@ -5,6 +5,35 @@ All notable changes to `@lotargo/memory_plugin` are documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
7
7
|
|
|
8
|
+
## [1.6.1] - 2026-08-10
|
|
9
|
+
|
|
10
|
+
### Fixed
|
|
11
|
+
|
|
12
|
+
- **Cryptic crash on Node.js < 22.5.0** (`No such built-in module: node:sqlite`).
|
|
13
|
+
ESM static imports are hoisted, so the `node:sqlite` import in `database.js`
|
|
14
|
+
crashed before any user code could run. Three layers of protection are now in
|
|
15
|
+
place:
|
|
16
|
+
1. **Boot guard** (`boot.js` / `cli_boot.js`): new lightweight entry points
|
|
17
|
+
that check `process.versions.node` *before* loading the ESM module graph.
|
|
18
|
+
On incompatible versions they print a clear boxed error with upgrade
|
|
19
|
+
instructions (`nvm install 22` / `brew install node@22`) and exit.
|
|
20
|
+
2. **`engine-strict`** (`.npmrc`): `npm install` now **fails** instead of
|
|
21
|
+
merely warning when `engines.node >= 22.5.0` is not satisfied.
|
|
22
|
+
3. **Preinstall warning** (`preinstall.js`): a prominent `stderr` message is
|
|
23
|
+
printed during installation on unsupported Node versions, explaining that
|
|
24
|
+
the server will not start.
|
|
25
|
+
- Process-kill patterns in `preinstall.js` now match the new `boot.js` entry
|
|
26
|
+
point in addition to `index.js`, so global updates correctly terminate running
|
|
27
|
+
server instances.
|
|
28
|
+
|
|
29
|
+
### Changed
|
|
30
|
+
|
|
31
|
+
- All `bin` entry points (`memory_plugin`, `memory-agent`, `memory-cli`) now
|
|
32
|
+
route through `boot.js` / `cli_boot.js` instead of directly to `index.js` /
|
|
33
|
+
`cli.js`.
|
|
34
|
+
- `.npmrc` is no longer git-ignored; it contains only the project-level
|
|
35
|
+
`engine-strict=true` setting (npm never publishes `.npmrc` to the tarball).
|
|
36
|
+
|
|
8
37
|
## [1.6.0] - 2026-08-10
|
|
9
38
|
|
|
10
39
|
This release is the outcome of a full five-part audit (publishing, security, code
|
|
@@ -105,4 +134,5 @@ a critical retrieval regression introduced after `v1.5.3`.
|
|
|
105
134
|
- `BENCHMARKS.md` tables were re-derived from the stored JSON artifacts; the
|
|
106
135
|
bge-m3 section had carried e5-small numbers shifted by a column.
|
|
107
136
|
|
|
137
|
+
[1.6.1]: https://github.com/Lotargo/memory_pugin/releases/tag/v1.6.1
|
|
108
138
|
[1.6.0]: https://github.com/Lotargo/memory_pugin/releases/tag/v1.6.0
|
package/README.md
CHANGED
|
@@ -334,18 +334,41 @@ The engine is configured through `<memory-dir>/config.json` (created with defaul
|
|
|
334
334
|
|
|
335
335
|
## Testing & Benchmarking
|
|
336
336
|
|
|
337
|
-
To run the automated test suite and benchmarks locally:
|
|
337
|
+
To run the automated test suite and benchmarks locally, from the repository root:
|
|
338
338
|
|
|
339
339
|
```bash
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
# Run unit and integration tests
|
|
340
|
+
# Unit + integration + cloud suites (12 files) — fast and fully offline
|
|
343
341
|
npm test
|
|
344
342
|
|
|
345
|
-
#
|
|
343
|
+
# End-to-end smoke test with REAL ONNX embeddings — run before a release
|
|
344
|
+
npm run smoke
|
|
345
|
+
|
|
346
|
+
# Search quality & ingestion benchmarks
|
|
346
347
|
npm run benchmark
|
|
347
348
|
```
|
|
348
349
|
|
|
350
|
+
### Two testing modes, and why both exist
|
|
351
|
+
|
|
352
|
+
`npm test` runs every suite with `generateEmbeddings: false`. That keeps it fast
|
|
353
|
+
and offline (no model download, no network), but it means the **dense-vector half
|
|
354
|
+
of the engine is never exercised** — retrieval falls back to BM25-only.
|
|
355
|
+
|
|
356
|
+
`npm run smoke` covers exactly that blind spot: it ingests a document with real
|
|
357
|
+
ONNX vectors and asserts that hybrid retrieval returns a non-zero cosine
|
|
358
|
+
similarity, plus that a Russian query still reaches an English document
|
|
359
|
+
(something BM25 cannot do). It also walks the full user journey — remember →
|
|
360
|
+
recall → ingest → query → link → update → get → forget — and checks the ingest
|
|
361
|
+
path guard.
|
|
362
|
+
|
|
363
|
+
This split is not academic: a regression in `v1.5.3+` disabled vector search
|
|
364
|
+
entirely (`node:sqlite` returns BLOBs as `Uint8Array`, and a `Buffer.isBuffer()`
|
|
365
|
+
guard discarded every stored vector) while all offline suites stayed green. The
|
|
366
|
+
smoke test exists so that class of failure cannot ship unnoticed again.
|
|
367
|
+
|
|
368
|
+
The smoke test reuses the model weights already cached in your data directory, so
|
|
369
|
+
it does not re-download them. Point `MEMORY_MODEL_CACHE` at a cache directory to
|
|
370
|
+
override the lookup; without any cache the weights are fetched once.
|
|
371
|
+
|
|
349
372
|
For complete methodology details and search quality evaluation metrics, see [`docs/BENCHMARKS.md`](./docs/BENCHMARKS.md).
|
|
350
373
|
|
|
351
374
|
### Empirical Search Quality Results
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// ── Boot Guard ──────────────────────────────────────────────────────────────
|
|
4
|
+
// This file is the true entry point for both `memory_plugin` and `memory-agent`
|
|
5
|
+
// binaries. Its sole purpose is to verify the Node.js version BEFORE the ESM
|
|
6
|
+
// module graph is evaluated — because `mcp-server/index.js` transitively
|
|
7
|
+
// imports `node:sqlite` (a built-in available only from Node 22.5.0), and ESM
|
|
8
|
+
// static imports are hoisted, so a version check inside that file would never
|
|
9
|
+
// execute.
|
|
10
|
+
//
|
|
11
|
+
// By keeping this file free of any `node:sqlite` dependency we can print a
|
|
12
|
+
// clear, actionable error message instead of the cryptic
|
|
13
|
+
// "No such built-in module: node:sqlite"
|
|
14
|
+
// that users on Node 18/20/21 would otherwise see.
|
|
15
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
16
|
+
|
|
17
|
+
const MIN_MAJOR = 22;
|
|
18
|
+
const MIN_MINOR = 5;
|
|
19
|
+
|
|
20
|
+
const [major, minor] = process.versions.node.split(".").map(Number);
|
|
21
|
+
|
|
22
|
+
if (major < MIN_MAJOR || (major === MIN_MAJOR && minor < MIN_MINOR)) {
|
|
23
|
+
process.stderr.write(
|
|
24
|
+
`\n` +
|
|
25
|
+
` ╔══════════════════════════════════════════════════════════════════╗\n` +
|
|
26
|
+
` ║ @lotargo/memory_plugin requires Node.js >= 22.5.0 ║\n` +
|
|
27
|
+
` ║ ║\n` +
|
|
28
|
+
` ║ Detected: Node.js ${process.versions.node.padEnd(44)}║\n` +
|
|
29
|
+
` ║ ║\n` +
|
|
30
|
+
` ║ The built-in node:sqlite module used by this plugin was ║\n` +
|
|
31
|
+
` ║ introduced in Node.js 22.5.0. Please upgrade your ║\n` +
|
|
32
|
+
` ║ Node.js installation: ║\n` +
|
|
33
|
+
` ║ ║\n` +
|
|
34
|
+
` ║ nvm install 22 # or: brew install node@22 ║\n` +
|
|
35
|
+
` ║ ║\n` +
|
|
36
|
+
` ╚══════════════════════════════════════════════════════════════════╝\n` +
|
|
37
|
+
`\n`
|
|
38
|
+
);
|
|
39
|
+
process.exit(1);
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
// Version is OK — hand off to the real entry point.
|
|
43
|
+
import("./index.js");
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
|
|
3
|
+
// ── CLI Boot Guard ──────────────────────────────────────────────────────────
|
|
4
|
+
// Same version check as boot.js — see that file for the rationale.
|
|
5
|
+
// ─────────────────────────────────────────────────────────────────────────────
|
|
6
|
+
|
|
7
|
+
const MIN_MAJOR = 22;
|
|
8
|
+
const MIN_MINOR = 5;
|
|
9
|
+
|
|
10
|
+
const [major, minor] = process.versions.node.split(".").map(Number);
|
|
11
|
+
|
|
12
|
+
if (major < MIN_MAJOR || (major === MIN_MAJOR && minor < MIN_MINOR)) {
|
|
13
|
+
process.stderr.write(
|
|
14
|
+
`\n` +
|
|
15
|
+
` ╔══════════════════════════════════════════════════════════════════╗\n` +
|
|
16
|
+
` ║ @lotargo/memory_plugin requires Node.js >= 22.5.0 ║\n` +
|
|
17
|
+
` ║ ║\n` +
|
|
18
|
+
` ║ Detected: Node.js ${process.versions.node.padEnd(44)}║\n` +
|
|
19
|
+
` ║ ║\n` +
|
|
20
|
+
` ║ The built-in node:sqlite module used by this plugin was ║\n` +
|
|
21
|
+
` ║ introduced in Node.js 22.5.0. Please upgrade your ║\n` +
|
|
22
|
+
` ║ Node.js installation: ║\n` +
|
|
23
|
+
` ║ ║\n` +
|
|
24
|
+
` ║ nvm install 22 # or: brew install node@22 ║\n` +
|
|
25
|
+
` ║ ║\n` +
|
|
26
|
+
` ╚══════════════════════════════════════════════════════════════════╝\n` +
|
|
27
|
+
`\n`
|
|
28
|
+
);
|
|
29
|
+
process.exit(1);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
// Version is OK — hand off to the real CLI.
|
|
33
|
+
import("./cli.js").then(m => {
|
|
34
|
+
if (process.argv[1] && process.argv[1].includes("cli_boot.js")) {
|
|
35
|
+
m.runCli().catch((err) => console.error("CLI error:", err));
|
|
36
|
+
}
|
|
37
|
+
});
|
package/mcp-server/preinstall.js
CHANGED
|
@@ -5,6 +5,27 @@ if (process.env.CI || process.env.CONTINUOUS_INTEGRATION || process.env.DEBIAN_F
|
|
|
5
5
|
process.exit(0);
|
|
6
6
|
}
|
|
7
7
|
|
|
8
|
+
// ── Node version warning ────────────────────────────────────────────────────
|
|
9
|
+
// engines.node >= 22.5.0 is set in package.json but npm only warns by default.
|
|
10
|
+
// Print a loud, actionable message so the user notices before the server crashes.
|
|
11
|
+
{
|
|
12
|
+
const [major, minor] = process.versions.node.split(".").map(Number);
|
|
13
|
+
if (major < 22 || (major === 22 && minor < 5)) {
|
|
14
|
+
console.error(
|
|
15
|
+
`\n` +
|
|
16
|
+
` ⚠️ @lotargo/memory_plugin requires Node.js >= 22.5.0\n` +
|
|
17
|
+
` Detected: Node.js ${process.versions.node}\n` +
|
|
18
|
+
`\n` +
|
|
19
|
+
` The built-in node:sqlite module used by this plugin was\n` +
|
|
20
|
+
` introduced in Node.js 22.5.0. The server WILL NOT START\n` +
|
|
21
|
+
` on your current version.\n` +
|
|
22
|
+
`\n` +
|
|
23
|
+
` Please upgrade: nvm install 22 (or: brew install node@22)\n`
|
|
24
|
+
);
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
|
|
8
29
|
// Only run graceful process termination during explicit global npm updates
|
|
9
30
|
if (process.env.npm_config_global === "true" || process.env.MEMORY_PREINSTALL_FORCE === "true") {
|
|
10
31
|
try {
|
|
@@ -13,7 +34,7 @@ if (process.env.npm_config_global === "true" || process.env.MEMORY_PREINSTALL_FO
|
|
|
13
34
|
|
|
14
35
|
if (process.platform === "win32") {
|
|
15
36
|
try {
|
|
16
|
-
const psCmd = `Get-CimInstance Win32_Process | Where-Object { ($_.CommandLine -like '*mcp-server/index.js*' -or $_.CommandLine -like '*mcp-server\\\\index.js*') -and $_.CommandLine -notlike '*install*' -and $_.ProcessId -ne ${currentPid} -and $_.ProcessId -ne ${ppid} } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }`;
|
|
37
|
+
const psCmd = `Get-CimInstance Win32_Process | Where-Object { ($_.CommandLine -like '*mcp-server/boot.js*' -or $_.CommandLine -like '*mcp-server\\\\boot.js*' -or $_.CommandLine -like '*mcp-server/index.js*' -or $_.CommandLine -like '*mcp-server\\\\index.js*') -and $_.CommandLine -notlike '*install*' -and $_.ProcessId -ne ${currentPid} -and $_.ProcessId -ne ${ppid} } | ForEach-Object { Stop-Process -Id $_.ProcessId -Force }`;
|
|
17
38
|
execSync(`powershell -NoProfile -NonInteractive -Command "${psCmd}"`, { stdio: "ignore" });
|
|
18
39
|
} catch {}
|
|
19
40
|
} else {
|
|
@@ -30,7 +51,7 @@ if (process.env.npm_config_global === "true" || process.env.MEMORY_PREINSTALL_FO
|
|
|
30
51
|
|
|
31
52
|
if (!pid || pid === currentPid || pid === ppid || parentPid === currentPid) continue;
|
|
32
53
|
|
|
33
|
-
const isServer = cmd.includes("mcp-server/
|
|
54
|
+
const isServer = cmd.includes("mcp-server/boot.js") || cmd.includes("mcp-server/index.js");
|
|
34
55
|
const isInstaller = /npm|npx|yarn|pnpm|preinstall|install/i.test(cmd);
|
|
35
56
|
|
|
36
57
|
if (isServer && !isInstaller) {
|
package/package.json
CHANGED
|
@@ -1,18 +1,19 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@lotargo/memory_plugin",
|
|
3
|
-
"version": "1.6.
|
|
3
|
+
"version": "1.6.1",
|
|
4
4
|
"description": "100% local hybrid RAG memory for AI coding agents (OpenCode, Claude Code, Codex, Antigravity). MCP server + plugin: persistent user facts, document ingestion, vector + SQLite FTS5 retrieval across sessions.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "opencode-plugin/index.js",
|
|
7
7
|
"scripts": {
|
|
8
8
|
"preinstall": "node mcp-server/preinstall.js || true",
|
|
9
9
|
"test": "node tests/run_all.js",
|
|
10
|
+
"smoke": "node tests/smoke/e2e_real_embeddings.test.js",
|
|
10
11
|
"benchmark": "node mcp-server/benchmarks/run_benchmarks.js"
|
|
11
12
|
},
|
|
12
13
|
"bin": {
|
|
13
|
-
"memory_plugin": "mcp-server/
|
|
14
|
-
"memory-agent": "mcp-server/
|
|
15
|
-
"memory-cli": "mcp-server/
|
|
14
|
+
"memory_plugin": "mcp-server/boot.js",
|
|
15
|
+
"memory-agent": "mcp-server/boot.js",
|
|
16
|
+
"memory-cli": "mcp-server/cli_boot.js"
|
|
16
17
|
},
|
|
17
18
|
"files": [
|
|
18
19
|
"CHANGELOG.md",
|
|
@@ -28,6 +29,8 @@
|
|
|
28
29
|
"mcp-server/security",
|
|
29
30
|
"mcp-server/storage",
|
|
30
31
|
"mcp-server/tools",
|
|
32
|
+
"mcp-server/boot.js",
|
|
33
|
+
"mcp-server/cli_boot.js",
|
|
31
34
|
"mcp-server/cli.js",
|
|
32
35
|
"mcp-server/index.js",
|
|
33
36
|
"mcp-server/fact_format.js",
|