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.
- package/bin/cli.js +1369 -1774
- package/node_modules/@context-vault/core/dist/capture.d.ts +1 -1
- package/node_modules/@context-vault/core/dist/capture.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/capture.js +34 -47
- package/node_modules/@context-vault/core/dist/capture.js.map +1 -1
- package/node_modules/@context-vault/core/dist/categories.js +30 -30
- package/node_modules/@context-vault/core/dist/config.d.ts +1 -1
- package/node_modules/@context-vault/core/dist/config.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/config.js +37 -43
- package/node_modules/@context-vault/core/dist/config.js.map +1 -1
- package/node_modules/@context-vault/core/dist/constants.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/constants.js +4 -4
- package/node_modules/@context-vault/core/dist/constants.js.map +1 -1
- package/node_modules/@context-vault/core/dist/db.d.ts +2 -2
- package/node_modules/@context-vault/core/dist/db.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/db.js +21 -20
- package/node_modules/@context-vault/core/dist/db.js.map +1 -1
- package/node_modules/@context-vault/core/dist/embed.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/embed.js +11 -11
- package/node_modules/@context-vault/core/dist/embed.js.map +1 -1
- package/node_modules/@context-vault/core/dist/files.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/files.js +12 -13
- package/node_modules/@context-vault/core/dist/files.js.map +1 -1
- package/node_modules/@context-vault/core/dist/formatters.js +5 -5
- package/node_modules/@context-vault/core/dist/frontmatter.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/frontmatter.js +23 -23
- package/node_modules/@context-vault/core/dist/frontmatter.js.map +1 -1
- package/node_modules/@context-vault/core/dist/index.d.ts +1 -1
- package/node_modules/@context-vault/core/dist/index.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/index.js +58 -46
- package/node_modules/@context-vault/core/dist/index.js.map +1 -1
- package/node_modules/@context-vault/core/dist/ingest-url.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/ingest-url.js +30 -33
- package/node_modules/@context-vault/core/dist/ingest-url.js.map +1 -1
- package/node_modules/@context-vault/core/dist/main.d.ts +13 -13
- package/node_modules/@context-vault/core/dist/main.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/main.js +12 -12
- package/node_modules/@context-vault/core/dist/main.js.map +1 -1
- package/node_modules/@context-vault/core/dist/search.d.ts +1 -1
- package/node_modules/@context-vault/core/dist/search.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/search.js +20 -22
- package/node_modules/@context-vault/core/dist/search.js.map +1 -1
- package/node_modules/@context-vault/core/dist/types.d.ts +1 -1
- package/node_modules/@context-vault/core/package.json +1 -1
- package/node_modules/@context-vault/core/src/capture.ts +44 -81
- package/node_modules/@context-vault/core/src/categories.ts +30 -30
- package/node_modules/@context-vault/core/src/config.ts +45 -60
- package/node_modules/@context-vault/core/src/constants.ts +8 -10
- package/node_modules/@context-vault/core/src/db.ts +37 -56
- package/node_modules/@context-vault/core/src/embed.ts +15 -26
- package/node_modules/@context-vault/core/src/files.ts +13 -16
- package/node_modules/@context-vault/core/src/formatters.ts +5 -5
- package/node_modules/@context-vault/core/src/frontmatter.ts +26 -30
- package/node_modules/@context-vault/core/src/index.ts +94 -100
- package/node_modules/@context-vault/core/src/ingest-url.ts +56 -93
- package/node_modules/@context-vault/core/src/main.ts +13 -18
- package/node_modules/@context-vault/core/src/search.ts +34 -56
- package/node_modules/@context-vault/core/src/types.ts +1 -1
- package/package.json +2 -2
- package/scripts/postinstall.js +18 -25
- package/scripts/prepack.js +13 -19
- package/src/archive.js +211 -0
- package/src/error-log.js +7 -7
- package/src/helpers.js +11 -13
- package/src/linking.js +8 -11
- package/src/migrate-dirs.js +139 -0
- package/src/register-tools.js +46 -48
- package/src/server.js +73 -99
- package/src/status.js +35 -71
- package/src/telemetry.js +18 -22
- package/src/temporal.js +19 -30
- package/src/tools/clear-context.js +15 -18
- package/src/tools/context-status.js +37 -57
- package/src/tools/create-snapshot.js +45 -57
- package/src/tools/delete-context.js +11 -12
- package/src/tools/get-context.js +112 -160
- package/src/tools/ingest-project.js +66 -86
- package/src/tools/ingest-url.js +25 -41
- package/src/tools/list-buckets.js +19 -25
- package/src/tools/list-context.js +35 -58
- package/src/tools/save-context.js +126 -182
- package/src/tools/session-start.js +46 -62
package/src/register-tools.js
CHANGED
|
@@ -1,27 +1,25 @@
|
|
|
1
|
-
import { reindex } from
|
|
2
|
-
import { captureAndIndex } from
|
|
3
|
-
import { err } from
|
|
4
|
-
import { sendTelemetryEvent } from
|
|
5
|
-
import { readFileSync } from
|
|
6
|
-
import { join, dirname } from
|
|
7
|
-
import { fileURLToPath } from
|
|
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
|
|
15
|
-
import * as saveContext from
|
|
16
|
-
import * as listContext from
|
|
17
|
-
import * as deleteContext from
|
|
18
|
-
import * as ingestUrl from
|
|
19
|
-
import * as contextStatus from
|
|
20
|
-
import * as clearContext from
|
|
21
|
-
import * as createSnapshot from
|
|
22
|
-
import * as sessionStart from
|
|
23
|
-
import * as listBuckets from
|
|
24
|
-
import * as ingestProject from
|
|
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 =
|
|
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 ===
|
|
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:
|
|
63
|
+
code: 'TIMEOUT',
|
|
69
64
|
timestamp: Date.now(),
|
|
70
65
|
};
|
|
71
66
|
}
|
|
72
67
|
sendTelemetryEvent(ctx.config, {
|
|
73
|
-
event:
|
|
74
|
-
code:
|
|
68
|
+
event: 'tool_error',
|
|
69
|
+
code: 'TIMEOUT',
|
|
75
70
|
tool: toolName,
|
|
76
71
|
cv_version: pkg.version,
|
|
77
72
|
});
|
|
78
73
|
return err(
|
|
79
|
-
|
|
80
|
-
|
|
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:
|
|
82
|
+
code: 'UNKNOWN',
|
|
88
83
|
timestamp: Date.now(),
|
|
89
84
|
};
|
|
90
85
|
}
|
|
91
86
|
sendTelemetryEvent(ctx.config, {
|
|
92
|
-
event:
|
|
93
|
-
code:
|
|
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:
|
|
100
|
-
title: `Unhandled error in ${toolName ??
|
|
101
|
-
body: `${e.message}\n\n${e.stack ??
|
|
102
|
-
tags: [
|
|
103
|
-
source:
|
|
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,
|
|
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)
|
|
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
|
|
4
|
-
import { StdioServerTransport } from
|
|
5
|
-
import {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
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
|
|
22
|
-
import { appendErrorLog } from
|
|
23
|
-
import { sendTelemetryEvent, maybeShowTelemetryNotice } from
|
|
24
|
-
import { embed } from
|
|
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
|
|
32
|
-
import { registerTools } from
|
|
33
|
-
import { pruneExpired } from
|
|
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 =
|
|
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 =
|
|
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,
|
|
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,
|
|
52
|
+
const markerPath = join(config.vaultDir, '.context-mcp');
|
|
65
53
|
const markerData = existsSync(markerPath)
|
|
66
|
-
? JSON.parse(readFileSync(markerPath,
|
|
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
|
-
) +
|
|
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 =
|
|
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 ?
|
|
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 =
|
|
106
|
+
phase = 'SERVER';
|
|
123
107
|
const server = new McpServer(
|
|
124
|
-
{ name:
|
|
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,
|
|
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(
|
|
150
|
-
db.exec(
|
|
131
|
+
console.error('[context-vault] Rolling back active transaction...');
|
|
132
|
+
db.exec('ROLLBACK');
|
|
151
133
|
}
|
|
152
|
-
db.pragma(
|
|
134
|
+
db.pragma('wal_checkpoint(TRUNCATE)');
|
|
153
135
|
db.close();
|
|
154
|
-
console.error(
|
|
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(
|
|
186
|
-
process.on(
|
|
167
|
+
process.on('SIGINT', () => shutdown('SIGINT'));
|
|
168
|
+
process.on('SIGTERM', () => shutdown('SIGTERM'));
|
|
187
169
|
|
|
188
|
-
phase =
|
|
170
|
+
phase = 'CONNECTED';
|
|
189
171
|
const transport = new StdioServerTransport();
|
|
190
172
|
await server.connect(transport);
|
|
191
173
|
|
|
192
174
|
setTimeout(() => {
|
|
193
|
-
import(
|
|
175
|
+
import('node:child_process')
|
|
194
176
|
.then(({ execSync }) => {
|
|
195
177
|
try {
|
|
196
|
-
const latest = execSync(
|
|
197
|
-
encoding:
|
|
178
|
+
const latest = execSync('npm view context-vault version', {
|
|
179
|
+
encoding: 'utf-8',
|
|
198
180
|
timeout: 5000,
|
|
199
|
-
stdio: [
|
|
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(),
|
|
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 ||
|
|
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,
|
|
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:
|
|
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,
|
|
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
|
-
|
|
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 ||
|
|
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(
|
|
274
|
-
const dataDir = join(homedir(),
|
|
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:
|
|
251
|
+
error_type: 'uncaughtException',
|
|
278
252
|
message: err.message,
|
|
279
|
-
stack: err.stack?.split(
|
|
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,
|
|
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(
|
|
293
|
-
const dataDir = join(homedir(),
|
|
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:
|
|
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,
|
|
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
|
});
|