@membank/core 0.6.1 → 0.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -28,6 +28,7 @@ let better_sqlite3 = require("better-sqlite3");
28
28
  better_sqlite3 = __toESM(better_sqlite3, 1);
29
29
  let sqlite_vec = require("sqlite-vec");
30
30
  sqlite_vec = __toESM(sqlite_vec, 1);
31
+ let zod = require("zod");
31
32
  let _huggingface_transformers = require("@huggingface/transformers");
32
33
  let node_crypto = require("node:crypto");
33
34
  let node_child_process = require("node:child_process");
@@ -156,13 +157,89 @@ var DatabaseManager = class DatabaseManager {
156
157
  }
157
158
  };
158
159
  //#endregion
160
+ //#region src/schemas.ts
161
+ const MEMORY_TYPE_VALUES = [
162
+ "correction",
163
+ "preference",
164
+ "decision",
165
+ "learning",
166
+ "fact"
167
+ ];
168
+ const MemoryTypeSchema = zod.z.enum(MEMORY_TYPE_VALUES);
169
+ const TagsJsonSchema = zod.z.array(zod.z.string());
170
+ const ProjectSchema = zod.z.object({
171
+ id: zod.z.string(),
172
+ name: zod.z.string(),
173
+ scopeHash: zod.z.string(),
174
+ createdAt: zod.z.string(),
175
+ updatedAt: zod.z.string()
176
+ });
177
+ const MemorySchema = zod.z.object({
178
+ id: zod.z.string(),
179
+ content: zod.z.string(),
180
+ type: MemoryTypeSchema,
181
+ tags: zod.z.array(zod.z.string()),
182
+ projects: zod.z.array(ProjectSchema),
183
+ sourceHarness: zod.z.string().nullable(),
184
+ accessCount: zod.z.number().int().nonnegative(),
185
+ pinned: zod.z.boolean(),
186
+ needsReview: zod.z.boolean(),
187
+ createdAt: zod.z.string(),
188
+ updatedAt: zod.z.string()
189
+ });
190
+ const QueryOptionsSchema = zod.z.object({
191
+ query: zod.z.string().min(1),
192
+ type: MemoryTypeSchema.optional(),
193
+ projectHash: zod.z.string().optional(),
194
+ limit: zod.z.number().int().positive().optional(),
195
+ includePinned: zod.z.boolean().optional()
196
+ });
197
+ const SaveOptionsSchema = zod.z.object({
198
+ content: zod.z.string().min(1),
199
+ type: MemoryTypeSchema,
200
+ tags: zod.z.array(zod.z.string()).optional(),
201
+ projectScope: zod.z.object({
202
+ hash: zod.z.string(),
203
+ name: zod.z.string()
204
+ }).optional(),
205
+ sourceHarness: zod.z.string().optional()
206
+ });
207
+ const MemoryPatchSchema = zod.z.object({
208
+ content: zod.z.string().min(1).optional(),
209
+ tags: zod.z.array(zod.z.string()).optional()
210
+ });
211
+ const SessionContextSchema = zod.z.object({
212
+ stats: zod.z.record(MemoryTypeSchema, zod.z.number()),
213
+ pinnedGlobal: zod.z.array(MemorySchema),
214
+ pinnedProject: zod.z.array(MemorySchema)
215
+ });
216
+ const MemoryRowSchema = zod.z.object({
217
+ id: zod.z.string(),
218
+ content: zod.z.string(),
219
+ type: zod.z.string(),
220
+ tags: zod.z.string(),
221
+ source: zod.z.string().nullable(),
222
+ access_count: zod.z.number(),
223
+ pinned: zod.z.number(),
224
+ needs_review: zod.z.number(),
225
+ created_at: zod.z.string(),
226
+ updated_at: zod.z.string()
227
+ });
228
+ const ProjectRowSchema = zod.z.object({
229
+ id: zod.z.string(),
230
+ name: zod.z.string(),
231
+ scope_hash: zod.z.string(),
232
+ created_at: zod.z.string(),
233
+ updated_at: zod.z.string()
234
+ });
235
+ //#endregion
159
236
  //#region src/db/row-types.ts
160
237
  function rowToMemory(row, projects) {
161
238
  return {
162
239
  id: row.id,
163
240
  content: row.content,
164
- type: row.type,
165
- tags: JSON.parse(row.tags),
241
+ type: MemoryTypeSchema.parse(row.type),
242
+ tags: TagsJsonSchema.parse(JSON.parse(row.tags)),
166
243
  projects,
167
244
  sourceHarness: row.source,
168
245
  accessCount: row.access_count,
@@ -207,15 +284,6 @@ var EmbeddingService = class {
207
284
  }
208
285
  };
209
286
  //#endregion
210
- //#region src/types.ts
211
- const MEMORY_TYPE_VALUES = [
212
- "correction",
213
- "preference",
214
- "decision",
215
- "learning",
216
- "fact"
217
- ];
218
- //#endregion
219
287
  //#region src/memory/repository.ts
220
288
  var MemoryRepository = class {
221
289
  #db;
@@ -227,7 +295,7 @@ var MemoryRepository = class {
227
295
  this.#projects = projects;
228
296
  }
229
297
  async save(options) {
230
- const { content, type, tags = [], projectScope, sourceHarness } = options;
298
+ const { content, type, tags = [], projectScope, sourceHarness } = SaveOptionsSchema.parse(options);
231
299
  const embedding = await this.#embedding.embed(content);
232
300
  const embeddingBlob = Buffer.from(embedding.buffer);
233
301
  let top;
@@ -246,7 +314,7 @@ var MemoryRepository = class {
246
314
  if (top !== void 0 && top.similarity > .92) {
247
315
  this.#db.db.prepare(`UPDATE memories SET content = ?, updated_at = ? WHERE id = ?`).run(content, now, top.id);
248
316
  this.#db.db.prepare(`UPDATE embeddings SET embedding = ? WHERE rowid = ?`).run(embeddingBlob, top.rowid);
249
- return rowToMemory(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(top.id), this.#projects.getProjectsForMemories([top.id]).get(top.id) ?? []);
317
+ return rowToMemory(MemoryRowSchema.parse(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(top.id)), this.#projects.getProjectsForMemories([top.id]).get(top.id) ?? []);
250
318
  }
251
319
  if (top !== void 0 && top.similarity >= .75) this.#db.db.prepare(`UPDATE memories SET needs_review = 1 WHERE id = ?`).run(top.id);
252
320
  const id = (0, node_crypto.randomUUID)();
@@ -257,30 +325,31 @@ var MemoryRepository = class {
257
325
  const project = this.#projects.upsertByHash(projectScope.hash, projectScope.name);
258
326
  this.#projects.addAssociation(id, project.id);
259
327
  }
260
- return rowToMemory(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id), this.#projects.getProjectsForMemories([id]).get(id) ?? []);
328
+ return rowToMemory(MemoryRowSchema.parse(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id)), this.#projects.getProjectsForMemories([id]).get(id) ?? []);
261
329
  }
262
330
  async update(id, patch) {
331
+ const { content, tags } = MemoryPatchSchema.parse(patch);
263
332
  const existing = this.#db.db.prepare(`SELECT m.rowid, m.* FROM memories m WHERE m.id = ?`).get(id);
264
333
  if (existing === void 0) throw new Error(`Memory not found: ${id}`);
265
334
  const now = (/* @__PURE__ */ new Date()).toISOString();
266
335
  const sets = ["updated_at = ?"];
267
336
  const values = [now];
268
- if (patch.content !== void 0) {
337
+ if (content !== void 0) {
269
338
  sets.push("content = ?");
270
- values.push(patch.content);
339
+ values.push(content);
271
340
  }
272
- if (patch.tags !== void 0) {
341
+ if (tags !== void 0) {
273
342
  sets.push("tags = ?");
274
- values.push(JSON.stringify(patch.tags));
343
+ values.push(JSON.stringify(tags));
275
344
  }
276
345
  values.push(id);
277
346
  this.#db.db.prepare(`UPDATE memories SET ${sets.join(", ")} WHERE id = ?`).run(...values);
278
- if (patch.content !== void 0) {
279
- const embedding = await this.#embedding.embed(patch.content);
347
+ if (content !== void 0) {
348
+ const embedding = await this.#embedding.embed(content);
280
349
  const embeddingBlob = Buffer.from(embedding.buffer);
281
350
  this.#db.db.prepare(`UPDATE embeddings SET embedding = ? WHERE rowid = ?`).run(embeddingBlob, existing.rowid);
282
351
  }
283
- return rowToMemory(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id), this.#projects.getProjectsForMemories([id]).get(id) ?? []);
352
+ return rowToMemory(MemoryRowSchema.parse(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id)), this.#projects.getProjectsForMemories([id]).get(id) ?? []);
284
353
  }
285
354
  delete(id) {
286
355
  const row = this.#db.db.prepare(`SELECT rowid FROM memories WHERE id = ?`).get(id);
@@ -307,7 +376,10 @@ var MemoryRepository = class {
307
376
  stats() {
308
377
  const byType = Object.fromEntries(MEMORY_TYPE_VALUES.map((t) => [t, 0]));
309
378
  const typeRows = this.#db.db.prepare(`SELECT type, COUNT(*) as count FROM memories GROUP BY type`).all();
310
- for (const row of typeRows) if (row.type in byType) byType[row.type] = row.count;
379
+ for (const row of typeRows) {
380
+ const parsed = MemoryTypeSchema.safeParse(row.type);
381
+ if (parsed.success) byType[parsed.data] = row.count;
382
+ }
311
383
  const totals = this.#db.db.prepare(`SELECT COUNT(*) as total, SUM(needs_review) as needsReview FROM memories`).get() ?? {
312
384
  total: 0,
313
385
  needsReview: 0
@@ -322,7 +394,7 @@ var MemoryRepository = class {
322
394
  if (this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id) === void 0) throw new Error(`Memory not found: ${id}`);
323
395
  const now = (/* @__PURE__ */ new Date()).toISOString();
324
396
  this.#db.db.prepare(`UPDATE memories SET pinned = ?, updated_at = ? WHERE id = ?`).run(pinned ? 1 : 0, now, id);
325
- return rowToMemory(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id), this.#projects.getProjectsForMemories([id]).get(id) ?? []);
397
+ return rowToMemory(MemoryRowSchema.parse(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id)), this.#projects.getProjectsForMemories([id]).get(id) ?? []);
326
398
  }
327
399
  incrementAccessCount(id) {
328
400
  this.#db.db.prepare(`UPDATE memories SET access_count = access_count + 1 WHERE id = ?`).run(id);
@@ -400,7 +472,7 @@ var ProjectRepository = class {
400
472
  const now = (/* @__PURE__ */ new Date()).toISOString();
401
473
  const id = (0, node_crypto.randomUUID)();
402
474
  this.#db.db.prepare(`INSERT OR IGNORE INTO projects (id, name, scope_hash, created_at, updated_at) VALUES (?, ?, ?, ?, ?)`).run(id, name, hash, now, now);
403
- return rowToProject(this.#db.db.prepare(`SELECT * FROM projects WHERE scope_hash = ?`).get(hash));
475
+ return rowToProject(ProjectRowSchema.parse(this.#db.db.prepare(`SELECT * FROM projects WHERE scope_hash = ?`).get(hash)));
404
476
  }
405
477
  rename(id, name) {
406
478
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -459,12 +531,13 @@ var QueryEngine = class {
459
531
  this.#repo = repo;
460
532
  }
461
533
  async query(options) {
462
- const { query, type, projectHash, limit = 10 } = options;
534
+ const { query, type, projectHash, limit = 10, includePinned } = QueryOptionsSchema.parse(options);
463
535
  const queryEmbedding = await this.#embedding.embed(query);
464
536
  const queryBlob = Buffer.from(queryEmbedding.buffer);
465
537
  const whereClauses = [];
466
538
  const params = [queryBlob];
467
539
  let joinClause = "";
540
+ if (!includePinned) whereClauses.push("m.pinned = 0");
468
541
  if (type !== void 0) {
469
542
  whereClauses.push("m.type = ?");
470
543
  params.push(type);
@@ -524,7 +597,10 @@ var SessionContextBuilder = class {
524
597
  WHERE p.scope_hash = ? AND m.pinned = 1`).all(projectHash).map((row) => rowToMemory(row, []));
525
598
  const typeCounts = this.#db.db.prepare("SELECT type, COUNT(*) as count FROM memories GROUP BY type").all();
526
599
  const stats = Object.fromEntries(MEMORY_TYPE_VALUES.map((t) => [t, 0]));
527
- for (const row of typeCounts) if (stats[row.type] !== void 0) stats[row.type] = row.count;
600
+ for (const row of typeCounts) {
601
+ const parsed = MemoryTypeSchema.safeParse(row.type);
602
+ if (parsed.success) stats[parsed.data] = row.count;
603
+ }
528
604
  return {
529
605
  stats,
530
606
  pinnedGlobal,
@@ -539,12 +615,23 @@ exports.EmbeddingService = EmbeddingService;
539
615
  exports.MEMORY_TYPE_VALUES = MEMORY_TYPE_VALUES;
540
616
  exports.MIGRATIONS = MIGRATIONS;
541
617
  exports.MembankError = MembankError;
618
+ exports.MemoryPatchSchema = MemoryPatchSchema;
542
619
  exports.MemoryRepository = MemoryRepository;
620
+ exports.MemoryRowSchema = MemoryRowSchema;
621
+ exports.MemorySchema = MemorySchema;
622
+ exports.MemoryTypeSchema = MemoryTypeSchema;
543
623
  exports.ProjectRepository = ProjectRepository;
624
+ exports.ProjectRowSchema = ProjectRowSchema;
625
+ exports.ProjectSchema = ProjectSchema;
544
626
  exports.QueryEngine = QueryEngine;
627
+ exports.QueryOptionsSchema = QueryOptionsSchema;
628
+ exports.SaveOptionsSchema = SaveOptionsSchema;
545
629
  exports.SessionContextBuilder = SessionContextBuilder;
630
+ exports.SessionContextSchema = SessionContextSchema;
631
+ exports.TagsJsonSchema = TagsJsonSchema;
546
632
  exports.listMemoryTypes = listMemoryTypes;
547
633
  exports.resolveProject = resolveProject;
548
634
  exports.resolveScope = resolveScope;
549
635
  exports.rowToMemory = rowToMemory;
636
+ exports.rowToProject = rowToProject;
550
637
  exports.runScopeToProjectsMigration = runScopeToProjectsMigration;
package/dist/index.d.cts CHANGED
@@ -1,4 +1,5 @@
1
1
  import BetterSqlite3 from "better-sqlite3";
2
+ import { z } from "zod";
2
3
 
3
4
  //#region src/db/errors.d.ts
4
5
  declare class MembankError extends Error {
@@ -21,65 +22,172 @@ declare class DatabaseManager {
21
22
  close(): void;
22
23
  }
23
24
  //#endregion
24
- //#region src/types.d.ts
25
- type MemoryType = "correction" | "preference" | "decision" | "learning" | "fact";
25
+ //#region src/schemas.d.ts
26
26
  declare const MEMORY_TYPE_VALUES: readonly ["correction", "preference", "decision", "learning", "fact"];
27
- interface Project {
28
- id: string;
29
- name: string;
30
- scopeHash: string;
31
- createdAt: string;
32
- updatedAt: string;
33
- }
34
- interface Memory {
35
- id: string;
36
- content: string;
37
- type: MemoryType;
38
- tags: string[];
39
- projects: Project[];
40
- sourceHarness: string | null;
41
- accessCount: number;
42
- pinned: boolean;
43
- needsReview: boolean;
44
- createdAt: string;
45
- updatedAt: string;
46
- }
47
- interface QueryOptions {
48
- query: string;
49
- type?: MemoryType;
50
- projectHash?: string;
51
- limit?: number;
52
- }
53
- interface SaveOptions {
54
- content: string;
55
- type: MemoryType;
56
- tags?: string[];
57
- projectScope?: {
58
- hash: string;
59
- name: string;
60
- };
61
- sourceHarness?: string;
62
- }
63
- interface SessionContext {
64
- stats: Record<MemoryType, number>;
65
- pinnedGlobal: Memory[];
66
- pinnedProject: Memory[];
67
- }
27
+ declare const MemoryTypeSchema: z.ZodEnum<{
28
+ correction: "correction";
29
+ preference: "preference";
30
+ decision: "decision";
31
+ learning: "learning";
32
+ fact: "fact";
33
+ }>;
34
+ type MemoryType = z.infer<typeof MemoryTypeSchema>;
35
+ declare const TagsJsonSchema: z.ZodArray<z.ZodString>;
36
+ declare const ProjectSchema: z.ZodObject<{
37
+ id: z.ZodString;
38
+ name: z.ZodString;
39
+ scopeHash: z.ZodString;
40
+ createdAt: z.ZodString;
41
+ updatedAt: z.ZodString;
42
+ }, z.core.$strip>;
43
+ type Project = z.infer<typeof ProjectSchema>;
44
+ declare const MemorySchema: z.ZodObject<{
45
+ id: z.ZodString;
46
+ content: z.ZodString;
47
+ type: z.ZodEnum<{
48
+ correction: "correction";
49
+ preference: "preference";
50
+ decision: "decision";
51
+ learning: "learning";
52
+ fact: "fact";
53
+ }>;
54
+ tags: z.ZodArray<z.ZodString>;
55
+ projects: z.ZodArray<z.ZodObject<{
56
+ id: z.ZodString;
57
+ name: z.ZodString;
58
+ scopeHash: z.ZodString;
59
+ createdAt: z.ZodString;
60
+ updatedAt: z.ZodString;
61
+ }, z.core.$strip>>;
62
+ sourceHarness: z.ZodNullable<z.ZodString>;
63
+ accessCount: z.ZodNumber;
64
+ pinned: z.ZodBoolean;
65
+ needsReview: z.ZodBoolean;
66
+ createdAt: z.ZodString;
67
+ updatedAt: z.ZodString;
68
+ }, z.core.$strip>;
69
+ type Memory = z.infer<typeof MemorySchema>;
70
+ declare const QueryOptionsSchema: z.ZodObject<{
71
+ query: z.ZodString;
72
+ type: z.ZodOptional<z.ZodEnum<{
73
+ correction: "correction";
74
+ preference: "preference";
75
+ decision: "decision";
76
+ learning: "learning";
77
+ fact: "fact";
78
+ }>>;
79
+ projectHash: z.ZodOptional<z.ZodString>;
80
+ limit: z.ZodOptional<z.ZodNumber>;
81
+ includePinned: z.ZodOptional<z.ZodBoolean>;
82
+ }, z.core.$strip>;
83
+ type QueryOptions = z.infer<typeof QueryOptionsSchema>;
84
+ declare const SaveOptionsSchema: z.ZodObject<{
85
+ content: z.ZodString;
86
+ type: z.ZodEnum<{
87
+ correction: "correction";
88
+ preference: "preference";
89
+ decision: "decision";
90
+ learning: "learning";
91
+ fact: "fact";
92
+ }>;
93
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
94
+ projectScope: z.ZodOptional<z.ZodObject<{
95
+ hash: z.ZodString;
96
+ name: z.ZodString;
97
+ }, z.core.$strip>>;
98
+ sourceHarness: z.ZodOptional<z.ZodString>;
99
+ }, z.core.$strip>;
100
+ type SaveOptions = z.infer<typeof SaveOptionsSchema>;
101
+ declare const MemoryPatchSchema: z.ZodObject<{
102
+ content: z.ZodOptional<z.ZodString>;
103
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
104
+ }, z.core.$strip>;
105
+ type MemoryPatch = z.infer<typeof MemoryPatchSchema>;
106
+ declare const SessionContextSchema: z.ZodObject<{
107
+ stats: z.ZodRecord<z.ZodEnum<{
108
+ correction: "correction";
109
+ preference: "preference";
110
+ decision: "decision";
111
+ learning: "learning";
112
+ fact: "fact";
113
+ }>, z.ZodNumber>;
114
+ pinnedGlobal: z.ZodArray<z.ZodObject<{
115
+ id: z.ZodString;
116
+ content: z.ZodString;
117
+ type: z.ZodEnum<{
118
+ correction: "correction";
119
+ preference: "preference";
120
+ decision: "decision";
121
+ learning: "learning";
122
+ fact: "fact";
123
+ }>;
124
+ tags: z.ZodArray<z.ZodString>;
125
+ projects: z.ZodArray<z.ZodObject<{
126
+ id: z.ZodString;
127
+ name: z.ZodString;
128
+ scopeHash: z.ZodString;
129
+ createdAt: z.ZodString;
130
+ updatedAt: z.ZodString;
131
+ }, z.core.$strip>>;
132
+ sourceHarness: z.ZodNullable<z.ZodString>;
133
+ accessCount: z.ZodNumber;
134
+ pinned: z.ZodBoolean;
135
+ needsReview: z.ZodBoolean;
136
+ createdAt: z.ZodString;
137
+ updatedAt: z.ZodString;
138
+ }, z.core.$strip>>;
139
+ pinnedProject: z.ZodArray<z.ZodObject<{
140
+ id: z.ZodString;
141
+ content: z.ZodString;
142
+ type: z.ZodEnum<{
143
+ correction: "correction";
144
+ preference: "preference";
145
+ decision: "decision";
146
+ learning: "learning";
147
+ fact: "fact";
148
+ }>;
149
+ tags: z.ZodArray<z.ZodString>;
150
+ projects: z.ZodArray<z.ZodObject<{
151
+ id: z.ZodString;
152
+ name: z.ZodString;
153
+ scopeHash: z.ZodString;
154
+ createdAt: z.ZodString;
155
+ updatedAt: z.ZodString;
156
+ }, z.core.$strip>>;
157
+ sourceHarness: z.ZodNullable<z.ZodString>;
158
+ accessCount: z.ZodNumber;
159
+ pinned: z.ZodBoolean;
160
+ needsReview: z.ZodBoolean;
161
+ createdAt: z.ZodString;
162
+ updatedAt: z.ZodString;
163
+ }, z.core.$strip>>;
164
+ }, z.core.$strip>;
165
+ type SessionContext = z.infer<typeof SessionContextSchema>;
166
+ declare const MemoryRowSchema: z.ZodObject<{
167
+ id: z.ZodString;
168
+ content: z.ZodString;
169
+ type: z.ZodString;
170
+ tags: z.ZodString;
171
+ source: z.ZodNullable<z.ZodString>;
172
+ access_count: z.ZodNumber;
173
+ pinned: z.ZodNumber;
174
+ needs_review: z.ZodNumber;
175
+ created_at: z.ZodString;
176
+ updated_at: z.ZodString;
177
+ }, z.core.$strip>;
178
+ type MemoryRow = z.infer<typeof MemoryRowSchema>;
179
+ declare const ProjectRowSchema: z.ZodObject<{
180
+ id: z.ZodString;
181
+ name: z.ZodString;
182
+ scope_hash: z.ZodString;
183
+ created_at: z.ZodString;
184
+ updated_at: z.ZodString;
185
+ }, z.core.$strip>;
186
+ type ProjectRow = z.infer<typeof ProjectRowSchema>;
68
187
  //#endregion
69
188
  //#region src/db/row-types.d.ts
70
- interface MemoryRow {
71
- id: string;
72
- content: string;
73
- type: string;
74
- tags: string;
75
- source: string | null;
76
- access_count: number;
77
- pinned: number;
78
- needs_review: number;
79
- created_at: string;
80
- updated_at: string;
81
- }
82
189
  declare function rowToMemory(row: MemoryRow, projects: Project[]): Memory;
190
+ declare function rowToProject(row: ProjectRow): Project;
83
191
  //#endregion
84
192
  //#region src/embedding/service.d.ts
85
193
  type ProgressCallback = (progress: {
@@ -114,10 +222,7 @@ declare class MemoryRepository {
114
222
  #private;
115
223
  constructor(db: DatabaseManager, embeddingService: EmbeddingService, projects: ProjectRepository);
116
224
  save(options: SaveOptions): Promise<Memory>;
117
- update(id: string, patch: {
118
- content?: string;
119
- tags?: string[];
120
- }): Promise<Memory>;
225
+ update(id: string, patch: MemoryPatch): Promise<Memory>;
121
226
  delete(id: string): Promise<void>;
122
227
  list(opts?: {
123
228
  type?: MemoryType;
@@ -170,5 +275,5 @@ declare class SessionContextBuilder {
170
275
  getSessionContext(projectHash: string): SessionContext;
171
276
  }
172
277
  //#endregion
173
- export { DatabaseError, DatabaseManager, EmbeddingService, MEMORY_TYPE_VALUES, MIGRATIONS, MembankError, Memory, MemoryRepository, type MemoryRow, MemoryType, MigrationMeta, ProgressCallback, Project, ProjectRepository, QueryEngine, QueryOptions, SaveOptions, ScopeToProjectsResult, SessionContext, SessionContextBuilder, listMemoryTypes, resolveProject, resolveScope, rowToMemory, runScopeToProjectsMigration };
278
+ export { DatabaseError, DatabaseManager, EmbeddingService, MEMORY_TYPE_VALUES, MIGRATIONS, MembankError, Memory, MemoryPatch, MemoryPatchSchema, MemoryRepository, MemoryRow, MemoryRowSchema, MemorySchema, MemoryType, MemoryTypeSchema, MigrationMeta, ProgressCallback, Project, ProjectRepository, ProjectRow, ProjectRowSchema, ProjectSchema, QueryEngine, QueryOptions, QueryOptionsSchema, SaveOptions, SaveOptionsSchema, ScopeToProjectsResult, SessionContext, SessionContextBuilder, SessionContextSchema, TagsJsonSchema, listMemoryTypes, resolveProject, resolveScope, rowToMemory, rowToProject, runScopeToProjectsMigration };
174
279
  //# sourceMappingURL=index.d.cts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.cts","names":[],"sources":["../src/db/errors.ts","../src/db/manager.ts","../src/types.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"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.cts","names":[],"sources":["../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"],"mappings":"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"}
package/dist/index.d.mts CHANGED
@@ -1,4 +1,5 @@
1
1
  import BetterSqlite3 from "better-sqlite3";
2
+ import { z } from "zod";
2
3
 
3
4
  //#region src/db/errors.d.ts
4
5
  declare class MembankError extends Error {
@@ -21,65 +22,172 @@ declare class DatabaseManager {
21
22
  close(): void;
22
23
  }
23
24
  //#endregion
24
- //#region src/types.d.ts
25
- type MemoryType = "correction" | "preference" | "decision" | "learning" | "fact";
25
+ //#region src/schemas.d.ts
26
26
  declare const MEMORY_TYPE_VALUES: readonly ["correction", "preference", "decision", "learning", "fact"];
27
- interface Project {
28
- id: string;
29
- name: string;
30
- scopeHash: string;
31
- createdAt: string;
32
- updatedAt: string;
33
- }
34
- interface Memory {
35
- id: string;
36
- content: string;
37
- type: MemoryType;
38
- tags: string[];
39
- projects: Project[];
40
- sourceHarness: string | null;
41
- accessCount: number;
42
- pinned: boolean;
43
- needsReview: boolean;
44
- createdAt: string;
45
- updatedAt: string;
46
- }
47
- interface QueryOptions {
48
- query: string;
49
- type?: MemoryType;
50
- projectHash?: string;
51
- limit?: number;
52
- }
53
- interface SaveOptions {
54
- content: string;
55
- type: MemoryType;
56
- tags?: string[];
57
- projectScope?: {
58
- hash: string;
59
- name: string;
60
- };
61
- sourceHarness?: string;
62
- }
63
- interface SessionContext {
64
- stats: Record<MemoryType, number>;
65
- pinnedGlobal: Memory[];
66
- pinnedProject: Memory[];
67
- }
27
+ declare const MemoryTypeSchema: z.ZodEnum<{
28
+ correction: "correction";
29
+ preference: "preference";
30
+ decision: "decision";
31
+ learning: "learning";
32
+ fact: "fact";
33
+ }>;
34
+ type MemoryType = z.infer<typeof MemoryTypeSchema>;
35
+ declare const TagsJsonSchema: z.ZodArray<z.ZodString>;
36
+ declare const ProjectSchema: z.ZodObject<{
37
+ id: z.ZodString;
38
+ name: z.ZodString;
39
+ scopeHash: z.ZodString;
40
+ createdAt: z.ZodString;
41
+ updatedAt: z.ZodString;
42
+ }, z.core.$strip>;
43
+ type Project = z.infer<typeof ProjectSchema>;
44
+ declare const MemorySchema: z.ZodObject<{
45
+ id: z.ZodString;
46
+ content: z.ZodString;
47
+ type: z.ZodEnum<{
48
+ correction: "correction";
49
+ preference: "preference";
50
+ decision: "decision";
51
+ learning: "learning";
52
+ fact: "fact";
53
+ }>;
54
+ tags: z.ZodArray<z.ZodString>;
55
+ projects: z.ZodArray<z.ZodObject<{
56
+ id: z.ZodString;
57
+ name: z.ZodString;
58
+ scopeHash: z.ZodString;
59
+ createdAt: z.ZodString;
60
+ updatedAt: z.ZodString;
61
+ }, z.core.$strip>>;
62
+ sourceHarness: z.ZodNullable<z.ZodString>;
63
+ accessCount: z.ZodNumber;
64
+ pinned: z.ZodBoolean;
65
+ needsReview: z.ZodBoolean;
66
+ createdAt: z.ZodString;
67
+ updatedAt: z.ZodString;
68
+ }, z.core.$strip>;
69
+ type Memory = z.infer<typeof MemorySchema>;
70
+ declare const QueryOptionsSchema: z.ZodObject<{
71
+ query: z.ZodString;
72
+ type: z.ZodOptional<z.ZodEnum<{
73
+ correction: "correction";
74
+ preference: "preference";
75
+ decision: "decision";
76
+ learning: "learning";
77
+ fact: "fact";
78
+ }>>;
79
+ projectHash: z.ZodOptional<z.ZodString>;
80
+ limit: z.ZodOptional<z.ZodNumber>;
81
+ includePinned: z.ZodOptional<z.ZodBoolean>;
82
+ }, z.core.$strip>;
83
+ type QueryOptions = z.infer<typeof QueryOptionsSchema>;
84
+ declare const SaveOptionsSchema: z.ZodObject<{
85
+ content: z.ZodString;
86
+ type: z.ZodEnum<{
87
+ correction: "correction";
88
+ preference: "preference";
89
+ decision: "decision";
90
+ learning: "learning";
91
+ fact: "fact";
92
+ }>;
93
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
94
+ projectScope: z.ZodOptional<z.ZodObject<{
95
+ hash: z.ZodString;
96
+ name: z.ZodString;
97
+ }, z.core.$strip>>;
98
+ sourceHarness: z.ZodOptional<z.ZodString>;
99
+ }, z.core.$strip>;
100
+ type SaveOptions = z.infer<typeof SaveOptionsSchema>;
101
+ declare const MemoryPatchSchema: z.ZodObject<{
102
+ content: z.ZodOptional<z.ZodString>;
103
+ tags: z.ZodOptional<z.ZodArray<z.ZodString>>;
104
+ }, z.core.$strip>;
105
+ type MemoryPatch = z.infer<typeof MemoryPatchSchema>;
106
+ declare const SessionContextSchema: z.ZodObject<{
107
+ stats: z.ZodRecord<z.ZodEnum<{
108
+ correction: "correction";
109
+ preference: "preference";
110
+ decision: "decision";
111
+ learning: "learning";
112
+ fact: "fact";
113
+ }>, z.ZodNumber>;
114
+ pinnedGlobal: z.ZodArray<z.ZodObject<{
115
+ id: z.ZodString;
116
+ content: z.ZodString;
117
+ type: z.ZodEnum<{
118
+ correction: "correction";
119
+ preference: "preference";
120
+ decision: "decision";
121
+ learning: "learning";
122
+ fact: "fact";
123
+ }>;
124
+ tags: z.ZodArray<z.ZodString>;
125
+ projects: z.ZodArray<z.ZodObject<{
126
+ id: z.ZodString;
127
+ name: z.ZodString;
128
+ scopeHash: z.ZodString;
129
+ createdAt: z.ZodString;
130
+ updatedAt: z.ZodString;
131
+ }, z.core.$strip>>;
132
+ sourceHarness: z.ZodNullable<z.ZodString>;
133
+ accessCount: z.ZodNumber;
134
+ pinned: z.ZodBoolean;
135
+ needsReview: z.ZodBoolean;
136
+ createdAt: z.ZodString;
137
+ updatedAt: z.ZodString;
138
+ }, z.core.$strip>>;
139
+ pinnedProject: z.ZodArray<z.ZodObject<{
140
+ id: z.ZodString;
141
+ content: z.ZodString;
142
+ type: z.ZodEnum<{
143
+ correction: "correction";
144
+ preference: "preference";
145
+ decision: "decision";
146
+ learning: "learning";
147
+ fact: "fact";
148
+ }>;
149
+ tags: z.ZodArray<z.ZodString>;
150
+ projects: z.ZodArray<z.ZodObject<{
151
+ id: z.ZodString;
152
+ name: z.ZodString;
153
+ scopeHash: z.ZodString;
154
+ createdAt: z.ZodString;
155
+ updatedAt: z.ZodString;
156
+ }, z.core.$strip>>;
157
+ sourceHarness: z.ZodNullable<z.ZodString>;
158
+ accessCount: z.ZodNumber;
159
+ pinned: z.ZodBoolean;
160
+ needsReview: z.ZodBoolean;
161
+ createdAt: z.ZodString;
162
+ updatedAt: z.ZodString;
163
+ }, z.core.$strip>>;
164
+ }, z.core.$strip>;
165
+ type SessionContext = z.infer<typeof SessionContextSchema>;
166
+ declare const MemoryRowSchema: z.ZodObject<{
167
+ id: z.ZodString;
168
+ content: z.ZodString;
169
+ type: z.ZodString;
170
+ tags: z.ZodString;
171
+ source: z.ZodNullable<z.ZodString>;
172
+ access_count: z.ZodNumber;
173
+ pinned: z.ZodNumber;
174
+ needs_review: z.ZodNumber;
175
+ created_at: z.ZodString;
176
+ updated_at: z.ZodString;
177
+ }, z.core.$strip>;
178
+ type MemoryRow = z.infer<typeof MemoryRowSchema>;
179
+ declare const ProjectRowSchema: z.ZodObject<{
180
+ id: z.ZodString;
181
+ name: z.ZodString;
182
+ scope_hash: z.ZodString;
183
+ created_at: z.ZodString;
184
+ updated_at: z.ZodString;
185
+ }, z.core.$strip>;
186
+ type ProjectRow = z.infer<typeof ProjectRowSchema>;
68
187
  //#endregion
69
188
  //#region src/db/row-types.d.ts
70
- interface MemoryRow {
71
- id: string;
72
- content: string;
73
- type: string;
74
- tags: string;
75
- source: string | null;
76
- access_count: number;
77
- pinned: number;
78
- needs_review: number;
79
- created_at: string;
80
- updated_at: string;
81
- }
82
189
  declare function rowToMemory(row: MemoryRow, projects: Project[]): Memory;
190
+ declare function rowToProject(row: ProjectRow): Project;
83
191
  //#endregion
84
192
  //#region src/embedding/service.d.ts
85
193
  type ProgressCallback = (progress: {
@@ -114,10 +222,7 @@ declare class MemoryRepository {
114
222
  #private;
115
223
  constructor(db: DatabaseManager, embeddingService: EmbeddingService, projects: ProjectRepository);
116
224
  save(options: SaveOptions): Promise<Memory>;
117
- update(id: string, patch: {
118
- content?: string;
119
- tags?: string[];
120
- }): Promise<Memory>;
225
+ update(id: string, patch: MemoryPatch): Promise<Memory>;
121
226
  delete(id: string): Promise<void>;
122
227
  list(opts?: {
123
228
  type?: MemoryType;
@@ -170,5 +275,5 @@ declare class SessionContextBuilder {
170
275
  getSessionContext(projectHash: string): SessionContext;
171
276
  }
172
277
  //#endregion
173
- export { DatabaseError, DatabaseManager, EmbeddingService, MEMORY_TYPE_VALUES, MIGRATIONS, MembankError, Memory, MemoryRepository, type MemoryRow, MemoryType, MigrationMeta, ProgressCallback, Project, ProjectRepository, QueryEngine, QueryOptions, SaveOptions, ScopeToProjectsResult, SessionContext, SessionContextBuilder, listMemoryTypes, resolveProject, resolveScope, rowToMemory, runScopeToProjectsMigration };
278
+ export { DatabaseError, DatabaseManager, EmbeddingService, MEMORY_TYPE_VALUES, MIGRATIONS, MembankError, Memory, MemoryPatch, MemoryPatchSchema, MemoryRepository, MemoryRow, MemoryRowSchema, MemorySchema, MemoryType, MemoryTypeSchema, MigrationMeta, ProgressCallback, Project, ProjectRepository, ProjectRow, ProjectRowSchema, ProjectSchema, QueryEngine, QueryOptions, QueryOptionsSchema, SaveOptions, SaveOptionsSchema, ScopeToProjectsResult, SessionContext, SessionContextBuilder, SessionContextSchema, TagsJsonSchema, listMemoryTypes, resolveProject, resolveScope, rowToMemory, rowToProject, runScopeToProjectsMigration };
174
279
  //# sourceMappingURL=index.d.mts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/db/errors.ts","../src/db/manager.ts","../src/types.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"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../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"],"mappings":"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"}
package/dist/index.mjs CHANGED
@@ -3,6 +3,7 @@ import { homedir } from "node:os";
3
3
  import { dirname, join } from "node:path";
4
4
  import BetterSqlite3 from "better-sqlite3";
5
5
  import * as sqliteVec from "sqlite-vec";
6
+ import { z } from "zod";
6
7
  import { pipeline } from "@huggingface/transformers";
7
8
  import { createHash, randomUUID } from "node:crypto";
8
9
  import { execFile } from "node:child_process";
@@ -131,13 +132,89 @@ var DatabaseManager = class DatabaseManager {
131
132
  }
132
133
  };
133
134
  //#endregion
135
+ //#region src/schemas.ts
136
+ const MEMORY_TYPE_VALUES = [
137
+ "correction",
138
+ "preference",
139
+ "decision",
140
+ "learning",
141
+ "fact"
142
+ ];
143
+ const MemoryTypeSchema = z.enum(MEMORY_TYPE_VALUES);
144
+ const TagsJsonSchema = z.array(z.string());
145
+ const ProjectSchema = z.object({
146
+ id: z.string(),
147
+ name: z.string(),
148
+ scopeHash: z.string(),
149
+ createdAt: z.string(),
150
+ updatedAt: z.string()
151
+ });
152
+ const MemorySchema = z.object({
153
+ id: z.string(),
154
+ content: z.string(),
155
+ type: MemoryTypeSchema,
156
+ tags: z.array(z.string()),
157
+ projects: z.array(ProjectSchema),
158
+ sourceHarness: z.string().nullable(),
159
+ accessCount: z.number().int().nonnegative(),
160
+ pinned: z.boolean(),
161
+ needsReview: z.boolean(),
162
+ createdAt: z.string(),
163
+ updatedAt: z.string()
164
+ });
165
+ const QueryOptionsSchema = z.object({
166
+ query: z.string().min(1),
167
+ type: MemoryTypeSchema.optional(),
168
+ projectHash: z.string().optional(),
169
+ limit: z.number().int().positive().optional(),
170
+ includePinned: z.boolean().optional()
171
+ });
172
+ const SaveOptionsSchema = z.object({
173
+ content: z.string().min(1),
174
+ type: MemoryTypeSchema,
175
+ tags: z.array(z.string()).optional(),
176
+ projectScope: z.object({
177
+ hash: z.string(),
178
+ name: z.string()
179
+ }).optional(),
180
+ sourceHarness: z.string().optional()
181
+ });
182
+ const MemoryPatchSchema = z.object({
183
+ content: z.string().min(1).optional(),
184
+ tags: z.array(z.string()).optional()
185
+ });
186
+ const SessionContextSchema = z.object({
187
+ stats: z.record(MemoryTypeSchema, z.number()),
188
+ pinnedGlobal: z.array(MemorySchema),
189
+ pinnedProject: z.array(MemorySchema)
190
+ });
191
+ const MemoryRowSchema = z.object({
192
+ id: z.string(),
193
+ content: z.string(),
194
+ type: z.string(),
195
+ tags: z.string(),
196
+ source: z.string().nullable(),
197
+ access_count: z.number(),
198
+ pinned: z.number(),
199
+ needs_review: z.number(),
200
+ created_at: z.string(),
201
+ updated_at: z.string()
202
+ });
203
+ const ProjectRowSchema = z.object({
204
+ id: z.string(),
205
+ name: z.string(),
206
+ scope_hash: z.string(),
207
+ created_at: z.string(),
208
+ updated_at: z.string()
209
+ });
210
+ //#endregion
134
211
  //#region src/db/row-types.ts
135
212
  function rowToMemory(row, projects) {
136
213
  return {
137
214
  id: row.id,
138
215
  content: row.content,
139
- type: row.type,
140
- tags: JSON.parse(row.tags),
216
+ type: MemoryTypeSchema.parse(row.type),
217
+ tags: TagsJsonSchema.parse(JSON.parse(row.tags)),
141
218
  projects,
142
219
  sourceHarness: row.source,
143
220
  accessCount: row.access_count,
@@ -182,15 +259,6 @@ var EmbeddingService = class {
182
259
  }
183
260
  };
184
261
  //#endregion
185
- //#region src/types.ts
186
- const MEMORY_TYPE_VALUES = [
187
- "correction",
188
- "preference",
189
- "decision",
190
- "learning",
191
- "fact"
192
- ];
193
- //#endregion
194
262
  //#region src/memory/repository.ts
195
263
  var MemoryRepository = class {
196
264
  #db;
@@ -202,7 +270,7 @@ var MemoryRepository = class {
202
270
  this.#projects = projects;
203
271
  }
204
272
  async save(options) {
205
- const { content, type, tags = [], projectScope, sourceHarness } = options;
273
+ const { content, type, tags = [], projectScope, sourceHarness } = SaveOptionsSchema.parse(options);
206
274
  const embedding = await this.#embedding.embed(content);
207
275
  const embeddingBlob = Buffer.from(embedding.buffer);
208
276
  let top;
@@ -221,7 +289,7 @@ var MemoryRepository = class {
221
289
  if (top !== void 0 && top.similarity > .92) {
222
290
  this.#db.db.prepare(`UPDATE memories SET content = ?, updated_at = ? WHERE id = ?`).run(content, now, top.id);
223
291
  this.#db.db.prepare(`UPDATE embeddings SET embedding = ? WHERE rowid = ?`).run(embeddingBlob, top.rowid);
224
- return rowToMemory(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(top.id), this.#projects.getProjectsForMemories([top.id]).get(top.id) ?? []);
292
+ return rowToMemory(MemoryRowSchema.parse(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(top.id)), this.#projects.getProjectsForMemories([top.id]).get(top.id) ?? []);
225
293
  }
226
294
  if (top !== void 0 && top.similarity >= .75) this.#db.db.prepare(`UPDATE memories SET needs_review = 1 WHERE id = ?`).run(top.id);
227
295
  const id = randomUUID();
@@ -232,30 +300,31 @@ var MemoryRepository = class {
232
300
  const project = this.#projects.upsertByHash(projectScope.hash, projectScope.name);
233
301
  this.#projects.addAssociation(id, project.id);
234
302
  }
235
- return rowToMemory(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id), this.#projects.getProjectsForMemories([id]).get(id) ?? []);
303
+ return rowToMemory(MemoryRowSchema.parse(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id)), this.#projects.getProjectsForMemories([id]).get(id) ?? []);
236
304
  }
237
305
  async update(id, patch) {
306
+ const { content, tags } = MemoryPatchSchema.parse(patch);
238
307
  const existing = this.#db.db.prepare(`SELECT m.rowid, m.* FROM memories m WHERE m.id = ?`).get(id);
239
308
  if (existing === void 0) throw new Error(`Memory not found: ${id}`);
240
309
  const now = (/* @__PURE__ */ new Date()).toISOString();
241
310
  const sets = ["updated_at = ?"];
242
311
  const values = [now];
243
- if (patch.content !== void 0) {
312
+ if (content !== void 0) {
244
313
  sets.push("content = ?");
245
- values.push(patch.content);
314
+ values.push(content);
246
315
  }
247
- if (patch.tags !== void 0) {
316
+ if (tags !== void 0) {
248
317
  sets.push("tags = ?");
249
- values.push(JSON.stringify(patch.tags));
318
+ values.push(JSON.stringify(tags));
250
319
  }
251
320
  values.push(id);
252
321
  this.#db.db.prepare(`UPDATE memories SET ${sets.join(", ")} WHERE id = ?`).run(...values);
253
- if (patch.content !== void 0) {
254
- const embedding = await this.#embedding.embed(patch.content);
322
+ if (content !== void 0) {
323
+ const embedding = await this.#embedding.embed(content);
255
324
  const embeddingBlob = Buffer.from(embedding.buffer);
256
325
  this.#db.db.prepare(`UPDATE embeddings SET embedding = ? WHERE rowid = ?`).run(embeddingBlob, existing.rowid);
257
326
  }
258
- return rowToMemory(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id), this.#projects.getProjectsForMemories([id]).get(id) ?? []);
327
+ return rowToMemory(MemoryRowSchema.parse(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id)), this.#projects.getProjectsForMemories([id]).get(id) ?? []);
259
328
  }
260
329
  delete(id) {
261
330
  const row = this.#db.db.prepare(`SELECT rowid FROM memories WHERE id = ?`).get(id);
@@ -282,7 +351,10 @@ var MemoryRepository = class {
282
351
  stats() {
283
352
  const byType = Object.fromEntries(MEMORY_TYPE_VALUES.map((t) => [t, 0]));
284
353
  const typeRows = this.#db.db.prepare(`SELECT type, COUNT(*) as count FROM memories GROUP BY type`).all();
285
- for (const row of typeRows) if (row.type in byType) byType[row.type] = row.count;
354
+ for (const row of typeRows) {
355
+ const parsed = MemoryTypeSchema.safeParse(row.type);
356
+ if (parsed.success) byType[parsed.data] = row.count;
357
+ }
286
358
  const totals = this.#db.db.prepare(`SELECT COUNT(*) as total, SUM(needs_review) as needsReview FROM memories`).get() ?? {
287
359
  total: 0,
288
360
  needsReview: 0
@@ -297,7 +369,7 @@ var MemoryRepository = class {
297
369
  if (this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id) === void 0) throw new Error(`Memory not found: ${id}`);
298
370
  const now = (/* @__PURE__ */ new Date()).toISOString();
299
371
  this.#db.db.prepare(`UPDATE memories SET pinned = ?, updated_at = ? WHERE id = ?`).run(pinned ? 1 : 0, now, id);
300
- return rowToMemory(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id), this.#projects.getProjectsForMemories([id]).get(id) ?? []);
372
+ return rowToMemory(MemoryRowSchema.parse(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id)), this.#projects.getProjectsForMemories([id]).get(id) ?? []);
301
373
  }
302
374
  incrementAccessCount(id) {
303
375
  this.#db.db.prepare(`UPDATE memories SET access_count = access_count + 1 WHERE id = ?`).run(id);
@@ -375,7 +447,7 @@ var ProjectRepository = class {
375
447
  const now = (/* @__PURE__ */ new Date()).toISOString();
376
448
  const id = randomUUID();
377
449
  this.#db.db.prepare(`INSERT OR IGNORE INTO projects (id, name, scope_hash, created_at, updated_at) VALUES (?, ?, ?, ?, ?)`).run(id, name, hash, now, now);
378
- return rowToProject(this.#db.db.prepare(`SELECT * FROM projects WHERE scope_hash = ?`).get(hash));
450
+ return rowToProject(ProjectRowSchema.parse(this.#db.db.prepare(`SELECT * FROM projects WHERE scope_hash = ?`).get(hash)));
379
451
  }
380
452
  rename(id, name) {
381
453
  const now = (/* @__PURE__ */ new Date()).toISOString();
@@ -434,12 +506,13 @@ var QueryEngine = class {
434
506
  this.#repo = repo;
435
507
  }
436
508
  async query(options) {
437
- const { query, type, projectHash, limit = 10 } = options;
509
+ const { query, type, projectHash, limit = 10, includePinned } = QueryOptionsSchema.parse(options);
438
510
  const queryEmbedding = await this.#embedding.embed(query);
439
511
  const queryBlob = Buffer.from(queryEmbedding.buffer);
440
512
  const whereClauses = [];
441
513
  const params = [queryBlob];
442
514
  let joinClause = "";
515
+ if (!includePinned) whereClauses.push("m.pinned = 0");
443
516
  if (type !== void 0) {
444
517
  whereClauses.push("m.type = ?");
445
518
  params.push(type);
@@ -499,7 +572,10 @@ var SessionContextBuilder = class {
499
572
  WHERE p.scope_hash = ? AND m.pinned = 1`).all(projectHash).map((row) => rowToMemory(row, []));
500
573
  const typeCounts = this.#db.db.prepare("SELECT type, COUNT(*) as count FROM memories GROUP BY type").all();
501
574
  const stats = Object.fromEntries(MEMORY_TYPE_VALUES.map((t) => [t, 0]));
502
- for (const row of typeCounts) if (stats[row.type] !== void 0) stats[row.type] = row.count;
575
+ for (const row of typeCounts) {
576
+ const parsed = MemoryTypeSchema.safeParse(row.type);
577
+ if (parsed.success) stats[parsed.data] = row.count;
578
+ }
503
579
  return {
504
580
  stats,
505
581
  pinnedGlobal,
@@ -508,6 +584,6 @@ var SessionContextBuilder = class {
508
584
  }
509
585
  };
510
586
  //#endregion
511
- export { DatabaseError, DatabaseManager, EmbeddingService, MEMORY_TYPE_VALUES, MIGRATIONS, MembankError, MemoryRepository, ProjectRepository, QueryEngine, SessionContextBuilder, listMemoryTypes, resolveProject, resolveScope, rowToMemory, runScopeToProjectsMigration };
587
+ export { DatabaseError, DatabaseManager, EmbeddingService, MEMORY_TYPE_VALUES, MIGRATIONS, MembankError, MemoryPatchSchema, MemoryRepository, MemoryRowSchema, MemorySchema, MemoryTypeSchema, ProjectRepository, ProjectRowSchema, ProjectSchema, QueryEngine, QueryOptionsSchema, SaveOptionsSchema, SessionContextBuilder, SessionContextSchema, TagsJsonSchema, listMemoryTypes, resolveProject, resolveScope, rowToMemory, rowToProject, runScopeToProjectsMigration };
512
588
 
513
589
  //# sourceMappingURL=index.mjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.mjs","names":["MIGRATIONS","#db","#init","#initInMemory","#runMigrations","#db","#embedding","#projects","#db","#db","#embedding","#repo","#computeScore","#db"],"sources":["../src/db/errors.ts","../src/db/manager.ts","../src/db/row-types.ts","../src/embedding/service.ts","../src/types.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"],"sourcesContent":["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\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 type { Memory, MemoryType, Project } from \"../types.js\";\n\nexport interface MemoryRow {\n id: string;\n content: string;\n type: string;\n tags: string;\n source: string | null;\n access_count: number;\n pinned: number;\n needs_review: number;\n created_at: string;\n updated_at: string;\n}\n\nexport interface ProjectRow {\n id: string;\n name: string;\n scope_hash: string;\n created_at: string;\n updated_at: string;\n}\n\nexport function rowToMemory(row: MemoryRow, projects: Project[]): Memory {\n return {\n id: row.id,\n content: row.content,\n type: row.type as MemoryType,\n tags: JSON.parse(row.tags) as string[],\n projects,\n sourceHarness: row.source,\n accessCount: row.access_count,\n pinned: row.pinned !== 0,\n needsReview: row.needs_review !== 0,\n createdAt: row.created_at,\n updatedAt: row.updated_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","export type MemoryType = \"correction\" | \"preference\" | \"decision\" | \"learning\" | \"fact\";\n\nexport const MEMORY_TYPE_VALUES = [\n \"correction\",\n \"preference\",\n \"decision\",\n \"learning\",\n \"fact\",\n] as const satisfies readonly MemoryType[];\n\nexport interface Project {\n id: string;\n name: string;\n scopeHash: string;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface Memory {\n id: string;\n content: string;\n type: MemoryType;\n tags: string[];\n projects: Project[];\n sourceHarness: string | null;\n accessCount: number;\n pinned: boolean;\n needsReview: boolean;\n createdAt: string;\n updatedAt: string;\n}\n\nexport interface QueryOptions {\n query: string;\n type?: MemoryType;\n projectHash?: string;\n limit?: number;\n}\n\nexport interface SaveOptions {\n content: string;\n type: MemoryType;\n tags?: string[];\n projectScope?: { hash: string; name: string };\n sourceHarness?: string;\n}\n\nexport interface SessionContext {\n stats: Record<MemoryType, number>;\n pinnedGlobal: Memory[];\n pinnedProject: Memory[];\n}\n","import { randomUUID } from \"node:crypto\";\nimport type { DatabaseManager } from \"../db/manager.js\";\nimport type { MemoryRow } from \"../db/row-types.js\";\nimport { rowToMemory } from \"../db/row-types.js\";\nimport type { EmbeddingService } from \"../embedding/service.js\";\nimport type { ProjectRepository } from \"../project/repository.js\";\nimport type { Memory, MemoryType, SaveOptions } from \"../types.js\";\nimport { MEMORY_TYPE_VALUES } from \"../types.js\";\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 { content, type, tags = [], projectScope, sourceHarness } = 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 = this.#db.db\n .prepare<[string], MemoryRow>(`SELECT * FROM memories WHERE id = ?`)\n .get(top.id) as MemoryRow;\n\n const projectMap = this.#projects.getProjectsForMemories([top.id]);\n return rowToMemory(updated, projectMap.get(top.id) ?? []);\n }\n\n if (top !== undefined && top.similarity >= 0.75) {\n this.#db.db.prepare(`UPDATE memories SET needs_review = 1 WHERE id = ?`).run(top.id);\n }\n\n const id = randomUUID();\n this.#db.db\n .prepare(\n `INSERT INTO memories (id, content, type, tags, source, access_count, pinned, needs_review, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, 0, 0, 0, ?, ?)`\n )\n .run(id, content, type, JSON.stringify(tags), sourceHarness ?? null, now, now);\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 = this.#db.db\n .prepare<[string], MemoryRow>(`SELECT * FROM memories WHERE id = ?`)\n .get(id) as MemoryRow;\n\n const projectMap = this.#projects.getProjectsForMemories([id]);\n return rowToMemory(row, projectMap.get(id) ?? []);\n }\n\n async update(id: string, patch: { content?: string; tags?: string[] }): Promise<Memory> {\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 (patch.content !== undefined) {\n sets.push(\"content = ?\");\n values.push(patch.content);\n }\n\n if (patch.tags !== undefined) {\n sets.push(\"tags = ?\");\n values.push(JSON.stringify(patch.tags));\n }\n\n values.push(id);\n this.#db.db.prepare(`UPDATE memories SET ${sets.join(\", \")} WHERE id = ?`).run(...values);\n\n if (patch.content !== undefined) {\n const embedding = await this.#embedding.embed(patch.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 = this.#db.db\n .prepare<[string], MemoryRow>(`SELECT * FROM memories WHERE id = ?`)\n .get(id) as MemoryRow;\n\n const projectMap = this.#projects.getProjectsForMemories([id]);\n return rowToMemory(updated, projectMap.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 return rows.map((row) => rowToMemory(row, projectMap.get(row.id) ?? []));\n }\n\n stats(): { byType: Record<MemoryType, number>; total: number; needsReview: number } {\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 if (row.type in byType) {\n byType[row.type as MemoryType] = row.count;\n }\n }\n\n const totals = this.#db.db\n .prepare<[], { total: number; needsReview: number }>(\n `SELECT COUNT(*) as total, SUM(needs_review) as needsReview FROM memories`\n )\n .get() ?? { total: 0, needsReview: 0 };\n\n return {\n byType,\n total: totals.total,\n needsReview: totals.needsReview ?? 0,\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 = this.#db.db\n .prepare<[string], MemoryRow>(`SELECT * FROM memories WHERE id = ?`)\n .get(id) as MemoryRow;\n\n const projectMap = this.#projects.getProjectsForMemories([id]);\n return rowToMemory(updated, projectMap.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 type { ProjectRow } from \"../db/row-types.js\";\nimport { rowToProject } from \"../db/row-types.js\";\nimport type { Project } 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 = this.#db.db\n .prepare<[string], ProjectRow>(`SELECT * FROM projects WHERE scope_hash = ?`)\n .get(hash) as ProjectRow;\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 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 type { MemoryRow } from \"../db/row-types.js\";\nimport { rowToMemory } from \"../db/row-types.js\";\nimport type { EmbeddingService } from \"../embedding/service.js\";\nimport type { MemoryRepository } from \"../memory/repository.js\";\nimport type { Memory, 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 { query, type, projectHash, limit = 10 } = 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 (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, 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, 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 typeWeight * 0.4 + accessCountNorm * 0.3 + recencyNorm * 0.2 + pinned * 0.1;\n }\n}\n","import type { DatabaseManager } from \"../db/manager.js\";\nimport type { MemoryRow } from \"../db/row-types.js\";\nimport { rowToMemory } from \"../db/row-types.js\";\nimport type { MemoryType, SessionContext } from \"../types.js\";\nimport { MEMORY_TYPE_VALUES } 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): SessionContext {\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 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 if (stats[row.type as MemoryType] !== undefined) {\n stats[row.type as MemoryType] = row.count;\n }\n }\n\n return { stats, pinnedGlobal, pinnedProject };\n }\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.mjs","names":["MIGRATIONS","#db","#init","#initInMemory","#runMigrations","#db","#embedding","#projects","#db","#db","#embedding","#repo","#computeScore","#db"],"sources":["../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"],"sourcesContent":["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\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 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 needsReview: z.boolean(),\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});\nexport type MemoryPatch = z.infer<typeof MemoryPatchSchema>;\n\nexport const SessionContextSchema = z.object({\n stats: z.record(MemoryTypeSchema, z.number()),\n pinnedGlobal: z.array(MemorySchema),\n pinnedProject: z.array(MemorySchema),\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 needs_review: 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, TagsJsonSchema } from \"../schemas.js\";\nimport type { Memory, MemoryRow, Project, ProjectRow } from \"../types.js\";\n\nexport function rowToMemory(row: MemoryRow, projects: Project[]): 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 needsReview: row.needs_review !== 0,\n createdAt: row.created_at,\n updatedAt: row.updated_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 } 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 SaveOptionsSchema,\n} from \"../schemas.js\";\nimport type { Memory, MemoryPatch, MemoryRow, MemoryType, SaveOptions } from \"../types.js\";\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 return rowToMemory(updated, projectMap.get(top.id) ?? []);\n }\n\n if (top !== undefined && top.similarity >= 0.75) {\n this.#db.db.prepare(`UPDATE memories SET needs_review = 1 WHERE id = ?`).run(top.id);\n }\n\n const id = randomUUID();\n this.#db.db\n .prepare(\n `INSERT INTO memories (id, content, type, tags, source, access_count, pinned, needs_review, created_at, updated_at)\n VALUES (?, ?, ?, ?, ?, 0, 0, 0, ?, ?)`\n )\n .run(id, content, type, JSON.stringify(tags), sourceHarness ?? null, now, now);\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 } = 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 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 return rowToMemory(updated, projectMap.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 return rows.map((row) => rowToMemory(row, projectMap.get(row.id) ?? []));\n }\n\n stats(): { byType: Record<MemoryType, number>; total: number; needsReview: number } {\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 totals = this.#db.db\n .prepare<[], { total: number; needsReview: number }>(\n `SELECT COUNT(*) as total, SUM(needs_review) as needsReview FROM memories`\n )\n .get() ?? { total: 0, needsReview: 0 };\n\n return {\n byType,\n total: totals.total,\n needsReview: totals.needsReview ?? 0,\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 return rowToMemory(updated, projectMap.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 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, 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, 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 typeWeight * 0.4 + accessCountNorm * 0.3 + recencyNorm * 0.2 + pinned * 0.1;\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): SessionContext {\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 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 return { stats, pinnedGlobal, pinnedProject };\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.6.1",
3
+ "version": "0.7.0",
4
4
  "type": "module",
5
5
  "repository": {
6
6
  "type": "git",
@@ -20,7 +20,8 @@
20
20
  "dependencies": {
21
21
  "@huggingface/transformers": "^4.2.0",
22
22
  "better-sqlite3": "^12.9.0",
23
- "sqlite-vec": "^0.1.9"
23
+ "sqlite-vec": "^0.1.9",
24
+ "zod": "^4.4.3"
24
25
  },
25
26
  "devDependencies": {
26
27
  "@types/better-sqlite3": "^7.6.13",