context-vault 3.13.0 → 3.16.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.
Files changed (89) hide show
  1. package/bin/cli.js +275 -0
  2. package/dist/error-log.d.ts +2 -0
  3. package/dist/error-log.d.ts.map +1 -1
  4. package/dist/error-log.js +31 -1
  5. package/dist/error-log.js.map +1 -1
  6. package/dist/server.js +32 -2
  7. package/dist/server.js.map +1 -1
  8. package/dist/status.d.ts.map +1 -1
  9. package/dist/status.js +17 -0
  10. package/dist/status.js.map +1 -1
  11. package/dist/tools/context-status.d.ts.map +1 -1
  12. package/dist/tools/context-status.js +26 -1
  13. package/dist/tools/context-status.js.map +1 -1
  14. package/dist/tools/delete-context.d.ts +1 -1
  15. package/dist/tools/delete-context.d.ts.map +1 -1
  16. package/dist/tools/delete-context.js +15 -2
  17. package/dist/tools/delete-context.js.map +1 -1
  18. package/dist/tools/get-context.d.ts.map +1 -1
  19. package/dist/tools/get-context.js +3 -2
  20. package/dist/tools/get-context.js.map +1 -1
  21. package/dist/tools/list-context.d.ts +7 -15
  22. package/dist/tools/list-context.d.ts.map +1 -1
  23. package/dist/tools/list-context.js +570 -111
  24. package/dist/tools/list-context.js.map +1 -1
  25. package/dist/tools/publish-to-team.js +1 -1
  26. package/dist/tools/publish-to-team.js.map +1 -1
  27. package/dist/tools/save-context.js +2 -2
  28. package/dist/tools/save-context.js.map +1 -1
  29. package/dist/tools/session-start.d.ts +20 -7
  30. package/dist/tools/session-start.d.ts.map +1 -1
  31. package/dist/tools/session-start.js +406 -439
  32. package/dist/tools/session-start.js.map +1 -1
  33. package/node_modules/@context-vault/core/dist/capture.d.ts.map +1 -1
  34. package/node_modules/@context-vault/core/dist/capture.js +4 -0
  35. package/node_modules/@context-vault/core/dist/capture.js.map +1 -1
  36. package/node_modules/@context-vault/core/dist/categories.d.ts.map +1 -1
  37. package/node_modules/@context-vault/core/dist/categories.js +8 -0
  38. package/node_modules/@context-vault/core/dist/categories.js.map +1 -1
  39. package/node_modules/@context-vault/core/dist/compact.d.ts +38 -0
  40. package/node_modules/@context-vault/core/dist/compact.d.ts.map +1 -0
  41. package/node_modules/@context-vault/core/dist/compact.js +127 -0
  42. package/node_modules/@context-vault/core/dist/compact.js.map +1 -0
  43. package/node_modules/@context-vault/core/dist/config.d.ts.map +1 -1
  44. package/node_modules/@context-vault/core/dist/config.js +12 -0
  45. package/node_modules/@context-vault/core/dist/config.js.map +1 -1
  46. package/node_modules/@context-vault/core/dist/db.d.ts +1 -1
  47. package/node_modules/@context-vault/core/dist/db.d.ts.map +1 -1
  48. package/node_modules/@context-vault/core/dist/db.js +40 -4
  49. package/node_modules/@context-vault/core/dist/db.js.map +1 -1
  50. package/node_modules/@context-vault/core/dist/main.d.ts +6 -2
  51. package/node_modules/@context-vault/core/dist/main.d.ts.map +1 -1
  52. package/node_modules/@context-vault/core/dist/main.js +5 -1
  53. package/node_modules/@context-vault/core/dist/main.js.map +1 -1
  54. package/node_modules/@context-vault/core/dist/search.d.ts +13 -1
  55. package/node_modules/@context-vault/core/dist/search.d.ts.map +1 -1
  56. package/node_modules/@context-vault/core/dist/search.js +50 -5
  57. package/node_modules/@context-vault/core/dist/search.js.map +1 -1
  58. package/node_modules/@context-vault/core/dist/tier-analysis.d.ts +36 -0
  59. package/node_modules/@context-vault/core/dist/tier-analysis.d.ts.map +1 -0
  60. package/node_modules/@context-vault/core/dist/tier-analysis.js +227 -0
  61. package/node_modules/@context-vault/core/dist/tier-analysis.js.map +1 -0
  62. package/node_modules/@context-vault/core/dist/types.d.ts +12 -0
  63. package/node_modules/@context-vault/core/dist/types.d.ts.map +1 -1
  64. package/node_modules/@context-vault/core/dist/watch.d.ts +21 -0
  65. package/node_modules/@context-vault/core/dist/watch.d.ts.map +1 -0
  66. package/node_modules/@context-vault/core/dist/watch.js +230 -0
  67. package/node_modules/@context-vault/core/dist/watch.js.map +1 -0
  68. package/node_modules/@context-vault/core/package.json +13 -1
  69. package/node_modules/@context-vault/core/src/capture.ts +4 -0
  70. package/node_modules/@context-vault/core/src/categories.ts +8 -0
  71. package/node_modules/@context-vault/core/src/compact.ts +183 -0
  72. package/node_modules/@context-vault/core/src/config.ts +8 -0
  73. package/node_modules/@context-vault/core/src/db.ts +40 -4
  74. package/node_modules/@context-vault/core/src/main.ts +10 -0
  75. package/node_modules/@context-vault/core/src/search.ts +55 -4
  76. package/node_modules/@context-vault/core/src/tier-analysis.ts +299 -0
  77. package/node_modules/@context-vault/core/src/types.ts +10 -0
  78. package/node_modules/@context-vault/core/src/watch.ts +269 -0
  79. package/package.json +2 -2
  80. package/src/error-log.ts +30 -0
  81. package/src/server.ts +31 -2
  82. package/src/status.ts +17 -0
  83. package/src/tools/context-status.ts +30 -1
  84. package/src/tools/delete-context.ts +10 -5
  85. package/src/tools/get-context.ts +3 -2
  86. package/src/tools/list-context.ts +620 -119
  87. package/src/tools/publish-to-team.ts +1 -1
  88. package/src/tools/save-context.ts +2 -2
  89. package/src/tools/session-start.ts +444 -484
@@ -1 +1 @@
1
- {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../src/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ import type { BaseCtx, IndexingConfig } from './types.js';
2
+ export interface WatcherOptions {
3
+ vaultDir: string;
4
+ debounceMs?: number;
5
+ indexingConfig?: IndexingConfig;
6
+ onIndex?: (filePath: string, action: 'upsert' | 'delete') => void;
7
+ onError?: (err: Error) => void;
8
+ /** Max concurrent file processing operations. Default 3. */
9
+ maxConcurrency?: number;
10
+ /** Max events queued before dropping oldest. Default 200. */
11
+ maxQueueSize?: number;
12
+ /** Data directory for the lock file (e.g. ~/.context-mcp). */
13
+ dataDir?: string;
14
+ }
15
+ export interface VaultWatcher {
16
+ close: () => void;
17
+ /** Mark a path as self-written so the watcher skips it. TTL: 2 seconds. */
18
+ markSelfWrite: (filePath: string) => void;
19
+ }
20
+ export declare function startWatcher(ctx: BaseCtx, opts: WatcherOptions): VaultWatcher;
21
+ //# sourceMappingURL=watch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EAAE,OAAO,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAO1D,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,cAAc,CAAC;IAChC,OAAO,CAAC,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,MAAM,EAAE,QAAQ,GAAG,QAAQ,KAAK,IAAI,CAAC;IAClE,OAAO,CAAC,EAAE,CAAC,GAAG,EAAE,KAAK,KAAK,IAAI,CAAC;IAC/B,4DAA4D;IAC5D,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,6DAA6D;IAC7D,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,8DAA8D;IAC9D,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,YAAY;IAC3B,KAAK,EAAE,MAAM,IAAI,CAAC;IAClB,2EAA2E;IAC3E,aAAa,EAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,IAAI,CAAC;CAC3C;AAkJD,wBAAgB,YAAY,CAAC,GAAG,EAAE,OAAO,EAAE,IAAI,EAAE,cAAc,GAAG,YAAY,CA8F7E"}
@@ -0,0 +1,230 @@
1
+ import { watch, readFileSync, existsSync, statSync, writeFileSync, unlinkSync, mkdirSync } from 'node:fs';
2
+ import { join, relative, extname, dirname } from 'node:path';
3
+ import { parseFrontmatter, parseEntryFromMarkdown } from './frontmatter.js';
4
+ import { indexEntry } from './index.js';
5
+ import { categoryFor, defaultTierFor } from './categories.js';
6
+ import { dirToKind } from './files.js';
7
+ import { shouldIndex } from './indexing.js';
8
+ const EXCLUDED_DIRS = new Set(['_archive', 'projects']);
9
+ const SELF_WRITE_TTL_MS = 2_000;
10
+ const LOCK_STALE_MS = 60_000;
11
+ function isExcluded(relPath) {
12
+ if (relPath.startsWith('.'))
13
+ return true;
14
+ const parts = relPath.split('/');
15
+ for (const part of parts) {
16
+ if (part.startsWith('.'))
17
+ return true;
18
+ if (EXCLUDED_DIRS.has(part))
19
+ return true;
20
+ }
21
+ return false;
22
+ }
23
+ /**
24
+ * Acquire a watcher lock file so only one instance watches per vault.
25
+ * Returns a release function, or null if another instance holds the lock.
26
+ */
27
+ function acquireWatcherLock(dataDir) {
28
+ const lockPath = join(dataDir, 'watcher.lock');
29
+ mkdirSync(dataDir, { recursive: true });
30
+ if (existsSync(lockPath)) {
31
+ try {
32
+ const content = readFileSync(lockPath, 'utf-8').trim();
33
+ const [pidStr, tsStr] = content.split(':');
34
+ const pid = parseInt(pidStr, 10);
35
+ const ts = parseInt(tsStr, 10);
36
+ // Check if the lock holder is still alive
37
+ if (pid && !isNaN(pid)) {
38
+ try {
39
+ process.kill(pid, 0); // signal 0 = check if alive
40
+ // Process is alive. Check if lock is stale (>60s without refresh).
41
+ if (Date.now() - ts < LOCK_STALE_MS) {
42
+ return null; // another live instance holds the lock
43
+ }
44
+ // Stale lock from a live process that stopped refreshing. Take over.
45
+ }
46
+ catch {
47
+ // Process is dead. Safe to take over the lock.
48
+ }
49
+ }
50
+ }
51
+ catch {
52
+ // Unreadable lock file. Overwrite it.
53
+ }
54
+ }
55
+ const writeLock = () => {
56
+ try {
57
+ writeFileSync(lockPath, `${process.pid}:${Date.now()}`);
58
+ }
59
+ catch { }
60
+ };
61
+ writeLock();
62
+ // Refresh lock periodically so other instances know we're alive
63
+ const refreshInterval = setInterval(writeLock, 15_000);
64
+ refreshInterval.unref();
65
+ return () => {
66
+ clearInterval(refreshInterval);
67
+ try {
68
+ unlinkSync(lockPath);
69
+ }
70
+ catch { }
71
+ };
72
+ }
73
+ async function processFile(ctx, filePath, opts) {
74
+ try {
75
+ if (!existsSync(filePath))
76
+ return;
77
+ const stat = statSync(filePath);
78
+ if (!stat.isFile())
79
+ return;
80
+ const content = readFileSync(filePath, 'utf-8');
81
+ const { meta: fmMeta, body: rawBody } = parseFrontmatter(content);
82
+ const id = fmMeta.id;
83
+ if (!id)
84
+ return; // no frontmatter id = not a vault entry
85
+ const relPath = relative(opts.vaultDir, filePath);
86
+ const topDir = relPath.split('/')[0];
87
+ const kind = fmMeta.kind || dirToKind(topDir) || 'reference';
88
+ const category = categoryFor(kind);
89
+ const tier = fmMeta.tier || defaultTierFor(kind);
90
+ const { title, body, meta } = parseEntryFromMarkdown(kind, rawBody, fmMeta);
91
+ const tags = Array.isArray(fmMeta.tags) ? fmMeta.tags : null;
92
+ const source = typeof fmMeta.source === 'string' ? fmMeta.source : null;
93
+ const identity_key = typeof fmMeta.identity_key === 'string' ? fmMeta.identity_key : null;
94
+ const expires_at = typeof fmMeta.expires_at === 'string' ? fmMeta.expires_at : null;
95
+ const createdAt = typeof fmMeta.created === 'string' ? fmMeta.created : new Date().toISOString();
96
+ const source_files = fmMeta.source_files
97
+ ? fmMeta.source_files
98
+ : null;
99
+ const explicitIndexed = fmMeta.indexed != null ? fmMeta.indexed === true || fmMeta.indexed === 'true' : undefined;
100
+ const indexed = shouldIndex({ kind, category, bodyLength: body.length, explicitIndexed }, opts.indexingConfig);
101
+ const supersedes = Array.isArray(fmMeta.supersedes) ? fmMeta.supersedes : null;
102
+ const related_to = Array.isArray(fmMeta.related_to) ? fmMeta.related_to : null;
103
+ await indexEntry(ctx, {
104
+ id,
105
+ kind,
106
+ category,
107
+ title,
108
+ body,
109
+ meta: meta || undefined,
110
+ tags,
111
+ source,
112
+ filePath,
113
+ createdAt,
114
+ identity_key,
115
+ expires_at,
116
+ source_files,
117
+ tier,
118
+ indexed,
119
+ supersedes,
120
+ related_to,
121
+ });
122
+ opts.onIndex?.(filePath, 'upsert');
123
+ }
124
+ catch (err) {
125
+ opts.onError?.(err);
126
+ }
127
+ }
128
+ function processDelete(ctx, filePath, opts) {
129
+ try {
130
+ const row = ctx.db.prepare('SELECT rowid, id FROM vault WHERE file_path = ?').get(filePath);
131
+ if (!row)
132
+ return;
133
+ ctx.deleteVec(row.rowid);
134
+ ctx.deleteCtxVec(row.rowid);
135
+ ctx.stmts.deleteEntry.run(row.id);
136
+ opts.onIndex?.(filePath, 'delete');
137
+ }
138
+ catch (err) {
139
+ opts.onError?.(err);
140
+ }
141
+ }
142
+ export function startWatcher(ctx, opts) {
143
+ const debounceMs = opts.debounceMs ?? 500;
144
+ const maxConcurrency = opts.maxConcurrency ?? 3;
145
+ const maxQueueSize = opts.maxQueueSize ?? 200;
146
+ // Singleton lock: only one watcher per vault directory
147
+ const dataDir = opts.dataDir || dirname(opts.vaultDir);
148
+ const releaseLock = acquireWatcherLock(dataDir);
149
+ if (!releaseLock) {
150
+ throw new Error('Another instance is already watching this vault. Skipping watcher.');
151
+ }
152
+ const pending = new Map();
153
+ const selfWrites = new Map(); // path -> expiry timestamp
154
+ let activeOps = 0;
155
+ const queue = [];
156
+ let watcher;
157
+ function drainQueue() {
158
+ while (activeOps < maxConcurrency && queue.length > 0) {
159
+ const item = queue.shift();
160
+ activeOps++;
161
+ if (item.isDelete) {
162
+ processDelete(ctx, item.fullPath, opts);
163
+ activeOps--;
164
+ drainQueue();
165
+ }
166
+ else {
167
+ processFile(ctx, item.fullPath, opts)
168
+ .finally(() => {
169
+ activeOps--;
170
+ drainQueue();
171
+ });
172
+ }
173
+ }
174
+ }
175
+ function enqueue(fullPath, isDelete) {
176
+ // Drop oldest if queue is full (back-pressure under bulk operations)
177
+ if (queue.length >= maxQueueSize) {
178
+ const dropped = queue.length - maxQueueSize + 1;
179
+ queue.splice(0, dropped);
180
+ }
181
+ queue.push({ fullPath, isDelete });
182
+ drainQueue();
183
+ }
184
+ try {
185
+ watcher = watch(opts.vaultDir, { recursive: true }, (eventType, filename) => {
186
+ if (!filename)
187
+ return;
188
+ const relPath = filename.replace(/\\/g, '/');
189
+ if (extname(relPath) !== '.md')
190
+ return;
191
+ if (isExcluded(relPath))
192
+ return;
193
+ const fullPath = join(opts.vaultDir, relPath);
194
+ // Skip self-written files (written by this MCP server via save_context)
195
+ const selfExpiry = selfWrites.get(fullPath);
196
+ if (selfExpiry && Date.now() < selfExpiry) {
197
+ selfWrites.delete(fullPath);
198
+ return;
199
+ }
200
+ if (pending.has(fullPath))
201
+ clearTimeout(pending.get(fullPath));
202
+ pending.set(fullPath, setTimeout(() => {
203
+ pending.delete(fullPath);
204
+ const isDelete = !existsSync(fullPath);
205
+ enqueue(fullPath, isDelete);
206
+ }, debounceMs));
207
+ });
208
+ watcher.on('error', (err) => {
209
+ opts.onError?.(err);
210
+ });
211
+ }
212
+ catch (err) {
213
+ releaseLock();
214
+ throw new Error(`Failed to start vault watcher: ${err.message}`);
215
+ }
216
+ return {
217
+ close() {
218
+ for (const timer of pending.values())
219
+ clearTimeout(timer);
220
+ pending.clear();
221
+ queue.length = 0;
222
+ watcher.close();
223
+ releaseLock();
224
+ },
225
+ markSelfWrite(filePath) {
226
+ selfWrites.set(filePath, Date.now() + SELF_WRITE_TTL_MS);
227
+ },
228
+ };
229
+ }
230
+ //# sourceMappingURL=watch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../src/watch.ts"],"names":[],"mappings":"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"}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@context-vault/core",
3
- "version": "3.13.0",
3
+ "version": "3.16.0",
4
4
  "type": "module",
5
5
  "description": "Pure local engine: capture, index, search, and utilities for context-vault",
6
6
  "main": "dist/main.js",
@@ -66,9 +66,21 @@
66
66
  "types": "./dist/context.d.ts",
67
67
  "import": "./dist/context.js"
68
68
  },
69
+ "./compact": {
70
+ "types": "./dist/compact.d.ts",
71
+ "import": "./dist/compact.js"
72
+ },
69
73
  "./indexing": {
70
74
  "types": "./dist/indexing.d.ts",
71
75
  "import": "./dist/indexing.js"
76
+ },
77
+ "./tier-analysis": {
78
+ "types": "./dist/tier-analysis.d.ts",
79
+ "import": "./dist/tier-analysis.js"
80
+ },
81
+ "./watch": {
82
+ "types": "./dist/watch.d.ts",
83
+ "import": "./dist/watch.js"
72
84
  }
73
85
  },
74
86
  "files": [
@@ -296,6 +296,10 @@ export async function captureAndIndex(
296
296
  }
297
297
 
298
298
  const entry = writeEntry(ctx, data);
299
+ // Tell the watcher to skip this file (we just wrote and indexed it ourselves)
300
+ if (typeof (ctx as any).markSelfWrite === 'function') {
301
+ (ctx as any).markSelfWrite(entry.filePath);
302
+ }
299
303
  try {
300
304
  await indexEntry(ctx, entry, precomputedEmbedding);
301
305
  if (entry.supersedes?.length && ctx.stmts.updateSupersededBy) {
@@ -20,6 +20,14 @@ const KIND_CATEGORY: Record<string, string> = {
20
20
  log: 'event',
21
21
  feedback: 'event',
22
22
  inbox: 'event',
23
+ events: 'event',
24
+ activity: 'event',
25
+ 'user-prompts': 'event',
26
+ agent: 'event',
27
+ handoff: 'event',
28
+ outcome: 'event',
29
+ 'session-review': 'event',
30
+ 'session-summary': 'event',
23
31
  };
24
32
 
25
33
  const CATEGORY_DIR_NAMES: Record<string, string> = {
@@ -0,0 +1,183 @@
1
+ import { gzipSync, gunzipSync } from 'node:zlib';
2
+ import { existsSync, mkdirSync, writeFileSync, readFileSync } from 'node:fs';
3
+ import { join } from 'node:path';
4
+ import type { DatabaseSync } from 'node:sqlite';
5
+ import type { VaultConfig, PreparedStatements, VaultEntry } from './types.js';
6
+ import { computeHeatForEntry } from './search.js';
7
+
8
+ export interface CompactCtx {
9
+ db: DatabaseSync;
10
+ config: VaultConfig;
11
+ stmts: PreparedStatements;
12
+ deleteVec: (rowid: number) => void;
13
+ deleteCtxVec: (rowid: number) => void;
14
+ }
15
+
16
+ export interface CompactOptions {
17
+ dryRun?: boolean;
18
+ tier?: 'cold';
19
+ }
20
+
21
+ export interface CompactResult {
22
+ candidates: number;
23
+ compacted: number;
24
+ bytesReclaimed: number;
25
+ entries: Array<{
26
+ id: string;
27
+ kind: string;
28
+ title: string | null;
29
+ bodySize: number;
30
+ heat: number;
31
+ tier: string | null;
32
+ ageDays: number;
33
+ }>;
34
+ }
35
+
36
+ function archiveGzPath(vaultDir: string, id: string): string {
37
+ return join(vaultDir, '_archive', `${id}.md.gz`);
38
+ }
39
+
40
+ function ensureArchiveDir(vaultDir: string): void {
41
+ const dir = join(vaultDir, '_archive');
42
+ if (!existsSync(dir)) {
43
+ mkdirSync(dir, { recursive: true });
44
+ }
45
+ }
46
+
47
+ function summarizeBody(body: string): string {
48
+ if (body.length <= 500) return body;
49
+ return body.slice(0, 500) + '\n\n[compacted: full body archived]';
50
+ }
51
+
52
+ /**
53
+ * Find entries eligible for compaction.
54
+ *
55
+ * Default: heat_tier IS NULL or 'cold', age > 90 days, recall_count = 0
56
+ * With tier='cold': also compact cold entries > 30 days
57
+ */
58
+ function findCompactCandidates(
59
+ db: DatabaseSync,
60
+ options: CompactOptions
61
+ ): Array<VaultEntry & { ageDays: number; heat: number; computedTier: string | null }> {
62
+ const now = Date.now();
63
+
64
+ // Query entries that might be eligible: no recalls, old enough
65
+ const minAgeDays = options.tier === 'cold' ? 30 : 90;
66
+ const cutoff = new Date(now - minAgeDays * 86400000).toISOString();
67
+
68
+ const rows = db
69
+ .prepare(
70
+ `SELECT * FROM vault
71
+ WHERE recall_count = 0
72
+ AND created_at <= ?
73
+ AND indexed != 0
74
+ ORDER BY created_at ASC`
75
+ )
76
+ .all(cutoff) as unknown as VaultEntry[];
77
+
78
+ const candidates: Array<VaultEntry & { ageDays: number; heat: number; computedTier: string | null }> = [];
79
+
80
+ for (const row of rows) {
81
+ const { heat, tier: computedTier } = computeHeatForEntry(row);
82
+
83
+ // Default mode: only null or cold heat_tier
84
+ // With --tier cold: also include cold entries specifically
85
+ const eligible =
86
+ options.tier === 'cold'
87
+ ? computedTier === 'cold' || computedTier === null
88
+ : computedTier === null || computedTier === 'cold';
89
+
90
+ if (!eligible) continue;
91
+
92
+ const ageDays = Math.floor((now - new Date(row.created_at).getTime()) / 86400000);
93
+ candidates.push({ ...row, ageDays, heat, computedTier });
94
+ }
95
+
96
+ return candidates;
97
+ }
98
+
99
+ /**
100
+ * Compact frozen vault entries: gzip full body to _archive, replace with summary,
101
+ * drop embeddings and mark as unindexed.
102
+ */
103
+ export async function compact(
104
+ ctx: CompactCtx,
105
+ options: CompactOptions = {}
106
+ ): Promise<CompactResult> {
107
+ const candidates = findCompactCandidates(ctx.db, options);
108
+
109
+ const result: CompactResult = {
110
+ candidates: candidates.length,
111
+ compacted: 0,
112
+ bytesReclaimed: 0,
113
+ entries: [],
114
+ };
115
+
116
+ if (candidates.length === 0 || options.dryRun) {
117
+ result.entries = candidates.map((c) => ({
118
+ id: c.id,
119
+ kind: c.kind,
120
+ title: c.title,
121
+ bodySize: Buffer.byteLength(c.body, 'utf-8'),
122
+ heat: c.heat,
123
+ tier: c.computedTier,
124
+ ageDays: c.ageDays,
125
+ }));
126
+ return result;
127
+ }
128
+
129
+ ensureArchiveDir(ctx.config.vaultDir);
130
+
131
+ for (const entry of candidates) {
132
+ const bodyBytes = Buffer.byteLength(entry.body, 'utf-8');
133
+ const gzPath = archiveGzPath(ctx.config.vaultDir, entry.id);
134
+
135
+ // Gzip and write the full body
136
+ const compressed = gzipSync(Buffer.from(entry.body, 'utf-8'));
137
+ writeFileSync(gzPath, compressed);
138
+
139
+ // Replace body with summary
140
+ const summary = summarizeBody(entry.body);
141
+
142
+ // Drop embeddings
143
+ const rowidRow = ctx.stmts.getRowid.get(entry.id) as { rowid?: number } | undefined;
144
+ if (rowidRow?.rowid) {
145
+ try { ctx.deleteVec(Number(rowidRow.rowid)); } catch {}
146
+ try { ctx.deleteCtxVec(Number(rowidRow.rowid)); } catch {}
147
+ }
148
+
149
+ // Update the DB entry: set indexed=0, update body
150
+ ctx.db
151
+ .prepare(
152
+ `UPDATE vault SET body = ?, indexed = 0, updated_at = ? WHERE id = ?`
153
+ )
154
+ .run(summary, new Date().toISOString(), entry.id);
155
+
156
+ const summaryBytes = Buffer.byteLength(summary, 'utf-8');
157
+ result.bytesReclaimed += bodyBytes - summaryBytes;
158
+ result.compacted++;
159
+ result.entries.push({
160
+ id: entry.id,
161
+ kind: entry.kind,
162
+ title: entry.title,
163
+ bodySize: bodyBytes,
164
+ heat: entry.heat,
165
+ tier: entry.computedTier,
166
+ ageDays: entry.ageDays,
167
+ });
168
+ }
169
+
170
+ return result;
171
+ }
172
+
173
+ /**
174
+ * Restore a compacted entry's full body from the gzipped archive.
175
+ * Returns the decompressed body or null if no archive exists.
176
+ */
177
+ export function restoreCompactedBody(vaultDir: string, id: string): string | null {
178
+ const gzPath = archiveGzPath(vaultDir, id);
179
+ if (!existsSync(gzPath)) return null;
180
+
181
+ const compressed = readFileSync(gzPath);
182
+ return gunzipSync(compressed).toString('utf-8');
183
+ }
@@ -73,6 +73,7 @@ export function resolveConfig(): VaultConfig {
73
73
  lifecycle: structuredClone(DEFAULT_LIFECYCLE),
74
74
  autoInsights: { ...DEFAULT_AUTO_INSIGHTS },
75
75
  indexing: { ...DEFAULT_INDEXING },
76
+ watch: { enabled: false },
76
77
  };
77
78
 
78
79
  const configPath = join(dataDir, 'config.json');
@@ -162,6 +163,13 @@ export function resolveConfig(): VaultConfig {
162
163
  if (ix.maxBodySize != null) config.indexing.maxBodySize = Number(ix.maxBodySize);
163
164
  if (ix.autoIndexEvents != null) config.indexing.autoIndexEvents = ix.autoIndexEvents === true;
164
165
  }
166
+ if (fc.watch && typeof fc.watch === 'object') {
167
+ const w = fc.watch;
168
+ if (!config.watch) config.watch = { enabled: true };
169
+ if (w.enabled != null) config.watch.enabled = w.enabled === true;
170
+ if (typeof w.path === 'string') config.watch.path = w.path;
171
+ if (w.debounceMs != null) config.watch.debounceMs = Number(w.debounceMs);
172
+ }
165
173
  if (fc.remote && typeof fc.remote === 'object') {
166
174
  const r = fc.remote;
167
175
  config.remote = {
@@ -147,7 +147,8 @@ export const SCHEMA_DDL = `
147
147
  indexed INTEGER DEFAULT 1,
148
148
  recall_count INTEGER DEFAULT 0,
149
149
  recall_sessions INTEGER DEFAULT 0,
150
- last_recalled_at TEXT
150
+ last_recalled_at TEXT,
151
+ heat_tier TEXT CHECK(heat_tier IN ('hot', 'warm', 'cold'))
151
152
  );
152
153
 
153
154
  CREATE INDEX IF NOT EXISTS idx_vault_kind ON vault(kind);
@@ -158,6 +159,7 @@ export const SCHEMA_DDL = `
158
159
  CREATE INDEX IF NOT EXISTS idx_vault_superseded ON vault(superseded_by) WHERE superseded_by IS NOT NULL;
159
160
  CREATE INDEX IF NOT EXISTS idx_vault_tier ON vault(tier);
160
161
  CREATE INDEX IF NOT EXISTS idx_vault_indexed ON vault(indexed);
162
+ CREATE INDEX IF NOT EXISTS idx_vault_heat_tier ON vault(heat_tier) WHERE heat_tier IS NOT NULL;
161
163
 
162
164
  CREATE VIRTUAL TABLE IF NOT EXISTS vault_fts USING fts5(
163
165
  title, body, tags, kind,
@@ -190,9 +192,20 @@ export const SCHEMA_DDL = `
190
192
  last_at TEXT NOT NULL,
191
193
  PRIMARY KEY (entry_a, entry_b)
192
194
  );
195
+
196
+ CREATE TABLE IF NOT EXISTS access_log (
197
+ id INTEGER PRIMARY KEY,
198
+ entry_id TEXT NOT NULL,
199
+ query TEXT,
200
+ session_id TEXT,
201
+ session_goal TEXT,
202
+ accessed_at TEXT NOT NULL DEFAULT (datetime('now'))
203
+ );
204
+ CREATE INDEX IF NOT EXISTS idx_access_log_entry_at ON access_log(entry_id, accessed_at);
205
+ CREATE INDEX IF NOT EXISTS idx_access_log_goal ON access_log(session_goal) WHERE session_goal IS NOT NULL;
193
206
  `;
194
207
 
195
- const CURRENT_VERSION = 18;
208
+ const CURRENT_VERSION = 19;
196
209
 
197
210
  export async function initDatabase(dbPath: string): Promise<DatabaseSync> {
198
211
  const sqliteVec = await loadSqliteVec();
@@ -272,9 +285,32 @@ export async function initDatabase(dbPath: string): Promise<DatabaseSync> {
272
285
  last_at TEXT NOT NULL,
273
286
  PRIMARY KEY (entry_a, entry_b)
274
287
  )`);
275
- db.exec(`PRAGMA user_version = ${CURRENT_VERSION}`);
288
+ db.exec(`PRAGMA user_version = 18`);
276
289
  } catch (e) {
277
290
  console.error(`[context-vault] v17->v18 migration failed: ${(e as Error).message}`);
291
+ return db;
292
+ }
293
+ // Fall through to v18->v19 migration
294
+ }
295
+
296
+ // v18 -> v19: add access_log table and heat_tier column
297
+ if (version === 18 || version === 17 || version === 16 || version === 15) {
298
+ try {
299
+ db.exec(`CREATE TABLE IF NOT EXISTS access_log (
300
+ id INTEGER PRIMARY KEY,
301
+ entry_id TEXT NOT NULL,
302
+ query TEXT,
303
+ session_id TEXT,
304
+ session_goal TEXT,
305
+ accessed_at TEXT NOT NULL DEFAULT (datetime('now'))
306
+ )`);
307
+ db.exec(`CREATE INDEX IF NOT EXISTS idx_access_log_entry_at ON access_log(entry_id, accessed_at)`);
308
+ db.exec(`CREATE INDEX IF NOT EXISTS idx_access_log_goal ON access_log(session_goal) WHERE session_goal IS NOT NULL`);
309
+ db.exec(`ALTER TABLE vault ADD COLUMN heat_tier TEXT CHECK(heat_tier IN ('hot', 'warm', 'cold'))`);
310
+ db.exec(`CREATE INDEX IF NOT EXISTS idx_vault_heat_tier ON vault(heat_tier) WHERE heat_tier IS NOT NULL`);
311
+ db.exec(`PRAGMA user_version = ${CURRENT_VERSION}`);
312
+ } catch (e) {
313
+ console.error(`[context-vault] v18->v19 migration failed: ${(e as Error).message}`);
278
314
  }
279
315
  return db;
280
316
  }
@@ -320,7 +356,7 @@ export async function initDatabase(dbPath: string): Promise<DatabaseSync> {
320
356
  return freshDb;
321
357
  }
322
358
 
323
- if (version < 18) {
359
+ if (version < 19) {
324
360
  db.exec(SCHEMA_DDL);
325
361
  db.exec(`PRAGMA user_version = ${CURRENT_VERSION}`);
326
362
  }