context-vault 3.1.6 → 3.1.7

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.
Files changed (82) hide show
  1. package/bin/cli.js +1369 -1774
  2. package/node_modules/@context-vault/core/dist/capture.d.ts +1 -1
  3. package/node_modules/@context-vault/core/dist/capture.d.ts.map +1 -1
  4. package/node_modules/@context-vault/core/dist/capture.js +34 -47
  5. package/node_modules/@context-vault/core/dist/capture.js.map +1 -1
  6. package/node_modules/@context-vault/core/dist/categories.js +30 -30
  7. package/node_modules/@context-vault/core/dist/config.d.ts +1 -1
  8. package/node_modules/@context-vault/core/dist/config.d.ts.map +1 -1
  9. package/node_modules/@context-vault/core/dist/config.js +37 -43
  10. package/node_modules/@context-vault/core/dist/config.js.map +1 -1
  11. package/node_modules/@context-vault/core/dist/constants.d.ts.map +1 -1
  12. package/node_modules/@context-vault/core/dist/constants.js +4 -4
  13. package/node_modules/@context-vault/core/dist/constants.js.map +1 -1
  14. package/node_modules/@context-vault/core/dist/db.d.ts +2 -2
  15. package/node_modules/@context-vault/core/dist/db.d.ts.map +1 -1
  16. package/node_modules/@context-vault/core/dist/db.js +21 -20
  17. package/node_modules/@context-vault/core/dist/db.js.map +1 -1
  18. package/node_modules/@context-vault/core/dist/embed.d.ts.map +1 -1
  19. package/node_modules/@context-vault/core/dist/embed.js +11 -11
  20. package/node_modules/@context-vault/core/dist/embed.js.map +1 -1
  21. package/node_modules/@context-vault/core/dist/files.d.ts.map +1 -1
  22. package/node_modules/@context-vault/core/dist/files.js +12 -13
  23. package/node_modules/@context-vault/core/dist/files.js.map +1 -1
  24. package/node_modules/@context-vault/core/dist/formatters.js +5 -5
  25. package/node_modules/@context-vault/core/dist/frontmatter.d.ts.map +1 -1
  26. package/node_modules/@context-vault/core/dist/frontmatter.js +23 -23
  27. package/node_modules/@context-vault/core/dist/frontmatter.js.map +1 -1
  28. package/node_modules/@context-vault/core/dist/index.d.ts +1 -1
  29. package/node_modules/@context-vault/core/dist/index.d.ts.map +1 -1
  30. package/node_modules/@context-vault/core/dist/index.js +58 -46
  31. package/node_modules/@context-vault/core/dist/index.js.map +1 -1
  32. package/node_modules/@context-vault/core/dist/ingest-url.d.ts.map +1 -1
  33. package/node_modules/@context-vault/core/dist/ingest-url.js +30 -33
  34. package/node_modules/@context-vault/core/dist/ingest-url.js.map +1 -1
  35. package/node_modules/@context-vault/core/dist/main.d.ts +13 -13
  36. package/node_modules/@context-vault/core/dist/main.d.ts.map +1 -1
  37. package/node_modules/@context-vault/core/dist/main.js +12 -12
  38. package/node_modules/@context-vault/core/dist/main.js.map +1 -1
  39. package/node_modules/@context-vault/core/dist/search.d.ts +1 -1
  40. package/node_modules/@context-vault/core/dist/search.d.ts.map +1 -1
  41. package/node_modules/@context-vault/core/dist/search.js +20 -22
  42. package/node_modules/@context-vault/core/dist/search.js.map +1 -1
  43. package/node_modules/@context-vault/core/dist/types.d.ts +1 -1
  44. package/node_modules/@context-vault/core/package.json +1 -1
  45. package/node_modules/@context-vault/core/src/capture.ts +44 -81
  46. package/node_modules/@context-vault/core/src/categories.ts +30 -30
  47. package/node_modules/@context-vault/core/src/config.ts +45 -60
  48. package/node_modules/@context-vault/core/src/constants.ts +8 -10
  49. package/node_modules/@context-vault/core/src/db.ts +37 -56
  50. package/node_modules/@context-vault/core/src/embed.ts +15 -26
  51. package/node_modules/@context-vault/core/src/files.ts +13 -16
  52. package/node_modules/@context-vault/core/src/formatters.ts +5 -5
  53. package/node_modules/@context-vault/core/src/frontmatter.ts +26 -30
  54. package/node_modules/@context-vault/core/src/index.ts +94 -100
  55. package/node_modules/@context-vault/core/src/ingest-url.ts +56 -93
  56. package/node_modules/@context-vault/core/src/main.ts +13 -18
  57. package/node_modules/@context-vault/core/src/search.ts +34 -56
  58. package/node_modules/@context-vault/core/src/types.ts +1 -1
  59. package/package.json +2 -2
  60. package/scripts/postinstall.js +18 -25
  61. package/scripts/prepack.js +13 -19
  62. package/src/archive.js +211 -0
  63. package/src/error-log.js +7 -7
  64. package/src/helpers.js +11 -13
  65. package/src/linking.js +8 -11
  66. package/src/migrate-dirs.js +139 -0
  67. package/src/register-tools.js +46 -48
  68. package/src/server.js +73 -99
  69. package/src/status.js +35 -71
  70. package/src/telemetry.js +18 -22
  71. package/src/temporal.js +19 -30
  72. package/src/tools/clear-context.js +15 -18
  73. package/src/tools/context-status.js +37 -57
  74. package/src/tools/create-snapshot.js +45 -57
  75. package/src/tools/delete-context.js +11 -12
  76. package/src/tools/get-context.js +112 -160
  77. package/src/tools/ingest-project.js +66 -86
  78. package/src/tools/ingest-url.js +25 -41
  79. package/src/tools/list-buckets.js +19 -25
  80. package/src/tools/list-context.js +35 -58
  81. package/src/tools/save-context.js +126 -182
  82. package/src/tools/session-start.js +46 -62
@@ -1,27 +1,25 @@
1
- import { reindex } from "@context-vault/core/index";
2
- import { captureAndIndex } from "@context-vault/core/capture";
3
- import { err } from "./helpers.js";
4
- import { sendTelemetryEvent } from "./telemetry.js";
5
- import { readFileSync } from "node:fs";
6
- import { join, dirname } from "node:path";
7
- import { fileURLToPath } from "node:url";
1
+ import { reindex } from '@context-vault/core/index';
2
+ import { captureAndIndex } from '@context-vault/core/capture';
3
+ import { err } from './helpers.js';
4
+ import { sendTelemetryEvent } from './telemetry.js';
5
+ import { readFileSync } from 'node:fs';
6
+ import { join, dirname } from 'node:path';
7
+ import { fileURLToPath } from 'node:url';
8
8
 
9
9
  const __dirname = dirname(fileURLToPath(import.meta.url));
10
- const pkg = JSON.parse(
11
- readFileSync(join(__dirname, "..", "package.json"), "utf-8"),
12
- );
10
+ const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
13
11
 
14
- import * as getContext from "./tools/get-context.js";
15
- import * as saveContext from "./tools/save-context.js";
16
- import * as listContext from "./tools/list-context.js";
17
- import * as deleteContext from "./tools/delete-context.js";
18
- import * as ingestUrl from "./tools/ingest-url.js";
19
- import * as contextStatus from "./tools/context-status.js";
20
- import * as clearContext from "./tools/clear-context.js";
21
- import * as createSnapshot from "./tools/create-snapshot.js";
22
- import * as sessionStart from "./tools/session-start.js";
23
- import * as listBuckets from "./tools/list-buckets.js";
24
- import * as ingestProject from "./tools/ingest-project.js";
12
+ import * as getContext from './tools/get-context.js';
13
+ import * as saveContext from './tools/save-context.js';
14
+ import * as listContext from './tools/list-context.js';
15
+ import * as deleteContext from './tools/delete-context.js';
16
+ import * as ingestUrl from './tools/ingest-url.js';
17
+ import * as contextStatus from './tools/context-status.js';
18
+ import * as clearContext from './tools/clear-context.js';
19
+ import * as createSnapshot from './tools/create-snapshot.js';
20
+ import * as sessionStart from './tools/session-start.js';
21
+ import * as listBuckets from './tools/list-buckets.js';
22
+ import * as ingestProject from './tools/ingest-project.js';
25
23
 
26
24
  const toolModules = [
27
25
  getContext,
@@ -37,7 +35,7 @@ const toolModules = [
37
35
  listBuckets,
38
36
  ];
39
37
 
40
- const TOOL_TIMEOUT_MS = 60_000;
38
+ const TOOL_TIMEOUT_MS = 120_000;
41
39
 
42
40
  export function registerTools(server, ctx) {
43
41
  function tracked(handler, toolName) {
@@ -50,57 +48,54 @@ export function registerTools(server, ctx) {
50
48
  const result = await Promise.race([
51
49
  handlerPromise,
52
50
  new Promise((_, reject) => {
53
- timer = setTimeout(
54
- () => reject(new Error("TOOL_TIMEOUT")),
55
- TOOL_TIMEOUT_MS,
56
- );
51
+ timer = setTimeout(() => reject(new Error('TOOL_TIMEOUT')), TOOL_TIMEOUT_MS);
57
52
  }),
58
53
  ]);
59
54
  if (ctx.toolStats) ctx.toolStats.ok++;
60
55
  return result;
61
56
  } catch (e) {
62
- if (e.message === "TOOL_TIMEOUT") {
57
+ if (e.message === 'TOOL_TIMEOUT') {
63
58
  handlerPromise?.catch(() => {});
64
59
  if (ctx.toolStats) {
65
60
  ctx.toolStats.errors++;
66
61
  ctx.toolStats.lastError = {
67
62
  tool: toolName,
68
- code: "TIMEOUT",
63
+ code: 'TIMEOUT',
69
64
  timestamp: Date.now(),
70
65
  };
71
66
  }
72
67
  sendTelemetryEvent(ctx.config, {
73
- event: "tool_error",
74
- code: "TIMEOUT",
68
+ event: 'tool_error',
69
+ code: 'TIMEOUT',
75
70
  tool: toolName,
76
71
  cv_version: pkg.version,
77
72
  });
78
73
  return err(
79
- "Tool timed out after 60s. Try a simpler query or run `context-vault reindex` first.",
80
- "TIMEOUT",
74
+ 'Tool timed out after 120s. Try a simpler query or run `context-vault reindex` first.',
75
+ 'TIMEOUT'
81
76
  );
82
77
  }
83
78
  if (ctx.toolStats) {
84
79
  ctx.toolStats.errors++;
85
80
  ctx.toolStats.lastError = {
86
81
  tool: toolName,
87
- code: "UNKNOWN",
82
+ code: 'UNKNOWN',
88
83
  timestamp: Date.now(),
89
84
  };
90
85
  }
91
86
  sendTelemetryEvent(ctx.config, {
92
- event: "tool_error",
93
- code: "UNKNOWN",
87
+ event: 'tool_error',
88
+ code: 'UNKNOWN',
94
89
  tool: toolName,
95
90
  cv_version: pkg.version,
96
91
  });
97
92
  try {
98
93
  await captureAndIndex(ctx, {
99
- kind: "feedback",
100
- title: `Unhandled error in ${toolName ?? "tool"} call`,
101
- body: `${e.message}\n\n${e.stack ?? ""}`,
102
- tags: ["bug", "auto-captured"],
103
- source: "auto-capture",
94
+ kind: 'feedback',
95
+ title: `Unhandled error in ${toolName ?? 'tool'} call`,
96
+ body: `${e.message}\n\n${e.stack ?? ''}`,
97
+ tags: ['bug', 'auto-captured'],
98
+ source: 'auto-capture',
104
99
  meta: {
105
100
  tool: toolName,
106
101
  error_type: e.constructor?.name,
@@ -109,7 +104,7 @@ export function registerTools(server, ctx) {
109
104
  },
110
105
  });
111
106
  } catch {}
112
- return err(e.message, "INTERNAL_ERROR");
107
+ return err(e.message, 'INTERNAL_ERROR');
113
108
  } finally {
114
109
  clearTimeout(timer);
115
110
  if (ctx.activeOps) ctx.activeOps.count--;
@@ -123,27 +118,30 @@ export function registerTools(server, ctx) {
123
118
  let reindexFailed = false;
124
119
  const MAX_REINDEX_ATTEMPTS = 2;
125
120
 
126
- async function ensureIndexed() {
121
+ async function ensureIndexed({ blocking = true } = {}) {
127
122
  if (reindexDone) return;
128
- if (reindexPromise) return reindexPromise;
123
+ if (reindexPromise) {
124
+ if (blocking) return reindexPromise;
125
+ return; // non-blocking: just ensure it's started
126
+ }
129
127
  const promise = reindex(ctx, { fullSync: true })
130
128
  .then((stats) => {
131
129
  reindexDone = true;
132
130
  const total = stats.added + stats.updated + stats.removed;
133
131
  if (total > 0) {
134
132
  console.error(
135
- `[context-vault] Auto-reindex: +${stats.added} ~${stats.updated} -${stats.removed} (${stats.unchanged} unchanged)`,
133
+ `[context-vault] Auto-reindex: +${stats.added} ~${stats.updated} -${stats.removed} (${stats.unchanged} unchanged)`
136
134
  );
137
135
  }
138
136
  })
139
137
  .catch((e) => {
140
138
  reindexAttempts++;
141
139
  console.error(
142
- `[context-vault] Auto-reindex failed (attempt ${reindexAttempts}/${MAX_REINDEX_ATTEMPTS}): ${e.message}`,
140
+ `[context-vault] Auto-reindex failed (attempt ${reindexAttempts}/${MAX_REINDEX_ATTEMPTS}): ${e.message}`
143
141
  );
144
142
  if (reindexAttempts >= MAX_REINDEX_ATTEMPTS) {
145
143
  console.error(
146
- `[context-vault] Giving up on auto-reindex. Run \`context-vault reindex\` manually to diagnose.`,
144
+ `[context-vault] Giving up on auto-reindex. Run \`context-vault reindex\` manually to diagnose.`
147
145
  );
148
146
  reindexDone = true;
149
147
  reindexFailed = true;
@@ -152,7 +150,7 @@ export function registerTools(server, ctx) {
152
150
  }
153
151
  });
154
152
  reindexPromise = promise;
155
- return reindexPromise;
153
+ if (blocking) return reindexPromise;
156
154
  }
157
155
 
158
156
  const shared = {
@@ -167,7 +165,7 @@ export function registerTools(server, ctx) {
167
165
  mod.name,
168
166
  mod.description,
169
167
  mod.inputSchema,
170
- tracked((args) => mod.handler(args, ctx, shared), mod.name),
168
+ tracked((args) => mod.handler(args, ctx, shared), mod.name)
171
169
  );
172
170
  }
173
171
 
package/src/server.js CHANGED
@@ -1,69 +1,57 @@
1
1
  #!/usr/bin/env node
2
2
 
3
- import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
4
- import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
5
- import {
6
- existsSync,
7
- mkdirSync,
8
- writeFileSync,
9
- readFileSync,
10
- unlinkSync,
11
- } from "node:fs";
12
- import { join, dirname } from "node:path";
13
- import { homedir } from "node:os";
14
- import { fileURLToPath } from "node:url";
3
+ import { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js';
4
+ import { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js';
5
+ import { existsSync, mkdirSync, writeFileSync, readFileSync, unlinkSync } from 'node:fs';
6
+ import { join, dirname } from 'node:path';
7
+ import { homedir } from 'node:os';
8
+ import { fileURLToPath } from 'node:url';
15
9
 
16
10
  const __dirname = dirname(fileURLToPath(import.meta.url));
17
- const pkg = JSON.parse(
18
- readFileSync(join(__dirname, "..", "package.json"), "utf-8"),
19
- );
11
+ const pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8'));
20
12
 
21
- import { resolveConfig } from "@context-vault/core/config";
22
- import { appendErrorLog } from "./error-log.js";
23
- import { sendTelemetryEvent, maybeShowTelemetryNotice } from "./telemetry.js";
24
- import { embed } from "@context-vault/core/embed";
13
+ import { resolveConfig } from '@context-vault/core/config';
14
+ import { appendErrorLog } from './error-log.js';
15
+ import { sendTelemetryEvent, maybeShowTelemetryNotice } from './telemetry.js';
16
+ import { embed } from '@context-vault/core/embed';
25
17
  import {
26
18
  initDatabase,
27
19
  NativeModuleError,
28
20
  prepareStatements,
29
21
  insertVec,
30
22
  deleteVec,
31
- } from "@context-vault/core/db";
32
- import { registerTools } from "./register-tools.js";
33
- import { pruneExpired } from "@context-vault/core/index";
23
+ } from '@context-vault/core/db';
24
+ import { registerTools } from './register-tools.js';
25
+ import { pruneExpired } from '@context-vault/core/index';
34
26
 
35
27
  async function main() {
36
- let phase = "CONFIG";
28
+ let phase = 'CONFIG';
37
29
  let db;
38
30
  let config;
39
31
 
40
32
  try {
41
33
  config = resolveConfig();
42
34
 
43
- phase = "DIRS";
35
+ phase = 'DIRS';
44
36
  mkdirSync(config.dataDir, { recursive: true });
45
37
  mkdirSync(config.vaultDir, { recursive: true });
46
38
  maybeShowTelemetryNotice(config.dataDir);
47
39
 
48
40
  try {
49
- const probe = join(config.vaultDir, ".write-probe");
50
- writeFileSync(probe, "");
41
+ const probe = join(config.vaultDir, '.write-probe');
42
+ writeFileSync(probe, '');
51
43
  unlinkSync(probe);
52
44
  } catch (writeErr) {
53
- console.error(
54
- `[context-vault] FATAL: Vault directory is not writable: ${config.vaultDir}`,
55
- );
45
+ console.error(`[context-vault] FATAL: Vault directory is not writable: ${config.vaultDir}`);
56
46
  console.error(`[context-vault] ${writeErr.message}`);
57
- console.error(
58
- `[context-vault] Fix permissions: chmod u+w "${config.vaultDir}"`,
59
- );
47
+ console.error(`[context-vault] Fix permissions: chmod u+w "${config.vaultDir}"`);
60
48
  process.exit(1);
61
49
  }
62
50
 
63
51
  try {
64
- const markerPath = join(config.vaultDir, ".context-mcp");
52
+ const markerPath = join(config.vaultDir, '.context-mcp');
65
53
  const markerData = existsSync(markerPath)
66
- ? JSON.parse(readFileSync(markerPath, "utf-8"))
54
+ ? JSON.parse(readFileSync(markerPath, 'utf-8'))
67
55
  : {};
68
56
  writeFileSync(
69
57
  markerPath,
@@ -73,13 +61,11 @@ async function main() {
73
61
  version: pkg.version,
74
62
  },
75
63
  null,
76
- 2,
77
- ) + "\n",
64
+ 2
65
+ ) + '\n'
78
66
  );
79
67
  } catch (markerErr) {
80
- console.error(
81
- `[context-vault] Warning: could not write marker file: ${markerErr.message}`,
82
- );
68
+ console.error(`[context-vault] Warning: could not write marker file: ${markerErr.message}`);
83
69
  }
84
70
 
85
71
  config.vaultDirExists = existsSync(config.vaultDir);
@@ -91,7 +77,7 @@ async function main() {
91
77
  console.error(`[context-vault] WARNING: Vault directory not found!`);
92
78
  }
93
79
 
94
- phase = "DB";
80
+ phase = 'DB';
95
81
  db = await initDatabase(config.dbPath);
96
82
  const stmts = prepareStatements(db);
97
83
 
@@ -110,29 +96,25 @@ async function main() {
110
96
  const pruned = await pruneExpired(ctx);
111
97
  if (pruned > 0) {
112
98
  console.error(
113
- `[context-vault] Pruned ${pruned} expired ${pruned === 1 ? "entry" : "entries"}`,
99
+ `[context-vault] Pruned ${pruned} expired ${pruned === 1 ? 'entry' : 'entries'}`
114
100
  );
115
101
  }
116
102
  } catch (pruneErr) {
117
- console.error(
118
- `[context-vault] Warning: startup prune failed: ${pruneErr.message}`,
119
- );
103
+ console.error(`[context-vault] Warning: startup prune failed: ${pruneErr.message}`);
120
104
  }
121
105
 
122
- phase = "SERVER";
106
+ phase = 'SERVER';
123
107
  const server = new McpServer(
124
- { name: "context-vault", version: pkg.version },
125
- { capabilities: { tools: {} } },
108
+ { name: 'context-vault', version: pkg.version },
109
+ { capabilities: { tools: {} } }
126
110
  );
127
111
 
128
112
  let lastVaultDir = config.vaultDir;
129
- Object.defineProperty(ctx, "config", {
113
+ Object.defineProperty(ctx, 'config', {
130
114
  get() {
131
115
  const fresh = resolveConfig();
132
116
  if (fresh.vaultDir !== lastVaultDir) {
133
- console.error(
134
- `[context-vault] Config reloaded: vaultDir changed to ${fresh.vaultDir}`,
135
- );
117
+ console.error(`[context-vault] Config reloaded: vaultDir changed to ${fresh.vaultDir}`);
136
118
  lastVaultDir = fresh.vaultDir;
137
119
  fresh.vaultDirExists = existsSync(fresh.vaultDir);
138
120
  }
@@ -146,12 +128,12 @@ async function main() {
146
128
  function closeDb() {
147
129
  try {
148
130
  if (db.inTransaction) {
149
- console.error("[context-vault] Rolling back active transaction...");
150
- db.exec("ROLLBACK");
131
+ console.error('[context-vault] Rolling back active transaction...');
132
+ db.exec('ROLLBACK');
151
133
  }
152
- db.pragma("wal_checkpoint(TRUNCATE)");
134
+ db.pragma('wal_checkpoint(TRUNCATE)');
153
135
  db.close();
154
- console.error("[context-vault] Database closed cleanly.");
136
+ console.error('[context-vault] Database closed cleanly.');
155
137
  } catch (shutdownErr) {
156
138
  console.error(`[context-vault] Shutdown error: ${shutdownErr.message}`);
157
139
  }
@@ -163,7 +145,7 @@ async function main() {
163
145
 
164
146
  if (ctx.activeOps.count > 0) {
165
147
  console.error(
166
- `[context-vault] Waiting for ${ctx.activeOps.count} in-flight operation(s)...`,
148
+ `[context-vault] Waiting for ${ctx.activeOps.count} in-flight operation(s)...`
167
149
  );
168
150
  const check = setInterval(() => {
169
151
  if (ctx.activeOps.count === 0) {
@@ -174,7 +156,7 @@ async function main() {
174
156
  setTimeout(() => {
175
157
  clearInterval(check);
176
158
  console.error(
177
- `[context-vault] Force shutdown — ${ctx.activeOps.count} operation(s) still running`,
159
+ `[context-vault] Force shutdown — ${ctx.activeOps.count} operation(s) still running`
178
160
  );
179
161
  closeDb();
180
162
  }, 5000);
@@ -182,25 +164,25 @@ async function main() {
182
164
  closeDb();
183
165
  }
184
166
  }
185
- process.on("SIGINT", () => shutdown("SIGINT"));
186
- process.on("SIGTERM", () => shutdown("SIGTERM"));
167
+ process.on('SIGINT', () => shutdown('SIGINT'));
168
+ process.on('SIGTERM', () => shutdown('SIGTERM'));
187
169
 
188
- phase = "CONNECTED";
170
+ phase = 'CONNECTED';
189
171
  const transport = new StdioServerTransport();
190
172
  await server.connect(transport);
191
173
 
192
174
  setTimeout(() => {
193
- import("node:child_process")
175
+ import('node:child_process')
194
176
  .then(({ execSync }) => {
195
177
  try {
196
- const latest = execSync("npm view context-vault version", {
197
- encoding: "utf-8",
178
+ const latest = execSync('npm view context-vault version', {
179
+ encoding: 'utf-8',
198
180
  timeout: 5000,
199
- stdio: ["pipe", "pipe", "pipe"],
181
+ stdio: ['pipe', 'pipe', 'pipe'],
200
182
  }).trim();
201
183
  if (latest && latest !== pkg.version) {
202
184
  console.error(
203
- `[context-vault] Update available: v${pkg.version} → v${latest}. Run: context-vault update`,
185
+ `[context-vault] Update available: v${pkg.version} → v${latest}. Run: context-vault update`
204
186
  );
205
187
  }
206
188
  } catch {}
@@ -208,11 +190,11 @@ async function main() {
208
190
  .catch(() => {});
209
191
  }, 3000);
210
192
  } catch (err) {
211
- const dataDir = config?.dataDir || join(homedir(), ".context-mcp");
193
+ const dataDir = config?.dataDir || join(homedir(), '.context-mcp');
212
194
 
213
195
  const logEntry = {
214
196
  timestamp: new Date().toISOString(),
215
- error_type: err.constructor?.name || "Error",
197
+ error_type: err.constructor?.name || 'Error',
216
198
  message: err.message,
217
199
  node_version: process.version,
218
200
  platform: process.platform,
@@ -224,59 +206,51 @@ async function main() {
224
206
  try {
225
207
  mkdirSync(dataDir, { recursive: true });
226
208
  writeFileSync(
227
- join(dataDir, ".last-error"),
228
- `${logEntry.timestamp} [${phase}] ${err.message}`,
209
+ join(dataDir, '.last-error'),
210
+ `${logEntry.timestamp} [${phase}] ${err.message}`
229
211
  );
230
212
  } catch {}
231
213
 
232
214
  sendTelemetryEvent(config, {
233
- event: "startup_error",
215
+ event: 'startup_error',
234
216
  code: phase,
235
217
  tool: null,
236
218
  cv_version: pkg.version,
237
219
  });
238
220
 
239
221
  if (err instanceof NativeModuleError) {
240
- console.error("");
241
- console.error(
242
- "╔══════════════════════════════════════════════════════════════╗",
243
- );
244
- console.error(
245
- "║ context-vault: Native Module Error ║",
246
- );
247
- console.error(
248
- "╚══════════════════════════════════════════════════════════════╝",
249
- );
250
- console.error("");
222
+ console.error('');
223
+ console.error('╔══════════════════════════════════════════════════════════════╗');
224
+ console.error('║ context-vault: Native Module Error ║');
225
+ console.error('╚══════════════════════════════════════════════════════════════╝');
226
+ console.error('');
251
227
  console.error(err.message);
252
- console.error("");
228
+ console.error('');
253
229
  console.error(` Node.js path: ${process.execPath}`);
254
230
  console.error(` Node.js version: ${process.version}`);
255
- console.error(` Error log: ${join(dataDir, "error.log")}`);
256
- console.error("");
231
+ console.error(` Error log: ${join(dataDir, 'error.log')}`);
232
+ console.error('');
257
233
  process.exit(78);
258
234
  }
259
235
 
260
- console.error(
261
- `[context-vault] Fatal error during ${phase} phase: ${err.message}`,
262
- );
263
- console.error(`[context-vault] Error log: ${join(dataDir, "error.log")}`);
264
- if (phase === "DB") {
236
+ console.error(`[context-vault] Fatal error during ${phase} phase: ${err.message}`);
237
+ console.error(`[context-vault] Error log: ${join(dataDir, 'error.log')}`);
238
+ if (phase === 'DB') {
265
239
  console.error(
266
- `[context-vault] Try deleting the DB file and restarting: rm "${config?.dbPath || "vault.db"}"`,
240
+ `[context-vault] Try deleting the DB file and restarting: rm "${config?.dbPath || 'vault.db'}"`
267
241
  );
268
242
  }
269
243
  process.exit(1);
270
244
  }
271
245
  }
272
246
 
273
- process.on("uncaughtException", (err) => {
274
- const dataDir = join(homedir(), ".context-mcp");
247
+ process.on('uncaughtException', (err) => {
248
+ const dataDir = join(homedir(), '.context-mcp');
275
249
  const logEntry = {
276
250
  timestamp: new Date().toISOString(),
277
- error_type: "uncaughtException",
251
+ error_type: 'uncaughtException',
278
252
  message: err.message,
279
- stack: err.stack?.split("\n").slice(0, 5).join(" | "),
253
+ stack: err.stack?.split('\n').slice(0, 5).join(' | '),
280
254
  node_version: process.version,
281
255
  platform: process.platform,
282
256
  arch: process.arch,
@@ -284,17 +258,17 @@ process.on("uncaughtException", (err) => {
284
258
  };
285
259
  appendErrorLog(dataDir, logEntry);
286
260
  console.error(`[context-vault] Uncaught exception: ${err.message}`);
287
- console.error(`[context-vault] Error log: ${join(dataDir, "error.log")}`);
261
+ console.error(`[context-vault] Error log: ${join(dataDir, 'error.log')}`);
288
262
  console.error(`[context-vault] Run: context-vault doctor`);
289
263
  process.exit(1);
290
264
  });
291
265
 
292
- process.on("unhandledRejection", (reason) => {
293
- const dataDir = join(homedir(), ".context-mcp");
266
+ process.on('unhandledRejection', (reason) => {
267
+ const dataDir = join(homedir(), '.context-mcp');
294
268
  const message = reason instanceof Error ? reason.message : String(reason);
295
269
  const logEntry = {
296
270
  timestamp: new Date().toISOString(),
297
- error_type: "unhandledRejection",
271
+ error_type: 'unhandledRejection',
298
272
  message,
299
273
  node_version: process.version,
300
274
  platform: process.platform,
@@ -303,7 +277,7 @@ process.on("unhandledRejection", (reason) => {
303
277
  };
304
278
  appendErrorLog(dataDir, logEntry);
305
279
  console.error(`[context-vault] Unhandled rejection: ${message}`);
306
- console.error(`[context-vault] Error log: ${join(dataDir, "error.log")}`);
280
+ console.error(`[context-vault] Error log: ${join(dataDir, 'error.log')}`);
307
281
  console.error(`[context-vault] Run: context-vault doctor`);
308
282
  process.exit(1);
309
283
  });