context-vault 3.13.0 → 3.16.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/bin/cli.js +263 -414
- package/dist/error-log.d.ts +2 -0
- package/dist/error-log.d.ts.map +1 -1
- package/dist/error-log.js +31 -1
- package/dist/error-log.js.map +1 -1
- package/dist/register-tools.d.ts.map +1 -1
- package/dist/register-tools.js +4 -0
- package/dist/register-tools.js.map +1 -1
- package/dist/server.js +23 -426
- package/dist/server.js.map +1 -1
- package/dist/status.d.ts.map +1 -1
- package/dist/status.js +17 -0
- package/dist/status.js.map +1 -1
- package/dist/tools/context-status.d.ts.map +1 -1
- package/dist/tools/context-status.js +26 -1
- package/dist/tools/context-status.js.map +1 -1
- package/dist/tools/delete-context.d.ts +1 -1
- package/dist/tools/delete-context.d.ts.map +1 -1
- package/dist/tools/delete-context.js +15 -2
- package/dist/tools/delete-context.js.map +1 -1
- package/dist/tools/get-context.d.ts.map +1 -1
- package/dist/tools/get-context.js +3 -2
- package/dist/tools/get-context.js.map +1 -1
- package/dist/tools/list-context.d.ts +7 -15
- package/dist/tools/list-context.d.ts.map +1 -1
- package/dist/tools/list-context.js +570 -111
- package/dist/tools/list-context.js.map +1 -1
- package/dist/tools/publish-to-team.js +1 -1
- package/dist/tools/publish-to-team.js.map +1 -1
- package/dist/tools/save-context.js +2 -2
- package/dist/tools/save-context.js.map +1 -1
- package/dist/tools/session-start.d.ts +20 -7
- package/dist/tools/session-start.d.ts.map +1 -1
- package/dist/tools/session-start.js +406 -439
- package/dist/tools/session-start.js.map +1 -1
- package/node_modules/@context-vault/core/dist/capture.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/capture.js +4 -0
- package/node_modules/@context-vault/core/dist/capture.js.map +1 -1
- package/node_modules/@context-vault/core/dist/categories.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/categories.js +8 -0
- package/node_modules/@context-vault/core/dist/categories.js.map +1 -1
- package/node_modules/@context-vault/core/dist/compact.d.ts +38 -0
- package/node_modules/@context-vault/core/dist/compact.d.ts.map +1 -0
- package/node_modules/@context-vault/core/dist/compact.js +127 -0
- package/node_modules/@context-vault/core/dist/compact.js.map +1 -0
- package/node_modules/@context-vault/core/dist/config.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/config.js +12 -0
- package/node_modules/@context-vault/core/dist/config.js.map +1 -1
- package/node_modules/@context-vault/core/dist/db.d.ts +1 -1
- package/node_modules/@context-vault/core/dist/db.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/db.js +40 -4
- package/node_modules/@context-vault/core/dist/db.js.map +1 -1
- package/node_modules/@context-vault/core/dist/main.d.ts +6 -2
- package/node_modules/@context-vault/core/dist/main.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/main.js +5 -1
- package/node_modules/@context-vault/core/dist/main.js.map +1 -1
- package/node_modules/@context-vault/core/dist/search.d.ts +13 -1
- package/node_modules/@context-vault/core/dist/search.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/search.js +50 -5
- package/node_modules/@context-vault/core/dist/search.js.map +1 -1
- package/node_modules/@context-vault/core/dist/tier-analysis.d.ts +36 -0
- package/node_modules/@context-vault/core/dist/tier-analysis.d.ts.map +1 -0
- package/node_modules/@context-vault/core/dist/tier-analysis.js +227 -0
- package/node_modules/@context-vault/core/dist/tier-analysis.js.map +1 -0
- package/node_modules/@context-vault/core/dist/types.d.ts +12 -0
- package/node_modules/@context-vault/core/dist/types.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/watch.d.ts +21 -0
- package/node_modules/@context-vault/core/dist/watch.d.ts.map +1 -0
- package/node_modules/@context-vault/core/dist/watch.js +230 -0
- package/node_modules/@context-vault/core/dist/watch.js.map +1 -0
- package/node_modules/@context-vault/core/package.json +13 -1
- package/node_modules/@context-vault/core/src/capture.ts +4 -0
- package/node_modules/@context-vault/core/src/categories.ts +8 -0
- package/node_modules/@context-vault/core/src/compact.ts +183 -0
- package/node_modules/@context-vault/core/src/config.ts +8 -0
- package/node_modules/@context-vault/core/src/db.ts +40 -4
- package/node_modules/@context-vault/core/src/main.ts +10 -0
- package/node_modules/@context-vault/core/src/search.ts +55 -4
- package/node_modules/@context-vault/core/src/tier-analysis.ts +299 -0
- package/node_modules/@context-vault/core/src/types.ts +10 -0
- package/node_modules/@context-vault/core/src/watch.ts +269 -0
- package/package.json +2 -2
- package/scripts/postinstall.js +26 -1
- package/src/error-log.ts +30 -0
- package/src/register-tools.ts +4 -0
- package/src/server.ts +23 -423
- package/src/status.ts +17 -0
- package/src/tools/context-status.ts +30 -1
- package/src/tools/delete-context.ts +10 -5
- package/src/tools/get-context.ts +3 -2
- package/src/tools/list-context.ts +620 -119
- package/src/tools/publish-to-team.ts +1 -1
- package/src/tools/save-context.ts +2 -2
- package/src/tools/session-start.ts +444 -484
package/bin/cli.js
CHANGED
|
@@ -443,7 +443,6 @@ ${bold('Commands:')}
|
|
|
443
443
|
${cyan('status')} Show vault diagnostics
|
|
444
444
|
${cyan('doctor')} Diagnose and repair common issues
|
|
445
445
|
${cyan('debug')} Generate AI-pasteable debug report
|
|
446
|
-
${cyan('daemon')} start|stop|status Run vault as a shared HTTP daemon (one process, all sessions)
|
|
447
446
|
${cyan('restart')} Stop running MCP server processes (client auto-restarts)
|
|
448
447
|
${cyan('reconnect')} Fix vault path, kill stale servers, re-register MCP, reindex
|
|
449
448
|
${cyan('search')} Search vault entries from CLI
|
|
@@ -453,6 +452,7 @@ ${bold('Commands:')}
|
|
|
453
452
|
${cyan('ingest')} <url> Fetch URL and save as vault entry
|
|
454
453
|
${cyan('ingest-project')} <path> Scan project directory and register as project entity
|
|
455
454
|
${cyan('reindex')} Rebuild search index from knowledge files
|
|
455
|
+
${cyan('reclassify')} Move prompt-history entries from knowledge to event category
|
|
456
456
|
${cyan('sync')} [dir] Index .context/ files into vault DB (use --dry-run to preview)
|
|
457
457
|
${cyan('migrate-dirs')} [--dry-run] Rename plural vault dirs to singular (post-2.18.0)
|
|
458
458
|
${cyan('archive')} Archive old ephemeral/event entries (use --dry-run to preview)
|
|
@@ -2188,6 +2188,101 @@ async function runReindex() {
|
|
|
2188
2188
|
}
|
|
2189
2189
|
}
|
|
2190
2190
|
|
|
2191
|
+
async function runReclassify() {
|
|
2192
|
+
const dryRun = flags.has('--dry-run');
|
|
2193
|
+
const kindFilter = getFlag('--kind');
|
|
2194
|
+
|
|
2195
|
+
const EVENT_KINDS = [
|
|
2196
|
+
'events', 'activity', 'user-prompts', 'agent',
|
|
2197
|
+
'handoff', 'outcome', 'session-review', 'session-summary',
|
|
2198
|
+
];
|
|
2199
|
+
|
|
2200
|
+
const kinds = kindFilter ? [kindFilter] : EVENT_KINDS;
|
|
2201
|
+
const placeholders = kinds.map(() => '?').join(', ');
|
|
2202
|
+
|
|
2203
|
+
const { resolveConfig } = await import('@context-vault/core/config');
|
|
2204
|
+
const { initDatabase, prepareStatements, deleteVec } =
|
|
2205
|
+
await import('@context-vault/core/db');
|
|
2206
|
+
|
|
2207
|
+
const config = resolveConfig();
|
|
2208
|
+
if (!config.vaultDirExists) {
|
|
2209
|
+
console.error(red(`Vault directory not found: ${config.vaultDir}`));
|
|
2210
|
+
console.error('Run ' + cyan('context-vault setup') + ' to configure.');
|
|
2211
|
+
process.exit(1);
|
|
2212
|
+
}
|
|
2213
|
+
|
|
2214
|
+
const db = await initDatabase(config.dbPath);
|
|
2215
|
+
|
|
2216
|
+
const countRow = db
|
|
2217
|
+
.prepare(
|
|
2218
|
+
`SELECT COUNT(*) as cnt FROM vault WHERE kind IN (${placeholders}) AND category = 'knowledge'`
|
|
2219
|
+
)
|
|
2220
|
+
.get(...kinds);
|
|
2221
|
+
const total = countRow.cnt;
|
|
2222
|
+
|
|
2223
|
+
if (total === 0) {
|
|
2224
|
+
console.log(green(' No entries need reclassification.'));
|
|
2225
|
+
db.close();
|
|
2226
|
+
return;
|
|
2227
|
+
}
|
|
2228
|
+
|
|
2229
|
+
if (dryRun) {
|
|
2230
|
+
console.log(`\n ${bold(String(total))} entries would be reclassified from ${yellow('knowledge')} to ${green('event')}:\n`);
|
|
2231
|
+
const breakdown = db
|
|
2232
|
+
.prepare(
|
|
2233
|
+
`SELECT kind, COUNT(*) as cnt FROM vault WHERE kind IN (${placeholders}) AND category = 'knowledge' GROUP BY kind ORDER BY cnt DESC`
|
|
2234
|
+
)
|
|
2235
|
+
.all(...kinds);
|
|
2236
|
+
for (const row of breakdown) {
|
|
2237
|
+
console.log(` ${row.kind}: ${bold(String(row.cnt))}`);
|
|
2238
|
+
}
|
|
2239
|
+
console.log(dim('\n Dry run, no changes made.'));
|
|
2240
|
+
db.close();
|
|
2241
|
+
return;
|
|
2242
|
+
}
|
|
2243
|
+
|
|
2244
|
+
const stmts = prepareStatements(db);
|
|
2245
|
+
const BATCH_SIZE = 1000;
|
|
2246
|
+
let reclassified = 0;
|
|
2247
|
+
let embeddingsRemoved = 0;
|
|
2248
|
+
|
|
2249
|
+
console.log(dim(` Reclassifying ${total} entries...`));
|
|
2250
|
+
|
|
2251
|
+
while (true) {
|
|
2252
|
+
const batch = db
|
|
2253
|
+
.prepare(
|
|
2254
|
+
`SELECT rowid, id FROM vault WHERE kind IN (${placeholders}) AND category = 'knowledge' LIMIT ${BATCH_SIZE}`
|
|
2255
|
+
)
|
|
2256
|
+
.all(...kinds);
|
|
2257
|
+
|
|
2258
|
+
if (batch.length === 0) break;
|
|
2259
|
+
|
|
2260
|
+
const rowids = batch.map((r) => r.rowid);
|
|
2261
|
+
const batchPlaceholders = rowids.map(() => '?').join(', ');
|
|
2262
|
+
|
|
2263
|
+
db.prepare(
|
|
2264
|
+
`UPDATE vault SET category = 'event', indexed = 0 WHERE rowid IN (${batchPlaceholders})`
|
|
2265
|
+
).run(...rowids);
|
|
2266
|
+
|
|
2267
|
+
for (const rowid of rowids) {
|
|
2268
|
+
try {
|
|
2269
|
+
deleteVec(stmts, rowid);
|
|
2270
|
+
embeddingsRemoved++;
|
|
2271
|
+
} catch {
|
|
2272
|
+
// Entry may not have had an embedding
|
|
2273
|
+
}
|
|
2274
|
+
}
|
|
2275
|
+
|
|
2276
|
+
reclassified += batch.length;
|
|
2277
|
+
process.stdout.write(`\r Progress: ${reclassified}/${total}`);
|
|
2278
|
+
}
|
|
2279
|
+
|
|
2280
|
+
db.close();
|
|
2281
|
+
console.log('');
|
|
2282
|
+
console.log(green(` Reclassified ${reclassified} entries from knowledge to event`));
|
|
2283
|
+
console.log(` Embeddings removed: ${embeddingsRemoved}`);
|
|
2284
|
+
}
|
|
2285
|
+
|
|
2191
2286
|
async function runSync() {
|
|
2192
2287
|
const dryRun = flags.has('--dry-run');
|
|
2193
2288
|
const positional = args.slice(1).find((a) => !a.startsWith('--'));
|
|
@@ -2697,6 +2792,7 @@ async function runRestore() {
|
|
|
2697
2792
|
await import('@context-vault/core/db');
|
|
2698
2793
|
const { embed } = await import('@context-vault/core/embed');
|
|
2699
2794
|
const { restoreEntry } = await import('../dist/archive.js');
|
|
2795
|
+
const { restoreCompactedBody } = await import('@context-vault/core/compact');
|
|
2700
2796
|
|
|
2701
2797
|
const config = resolveConfig();
|
|
2702
2798
|
if (!config.vaultDirExists) {
|
|
@@ -2716,6 +2812,26 @@ async function runRestore() {
|
|
|
2716
2812
|
deleteVec: (r) => deleteVec(stmts, r),
|
|
2717
2813
|
};
|
|
2718
2814
|
|
|
2815
|
+
// First try restoring from compacted gz archive
|
|
2816
|
+
const fullBody = restoreCompactedBody(config.vaultDir, entryId);
|
|
2817
|
+
if (fullBody !== null) {
|
|
2818
|
+
// Entry was compacted, restore its body and re-enable indexing
|
|
2819
|
+
db.prepare('UPDATE vault SET body = ?, indexed = 1, updated_at = ? WHERE id = ?')
|
|
2820
|
+
.run(fullBody, new Date().toISOString(), entryId);
|
|
2821
|
+
|
|
2822
|
+
// Remove the gz archive file
|
|
2823
|
+
const { unlinkSync } = await import('node:fs');
|
|
2824
|
+
const { join } = await import('node:path');
|
|
2825
|
+
const gzPath = join(config.vaultDir, '_archive', `${entryId}.md.gz`);
|
|
2826
|
+
try { unlinkSync(gzPath); } catch {}
|
|
2827
|
+
|
|
2828
|
+
db.close();
|
|
2829
|
+
console.log(green(` ✓ Restored compacted entry: ${entryId}`));
|
|
2830
|
+
console.log(dim(' Full body recovered from gzip archive. Entry will be re-indexed on next search.'));
|
|
2831
|
+
return;
|
|
2832
|
+
}
|
|
2833
|
+
|
|
2834
|
+
// Fall back to standard archive restore
|
|
2719
2835
|
const result = await restoreEntry(ctx, entryId);
|
|
2720
2836
|
db.close();
|
|
2721
2837
|
|
|
@@ -2728,6 +2844,65 @@ async function runRestore() {
|
|
|
2728
2844
|
}
|
|
2729
2845
|
}
|
|
2730
2846
|
|
|
2847
|
+
async function runCompact() {
|
|
2848
|
+
const dryRun = flags.has('--dry-run');
|
|
2849
|
+
const tierFlag = getFlag('--tier');
|
|
2850
|
+
|
|
2851
|
+
const { resolveConfig } = await import('@context-vault/core/config');
|
|
2852
|
+
const { initDatabase, prepareStatements, deleteVec, deleteCtxVec } =
|
|
2853
|
+
await import('@context-vault/core/db');
|
|
2854
|
+
const { compact } = await import('@context-vault/core/compact');
|
|
2855
|
+
|
|
2856
|
+
const config = resolveConfig();
|
|
2857
|
+
if (!config.vaultDirExists) {
|
|
2858
|
+
console.error(red(`Vault directory not found: ${config.vaultDir}`));
|
|
2859
|
+
console.error('Run ' + cyan('context-vault setup') + ' to configure.');
|
|
2860
|
+
process.exit(1);
|
|
2861
|
+
}
|
|
2862
|
+
|
|
2863
|
+
const db = await initDatabase(config.dbPath);
|
|
2864
|
+
const stmts = prepareStatements(db);
|
|
2865
|
+
const ctx = {
|
|
2866
|
+
db,
|
|
2867
|
+
config,
|
|
2868
|
+
stmts,
|
|
2869
|
+
deleteVec: (r) => deleteVec(stmts, r),
|
|
2870
|
+
deleteCtxVec: (r) => deleteCtxVec(stmts, r),
|
|
2871
|
+
};
|
|
2872
|
+
|
|
2873
|
+
const options = { dryRun, tier: tierFlag === 'cold' ? 'cold' : undefined };
|
|
2874
|
+
const result = await compact(ctx, options);
|
|
2875
|
+
db.close();
|
|
2876
|
+
|
|
2877
|
+
if (result.candidates === 0) {
|
|
2878
|
+
console.log(green(' No entries eligible for compaction.'));
|
|
2879
|
+
console.log(dim(`\n Criteria: recall_count=0, heat_tier cold/null, age > ${tierFlag === 'cold' ? '30' : '90'} days`));
|
|
2880
|
+
return;
|
|
2881
|
+
}
|
|
2882
|
+
|
|
2883
|
+
if (dryRun) {
|
|
2884
|
+
console.log(
|
|
2885
|
+
`\n ${bold(String(result.candidates))} ${result.candidates === 1 ? 'entry' : 'entries'} eligible for compaction:\n`
|
|
2886
|
+
);
|
|
2887
|
+
let totalBytes = 0;
|
|
2888
|
+
for (const e of result.entries) {
|
|
2889
|
+
const label = e.title ? `${e.kind}: ${e.title.slice(0, 60)}` : `${e.kind} (${e.id})`;
|
|
2890
|
+
const sizeKb = (e.bodySize / 1024).toFixed(1);
|
|
2891
|
+
console.log(` ${dim('-')} ${label} ${dim(`(heat=${e.heat}, age=${e.ageDays}d, body=${sizeKb}KB)`)}`);
|
|
2892
|
+
totalBytes += e.bodySize;
|
|
2893
|
+
}
|
|
2894
|
+
const totalKb = (totalBytes / 1024).toFixed(1);
|
|
2895
|
+
console.log(dim(`\n Total body size: ${totalKb}KB`));
|
|
2896
|
+
console.log(dim(' Dry run, no changes made. Remove --dry-run to compact.'));
|
|
2897
|
+
return;
|
|
2898
|
+
}
|
|
2899
|
+
|
|
2900
|
+
console.log(green(` Compacted ${result.compacted} ${result.compacted === 1 ? 'entry' : 'entries'}.`));
|
|
2901
|
+
const reclaimedKb = (result.bytesReclaimed / 1024).toFixed(1);
|
|
2902
|
+
console.log(dim(` Reclaimed ~${reclaimedKb}KB. Bodies archived to _archive/<id>.md.gz`));
|
|
2903
|
+
console.log(dim(' Use context-vault restore <id> to recover full body.'));
|
|
2904
|
+
}
|
|
2905
|
+
|
|
2731
2906
|
async function runStatus() {
|
|
2732
2907
|
const { resolveConfig } = await import('@context-vault/core/config');
|
|
2733
2908
|
const { initDatabase } = await import('@context-vault/core/db');
|
|
@@ -6232,116 +6407,6 @@ async function runHealth() {
|
|
|
6232
6407
|
if (!healthy) process.exit(1);
|
|
6233
6408
|
}
|
|
6234
6409
|
|
|
6235
|
-
async function runRestart() {
|
|
6236
|
-
const force = flags.has('--force');
|
|
6237
|
-
|
|
6238
|
-
console.log();
|
|
6239
|
-
console.log(` ${bold('◇ context-vault restart')}`);
|
|
6240
|
-
console.log();
|
|
6241
|
-
|
|
6242
|
-
const isWin = platform() === 'win32';
|
|
6243
|
-
let psOutput;
|
|
6244
|
-
try {
|
|
6245
|
-
const psCmd = isWin
|
|
6246
|
-
? 'wmic process where "CommandLine like \'%context-vault%\'" get ProcessId,CommandLine /format:list'
|
|
6247
|
-
: 'ps aux';
|
|
6248
|
-
psOutput = execSync(psCmd, { encoding: 'utf-8', timeout: 5000 });
|
|
6249
|
-
} catch (e) {
|
|
6250
|
-
console.error(red(` Failed to list processes: ${e.message}`));
|
|
6251
|
-
process.exit(1);
|
|
6252
|
-
}
|
|
6253
|
-
|
|
6254
|
-
const currentPid = process.pid;
|
|
6255
|
-
const serverPids = [];
|
|
6256
|
-
|
|
6257
|
-
if (isWin) {
|
|
6258
|
-
const pidMatches = psOutput.matchAll(/ProcessId=(\d+)/g);
|
|
6259
|
-
for (const m of pidMatches) {
|
|
6260
|
-
const pid = parseInt(m[1], 10);
|
|
6261
|
-
if (pid !== currentPid) serverPids.push(pid);
|
|
6262
|
-
}
|
|
6263
|
-
} else {
|
|
6264
|
-
const lines = psOutput.split('\n');
|
|
6265
|
-
for (const line of lines) {
|
|
6266
|
-
const match = line.match(/^\S+\s+(\d+)\s/);
|
|
6267
|
-
if (!match) continue;
|
|
6268
|
-
const pid = parseInt(match[1], 10);
|
|
6269
|
-
if (pid === currentPid) continue;
|
|
6270
|
-
if (
|
|
6271
|
-
/context-vault.*(serve|stdio|server\/index)/.test(line) ||
|
|
6272
|
-
/server\/index\.js.*context-vault/.test(line)
|
|
6273
|
-
) {
|
|
6274
|
-
serverPids.push(pid);
|
|
6275
|
-
}
|
|
6276
|
-
}
|
|
6277
|
-
}
|
|
6278
|
-
|
|
6279
|
-
if (serverPids.length === 0) {
|
|
6280
|
-
console.log(dim(' No running context-vault MCP server processes found.'));
|
|
6281
|
-
console.log(dim(' The MCP client will start the server automatically on the next tool call.'));
|
|
6282
|
-
console.log();
|
|
6283
|
-
return;
|
|
6284
|
-
}
|
|
6285
|
-
|
|
6286
|
-
console.log(
|
|
6287
|
-
` Found ${serverPids.length} server process${serverPids.length === 1 ? '' : 'es'}: ${dim(serverPids.join(', '))}`
|
|
6288
|
-
);
|
|
6289
|
-
console.log();
|
|
6290
|
-
|
|
6291
|
-
const signal = force ? 'SIGKILL' : 'SIGTERM';
|
|
6292
|
-
const killed = [];
|
|
6293
|
-
const failed = [];
|
|
6294
|
-
|
|
6295
|
-
for (const pid of serverPids) {
|
|
6296
|
-
try {
|
|
6297
|
-
process.kill(pid, signal);
|
|
6298
|
-
killed.push(pid);
|
|
6299
|
-
console.log(` ${green('✓')} Sent ${signal} to PID ${pid}`);
|
|
6300
|
-
} catch (e) {
|
|
6301
|
-
if (e.code === 'ESRCH') {
|
|
6302
|
-
console.log(` ${dim('-')} PID ${pid} already gone`);
|
|
6303
|
-
} else {
|
|
6304
|
-
failed.push(pid);
|
|
6305
|
-
console.log(` ${red('✘')} Failed to signal PID ${pid}: ${e.message}`);
|
|
6306
|
-
}
|
|
6307
|
-
}
|
|
6308
|
-
}
|
|
6309
|
-
|
|
6310
|
-
if (!force && killed.length > 0) {
|
|
6311
|
-
await new Promise((resolve) => setTimeout(resolve, 2000));
|
|
6312
|
-
|
|
6313
|
-
for (const pid of killed) {
|
|
6314
|
-
try {
|
|
6315
|
-
process.kill(pid, 0);
|
|
6316
|
-
console.log(` ${yellow('!')} PID ${pid} still running — sending SIGKILL`);
|
|
6317
|
-
try {
|
|
6318
|
-
process.kill(pid, 'SIGKILL');
|
|
6319
|
-
} catch {}
|
|
6320
|
-
} catch {
|
|
6321
|
-
// process is gone — expected
|
|
6322
|
-
}
|
|
6323
|
-
}
|
|
6324
|
-
}
|
|
6325
|
-
|
|
6326
|
-
console.log();
|
|
6327
|
-
|
|
6328
|
-
if (failed.length > 0) {
|
|
6329
|
-
console.log(
|
|
6330
|
-
red(
|
|
6331
|
-
` Could not stop ${failed.length} process${failed.length === 1 ? '' : 'es'}. Try --force.`
|
|
6332
|
-
)
|
|
6333
|
-
);
|
|
6334
|
-
process.exit(1);
|
|
6335
|
-
} else {
|
|
6336
|
-
console.log(
|
|
6337
|
-
green(' Server stopped.') +
|
|
6338
|
-
dim(' The MCP client will restart it automatically on the next tool call.')
|
|
6339
|
-
);
|
|
6340
|
-
}
|
|
6341
|
-
|
|
6342
|
-
console.log();
|
|
6343
|
-
}
|
|
6344
|
-
|
|
6345
6410
|
async function runReconnect() {
|
|
6346
6411
|
console.log();
|
|
6347
6412
|
console.log(` ${bold('◇ context-vault reconnect')}`);
|
|
@@ -6681,321 +6746,94 @@ async function runDebug() {
|
|
|
6681
6746
|
console.log(lines.join('\n'));
|
|
6682
6747
|
}
|
|
6683
6748
|
|
|
6684
|
-
async function
|
|
6685
|
-
const
|
|
6686
|
-
const
|
|
6687
|
-
const
|
|
6688
|
-
|
|
6689
|
-
function readPid() {
|
|
6690
|
-
try {
|
|
6691
|
-
return JSON.parse(readFileSync(pidPath, 'utf-8'));
|
|
6692
|
-
} catch {
|
|
6693
|
-
return null;
|
|
6694
|
-
}
|
|
6695
|
-
}
|
|
6696
|
-
|
|
6697
|
-
function isAlive(pid) {
|
|
6698
|
-
try {
|
|
6699
|
-
process.kill(pid, 0);
|
|
6700
|
-
return true;
|
|
6701
|
-
} catch {
|
|
6702
|
-
return false;
|
|
6703
|
-
}
|
|
6704
|
-
}
|
|
6705
|
-
|
|
6706
|
-
async function pollHealth(port, timeoutMs = 5000) {
|
|
6707
|
-
const start = Date.now();
|
|
6708
|
-
while (Date.now() - start < timeoutMs) {
|
|
6709
|
-
try {
|
|
6710
|
-
const res = await fetch(`http://localhost:${port}/health`);
|
|
6711
|
-
if (res.ok) return await res.json();
|
|
6712
|
-
} catch {}
|
|
6713
|
-
await new Promise((r) => setTimeout(r, 200));
|
|
6714
|
-
}
|
|
6715
|
-
return null;
|
|
6716
|
-
}
|
|
6717
|
-
|
|
6718
|
-
function configureClaudeDaemon(port) {
|
|
6719
|
-
const env = { ...process.env };
|
|
6720
|
-
delete env.CLAUDECODE;
|
|
6721
|
-
|
|
6722
|
-
for (const oldName of ['context-mcp', 'context-vault']) {
|
|
6723
|
-
try {
|
|
6724
|
-
execFileSync('claude', ['mcp', 'remove', oldName, '-s', 'user'], {
|
|
6725
|
-
stdio: 'pipe',
|
|
6726
|
-
env,
|
|
6727
|
-
});
|
|
6728
|
-
} catch {}
|
|
6729
|
-
}
|
|
6749
|
+
async function runTier() {
|
|
6750
|
+
const { resolveConfig } = await import('@context-vault/core/config');
|
|
6751
|
+
const { initDatabase, prepareStatements, insertVec, deleteVec, insertCtxVec, deleteCtxVec } = await import('@context-vault/core/db');
|
|
6752
|
+
const { runTierAnalysis } = await import('@context-vault/core/tier-analysis');
|
|
6730
6753
|
|
|
6731
|
-
|
|
6732
|
-
|
|
6733
|
-
|
|
6734
|
-
|
|
6735
|
-
|
|
6736
|
-
'--transport', 'http',
|
|
6737
|
-
'context-vault',
|
|
6738
|
-
`http://localhost:${port}/mcp`,
|
|
6739
|
-
],
|
|
6740
|
-
{ stdio: 'pipe', env }
|
|
6741
|
-
);
|
|
6742
|
-
} catch (e) {
|
|
6743
|
-
const stderr = e.stderr?.toString().trim();
|
|
6744
|
-
throw new Error(stderr || e.message);
|
|
6745
|
-
}
|
|
6746
|
-
}
|
|
6754
|
+
const config = resolveConfig();
|
|
6755
|
+
const dryRun = args.includes('--dry-run');
|
|
6756
|
+
const hotThreshold = parseInt(argValue('--hot-threshold') || '5', 10);
|
|
6757
|
+
const coldDays = parseInt(argValue('--cold-days') || '30', 10);
|
|
6758
|
+
const bundleThreshold = parseInt(argValue('--bundle-threshold') || '3', 10);
|
|
6747
6759
|
|
|
6748
|
-
|
|
6749
|
-
|
|
6750
|
-
|
|
6751
|
-
|
|
6752
|
-
${
|
|
6753
|
-
|
|
6754
|
-
${cyan('stop')} Stop the running daemon
|
|
6755
|
-
${cyan('status')} Show daemon status
|
|
6756
|
-
${cyan('install')} Start daemon + configure Claude Code to use it
|
|
6757
|
-
${cyan('uninstall')} Stop daemon + revert Claude Code to stdio mode
|
|
6758
|
-
`);
|
|
6759
|
-
return;
|
|
6760
|
+
let db;
|
|
6761
|
+
try {
|
|
6762
|
+
db = await initDatabase(config.dbPath);
|
|
6763
|
+
} catch (e) {
|
|
6764
|
+
console.error(red(` Database not accessible: ${e.message}`));
|
|
6765
|
+
process.exit(1);
|
|
6760
6766
|
}
|
|
6761
6767
|
|
|
6762
|
-
|
|
6763
|
-
|
|
6764
|
-
|
|
6765
|
-
|
|
6766
|
-
|
|
6767
|
-
|
|
6768
|
-
|
|
6769
|
-
|
|
6770
|
-
|
|
6771
|
-
|
|
6772
|
-
try { unlinkSync(pidPath); } catch {}
|
|
6773
|
-
}
|
|
6774
|
-
|
|
6775
|
-
console.log(` Starting daemon on port ${port}...`);
|
|
6776
|
-
|
|
6777
|
-
const vaultDir = getFlag('--vault-dir');
|
|
6778
|
-
const serverArgs = [SERVER_PATH, '--http', '--port', String(port)];
|
|
6779
|
-
if (vaultDir) serverArgs.push('--vault-dir', vaultDir);
|
|
6768
|
+
const stmts = prepareStatements(db);
|
|
6769
|
+
const embedMod = await import('@context-vault/core/embed');
|
|
6770
|
+
const ctx = {
|
|
6771
|
+
db, config, stmts,
|
|
6772
|
+
embed: (text) => embedMod.embed(text),
|
|
6773
|
+
insertVec: (rowid, emb) => insertVec(stmts, rowid, emb),
|
|
6774
|
+
deleteVec: (rowid) => deleteVec(stmts, rowid),
|
|
6775
|
+
insertCtxVec: (rowid, emb) => insertCtxVec(stmts, rowid, emb),
|
|
6776
|
+
deleteCtxVec: (rowid) => deleteCtxVec(stmts, rowid),
|
|
6777
|
+
};
|
|
6780
6778
|
|
|
6781
|
-
|
|
6782
|
-
|
|
6783
|
-
|
|
6784
|
-
|
|
6779
|
+
let report;
|
|
6780
|
+
try {
|
|
6781
|
+
report = await runTierAnalysis(ctx, {
|
|
6782
|
+
hotThreshold,
|
|
6783
|
+
coldDays,
|
|
6784
|
+
coAccessThreshold: bundleThreshold,
|
|
6785
|
+
dryRun,
|
|
6785
6786
|
});
|
|
6786
|
-
|
|
6787
|
-
|
|
6788
|
-
|
|
6789
|
-
if (health) {
|
|
6790
|
-
console.log(` ${green('✓')} Daemon started on http://localhost:${port}/mcp (PID ${health.pid})`);
|
|
6791
|
-
} else {
|
|
6792
|
-
console.error(red(` Failed to start daemon. Check error log: ~/.context-mcp/error.log`));
|
|
6793
|
-
process.exit(1);
|
|
6794
|
-
}
|
|
6795
|
-
|
|
6796
|
-
} else if (sub === 'stop') {
|
|
6797
|
-
const existing = readPid();
|
|
6798
|
-
if (!existing) {
|
|
6799
|
-
console.log(dim(' No daemon running.'));
|
|
6800
|
-
return;
|
|
6801
|
-
}
|
|
6802
|
-
|
|
6803
|
-
if (!isAlive(existing.pid)) {
|
|
6804
|
-
console.log(dim(' Stale PID file (process not running). Cleaning up.'));
|
|
6805
|
-
try { unlinkSync(pidPath); } catch {}
|
|
6806
|
-
return;
|
|
6807
|
-
}
|
|
6808
|
-
|
|
6809
|
-
console.log(` Stopping daemon (PID ${existing.pid})...`);
|
|
6810
|
-
process.kill(existing.pid, 'SIGTERM');
|
|
6811
|
-
|
|
6812
|
-
const deadline = Date.now() + 3000;
|
|
6813
|
-
while (Date.now() < deadline && isAlive(existing.pid)) {
|
|
6814
|
-
await new Promise((r) => setTimeout(r, 200));
|
|
6815
|
-
}
|
|
6816
|
-
|
|
6817
|
-
if (isAlive(existing.pid)) {
|
|
6818
|
-
console.log(` ${yellow('!')} Still alive, sending SIGKILL...`);
|
|
6819
|
-
try { process.kill(existing.pid, 'SIGKILL'); } catch {}
|
|
6820
|
-
}
|
|
6821
|
-
|
|
6822
|
-
try { unlinkSync(pidPath); } catch {}
|
|
6823
|
-
console.log(` ${green('✓')} Daemon stopped.`);
|
|
6824
|
-
|
|
6825
|
-
} else if (sub === 'status') {
|
|
6826
|
-
const existing = readPid();
|
|
6827
|
-
if (!existing) {
|
|
6828
|
-
console.log(dim(' Not running.'));
|
|
6829
|
-
return;
|
|
6830
|
-
}
|
|
6831
|
-
|
|
6832
|
-
if (!isAlive(existing.pid)) {
|
|
6833
|
-
console.log(` ${yellow('!')} Stale PID file (PID ${existing.pid} not found).`);
|
|
6834
|
-
return;
|
|
6835
|
-
}
|
|
6836
|
-
|
|
6837
|
-
try {
|
|
6838
|
-
const res = await fetch(`http://localhost:${existing.port}/health`);
|
|
6839
|
-
const health = await res.json();
|
|
6840
|
-
const uptimeMin = Math.floor(health.uptime / 60);
|
|
6841
|
-
console.log(
|
|
6842
|
-
` ${green('●')} Running (PID ${health.pid}, port ${existing.port}, v${health.version}, ` +
|
|
6843
|
-
`${health.sessions} session${health.sessions === 1 ? '' : 's'}, uptime ${uptimeMin}m)`
|
|
6844
|
-
);
|
|
6845
|
-
} catch (e) {
|
|
6846
|
-
console.log(` ${yellow('!')} Process alive (PID ${existing.pid}) but health check failed: ${e.message}`);
|
|
6847
|
-
}
|
|
6848
|
-
|
|
6849
|
-
} else if (sub === 'install') {
|
|
6850
|
-
const port = parseInt(getFlag('--port') || String(defaultPort), 10);
|
|
6851
|
-
|
|
6852
|
-
// 1. Install LaunchAgent on macOS for auto-start on login
|
|
6853
|
-
if (platform() === 'darwin') {
|
|
6854
|
-
const launchAgentDir = join(HOME, 'Library', 'LaunchAgents');
|
|
6855
|
-
const plistPath = join(launchAgentDir, 'com.context-vault.daemon.plist');
|
|
6856
|
-
const logPath = join(HOME, '.context-mcp', 'daemon.log');
|
|
6857
|
-
const vaultDir = getFlag('--vault-dir');
|
|
6858
|
-
const progArgs = [process.execPath, SERVER_PATH, '--http', '--port', String(port)];
|
|
6859
|
-
if (vaultDir) progArgs.push('--vault-dir', vaultDir);
|
|
6860
|
-
|
|
6861
|
-
const plist = `<?xml version="1.0" encoding="UTF-8"?>
|
|
6862
|
-
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
6863
|
-
<plist version="1.0">
|
|
6864
|
-
<dict>
|
|
6865
|
-
<key>Label</key>
|
|
6866
|
-
<string>com.context-vault.daemon</string>
|
|
6867
|
-
<key>ProgramArguments</key>
|
|
6868
|
-
<array>
|
|
6869
|
-
${progArgs.map(a => ` <string>${a}</string>`).join('\n')}
|
|
6870
|
-
</array>
|
|
6871
|
-
<key>RunAtLoad</key>
|
|
6872
|
-
<true/>
|
|
6873
|
-
<key>KeepAlive</key>
|
|
6874
|
-
<dict>
|
|
6875
|
-
<key>SuccessfulExit</key>
|
|
6876
|
-
<false/>
|
|
6877
|
-
</dict>
|
|
6878
|
-
<key>StandardErrorPath</key>
|
|
6879
|
-
<string>${logPath}</string>
|
|
6880
|
-
<key>StandardOutPath</key>
|
|
6881
|
-
<string>/dev/null</string>
|
|
6882
|
-
<key>EnvironmentVariables</key>
|
|
6883
|
-
<dict>
|
|
6884
|
-
<key>NODE_OPTIONS</key>
|
|
6885
|
-
<string>--no-warnings=ExperimentalWarning</string>
|
|
6886
|
-
<key>CONTEXT_VAULT_NO_DAEMON</key>
|
|
6887
|
-
<string>1</string>
|
|
6888
|
-
</dict>
|
|
6889
|
-
<key>ThrottleInterval</key>
|
|
6890
|
-
<integer>5</integer>
|
|
6891
|
-
</dict>
|
|
6892
|
-
</plist>`;
|
|
6893
|
-
|
|
6894
|
-
mkdirSync(launchAgentDir, { recursive: true });
|
|
6895
|
-
|
|
6896
|
-
// Unload existing agent if present
|
|
6897
|
-
try { execSync(`launchctl unload "${plistPath}" 2>/dev/null`, { stdio: 'pipe' }); } catch {}
|
|
6898
|
-
|
|
6899
|
-
writeFileSync(plistPath, plist);
|
|
6900
|
-
try {
|
|
6901
|
-
execSync(`launchctl load -w "${plistPath}"`, { stdio: 'pipe' });
|
|
6902
|
-
console.log(` ${green('✓')} LaunchAgent installed (auto-starts on login, restarts on crash)`);
|
|
6903
|
-
} catch (e) {
|
|
6904
|
-
console.log(` ${yellow('!')} LaunchAgent write succeeded but launchctl load failed: ${e.message}`);
|
|
6905
|
-
}
|
|
6906
|
-
|
|
6907
|
-
// Wait for launchd to start the daemon
|
|
6908
|
-
const health = await pollHealth(port, 8000);
|
|
6909
|
-
if (health) {
|
|
6910
|
-
console.log(` ${green('✓')} Daemon running (PID ${health.pid})`);
|
|
6911
|
-
} else {
|
|
6912
|
-
console.error(red(` Daemon did not start. Check log: ${logPath}`));
|
|
6913
|
-
process.exit(1);
|
|
6914
|
-
}
|
|
6915
|
-
} else {
|
|
6916
|
-
// Non-macOS: direct spawn (no service manager integration yet)
|
|
6917
|
-
const existing = readPid();
|
|
6918
|
-
if (!existing || !isAlive(existing.pid)) {
|
|
6919
|
-
if (existing) try { unlinkSync(pidPath); } catch {}
|
|
6920
|
-
|
|
6921
|
-
console.log(` Starting daemon on port ${port}...`);
|
|
6922
|
-
const vaultDir = getFlag('--vault-dir');
|
|
6923
|
-
const serverArgs = [SERVER_PATH, '--http', '--port', String(port)];
|
|
6924
|
-
if (vaultDir) serverArgs.push('--vault-dir', vaultDir);
|
|
6925
|
-
|
|
6926
|
-
const child = spawn(process.execPath, serverArgs, {
|
|
6927
|
-
detached: true,
|
|
6928
|
-
stdio: 'ignore',
|
|
6929
|
-
env: { ...process.env, NODE_OPTIONS: '--no-warnings=ExperimentalWarning' },
|
|
6930
|
-
});
|
|
6931
|
-
child.unref();
|
|
6787
|
+
} finally {
|
|
6788
|
+
db.close();
|
|
6789
|
+
}
|
|
6932
6790
|
|
|
6933
|
-
|
|
6934
|
-
|
|
6935
|
-
|
|
6936
|
-
|
|
6937
|
-
|
|
6938
|
-
|
|
6939
|
-
|
|
6940
|
-
|
|
6941
|
-
}
|
|
6942
|
-
}
|
|
6791
|
+
console.log();
|
|
6792
|
+
console.log(` ${bold('◇ context-vault tier')}${dryRun ? dim(' (dry run)') : ''}`);
|
|
6793
|
+
console.log();
|
|
6794
|
+
console.log(` Hot entries (${hotThreshold}+ accesses / 7 days): ${bold(String(report.hotEntries.length))}`);
|
|
6795
|
+
console.log(` Cold entries (no access / ${coldDays} days): ${bold(String(report.coldEntries.length))}`);
|
|
6796
|
+
console.log(` Warm resets: ${bold(String(report.warmReset))}`);
|
|
6797
|
+
console.log(` Co-access bundles: ${bold(String(report.bundles.length))}`);
|
|
6798
|
+
console.log(` Access log pruned: ${bold(String(report.accessLogPruned))} rows`);
|
|
6943
6799
|
|
|
6944
|
-
|
|
6945
|
-
console.log(
|
|
6946
|
-
|
|
6947
|
-
|
|
6948
|
-
|
|
6949
|
-
|
|
6950
|
-
console.log(
|
|
6951
|
-
} catch (e) {
|
|
6952
|
-
console.error(red(` Failed to configure Claude Code: ${e.message}`));
|
|
6953
|
-
process.exit(1);
|
|
6800
|
+
if (report.hotEntries.length > 0) {
|
|
6801
|
+
console.log();
|
|
6802
|
+
console.log(` ${bold('Hot entries:')}`);
|
|
6803
|
+
for (let i = 0; i < report.hotEntries.length; i++) {
|
|
6804
|
+
const e = report.hotEntries[i];
|
|
6805
|
+
const title = (e.title || '(untitled)').slice(0, 50);
|
|
6806
|
+
console.log(` ${i + 1}. "${title}" (${e.accessCount} accesses)`);
|
|
6954
6807
|
}
|
|
6808
|
+
}
|
|
6955
6809
|
|
|
6956
|
-
|
|
6957
|
-
|
|
6958
|
-
console.log(`
|
|
6959
|
-
|
|
6960
|
-
const
|
|
6961
|
-
const
|
|
6962
|
-
|
|
6963
|
-
console.log(`
|
|
6964
|
-
} catch (e) {
|
|
6965
|
-
console.error(red(` Failed to reconfigure Claude Code: ${e.message}`));
|
|
6810
|
+
if (report.coldEntries.length > 0) {
|
|
6811
|
+
console.log();
|
|
6812
|
+
console.log(` ${bold('Cold entries:')} ${dim(`(showing first 10 of ${report.coldEntries.length})`)}`);
|
|
6813
|
+
for (let i = 0; i < Math.min(10, report.coldEntries.length); i++) {
|
|
6814
|
+
const e = report.coldEntries[i];
|
|
6815
|
+
const title = (e.title || '(untitled)').slice(0, 50);
|
|
6816
|
+
const last = e.lastAccessed ? e.lastAccessed.slice(0, 10) : 'never';
|
|
6817
|
+
console.log(` ${i + 1}. "${title}" (last: ${last})`);
|
|
6966
6818
|
}
|
|
6819
|
+
}
|
|
6967
6820
|
|
|
6968
|
-
|
|
6969
|
-
|
|
6970
|
-
|
|
6971
|
-
|
|
6972
|
-
|
|
6973
|
-
|
|
6974
|
-
|
|
6975
|
-
}
|
|
6821
|
+
if (report.bundles.length > 0) {
|
|
6822
|
+
console.log();
|
|
6823
|
+
console.log(` ${bold('Co-access bundles:')}`);
|
|
6824
|
+
for (let i = 0; i < report.bundles.length; i++) {
|
|
6825
|
+
const b = report.bundles[i];
|
|
6826
|
+
const names = b.entries.slice(0, 4).map((e) => e.title || e.id.slice(-8)).join(', ');
|
|
6827
|
+
console.log(` ${i + 1}. [${b.entries.length} entries, weight: ${b.totalWeight}] ${names}`);
|
|
6976
6828
|
}
|
|
6829
|
+
}
|
|
6977
6830
|
|
|
6978
|
-
|
|
6979
|
-
|
|
6980
|
-
if (existing && isAlive(existing.pid)) {
|
|
6981
|
-
console.log(` Stopping daemon (PID ${existing.pid})...`);
|
|
6982
|
-
process.kill(existing.pid, 'SIGTERM');
|
|
6983
|
-
const deadline = Date.now() + 3000;
|
|
6984
|
-
while (Date.now() < deadline && isAlive(existing.pid)) {
|
|
6985
|
-
await new Promise((r) => setTimeout(r, 200));
|
|
6986
|
-
}
|
|
6987
|
-
if (isAlive(existing.pid)) {
|
|
6988
|
-
try { process.kill(existing.pid, 'SIGKILL'); } catch {}
|
|
6989
|
-
}
|
|
6990
|
-
try { unlinkSync(pidPath); } catch {}
|
|
6991
|
-
console.log(` ${green('✓')} Daemon stopped.`);
|
|
6992
|
-
}
|
|
6831
|
+
console.log();
|
|
6832
|
+
}
|
|
6993
6833
|
|
|
6994
|
-
|
|
6995
|
-
|
|
6996
|
-
|
|
6997
|
-
process.exit(1);
|
|
6998
|
-
}
|
|
6834
|
+
function argValue(flag) {
|
|
6835
|
+
const idx = args.indexOf(flag);
|
|
6836
|
+
return idx >= 0 && idx + 1 < args.length ? args[idx + 1] : null;
|
|
6999
6837
|
}
|
|
7000
6838
|
|
|
7001
6839
|
async function runStats() {
|
|
@@ -8230,7 +8068,7 @@ async function main() {
|
|
|
8230
8068
|
|
|
8231
8069
|
if (flags.has('--help') || command === 'help') {
|
|
8232
8070
|
// Commands with their own --help handling: delegate to them
|
|
8233
|
-
const commandsWithHelp = new Set(['save', 'search', 'rules', 'hooks', '
|
|
8071
|
+
const commandsWithHelp = new Set(['save', 'search', 'rules', 'hooks', 'team', 'remote']);
|
|
8234
8072
|
if (!command || command === 'help' || !commandsWithHelp.has(command)) {
|
|
8235
8073
|
showHelp(flags.has('--all'));
|
|
8236
8074
|
return;
|
|
@@ -8259,7 +8097,8 @@ async function main() {
|
|
|
8259
8097
|
await runSwitch();
|
|
8260
8098
|
break;
|
|
8261
8099
|
case 'daemon':
|
|
8262
|
-
|
|
8100
|
+
console.log('The daemon command was removed in v3.16.1. context-vault now runs in stdio mode only.');
|
|
8101
|
+
process.exit(0);
|
|
8263
8102
|
break;
|
|
8264
8103
|
case 'serve':
|
|
8265
8104
|
await runServe();
|
|
@@ -8312,6 +8151,9 @@ async function main() {
|
|
|
8312
8151
|
case 'reindex':
|
|
8313
8152
|
await runReindex();
|
|
8314
8153
|
break;
|
|
8154
|
+
case 'reclassify':
|
|
8155
|
+
await runReclassify();
|
|
8156
|
+
break;
|
|
8315
8157
|
case 'sync':
|
|
8316
8158
|
await runSync();
|
|
8317
8159
|
break;
|
|
@@ -8346,7 +8188,8 @@ async function main() {
|
|
|
8346
8188
|
await runHealth();
|
|
8347
8189
|
break;
|
|
8348
8190
|
case 'restart':
|
|
8349
|
-
|
|
8191
|
+
console.log('The restart command was removed in v3.16.1. Use "context-vault reconnect" instead.');
|
|
8192
|
+
process.exit(0);
|
|
8350
8193
|
break;
|
|
8351
8194
|
case 'reconnect':
|
|
8352
8195
|
await runReconnect();
|
|
@@ -8360,6 +8203,9 @@ async function main() {
|
|
|
8360
8203
|
case 'stats':
|
|
8361
8204
|
await runStats();
|
|
8362
8205
|
break;
|
|
8206
|
+
case 'tier':
|
|
8207
|
+
await runTier();
|
|
8208
|
+
break;
|
|
8363
8209
|
case 'remote':
|
|
8364
8210
|
await runRemote();
|
|
8365
8211
|
break;
|
|
@@ -8369,6 +8215,9 @@ async function main() {
|
|
|
8369
8215
|
case 'public':
|
|
8370
8216
|
await runPublic();
|
|
8371
8217
|
break;
|
|
8218
|
+
case 'compact':
|
|
8219
|
+
await runCompact();
|
|
8220
|
+
break;
|
|
8372
8221
|
default:
|
|
8373
8222
|
console.error(red(`Unknown command: ${command}`));
|
|
8374
8223
|
console.error(`Run ${cyan('context-vault --help')} for usage.`);
|