context-vault 3.1.6 → 3.1.7
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/bin/cli.js +1369 -1774
- package/node_modules/@context-vault/core/dist/capture.d.ts +1 -1
- package/node_modules/@context-vault/core/dist/capture.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/capture.js +34 -47
- package/node_modules/@context-vault/core/dist/capture.js.map +1 -1
- package/node_modules/@context-vault/core/dist/categories.js +30 -30
- package/node_modules/@context-vault/core/dist/config.d.ts +1 -1
- package/node_modules/@context-vault/core/dist/config.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/config.js +37 -43
- package/node_modules/@context-vault/core/dist/config.js.map +1 -1
- package/node_modules/@context-vault/core/dist/constants.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/constants.js +4 -4
- package/node_modules/@context-vault/core/dist/constants.js.map +1 -1
- package/node_modules/@context-vault/core/dist/db.d.ts +2 -2
- package/node_modules/@context-vault/core/dist/db.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/db.js +21 -20
- package/node_modules/@context-vault/core/dist/db.js.map +1 -1
- package/node_modules/@context-vault/core/dist/embed.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/embed.js +11 -11
- package/node_modules/@context-vault/core/dist/embed.js.map +1 -1
- package/node_modules/@context-vault/core/dist/files.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/files.js +12 -13
- package/node_modules/@context-vault/core/dist/files.js.map +1 -1
- package/node_modules/@context-vault/core/dist/formatters.js +5 -5
- package/node_modules/@context-vault/core/dist/frontmatter.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/frontmatter.js +23 -23
- package/node_modules/@context-vault/core/dist/frontmatter.js.map +1 -1
- package/node_modules/@context-vault/core/dist/index.d.ts +1 -1
- package/node_modules/@context-vault/core/dist/index.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/index.js +58 -46
- package/node_modules/@context-vault/core/dist/index.js.map +1 -1
- package/node_modules/@context-vault/core/dist/ingest-url.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/ingest-url.js +30 -33
- package/node_modules/@context-vault/core/dist/ingest-url.js.map +1 -1
- package/node_modules/@context-vault/core/dist/main.d.ts +13 -13
- package/node_modules/@context-vault/core/dist/main.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/main.js +12 -12
- package/node_modules/@context-vault/core/dist/main.js.map +1 -1
- package/node_modules/@context-vault/core/dist/search.d.ts +1 -1
- package/node_modules/@context-vault/core/dist/search.d.ts.map +1 -1
- package/node_modules/@context-vault/core/dist/search.js +20 -22
- package/node_modules/@context-vault/core/dist/search.js.map +1 -1
- package/node_modules/@context-vault/core/dist/types.d.ts +1 -1
- package/node_modules/@context-vault/core/package.json +1 -1
- package/node_modules/@context-vault/core/src/capture.ts +44 -81
- package/node_modules/@context-vault/core/src/categories.ts +30 -30
- package/node_modules/@context-vault/core/src/config.ts +45 -60
- package/node_modules/@context-vault/core/src/constants.ts +8 -10
- package/node_modules/@context-vault/core/src/db.ts +37 -56
- package/node_modules/@context-vault/core/src/embed.ts +15 -26
- package/node_modules/@context-vault/core/src/files.ts +13 -16
- package/node_modules/@context-vault/core/src/formatters.ts +5 -5
- package/node_modules/@context-vault/core/src/frontmatter.ts +26 -30
- package/node_modules/@context-vault/core/src/index.ts +94 -100
- package/node_modules/@context-vault/core/src/ingest-url.ts +56 -93
- package/node_modules/@context-vault/core/src/main.ts +13 -18
- package/node_modules/@context-vault/core/src/search.ts +34 -56
- package/node_modules/@context-vault/core/src/types.ts +1 -1
- package/package.json +2 -2
- package/scripts/postinstall.js +18 -25
- package/scripts/prepack.js +13 -19
- package/src/archive.js +211 -0
- package/src/error-log.js +7 -7
- package/src/helpers.js +11 -13
- package/src/linking.js +8 -11
- package/src/migrate-dirs.js +139 -0
- package/src/register-tools.js +46 -48
- package/src/server.js +73 -99
- package/src/status.js +35 -71
- package/src/telemetry.js +18 -22
- package/src/temporal.js +19 -30
- package/src/tools/clear-context.js +15 -18
- package/src/tools/context-status.js +37 -57
- package/src/tools/create-snapshot.js +45 -57
- package/src/tools/delete-context.js +11 -12
- package/src/tools/get-context.js +112 -160
- package/src/tools/ingest-project.js +66 -86
- package/src/tools/ingest-url.js +25 -41
- package/src/tools/list-buckets.js +19 -25
- package/src/tools/list-context.js +35 -58
- package/src/tools/save-context.js +126 -182
- package/src/tools/session-start.js +46 -62
|
@@ -1,45 +1,43 @@
|
|
|
1
|
-
import { z } from
|
|
2
|
-
import { execSync } from
|
|
3
|
-
import { ok, err, ensureVaultExists } from
|
|
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 = [
|
|
9
|
-
const SESSION_SUMMARY_KIND =
|
|
8
|
+
const PRIORITY_KINDS = ['decision', 'insight', 'pattern'];
|
|
9
|
+
const SESSION_SUMMARY_KIND = 'session';
|
|
10
10
|
|
|
11
|
-
export const name =
|
|
11
|
+
export const name = 'session_start';
|
|
12
12
|
|
|
13
13
|
export const description =
|
|
14
|
-
|
|
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
|
-
|
|
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(
|
|
40
|
-
encoding:
|
|
37
|
+
const remote = execSync('git remote get-url origin 2>/dev/null', {
|
|
38
|
+
encoding: 'utf-8',
|
|
41
39
|
timeout: 3000,
|
|
42
|
-
stdio: [
|
|
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
|
|
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 ||
|
|
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(
|
|
72
|
-
const date = entry.updated_at || entry.created_at ||
|
|
69
|
+
const tagStr = tags.length ? tags.join(', ') : 'none';
|
|
70
|
+
const date = entry.updated_at || entry.created_at || 'unknown';
|
|
73
71
|
return [
|
|
74
|
-
`- **${entry.title ||
|
|
72
|
+
`- **${entry.title || '(untitled)'}** [${entry.kind}]`,
|
|
75
73
|
` tags: ${tagStr} | ${date} | id: \`${entry.id}\``,
|
|
76
|
-
` ${truncateBody(entry.body).replace(/\n+/g,
|
|
77
|
-
].join(
|
|
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
|
-
|
|
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(
|
|
102
|
+
tokensUsed += estimateTokens(sections.join('\n'));
|
|
117
103
|
|
|
118
104
|
const lastSession = queryLastSession(ctx, effectiveTags);
|
|
119
105
|
if (lastSession) {
|
|
120
|
-
const sessionBlock = [
|
|
121
|
-
|
|
122
|
-
|
|
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 =
|
|
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(
|
|
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(
|
|
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 ||
|
|
176
|
+
`_${tokensUsed} / ${tokenBudget} tokens used | project: ${effectiveProject || 'unscoped'}_`
|
|
193
177
|
);
|
|
194
178
|
|
|
195
|
-
const result = ok(sections.join(
|
|
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(
|
|
201
|
+
clauses.push('superseded_by IS NULL');
|
|
218
202
|
|
|
219
|
-
const where = `WHERE ${clauses.join(
|
|
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(() =>
|
|
219
|
+
const kindPlaceholders = kinds.map(() => '?').join(',');
|
|
236
220
|
const clauses = [`kind IN (${kindPlaceholders})`];
|
|
237
221
|
const params = [...kinds];
|
|
238
222
|
|
|
239
|
-
clauses.push(
|
|
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(
|
|
229
|
+
clauses.push('superseded_by IS NULL');
|
|
246
230
|
|
|
247
|
-
const where = `WHERE ${clauses.join(
|
|
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 = [
|
|
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(
|
|
253
|
+
clauses.push('superseded_by IS NULL');
|
|
270
254
|
|
|
271
|
-
const where = `WHERE ${clauses.join(
|
|
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);
|