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/cli.js ADDED
@@ -0,0 +1,327 @@
1
+ import { existsSync, mkdirSync, readFileSync, statSync, writeFileSync } from "node:fs";
2
+ import os from "node:os";
3
+ import path from "node:path";
4
+ import { createInterface } from "node:readline/promises";
5
+ import { fileURLToPath } from "node:url";
6
+ import { parseArgs } from "node:util";
7
+ import { Engine } from "./engine.js";
8
+ import { detectHarnesses, formatHarnessReport, installDetectedHarnesses, pathHasCommand, promptHarnessChoice, } from "./harness.js";
9
+ import { runStdio } from "./mcp.js";
10
+ import { resolveProjectPath } from "./paths.js";
11
+ import { ensureTypeSafeKey, loadTypeSafeApiKey, openOsKeychain } from "./secrets.js";
12
+ import { TypeSafeRelevanceEvaluator } from "./typesafe.js";
13
+ const MARKER_START = "<!-- context-eng:start -->";
14
+ const MARKER_END = "<!-- context-eng:end -->";
15
+ const CURSOR_RULE_FILE = "context-eng-memory.mdc";
16
+ const CURSOR_RULE_FRONTMATTER = `---
17
+ description: Use context-eng MCP memory tools for local project memory.
18
+ alwaysApply: true
19
+ ---
20
+ `;
21
+ const RULE_SCOPES = ["global", "project", "both"];
22
+ const CLAUDE_RULE_FILE = "context-eng-memory.md";
23
+ const USAGE = `Usage:
24
+ context-eng mcp [--project <path>]
25
+ context-eng init [--project <path>] [--yes]
26
+ context-eng init --codex-only
27
+ context-eng init --cursor-only [--scope global|project|both] [--project <path>]
28
+ context-eng init --claude-only [--scope global|project|both] [--project <path>]
29
+ `;
30
+ export function upsertMarkedBlock(existing, block) {
31
+ const unit = block.trimEnd();
32
+ if (existing == null || existing.trim() === "") {
33
+ return `${unit}\n`;
34
+ }
35
+ const start = existing.indexOf(MARKER_START);
36
+ const end = existing.indexOf(MARKER_END);
37
+ if (start !== -1 && end !== -1 && end > start) {
38
+ const before = existing.slice(0, start);
39
+ const after = existing.slice(end + MARKER_END.length);
40
+ const out = `${before}${unit}${after}`;
41
+ return out.endsWith("\n") ? out : `${out}\n`;
42
+ }
43
+ const head = existing.replace(/\s+$/, "");
44
+ return `${head}\n\n${unit}\n`;
45
+ }
46
+ function repoRoot() {
47
+ return path.resolve(path.dirname(fileURLToPath(import.meta.url)), "..");
48
+ }
49
+ export function agentPointerBlock() {
50
+ const raw = readFileSync(path.join(repoRoot(), "system_prompts", "AGENTS.md"), "utf8");
51
+ const start = raw.indexOf(MARKER_START);
52
+ const end = raw.indexOf(MARKER_END);
53
+ const inner = start !== -1 && end !== -1 && end > start
54
+ ? raw.slice(start + MARKER_START.length, end)
55
+ : raw;
56
+ const adapted = inner
57
+ .replaceAll("memory.search", "memory_search")
58
+ .replaceAll("memory.create", "memory_create")
59
+ .replaceAll("memory.delete", "memory_delete")
60
+ .replaceAll("memory.edit", "memory_edit")
61
+ .replaceAll("memory.map", "memory_map")
62
+ .replaceAll("memory.promote", "memory_promote")
63
+ .replaceAll("memory.demote", "memory_demote")
64
+ .trim();
65
+ return `${MARKER_START}\n${adapted}\n${MARKER_END}\n`;
66
+ }
67
+ function writePointer(file, block) {
68
+ const existing = existsSync(file) ? readFileSync(file, "utf8") : null;
69
+ writeFileSync(file, upsertMarkedBlock(existing, block), "utf8");
70
+ }
71
+ export function updateExistingPointer(file, block) {
72
+ if (!existsSync(file))
73
+ return false;
74
+ writePointer(file, block);
75
+ return true;
76
+ }
77
+ function usage(exitCode = 1) {
78
+ (exitCode === 0 ? console.log : console.error)(USAGE);
79
+ process.exit(exitCode);
80
+ }
81
+ function engineOpts(project) {
82
+ if (project !== undefined)
83
+ return { projectPath: project };
84
+ return {};
85
+ }
86
+ export function codexAgentsPath(home = os.homedir()) {
87
+ return path.join(home, ".codex", "AGENTS.md");
88
+ }
89
+ export function writeCodexAgentsPointer(block, home = os.homedir()) {
90
+ const file = codexAgentsPath(home);
91
+ mkdirSync(path.dirname(file), { recursive: true });
92
+ writePointer(file, block);
93
+ return file;
94
+ }
95
+ export function globalCursorRulePath(home = os.homedir()) {
96
+ return path.join(home, ".cursor", "rules", CURSOR_RULE_FILE);
97
+ }
98
+ export function cursorRulePath(projectPath) {
99
+ return path.join(projectPath, ".cursor", "rules", CURSOR_RULE_FILE);
100
+ }
101
+ export function resolveRuleScope(scope, project) {
102
+ if (scope !== undefined) {
103
+ if (!RULE_SCOPES.includes(scope)) {
104
+ throw new Error(`scope must be one of: ${RULE_SCOPES.join(", ")}`);
105
+ }
106
+ return scope;
107
+ }
108
+ if (project !== undefined)
109
+ return "project";
110
+ return "global";
111
+ }
112
+ export const resolveCursorRuleScope = resolveRuleScope;
113
+ function splitCursorRule(existing) {
114
+ if (existing.startsWith("---\n")) {
115
+ const end = existing.indexOf("\n---\n", 4);
116
+ if (end !== -1) {
117
+ return {
118
+ frontmatter: existing.slice(0, end + 5),
119
+ body: existing.slice(end + 5),
120
+ };
121
+ }
122
+ }
123
+ return { frontmatter: CURSOR_RULE_FRONTMATTER.trimEnd(), body: existing };
124
+ }
125
+ export function writeCursorRuleFile(block, file) {
126
+ mkdirSync(path.dirname(file), { recursive: true });
127
+ const existing = existsSync(file) ? readFileSync(file, "utf8") : null;
128
+ if (existing == null || existing.trim() === "") {
129
+ writeFileSync(file, `${CURSOR_RULE_FRONTMATTER}\n${block.trimEnd()}\n`, "utf8");
130
+ return file;
131
+ }
132
+ const { frontmatter, body } = splitCursorRule(existing);
133
+ const nextBody = upsertMarkedBlock(body.trim() === "" ? null : body, block);
134
+ writeFileSync(file, `${frontmatter}\n${nextBody}`, "utf8");
135
+ return file;
136
+ }
137
+ export function writeCursorRule(block, projectPath) {
138
+ return writeCursorRuleFile(block, cursorRulePath(projectPath));
139
+ }
140
+ export function writeCursorRules(block, opts) {
141
+ const files = [];
142
+ const home = opts.home ?? os.homedir();
143
+ if (opts.scope === "global" || opts.scope === "both") {
144
+ files.push(writeCursorRuleFile(block, globalCursorRulePath(home)));
145
+ }
146
+ if (opts.scope === "project" || opts.scope === "both") {
147
+ if (opts.project === undefined) {
148
+ throw new Error("scope project or both requires --project <path>");
149
+ }
150
+ files.push(writeCursorRuleFile(block, cursorRulePath(resolveProjectPath(opts.project))));
151
+ }
152
+ return files;
153
+ }
154
+ export function globalClaudeAgentsPath(home = os.homedir()) {
155
+ return path.join(home, ".claude", "CLAUDE.md");
156
+ }
157
+ export function writeGlobalClaudePointer(block, home = os.homedir()) {
158
+ const file = globalClaudeAgentsPath(home);
159
+ mkdirSync(path.dirname(file), { recursive: true });
160
+ writePointer(file, block);
161
+ return file;
162
+ }
163
+ export function claudeRulePath(projectPath) {
164
+ return path.join(projectPath, ".claude", "rules", CLAUDE_RULE_FILE);
165
+ }
166
+ export function writeClaudeRuleFile(block, file) {
167
+ mkdirSync(path.dirname(file), { recursive: true });
168
+ writePointer(file, block);
169
+ return file;
170
+ }
171
+ export function writeClaudeRule(block, projectPath) {
172
+ return writeClaudeRuleFile(block, claudeRulePath(projectPath));
173
+ }
174
+ export function writeClaudeRules(block, opts) {
175
+ const files = [];
176
+ const home = opts.home ?? os.homedir();
177
+ if (opts.scope === "global" || opts.scope === "both") {
178
+ files.push(writeGlobalClaudePointer(block, home));
179
+ }
180
+ if (opts.scope === "project" || opts.scope === "both") {
181
+ if (opts.project === undefined) {
182
+ throw new Error("scope project or both requires --project <path>");
183
+ }
184
+ files.push(writeClaudeRuleFile(block, claudeRulePath(resolveProjectPath(opts.project))));
185
+ }
186
+ return files;
187
+ }
188
+ async function confirmHarnessReplacement(id, file) {
189
+ const prompt = createInterface({ input: process.stdin, output: process.stdout });
190
+ try {
191
+ const answer = await prompt.question(`${id} already has a different context-eng server in ${file}. Replace it? [y/N] `);
192
+ return /^y(?:es)?$/i.test(answer.trim());
193
+ }
194
+ catch {
195
+ return false;
196
+ }
197
+ finally {
198
+ prompt.close();
199
+ }
200
+ }
201
+ export async function main() {
202
+ let values;
203
+ let positionals;
204
+ try {
205
+ const parsed = parseArgs({
206
+ args: process.argv.slice(2),
207
+ options: {
208
+ project: { type: "string" },
209
+ scope: { type: "string" },
210
+ help: { type: "boolean", short: "h" },
211
+ yes: { type: "boolean" },
212
+ "codex-only": { type: "boolean" },
213
+ "cursor-only": { type: "boolean" },
214
+ "claude-only": { type: "boolean" },
215
+ },
216
+ allowPositionals: true,
217
+ strict: true,
218
+ });
219
+ values = parsed.values;
220
+ positionals = parsed.positionals;
221
+ }
222
+ catch {
223
+ usage();
224
+ }
225
+ if (values.help)
226
+ usage(0);
227
+ if (positionals.length !== 1) {
228
+ usage();
229
+ }
230
+ const command = positionals[0];
231
+ if (command !== "mcp" && command !== "init") {
232
+ usage();
233
+ }
234
+ if (command === "mcp") {
235
+ const loaded = await loadTypeSafeApiKey();
236
+ if (loaded.warning)
237
+ console.error(loaded.warning);
238
+ const engine = new Engine({
239
+ ...engineOpts(values.project),
240
+ deferProject: values.project === undefined,
241
+ });
242
+ await runStdio(engine, new TypeSafeRelevanceEvaluator({ apiKey: loaded.apiKey }));
243
+ return;
244
+ }
245
+ if (values["codex-only"] || values["cursor-only"] || values["claude-only"]) {
246
+ const block = agentPointerBlock();
247
+ if (values["codex-only"]) {
248
+ console.log(`Updated ${writeCodexAgentsPointer(block)}`);
249
+ }
250
+ const scopedOpts = values.project === undefined
251
+ ? undefined
252
+ : { project: values.project };
253
+ if (values["cursor-only"]) {
254
+ const scope = resolveRuleScope(values.scope, values.project);
255
+ const cursorOpts = scopedOpts === undefined ? { scope } : { scope, ...scopedOpts };
256
+ for (const file of writeCursorRules(block, cursorOpts)) {
257
+ console.log(`Updated ${file}`);
258
+ }
259
+ }
260
+ if (values["claude-only"]) {
261
+ const scope = resolveRuleScope(values.scope, values.project);
262
+ const claudeOpts = scopedOpts === undefined ? { scope } : { scope, ...scopedOpts };
263
+ for (const file of writeClaudeRules(block, claudeOpts)) {
264
+ console.log(`Updated ${file}`);
265
+ }
266
+ }
267
+ return;
268
+ }
269
+ const projectPath = resolveProjectPath(values.project);
270
+ if (!existsSync(projectPath) || !statSync(projectPath).isDirectory()) {
271
+ throw new Error(`project path must be an existing directory: ${projectPath}`);
272
+ }
273
+ await ensureTypeSafeKey({
274
+ store: await openOsKeychain(),
275
+ interactive: process.stdin.isTTY === true,
276
+ });
277
+ const engine = new Engine({ projectPath });
278
+ try {
279
+ const block = agentPointerBlock();
280
+ const projectAgents = path.join(engine.layout.projectPath, "AGENTS.md");
281
+ const projectClaude = path.join(engine.layout.projectPath, "CLAUDE.md");
282
+ const canWriteGlobal = process.stdin.isTTY === true || values.yes === true;
283
+ const globalCodexAgents = canWriteGlobal ? writeCodexAgentsPointer(block) : undefined;
284
+ const projectAgentsUpdated = updateExistingPointer(projectAgents, block);
285
+ const projectClaudeUpdated = updateExistingPointer(projectClaude, block);
286
+ console.log("");
287
+ console.log("Agent pointers");
288
+ if (projectAgentsUpdated)
289
+ console.log(` project AGENTS.md: ${projectAgents}`);
290
+ if (projectClaudeUpdated)
291
+ console.log(` project CLAUDE.md: ${projectClaude}`);
292
+ if (globalCodexAgents)
293
+ console.log(` codex AGENTS.md: ${globalCodexAgents}`);
294
+ console.log("");
295
+ console.log("Data layout");
296
+ console.log(` home: ${engine.layout.home}`);
297
+ console.log(` projectDir: ${engine.layout.projectDir}`);
298
+ console.log(` projectKey: ${engine.layout.projectKey}`);
299
+ console.log("");
300
+ const home = os.homedir();
301
+ const installed = detectHarnesses({ home, hasCommand: pathHasCommand })
302
+ .filter((hit) => hit.installed)
303
+ .map((hit) => hit.id);
304
+ const selected = values.yes === true
305
+ ? installed
306
+ : process.stdin.isTTY === true
307
+ ? await promptHarnessChoice(installed)
308
+ : [];
309
+ const report = await installDetectedHarnesses({
310
+ home,
311
+ hasCommand: pathHasCommand,
312
+ selected,
313
+ ...(process.stdin.isTTY === true && values.yes !== true
314
+ ? { confirmReplace: confirmHarnessReplacement }
315
+ : {}),
316
+ });
317
+ const claude = report.harnesses.find((item) => item.id === "claude");
318
+ if (canWriteGlobal && claude?.installed && !claude.skipped && !claude.error && !claude.preserved) {
319
+ console.log(` global Claude instructions: ${writeGlobalClaudePointer(block, home)}`);
320
+ }
321
+ console.log(formatHarnessReport(report));
322
+ }
323
+ finally {
324
+ engine.close();
325
+ }
326
+ }
327
+ //# sourceMappingURL=cli.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cli.js","sourceRoot":"","sources":["../src/cli.ts"],"names":[],"mappings":"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"}
package/dist/db.d.ts ADDED
@@ -0,0 +1,40 @@
1
+ import Database from "better-sqlite3";
2
+ export type Db = Database.Database;
3
+ export declare function nowSeconds(): number;
4
+ export interface MemoryRow {
5
+ id: string;
6
+ project_id: string;
7
+ chat_id: string | null;
8
+ category: string;
9
+ content: string;
10
+ subject: string | null;
11
+ topics: string | null;
12
+ tags: string | null;
13
+ links: string | null;
14
+ importance: number;
15
+ active: number;
16
+ created_at: number;
17
+ updated_at: number;
18
+ }
19
+ export interface CategoryRecord {
20
+ canonical: string;
21
+ display_name: string;
22
+ db_file: string;
23
+ created_at: number;
24
+ }
25
+ export declare function openCategoryDb(file: string): Db;
26
+ /** Compatibility alias for callers that open a single category database. */
27
+ export declare const openDb: typeof openCategoryDb;
28
+ export declare function openCatalog(file: string): Db;
29
+ export declare function listCategories(catalog: Db): CategoryRecord[];
30
+ export declare function categoryRecord(catalog: Db, canonical: string): CategoryRecord | undefined;
31
+ export declare function registerCategory(catalog: Db, record: CategoryRecord): CategoryRecord;
32
+ export declare function metadataValue(catalog: Db, key: string): string | undefined;
33
+ export declare function setMetadata(catalog: Db, key: string, value: string): void;
34
+ export declare function insertRow(db: Db, row: MemoryRow, ignore?: boolean): void;
35
+ export declare function updateRow(db: Db, row: MemoryRow): void;
36
+ export declare function replaceLabels(db: Db, memoryId: string, labels: {
37
+ topics: readonly string[];
38
+ tags: readonly string[];
39
+ links: readonly string[];
40
+ }): void;
package/dist/db.js ADDED
@@ -0,0 +1,158 @@
1
+ import Database from "better-sqlite3";
2
+ import { mkdirSync } from "node:fs";
3
+ import path from "node:path";
4
+ const MS_FLOOR = 1_000_000_000_000;
5
+ export function nowSeconds() {
6
+ return Math.floor(Date.now() / 1000);
7
+ }
8
+ const CATEGORY_SCHEMA = `
9
+ CREATE TABLE IF NOT EXISTS memories (
10
+ id TEXT PRIMARY KEY,
11
+ project_id TEXT NOT NULL,
12
+ chat_id TEXT,
13
+ category TEXT NOT NULL,
14
+ content TEXT NOT NULL,
15
+ subject TEXT,
16
+ topics TEXT,
17
+ tags TEXT,
18
+ links TEXT,
19
+ importance REAL DEFAULT 0.5,
20
+ active INTEGER DEFAULT 1,
21
+ created_at INTEGER NOT NULL,
22
+ updated_at INTEGER NOT NULL
23
+ );
24
+
25
+ CREATE INDEX IF NOT EXISTS memories_chat_idx ON memories(chat_id, active);
26
+ CREATE INDEX IF NOT EXISTS memories_subject_idx ON memories(subject);
27
+ CREATE INDEX IF NOT EXISTS memories_importance_idx ON memories(importance);
28
+ CREATE INDEX IF NOT EXISTS memories_created_idx ON memories(created_at);
29
+ CREATE INDEX IF NOT EXISTS memories_updated_idx ON memories(updated_at);
30
+
31
+ CREATE TABLE IF NOT EXISTS memory_labels (
32
+ memory_id TEXT NOT NULL,
33
+ kind TEXT NOT NULL CHECK(kind IN ('topic', 'tag', 'link')),
34
+ value TEXT NOT NULL,
35
+ PRIMARY KEY(memory_id, kind, value),
36
+ FOREIGN KEY(memory_id) REFERENCES memories(id) ON DELETE CASCADE
37
+ );
38
+ CREATE INDEX IF NOT EXISTS memory_labels_lookup_idx ON memory_labels(kind, value, memory_id);
39
+
40
+ CREATE VIRTUAL TABLE IF NOT EXISTS memories_fts USING fts5(
41
+ content,
42
+ subject,
43
+ topics,
44
+ tags,
45
+ links,
46
+ content='memories',
47
+ content_rowid='rowid',
48
+ tokenize='porter unicode61'
49
+ );
50
+
51
+ CREATE TRIGGER IF NOT EXISTS memories_ai AFTER INSERT ON memories BEGIN
52
+ INSERT INTO memories_fts(rowid, content, subject, topics, tags, links)
53
+ VALUES (new.rowid, new.content, new.subject, new.topics, new.tags, new.links);
54
+ END;
55
+
56
+ CREATE TRIGGER IF NOT EXISTS memories_ad AFTER DELETE ON memories BEGIN
57
+ INSERT INTO memories_fts(memories_fts, rowid, content, subject, topics, tags, links)
58
+ VALUES ('delete', old.rowid, old.content, old.subject, old.topics, old.tags, old.links);
59
+ END;
60
+
61
+ CREATE TRIGGER IF NOT EXISTS memories_au AFTER UPDATE ON memories BEGIN
62
+ INSERT INTO memories_fts(memories_fts, rowid, content, subject, topics, tags, links)
63
+ VALUES ('delete', old.rowid, old.content, old.subject, old.topics, old.tags, old.links);
64
+ INSERT INTO memories_fts(rowid, content, subject, topics, tags, links)
65
+ VALUES (new.rowid, new.content, new.subject, new.topics, new.tags, new.links);
66
+ END;
67
+ `;
68
+ const CATALOG_SCHEMA = `
69
+ CREATE TABLE IF NOT EXISTS categories (
70
+ canonical TEXT PRIMARY KEY,
71
+ display_name TEXT NOT NULL,
72
+ db_file TEXT NOT NULL UNIQUE,
73
+ created_at INTEGER NOT NULL
74
+ );
75
+ CREATE TABLE IF NOT EXISTS metadata (
76
+ key TEXT PRIMARY KEY,
77
+ value TEXT NOT NULL
78
+ );
79
+ `;
80
+ function configure(db) {
81
+ db.pragma("journal_mode = WAL");
82
+ db.pragma("busy_timeout = 5000");
83
+ db.pragma("synchronous = NORMAL");
84
+ db.pragma("foreign_keys = ON");
85
+ }
86
+ export function openCategoryDb(file) {
87
+ mkdirSync(path.dirname(file), { recursive: true });
88
+ const db = new Database(file);
89
+ configure(db);
90
+ db.exec(CATEGORY_SCHEMA);
91
+ db.exec(`
92
+ UPDATE memories SET created_at = created_at / 1000 WHERE created_at >= ${MS_FLOOR};
93
+ UPDATE memories SET updated_at = updated_at / 1000 WHERE updated_at >= ${MS_FLOOR};
94
+ `);
95
+ return db;
96
+ }
97
+ /** Compatibility alias for callers that open a single category database. */
98
+ export const openDb = openCategoryDb;
99
+ export function openCatalog(file) {
100
+ mkdirSync(path.dirname(file), { recursive: true });
101
+ const db = new Database(file);
102
+ configure(db);
103
+ db.exec(CATALOG_SCHEMA);
104
+ return db;
105
+ }
106
+ export function listCategories(catalog) {
107
+ return catalog
108
+ .prepare(`SELECT canonical, display_name, db_file, created_at FROM categories ORDER BY display_name`)
109
+ .all();
110
+ }
111
+ export function categoryRecord(catalog, canonical) {
112
+ return catalog
113
+ .prepare(`SELECT canonical, display_name, db_file, created_at FROM categories WHERE canonical = ?`)
114
+ .get(canonical);
115
+ }
116
+ export function registerCategory(catalog, record) {
117
+ catalog
118
+ .prepare(`INSERT OR IGNORE INTO categories (canonical, display_name, db_file, created_at)
119
+ VALUES (@canonical, @display_name, @db_file, @created_at)`)
120
+ .run(record);
121
+ return categoryRecord(catalog, record.canonical) ?? record;
122
+ }
123
+ export function metadataValue(catalog, key) {
124
+ const row = catalog.prepare(`SELECT value FROM metadata WHERE key = ?`).get(key);
125
+ return row?.value;
126
+ }
127
+ export function setMetadata(catalog, key, value) {
128
+ catalog
129
+ .prepare(`INSERT INTO metadata (key, value) VALUES (?, ?)
130
+ ON CONFLICT(key) DO UPDATE SET value = excluded.value`)
131
+ .run(key, value);
132
+ }
133
+ export function insertRow(db, row, ignore = false) {
134
+ db.prepare(`INSERT ${ignore ? "OR IGNORE " : ""}INTO memories
135
+ (id, project_id, chat_id, category, content, subject, topics, tags, links,
136
+ importance, active, created_at, updated_at)
137
+ VALUES (@id, @project_id, @chat_id, @category, @content, @subject, @topics, @tags, @links,
138
+ @importance, @active, @created_at, @updated_at)`).run(row);
139
+ }
140
+ export function updateRow(db, row) {
141
+ db.prepare(`UPDATE memories SET content = @content, category = @category, subject = @subject,
142
+ topics = @topics, tags = @tags, links = @links, importance = @importance,
143
+ chat_id = @chat_id, updated_at = @updated_at WHERE id = @id`).run(row);
144
+ }
145
+ export function replaceLabels(db, memoryId, labels) {
146
+ const remove = db.prepare(`DELETE FROM memory_labels WHERE memory_id = ?`);
147
+ const insert = db.prepare(`INSERT INTO memory_labels (memory_id, kind, value) VALUES (?, ?, ?)`);
148
+ db.transaction(() => {
149
+ remove.run(memoryId);
150
+ for (const value of labels.topics)
151
+ insert.run(memoryId, "topic", value);
152
+ for (const value of labels.tags)
153
+ insert.run(memoryId, "tag", value);
154
+ for (const value of labels.links)
155
+ insert.run(memoryId, "link", value);
156
+ })();
157
+ }
158
+ //# sourceMappingURL=db.js.map
package/dist/db.js.map ADDED
@@ -0,0 +1 @@
1
+ {"version":3,"file":"db.js","sourceRoot":"","sources":["../src/db.ts"],"names":[],"mappings":"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"}