context-vault 3.1.6 → 3.1.7

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (82) hide show
  1. package/bin/cli.js +1369 -1774
  2. package/node_modules/@context-vault/core/dist/capture.d.ts +1 -1
  3. package/node_modules/@context-vault/core/dist/capture.d.ts.map +1 -1
  4. package/node_modules/@context-vault/core/dist/capture.js +34 -47
  5. package/node_modules/@context-vault/core/dist/capture.js.map +1 -1
  6. package/node_modules/@context-vault/core/dist/categories.js +30 -30
  7. package/node_modules/@context-vault/core/dist/config.d.ts +1 -1
  8. package/node_modules/@context-vault/core/dist/config.d.ts.map +1 -1
  9. package/node_modules/@context-vault/core/dist/config.js +37 -43
  10. package/node_modules/@context-vault/core/dist/config.js.map +1 -1
  11. package/node_modules/@context-vault/core/dist/constants.d.ts.map +1 -1
  12. package/node_modules/@context-vault/core/dist/constants.js +4 -4
  13. package/node_modules/@context-vault/core/dist/constants.js.map +1 -1
  14. package/node_modules/@context-vault/core/dist/db.d.ts +2 -2
  15. package/node_modules/@context-vault/core/dist/db.d.ts.map +1 -1
  16. package/node_modules/@context-vault/core/dist/db.js +21 -20
  17. package/node_modules/@context-vault/core/dist/db.js.map +1 -1
  18. package/node_modules/@context-vault/core/dist/embed.d.ts.map +1 -1
  19. package/node_modules/@context-vault/core/dist/embed.js +11 -11
  20. package/node_modules/@context-vault/core/dist/embed.js.map +1 -1
  21. package/node_modules/@context-vault/core/dist/files.d.ts.map +1 -1
  22. package/node_modules/@context-vault/core/dist/files.js +12 -13
  23. package/node_modules/@context-vault/core/dist/files.js.map +1 -1
  24. package/node_modules/@context-vault/core/dist/formatters.js +5 -5
  25. package/node_modules/@context-vault/core/dist/frontmatter.d.ts.map +1 -1
  26. package/node_modules/@context-vault/core/dist/frontmatter.js +23 -23
  27. package/node_modules/@context-vault/core/dist/frontmatter.js.map +1 -1
  28. package/node_modules/@context-vault/core/dist/index.d.ts +1 -1
  29. package/node_modules/@context-vault/core/dist/index.d.ts.map +1 -1
  30. package/node_modules/@context-vault/core/dist/index.js +58 -46
  31. package/node_modules/@context-vault/core/dist/index.js.map +1 -1
  32. package/node_modules/@context-vault/core/dist/ingest-url.d.ts.map +1 -1
  33. package/node_modules/@context-vault/core/dist/ingest-url.js +30 -33
  34. package/node_modules/@context-vault/core/dist/ingest-url.js.map +1 -1
  35. package/node_modules/@context-vault/core/dist/main.d.ts +13 -13
  36. package/node_modules/@context-vault/core/dist/main.d.ts.map +1 -1
  37. package/node_modules/@context-vault/core/dist/main.js +12 -12
  38. package/node_modules/@context-vault/core/dist/main.js.map +1 -1
  39. package/node_modules/@context-vault/core/dist/search.d.ts +1 -1
  40. package/node_modules/@context-vault/core/dist/search.d.ts.map +1 -1
  41. package/node_modules/@context-vault/core/dist/search.js +20 -22
  42. package/node_modules/@context-vault/core/dist/search.js.map +1 -1
  43. package/node_modules/@context-vault/core/dist/types.d.ts +1 -1
  44. package/node_modules/@context-vault/core/package.json +1 -1
  45. package/node_modules/@context-vault/core/src/capture.ts +44 -81
  46. package/node_modules/@context-vault/core/src/categories.ts +30 -30
  47. package/node_modules/@context-vault/core/src/config.ts +45 -60
  48. package/node_modules/@context-vault/core/src/constants.ts +8 -10
  49. package/node_modules/@context-vault/core/src/db.ts +37 -56
  50. package/node_modules/@context-vault/core/src/embed.ts +15 -26
  51. package/node_modules/@context-vault/core/src/files.ts +13 -16
  52. package/node_modules/@context-vault/core/src/formatters.ts +5 -5
  53. package/node_modules/@context-vault/core/src/frontmatter.ts +26 -30
  54. package/node_modules/@context-vault/core/src/index.ts +94 -100
  55. package/node_modules/@context-vault/core/src/ingest-url.ts +56 -93
  56. package/node_modules/@context-vault/core/src/main.ts +13 -18
  57. package/node_modules/@context-vault/core/src/search.ts +34 -56
  58. package/node_modules/@context-vault/core/src/types.ts +1 -1
  59. package/package.json +2 -2
  60. package/scripts/postinstall.js +18 -25
  61. package/scripts/prepack.js +13 -19
  62. package/src/archive.js +211 -0
  63. package/src/error-log.js +7 -7
  64. package/src/helpers.js +11 -13
  65. package/src/linking.js +8 -11
  66. package/src/migrate-dirs.js +139 -0
  67. package/src/register-tools.js +46 -48
  68. package/src/server.js +73 -99
  69. package/src/status.js +35 -71
  70. package/src/telemetry.js +18 -22
  71. package/src/temporal.js +19 -30
  72. package/src/tools/clear-context.js +15 -18
  73. package/src/tools/context-status.js +37 -57
  74. package/src/tools/create-snapshot.js +45 -57
  75. package/src/tools/delete-context.js +11 -12
  76. package/src/tools/get-context.js +112 -160
  77. package/src/tools/ingest-project.js +66 -86
  78. package/src/tools/ingest-url.js +25 -41
  79. package/src/tools/list-buckets.js +19 -25
  80. package/src/tools/list-context.js +35 -58
  81. package/src/tools/save-context.js +126 -182
  82. package/src/tools/session-start.js +46 -62
@@ -1,45 +1,43 @@
1
- import { z } from "zod";
2
- import { execSync } from "node:child_process";
3
- import { ok, err, ensureVaultExists } from "../helpers.js";
1
+ import { z } from 'zod';
2
+ import { execSync } from 'node:child_process';
3
+ import { ok, err, ensureVaultExists } from '../helpers.js';
4
4
 
5
5
  const DEFAULT_MAX_TOKENS = 4000;
6
6
  const RECENT_DAYS = 7;
7
7
  const MAX_BODY_PER_ENTRY = 400;
8
- const PRIORITY_KINDS = ["decision", "insight", "pattern"];
9
- const SESSION_SUMMARY_KIND = "session";
8
+ const PRIORITY_KINDS = ['decision', 'insight', 'pattern'];
9
+ const SESSION_SUMMARY_KIND = 'session';
10
10
 
11
- export const name = "session_start";
11
+ export const name = 'session_start';
12
12
 
13
13
  export const description =
14
- "Auto-assemble a context brief for the current project on session start. Pulls recent entries, last session summary, and active decisions/blockers into a token-budgeted capsule formatted for agent consumption.";
14
+ 'Auto-assemble a context brief for the current project on session start. Pulls recent entries, last session summary, and active decisions/blockers into a token-budgeted capsule formatted for agent consumption.';
15
15
 
16
16
  export const inputSchema = {
17
17
  project: z
18
18
  .string()
19
19
  .optional()
20
20
  .describe(
21
- "Project name or tag to scope the brief. Auto-detected from cwd/git remote if not provided.",
21
+ 'Project name or tag to scope the brief. Auto-detected from cwd/git remote if not provided.'
22
22
  ),
23
23
  max_tokens: z
24
24
  .number()
25
25
  .optional()
26
- .describe(
27
- "Token budget for the capsule (rough estimate: 1 token ~ 4 chars). Default: 4000.",
28
- ),
26
+ .describe('Token budget for the capsule (rough estimate: 1 token ~ 4 chars). Default: 4000.'),
29
27
  buckets: z
30
28
  .array(z.string())
31
29
  .optional()
32
30
  .describe(
33
- "Bucket names to scope the session brief. Each name expands to a 'bucket:<name>' tag filter. When provided, the brief only includes entries from these buckets.",
31
+ "Bucket names to scope the session brief. Each name expands to a 'bucket:<name>' tag filter. When provided, the brief only includes entries from these buckets."
34
32
  ),
35
33
  };
36
34
 
37
35
  function detectProject() {
38
36
  try {
39
- const remote = execSync("git remote get-url origin 2>/dev/null", {
40
- encoding: "utf-8",
37
+ const remote = execSync('git remote get-url origin 2>/dev/null', {
38
+ encoding: 'utf-8',
41
39
  timeout: 3000,
42
- stdio: ["pipe", "pipe", "pipe"],
40
+ stdio: ['pipe', 'pipe', 'pipe'],
43
41
  }).trim();
44
42
  if (remote) {
45
43
  const match = remote.match(/\/([^/]+?)(?:\.git)?$/);
@@ -57,31 +55,27 @@ function detectProject() {
57
55
  }
58
56
 
59
57
  function truncateBody(body, maxLen = MAX_BODY_PER_ENTRY) {
60
- if (!body) return "(no body)";
58
+ if (!body) return '(no body)';
61
59
  if (body.length <= maxLen) return body;
62
- return body.slice(0, maxLen) + "...";
60
+ return body.slice(0, maxLen) + '...';
63
61
  }
64
62
 
65
63
  function estimateTokens(text) {
66
- return Math.ceil((text || "").length / 4);
64
+ return Math.ceil((text || '').length / 4);
67
65
  }
68
66
 
69
67
  function formatEntry(entry) {
70
68
  const tags = entry.tags ? JSON.parse(entry.tags) : [];
71
- const tagStr = tags.length ? tags.join(", ") : "none";
72
- const date = entry.updated_at || entry.created_at || "unknown";
69
+ const tagStr = tags.length ? tags.join(', ') : 'none';
70
+ const date = entry.updated_at || entry.created_at || 'unknown';
73
71
  return [
74
- `- **${entry.title || "(untitled)"}** [${entry.kind}]`,
72
+ `- **${entry.title || '(untitled)'}** [${entry.kind}]`,
75
73
  ` tags: ${tagStr} | ${date} | id: \`${entry.id}\``,
76
- ` ${truncateBody(entry.body).replace(/\n+/g, " ").trim()}`,
77
- ].join("\n");
74
+ ` ${truncateBody(entry.body).replace(/\n+/g, ' ').trim()}`,
75
+ ].join('\n');
78
76
  }
79
77
 
80
- export async function handler(
81
- { project, max_tokens, buckets },
82
- ctx,
83
- { ensureIndexed },
84
- ) {
78
+ export async function handler({ project, max_tokens, buckets }, ctx, { ensureIndexed }) {
85
79
  const { config } = ctx;
86
80
 
87
81
  const vaultErr = ensureVaultExists(config);
@@ -93,35 +87,25 @@ export async function handler(
93
87
  const tokenBudget = max_tokens || DEFAULT_MAX_TOKENS;
94
88
 
95
89
  const bucketTags = buckets?.length ? buckets.map((b) => `bucket:${b}`) : [];
96
- const effectiveTags = bucketTags.length
97
- ? bucketTags
98
- : effectiveProject
99
- ? [effectiveProject]
100
- : [];
90
+ const effectiveTags = bucketTags.length ? bucketTags : effectiveProject ? [effectiveProject] : [];
101
91
 
102
92
  const sinceDate = new Date(Date.now() - RECENT_DAYS * 86400000).toISOString();
103
93
 
104
94
  const sections = [];
105
95
  let tokensUsed = 0;
106
96
 
97
+ sections.push(`# Session Brief${effectiveProject ? ` — ${effectiveProject}` : ''}`);
98
+ const bucketsLabel = buckets?.length ? ` | buckets: ${buckets.join(', ')}` : '';
107
99
  sections.push(
108
- `# Session Brief${effectiveProject ? ` ${effectiveProject}` : ""}`,
109
- );
110
- const bucketsLabel = buckets?.length
111
- ? ` | buckets: ${buckets.join(", ")}`
112
- : "";
113
- sections.push(
114
- `_Generated ${new Date().toISOString().slice(0, 10)} | budget: ${tokenBudget} tokens${bucketsLabel}_\n`,
100
+ `_Generated ${new Date().toISOString().slice(0, 10)} | budget: ${tokenBudget} tokens${bucketsLabel}_\n`
115
101
  );
116
- tokensUsed += estimateTokens(sections.join("\n"));
102
+ tokensUsed += estimateTokens(sections.join('\n'));
117
103
 
118
104
  const lastSession = queryLastSession(ctx, effectiveTags);
119
105
  if (lastSession) {
120
- const sessionBlock = [
121
- "## Last Session Summary",
122
- truncateBody(lastSession.body, 600),
123
- "",
124
- ].join("\n");
106
+ const sessionBlock = ['## Last Session Summary', truncateBody(lastSession.body, 600), ''].join(
107
+ '\n'
108
+ );
125
109
  const sessionTokens = estimateTokens(sessionBlock);
126
110
  if (tokensUsed + sessionTokens <= tokenBudget) {
127
111
  sections.push(sessionBlock);
@@ -134,10 +118,10 @@ export async function handler(
134
118
  PRIORITY_KINDS,
135
119
  sinceDate,
136
120
 
137
- effectiveTags,
121
+ effectiveTags
138
122
  );
139
123
  if (decisions.length > 0) {
140
- const header = "## Active Decisions, Insights & Patterns\n";
124
+ const header = '## Active Decisions, Insights & Patterns\n';
141
125
  const headerTokens = estimateTokens(header);
142
126
  if (tokensUsed + headerTokens <= tokenBudget) {
143
127
  const entryLines = [];
@@ -150,7 +134,7 @@ export async function handler(
150
134
  tokensUsed += lineTokens;
151
135
  }
152
136
  if (entryLines.length > 0) {
153
- sections.push(header + entryLines.join("\n") + "\n");
137
+ sections.push(header + entryLines.join('\n') + '\n');
154
138
  }
155
139
  }
156
140
  }
@@ -174,7 +158,7 @@ export async function handler(
174
158
  tokensUsed += lineTokens;
175
159
  }
176
160
  if (entryLines.length > 0) {
177
- sections.push(header + entryLines.join("\n") + "\n");
161
+ sections.push(header + entryLines.join('\n') + '\n');
178
162
  }
179
163
  }
180
164
  }
@@ -187,12 +171,12 @@ export async function handler(
187
171
  return true;
188
172
  }).length;
189
173
 
190
- sections.push("---");
174
+ sections.push('---');
191
175
  sections.push(
192
- `_${tokensUsed} / ${tokenBudget} tokens used | project: ${effectiveProject || "unscoped"}_`,
176
+ `_${tokensUsed} / ${tokenBudget} tokens used | project: ${effectiveProject || 'unscoped'}_`
193
177
  );
194
178
 
195
- const result = ok(sections.join("\n"));
179
+ const result = ok(sections.join('\n'));
196
180
  result._meta = {
197
181
  project: effectiveProject || null,
198
182
  buckets: buckets || null,
@@ -214,9 +198,9 @@ function queryLastSession(ctx, effectiveTags) {
214
198
  if (false) {
215
199
  }
216
200
  clauses.push("(expires_at IS NULL OR expires_at > datetime('now'))");
217
- clauses.push("superseded_by IS NULL");
201
+ clauses.push('superseded_by IS NULL');
218
202
 
219
- const where = `WHERE ${clauses.join(" AND ")}`;
203
+ const where = `WHERE ${clauses.join(' AND ')}`;
220
204
  const rows = ctx.db
221
205
  .prepare(`SELECT * FROM vault ${where} ORDER BY created_at DESC LIMIT 5`)
222
206
  .all(...params);
@@ -232,19 +216,19 @@ function queryLastSession(ctx, effectiveTags) {
232
216
  }
233
217
 
234
218
  function queryByKinds(ctx, kinds, since, effectiveTags) {
235
- const kindPlaceholders = kinds.map(() => "?").join(",");
219
+ const kindPlaceholders = kinds.map(() => '?').join(',');
236
220
  const clauses = [`kind IN (${kindPlaceholders})`];
237
221
  const params = [...kinds];
238
222
 
239
- clauses.push("created_at >= ?");
223
+ clauses.push('created_at >= ?');
240
224
  params.push(since);
241
225
 
242
226
  if (false) {
243
227
  }
244
228
  clauses.push("(expires_at IS NULL OR expires_at > datetime('now'))");
245
- clauses.push("superseded_by IS NULL");
229
+ clauses.push('superseded_by IS NULL');
246
230
 
247
- const where = `WHERE ${clauses.join(" AND ")}`;
231
+ const where = `WHERE ${clauses.join(' AND ')}`;
248
232
  const rows = ctx.db
249
233
  .prepare(`SELECT * FROM vault ${where} ORDER BY created_at DESC LIMIT 50`)
250
234
  .all(...params);
@@ -260,15 +244,15 @@ function queryByKinds(ctx, kinds, since, effectiveTags) {
260
244
  }
261
245
 
262
246
  function queryRecent(ctx, since, effectiveTags) {
263
- const clauses = ["created_at >= ?"];
247
+ const clauses = ['created_at >= ?'];
264
248
  const params = [since];
265
249
 
266
250
  if (false) {
267
251
  }
268
252
  clauses.push("(expires_at IS NULL OR expires_at > datetime('now'))");
269
- clauses.push("superseded_by IS NULL");
253
+ clauses.push('superseded_by IS NULL');
270
254
 
271
- const where = `WHERE ${clauses.join(" AND ")}`;
255
+ const where = `WHERE ${clauses.join(' AND ')}`;
272
256
  const rows = ctx.db
273
257
  .prepare(`SELECT * FROM vault ${where} ORDER BY created_at DESC LIMIT 50`)
274
258
  .all(...params);