context-eng 0.1.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 (60) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +272 -0
  3. package/dist/categories.d.ts +27 -0
  4. package/dist/categories.js +71 -0
  5. package/dist/categories.js.map +1 -0
  6. package/dist/cli-entry.d.ts +2 -0
  7. package/dist/cli-entry.js +7 -0
  8. package/dist/cli-entry.js.map +1 -0
  9. package/dist/cli.d.ts +30 -0
  10. package/dist/cli.js +327 -0
  11. package/dist/cli.js.map +1 -0
  12. package/dist/db.d.ts +40 -0
  13. package/dist/db.js +158 -0
  14. package/dist/db.js.map +1 -0
  15. package/dist/engine.d.ts +149 -0
  16. package/dist/engine.js +589 -0
  17. package/dist/engine.js.map +1 -0
  18. package/dist/harness.d.ts +56 -0
  19. package/dist/harness.js +358 -0
  20. package/dist/harness.js.map +1 -0
  21. package/dist/index.d.ts +4 -0
  22. package/dist/index.js +3 -0
  23. package/dist/index.js.map +1 -0
  24. package/dist/inspect-cli.d.ts +2 -0
  25. package/dist/inspect-cli.js +96 -0
  26. package/dist/inspect-cli.js.map +1 -0
  27. package/dist/inspect.d.ts +33 -0
  28. package/dist/inspect.js +149 -0
  29. package/dist/inspect.js.map +1 -0
  30. package/dist/map.d.ts +39 -0
  31. package/dist/map.js +106 -0
  32. package/dist/map.js.map +1 -0
  33. package/dist/mcp.d.ts +5 -0
  34. package/dist/mcp.js +348 -0
  35. package/dist/mcp.js.map +1 -0
  36. package/dist/migrate.d.ts +7 -0
  37. package/dist/migrate.js +107 -0
  38. package/dist/migrate.js.map +1 -0
  39. package/dist/paths.d.ts +29 -0
  40. package/dist/paths.js +69 -0
  41. package/dist/paths.js.map +1 -0
  42. package/dist/search.d.ts +144 -0
  43. package/dist/search.js +449 -0
  44. package/dist/search.js.map +1 -0
  45. package/dist/secrets.d.ts +28 -0
  46. package/dist/secrets.js +135 -0
  47. package/dist/secrets.js.map +1 -0
  48. package/dist/text.d.ts +22 -0
  49. package/dist/text.js +153 -0
  50. package/dist/text.js.map +1 -0
  51. package/dist/tokens.d.ts +6 -0
  52. package/dist/tokens.js +15 -0
  53. package/dist/tokens.js.map +1 -0
  54. package/dist/typesafe.d.ts +40 -0
  55. package/dist/typesafe.js +170 -0
  56. package/dist/typesafe.js.map +1 -0
  57. package/package.json +51 -0
  58. package/system_prompts/AGENTS.md +14 -0
  59. package/system_prompts/CLAUDE.md +14 -0
  60. package/system_prompts/rules.md +157 -0
package/dist/mcp.js ADDED
@@ -0,0 +1,348 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
3
+ import { z } from "zod";
4
+ import { MAX_CATEGORY_LENGTH, MAX_FILTER_VALUE_LENGTH, MAX_FILTER_VALUES, MAX_HITS, MAX_JEV_BATCHES, MAX_JEV_CANDIDATES, MAX_SEARCH_CATEGORIES, } from "./categories.js";
5
+ import { EngineError } from "./engine.js";
6
+ import { NOT_RELEVANT_MESSAGE, TypeSafeError, TypeSafeRelevanceEvaluator, applyRelevanceGate, } from "./typesafe.js";
7
+ const CategorySchema = z.string().min(1).max(MAX_CATEGORY_LENGTH);
8
+ const LabelArraySchema = z.array(z.string().min(1).max(MAX_FILTER_VALUE_LENGTH)).max(MAX_FILTER_VALUES);
9
+ const ListFilterSchema = z.object({
10
+ values: LabelArraySchema,
11
+ match: z.enum(["any", "all"]).optional(),
12
+ });
13
+ const HintArraySchema = LabelArraySchema.min(1);
14
+ const SearchHintsSchema = z.object({
15
+ topics: HintArraySchema.optional(),
16
+ tags: HintArraySchema.optional(),
17
+ links: HintArraySchema.optional(),
18
+ categories: z.array(CategorySchema).min(1).max(MAX_SEARCH_CATEGORIES).optional(),
19
+ }).strict();
20
+ const ProjectPathSchema = z
21
+ .string()
22
+ .optional()
23
+ .describe("Workspace path. On PROJECT_NOT_BOUND, retry this call with this set. Absolute or `.`. Creates that project's DB if missing.");
24
+ function memorySelector(id, line) {
25
+ return {
26
+ ...(id !== undefined ? { id } : {}),
27
+ ...(line !== undefined ? { line } : {}),
28
+ };
29
+ }
30
+ function maybeBind(engine, projectPath) {
31
+ if (projectPath !== undefined && projectPath.trim().length > 0) {
32
+ engine.bind(projectPath);
33
+ }
34
+ }
35
+ function ok(result) {
36
+ return { content: [{ type: "text", text: JSON.stringify(result, null, 2) }] };
37
+ }
38
+ function engineFail(err, retryTool) {
39
+ const message = err.code === "NEAR_CATEGORY" && retryTool && err.near
40
+ ? `"${err.near.requested}" is too close to existing category "${err.near.existing}". Use category "${err.near.existing}", or retry ${retryTool} with confirmNewCategory: true to create "${err.near.requested}". No memory was written.`
41
+ : err.message;
42
+ return {
43
+ isError: true,
44
+ content: [
45
+ {
46
+ type: "text",
47
+ text: JSON.stringify({ error: err.code, message }),
48
+ },
49
+ ],
50
+ };
51
+ }
52
+ function contextOnly(result, projectPath) {
53
+ const evaluatedCandidates = Math.min(result.retrieval.candidate_count, MAX_JEV_CANDIDATES * MAX_JEV_BATCHES);
54
+ const channels = result.retrieval.channels.join("+") || "none";
55
+ const retrieval = result.retrieval.mode === "small"
56
+ ? `retrieval: small · eligible ${result.eligible_count}`
57
+ : `retrieval: large · ${evaluatedCandidates} candidates · ${channels}`;
58
+ const context = result.hits
59
+ .map((hit) => {
60
+ const project = hit.scope === "global" ? "global" : projectPath ?? "unbound";
61
+ const updated = new Date(hit.updated_at * 1000).toISOString();
62
+ return `[last updated: ${updated} | category: ${hit.category} | project: ${project}]\n${hit.content}`;
63
+ })
64
+ .join("\n\n");
65
+ const text = [retrieval, context, result.message || (context ? undefined : NOT_RELEVANT_MESSAGE)]
66
+ .filter(Boolean)
67
+ .join("\n\n");
68
+ return {
69
+ content: [
70
+ {
71
+ type: "text",
72
+ text,
73
+ },
74
+ ],
75
+ };
76
+ }
77
+ function handle(fn, retryTool) {
78
+ try {
79
+ return ok(fn());
80
+ }
81
+ catch (err) {
82
+ if (err instanceof EngineError)
83
+ return engineFail(err, retryTool);
84
+ throw err;
85
+ }
86
+ }
87
+ async function handleSearch(engine, fn) {
88
+ try {
89
+ return contextOnly(await fn(), engine.projectPath);
90
+ }
91
+ catch (err) {
92
+ if (err instanceof EngineError) {
93
+ const message = err.code === "PROJECT_NOT_BOUND" ? `${err.code}: ${err.message}` : err.message;
94
+ return {
95
+ isError: true,
96
+ content: [{ type: "text", text: message }],
97
+ };
98
+ }
99
+ throw err;
100
+ }
101
+ }
102
+ export function createServer(engine, relevanceEvaluator = new TypeSafeRelevanceEvaluator()) {
103
+ const server = new McpServer({
104
+ name: "context-eng",
105
+ version: "0.1.0",
106
+ });
107
+ server.registerTool("memory_search", {
108
+ title: "Search memories",
109
+ description: "Search memories before work. query is required. Pass projectPath when no project is bound and scope is project or both; if this returns PROJECT_NOT_BOUND, retry the same call with projectPath. Categories, filters, hints, sort, and limit are optional. Global-only search needs no project. Small filtered sets go entirely to Jev; large sets merge FTS, exact hint-label, typo-retry, and fill candidates before Jev evaluates the first 90 in batches of 30. Hints boost retrieval but never act as hard filters. Up to 50 gated notes are returned. Missing, timed-out, or failed Jev falls back to local lexical and exact-label retrieval.",
110
+ annotations: { readOnlyHint: true },
111
+ inputSchema: {
112
+ query: z.string().describe("The full agent request used for semantic or FTS5 relevance."),
113
+ categories: z
114
+ .array(CategorySchema)
115
+ .min(1)
116
+ .max(MAX_SEARCH_CATEGORIES)
117
+ .optional()
118
+ .describe("Optional unique categories to search; omit to search all available categories."),
119
+ filters: z
120
+ .object({
121
+ scope: z.enum(["both", "global", "project"]).optional(),
122
+ includeStaging: z.boolean().optional(),
123
+ minImportance: z.number().min(0).max(1).optional(),
124
+ subject: z.string().max(MAX_FILTER_VALUE_LENGTH).optional(),
125
+ topics: ListFilterSchema.optional(),
126
+ tags: ListFilterSchema.optional(),
127
+ links: ListFilterSchema.optional(),
128
+ time: z
129
+ .object({
130
+ field: z.enum(["created", "updated"]).optional(),
131
+ preset: z.enum(["this_week", "this_month"]).optional(),
132
+ from: z.string().optional(),
133
+ to: z.string().optional(),
134
+ })
135
+ .optional(),
136
+ })
137
+ .optional(),
138
+ hints: SearchHintsSchema.optional().describe("Optional topic, tag, link, and category boosts. These never replace the raw query or hard-filter results."),
139
+ sort: z
140
+ .object({
141
+ by: z.enum(["relevance", "updated", "created", "importance"]),
142
+ order: z.enum(["asc", "desc"]).optional(),
143
+ })
144
+ .optional(),
145
+ limit: z
146
+ .number()
147
+ .int()
148
+ .min(1)
149
+ .max(MAX_HITS)
150
+ .optional()
151
+ .describe(`Max hits, 1 to ${MAX_HITS}. Default ${MAX_HITS}.`),
152
+ projectPath: ProjectPathSchema,
153
+ },
154
+ }, (args) => handleSearch(engine, async () => {
155
+ maybeBind(engine, args.projectPath);
156
+ const input = {
157
+ query: args.query,
158
+ ...(args.categories !== undefined ? { categories: args.categories } : {}),
159
+ ...(args.filters !== undefined ? { filters: args.filters } : {}),
160
+ ...(args.hints !== undefined ? { hints: args.hints } : {}),
161
+ ...(args.sort !== undefined ? { sort: args.sort } : {}),
162
+ ...(args.limit !== undefined ? { limit: args.limit } : {}),
163
+ };
164
+ if (relevanceEvaluator.available?.() === false)
165
+ return engine.search(input);
166
+ try {
167
+ return await applyRelevanceGate(engine.prepareSearch(input), relevanceEvaluator);
168
+ }
169
+ catch (error) {
170
+ if (!(error instanceof TypeSafeError))
171
+ throw error;
172
+ const message = error instanceof Error ? error.message : String(error);
173
+ process.stderr.write(`[context-eng] Jev unavailable; using FTS5 fallback: ${message}\n`);
174
+ return engine.search(input);
175
+ }
176
+ }));
177
+ server.registerTool("memory_create", {
178
+ title: "Create a memory",
179
+ description: "Write one claim into a built-in or custom category database. A new name that is too similar to an existing category is rejected until the agent uses the existing category or retries with confirmNewCategory: true. Built-in durable categories auto-promote; custom categories start in staging.",
180
+ annotations: { readOnlyHint: false },
181
+ inputSchema: {
182
+ scope: z
183
+ .enum(["global", "project"])
184
+ .describe("Which database to write. global or project."),
185
+ category: CategorySchema.describe("Built-in or custom category; missing custom categories are created unless the name is too similar to an existing category."),
186
+ confirmNewCategory: z
187
+ .boolean()
188
+ .optional()
189
+ .describe("Retry-only override. Set true after NEAR_CATEGORY to explicitly create the requested new category."),
190
+ content: z.string().describe("One sentence. One claim. Hard cap 800 tokens."),
191
+ subject: z.string().max(MAX_FILTER_VALUE_LENGTH).optional(),
192
+ topics: LabelArraySchema.optional(),
193
+ tags: LabelArraySchema.optional(),
194
+ links: LabelArraySchema.optional(),
195
+ importance: z.number().min(0).max(1).optional().describe("0 to 1. Default 0.5."),
196
+ projectPath: ProjectPathSchema,
197
+ },
198
+ }, (args) => handle(() => {
199
+ maybeBind(engine, args.projectPath);
200
+ return engine.create({
201
+ scope: args.scope,
202
+ category: args.category,
203
+ ...(args.confirmNewCategory !== undefined ? { confirmNewCategory: args.confirmNewCategory } : {}),
204
+ content: args.content,
205
+ ...(args.subject !== undefined ? { subject: args.subject } : {}),
206
+ ...(args.topics !== undefined ? { topics: args.topics } : {}),
207
+ ...(args.tags !== undefined ? { tags: args.tags } : {}),
208
+ ...(args.links !== undefined ? { links: args.links } : {}),
209
+ ...(args.importance !== undefined ? { importance: args.importance } : {}),
210
+ });
211
+ }, "memory_create"));
212
+ server.registerTool("memory_edit", {
213
+ title: "Edit a memory",
214
+ description: "Patch fields on an existing memory by id. Content still has the 800-token one-sentence cap. Changing category auto-promotes or demotes, and a near-duplicate new category requires a second call with confirmNewCategory: true.",
215
+ annotations: { readOnlyHint: false },
216
+ inputSchema: {
217
+ currentCategory: CategorySchema.describe("Category database that currently contains the memory."),
218
+ id: z.string().describe("Memory id."),
219
+ content: z.string().optional().describe("Replacement text. One claim, hard cap 800 tokens."),
220
+ category: CategorySchema.optional().describe("Destination category; moves the memory when changed."),
221
+ confirmNewCategory: z
222
+ .boolean()
223
+ .optional()
224
+ .describe("Retry-only override. Set true after NEAR_CATEGORY to explicitly create the requested destination category."),
225
+ subject: z.string().max(MAX_FILTER_VALUE_LENGTH).nullable().optional(),
226
+ topics: LabelArraySchema.optional(),
227
+ tags: LabelArraySchema.optional(),
228
+ links: LabelArraySchema.optional(),
229
+ importance: z.number().min(0).max(1).optional().describe("Replacement importance, 0 to 1."),
230
+ },
231
+ }, (args) => handle(() => engine.edit(args.currentCategory, args.id, {
232
+ ...(args.content !== undefined ? { content: args.content } : {}),
233
+ ...(args.category !== undefined ? { category: args.category } : {}),
234
+ ...(args.confirmNewCategory !== undefined ? { confirmNewCategory: args.confirmNewCategory } : {}),
235
+ ...(args.subject !== undefined ? { subject: args.subject } : {}),
236
+ ...(args.topics !== undefined ? { topics: args.topics } : {}),
237
+ ...(args.tags !== undefined ? { tags: args.tags } : {}),
238
+ ...(args.links !== undefined ? { links: args.links } : {}),
239
+ ...(args.importance !== undefined ? { importance: args.importance } : {}),
240
+ }), "memory_edit"));
241
+ server.registerTool("memory_list_categories", {
242
+ title: "List memory categories",
243
+ description: "List current category names. Set scope to global or project, or omit it to list every available scope. An unbound server returns global categories only; explicit project scope requires projectPath or memory_bind.",
244
+ annotations: { readOnlyHint: true },
245
+ inputSchema: {
246
+ scope: z
247
+ .enum(["global", "project"])
248
+ .optional()
249
+ .describe("Optional category scope. Omit to list global and, when bound, project categories."),
250
+ projectPath: ProjectPathSchema,
251
+ },
252
+ }, (args) => handle(() => {
253
+ maybeBind(engine, args.projectPath);
254
+ return engine.listCategoryNames(args.scope);
255
+ }));
256
+ server.registerTool("memory_map", {
257
+ title: "Memory map",
258
+ description: "JSON index with memory line IDs for global, project, or both scopes. An unbound default/both request returns the global portion only; explicit project scope needs a bound workspace or projectPath. Collection lines_ids align with lines; staging also includes aligned lines_categories.",
259
+ annotations: { readOnlyHint: true },
260
+ inputSchema: {
261
+ scope: z
262
+ .enum(["both", "global", "project"])
263
+ .optional()
264
+ .describe("Map scope. Defaults to both."),
265
+ projectPath: ProjectPathSchema,
266
+ },
267
+ }, (args) => handle(() => {
268
+ maybeBind(engine, args.projectPath);
269
+ const index = args.scope === undefined || args.scope === "both"
270
+ ? engine.map()
271
+ : args.scope === "global"
272
+ ? engine.map("global")
273
+ : engine.map("project");
274
+ const includeGlobal = args.scope === undefined || args.scope === "both" || args.scope === "global";
275
+ return {
276
+ ...index,
277
+ maps: {
278
+ ...(includeGlobal ? { global: engine.globalMapPath } : {}),
279
+ ...("project" in index && index.project !== undefined ? { project: engine.projectMapPath } : {}),
280
+ },
281
+ };
282
+ }));
283
+ server.registerTool("memory_bind", {
284
+ title: "Bind a project database",
285
+ description: "Bind this workspace. Creates ~/.context/projects/<key>/ if missing. Later scope=project writes go there. Does not write AGENTS.md.",
286
+ annotations: { readOnlyHint: false },
287
+ inputSchema: {
288
+ projectPath: z
289
+ .string()
290
+ .describe("Existing workspace path to bind. Absolute or `.`."),
291
+ },
292
+ }, (args) => handle(() => engine.bind(args.projectPath)));
293
+ server.registerTool("memory_promote", {
294
+ title: "Promote a memory",
295
+ description: "Move a staging memory into search. Pass id, the exact line text, or both. Both must name the same note.",
296
+ annotations: { readOnlyHint: false },
297
+ inputSchema: {
298
+ category: CategorySchema.describe("Category database containing the memory."),
299
+ id: z.string().optional().describe("Memory id. Optional when line is the exact memory text."),
300
+ line: z.string().optional().describe("Exact memory text from memory_map lines. Optional when id is set."),
301
+ },
302
+ }, (args) => handle(() => engine.promote(args.category, memorySelector(args.id, args.line))));
303
+ server.registerTool("memory_demote", {
304
+ title: "Demote a memory",
305
+ description: "Move a searchable memory back to staging. Pass id, the exact line text, or both. Both must name the same note.",
306
+ annotations: { readOnlyHint: false },
307
+ inputSchema: {
308
+ category: CategorySchema.describe("Category database containing the memory."),
309
+ id: z.string().optional().describe("Memory id. Optional when line is the exact memory text."),
310
+ line: z.string().optional().describe("Exact memory text from memory_map lines. Optional when id is set."),
311
+ },
312
+ }, (args) => handle(() => engine.demote(args.category, memorySelector(args.id, args.line))));
313
+ server.registerTool("memory_delete", {
314
+ title: "Delete a staging memory",
315
+ description: "Delete a staging memory. Pass id, the exact line text, or both. Both must name the same note. Promoted rows cannot be deleted.",
316
+ annotations: { readOnlyHint: false },
317
+ inputSchema: {
318
+ category: CategorySchema.describe("Category database containing the memory."),
319
+ id: z.string().optional().describe("Staging memory id. Optional when line is the exact memory text."),
320
+ line: z.string().optional().describe("Exact memory text from memory_map lines. Optional when id is set."),
321
+ },
322
+ }, (args) => handle(() => engine.delete(args.category, memorySelector(args.id, args.line))));
323
+ return server;
324
+ }
325
+ export async function runStdio(engine, relevanceEvaluator) {
326
+ const server = createServer(engine, relevanceEvaluator);
327
+ const transport = new StdioServerTransport();
328
+ await server.connect(transport);
329
+ await new Promise((resolve) => {
330
+ let finished = false;
331
+ const finish = () => {
332
+ if (finished)
333
+ return;
334
+ finished = true;
335
+ void server.close().finally(() => {
336
+ engine.close();
337
+ resolve();
338
+ });
339
+ };
340
+ process.stdin.on("end", () => {
341
+ setTimeout(finish, 200);
342
+ });
343
+ process.stdin.on("close", () => {
344
+ setTimeout(finish, 200);
345
+ });
346
+ });
347
+ }
348
+ //# sourceMappingURL=mcp.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp.js","sourceRoot":"","sources":["../src/mcp.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { type Db } from "./db.js";
2
+ export declare const MIGRATION_KEY = "legacy_v1_migrated";
3
+ export declare function migrateLegacy(args: {
4
+ catalog: Db;
5
+ categoriesDir: string;
6
+ legacyFile: string;
7
+ }): void;
@@ -0,0 +1,107 @@
1
+ import Database from "better-sqlite3";
2
+ import { existsSync, mkdirSync, mkdtempSync, renameSync, rmSync } from "node:fs";
3
+ import path from "node:path";
4
+ import { canonicalCategory, displayCategory, isCategory } from "./categories.js";
5
+ import { categoryRecord, insertRow, metadataValue, nowSeconds, openCategoryDb, registerCategory, replaceLabels, setMetadata, } from "./db.js";
6
+ import { categoryFileName } from "./paths.js";
7
+ import { parseLabels } from "./text.js";
8
+ export const MIGRATION_KEY = "legacy_v1_migrated";
9
+ export function migrateLegacy(args) {
10
+ const { catalog, categoriesDir, legacyFile } = args;
11
+ if (metadataValue(catalog, MIGRATION_KEY) === "2")
12
+ return;
13
+ if (!existsSync(legacyFile)) {
14
+ setMetadata(catalog, MIGRATION_KEY, "2");
15
+ return;
16
+ }
17
+ const legacy = new Database(legacyFile, { readonly: true, fileMustExist: true });
18
+ let stagingDir;
19
+ try {
20
+ const table = legacy
21
+ .prepare(`SELECT 1 AS present FROM sqlite_master WHERE type = 'table' AND name = 'memories'`)
22
+ .get();
23
+ if (!table) {
24
+ setMetadata(catalog, MIGRATION_KEY, "2");
25
+ return;
26
+ }
27
+ const rawRows = legacy.prepare(`SELECT * FROM memories`).all();
28
+ const validRows = rawRows.filter((raw) => isCategory(String(raw.category ?? "")));
29
+ if (validRows.length === 0) {
30
+ setMetadata(catalog, MIGRATION_KEY, "2");
31
+ return;
32
+ }
33
+ const migrationParent = path.dirname(categoriesDir);
34
+ mkdirSync(migrationParent, { recursive: true });
35
+ stagingDir = mkdtempSync(path.join(migrationParent, ".category-migration-"));
36
+ const staged = new Map();
37
+ for (const raw of validRows) {
38
+ const category = String(raw.category);
39
+ const canonical = canonicalCategory(category);
40
+ let target = staged.get(canonical);
41
+ if (!target) {
42
+ const existing = categoryRecord(catalog, canonical);
43
+ const record = existing ?? {
44
+ canonical,
45
+ display_name: displayCategory(category),
46
+ db_file: categoryFileName(canonical),
47
+ created_at: nowSeconds(),
48
+ };
49
+ target = {
50
+ record,
51
+ db: openCategoryDb(path.join(stagingDir, record.db_file)),
52
+ ids: [],
53
+ };
54
+ staged.set(canonical, target);
55
+ }
56
+ const row = {
57
+ id: String(raw.id),
58
+ project_id: String(raw.project_id),
59
+ chat_id: raw.chat_id === null || raw.chat_id === undefined ? null : String(raw.chat_id),
60
+ category: target.record.display_name,
61
+ content: String(raw.content),
62
+ subject: null,
63
+ topics: null,
64
+ tags: raw.tags === null || raw.tags === undefined ? null : String(raw.tags),
65
+ links: null,
66
+ importance: Number(raw.importance ?? 0.5),
67
+ active: Number(raw.active ?? 1),
68
+ created_at: normalizeLegacyTimestamp(Number(raw.created_at)),
69
+ updated_at: normalizeLegacyTimestamp(Number(raw.updated_at)),
70
+ };
71
+ target.db.transaction(() => {
72
+ insertRow(target.db, row, true);
73
+ replaceLabels(target.db, row.id, labelsFromRow(row));
74
+ })();
75
+ target.ids.push(row.id);
76
+ }
77
+ for (const target of staged.values()) {
78
+ for (const id of target.ids) {
79
+ const found = target.db.prepare(`SELECT 1 AS present FROM memories WHERE id = ?`).get(id);
80
+ if (!found)
81
+ throw new Error(`legacy migration failed to copy memory ${id}`);
82
+ }
83
+ target.db.close();
84
+ }
85
+ mkdirSync(categoriesDir, { recursive: true });
86
+ for (const target of staged.values()) {
87
+ renameSync(path.join(stagingDir, target.record.db_file), path.join(categoriesDir, target.record.db_file));
88
+ }
89
+ catalog.transaction(() => {
90
+ for (const target of staged.values())
91
+ registerCategory(catalog, target.record);
92
+ setMetadata(catalog, MIGRATION_KEY, "2");
93
+ })();
94
+ }
95
+ finally {
96
+ legacy.close();
97
+ if (stagingDir)
98
+ rmSync(stagingDir, { recursive: true, force: true });
99
+ }
100
+ }
101
+ function labelsFromRow(row) {
102
+ return { topics: parseLabels(row.topics), tags: parseLabels(row.tags), links: parseLabels(row.links) };
103
+ }
104
+ function normalizeLegacyTimestamp(value) {
105
+ return value >= 1_000_000_000_000 ? Math.floor(value / 1000) : value;
106
+ }
107
+ //# sourceMappingURL=migrate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"migrate.js","sourceRoot":"","sources":["../src/migrate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,29 @@
1
+ export declare const HOME_ENV = "CONTEXT_ENG_HOME";
2
+ export declare const PROJECT_ENV = "CONTEXT_ENG_PROJECT";
3
+ export declare function contextHome(): string;
4
+ export declare function resolveProjectPath(explicit?: string): string;
5
+ export declare function projectKey(resolvedPath: string): string;
6
+ export declare function categoryFileName(canonical: string): string;
7
+ export interface GlobalLayout {
8
+ home: string;
9
+ /** Legacy v1 files retained as migration sources and recovery copies. */
10
+ globalDb: string;
11
+ globalDir: string;
12
+ globalCatalogDb: string;
13
+ globalCategoriesDir: string;
14
+ globalMapMd: string;
15
+ globalMapJson: string;
16
+ }
17
+ export interface Layout extends GlobalLayout {
18
+ projectPath: string;
19
+ projectKey: string;
20
+ /** Legacy v1 project file retained as a migration source and recovery copy. */
21
+ projectDb: string;
22
+ projectDir: string;
23
+ projectCatalogDb: string;
24
+ projectCategoriesDir: string;
25
+ projectMapMd: string;
26
+ projectMapJson: string;
27
+ }
28
+ export declare function globalLayoutFor(home?: string): GlobalLayout;
29
+ export declare function layoutFor(projectPath: string, home?: string): Layout;
package/dist/paths.js ADDED
@@ -0,0 +1,69 @@
1
+ import { createHash } from "node:crypto";
2
+ import { realpathSync } from "node:fs";
3
+ import os from "node:os";
4
+ import path from "node:path";
5
+ export const HOME_ENV = "CONTEXT_ENG_HOME";
6
+ export const PROJECT_ENV = "CONTEXT_ENG_PROJECT";
7
+ export function contextHome() {
8
+ const override = process.env[HOME_ENV];
9
+ if (override && override.trim().length > 0)
10
+ return path.resolve(override);
11
+ return path.join(os.homedir(), ".context");
12
+ }
13
+ export function resolveProjectPath(explicit) {
14
+ const candidate = explicit ?? process.env[PROJECT_ENV] ?? process.cwd();
15
+ const abs = path.resolve(candidate);
16
+ try {
17
+ return realpathSync(abs);
18
+ }
19
+ catch {
20
+ return abs;
21
+ }
22
+ }
23
+ export function projectKey(resolvedPath) {
24
+ const base = path.basename(resolvedPath) || "root";
25
+ const slug = safeSlug(base);
26
+ const hash = createHash("sha1").update(resolvedPath).digest("hex").slice(0, 10);
27
+ return `${slug}-${hash}`;
28
+ }
29
+ export function categoryFileName(canonical) {
30
+ const slug = safeSlug(canonical);
31
+ const hash = createHash("sha256").update(canonical).digest("hex").slice(0, 12);
32
+ return `${slug}-${hash}.db`;
33
+ }
34
+ function safeSlug(value) {
35
+ return (value
36
+ .toLowerCase()
37
+ .replace(/[^a-z0-9]+/g, "-")
38
+ .replace(/^-+|-+$/g, "")
39
+ .slice(0, 40) || "category");
40
+ }
41
+ export function globalLayoutFor(home = contextHome()) {
42
+ const globalDir = path.join(home, "global");
43
+ return {
44
+ home,
45
+ globalDb: path.join(home, "global.db"),
46
+ globalDir,
47
+ globalCatalogDb: path.join(globalDir, "catalog.db"),
48
+ globalCategoriesDir: path.join(globalDir, "categories"),
49
+ globalMapMd: path.join(home, "map.md"),
50
+ globalMapJson: path.join(home, "map.json"),
51
+ };
52
+ }
53
+ export function layoutFor(projectPath, home = contextHome()) {
54
+ const key = projectKey(projectPath);
55
+ const projectDir = path.join(home, "projects", key);
56
+ const global = globalLayoutFor(home);
57
+ return {
58
+ ...global,
59
+ projectPath,
60
+ projectKey: key,
61
+ projectDb: path.join(projectDir, "memory.db"),
62
+ projectDir,
63
+ projectCatalogDb: path.join(projectDir, "catalog.db"),
64
+ projectCategoriesDir: path.join(projectDir, "categories"),
65
+ projectMapMd: path.join(projectDir, "map.md"),
66
+ projectMapJson: path.join(projectDir, "map.json"),
67
+ };
68
+ }
69
+ //# sourceMappingURL=paths.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"paths.js","sourceRoot":"","sources":["../src/paths.ts"],"names":[],"mappings":"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"}