context-vault 2.8.19 → 2.9.0

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/bin/cli.js CHANGED
@@ -699,6 +699,8 @@ async function configureClaude(tool, vaultDir) {
699
699
  "add",
700
700
  "-s",
701
701
  "user",
702
+ "-e",
703
+ "NODE_OPTIONS=--no-warnings=ExperimentalWarning",
702
704
  "context-vault",
703
705
  "--",
704
706
  "npx",
@@ -719,6 +721,8 @@ async function configureClaude(tool, vaultDir) {
719
721
  "add",
720
722
  "-s",
721
723
  "user",
724
+ "-e",
725
+ "NODE_OPTIONS=--no-warnings=ExperimentalWarning",
722
726
  "context-vault",
723
727
  "--",
724
728
  process.execPath,
@@ -801,6 +805,7 @@ function configureJsonTool(tool, vaultDir) {
801
805
  config[tool.configKey]["context-vault"] = {
802
806
  command: "npx",
803
807
  args: ["-y", "context-vault", "serve", ...serverArgs],
808
+ env: { NODE_OPTIONS: "--no-warnings=ExperimentalWarning" },
804
809
  };
805
810
  } else if (isInstalledPackage()) {
806
811
  const launcherPath = join(HOME, ".context-mcp", "server.mjs");
@@ -809,6 +814,7 @@ function configureJsonTool(tool, vaultDir) {
809
814
  config[tool.configKey]["context-vault"] = {
810
815
  command: process.execPath,
811
816
  args: [launcherPath, ...serverArgs],
817
+ env: { NODE_OPTIONS: "--no-warnings=ExperimentalWarning" },
812
818
  };
813
819
  } else {
814
820
  const serverArgs = [SERVER_PATH];
@@ -816,6 +822,7 @@ function configureJsonTool(tool, vaultDir) {
816
822
  config[tool.configKey]["context-vault"] = {
817
823
  command: process.execPath,
818
824
  args: serverArgs,
825
+ env: { NODE_OPTIONS: "--no-warnings=ExperimentalWarning" },
819
826
  };
820
827
  }
821
828
 
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@context-vault/core",
3
- "version": "2.8.19",
3
+ "version": "2.9.0",
4
4
  "type": "module",
5
5
  "description": "Shared core: capture, index, retrieve, tools, and utilities for context-vault",
6
6
  "main": "src/index.js",
@@ -31,7 +31,7 @@
31
31
  ],
32
32
  "license": "MIT",
33
33
  "engines": {
34
- "node": ">=20"
34
+ "node": ">=24"
35
35
  },
36
36
  "author": "Felix Hellstrom",
37
37
  "repository": {
@@ -1,4 +1,5 @@
1
1
  import { unlinkSync, copyFileSync, existsSync } from "node:fs";
2
+ import { DatabaseSync } from "node:sqlite";
2
3
 
3
4
  export class NativeModuleError extends Error {
4
5
  constructor(originalError) {
@@ -11,55 +12,34 @@ export class NativeModuleError extends Error {
11
12
 
12
13
  function formatNativeModuleError(err) {
13
14
  const msg = err.message || "";
14
- const versionMatch = msg.match(
15
- /was compiled against a different Node\.js version using\s+NODE_MODULE_VERSION (\d+)\. This version of Node\.js requires\s+NODE_MODULE_VERSION (\d+)/,
16
- );
17
-
18
- const lines = [
19
- `Native module failed to load: ${msg}`,
15
+ return [
16
+ `sqlite-vec extension failed to load: ${msg}`,
20
17
  "",
21
18
  ` Running Node.js: ${process.version} (${process.execPath})`,
22
- ];
23
-
24
- if (versionMatch) {
25
- lines.push(` Module compiled for: NODE_MODULE_VERSION ${versionMatch[1]}`);
26
- lines.push(` Current runtime: NODE_MODULE_VERSION ${versionMatch[2]}`);
27
- }
28
-
29
- lines.push(
30
- "",
31
- " Fix: Rebuild native modules for your current Node.js:",
32
- " npm rebuild better-sqlite3 sqlite-vec",
33
19
  "",
34
- " Or reinstall:",
20
+ " Fix: Reinstall context-vault:",
35
21
  " npx -y context-vault@latest setup",
36
- );
37
-
38
- return lines.join("\n");
22
+ ].join("\n");
39
23
  }
40
24
 
41
- let _Database = null;
42
25
  let _sqliteVec = null;
43
26
 
44
- async function loadNativeModules() {
45
- if (_Database && _sqliteVec)
46
- return { Database: _Database, sqliteVec: _sqliteVec };
47
-
48
- try {
49
- const dbMod = await import("better-sqlite3");
50
- _Database = dbMod.default;
51
- } catch (e) {
52
- throw new NativeModuleError(e);
53
- }
27
+ async function loadSqliteVec() {
28
+ if (_sqliteVec) return _sqliteVec;
29
+ const vecMod = await import("sqlite-vec");
30
+ _sqliteVec = vecMod;
31
+ return _sqliteVec;
32
+ }
54
33
 
34
+ function runTransaction(db, fn) {
35
+ db.exec("BEGIN");
55
36
  try {
56
- const vecMod = await import("sqlite-vec");
57
- _sqliteVec = vecMod;
37
+ fn();
38
+ db.exec("COMMIT");
58
39
  } catch (e) {
59
- throw new NativeModuleError(e);
40
+ db.exec("ROLLBACK");
41
+ throw e;
60
42
  }
61
-
62
- return { Database: _Database, sqliteVec: _sqliteVec };
63
43
  }
64
44
 
65
45
  export const SCHEMA_DDL = `
@@ -118,12 +98,12 @@ export const SCHEMA_DDL = `
118
98
  `;
119
99
 
120
100
  export async function initDatabase(dbPath) {
121
- const { Database, sqliteVec } = await loadNativeModules();
101
+ const sqliteVec = await loadSqliteVec();
122
102
 
123
103
  function createDb(path) {
124
- const db = new Database(path);
125
- db.pragma("journal_mode = WAL");
126
- db.pragma("foreign_keys = ON");
104
+ const db = new DatabaseSync(path, { allowExtension: true });
105
+ db.exec("PRAGMA journal_mode = WAL");
106
+ db.exec("PRAGMA foreign_keys = ON");
127
107
  try {
128
108
  sqliteVec.load(db);
129
109
  } catch (e) {
@@ -133,7 +113,7 @@ export async function initDatabase(dbPath) {
133
113
  }
134
114
 
135
115
  const db = createDb(dbPath);
136
- const version = db.pragma("user_version", { simple: true });
116
+ const version = db.prepare("PRAGMA user_version").get().user_version;
137
117
 
138
118
  // Enforce fresh-DB-only — old schemas get a full rebuild (with backup)
139
119
  if (version > 0 && version < 5) {
@@ -167,17 +147,17 @@ export async function initDatabase(dbPath) {
167
147
 
168
148
  const freshDb = createDb(dbPath);
169
149
  freshDb.exec(SCHEMA_DDL);
170
- freshDb.pragma("user_version = 7");
150
+ freshDb.exec("PRAGMA user_version = 7");
171
151
  return freshDb;
172
152
  }
173
153
 
174
154
  if (version < 5) {
175
155
  db.exec(SCHEMA_DDL);
176
- db.pragma("user_version = 7");
156
+ db.exec("PRAGMA user_version = 7");
177
157
  } else if (version === 5) {
178
158
  // v5 -> v6 migration: add multi-tenancy + encryption columns
179
159
  // Wrapped in transaction with duplicate-column guards for idempotent retry
180
- const migrate = db.transaction(() => {
160
+ runTransaction(db, () => {
181
161
  const addColumnSafe = (sql) => {
182
162
  try {
183
163
  db.exec(sql);
@@ -197,21 +177,19 @@ export async function initDatabase(dbPath) {
197
177
  db.exec(
198
178
  `CREATE UNIQUE INDEX IF NOT EXISTS idx_vault_identity ON vault(user_id, kind, identity_key) WHERE identity_key IS NOT NULL`,
199
179
  );
200
- db.pragma("user_version = 7");
180
+ db.exec("PRAGMA user_version = 7");
201
181
  });
202
- migrate();
203
182
  } else if (version === 6) {
204
183
  // v6 -> v7 migration: add team_id column
205
- const migrate = db.transaction(() => {
184
+ runTransaction(db, () => {
206
185
  try {
207
186
  db.exec(`ALTER TABLE vault ADD COLUMN team_id TEXT`);
208
187
  } catch (e) {
209
188
  if (!e.message.includes("duplicate column")) throw e;
210
189
  }
211
190
  db.exec(`CREATE INDEX IF NOT EXISTS idx_vault_team ON vault(team_id)`);
212
- db.pragma("user_version = 7");
191
+ db.exec("PRAGMA user_version = 7");
213
192
  });
214
- migrate();
215
193
  }
216
194
 
217
195
  return db;
@@ -247,15 +225,15 @@ export function prepareStatements(db) {
247
225
  } catch (e) {
248
226
  throw new Error(
249
227
  `Failed to prepare database statements. The database may be corrupted.\n` +
250
- `Try deleting and rebuilding: rm "${db.name}" && context-vault reindex\n` +
228
+ `Try deleting and rebuilding: context-vault reindex\n` +
251
229
  `Original error: ${e.message}`,
252
230
  );
253
231
  }
254
232
  }
255
233
 
256
234
  export function insertVec(stmts, rowid, embedding) {
257
- // sqlite-vec requires BigInt for primary key — better-sqlite3 binds Number as REAL,
258
- // but vec0 virtual tables only accept INTEGER rowids
235
+ // sqlite-vec requires BigInt for primary key — node:sqlite may bind Number as REAL
236
+ // for vec0 virtual tables which only accept INTEGER rowids
259
237
  const safeRowid = BigInt(rowid);
260
238
  if (safeRowid < 1n) throw new Error(`Invalid rowid: ${rowid}`);
261
239
  stmts.insertVecStmt.run(safeRowid, embedding);
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "context-vault",
3
- "version": "2.8.19",
3
+ "version": "2.9.0",
4
4
  "type": "module",
5
5
  "description": "Persistent memory for AI agents — saves and searches knowledge across sessions",
6
6
  "bin": {
@@ -25,7 +25,7 @@
25
25
  ],
26
26
  "license": "MIT",
27
27
  "engines": {
28
- "node": ">=20"
28
+ "node": ">=24"
29
29
  },
30
30
  "author": "Felix Hellstrom",
31
31
  "repository": {
@@ -55,9 +55,8 @@
55
55
  "@context-vault/core"
56
56
  ],
57
57
  "dependencies": {
58
- "@context-vault/core": "^2.8.19",
58
+ "@context-vault/core": "^2.9.0",
59
59
  "@modelcontextprotocol/sdk": "^1.26.0",
60
- "better-sqlite3": "^12.6.2",
61
60
  "sqlite-vec": "^0.1.0"
62
61
  }
63
62
  }
@@ -3,10 +3,10 @@
3
3
  /**
4
4
  * postinstall.js — Post-install setup for context-vault
5
5
  *
6
- * 1. Detects NODE_MODULE_VERSION mismatches for native modules and rebuilds.
7
- * 2. Installs @huggingface/transformers with --ignore-scripts to avoid sharp's
6
+ * 1. Installs @huggingface/transformers with --ignore-scripts to avoid sharp's
8
7
  * broken install lifecycle in global contexts. Semantic search degrades
9
8
  * gracefully if this step fails.
9
+ * 2. Writes local server launcher (global installs only).
10
10
  */
11
11
 
12
12
  import { execSync } from "node:child_process";
@@ -20,46 +20,7 @@ const PKG_ROOT = join(__dirname, "..");
20
20
  const NODE_MODULES = join(PKG_ROOT, "node_modules");
21
21
 
22
22
  async function main() {
23
- // ── 1. Native-module rebuild ──────────────────────────────────────────
24
- let needsRebuild = false;
25
-
26
- try {
27
- await import("better-sqlite3");
28
- } catch (e) {
29
- if (e.message?.includes("NODE_MODULE_VERSION")) {
30
- needsRebuild = true;
31
- }
32
- }
33
-
34
- try {
35
- await import("sqlite-vec");
36
- } catch (e) {
37
- if (e.message?.includes("NODE_MODULE_VERSION")) {
38
- needsRebuild = true;
39
- }
40
- }
41
-
42
- if (needsRebuild) {
43
- console.log(
44
- "[context-vault] Rebuilding native modules for Node.js " +
45
- process.version +
46
- "...",
47
- );
48
- try {
49
- execSync("npm rebuild better-sqlite3 sqlite-vec", {
50
- stdio: "inherit",
51
- timeout: 60000,
52
- });
53
- console.log("[context-vault] Native modules rebuilt successfully.");
54
- } catch {
55
- console.error("[context-vault] Warning: native module rebuild failed.");
56
- console.error(
57
- "[context-vault] Try manually: npm rebuild better-sqlite3 sqlite-vec",
58
- );
59
- }
60
- }
61
-
62
- // ── 2. Install @huggingface/transformers (optional) ───────────────────
23
+ // ── 1. Install @huggingface/transformers (optional) ───────────────────
63
24
  // The transformers package depends on `sharp`, whose install script fails
64
25
  // in global npm contexts. We install with --ignore-scripts to skip it —
65
26
  // context-vault only uses text embeddings, not image processing.
@@ -90,7 +51,7 @@ async function main() {
90
51
  }
91
52
  }
92
53
 
93
- // ── 3. Write local server launcher (global installs only) ────────────
54
+ // ── 2. Write local server launcher (global installs only) ────────────
94
55
  // Under npx the path would be stale after cache eviction — configs use
95
56
  // `npx context-vault serve` instead, so skip writing the launcher.
96
57
  const isNpx = PKG_ROOT.includes("/_npx/") || PKG_ROOT.includes("\\_npx\\");
@@ -30,7 +30,7 @@ cpSync(CORE_SRC, CORE_DEST, { recursive: true, dereference: true });
30
30
  rmSync(join(CORE_DEST, "node_modules"), { recursive: true, force: true });
31
31
 
32
32
  // Strip all dependencies from the bundled core's package.json.
33
- // Core's deps (better-sqlite3, sqlite-vec, MCP SDK) are hoisted to
33
+ // Core's deps (sqlite-vec, MCP SDK) are hoisted to
34
34
  // context-vault's own dependencies. @huggingface/transformers is
35
35
  // dynamically imported and installed via postinstall. Leaving them
36
36
  // in the bundled core causes duplicate resolution that breaks native