context-vault 2.17.0 → 3.0.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.
Files changed (110) hide show
  1. package/bin/cli.js +783 -108
  2. package/node_modules/@context-vault/core/dist/capture.d.ts +21 -0
  3. package/node_modules/@context-vault/core/dist/capture.d.ts.map +1 -0
  4. package/node_modules/@context-vault/core/dist/capture.js +269 -0
  5. package/node_modules/@context-vault/core/dist/capture.js.map +1 -0
  6. package/node_modules/@context-vault/core/dist/categories.d.ts +6 -0
  7. package/node_modules/@context-vault/core/dist/categories.d.ts.map +1 -0
  8. package/node_modules/@context-vault/core/dist/categories.js +50 -0
  9. package/node_modules/@context-vault/core/dist/categories.js.map +1 -0
  10. package/node_modules/@context-vault/core/dist/config.d.ts +4 -0
  11. package/node_modules/@context-vault/core/dist/config.d.ts.map +1 -0
  12. package/node_modules/@context-vault/core/dist/config.js +190 -0
  13. package/node_modules/@context-vault/core/dist/config.js.map +1 -0
  14. package/node_modules/@context-vault/core/dist/constants.d.ts +33 -0
  15. package/node_modules/@context-vault/core/dist/constants.d.ts.map +1 -0
  16. package/node_modules/@context-vault/core/dist/constants.js +23 -0
  17. package/node_modules/@context-vault/core/dist/constants.js.map +1 -0
  18. package/node_modules/@context-vault/core/dist/db.d.ts +13 -0
  19. package/node_modules/@context-vault/core/dist/db.d.ts.map +1 -0
  20. package/node_modules/@context-vault/core/dist/db.js +191 -0
  21. package/node_modules/@context-vault/core/dist/db.js.map +1 -0
  22. package/node_modules/@context-vault/core/dist/embed.d.ts +5 -0
  23. package/node_modules/@context-vault/core/dist/embed.d.ts.map +1 -0
  24. package/node_modules/@context-vault/core/dist/embed.js +78 -0
  25. package/node_modules/@context-vault/core/dist/embed.js.map +1 -0
  26. package/node_modules/@context-vault/core/dist/files.d.ts +13 -0
  27. package/node_modules/@context-vault/core/dist/files.d.ts.map +1 -0
  28. package/node_modules/@context-vault/core/dist/files.js +66 -0
  29. package/node_modules/@context-vault/core/dist/files.js.map +1 -0
  30. package/node_modules/@context-vault/core/dist/formatters.d.ts +8 -0
  31. package/node_modules/@context-vault/core/dist/formatters.d.ts.map +1 -0
  32. package/node_modules/@context-vault/core/dist/formatters.js +18 -0
  33. package/node_modules/@context-vault/core/dist/formatters.js.map +1 -0
  34. package/node_modules/@context-vault/core/dist/frontmatter.d.ts +12 -0
  35. package/node_modules/@context-vault/core/dist/frontmatter.d.ts.map +1 -0
  36. package/node_modules/@context-vault/core/dist/frontmatter.js +101 -0
  37. package/node_modules/@context-vault/core/dist/frontmatter.js.map +1 -0
  38. package/node_modules/@context-vault/core/dist/index.d.ts +10 -0
  39. package/node_modules/@context-vault/core/dist/index.d.ts.map +1 -0
  40. package/node_modules/@context-vault/core/dist/index.js +297 -0
  41. package/node_modules/@context-vault/core/dist/index.js.map +1 -0
  42. package/node_modules/@context-vault/core/dist/ingest-url.d.ts +20 -0
  43. package/node_modules/@context-vault/core/dist/ingest-url.d.ts.map +1 -0
  44. package/node_modules/@context-vault/core/dist/ingest-url.js +113 -0
  45. package/node_modules/@context-vault/core/dist/ingest-url.js.map +1 -0
  46. package/node_modules/@context-vault/core/dist/main.d.ts +14 -0
  47. package/node_modules/@context-vault/core/dist/main.d.ts.map +1 -0
  48. package/node_modules/@context-vault/core/dist/main.js +25 -0
  49. package/node_modules/@context-vault/core/dist/main.js.map +1 -0
  50. package/node_modules/@context-vault/core/dist/search.d.ts +18 -0
  51. package/node_modules/@context-vault/core/dist/search.d.ts.map +1 -0
  52. package/node_modules/@context-vault/core/dist/search.js +238 -0
  53. package/node_modules/@context-vault/core/dist/search.js.map +1 -0
  54. package/node_modules/@context-vault/core/dist/types.d.ts +176 -0
  55. package/node_modules/@context-vault/core/dist/types.d.ts.map +1 -0
  56. package/node_modules/@context-vault/core/dist/types.js +2 -0
  57. package/node_modules/@context-vault/core/dist/types.js.map +1 -0
  58. package/node_modules/@context-vault/core/package.json +66 -16
  59. package/node_modules/@context-vault/core/src/capture.ts +308 -0
  60. package/node_modules/@context-vault/core/src/categories.ts +54 -0
  61. package/node_modules/@context-vault/core/src/{core/config.js → config.ts} +34 -33
  62. package/node_modules/@context-vault/core/src/{constants.js → constants.ts} +6 -3
  63. package/node_modules/@context-vault/core/src/db.ts +229 -0
  64. package/node_modules/@context-vault/core/src/{index/embed.js → embed.ts} +10 -35
  65. package/node_modules/@context-vault/core/src/files.ts +80 -0
  66. package/node_modules/@context-vault/core/src/{capture/formatters.js → formatters.ts} +13 -11
  67. package/node_modules/@context-vault/core/src/{core/frontmatter.js → frontmatter.ts} +27 -33
  68. package/node_modules/@context-vault/core/src/index.ts +351 -0
  69. package/node_modules/@context-vault/core/src/ingest-url.ts +99 -0
  70. package/node_modules/@context-vault/core/src/main.ts +111 -0
  71. package/node_modules/@context-vault/core/src/search.ts +285 -0
  72. package/node_modules/@context-vault/core/src/types.ts +166 -0
  73. package/package.json +12 -7
  74. package/scripts/postinstall.js +1 -1
  75. package/{node_modules/@context-vault/core/src/core → src}/error-log.js +1 -15
  76. package/{node_modules/@context-vault/core/src/server → src}/helpers.js +9 -4
  77. package/src/linking.js +100 -0
  78. package/{node_modules/@context-vault/core/src/server/tools.js → src/register-tools.js} +14 -15
  79. package/src/{server/index.js → server.js} +8 -35
  80. package/src/status.js +235 -0
  81. package/{node_modules/@context-vault/core/src/core → src}/telemetry.js +9 -19
  82. package/src/temporal.js +97 -0
  83. package/{node_modules/@context-vault/core/src/server → src}/tools/context-status.js +3 -4
  84. package/{node_modules/@context-vault/core/src/server → src}/tools/create-snapshot.js +43 -75
  85. package/{node_modules/@context-vault/core/src/server → src}/tools/delete-context.js +0 -2
  86. package/{node_modules/@context-vault/core/src/server → src}/tools/get-context.js +118 -35
  87. package/{node_modules/@context-vault/core/src/server → src}/tools/ingest-project.js +5 -6
  88. package/{node_modules/@context-vault/core/src/server → src}/tools/ingest-url.js +3 -4
  89. package/{node_modules/@context-vault/core/src/server → src}/tools/list-buckets.js +4 -5
  90. package/{node_modules/@context-vault/core/src/server → src}/tools/list-context.js +3 -6
  91. package/{node_modules/@context-vault/core/src/server → src}/tools/save-context.js +41 -21
  92. package/{node_modules/@context-vault/core/src/server → src}/tools/session-start.js +9 -16
  93. package/node_modules/@context-vault/core/src/capture/file-ops.js +0 -97
  94. package/node_modules/@context-vault/core/src/capture/import-pipeline.js +0 -46
  95. package/node_modules/@context-vault/core/src/capture/importers.js +0 -387
  96. package/node_modules/@context-vault/core/src/capture/index.js +0 -236
  97. package/node_modules/@context-vault/core/src/capture/ingest-url.js +0 -252
  98. package/node_modules/@context-vault/core/src/consolidation/index.js +0 -112
  99. package/node_modules/@context-vault/core/src/core/categories.js +0 -72
  100. package/node_modules/@context-vault/core/src/core/files.js +0 -108
  101. package/node_modules/@context-vault/core/src/core/status.js +0 -350
  102. package/node_modules/@context-vault/core/src/index/db.js +0 -416
  103. package/node_modules/@context-vault/core/src/index/index.js +0 -522
  104. package/node_modules/@context-vault/core/src/index.js +0 -66
  105. package/node_modules/@context-vault/core/src/retrieve/index.js +0 -500
  106. package/node_modules/@context-vault/core/src/server/tools/submit-feedback.js +0 -55
  107. package/node_modules/@context-vault/core/src/sync/sync.js +0 -235
  108. package/src/hooks/post-tool-call.mjs +0 -62
  109. package/src/hooks/session-end.mjs +0 -492
  110. /package/{node_modules/@context-vault/core/src/server → src}/tools/clear-context.js +0 -0
@@ -1,350 +0,0 @@
1
- /**
2
- * status.js — Vault status/diagnostics data gathering
3
- */
4
-
5
- import { existsSync, readdirSync, statSync } from "node:fs";
6
- import { join } from "node:path";
7
- import { walkDir } from "./files.js";
8
- import { isEmbedAvailable } from "../index/embed.js";
9
- import { KIND_STALENESS_DAYS } from "./categories.js";
10
-
11
- /**
12
- * Gather raw vault status data for formatting by consumers.
13
- *
14
- * @param {import('../server/types.js').BaseCtx} ctx
15
- * @param {{ userId?: string }} opts — optional userId for per-user stats
16
- * @returns {{ fileCount, subdirs, kindCounts, dbSize, stalePaths, resolvedFrom, embeddingStatus, errors }}
17
- */
18
- export function gatherVaultStatus(ctx, opts = {}) {
19
- const { db, config } = ctx;
20
- const { userId } = opts;
21
- const errors = [];
22
-
23
- // Build user filter clause for DB queries
24
- const hasUser = userId !== undefined;
25
- const userWhere = hasUser ? "WHERE user_id = ?" : "";
26
- const userAnd = hasUser ? "AND user_id = ?" : "";
27
- const userParams = hasUser ? [userId] : [];
28
-
29
- // Count files in vault subdirs (auto-discover)
30
- let fileCount = 0;
31
- const subdirs = [];
32
- try {
33
- if (existsSync(config.vaultDir)) {
34
- for (const d of readdirSync(config.vaultDir, { withFileTypes: true })) {
35
- if (d.isDirectory()) {
36
- const dir = join(config.vaultDir, d.name);
37
- const count = walkDir(dir).length;
38
- fileCount += count;
39
- if (count > 0) subdirs.push({ name: d.name, count });
40
- }
41
- }
42
- }
43
- } catch (e) {
44
- errors.push(`File scan failed: ${e.message}`);
45
- }
46
-
47
- // Count DB rows by kind
48
- let kindCounts = [];
49
- try {
50
- kindCounts = db
51
- .prepare(
52
- `SELECT kind, COUNT(*) as c FROM vault ${userWhere} GROUP BY kind`,
53
- )
54
- .all(...userParams);
55
- } catch (e) {
56
- errors.push(`Kind count query failed: ${e.message}`);
57
- }
58
-
59
- // Count DB rows by category
60
- let categoryCounts = [];
61
- try {
62
- categoryCounts = db
63
- .prepare(
64
- `SELECT category, COUNT(*) as c FROM vault ${userWhere} GROUP BY category`,
65
- )
66
- .all(...userParams);
67
- } catch (e) {
68
- errors.push(`Category count query failed: ${e.message}`);
69
- }
70
-
71
- // DB file size
72
- let dbSize = "n/a";
73
- let dbSizeBytes = 0;
74
- try {
75
- if (existsSync(config.dbPath)) {
76
- dbSizeBytes = statSync(config.dbPath).size;
77
- dbSize =
78
- dbSizeBytes > 1024 * 1024
79
- ? `${(dbSizeBytes / 1024 / 1024).toFixed(1)}MB`
80
- : `${(dbSizeBytes / 1024).toFixed(1)}KB`;
81
- }
82
- } catch (e) {
83
- errors.push(`DB size check failed: ${e.message}`);
84
- }
85
-
86
- // Check for stale paths (count all mismatches, not just a sample)
87
- let stalePaths = false;
88
- let staleCount = 0;
89
- try {
90
- const result = db
91
- .prepare(
92
- `SELECT COUNT(*) as c FROM vault WHERE file_path NOT LIKE ? || '%' ${userAnd}`,
93
- )
94
- .get(config.vaultDir, ...userParams);
95
- staleCount = result.c;
96
- stalePaths = staleCount > 0;
97
- } catch (e) {
98
- errors.push(`Stale path check failed: ${e.message}`);
99
- }
100
-
101
- // Count expired entries pending pruning
102
- let expiredCount = 0;
103
- try {
104
- expiredCount = db
105
- .prepare(
106
- `SELECT COUNT(*) as c FROM vault WHERE expires_at IS NOT NULL AND expires_at <= datetime('now') ${userAnd}`,
107
- )
108
- .get(...userParams).c;
109
- } catch (e) {
110
- errors.push(`Expired count failed: ${e.message}`);
111
- }
112
-
113
- // Count event-category entries
114
- let eventCount = 0;
115
- try {
116
- eventCount = db
117
- .prepare(
118
- `SELECT COUNT(*) as c FROM vault WHERE category = 'event' ${userAnd}`,
119
- )
120
- .get(...userParams).c;
121
- } catch (e) {
122
- errors.push(`Event count failed: ${e.message}`);
123
- }
124
-
125
- // Count event entries without expires_at
126
- let eventsWithoutTtlCount = 0;
127
- try {
128
- eventsWithoutTtlCount = db
129
- .prepare(
130
- `SELECT COUNT(*) as c FROM vault WHERE category = 'event' AND expires_at IS NULL ${userAnd}`,
131
- )
132
- .get(...userParams).c;
133
- } catch (e) {
134
- errors.push(`Events without TTL count failed: ${e.message}`);
135
- }
136
-
137
- // Embedding/vector status
138
- let embeddingStatus = null;
139
- try {
140
- const total = db
141
- .prepare(`SELECT COUNT(*) as c FROM vault ${userWhere}`)
142
- .get(...userParams).c;
143
- const indexed = db
144
- .prepare(
145
- `SELECT COUNT(*) as c FROM vault WHERE rowid IN (SELECT rowid FROM vault_vec) ${userAnd}`,
146
- )
147
- .get(...userParams).c;
148
- embeddingStatus = { indexed, total, missing: total - indexed };
149
- } catch (e) {
150
- errors.push(`Embedding status check failed: ${e.message}`);
151
- }
152
-
153
- // Embedding model availability
154
- const embedModelAvailable = isEmbedAvailable();
155
-
156
- // Count auto-captured feedback entries (written by tracked() on unhandled errors)
157
- let autoCapturedFeedbackCount = 0;
158
- try {
159
- autoCapturedFeedbackCount = db
160
- .prepare(
161
- `SELECT COUNT(*) as c FROM vault WHERE kind = 'feedback' AND tags LIKE '%"auto-captured"%' ${userAnd}`,
162
- )
163
- .get(...userParams).c;
164
- } catch (e) {
165
- errors.push(`Auto-captured feedback count failed: ${e.message}`);
166
- }
167
-
168
- // Stale knowledge entries — kinds with a threshold, not updated within N days
169
- let staleKnowledge = [];
170
- try {
171
- const stalenessKinds = Object.entries(KIND_STALENESS_DAYS);
172
- if (stalenessKinds.length > 0) {
173
- const kindClauses = stalenessKinds
174
- .map(
175
- ([kind, days]) =>
176
- `(kind = '${kind}' AND COALESCE(updated_at, created_at) <= datetime('now', '-${days} days'))`,
177
- )
178
- .join(" OR ");
179
- staleKnowledge = db
180
- .prepare(
181
- `SELECT kind, title, COALESCE(updated_at, created_at) as last_updated FROM vault WHERE category = 'knowledge' AND (${kindClauses}) AND (expires_at IS NULL OR expires_at > datetime('now')) ${userAnd} ORDER BY last_updated ASC LIMIT 10`,
182
- )
183
- .all(...userParams);
184
- }
185
- } catch (e) {
186
- errors.push(`Stale knowledge check failed: ${e.message}`);
187
- }
188
-
189
- return {
190
- fileCount,
191
- subdirs,
192
- kindCounts,
193
- categoryCounts,
194
- dbSize,
195
- dbSizeBytes,
196
- stalePaths,
197
- staleCount,
198
- expiredCount,
199
- eventCount,
200
- eventsWithoutTtlCount,
201
- embeddingStatus,
202
- embedModelAvailable,
203
- autoCapturedFeedbackCount,
204
- staleKnowledge,
205
- resolvedFrom: config.resolvedFrom,
206
- errors,
207
- };
208
- }
209
-
210
- /**
211
- * Compute growth warnings based on vault status and configured thresholds.
212
- *
213
- * @param {object} status — result of gatherVaultStatus()
214
- * @param {object} thresholds — from config.thresholds
215
- * @returns {{ warnings: Array, hasCritical: boolean, hasWarnings: boolean, actions: string[], kindBreakdown: Array }}
216
- */
217
- export function computeGrowthWarnings(status, thresholds) {
218
- if (!thresholds)
219
- return {
220
- warnings: [],
221
- hasCritical: false,
222
- hasWarnings: false,
223
- actions: [],
224
- kindBreakdown: [],
225
- };
226
-
227
- const t = thresholds;
228
- const warnings = [];
229
- const actions = [];
230
-
231
- const total = status.embeddingStatus?.total ?? 0;
232
- const {
233
- eventCount = 0,
234
- eventsWithoutTtlCount = 0,
235
- expiredCount = 0,
236
- dbSizeBytes = 0,
237
- } = status;
238
-
239
- let totalExceeded = false;
240
-
241
- if (t.totalEntries?.critical != null && total >= t.totalEntries.critical) {
242
- totalExceeded = true;
243
- warnings.push({
244
- level: "critical",
245
- message: `Total entries: ${total.toLocaleString()} (exceeds critical limit of ${t.totalEntries.critical.toLocaleString()})`,
246
- });
247
- } else if (t.totalEntries?.warn != null && total >= t.totalEntries.warn) {
248
- totalExceeded = true;
249
- warnings.push({
250
- level: "warn",
251
- message: `Total entries: ${total.toLocaleString()} (exceeds recommended ${t.totalEntries.warn.toLocaleString()})`,
252
- });
253
- }
254
-
255
- if (
256
- t.eventEntries?.critical != null &&
257
- eventCount >= t.eventEntries.critical
258
- ) {
259
- warnings.push({
260
- level: "critical",
261
- message: `Event entries: ${eventCount.toLocaleString()} (exceeds critical limit of ${t.eventEntries.critical.toLocaleString()})`,
262
- });
263
- } else if (
264
- t.eventEntries?.warn != null &&
265
- eventCount >= t.eventEntries.warn
266
- ) {
267
- const ttlNote =
268
- eventsWithoutTtlCount > 0
269
- ? ` (${eventsWithoutTtlCount.toLocaleString()} without TTL)`
270
- : "";
271
- warnings.push({
272
- level: "warn",
273
- message: `Event entries: ${eventCount.toLocaleString()}${ttlNote} (exceeds recommended ${t.eventEntries.warn.toLocaleString()})`,
274
- });
275
- }
276
-
277
- if (
278
- t.vaultSizeBytes?.critical != null &&
279
- dbSizeBytes >= t.vaultSizeBytes.critical
280
- ) {
281
- warnings.push({
282
- level: "critical",
283
- message: `Database size: ${(dbSizeBytes / 1024 / 1024).toFixed(1)}MB (exceeds critical limit of ${(t.vaultSizeBytes.critical / 1024 / 1024).toFixed(0)}MB)`,
284
- });
285
- } else if (
286
- t.vaultSizeBytes?.warn != null &&
287
- dbSizeBytes >= t.vaultSizeBytes.warn
288
- ) {
289
- warnings.push({
290
- level: "warn",
291
- message: `Database size: ${(dbSizeBytes / 1024 / 1024).toFixed(1)}MB (exceeds recommended ${(t.vaultSizeBytes.warn / 1024 / 1024).toFixed(0)}MB)`,
292
- });
293
- }
294
-
295
- if (
296
- t.eventsWithoutTtl?.warn != null &&
297
- eventsWithoutTtlCount >= t.eventsWithoutTtl.warn
298
- ) {
299
- warnings.push({
300
- level: "warn",
301
- message: `Event entries without expires_at: ${eventsWithoutTtlCount.toLocaleString()} (exceeds recommended ${t.eventsWithoutTtl.warn.toLocaleString()})`,
302
- });
303
- }
304
-
305
- const hasCritical = warnings.some((w) => w.level === "critical");
306
-
307
- if (expiredCount > 0) {
308
- actions.push(
309
- `Run \`context-vault prune\` to remove ${expiredCount} expired event entr${expiredCount === 1 ? "y" : "ies"}`,
310
- );
311
- }
312
- const eventThresholdExceeded =
313
- eventCount >= (t.eventEntries?.warn ?? Infinity);
314
- const ttlThresholdExceeded =
315
- eventsWithoutTtlCount >= (t.eventsWithoutTtl?.warn ?? Infinity);
316
- if (
317
- eventsWithoutTtlCount > 0 &&
318
- (eventThresholdExceeded || ttlThresholdExceeded)
319
- ) {
320
- actions.push(
321
- "Add `expires_at` to event/session entries to enable automatic cleanup",
322
- );
323
- }
324
- if (total >= (t.totalEntries?.warn ?? Infinity)) {
325
- actions.push("Consider archiving events older than 90 days");
326
- }
327
-
328
- const kindBreakdown = totalExceeded
329
- ? buildKindBreakdown(status.kindCounts, total)
330
- : [];
331
-
332
- return {
333
- warnings,
334
- hasCritical,
335
- hasWarnings: warnings.length > 0,
336
- actions,
337
- kindBreakdown,
338
- };
339
- }
340
-
341
- function buildKindBreakdown(kindCounts, total) {
342
- if (!kindCounts?.length || total === 0) return [];
343
- return [...kindCounts]
344
- .sort((a, b) => b.c - a.c)
345
- .map(({ kind, c }) => ({
346
- kind,
347
- count: c,
348
- pct: Math.round((c / total) * 100),
349
- }));
350
- }