@membank/core 0.9.3 → 0.9.4

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/dist/index.cjs CHANGED
@@ -154,6 +154,65 @@ CREATE INDEX IF NOT EXISTS idx_syntheses_expires_at
154
154
 
155
155
  CREATE INDEX IF NOT EXISTS idx_syntheses_scope_inflight
156
156
  ON syntheses(scope) WHERE in_flight_since IS NOT NULL;
157
+ `],
158
+ [5, `
159
+ PRAGMA foreign_keys = OFF;
160
+
161
+ BEGIN;
162
+
163
+ -- Rescue associations from corrupt projects by relinking them to a valid project with the same name
164
+ INSERT OR IGNORE INTO memory_projects (memory_id, project_id)
165
+ SELECT mp.memory_id, (
166
+ SELECT p_good.id
167
+ FROM projects p_good
168
+ WHERE p_good.name = p_bad.name
169
+ AND length(p_good.scope_hash) = 16
170
+ AND trim(p_good.scope_hash, '0123456789abcdef') = ''
171
+ ORDER BY p_good.created_at
172
+ LIMIT 1
173
+ )
174
+ FROM memory_projects mp
175
+ JOIN projects p_bad ON p_bad.id = mp.project_id
176
+ WHERE (length(p_bad.scope_hash) != 16 OR trim(p_bad.scope_hash, '0123456789abcdef') != '')
177
+ AND EXISTS (
178
+ SELECT 1 FROM projects p_good
179
+ WHERE p_good.name = p_bad.name
180
+ AND length(p_good.scope_hash) = 16
181
+ AND trim(p_good.scope_hash, '0123456789abcdef') = ''
182
+ );
183
+
184
+ -- Drop all associations to corrupt projects (memories with no valid counterpart become global)
185
+ DELETE FROM memory_projects
186
+ WHERE project_id IN (
187
+ SELECT id FROM projects
188
+ WHERE length(scope_hash) != 16 OR trim(scope_hash, '0123456789abcdef') != ''
189
+ );
190
+
191
+ -- Delete corrupt projects
192
+ DELETE FROM projects
193
+ WHERE length(scope_hash) != 16 OR trim(scope_hash, '0123456789abcdef') != '';
194
+
195
+ -- Recreate projects table with CHECK constraint on scope_hash
196
+ -- SQLite requires table recreation to add CHECK constraints
197
+ DROP TABLE IF EXISTS projects_new;
198
+
199
+ CREATE TABLE projects_new (
200
+ id TEXT PRIMARY KEY,
201
+ name TEXT NOT NULL,
202
+ scope_hash TEXT NOT NULL UNIQUE
203
+ CHECK(length(scope_hash) = 16 AND trim(scope_hash, '0123456789abcdef') = ''),
204
+ created_at TEXT NOT NULL,
205
+ updated_at TEXT NOT NULL
206
+ );
207
+
208
+ INSERT INTO projects_new SELECT * FROM projects;
209
+
210
+ DROP TABLE projects;
211
+ ALTER TABLE projects_new RENAME TO projects;
212
+
213
+ COMMIT;
214
+
215
+ PRAGMA foreign_keys = ON;
157
216
  `]
158
217
  ];
159
218
  var DatabaseManager = class DatabaseManager {
@@ -630,6 +689,7 @@ var ProjectRepository = class {
630
689
  this.#db = db;
631
690
  }
632
691
  upsertByHash(hash, name) {
692
+ if (!/^[0-9a-f]{16}$/.test(hash)) throw new Error(`Invalid scope hash "${hash}": expected 16 lowercase hex characters`);
633
693
  const now = (/* @__PURE__ */ new Date()).toISOString();
634
694
  const id = (0, node_crypto.randomUUID)();
635
695
  this.#db.db.prepare(`INSERT OR IGNORE INTO projects (id, name, scope_hash, created_at, updated_at) VALUES (?, ?, ?, ?, ?)`).run(id, name, hash, now, now);
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/config/loader.ts","../src/db/errors.ts","../src/db/manager.ts","../src/schemas.ts","../src/db/row-types.ts","../src/embedding/service.ts","../src/project/repository.ts","../src/memory/repository.ts","../src/migrations/index.ts","../src/query/engine.ts","../src/scope/resolver.ts","../src/session/builder.ts","../src/synthesis/repository.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../src/config/loader.ts","../src/db/errors.ts","../src/db/manager.ts","../src/schemas.ts","../src/db/row-types.ts","../src/embedding/service.ts","../src/project/repository.ts","../src/memory/repository.ts","../src/migrations/index.ts","../src/query/engine.ts","../src/scope/resolver.ts","../src/session/builder.ts","../src/synthesis/repository.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/config/loader.ts","../src/db/errors.ts","../src/db/manager.ts","../src/schemas.ts","../src/db/row-types.ts","../src/embedding/service.ts","../src/project/repository.ts","../src/memory/repository.ts","../src/migrations/index.ts","../src/query/engine.ts","../src/scope/resolver.ts","../src/session/builder.ts","../src/synthesis/repository.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/config/loader.ts","../src/db/errors.ts","../src/db/manager.ts","../src/schemas.ts","../src/db/row-types.ts","../src/embedding/service.ts","../src/project/repository.ts","../src/memory/repository.ts","../src/migrations/index.ts","../src/query/engine.ts","../src/scope/resolver.ts","../src/session/builder.ts","../src/synthesis/repository.ts"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -129,6 +129,65 @@ CREATE INDEX IF NOT EXISTS idx_syntheses_expires_at
129
129
 
130
130
  CREATE INDEX IF NOT EXISTS idx_syntheses_scope_inflight
131
131
  ON syntheses(scope) WHERE in_flight_since IS NOT NULL;
132
+ `],
133
+ [5, `
134
+ PRAGMA foreign_keys = OFF;
135
+
136
+ BEGIN;
137
+
138
+ -- Rescue associations from corrupt projects by relinking them to a valid project with the same name
139
+ INSERT OR IGNORE INTO memory_projects (memory_id, project_id)
140
+ SELECT mp.memory_id, (
141
+ SELECT p_good.id
142
+ FROM projects p_good
143
+ WHERE p_good.name = p_bad.name
144
+ AND length(p_good.scope_hash) = 16
145
+ AND trim(p_good.scope_hash, '0123456789abcdef') = ''
146
+ ORDER BY p_good.created_at
147
+ LIMIT 1
148
+ )
149
+ FROM memory_projects mp
150
+ JOIN projects p_bad ON p_bad.id = mp.project_id
151
+ WHERE (length(p_bad.scope_hash) != 16 OR trim(p_bad.scope_hash, '0123456789abcdef') != '')
152
+ AND EXISTS (
153
+ SELECT 1 FROM projects p_good
154
+ WHERE p_good.name = p_bad.name
155
+ AND length(p_good.scope_hash) = 16
156
+ AND trim(p_good.scope_hash, '0123456789abcdef') = ''
157
+ );
158
+
159
+ -- Drop all associations to corrupt projects (memories with no valid counterpart become global)
160
+ DELETE FROM memory_projects
161
+ WHERE project_id IN (
162
+ SELECT id FROM projects
163
+ WHERE length(scope_hash) != 16 OR trim(scope_hash, '0123456789abcdef') != ''
164
+ );
165
+
166
+ -- Delete corrupt projects
167
+ DELETE FROM projects
168
+ WHERE length(scope_hash) != 16 OR trim(scope_hash, '0123456789abcdef') != '';
169
+
170
+ -- Recreate projects table with CHECK constraint on scope_hash
171
+ -- SQLite requires table recreation to add CHECK constraints
172
+ DROP TABLE IF EXISTS projects_new;
173
+
174
+ CREATE TABLE projects_new (
175
+ id TEXT PRIMARY KEY,
176
+ name TEXT NOT NULL,
177
+ scope_hash TEXT NOT NULL UNIQUE
178
+ CHECK(length(scope_hash) = 16 AND trim(scope_hash, '0123456789abcdef') = ''),
179
+ created_at TEXT NOT NULL,
180
+ updated_at TEXT NOT NULL
181
+ );
182
+
183
+ INSERT INTO projects_new SELECT * FROM projects;
184
+
185
+ DROP TABLE projects;
186
+ ALTER TABLE projects_new RENAME TO projects;
187
+
188
+ COMMIT;
189
+
190
+ PRAGMA foreign_keys = ON;
132
191
  `]
133
192
  ];
134
193
  var DatabaseManager = class DatabaseManager {
@@ -605,6 +664,7 @@ var ProjectRepository = class {
605
664
  this.#db = db;
606
665
  }
607
666
  upsertByHash(hash, name) {
667
+ if (!/^[0-9a-f]{16}$/.test(hash)) throw new Error(`Invalid scope hash "${hash}": expected 16 lowercase hex characters`);
608
668
  const now = (/* @__PURE__ */ new Date()).toISOString();
609
669
  const id = randomUUID();
610
670
  this.#db.db.prepare(`INSERT OR IGNORE INTO projects (id, name, scope_hash, created_at, updated_at) VALUES (?, ?, ?, ?, ?)`).run(id, name, hash, now, now);
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["MIGRATIONS","#db","#init","#initInMemory","#runMigrations","#db","#embedding","#projects","#getEventsForMemories","#db","#db","#embedding","#repo","#computeScore","#db","#db"],"sources":["../src/config/loader.ts","../src/db/errors.ts","../src/db/manager.ts","../src/schemas.ts","../src/db/row-types.ts","../src/embedding/service.ts","../src/memory/repository.ts","../src/scope/resolver.ts","../src/migrations/index.ts","../src/project/repository.ts","../src/query/engine.ts","../src/session/builder.ts","../src/synthesis/repository.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\ninterface MemoryConfig {\n synthesis?: { enabled?: boolean };\n}\n\nfunction loadConfig(): MemoryConfig | null {\n const configPath = join(homedir(), \".membank\", \"config.json\");\n try {\n const raw = readFileSync(configPath, \"utf8\");\n return JSON.parse(raw) as MemoryConfig;\n } catch {\n return null;\n }\n}\n\nexport function isSynthesisEnabled(): boolean {\n const config = loadConfig();\n return config?.synthesis?.enabled === true;\n}\n","export class MembankError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"MembankError\";\n }\n}\n\nexport class DatabaseError extends MembankError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"DatabaseError\";\n }\n}\n","import { mkdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport BetterSqlite3 from \"better-sqlite3\";\nimport * as sqliteVec from \"sqlite-vec\";\nimport { DatabaseError } from \"./errors.js\";\n\nconst DEFAULT_DB_PATH = join(homedir(), \".membank\", \"memory.db\");\n\ntype VecLoader = (db: BetterSqlite3.Database) => void;\n\nconst MIGRATIONS: [number, string][] = [\n [\n 1,\n `\nCREATE TABLE IF NOT EXISTS memories (\n id TEXT PRIMARY KEY,\n content TEXT NOT NULL,\n type TEXT NOT NULL,\n tags TEXT NOT NULL DEFAULT '[]',\n scope TEXT NOT NULL,\n source TEXT,\n access_count INTEGER NOT NULL DEFAULT 0,\n pinned INTEGER NOT NULL DEFAULT 0,\n needs_review INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n\nCREATE VIRTUAL TABLE IF NOT EXISTS embeddings USING vec0(\n embedding FLOAT[384]\n);\n`,\n ],\n [\n 2,\n `\nCREATE TABLE IF NOT EXISTS projects (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n scope_hash TEXT NOT NULL UNIQUE,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS memory_projects (\n memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n PRIMARY KEY (memory_id, project_id)\n);\n\nINSERT OR IGNORE INTO projects (id, name, scope_hash, created_at, updated_at)\nSELECT\n lower(hex(randomblob(16))),\n 'project-' || substr(scope, 1, 8),\n scope,\n datetime('now'),\n datetime('now')\nFROM memories\nWHERE scope != 'global'\nGROUP BY scope;\n\nINSERT OR IGNORE INTO memory_projects (memory_id, project_id)\nSELECT m.id, p.id\nFROM memories m\nJOIN projects p ON p.scope_hash = m.scope\nWHERE m.scope != 'global';\n\nALTER TABLE memories DROP COLUMN scope;\n`,\n ],\n [\n 3,\n `\nCREATE TABLE IF NOT EXISTS memory_review_events (\n id TEXT PRIMARY KEY,\n memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n conflicting_memory_id TEXT REFERENCES memories(id) ON DELETE SET NULL,\n similarity REAL NOT NULL,\n conflict_content_snapshot TEXT NOT NULL,\n reason TEXT NOT NULL,\n created_at TEXT NOT NULL,\n resolved_at TEXT\n);\n\nCREATE INDEX IF NOT EXISTS idx_review_events_memory_open\n ON memory_review_events(memory_id) WHERE resolved_at IS NULL;\n\nALTER TABLE memories DROP COLUMN needs_review;\n`,\n ],\n [\n 4,\n `\nCREATE TABLE IF NOT EXISTS syntheses (\n id TEXT PRIMARY KEY,\n scope TEXT NOT NULL,\n content TEXT NOT NULL,\n source_memory_hash TEXT NOT NULL,\n synthesized_at TEXT NOT NULL,\n expires_at TEXT NOT NULL,\n in_flight_since TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE(scope),\n CHECK(expires_at > synthesized_at)\n);\n\nCREATE INDEX IF NOT EXISTS idx_syntheses_expires_at\n ON syntheses(expires_at);\n\nCREATE INDEX IF NOT EXISTS idx_syntheses_scope_inflight\n ON syntheses(scope) WHERE in_flight_since IS NOT NULL;\n`,\n ],\n];\n\nexport class DatabaseManager {\n readonly #db: BetterSqlite3.Database;\n\n private constructor(db: BetterSqlite3.Database) {\n this.#db = db;\n }\n\n static open(dbPath?: string): DatabaseManager {\n const resolvedPath = dbPath ?? DEFAULT_DB_PATH;\n mkdirSync(dirname(resolvedPath), { recursive: true });\n const db = new BetterSqlite3(resolvedPath);\n return DatabaseManager.#init(db, sqliteVec.load);\n }\n\n static openInMemory(): DatabaseManager {\n return DatabaseManager.#initInMemory(sqliteVec.load);\n }\n\n /** For testing: inject a custom vec loader (e.g. a throwing stub). */\n static _openInMemoryWithLoader(loader: VecLoader): DatabaseManager {\n return DatabaseManager.#initInMemory(loader);\n }\n\n static #initInMemory(loader: VecLoader): DatabaseManager {\n const db = new BetterSqlite3(\":memory:\");\n return DatabaseManager.#init(db, loader);\n }\n\n static #init(db: BetterSqlite3.Database, loader: VecLoader): DatabaseManager {\n try {\n loader(db);\n } catch (err) {\n throw new DatabaseError(\"Failed to load sqlite-vec extension\", {\n cause: err,\n });\n }\n\n db.pragma(\"journal_mode = WAL\");\n db.pragma(\"foreign_keys = ON\");\n\n const manager = new DatabaseManager(db);\n manager.#runMigrations();\n return manager;\n }\n\n #runMigrations(): void {\n // Bootstrap the meta table before reading schema_version from it\n this.#db.exec(`\n CREATE TABLE IF NOT EXISTS meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n `);\n\n const row = this.#db\n .prepare<[], { value: string }>(\"SELECT value FROM meta WHERE key = 'schema_version'\")\n .get();\n\n const currentVersion = row ? Number.parseInt(row.value, 10) : 0;\n\n for (const [targetVersion, sql] of MIGRATIONS) {\n if (currentVersion < targetVersion) {\n this.#db.exec(sql);\n this.#db\n .prepare(\"INSERT OR REPLACE INTO meta (key, value) VALUES ('schema_version', ?)\")\n .run(String(targetVersion));\n }\n }\n }\n\n get db(): BetterSqlite3.Database {\n return this.#db;\n }\n\n close(): void {\n this.#db.close();\n }\n}\n","import { z } from \"zod\";\n\nexport const MEMORY_TYPE_VALUES = [\n \"correction\",\n \"preference\",\n \"decision\",\n \"learning\",\n \"fact\",\n] as const;\n\nexport const MemoryTypeSchema = z.enum(MEMORY_TYPE_VALUES);\nexport type MemoryType = z.infer<typeof MemoryTypeSchema>;\n\nexport const TagsJsonSchema = z.array(z.string());\n\nexport const ProjectSchema = z.object({\n id: z.string(),\n name: z.string(),\n scopeHash: z.string(),\n createdAt: z.string(),\n updatedAt: z.string(),\n});\nexport type Project = z.infer<typeof ProjectSchema>;\n\nexport const ReviewReasonSchema = z.enum([\"similarity_dedup\"]);\nexport type ReviewReason = z.infer<typeof ReviewReasonSchema>;\n\nexport const ReviewEventSchema = z.object({\n id: z.string(),\n memoryId: z.string(),\n conflictingMemoryId: z.string().nullable(),\n similarity: z.number(),\n conflictContentSnapshot: z.string(),\n reason: ReviewReasonSchema,\n createdAt: z.string(),\n resolvedAt: z.string().nullable(),\n});\nexport type ReviewEvent = z.infer<typeof ReviewEventSchema>;\n\nexport const ReviewEventRowSchema = z.object({\n id: z.string(),\n memory_id: z.string(),\n conflicting_memory_id: z.string().nullable(),\n similarity: z.number(),\n conflict_content_snapshot: z.string(),\n reason: ReviewReasonSchema,\n created_at: z.string(),\n resolved_at: z.string().nullable(),\n});\nexport type ReviewEventRow = z.infer<typeof ReviewEventRowSchema>;\n\nexport const MemorySchema = z.object({\n id: z.string(),\n content: z.string(),\n type: MemoryTypeSchema,\n tags: z.array(z.string()),\n projects: z.array(ProjectSchema),\n sourceHarness: z.string().nullable(),\n accessCount: z.number().int().nonnegative(),\n pinned: z.boolean(),\n reviewEvents: z.array(ReviewEventSchema),\n createdAt: z.string(),\n updatedAt: z.string(),\n});\nexport type Memory = z.infer<typeof MemorySchema>;\n\nexport const QueryOptionsSchema = z.object({\n query: z.string().min(1),\n type: MemoryTypeSchema.optional(),\n projectHash: z.string().optional(),\n limit: z.number().int().positive().optional(),\n includePinned: z.boolean().optional(),\n});\nexport type QueryOptions = z.infer<typeof QueryOptionsSchema>;\n\nexport const SaveOptionsSchema = z.object({\n content: z.string().min(1),\n type: MemoryTypeSchema,\n tags: z.array(z.string()).optional(),\n projectScope: z.object({ hash: z.string(), name: z.string() }).optional(),\n sourceHarness: z.string().optional(),\n});\nexport type SaveOptions = z.infer<typeof SaveOptionsSchema>;\n\nexport const MemoryPatchSchema = z.object({\n content: z.string().min(1).optional(),\n tags: z.array(z.string()).optional(),\n type: MemoryTypeSchema.optional(),\n});\nexport type MemoryPatch = z.infer<typeof MemoryPatchSchema>;\n\nexport const SynthesisSchema = z.object({\n id: z.string(),\n scope: z.string(),\n content: z.string(),\n sourceMemoryHash: z.string(),\n synthesizedAt: z.string(),\n expiresAt: z.string(),\n inFlightSince: z.string().nullable(),\n createdAt: z.string(),\n updatedAt: z.string(),\n});\nexport type Synthesis = z.infer<typeof SynthesisSchema>;\n\nexport const SessionContextSchema = z.object({\n stats: z.record(MemoryTypeSchema, z.number()),\n pinnedGlobal: z.array(MemorySchema),\n pinnedProject: z.array(MemorySchema),\n synthesis: z.string().optional(),\n});\nexport type SessionContext = z.infer<typeof SessionContextSchema>;\n\nexport const MemoryRowSchema = z.object({\n id: z.string(),\n content: z.string(),\n type: z.string(),\n tags: z.string(),\n source: z.string().nullable(),\n access_count: z.number(),\n pinned: z.number(),\n created_at: z.string(),\n updated_at: z.string(),\n});\nexport type MemoryRow = z.infer<typeof MemoryRowSchema>;\n\nexport const ProjectRowSchema = z.object({\n id: z.string(),\n name: z.string(),\n scope_hash: z.string(),\n created_at: z.string(),\n updated_at: z.string(),\n});\nexport type ProjectRow = z.infer<typeof ProjectRowSchema>;\n","import { MemoryTypeSchema, ReviewEventRowSchema, TagsJsonSchema } from \"../schemas.js\";\nimport type {\n Memory,\n MemoryRow,\n Project,\n ProjectRow,\n ReviewEvent,\n ReviewEventRow,\n} from \"../types.js\";\n\nexport function rowToMemory(\n row: MemoryRow,\n projects: Project[],\n reviewEvents: ReviewEvent[] = []\n): Memory {\n return {\n id: row.id,\n content: row.content,\n type: MemoryTypeSchema.parse(row.type),\n tags: TagsJsonSchema.parse(JSON.parse(row.tags)),\n projects,\n sourceHarness: row.source,\n accessCount: row.access_count,\n pinned: row.pinned !== 0,\n reviewEvents,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nexport function rowToReviewEvent(row: ReviewEventRow): ReviewEvent {\n const parsed = ReviewEventRowSchema.parse(row);\n return {\n id: parsed.id,\n memoryId: parsed.memory_id,\n conflictingMemoryId: parsed.conflicting_memory_id,\n similarity: parsed.similarity,\n conflictContentSnapshot: parsed.conflict_content_snapshot,\n reason: parsed.reason,\n createdAt: parsed.created_at,\n resolvedAt: parsed.resolved_at,\n };\n}\n\nexport function rowToProject(row: ProjectRow): Project {\n return {\n id: row.id,\n name: row.name,\n scopeHash: row.scope_hash,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { pipeline } from \"@huggingface/transformers\";\n\nexport type ProgressCallback = (progress: { status: string; progress?: number }) => void;\n\nexport class EmbeddingService {\n private readonly modelCachePath: string;\n private readonly onProgress: ProgressCallback | undefined;\n private pipelineInstance: Awaited<ReturnType<typeof pipeline>> | null = null;\n\n constructor(modelCachePath?: string, onProgress?: ProgressCallback) {\n this.modelCachePath = modelCachePath ?? join(homedir(), \".membank\", \"models\");\n this.onProgress = onProgress;\n }\n\n private async getPipeline(): Promise<Awaited<ReturnType<typeof pipeline>>> {\n if (this.pipelineInstance === null) {\n this.pipelineInstance = await pipeline(\"feature-extraction\", \"Xenova/bge-small-en-v1.5\", {\n cache_dir: this.modelCachePath,\n progress_callback: this.onProgress,\n });\n }\n return this.pipelineInstance;\n }\n\n async embed(text: string): Promise<Float32Array> {\n const pipe = await this.getPipeline();\n // Shape: [1, seq_len, 384]. Cast to any to bypass the non-unified pipeline union signature.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const output = await (\n pipe as (input: string, opts: Record<string, unknown>) => Promise<unknown>\n )(text, { pooling: \"mean\", normalize: true });\n\n // @huggingface/transformers Tensor has a .data property with the flat array\n const tensor = output as { data: Float32Array | number[] };\n const flat = tensor.data;\n\n return flat instanceof Float32Array ? flat : new Float32Array(flat);\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport type { DatabaseManager } from \"../db/manager.js\";\nimport { rowToMemory, rowToReviewEvent } from \"../db/row-types.js\";\nimport type { EmbeddingService } from \"../embedding/service.js\";\nimport type { ProjectRepository } from \"../project/repository.js\";\nimport {\n MEMORY_TYPE_VALUES,\n MemoryPatchSchema,\n MemoryRowSchema,\n MemoryTypeSchema,\n ReviewEventRowSchema,\n SaveOptionsSchema,\n} from \"../schemas.js\";\nimport type {\n Memory,\n MemoryPatch,\n MemoryRow,\n MemoryType,\n ReviewEvent,\n ReviewEventRow,\n SaveOptions,\n} from \"../types.js\";\n\nexport const PIN_BUDGET_THRESHOLD = 8000;\n\ninterface SimilarityRow extends MemoryRow {\n rowid: number;\n similarity: number;\n}\n\nexport class MemoryRepository {\n readonly #db: DatabaseManager;\n readonly #embedding: EmbeddingService;\n readonly #projects: ProjectRepository;\n\n constructor(\n db: DatabaseManager,\n embeddingService: EmbeddingService,\n projects: ProjectRepository\n ) {\n this.#db = db;\n this.#embedding = embeddingService;\n this.#projects = projects;\n }\n\n async save(options: SaveOptions): Promise<Memory> {\n const {\n content,\n type,\n tags = [],\n projectScope,\n sourceHarness,\n } = SaveOptionsSchema.parse(options);\n\n const embedding = await this.#embedding.embed(content);\n const embeddingBlob = Buffer.from(embedding.buffer);\n\n // Dedup: find similar memory in same context\n let top: SimilarityRow | undefined;\n if (projectScope !== undefined) {\n top = this.#db.db\n .prepare<[Buffer, string, string], SimilarityRow>(\n `SELECT m.rowid, m.*, (1 - vec_distance_cosine(e.embedding, ?)) AS similarity\n FROM memories m JOIN embeddings e ON e.rowid = m.rowid\n JOIN memory_projects mp ON mp.memory_id = m.id\n JOIN projects p ON p.id = mp.project_id\n WHERE m.type = ? AND p.scope_hash = ?\n ORDER BY similarity DESC LIMIT 1`\n )\n .get(embeddingBlob, type, projectScope.hash);\n } else {\n top = this.#db.db\n .prepare<[Buffer, string], SimilarityRow>(\n `SELECT m.rowid, m.*, (1 - vec_distance_cosine(e.embedding, ?)) AS similarity\n FROM memories m JOIN embeddings e ON e.rowid = m.rowid\n WHERE m.type = ?\n AND m.id NOT IN (SELECT memory_id FROM memory_projects)\n ORDER BY similarity DESC LIMIT 1`\n )\n .get(embeddingBlob, type);\n }\n\n const now = new Date().toISOString();\n\n if (top !== undefined && top.similarity > 0.92) {\n this.#db.db\n .prepare(`UPDATE memories SET content = ?, updated_at = ? WHERE id = ?`)\n .run(content, now, top.id);\n this.#db.db\n .prepare(`UPDATE embeddings SET embedding = ? WHERE rowid = ?`)\n .run(embeddingBlob, top.rowid);\n\n const updated = MemoryRowSchema.parse(\n this.#db.db.prepare<[string], unknown>(`SELECT * FROM memories WHERE id = ?`).get(top.id)\n );\n\n const projectMap = this.#projects.getProjectsForMemories([top.id]);\n const events = this.#getEventsForMemories([top.id]);\n return rowToMemory(updated, projectMap.get(top.id) ?? [], events.get(top.id) ?? []);\n }\n\n const id = randomUUID();\n\n this.#db.db\n .prepare(\n `INSERT INTO memories (id, content, type, tags, source, access_count, pinned, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, 0, 0, ?, ?)`\n )\n .run(id, content, type, JSON.stringify(tags), sourceHarness ?? null, now, now);\n\n if (top !== undefined && top.similarity >= 0.75) {\n this.#db.db\n .prepare(\n `INSERT INTO memory_review_events\n (id, memory_id, conflicting_memory_id, similarity, conflict_content_snapshot, reason, created_at)\n VALUES (?, ?, ?, ?, ?, 'similarity_dedup', ?)`\n )\n .run(randomUUID(), top.id, id, top.similarity, content, now);\n }\n\n this.#db.db\n .prepare(\n `INSERT INTO embeddings (rowid, embedding) SELECT m.rowid, ? FROM memories m WHERE m.id = ?`\n )\n .run(embeddingBlob, id);\n\n if (projectScope !== undefined) {\n const project = this.#projects.upsertByHash(projectScope.hash, projectScope.name);\n this.#projects.addAssociation(id, project.id);\n }\n\n const row = MemoryRowSchema.parse(\n this.#db.db.prepare<[string], unknown>(`SELECT * FROM memories WHERE id = ?`).get(id)\n );\n\n const projectMap = this.#projects.getProjectsForMemories([id]);\n return rowToMemory(row, projectMap.get(id) ?? [], []);\n }\n\n async update(id: string, patch: MemoryPatch): Promise<Memory> {\n const { content, tags, type } = MemoryPatchSchema.parse(patch);\n\n const existing = this.#db.db\n .prepare<[string], MemoryRow & { rowid: number }>(\n `SELECT m.rowid, m.* FROM memories m WHERE m.id = ?`\n )\n .get(id);\n\n if (existing === undefined) {\n throw new Error(`Memory not found: ${id}`);\n }\n\n const now = new Date().toISOString();\n const sets: string[] = [\"updated_at = ?\"];\n const values: string[] = [now];\n\n if (content !== undefined) {\n sets.push(\"content = ?\");\n values.push(content);\n }\n\n if (tags !== undefined) {\n sets.push(\"tags = ?\");\n values.push(JSON.stringify(tags));\n }\n\n if (type !== undefined) {\n sets.push(\"type = ?\");\n values.push(type);\n }\n\n values.push(id);\n this.#db.db.prepare(`UPDATE memories SET ${sets.join(\", \")} WHERE id = ?`).run(...values);\n\n if (content !== undefined) {\n const embedding = await this.#embedding.embed(content);\n const embeddingBlob = Buffer.from(embedding.buffer);\n this.#db.db\n .prepare(`UPDATE embeddings SET embedding = ? WHERE rowid = ?`)\n .run(embeddingBlob, existing.rowid);\n }\n\n const updated = MemoryRowSchema.parse(\n this.#db.db.prepare<[string], unknown>(`SELECT * FROM memories WHERE id = ?`).get(id)\n );\n\n const projectMap = this.#projects.getProjectsForMemories([id]);\n const events = this.#getEventsForMemories([id]);\n return rowToMemory(updated, projectMap.get(id) ?? [], events.get(id) ?? []);\n }\n\n delete(id: string): Promise<void> {\n const row = this.#db.db\n .prepare<[string], { rowid: number }>(`SELECT rowid FROM memories WHERE id = ?`)\n .get(id);\n\n if (row !== undefined) {\n this.#db.db.prepare(`DELETE FROM embeddings WHERE rowid = ?`).run(row.rowid);\n }\n\n this.#db.db.prepare(`DELETE FROM memory_projects WHERE memory_id = ?`).run(id);\n this.#db.db.prepare(`DELETE FROM memories WHERE id = ?`).run(id);\n\n return Promise.resolve();\n }\n\n list(opts?: { type?: MemoryType; pinned?: boolean }): Memory[] {\n const conditions: string[] = [];\n const params: (string | number)[] = [];\n\n if (opts?.type !== undefined) {\n conditions.push(\"type = ?\");\n params.push(opts.type);\n }\n\n if (opts?.pinned === true) {\n conditions.push(\"pinned = 1\");\n }\n\n const where = conditions.length > 0 ? `WHERE ${conditions.join(\" AND \")}` : \"\";\n const rows = this.#db.db\n .prepare<(string | number)[], MemoryRow>(\n `SELECT * FROM memories ${where} ORDER BY created_at DESC`\n )\n .all(...params);\n\n if (rows.length === 0) return [];\n\n const ids = rows.map((r) => r.id);\n const projectMap = this.#projects.getProjectsForMemories(ids);\n const eventMap = this.#getEventsForMemories(ids);\n return rows.map((row) =>\n rowToMemory(row, projectMap.get(row.id) ?? [], eventMap.get(row.id) ?? [])\n );\n }\n\n listFlagged(): Memory[] {\n const rows = this.#db.db\n .prepare<[], MemoryRow>(\n `SELECT * FROM memories\n WHERE EXISTS (\n SELECT 1 FROM memory_review_events e\n WHERE e.memory_id = memories.id AND e.resolved_at IS NULL\n )\n ORDER BY created_at DESC`\n )\n .all();\n\n if (rows.length === 0) return [];\n\n const ids = rows.map((r) => r.id);\n const projectMap = this.#projects.getProjectsForMemories(ids);\n const eventMap = this.#getEventsForMemories(ids, { unresolvedOnly: true });\n return rows.map((row) =>\n rowToMemory(row, projectMap.get(row.id) ?? [], eventMap.get(row.id) ?? [])\n );\n }\n\n listReviewEvents(memoryId: string, opts?: { unresolvedOnly?: boolean }): ReviewEvent[] {\n const where =\n opts?.unresolvedOnly === true\n ? \"WHERE memory_id = ? AND resolved_at IS NULL\"\n : \"WHERE memory_id = ?\";\n\n const rows = this.#db.db\n .prepare<[string], ReviewEventRow>(\n `SELECT * FROM memory_review_events ${where} ORDER BY created_at DESC`\n )\n .all(memoryId);\n\n return rows.map((r) => rowToReviewEvent(ReviewEventRowSchema.parse(r)));\n }\n\n resolveReviewEvents(memoryId: string): void {\n const now = new Date().toISOString();\n this.#db.db\n .prepare(\n `UPDATE memory_review_events SET resolved_at = ? WHERE memory_id = ? AND resolved_at IS NULL`\n )\n .run(now, memoryId);\n }\n\n #getEventsForMemories(\n ids: string[],\n opts?: { unresolvedOnly?: boolean }\n ): Map<string, ReviewEvent[]> {\n if (ids.length === 0) return new Map();\n\n const placeholders = ids.map(() => \"?\").join(\", \");\n const unresolvedClause = opts?.unresolvedOnly === true ? \"AND resolved_at IS NULL\" : \"\";\n const rows = this.#db.db\n .prepare<string[], ReviewEventRow>(\n `SELECT * FROM memory_review_events\n WHERE memory_id IN (${placeholders}) ${unresolvedClause}\n ORDER BY created_at DESC`\n )\n .all(...ids);\n\n const map = new Map<string, ReviewEvent[]>();\n for (const row of rows) {\n const event = rowToReviewEvent(ReviewEventRowSchema.parse(row));\n const existing = map.get(event.memoryId) ?? [];\n existing.push(event);\n map.set(event.memoryId, existing);\n }\n return map;\n }\n\n getPinnedCharCount(): number {\n const row = this.#db.db\n .prepare<[], { total: number }>(\n `SELECT COALESCE(SUM(LENGTH(content)), 0) as total FROM memories WHERE pinned = 1`\n )\n .get() ?? { total: 0 };\n return row.total;\n }\n\n stats(): {\n byType: Record<MemoryType, number>;\n total: number;\n pinned: number;\n needsReview: number;\n pinBudgetChars: number;\n } {\n const byType = Object.fromEntries(MEMORY_TYPE_VALUES.map((t) => [t, 0])) as Record<\n MemoryType,\n number\n >;\n\n const typeRows = this.#db.db\n .prepare<[], { type: string; count: number }>(\n `SELECT type, COUNT(*) as count FROM memories GROUP BY type`\n )\n .all();\n\n for (const row of typeRows) {\n const parsed = MemoryTypeSchema.safeParse(row.type);\n if (parsed.success) {\n byType[parsed.data] = row.count;\n }\n }\n\n const aggregates = this.#db.db\n .prepare<[], { total: number; pinned: number | null }>(\n `SELECT COUNT(*) as total, SUM(pinned) as pinned FROM memories`\n )\n .get() ?? { total: 0, pinned: 0 };\n\n const reviewRow = this.#db.db\n .prepare<[], { needsReview: number }>(\n `SELECT COUNT(DISTINCT memory_id) as needsReview FROM memory_review_events WHERE resolved_at IS NULL`\n )\n .get() ?? { needsReview: 0 };\n\n return {\n byType,\n total: aggregates.total,\n pinned: aggregates.pinned ?? 0,\n needsReview: reviewRow.needsReview,\n pinBudgetChars: this.getPinnedCharCount(),\n };\n }\n\n setPin(id: string, pinned: boolean): Memory {\n const existing = this.#db.db\n .prepare<[string], MemoryRow>(`SELECT * FROM memories WHERE id = ?`)\n .get(id);\n\n if (existing === undefined) {\n throw new Error(`Memory not found: ${id}`);\n }\n\n const now = new Date().toISOString();\n this.#db.db\n .prepare(`UPDATE memories SET pinned = ?, updated_at = ? WHERE id = ?`)\n .run(pinned ? 1 : 0, now, id);\n\n const updated = MemoryRowSchema.parse(\n this.#db.db.prepare<[string], unknown>(`SELECT * FROM memories WHERE id = ?`).get(id)\n );\n\n const projectMap = this.#projects.getProjectsForMemories([id]);\n const events = this.#getEventsForMemories([id]);\n return rowToMemory(updated, projectMap.get(id) ?? [], events.get(id) ?? []);\n }\n\n incrementAccessCount(id: string): void {\n this.#db.db.prepare(`UPDATE memories SET access_count = access_count + 1 WHERE id = ?`).run(id);\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\nfunction sha256Truncated(input: string): string {\n return createHash(\"sha256\").update(input).digest(\"hex\").slice(0, 16);\n}\n\nexport async function resolveProject(): Promise<{ hash: string; name: string }> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"remote\", \"get-url\", \"origin\"]);\n const url = stdout.trim();\n if (url) {\n const hash = sha256Truncated(url);\n // parse last path segment, strip .git suffix\n const name =\n url\n .split(\"/\")\n .pop()\n ?.replace(/\\.git$/, \"\") ?? hash.slice(0, 8);\n return { hash, name };\n }\n } catch {\n // fall through\n }\n\n const cwd = process.cwd();\n const hash = sha256Truncated(cwd);\n const name = cwd.split(/[/\\\\]/).filter(Boolean).pop() ?? hash.slice(0, 8);\n return { hash, name };\n}\n\nexport async function resolveScope(): Promise<string> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"remote\", \"get-url\", \"origin\"]);\n const url = stdout.trim();\n if (url) {\n return sha256Truncated(url);\n }\n } catch {\n // git not available, not a repo, or no remote — fall through to cwd fallback\n }\n\n return sha256Truncated(process.cwd());\n}\n","import type { ProjectRepository } from \"../project/index.js\";\nimport { resolveProject } from \"../scope/index.js\";\n\nexport interface MigrationMeta {\n name: string;\n description: string;\n}\n\nexport interface ScopeToProjectsResult {\n migration: \"scope-to-projects\";\n oldName: string;\n newName: string;\n memoryCount: number;\n}\n\nexport const MIGRATIONS: MigrationMeta[] = [\n {\n name: \"scope-to-projects\",\n description:\n \"Rename the auto-migrated project for the current directory from its generic hash-derived name to the resolved repo/directory name.\",\n },\n];\n\nexport async function runScopeToProjectsMigration(\n projects: ProjectRepository\n): Promise<ScopeToProjectsResult | null> {\n const resolved = await resolveProject();\n const project = projects.getByHash(resolved.hash);\n\n if (project === undefined) {\n return null;\n }\n\n const oldName = project.name;\n const memoryCount = projects.countMemories(project.id);\n projects.rename(project.id, resolved.name);\n\n return {\n migration: \"scope-to-projects\",\n oldName,\n newName: resolved.name,\n memoryCount,\n };\n}\n","import { randomUUID } from \"node:crypto\";\nimport type { DatabaseManager } from \"../db/manager.js\";\nimport { rowToProject } from \"../db/row-types.js\";\nimport { ProjectRowSchema } from \"../schemas.js\";\nimport type { Project, ProjectRow } from \"../types.js\";\n\ninterface ProjectMemoryRow extends ProjectRow {\n memory_id: string;\n}\n\nexport class ProjectRepository {\n readonly #db: DatabaseManager;\n\n constructor(db: DatabaseManager) {\n this.#db = db;\n }\n\n upsertByHash(hash: string, name: string): Project {\n const now = new Date().toISOString();\n const id = randomUUID();\n this.#db.db\n .prepare(\n `INSERT OR IGNORE INTO projects (id, name, scope_hash, created_at, updated_at) VALUES (?, ?, ?, ?, ?)`\n )\n .run(id, name, hash, now, now);\n\n const row = ProjectRowSchema.parse(\n this.#db.db\n .prepare<[string], unknown>(`SELECT * FROM projects WHERE scope_hash = ?`)\n .get(hash)\n );\n\n return rowToProject(row);\n }\n\n rename(id: string, name: string): Project {\n const now = new Date().toISOString();\n this.#db.db\n .prepare(`UPDATE projects SET name = ?, updated_at = ? WHERE id = ?`)\n .run(name, now, id);\n\n const row = this.#db.db\n .prepare<[string], ProjectRow>(`SELECT * FROM projects WHERE id = ?`)\n .get(id);\n\n if (row === undefined) throw new Error(`Project not found: ${id}`);\n return rowToProject(row);\n }\n\n list(): Project[] {\n return this.#db.db\n .prepare<[], ProjectRow>(`SELECT * FROM projects ORDER BY name ASC`)\n .all()\n .map(rowToProject);\n }\n\n getByHash(hash: string): Project | undefined {\n const row = this.#db.db\n .prepare<[string], ProjectRow>(`SELECT * FROM projects WHERE scope_hash = ?`)\n .get(hash);\n return row !== undefined ? rowToProject(row) : undefined;\n }\n\n getByName(name: string): Project | undefined {\n const row = this.#db.db\n .prepare<[string], ProjectRow>(`SELECT * FROM projects WHERE name = ? LIMIT 1`)\n .get(name);\n return row !== undefined ? rowToProject(row) : undefined;\n }\n\n addAssociation(memoryId: string, projectId: string): void {\n this.#db.db\n .prepare(`INSERT OR IGNORE INTO memory_projects (memory_id, project_id) VALUES (?, ?)`)\n .run(memoryId, projectId);\n }\n\n removeAssociation(memoryId: string, projectId: string): void {\n this.#db.db\n .prepare(`DELETE FROM memory_projects WHERE memory_id = ? AND project_id = ?`)\n .run(memoryId, projectId);\n }\n\n countMemories(projectId: string): number {\n const row = this.#db.db\n .prepare<[string], { count: number }>(\n `SELECT COUNT(*) AS count FROM memory_projects WHERE project_id = ?`\n )\n .get(projectId);\n return row?.count ?? 0;\n }\n\n getProjectsForMemories(memoryIds: string[]): Map<string, Project[]> {\n if (memoryIds.length === 0) return new Map();\n const placeholders = memoryIds.map(() => \"?\").join(\",\");\n const rows = this.#db.db\n .prepare<string[], ProjectMemoryRow>(\n `SELECT p.*, mp.memory_id FROM projects p\n JOIN memory_projects mp ON mp.project_id = p.id\n WHERE mp.memory_id IN (${placeholders})`\n )\n .all(...memoryIds);\n\n const result = new Map<string, Project[]>();\n for (const row of rows) {\n const list = result.get(row.memory_id) ?? [];\n list.push(rowToProject(row));\n result.set(row.memory_id, list);\n }\n return result;\n }\n}\n","import type { DatabaseManager } from \"../db/manager.js\";\nimport { rowToMemory } from \"../db/row-types.js\";\nimport type { EmbeddingService } from \"../embedding/service.js\";\nimport type { MemoryRepository } from \"../memory/repository.js\";\nimport { QueryOptionsSchema } from \"../schemas.js\";\nimport type { Memory, MemoryRow, MemoryType, QueryOptions } from \"../types.js\";\n\ninterface QueryMemoryRow extends MemoryRow {\n cosine_sim: number;\n}\n\nconst TYPE_WEIGHTS = {\n correction: 1.0,\n preference: 0.8,\n decision: 0.6,\n learning: 0.4,\n fact: 0.2,\n} satisfies Record<MemoryType, number>;\n\nexport class QueryEngine {\n readonly #db: DatabaseManager;\n readonly #embedding: EmbeddingService;\n readonly #repo: MemoryRepository;\n\n constructor(db: DatabaseManager, embeddingService: EmbeddingService, repo: MemoryRepository) {\n this.#db = db;\n this.#embedding = embeddingService;\n this.#repo = repo;\n }\n\n async query(options: QueryOptions): Promise<Array<Memory & { score: number }>> {\n const {\n query,\n type,\n projectHash,\n limit = 10,\n includePinned,\n } = QueryOptionsSchema.parse(options);\n\n const queryEmbedding = await this.#embedding.embed(query);\n const queryBlob = Buffer.from(queryEmbedding.buffer);\n\n const whereClauses: string[] = [];\n const params: unknown[] = [queryBlob];\n let joinClause = \"\";\n\n if (!includePinned) {\n whereClauses.push(\"m.pinned = 0\");\n }\n\n if (type !== undefined) {\n whereClauses.push(\"m.type = ?\");\n params.push(type);\n }\n\n if (projectHash !== undefined) {\n joinClause =\n \"LEFT JOIN memory_projects mp ON mp.memory_id = m.id LEFT JOIN projects p ON p.id = mp.project_id\";\n whereClauses.push(\"p.scope_hash = ?\");\n params.push(projectHash);\n }\n\n const whereSQL = whereClauses.length > 0 ? `WHERE ${whereClauses.join(\" AND \")}` : \"\";\n\n const sql = `\n SELECT m.*, (1 - vec_distance_cosine(e.embedding, ?)) AS cosine_sim\n FROM memories m JOIN embeddings e ON e.rowid = m.rowid\n ${joinClause}\n ${whereSQL}\n `;\n\n const rows = this.#db.db.prepare<unknown[], QueryMemoryRow>(sql).all(...params);\n\n const now = Date.now();\n\n const scored = rows\n .filter((row) => row.cosine_sim > 0)\n .map((row) => {\n const memory = rowToMemory(row, []);\n const score = this.#computeScore(memory, row.cosine_sim, now);\n return { ...memory, score };\n });\n\n scored.sort((a, b) => b.score - a.score);\n\n const results = scored.slice(0, limit);\n\n for (const result of results) {\n this.#repo.incrementAccessCount(result.id);\n }\n\n return results;\n }\n\n #computeScore(memory: Memory, cosine_sim: number, now: number): number {\n const typeWeight = TYPE_WEIGHTS[memory.type];\n const accessCountNorm = memory.accessCount / (memory.accessCount + 10);\n const daysSinceUpdate = (now - new Date(memory.updatedAt).getTime()) / 86400000;\n const recencyNorm = 1 / (1 + daysSinceUpdate);\n const pinned = memory.pinned ? 1.0 : 0.0;\n\n return (\n cosine_sim * 0.4 +\n typeWeight * 0.25 +\n accessCountNorm * 0.2 +\n recencyNorm * 0.1 +\n pinned * 0.05\n );\n }\n}\n","import type { DatabaseManager } from \"../db/manager.js\";\nimport { rowToMemory } from \"../db/row-types.js\";\nimport { MEMORY_TYPE_VALUES, MemoryTypeSchema } from \"../schemas.js\";\nimport type { MemoryRow, MemoryType, SessionContext } from \"../types.js\";\n\ninterface TypeCountRow {\n type: string;\n count: number;\n}\n\nexport function listMemoryTypes(): MemoryType[] {\n return [...MEMORY_TYPE_VALUES];\n}\n\nexport class SessionContextBuilder {\n readonly #db: DatabaseManager;\n\n constructor(db: DatabaseManager) {\n this.#db = db;\n }\n\n getSessionContext(projectHash: string, synthesis?: string): SessionContext {\n const typeCounts = this.#db.db\n .prepare<[], TypeCountRow>(\"SELECT type, COUNT(*) as count FROM memories GROUP BY type\")\n .all();\n\n const stats = Object.fromEntries(MEMORY_TYPE_VALUES.map((t) => [t, 0])) as Record<\n MemoryType,\n number\n >;\n for (const row of typeCounts) {\n const parsed = MemoryTypeSchema.safeParse(row.type);\n if (parsed.success) {\n stats[parsed.data] = row.count;\n }\n }\n\n if (synthesis !== undefined && synthesis.length > 0) {\n return { stats, pinnedGlobal: [], pinnedProject: [], synthesis };\n }\n\n const pinnedGlobal = this.#db.db\n .prepare<[], MemoryRow>(\n `SELECT * FROM memories\n WHERE id NOT IN (SELECT memory_id FROM memory_projects)\n AND pinned = 1`\n )\n .all()\n .map((row) => rowToMemory(row, []));\n\n const pinnedProject = this.#db.db\n .prepare<[string], MemoryRow>(\n `SELECT m.* FROM memories m\n JOIN memory_projects mp ON mp.memory_id = m.id\n JOIN projects p ON p.id = mp.project_id\n WHERE p.scope_hash = ? AND m.pinned = 1`\n )\n .all(projectHash)\n .map((row) => rowToMemory(row, []));\n\n return { stats, pinnedGlobal, pinnedProject };\n }\n}\n","import { createHash, randomUUID } from \"node:crypto\";\nimport type { DatabaseManager } from \"../db/manager.js\";\nimport type { Synthesis } from \"../schemas.js\";\nimport { SynthesisSchema } from \"../schemas.js\";\n\ninterface SynthesisRow {\n id: string;\n scope: string;\n content: string;\n source_memory_hash: string;\n synthesized_at: string;\n expires_at: string;\n in_flight_since: string | null;\n created_at: string;\n updated_at: string;\n}\n\nfunction rowToSynthesis(row: SynthesisRow): Synthesis {\n return SynthesisSchema.parse({\n id: row.id,\n scope: row.scope,\n content: row.content,\n sourceMemoryHash: row.source_memory_hash,\n synthesizedAt: row.synthesized_at,\n expiresAt: row.expires_at,\n inFlightSince: row.in_flight_since,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n });\n}\n\nconst STALENESS_DAYS = 30;\n\nexport class SynthesisRepository {\n readonly #db: DatabaseManager;\n\n constructor(db: DatabaseManager) {\n this.#db = db;\n }\n\n saveSynthesis(scope: string, content: string, sourceHash: string): Synthesis {\n const now = new Date().toISOString();\n const expiresAt = new Date(Date.now() + STALENESS_DAYS * 24 * 60 * 60 * 1000).toISOString();\n\n const existing = this.#db.db\n .prepare<[string], { id: string }>(\"SELECT id FROM syntheses WHERE scope = ?\")\n .get(scope);\n\n if (existing !== undefined) {\n this.#db.db\n .prepare(\n `UPDATE syntheses\n SET content = ?, source_memory_hash = ?, synthesized_at = ?, expires_at = ?,\n in_flight_since = NULL, updated_at = ?\n WHERE scope = ?`\n )\n .run(content, sourceHash, now, expiresAt, now, scope);\n } else {\n const id = randomUUID();\n this.#db.db\n .prepare(\n `INSERT INTO syntheses\n (id, scope, content, source_memory_hash, synthesized_at, expires_at,\n in_flight_since, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, NULL, ?, ?)`\n )\n .run(id, scope, content, sourceHash, now, expiresAt, now, now);\n }\n\n const row = this.#db.db\n .prepare<[string], SynthesisRow>(\"SELECT * FROM syntheses WHERE scope = ?\")\n .get(scope);\n\n if (row === undefined) throw new Error(`Failed to save synthesis for scope: ${scope}`);\n return rowToSynthesis(row);\n }\n\n getSynthesis(scope: string): Synthesis | undefined {\n const row = this.#db.db\n .prepare<[string], SynthesisRow>(\"SELECT * FROM syntheses WHERE scope = ?\")\n .get(scope);\n return row !== undefined ? rowToSynthesis(row) : undefined;\n }\n\n markInFlight(scope: string): void {\n const now = new Date().toISOString();\n const existing = this.#db.db\n .prepare<[string], { id: string }>(\"SELECT id FROM syntheses WHERE scope = ?\")\n .get(scope);\n\n if (existing !== undefined) {\n this.#db.db\n .prepare(\"UPDATE syntheses SET in_flight_since = ?, updated_at = ? WHERE scope = ?\")\n .run(now, now, scope);\n } else {\n // Create a placeholder row so in_flight_since is tracked before the first synthesis\n const id = randomUUID();\n const placeholder = \"pending\";\n const future = new Date(Date.now() + STALENESS_DAYS * 24 * 60 * 60 * 1000).toISOString();\n this.#db.db\n .prepare(\n `INSERT INTO syntheses\n (id, scope, content, source_memory_hash, synthesized_at, expires_at,\n in_flight_since, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`\n )\n .run(id, scope, placeholder, \"\", now, future, now, now, now);\n }\n }\n\n clearInFlight(scope: string): void {\n const now = new Date().toISOString();\n this.#db.db\n .prepare(\"UPDATE syntheses SET in_flight_since = NULL, updated_at = ? WHERE scope = ?\")\n .run(now, scope);\n }\n\n clearStaleInFlight(thresholdMs: number): void {\n const cutoff = new Date(Date.now() - thresholdMs).toISOString();\n const now = new Date().toISOString();\n this.#db.db\n .prepare(\n \"UPDATE syntheses SET in_flight_since = NULL, updated_at = ? WHERE in_flight_since IS NOT NULL AND in_flight_since < ?\"\n )\n .run(now, cutoff);\n }\n\n computeSourceMemoryHash(scope: string): string {\n let contents: { content: string }[];\n\n if (scope === \"global\") {\n contents = this.#db.db\n .prepare<[], { content: string }>(\n `SELECT content FROM memories\n WHERE id NOT IN (SELECT memory_id FROM memory_projects)\n ORDER BY id`\n )\n .all();\n } else {\n contents = this.#db.db\n .prepare<[string], { content: string }>(\n `SELECT m.content FROM memories m\n JOIN memory_projects mp ON mp.memory_id = m.id\n JOIN projects p ON p.id = mp.project_id\n WHERE p.scope_hash = ?\n ORDER BY m.id`\n )\n .all(scope);\n }\n\n return createHash(\"sha256\")\n .update(JSON.stringify(contents.map((r) => r.content)))\n .digest(\"hex\");\n }\n\n getExpiredOrDirtyScopes(): { scope: string; reason: \"expired\" | \"dirty\" | \"missing\" }[] {\n const allScopes = this.getAllActiveScopes();\n const now = new Date().toISOString();\n const results: { scope: string; reason: \"expired\" | \"dirty\" | \"missing\" }[] = [];\n\n for (const scope of allScopes) {\n const row = this.#db.db\n .prepare<[string], SynthesisRow>(\"SELECT * FROM syntheses WHERE scope = ?\")\n .get(scope);\n\n if (row === undefined || (row.content === \"pending\" && row.source_memory_hash === \"\")) {\n results.push({ scope, reason: \"missing\" });\n continue;\n }\n\n if (row.expires_at <= now) {\n results.push({ scope, reason: \"expired\" });\n continue;\n }\n\n const currentHash = this.computeSourceMemoryHash(scope);\n if (currentHash !== row.source_memory_hash) {\n results.push({ scope, reason: \"dirty\" });\n }\n }\n\n return results;\n }\n\n getAllActiveScopes(): string[] {\n const projectScopes = this.#db.db\n .prepare<[], { scope_hash: string }>(\"SELECT DISTINCT scope_hash FROM projects\")\n .all()\n .map((r) => r.scope_hash);\n\n return [\"global\", ...projectScopes];\n }\n\n expireStale(): void {\n const now = new Date().toISOString();\n this.#db.db.prepare(\"DELETE FROM syntheses WHERE expires_at < ?\").run(now);\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["MIGRATIONS","#db","#init","#initInMemory","#runMigrations","#db","#embedding","#projects","#getEventsForMemories","#db","#db","#embedding","#repo","#computeScore","#db","#db"],"sources":["../src/config/loader.ts","../src/db/errors.ts","../src/db/manager.ts","../src/schemas.ts","../src/db/row-types.ts","../src/embedding/service.ts","../src/memory/repository.ts","../src/scope/resolver.ts","../src/migrations/index.ts","../src/project/repository.ts","../src/query/engine.ts","../src/session/builder.ts","../src/synthesis/repository.ts"],"sourcesContent":["import { readFileSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { join } from \"node:path\";\n\ninterface MemoryConfig {\n synthesis?: { enabled?: boolean };\n}\n\nfunction loadConfig(): MemoryConfig | null {\n const configPath = join(homedir(), \".membank\", \"config.json\");\n try {\n const raw = readFileSync(configPath, \"utf8\");\n return JSON.parse(raw) as MemoryConfig;\n } catch {\n return null;\n }\n}\n\nexport function isSynthesisEnabled(): boolean {\n const config = loadConfig();\n return config?.synthesis?.enabled === true;\n}\n","export class MembankError extends Error {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"MembankError\";\n }\n}\n\nexport class DatabaseError extends MembankError {\n constructor(message: string, options?: ErrorOptions) {\n super(message, options);\n this.name = \"DatabaseError\";\n }\n}\n","import { mkdirSync } from \"node:fs\";\nimport { homedir } from \"node:os\";\nimport { dirname, join } from \"node:path\";\nimport BetterSqlite3 from \"better-sqlite3\";\nimport * as sqliteVec from \"sqlite-vec\";\nimport { DatabaseError } from \"./errors.js\";\n\nconst DEFAULT_DB_PATH = join(homedir(), \".membank\", \"memory.db\");\n\ntype VecLoader = (db: BetterSqlite3.Database) => void;\n\nconst MIGRATIONS: [number, string][] = [\n [\n 1,\n `\nCREATE TABLE IF NOT EXISTS memories (\n id TEXT PRIMARY KEY,\n content TEXT NOT NULL,\n type TEXT NOT NULL,\n tags TEXT NOT NULL DEFAULT '[]',\n scope TEXT NOT NULL,\n source TEXT,\n access_count INTEGER NOT NULL DEFAULT 0,\n pinned INTEGER NOT NULL DEFAULT 0,\n needs_review INTEGER NOT NULL DEFAULT 0,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n\nCREATE VIRTUAL TABLE IF NOT EXISTS embeddings USING vec0(\n embedding FLOAT[384]\n);\n`,\n ],\n [\n 2,\n `\nCREATE TABLE IF NOT EXISTS projects (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n scope_hash TEXT NOT NULL UNIQUE,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n\nCREATE TABLE IF NOT EXISTS memory_projects (\n memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n project_id TEXT NOT NULL REFERENCES projects(id) ON DELETE CASCADE,\n PRIMARY KEY (memory_id, project_id)\n);\n\nINSERT OR IGNORE INTO projects (id, name, scope_hash, created_at, updated_at)\nSELECT\n lower(hex(randomblob(16))),\n 'project-' || substr(scope, 1, 8),\n scope,\n datetime('now'),\n datetime('now')\nFROM memories\nWHERE scope != 'global'\nGROUP BY scope;\n\nINSERT OR IGNORE INTO memory_projects (memory_id, project_id)\nSELECT m.id, p.id\nFROM memories m\nJOIN projects p ON p.scope_hash = m.scope\nWHERE m.scope != 'global';\n\nALTER TABLE memories DROP COLUMN scope;\n`,\n ],\n [\n 3,\n `\nCREATE TABLE IF NOT EXISTS memory_review_events (\n id TEXT PRIMARY KEY,\n memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,\n conflicting_memory_id TEXT REFERENCES memories(id) ON DELETE SET NULL,\n similarity REAL NOT NULL,\n conflict_content_snapshot TEXT NOT NULL,\n reason TEXT NOT NULL,\n created_at TEXT NOT NULL,\n resolved_at TEXT\n);\n\nCREATE INDEX IF NOT EXISTS idx_review_events_memory_open\n ON memory_review_events(memory_id) WHERE resolved_at IS NULL;\n\nALTER TABLE memories DROP COLUMN needs_review;\n`,\n ],\n [\n 4,\n `\nCREATE TABLE IF NOT EXISTS syntheses (\n id TEXT PRIMARY KEY,\n scope TEXT NOT NULL,\n content TEXT NOT NULL,\n source_memory_hash TEXT NOT NULL,\n synthesized_at TEXT NOT NULL,\n expires_at TEXT NOT NULL,\n in_flight_since TEXT,\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL,\n UNIQUE(scope),\n CHECK(expires_at > synthesized_at)\n);\n\nCREATE INDEX IF NOT EXISTS idx_syntheses_expires_at\n ON syntheses(expires_at);\n\nCREATE INDEX IF NOT EXISTS idx_syntheses_scope_inflight\n ON syntheses(scope) WHERE in_flight_since IS NOT NULL;\n`,\n ],\n [\n 5,\n `\nPRAGMA foreign_keys = OFF;\n\nBEGIN;\n\n-- Rescue associations from corrupt projects by relinking them to a valid project with the same name\nINSERT OR IGNORE INTO memory_projects (memory_id, project_id)\nSELECT mp.memory_id, (\n SELECT p_good.id\n FROM projects p_good\n WHERE p_good.name = p_bad.name\n AND length(p_good.scope_hash) = 16\n AND trim(p_good.scope_hash, '0123456789abcdef') = ''\n ORDER BY p_good.created_at\n LIMIT 1\n)\nFROM memory_projects mp\nJOIN projects p_bad ON p_bad.id = mp.project_id\nWHERE (length(p_bad.scope_hash) != 16 OR trim(p_bad.scope_hash, '0123456789abcdef') != '')\n AND EXISTS (\n SELECT 1 FROM projects p_good\n WHERE p_good.name = p_bad.name\n AND length(p_good.scope_hash) = 16\n AND trim(p_good.scope_hash, '0123456789abcdef') = ''\n );\n\n-- Drop all associations to corrupt projects (memories with no valid counterpart become global)\nDELETE FROM memory_projects\nWHERE project_id IN (\n SELECT id FROM projects\n WHERE length(scope_hash) != 16 OR trim(scope_hash, '0123456789abcdef') != ''\n);\n\n-- Delete corrupt projects\nDELETE FROM projects\nWHERE length(scope_hash) != 16 OR trim(scope_hash, '0123456789abcdef') != '';\n\n-- Recreate projects table with CHECK constraint on scope_hash\n-- SQLite requires table recreation to add CHECK constraints\nDROP TABLE IF EXISTS projects_new;\n\nCREATE TABLE projects_new (\n id TEXT PRIMARY KEY,\n name TEXT NOT NULL,\n scope_hash TEXT NOT NULL UNIQUE\n CHECK(length(scope_hash) = 16 AND trim(scope_hash, '0123456789abcdef') = ''),\n created_at TEXT NOT NULL,\n updated_at TEXT NOT NULL\n);\n\nINSERT INTO projects_new SELECT * FROM projects;\n\nDROP TABLE projects;\nALTER TABLE projects_new RENAME TO projects;\n\nCOMMIT;\n\nPRAGMA foreign_keys = ON;\n`,\n ],\n];\n\nexport class DatabaseManager {\n readonly #db: BetterSqlite3.Database;\n\n private constructor(db: BetterSqlite3.Database) {\n this.#db = db;\n }\n\n static open(dbPath?: string): DatabaseManager {\n const resolvedPath = dbPath ?? DEFAULT_DB_PATH;\n mkdirSync(dirname(resolvedPath), { recursive: true });\n const db = new BetterSqlite3(resolvedPath);\n return DatabaseManager.#init(db, sqliteVec.load);\n }\n\n static openInMemory(): DatabaseManager {\n return DatabaseManager.#initInMemory(sqliteVec.load);\n }\n\n /** For testing: inject a custom vec loader (e.g. a throwing stub). */\n static _openInMemoryWithLoader(loader: VecLoader): DatabaseManager {\n return DatabaseManager.#initInMemory(loader);\n }\n\n static #initInMemory(loader: VecLoader): DatabaseManager {\n const db = new BetterSqlite3(\":memory:\");\n return DatabaseManager.#init(db, loader);\n }\n\n static #init(db: BetterSqlite3.Database, loader: VecLoader): DatabaseManager {\n try {\n loader(db);\n } catch (err) {\n throw new DatabaseError(\"Failed to load sqlite-vec extension\", {\n cause: err,\n });\n }\n\n db.pragma(\"journal_mode = WAL\");\n db.pragma(\"foreign_keys = ON\");\n\n const manager = new DatabaseManager(db);\n manager.#runMigrations();\n return manager;\n }\n\n #runMigrations(): void {\n // Bootstrap the meta table before reading schema_version from it\n this.#db.exec(`\n CREATE TABLE IF NOT EXISTS meta (\n key TEXT PRIMARY KEY,\n value TEXT NOT NULL\n );\n `);\n\n const row = this.#db\n .prepare<[], { value: string }>(\"SELECT value FROM meta WHERE key = 'schema_version'\")\n .get();\n\n const currentVersion = row ? Number.parseInt(row.value, 10) : 0;\n\n for (const [targetVersion, sql] of MIGRATIONS) {\n if (currentVersion < targetVersion) {\n this.#db.exec(sql);\n this.#db\n .prepare(\"INSERT OR REPLACE INTO meta (key, value) VALUES ('schema_version', ?)\")\n .run(String(targetVersion));\n }\n }\n }\n\n get db(): BetterSqlite3.Database {\n return this.#db;\n }\n\n close(): void {\n this.#db.close();\n }\n}\n","import { z } from \"zod\";\n\nexport const MEMORY_TYPE_VALUES = [\n \"correction\",\n \"preference\",\n \"decision\",\n \"learning\",\n \"fact\",\n] as const;\n\nexport const MemoryTypeSchema = z.enum(MEMORY_TYPE_VALUES);\nexport type MemoryType = z.infer<typeof MemoryTypeSchema>;\n\nexport const TagsJsonSchema = z.array(z.string());\n\nexport const ProjectSchema = z.object({\n id: z.string(),\n name: z.string(),\n scopeHash: z.string(),\n createdAt: z.string(),\n updatedAt: z.string(),\n});\nexport type Project = z.infer<typeof ProjectSchema>;\n\nexport const ReviewReasonSchema = z.enum([\"similarity_dedup\"]);\nexport type ReviewReason = z.infer<typeof ReviewReasonSchema>;\n\nexport const ReviewEventSchema = z.object({\n id: z.string(),\n memoryId: z.string(),\n conflictingMemoryId: z.string().nullable(),\n similarity: z.number(),\n conflictContentSnapshot: z.string(),\n reason: ReviewReasonSchema,\n createdAt: z.string(),\n resolvedAt: z.string().nullable(),\n});\nexport type ReviewEvent = z.infer<typeof ReviewEventSchema>;\n\nexport const ReviewEventRowSchema = z.object({\n id: z.string(),\n memory_id: z.string(),\n conflicting_memory_id: z.string().nullable(),\n similarity: z.number(),\n conflict_content_snapshot: z.string(),\n reason: ReviewReasonSchema,\n created_at: z.string(),\n resolved_at: z.string().nullable(),\n});\nexport type ReviewEventRow = z.infer<typeof ReviewEventRowSchema>;\n\nexport const MemorySchema = z.object({\n id: z.string(),\n content: z.string(),\n type: MemoryTypeSchema,\n tags: z.array(z.string()),\n projects: z.array(ProjectSchema),\n sourceHarness: z.string().nullable(),\n accessCount: z.number().int().nonnegative(),\n pinned: z.boolean(),\n reviewEvents: z.array(ReviewEventSchema),\n createdAt: z.string(),\n updatedAt: z.string(),\n});\nexport type Memory = z.infer<typeof MemorySchema>;\n\nexport const QueryOptionsSchema = z.object({\n query: z.string().min(1),\n type: MemoryTypeSchema.optional(),\n projectHash: z.string().optional(),\n limit: z.number().int().positive().optional(),\n includePinned: z.boolean().optional(),\n});\nexport type QueryOptions = z.infer<typeof QueryOptionsSchema>;\n\nexport const SaveOptionsSchema = z.object({\n content: z.string().min(1),\n type: MemoryTypeSchema,\n tags: z.array(z.string()).optional(),\n projectScope: z.object({ hash: z.string(), name: z.string() }).optional(),\n sourceHarness: z.string().optional(),\n});\nexport type SaveOptions = z.infer<typeof SaveOptionsSchema>;\n\nexport const MemoryPatchSchema = z.object({\n content: z.string().min(1).optional(),\n tags: z.array(z.string()).optional(),\n type: MemoryTypeSchema.optional(),\n});\nexport type MemoryPatch = z.infer<typeof MemoryPatchSchema>;\n\nexport const SynthesisSchema = z.object({\n id: z.string(),\n scope: z.string(),\n content: z.string(),\n sourceMemoryHash: z.string(),\n synthesizedAt: z.string(),\n expiresAt: z.string(),\n inFlightSince: z.string().nullable(),\n createdAt: z.string(),\n updatedAt: z.string(),\n});\nexport type Synthesis = z.infer<typeof SynthesisSchema>;\n\nexport const SessionContextSchema = z.object({\n stats: z.record(MemoryTypeSchema, z.number()),\n pinnedGlobal: z.array(MemorySchema),\n pinnedProject: z.array(MemorySchema),\n synthesis: z.string().optional(),\n});\nexport type SessionContext = z.infer<typeof SessionContextSchema>;\n\nexport const MemoryRowSchema = z.object({\n id: z.string(),\n content: z.string(),\n type: z.string(),\n tags: z.string(),\n source: z.string().nullable(),\n access_count: z.number(),\n pinned: z.number(),\n created_at: z.string(),\n updated_at: z.string(),\n});\nexport type MemoryRow = z.infer<typeof MemoryRowSchema>;\n\nexport const ProjectRowSchema = z.object({\n id: z.string(),\n name: z.string(),\n scope_hash: z.string(),\n created_at: z.string(),\n updated_at: z.string(),\n});\nexport type ProjectRow = z.infer<typeof ProjectRowSchema>;\n","import { MemoryTypeSchema, ReviewEventRowSchema, TagsJsonSchema } from \"../schemas.js\";\nimport type {\n Memory,\n MemoryRow,\n Project,\n ProjectRow,\n ReviewEvent,\n ReviewEventRow,\n} from \"../types.js\";\n\nexport function rowToMemory(\n row: MemoryRow,\n projects: Project[],\n reviewEvents: ReviewEvent[] = []\n): Memory {\n return {\n id: row.id,\n content: row.content,\n type: MemoryTypeSchema.parse(row.type),\n tags: TagsJsonSchema.parse(JSON.parse(row.tags)),\n projects,\n sourceHarness: row.source,\n accessCount: row.access_count,\n pinned: row.pinned !== 0,\n reviewEvents,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n\nexport function rowToReviewEvent(row: ReviewEventRow): ReviewEvent {\n const parsed = ReviewEventRowSchema.parse(row);\n return {\n id: parsed.id,\n memoryId: parsed.memory_id,\n conflictingMemoryId: parsed.conflicting_memory_id,\n similarity: parsed.similarity,\n conflictContentSnapshot: parsed.conflict_content_snapshot,\n reason: parsed.reason,\n createdAt: parsed.created_at,\n resolvedAt: parsed.resolved_at,\n };\n}\n\nexport function rowToProject(row: ProjectRow): Project {\n return {\n id: row.id,\n name: row.name,\n scopeHash: row.scope_hash,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n };\n}\n","import { homedir } from \"node:os\";\nimport { join } from \"node:path\";\nimport { pipeline } from \"@huggingface/transformers\";\n\nexport type ProgressCallback = (progress: { status: string; progress?: number }) => void;\n\nexport class EmbeddingService {\n private readonly modelCachePath: string;\n private readonly onProgress: ProgressCallback | undefined;\n private pipelineInstance: Awaited<ReturnType<typeof pipeline>> | null = null;\n\n constructor(modelCachePath?: string, onProgress?: ProgressCallback) {\n this.modelCachePath = modelCachePath ?? join(homedir(), \".membank\", \"models\");\n this.onProgress = onProgress;\n }\n\n private async getPipeline(): Promise<Awaited<ReturnType<typeof pipeline>>> {\n if (this.pipelineInstance === null) {\n this.pipelineInstance = await pipeline(\"feature-extraction\", \"Xenova/bge-small-en-v1.5\", {\n cache_dir: this.modelCachePath,\n progress_callback: this.onProgress,\n });\n }\n return this.pipelineInstance;\n }\n\n async embed(text: string): Promise<Float32Array> {\n const pipe = await this.getPipeline();\n // Shape: [1, seq_len, 384]. Cast to any to bypass the non-unified pipeline union signature.\n // eslint-disable-next-line @typescript-eslint/no-explicit-any\n const output = await (\n pipe as (input: string, opts: Record<string, unknown>) => Promise<unknown>\n )(text, { pooling: \"mean\", normalize: true });\n\n // @huggingface/transformers Tensor has a .data property with the flat array\n const tensor = output as { data: Float32Array | number[] };\n const flat = tensor.data;\n\n return flat instanceof Float32Array ? flat : new Float32Array(flat);\n }\n}\n","import { randomUUID } from \"node:crypto\";\nimport type { DatabaseManager } from \"../db/manager.js\";\nimport { rowToMemory, rowToReviewEvent } from \"../db/row-types.js\";\nimport type { EmbeddingService } from \"../embedding/service.js\";\nimport type { ProjectRepository } from \"../project/repository.js\";\nimport {\n MEMORY_TYPE_VALUES,\n MemoryPatchSchema,\n MemoryRowSchema,\n MemoryTypeSchema,\n ReviewEventRowSchema,\n SaveOptionsSchema,\n} from \"../schemas.js\";\nimport type {\n Memory,\n MemoryPatch,\n MemoryRow,\n MemoryType,\n ReviewEvent,\n ReviewEventRow,\n SaveOptions,\n} from \"../types.js\";\n\nexport const PIN_BUDGET_THRESHOLD = 8000;\n\ninterface SimilarityRow extends MemoryRow {\n rowid: number;\n similarity: number;\n}\n\nexport class MemoryRepository {\n readonly #db: DatabaseManager;\n readonly #embedding: EmbeddingService;\n readonly #projects: ProjectRepository;\n\n constructor(\n db: DatabaseManager,\n embeddingService: EmbeddingService,\n projects: ProjectRepository\n ) {\n this.#db = db;\n this.#embedding = embeddingService;\n this.#projects = projects;\n }\n\n async save(options: SaveOptions): Promise<Memory> {\n const {\n content,\n type,\n tags = [],\n projectScope,\n sourceHarness,\n } = SaveOptionsSchema.parse(options);\n\n const embedding = await this.#embedding.embed(content);\n const embeddingBlob = Buffer.from(embedding.buffer);\n\n // Dedup: find similar memory in same context\n let top: SimilarityRow | undefined;\n if (projectScope !== undefined) {\n top = this.#db.db\n .prepare<[Buffer, string, string], SimilarityRow>(\n `SELECT m.rowid, m.*, (1 - vec_distance_cosine(e.embedding, ?)) AS similarity\n FROM memories m JOIN embeddings e ON e.rowid = m.rowid\n JOIN memory_projects mp ON mp.memory_id = m.id\n JOIN projects p ON p.id = mp.project_id\n WHERE m.type = ? AND p.scope_hash = ?\n ORDER BY similarity DESC LIMIT 1`\n )\n .get(embeddingBlob, type, projectScope.hash);\n } else {\n top = this.#db.db\n .prepare<[Buffer, string], SimilarityRow>(\n `SELECT m.rowid, m.*, (1 - vec_distance_cosine(e.embedding, ?)) AS similarity\n FROM memories m JOIN embeddings e ON e.rowid = m.rowid\n WHERE m.type = ?\n AND m.id NOT IN (SELECT memory_id FROM memory_projects)\n ORDER BY similarity DESC LIMIT 1`\n )\n .get(embeddingBlob, type);\n }\n\n const now = new Date().toISOString();\n\n if (top !== undefined && top.similarity > 0.92) {\n this.#db.db\n .prepare(`UPDATE memories SET content = ?, updated_at = ? WHERE id = ?`)\n .run(content, now, top.id);\n this.#db.db\n .prepare(`UPDATE embeddings SET embedding = ? WHERE rowid = ?`)\n .run(embeddingBlob, top.rowid);\n\n const updated = MemoryRowSchema.parse(\n this.#db.db.prepare<[string], unknown>(`SELECT * FROM memories WHERE id = ?`).get(top.id)\n );\n\n const projectMap = this.#projects.getProjectsForMemories([top.id]);\n const events = this.#getEventsForMemories([top.id]);\n return rowToMemory(updated, projectMap.get(top.id) ?? [], events.get(top.id) ?? []);\n }\n\n const id = randomUUID();\n\n this.#db.db\n .prepare(\n `INSERT INTO memories (id, content, type, tags, source, access_count, pinned, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, 0, 0, ?, ?)`\n )\n .run(id, content, type, JSON.stringify(tags), sourceHarness ?? null, now, now);\n\n if (top !== undefined && top.similarity >= 0.75) {\n this.#db.db\n .prepare(\n `INSERT INTO memory_review_events\n (id, memory_id, conflicting_memory_id, similarity, conflict_content_snapshot, reason, created_at)\n VALUES (?, ?, ?, ?, ?, 'similarity_dedup', ?)`\n )\n .run(randomUUID(), top.id, id, top.similarity, content, now);\n }\n\n this.#db.db\n .prepare(\n `INSERT INTO embeddings (rowid, embedding) SELECT m.rowid, ? FROM memories m WHERE m.id = ?`\n )\n .run(embeddingBlob, id);\n\n if (projectScope !== undefined) {\n const project = this.#projects.upsertByHash(projectScope.hash, projectScope.name);\n this.#projects.addAssociation(id, project.id);\n }\n\n const row = MemoryRowSchema.parse(\n this.#db.db.prepare<[string], unknown>(`SELECT * FROM memories WHERE id = ?`).get(id)\n );\n\n const projectMap = this.#projects.getProjectsForMemories([id]);\n return rowToMemory(row, projectMap.get(id) ?? [], []);\n }\n\n async update(id: string, patch: MemoryPatch): Promise<Memory> {\n const { content, tags, type } = MemoryPatchSchema.parse(patch);\n\n const existing = this.#db.db\n .prepare<[string], MemoryRow & { rowid: number }>(\n `SELECT m.rowid, m.* FROM memories m WHERE m.id = ?`\n )\n .get(id);\n\n if (existing === undefined) {\n throw new Error(`Memory not found: ${id}`);\n }\n\n const now = new Date().toISOString();\n const sets: string[] = [\"updated_at = ?\"];\n const values: string[] = [now];\n\n if (content !== undefined) {\n sets.push(\"content = ?\");\n values.push(content);\n }\n\n if (tags !== undefined) {\n sets.push(\"tags = ?\");\n values.push(JSON.stringify(tags));\n }\n\n if (type !== undefined) {\n sets.push(\"type = ?\");\n values.push(type);\n }\n\n values.push(id);\n this.#db.db.prepare(`UPDATE memories SET ${sets.join(\", \")} WHERE id = ?`).run(...values);\n\n if (content !== undefined) {\n const embedding = await this.#embedding.embed(content);\n const embeddingBlob = Buffer.from(embedding.buffer);\n this.#db.db\n .prepare(`UPDATE embeddings SET embedding = ? WHERE rowid = ?`)\n .run(embeddingBlob, existing.rowid);\n }\n\n const updated = MemoryRowSchema.parse(\n this.#db.db.prepare<[string], unknown>(`SELECT * FROM memories WHERE id = ?`).get(id)\n );\n\n const projectMap = this.#projects.getProjectsForMemories([id]);\n const events = this.#getEventsForMemories([id]);\n return rowToMemory(updated, projectMap.get(id) ?? [], events.get(id) ?? []);\n }\n\n delete(id: string): Promise<void> {\n const row = this.#db.db\n .prepare<[string], { rowid: number }>(`SELECT rowid FROM memories WHERE id = ?`)\n .get(id);\n\n if (row !== undefined) {\n this.#db.db.prepare(`DELETE FROM embeddings WHERE rowid = ?`).run(row.rowid);\n }\n\n this.#db.db.prepare(`DELETE FROM memory_projects WHERE memory_id = ?`).run(id);\n this.#db.db.prepare(`DELETE FROM memories WHERE id = ?`).run(id);\n\n return Promise.resolve();\n }\n\n list(opts?: { type?: MemoryType; pinned?: boolean }): Memory[] {\n const conditions: string[] = [];\n const params: (string | number)[] = [];\n\n if (opts?.type !== undefined) {\n conditions.push(\"type = ?\");\n params.push(opts.type);\n }\n\n if (opts?.pinned === true) {\n conditions.push(\"pinned = 1\");\n }\n\n const where = conditions.length > 0 ? `WHERE ${conditions.join(\" AND \")}` : \"\";\n const rows = this.#db.db\n .prepare<(string | number)[], MemoryRow>(\n `SELECT * FROM memories ${where} ORDER BY created_at DESC`\n )\n .all(...params);\n\n if (rows.length === 0) return [];\n\n const ids = rows.map((r) => r.id);\n const projectMap = this.#projects.getProjectsForMemories(ids);\n const eventMap = this.#getEventsForMemories(ids);\n return rows.map((row) =>\n rowToMemory(row, projectMap.get(row.id) ?? [], eventMap.get(row.id) ?? [])\n );\n }\n\n listFlagged(): Memory[] {\n const rows = this.#db.db\n .prepare<[], MemoryRow>(\n `SELECT * FROM memories\n WHERE EXISTS (\n SELECT 1 FROM memory_review_events e\n WHERE e.memory_id = memories.id AND e.resolved_at IS NULL\n )\n ORDER BY created_at DESC`\n )\n .all();\n\n if (rows.length === 0) return [];\n\n const ids = rows.map((r) => r.id);\n const projectMap = this.#projects.getProjectsForMemories(ids);\n const eventMap = this.#getEventsForMemories(ids, { unresolvedOnly: true });\n return rows.map((row) =>\n rowToMemory(row, projectMap.get(row.id) ?? [], eventMap.get(row.id) ?? [])\n );\n }\n\n listReviewEvents(memoryId: string, opts?: { unresolvedOnly?: boolean }): ReviewEvent[] {\n const where =\n opts?.unresolvedOnly === true\n ? \"WHERE memory_id = ? AND resolved_at IS NULL\"\n : \"WHERE memory_id = ?\";\n\n const rows = this.#db.db\n .prepare<[string], ReviewEventRow>(\n `SELECT * FROM memory_review_events ${where} ORDER BY created_at DESC`\n )\n .all(memoryId);\n\n return rows.map((r) => rowToReviewEvent(ReviewEventRowSchema.parse(r)));\n }\n\n resolveReviewEvents(memoryId: string): void {\n const now = new Date().toISOString();\n this.#db.db\n .prepare(\n `UPDATE memory_review_events SET resolved_at = ? WHERE memory_id = ? AND resolved_at IS NULL`\n )\n .run(now, memoryId);\n }\n\n #getEventsForMemories(\n ids: string[],\n opts?: { unresolvedOnly?: boolean }\n ): Map<string, ReviewEvent[]> {\n if (ids.length === 0) return new Map();\n\n const placeholders = ids.map(() => \"?\").join(\", \");\n const unresolvedClause = opts?.unresolvedOnly === true ? \"AND resolved_at IS NULL\" : \"\";\n const rows = this.#db.db\n .prepare<string[], ReviewEventRow>(\n `SELECT * FROM memory_review_events\n WHERE memory_id IN (${placeholders}) ${unresolvedClause}\n ORDER BY created_at DESC`\n )\n .all(...ids);\n\n const map = new Map<string, ReviewEvent[]>();\n for (const row of rows) {\n const event = rowToReviewEvent(ReviewEventRowSchema.parse(row));\n const existing = map.get(event.memoryId) ?? [];\n existing.push(event);\n map.set(event.memoryId, existing);\n }\n return map;\n }\n\n getPinnedCharCount(): number {\n const row = this.#db.db\n .prepare<[], { total: number }>(\n `SELECT COALESCE(SUM(LENGTH(content)), 0) as total FROM memories WHERE pinned = 1`\n )\n .get() ?? { total: 0 };\n return row.total;\n }\n\n stats(): {\n byType: Record<MemoryType, number>;\n total: number;\n pinned: number;\n needsReview: number;\n pinBudgetChars: number;\n } {\n const byType = Object.fromEntries(MEMORY_TYPE_VALUES.map((t) => [t, 0])) as Record<\n MemoryType,\n number\n >;\n\n const typeRows = this.#db.db\n .prepare<[], { type: string; count: number }>(\n `SELECT type, COUNT(*) as count FROM memories GROUP BY type`\n )\n .all();\n\n for (const row of typeRows) {\n const parsed = MemoryTypeSchema.safeParse(row.type);\n if (parsed.success) {\n byType[parsed.data] = row.count;\n }\n }\n\n const aggregates = this.#db.db\n .prepare<[], { total: number; pinned: number | null }>(\n `SELECT COUNT(*) as total, SUM(pinned) as pinned FROM memories`\n )\n .get() ?? { total: 0, pinned: 0 };\n\n const reviewRow = this.#db.db\n .prepare<[], { needsReview: number }>(\n `SELECT COUNT(DISTINCT memory_id) as needsReview FROM memory_review_events WHERE resolved_at IS NULL`\n )\n .get() ?? { needsReview: 0 };\n\n return {\n byType,\n total: aggregates.total,\n pinned: aggregates.pinned ?? 0,\n needsReview: reviewRow.needsReview,\n pinBudgetChars: this.getPinnedCharCount(),\n };\n }\n\n setPin(id: string, pinned: boolean): Memory {\n const existing = this.#db.db\n .prepare<[string], MemoryRow>(`SELECT * FROM memories WHERE id = ?`)\n .get(id);\n\n if (existing === undefined) {\n throw new Error(`Memory not found: ${id}`);\n }\n\n const now = new Date().toISOString();\n this.#db.db\n .prepare(`UPDATE memories SET pinned = ?, updated_at = ? WHERE id = ?`)\n .run(pinned ? 1 : 0, now, id);\n\n const updated = MemoryRowSchema.parse(\n this.#db.db.prepare<[string], unknown>(`SELECT * FROM memories WHERE id = ?`).get(id)\n );\n\n const projectMap = this.#projects.getProjectsForMemories([id]);\n const events = this.#getEventsForMemories([id]);\n return rowToMemory(updated, projectMap.get(id) ?? [], events.get(id) ?? []);\n }\n\n incrementAccessCount(id: string): void {\n this.#db.db.prepare(`UPDATE memories SET access_count = access_count + 1 WHERE id = ?`).run(id);\n }\n}\n","import { execFile } from \"node:child_process\";\nimport { createHash } from \"node:crypto\";\nimport { promisify } from \"node:util\";\n\nconst execFileAsync = promisify(execFile);\n\nfunction sha256Truncated(input: string): string {\n return createHash(\"sha256\").update(input).digest(\"hex\").slice(0, 16);\n}\n\nexport async function resolveProject(): Promise<{ hash: string; name: string }> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"remote\", \"get-url\", \"origin\"]);\n const url = stdout.trim();\n if (url) {\n const hash = sha256Truncated(url);\n // parse last path segment, strip .git suffix\n const name =\n url\n .split(\"/\")\n .pop()\n ?.replace(/\\.git$/, \"\") ?? hash.slice(0, 8);\n return { hash, name };\n }\n } catch {\n // fall through\n }\n\n const cwd = process.cwd();\n const hash = sha256Truncated(cwd);\n const name = cwd.split(/[/\\\\]/).filter(Boolean).pop() ?? hash.slice(0, 8);\n return { hash, name };\n}\n\nexport async function resolveScope(): Promise<string> {\n try {\n const { stdout } = await execFileAsync(\"git\", [\"remote\", \"get-url\", \"origin\"]);\n const url = stdout.trim();\n if (url) {\n return sha256Truncated(url);\n }\n } catch {\n // git not available, not a repo, or no remote — fall through to cwd fallback\n }\n\n return sha256Truncated(process.cwd());\n}\n","import type { ProjectRepository } from \"../project/index.js\";\nimport { resolveProject } from \"../scope/index.js\";\n\nexport interface MigrationMeta {\n name: string;\n description: string;\n}\n\nexport interface ScopeToProjectsResult {\n migration: \"scope-to-projects\";\n oldName: string;\n newName: string;\n memoryCount: number;\n}\n\nexport const MIGRATIONS: MigrationMeta[] = [\n {\n name: \"scope-to-projects\",\n description:\n \"Rename the auto-migrated project for the current directory from its generic hash-derived name to the resolved repo/directory name.\",\n },\n];\n\nexport async function runScopeToProjectsMigration(\n projects: ProjectRepository\n): Promise<ScopeToProjectsResult | null> {\n const resolved = await resolveProject();\n const project = projects.getByHash(resolved.hash);\n\n if (project === undefined) {\n return null;\n }\n\n const oldName = project.name;\n const memoryCount = projects.countMemories(project.id);\n projects.rename(project.id, resolved.name);\n\n return {\n migration: \"scope-to-projects\",\n oldName,\n newName: resolved.name,\n memoryCount,\n };\n}\n","import { randomUUID } from \"node:crypto\";\nimport type { DatabaseManager } from \"../db/manager.js\";\nimport { rowToProject } from \"../db/row-types.js\";\nimport { ProjectRowSchema } from \"../schemas.js\";\nimport type { Project, ProjectRow } from \"../types.js\";\n\ninterface ProjectMemoryRow extends ProjectRow {\n memory_id: string;\n}\n\nexport class ProjectRepository {\n readonly #db: DatabaseManager;\n\n constructor(db: DatabaseManager) {\n this.#db = db;\n }\n\n upsertByHash(hash: string, name: string): Project {\n if (!/^[0-9a-f]{16}$/.test(hash)) {\n throw new Error(`Invalid scope hash \"${hash}\": expected 16 lowercase hex characters`);\n }\n const now = new Date().toISOString();\n const id = randomUUID();\n this.#db.db\n .prepare(\n `INSERT OR IGNORE INTO projects (id, name, scope_hash, created_at, updated_at) VALUES (?, ?, ?, ?, ?)`\n )\n .run(id, name, hash, now, now);\n\n const row = ProjectRowSchema.parse(\n this.#db.db\n .prepare<[string], unknown>(`SELECT * FROM projects WHERE scope_hash = ?`)\n .get(hash)\n );\n\n return rowToProject(row);\n }\n\n rename(id: string, name: string): Project {\n const now = new Date().toISOString();\n this.#db.db\n .prepare(`UPDATE projects SET name = ?, updated_at = ? WHERE id = ?`)\n .run(name, now, id);\n\n const row = this.#db.db\n .prepare<[string], ProjectRow>(`SELECT * FROM projects WHERE id = ?`)\n .get(id);\n\n if (row === undefined) throw new Error(`Project not found: ${id}`);\n return rowToProject(row);\n }\n\n list(): Project[] {\n return this.#db.db\n .prepare<[], ProjectRow>(`SELECT * FROM projects ORDER BY name ASC`)\n .all()\n .map(rowToProject);\n }\n\n getByHash(hash: string): Project | undefined {\n const row = this.#db.db\n .prepare<[string], ProjectRow>(`SELECT * FROM projects WHERE scope_hash = ?`)\n .get(hash);\n return row !== undefined ? rowToProject(row) : undefined;\n }\n\n getByName(name: string): Project | undefined {\n const row = this.#db.db\n .prepare<[string], ProjectRow>(`SELECT * FROM projects WHERE name = ? LIMIT 1`)\n .get(name);\n return row !== undefined ? rowToProject(row) : undefined;\n }\n\n addAssociation(memoryId: string, projectId: string): void {\n this.#db.db\n .prepare(`INSERT OR IGNORE INTO memory_projects (memory_id, project_id) VALUES (?, ?)`)\n .run(memoryId, projectId);\n }\n\n removeAssociation(memoryId: string, projectId: string): void {\n this.#db.db\n .prepare(`DELETE FROM memory_projects WHERE memory_id = ? AND project_id = ?`)\n .run(memoryId, projectId);\n }\n\n countMemories(projectId: string): number {\n const row = this.#db.db\n .prepare<[string], { count: number }>(\n `SELECT COUNT(*) AS count FROM memory_projects WHERE project_id = ?`\n )\n .get(projectId);\n return row?.count ?? 0;\n }\n\n getProjectsForMemories(memoryIds: string[]): Map<string, Project[]> {\n if (memoryIds.length === 0) return new Map();\n const placeholders = memoryIds.map(() => \"?\").join(\",\");\n const rows = this.#db.db\n .prepare<string[], ProjectMemoryRow>(\n `SELECT p.*, mp.memory_id FROM projects p\n JOIN memory_projects mp ON mp.project_id = p.id\n WHERE mp.memory_id IN (${placeholders})`\n )\n .all(...memoryIds);\n\n const result = new Map<string, Project[]>();\n for (const row of rows) {\n const list = result.get(row.memory_id) ?? [];\n list.push(rowToProject(row));\n result.set(row.memory_id, list);\n }\n return result;\n }\n}\n","import type { DatabaseManager } from \"../db/manager.js\";\nimport { rowToMemory } from \"../db/row-types.js\";\nimport type { EmbeddingService } from \"../embedding/service.js\";\nimport type { MemoryRepository } from \"../memory/repository.js\";\nimport { QueryOptionsSchema } from \"../schemas.js\";\nimport type { Memory, MemoryRow, MemoryType, QueryOptions } from \"../types.js\";\n\ninterface QueryMemoryRow extends MemoryRow {\n cosine_sim: number;\n}\n\nconst TYPE_WEIGHTS = {\n correction: 1.0,\n preference: 0.8,\n decision: 0.6,\n learning: 0.4,\n fact: 0.2,\n} satisfies Record<MemoryType, number>;\n\nexport class QueryEngine {\n readonly #db: DatabaseManager;\n readonly #embedding: EmbeddingService;\n readonly #repo: MemoryRepository;\n\n constructor(db: DatabaseManager, embeddingService: EmbeddingService, repo: MemoryRepository) {\n this.#db = db;\n this.#embedding = embeddingService;\n this.#repo = repo;\n }\n\n async query(options: QueryOptions): Promise<Array<Memory & { score: number }>> {\n const {\n query,\n type,\n projectHash,\n limit = 10,\n includePinned,\n } = QueryOptionsSchema.parse(options);\n\n const queryEmbedding = await this.#embedding.embed(query);\n const queryBlob = Buffer.from(queryEmbedding.buffer);\n\n const whereClauses: string[] = [];\n const params: unknown[] = [queryBlob];\n let joinClause = \"\";\n\n if (!includePinned) {\n whereClauses.push(\"m.pinned = 0\");\n }\n\n if (type !== undefined) {\n whereClauses.push(\"m.type = ?\");\n params.push(type);\n }\n\n if (projectHash !== undefined) {\n joinClause =\n \"LEFT JOIN memory_projects mp ON mp.memory_id = m.id LEFT JOIN projects p ON p.id = mp.project_id\";\n whereClauses.push(\"p.scope_hash = ?\");\n params.push(projectHash);\n }\n\n const whereSQL = whereClauses.length > 0 ? `WHERE ${whereClauses.join(\" AND \")}` : \"\";\n\n const sql = `\n SELECT m.*, (1 - vec_distance_cosine(e.embedding, ?)) AS cosine_sim\n FROM memories m JOIN embeddings e ON e.rowid = m.rowid\n ${joinClause}\n ${whereSQL}\n `;\n\n const rows = this.#db.db.prepare<unknown[], QueryMemoryRow>(sql).all(...params);\n\n const now = Date.now();\n\n const scored = rows\n .filter((row) => row.cosine_sim > 0)\n .map((row) => {\n const memory = rowToMemory(row, []);\n const score = this.#computeScore(memory, row.cosine_sim, now);\n return { ...memory, score };\n });\n\n scored.sort((a, b) => b.score - a.score);\n\n const results = scored.slice(0, limit);\n\n for (const result of results) {\n this.#repo.incrementAccessCount(result.id);\n }\n\n return results;\n }\n\n #computeScore(memory: Memory, cosine_sim: number, now: number): number {\n const typeWeight = TYPE_WEIGHTS[memory.type];\n const accessCountNorm = memory.accessCount / (memory.accessCount + 10);\n const daysSinceUpdate = (now - new Date(memory.updatedAt).getTime()) / 86400000;\n const recencyNorm = 1 / (1 + daysSinceUpdate);\n const pinned = memory.pinned ? 1.0 : 0.0;\n\n return (\n cosine_sim * 0.4 +\n typeWeight * 0.25 +\n accessCountNorm * 0.2 +\n recencyNorm * 0.1 +\n pinned * 0.05\n );\n }\n}\n","import type { DatabaseManager } from \"../db/manager.js\";\nimport { rowToMemory } from \"../db/row-types.js\";\nimport { MEMORY_TYPE_VALUES, MemoryTypeSchema } from \"../schemas.js\";\nimport type { MemoryRow, MemoryType, SessionContext } from \"../types.js\";\n\ninterface TypeCountRow {\n type: string;\n count: number;\n}\n\nexport function listMemoryTypes(): MemoryType[] {\n return [...MEMORY_TYPE_VALUES];\n}\n\nexport class SessionContextBuilder {\n readonly #db: DatabaseManager;\n\n constructor(db: DatabaseManager) {\n this.#db = db;\n }\n\n getSessionContext(projectHash: string, synthesis?: string): SessionContext {\n const typeCounts = this.#db.db\n .prepare<[], TypeCountRow>(\"SELECT type, COUNT(*) as count FROM memories GROUP BY type\")\n .all();\n\n const stats = Object.fromEntries(MEMORY_TYPE_VALUES.map((t) => [t, 0])) as Record<\n MemoryType,\n number\n >;\n for (const row of typeCounts) {\n const parsed = MemoryTypeSchema.safeParse(row.type);\n if (parsed.success) {\n stats[parsed.data] = row.count;\n }\n }\n\n if (synthesis !== undefined && synthesis.length > 0) {\n return { stats, pinnedGlobal: [], pinnedProject: [], synthesis };\n }\n\n const pinnedGlobal = this.#db.db\n .prepare<[], MemoryRow>(\n `SELECT * FROM memories\n WHERE id NOT IN (SELECT memory_id FROM memory_projects)\n AND pinned = 1`\n )\n .all()\n .map((row) => rowToMemory(row, []));\n\n const pinnedProject = this.#db.db\n .prepare<[string], MemoryRow>(\n `SELECT m.* FROM memories m\n JOIN memory_projects mp ON mp.memory_id = m.id\n JOIN projects p ON p.id = mp.project_id\n WHERE p.scope_hash = ? AND m.pinned = 1`\n )\n .all(projectHash)\n .map((row) => rowToMemory(row, []));\n\n return { stats, pinnedGlobal, pinnedProject };\n }\n}\n","import { createHash, randomUUID } from \"node:crypto\";\nimport type { DatabaseManager } from \"../db/manager.js\";\nimport type { Synthesis } from \"../schemas.js\";\nimport { SynthesisSchema } from \"../schemas.js\";\n\ninterface SynthesisRow {\n id: string;\n scope: string;\n content: string;\n source_memory_hash: string;\n synthesized_at: string;\n expires_at: string;\n in_flight_since: string | null;\n created_at: string;\n updated_at: string;\n}\n\nfunction rowToSynthesis(row: SynthesisRow): Synthesis {\n return SynthesisSchema.parse({\n id: row.id,\n scope: row.scope,\n content: row.content,\n sourceMemoryHash: row.source_memory_hash,\n synthesizedAt: row.synthesized_at,\n expiresAt: row.expires_at,\n inFlightSince: row.in_flight_since,\n createdAt: row.created_at,\n updatedAt: row.updated_at,\n });\n}\n\nconst STALENESS_DAYS = 30;\n\nexport class SynthesisRepository {\n readonly #db: DatabaseManager;\n\n constructor(db: DatabaseManager) {\n this.#db = db;\n }\n\n saveSynthesis(scope: string, content: string, sourceHash: string): Synthesis {\n const now = new Date().toISOString();\n const expiresAt = new Date(Date.now() + STALENESS_DAYS * 24 * 60 * 60 * 1000).toISOString();\n\n const existing = this.#db.db\n .prepare<[string], { id: string }>(\"SELECT id FROM syntheses WHERE scope = ?\")\n .get(scope);\n\n if (existing !== undefined) {\n this.#db.db\n .prepare(\n `UPDATE syntheses\n SET content = ?, source_memory_hash = ?, synthesized_at = ?, expires_at = ?,\n in_flight_since = NULL, updated_at = ?\n WHERE scope = ?`\n )\n .run(content, sourceHash, now, expiresAt, now, scope);\n } else {\n const id = randomUUID();\n this.#db.db\n .prepare(\n `INSERT INTO syntheses\n (id, scope, content, source_memory_hash, synthesized_at, expires_at,\n in_flight_since, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, NULL, ?, ?)`\n )\n .run(id, scope, content, sourceHash, now, expiresAt, now, now);\n }\n\n const row = this.#db.db\n .prepare<[string], SynthesisRow>(\"SELECT * FROM syntheses WHERE scope = ?\")\n .get(scope);\n\n if (row === undefined) throw new Error(`Failed to save synthesis for scope: ${scope}`);\n return rowToSynthesis(row);\n }\n\n getSynthesis(scope: string): Synthesis | undefined {\n const row = this.#db.db\n .prepare<[string], SynthesisRow>(\"SELECT * FROM syntheses WHERE scope = ?\")\n .get(scope);\n return row !== undefined ? rowToSynthesis(row) : undefined;\n }\n\n markInFlight(scope: string): void {\n const now = new Date().toISOString();\n const existing = this.#db.db\n .prepare<[string], { id: string }>(\"SELECT id FROM syntheses WHERE scope = ?\")\n .get(scope);\n\n if (existing !== undefined) {\n this.#db.db\n .prepare(\"UPDATE syntheses SET in_flight_since = ?, updated_at = ? WHERE scope = ?\")\n .run(now, now, scope);\n } else {\n // Create a placeholder row so in_flight_since is tracked before the first synthesis\n const id = randomUUID();\n const placeholder = \"pending\";\n const future = new Date(Date.now() + STALENESS_DAYS * 24 * 60 * 60 * 1000).toISOString();\n this.#db.db\n .prepare(\n `INSERT INTO syntheses\n (id, scope, content, source_memory_hash, synthesized_at, expires_at,\n in_flight_since, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`\n )\n .run(id, scope, placeholder, \"\", now, future, now, now, now);\n }\n }\n\n clearInFlight(scope: string): void {\n const now = new Date().toISOString();\n this.#db.db\n .prepare(\"UPDATE syntheses SET in_flight_since = NULL, updated_at = ? WHERE scope = ?\")\n .run(now, scope);\n }\n\n clearStaleInFlight(thresholdMs: number): void {\n const cutoff = new Date(Date.now() - thresholdMs).toISOString();\n const now = new Date().toISOString();\n this.#db.db\n .prepare(\n \"UPDATE syntheses SET in_flight_since = NULL, updated_at = ? WHERE in_flight_since IS NOT NULL AND in_flight_since < ?\"\n )\n .run(now, cutoff);\n }\n\n computeSourceMemoryHash(scope: string): string {\n let contents: { content: string }[];\n\n if (scope === \"global\") {\n contents = this.#db.db\n .prepare<[], { content: string }>(\n `SELECT content FROM memories\n WHERE id NOT IN (SELECT memory_id FROM memory_projects)\n ORDER BY id`\n )\n .all();\n } else {\n contents = this.#db.db\n .prepare<[string], { content: string }>(\n `SELECT m.content FROM memories m\n JOIN memory_projects mp ON mp.memory_id = m.id\n JOIN projects p ON p.id = mp.project_id\n WHERE p.scope_hash = ?\n ORDER BY m.id`\n )\n .all(scope);\n }\n\n return createHash(\"sha256\")\n .update(JSON.stringify(contents.map((r) => r.content)))\n .digest(\"hex\");\n }\n\n getExpiredOrDirtyScopes(): { scope: string; reason: \"expired\" | \"dirty\" | \"missing\" }[] {\n const allScopes = this.getAllActiveScopes();\n const now = new Date().toISOString();\n const results: { scope: string; reason: \"expired\" | \"dirty\" | \"missing\" }[] = [];\n\n for (const scope of allScopes) {\n const row = this.#db.db\n .prepare<[string], SynthesisRow>(\"SELECT * FROM syntheses WHERE scope = ?\")\n .get(scope);\n\n if (row === undefined || (row.content === \"pending\" && row.source_memory_hash === \"\")) {\n results.push({ scope, reason: \"missing\" });\n continue;\n }\n\n if (row.expires_at <= now) {\n results.push({ scope, reason: \"expired\" });\n continue;\n }\n\n const currentHash = this.computeSourceMemoryHash(scope);\n if (currentHash !== row.source_memory_hash) {\n results.push({ scope, reason: \"dirty\" });\n }\n }\n\n return results;\n }\n\n getAllActiveScopes(): string[] {\n const projectScopes = this.#db.db\n .prepare<[], { scope_hash: string }>(\"SELECT DISTINCT scope_hash FROM projects\")\n .all()\n .map((r) => r.scope_hash);\n\n return [\"global\", ...projectScopes];\n }\n\n expireStale(): void {\n const now = new Date().toISOString();\n this.#db.db.prepare(\"DELETE FROM syntheses WHERE expires_at < ?\").run(now);\n }\n}\n"],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@membank/core",
3
- "version": "0.9.3",
3
+ "version": "0.9.4",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -36,7 +36,7 @@
36
36
  "lint": "biome check ./src",
37
37
  "test": "vitest run",
38
38
  "test:watch": "vitest",
39
- "test:integration": "vitest run --reporter=verbose src/**/*.integration.test.ts",
39
+ "test:integration": "vitest run --reporter=verbose",
40
40
  "clean": "rm -rf dist *.tsbuildinfo"
41
41
  }
42
42
  }