@membank/core 0.6.1 → 0.8.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 +230 -40
- package/dist/index.d.cts +233 -61
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +233 -61
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +217 -41
- package/dist/index.mjs.map +1 -1
- package/package.json +3 -2
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");
|
|
@@ -48,7 +49,8 @@ var DatabaseError = class extends MembankError {
|
|
|
48
49
|
//#endregion
|
|
49
50
|
//#region src/db/manager.ts
|
|
50
51
|
const DEFAULT_DB_PATH = (0, node_path.join)((0, node_os.homedir)(), ".membank", "memory.db");
|
|
51
|
-
const MIGRATIONS$1 = [
|
|
52
|
+
const MIGRATIONS$1 = [
|
|
53
|
+
[1, `
|
|
52
54
|
CREATE TABLE IF NOT EXISTS memories (
|
|
53
55
|
id TEXT PRIMARY KEY,
|
|
54
56
|
content TEXT NOT NULL,
|
|
@@ -66,7 +68,8 @@ CREATE TABLE IF NOT EXISTS memories (
|
|
|
66
68
|
CREATE VIRTUAL TABLE IF NOT EXISTS embeddings USING vec0(
|
|
67
69
|
embedding FLOAT[384]
|
|
68
70
|
);
|
|
69
|
-
`],
|
|
71
|
+
`],
|
|
72
|
+
[2, `
|
|
70
73
|
CREATE TABLE IF NOT EXISTS projects (
|
|
71
74
|
id TEXT PRIMARY KEY,
|
|
72
75
|
name TEXT NOT NULL,
|
|
@@ -99,7 +102,25 @@ JOIN projects p ON p.scope_hash = m.scope
|
|
|
99
102
|
WHERE m.scope != 'global';
|
|
100
103
|
|
|
101
104
|
ALTER TABLE memories DROP COLUMN scope;
|
|
102
|
-
`]
|
|
105
|
+
`],
|
|
106
|
+
[3, `
|
|
107
|
+
CREATE TABLE IF NOT EXISTS memory_review_events (
|
|
108
|
+
id TEXT PRIMARY KEY,
|
|
109
|
+
memory_id TEXT NOT NULL REFERENCES memories(id) ON DELETE CASCADE,
|
|
110
|
+
conflicting_memory_id TEXT REFERENCES memories(id) ON DELETE SET NULL,
|
|
111
|
+
similarity REAL NOT NULL,
|
|
112
|
+
conflict_content_snapshot TEXT NOT NULL,
|
|
113
|
+
reason TEXT NOT NULL,
|
|
114
|
+
created_at TEXT NOT NULL,
|
|
115
|
+
resolved_at TEXT
|
|
116
|
+
);
|
|
117
|
+
|
|
118
|
+
CREATE INDEX IF NOT EXISTS idx_review_events_memory_open
|
|
119
|
+
ON memory_review_events(memory_id) WHERE resolved_at IS NULL;
|
|
120
|
+
|
|
121
|
+
ALTER TABLE memories DROP COLUMN needs_review;
|
|
122
|
+
`]
|
|
123
|
+
];
|
|
103
124
|
var DatabaseManager = class DatabaseManager {
|
|
104
125
|
#db;
|
|
105
126
|
constructor(db) {
|
|
@@ -156,22 +177,131 @@ var DatabaseManager = class DatabaseManager {
|
|
|
156
177
|
}
|
|
157
178
|
};
|
|
158
179
|
//#endregion
|
|
180
|
+
//#region src/schemas.ts
|
|
181
|
+
const MEMORY_TYPE_VALUES = [
|
|
182
|
+
"correction",
|
|
183
|
+
"preference",
|
|
184
|
+
"decision",
|
|
185
|
+
"learning",
|
|
186
|
+
"fact"
|
|
187
|
+
];
|
|
188
|
+
const MemoryTypeSchema = zod.z.enum(MEMORY_TYPE_VALUES);
|
|
189
|
+
const TagsJsonSchema = zod.z.array(zod.z.string());
|
|
190
|
+
const ProjectSchema = zod.z.object({
|
|
191
|
+
id: zod.z.string(),
|
|
192
|
+
name: zod.z.string(),
|
|
193
|
+
scopeHash: zod.z.string(),
|
|
194
|
+
createdAt: zod.z.string(),
|
|
195
|
+
updatedAt: zod.z.string()
|
|
196
|
+
});
|
|
197
|
+
const ReviewReasonSchema = zod.z.enum(["similarity_dedup"]);
|
|
198
|
+
const ReviewEventSchema = zod.z.object({
|
|
199
|
+
id: zod.z.string(),
|
|
200
|
+
memoryId: zod.z.string(),
|
|
201
|
+
conflictingMemoryId: zod.z.string().nullable(),
|
|
202
|
+
similarity: zod.z.number(),
|
|
203
|
+
conflictContentSnapshot: zod.z.string(),
|
|
204
|
+
reason: ReviewReasonSchema,
|
|
205
|
+
createdAt: zod.z.string(),
|
|
206
|
+
resolvedAt: zod.z.string().nullable()
|
|
207
|
+
});
|
|
208
|
+
const ReviewEventRowSchema = zod.z.object({
|
|
209
|
+
id: zod.z.string(),
|
|
210
|
+
memory_id: zod.z.string(),
|
|
211
|
+
conflicting_memory_id: zod.z.string().nullable(),
|
|
212
|
+
similarity: zod.z.number(),
|
|
213
|
+
conflict_content_snapshot: zod.z.string(),
|
|
214
|
+
reason: ReviewReasonSchema,
|
|
215
|
+
created_at: zod.z.string(),
|
|
216
|
+
resolved_at: zod.z.string().nullable()
|
|
217
|
+
});
|
|
218
|
+
const MemorySchema = zod.z.object({
|
|
219
|
+
id: zod.z.string(),
|
|
220
|
+
content: zod.z.string(),
|
|
221
|
+
type: MemoryTypeSchema,
|
|
222
|
+
tags: zod.z.array(zod.z.string()),
|
|
223
|
+
projects: zod.z.array(ProjectSchema),
|
|
224
|
+
sourceHarness: zod.z.string().nullable(),
|
|
225
|
+
accessCount: zod.z.number().int().nonnegative(),
|
|
226
|
+
pinned: zod.z.boolean(),
|
|
227
|
+
reviewEvents: zod.z.array(ReviewEventSchema),
|
|
228
|
+
createdAt: zod.z.string(),
|
|
229
|
+
updatedAt: zod.z.string()
|
|
230
|
+
});
|
|
231
|
+
const QueryOptionsSchema = zod.z.object({
|
|
232
|
+
query: zod.z.string().min(1),
|
|
233
|
+
type: MemoryTypeSchema.optional(),
|
|
234
|
+
projectHash: zod.z.string().optional(),
|
|
235
|
+
limit: zod.z.number().int().positive().optional(),
|
|
236
|
+
includePinned: zod.z.boolean().optional()
|
|
237
|
+
});
|
|
238
|
+
const SaveOptionsSchema = zod.z.object({
|
|
239
|
+
content: zod.z.string().min(1),
|
|
240
|
+
type: MemoryTypeSchema,
|
|
241
|
+
tags: zod.z.array(zod.z.string()).optional(),
|
|
242
|
+
projectScope: zod.z.object({
|
|
243
|
+
hash: zod.z.string(),
|
|
244
|
+
name: zod.z.string()
|
|
245
|
+
}).optional(),
|
|
246
|
+
sourceHarness: zod.z.string().optional()
|
|
247
|
+
});
|
|
248
|
+
const MemoryPatchSchema = zod.z.object({
|
|
249
|
+
content: zod.z.string().min(1).optional(),
|
|
250
|
+
tags: zod.z.array(zod.z.string()).optional()
|
|
251
|
+
});
|
|
252
|
+
const SessionContextSchema = zod.z.object({
|
|
253
|
+
stats: zod.z.record(MemoryTypeSchema, zod.z.number()),
|
|
254
|
+
pinnedGlobal: zod.z.array(MemorySchema),
|
|
255
|
+
pinnedProject: zod.z.array(MemorySchema)
|
|
256
|
+
});
|
|
257
|
+
const MemoryRowSchema = zod.z.object({
|
|
258
|
+
id: zod.z.string(),
|
|
259
|
+
content: zod.z.string(),
|
|
260
|
+
type: zod.z.string(),
|
|
261
|
+
tags: zod.z.string(),
|
|
262
|
+
source: zod.z.string().nullable(),
|
|
263
|
+
access_count: zod.z.number(),
|
|
264
|
+
pinned: zod.z.number(),
|
|
265
|
+
created_at: zod.z.string(),
|
|
266
|
+
updated_at: zod.z.string()
|
|
267
|
+
});
|
|
268
|
+
const ProjectRowSchema = zod.z.object({
|
|
269
|
+
id: zod.z.string(),
|
|
270
|
+
name: zod.z.string(),
|
|
271
|
+
scope_hash: zod.z.string(),
|
|
272
|
+
created_at: zod.z.string(),
|
|
273
|
+
updated_at: zod.z.string()
|
|
274
|
+
});
|
|
275
|
+
//#endregion
|
|
159
276
|
//#region src/db/row-types.ts
|
|
160
|
-
function rowToMemory(row, projects) {
|
|
277
|
+
function rowToMemory(row, projects, reviewEvents = []) {
|
|
161
278
|
return {
|
|
162
279
|
id: row.id,
|
|
163
280
|
content: row.content,
|
|
164
|
-
type: row.type,
|
|
165
|
-
tags: JSON.parse(row.tags),
|
|
281
|
+
type: MemoryTypeSchema.parse(row.type),
|
|
282
|
+
tags: TagsJsonSchema.parse(JSON.parse(row.tags)),
|
|
166
283
|
projects,
|
|
167
284
|
sourceHarness: row.source,
|
|
168
285
|
accessCount: row.access_count,
|
|
169
286
|
pinned: row.pinned !== 0,
|
|
170
|
-
|
|
287
|
+
reviewEvents,
|
|
171
288
|
createdAt: row.created_at,
|
|
172
289
|
updatedAt: row.updated_at
|
|
173
290
|
};
|
|
174
291
|
}
|
|
292
|
+
function rowToReviewEvent(row) {
|
|
293
|
+
const parsed = ReviewEventRowSchema.parse(row);
|
|
294
|
+
return {
|
|
295
|
+
id: parsed.id,
|
|
296
|
+
memoryId: parsed.memory_id,
|
|
297
|
+
conflictingMemoryId: parsed.conflicting_memory_id,
|
|
298
|
+
similarity: parsed.similarity,
|
|
299
|
+
conflictContentSnapshot: parsed.conflict_content_snapshot,
|
|
300
|
+
reason: parsed.reason,
|
|
301
|
+
createdAt: parsed.created_at,
|
|
302
|
+
resolvedAt: parsed.resolved_at
|
|
303
|
+
};
|
|
304
|
+
}
|
|
175
305
|
function rowToProject(row) {
|
|
176
306
|
return {
|
|
177
307
|
id: row.id,
|
|
@@ -207,15 +337,6 @@ var EmbeddingService = class {
|
|
|
207
337
|
}
|
|
208
338
|
};
|
|
209
339
|
//#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
340
|
//#region src/memory/repository.ts
|
|
220
341
|
var MemoryRepository = class {
|
|
221
342
|
#db;
|
|
@@ -227,7 +348,7 @@ var MemoryRepository = class {
|
|
|
227
348
|
this.#projects = projects;
|
|
228
349
|
}
|
|
229
350
|
async save(options) {
|
|
230
|
-
const { content, type, tags = [], projectScope, sourceHarness } = options;
|
|
351
|
+
const { content, type, tags = [], projectScope, sourceHarness } = SaveOptionsSchema.parse(options);
|
|
231
352
|
const embedding = await this.#embedding.embed(content);
|
|
232
353
|
const embeddingBlob = Buffer.from(embedding.buffer);
|
|
233
354
|
let top;
|
|
@@ -246,41 +367,50 @@ var MemoryRepository = class {
|
|
|
246
367
|
if (top !== void 0 && top.similarity > .92) {
|
|
247
368
|
this.#db.db.prepare(`UPDATE memories SET content = ?, updated_at = ? WHERE id = ?`).run(content, now, top.id);
|
|
248
369
|
this.#db.db.prepare(`UPDATE embeddings SET embedding = ? WHERE rowid = ?`).run(embeddingBlob, top.rowid);
|
|
249
|
-
|
|
370
|
+
const updated = MemoryRowSchema.parse(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(top.id));
|
|
371
|
+
const projectMap = this.#projects.getProjectsForMemories([top.id]);
|
|
372
|
+
const events = this.#getEventsForMemories([top.id]);
|
|
373
|
+
return rowToMemory(updated, projectMap.get(top.id) ?? [], events.get(top.id) ?? []);
|
|
250
374
|
}
|
|
251
|
-
if (top !== void 0 && top.similarity >= .75) this.#db.db.prepare(`UPDATE memories SET needs_review = 1 WHERE id = ?`).run(top.id);
|
|
252
375
|
const id = (0, node_crypto.randomUUID)();
|
|
253
|
-
this.#db.db.prepare(`INSERT INTO memories (id, content, type, tags, source, access_count, pinned,
|
|
254
|
-
VALUES (?, ?, ?, ?, ?, 0, 0,
|
|
376
|
+
this.#db.db.prepare(`INSERT INTO memories (id, content, type, tags, source, access_count, pinned, created_at, updated_at)
|
|
377
|
+
VALUES (?, ?, ?, ?, ?, 0, 0, ?, ?)`).run(id, content, type, JSON.stringify(tags), sourceHarness ?? null, now, now);
|
|
378
|
+
if (top !== void 0 && top.similarity >= .75) this.#db.db.prepare(`INSERT INTO memory_review_events
|
|
379
|
+
(id, memory_id, conflicting_memory_id, similarity, conflict_content_snapshot, reason, created_at)
|
|
380
|
+
VALUES (?, ?, ?, ?, ?, 'similarity_dedup', ?)`).run((0, node_crypto.randomUUID)(), top.id, id, top.similarity, content, now);
|
|
255
381
|
this.#db.db.prepare(`INSERT INTO embeddings (rowid, embedding) SELECT m.rowid, ? FROM memories m WHERE m.id = ?`).run(embeddingBlob, id);
|
|
256
382
|
if (projectScope !== void 0) {
|
|
257
383
|
const project = this.#projects.upsertByHash(projectScope.hash, projectScope.name);
|
|
258
384
|
this.#projects.addAssociation(id, project.id);
|
|
259
385
|
}
|
|
260
|
-
return rowToMemory(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id), this.#projects.getProjectsForMemories([id]).get(id) ?? []);
|
|
386
|
+
return rowToMemory(MemoryRowSchema.parse(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id)), this.#projects.getProjectsForMemories([id]).get(id) ?? [], []);
|
|
261
387
|
}
|
|
262
388
|
async update(id, patch) {
|
|
389
|
+
const { content, tags } = MemoryPatchSchema.parse(patch);
|
|
263
390
|
const existing = this.#db.db.prepare(`SELECT m.rowid, m.* FROM memories m WHERE m.id = ?`).get(id);
|
|
264
391
|
if (existing === void 0) throw new Error(`Memory not found: ${id}`);
|
|
265
392
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
266
393
|
const sets = ["updated_at = ?"];
|
|
267
394
|
const values = [now];
|
|
268
|
-
if (
|
|
395
|
+
if (content !== void 0) {
|
|
269
396
|
sets.push("content = ?");
|
|
270
|
-
values.push(
|
|
397
|
+
values.push(content);
|
|
271
398
|
}
|
|
272
|
-
if (
|
|
399
|
+
if (tags !== void 0) {
|
|
273
400
|
sets.push("tags = ?");
|
|
274
|
-
values.push(JSON.stringify(
|
|
401
|
+
values.push(JSON.stringify(tags));
|
|
275
402
|
}
|
|
276
403
|
values.push(id);
|
|
277
404
|
this.#db.db.prepare(`UPDATE memories SET ${sets.join(", ")} WHERE id = ?`).run(...values);
|
|
278
|
-
if (
|
|
279
|
-
const embedding = await this.#embedding.embed(
|
|
405
|
+
if (content !== void 0) {
|
|
406
|
+
const embedding = await this.#embedding.embed(content);
|
|
280
407
|
const embeddingBlob = Buffer.from(embedding.buffer);
|
|
281
408
|
this.#db.db.prepare(`UPDATE embeddings SET embedding = ? WHERE rowid = ?`).run(embeddingBlob, existing.rowid);
|
|
282
409
|
}
|
|
283
|
-
|
|
410
|
+
const updated = MemoryRowSchema.parse(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id));
|
|
411
|
+
const projectMap = this.#projects.getProjectsForMemories([id]);
|
|
412
|
+
const events = this.#getEventsForMemories([id]);
|
|
413
|
+
return rowToMemory(updated, projectMap.get(id) ?? [], events.get(id) ?? []);
|
|
284
414
|
}
|
|
285
415
|
delete(id) {
|
|
286
416
|
const row = this.#db.db.prepare(`SELECT rowid FROM memories WHERE id = ?`).get(id);
|
|
@@ -302,27 +432,69 @@ var MemoryRepository = class {
|
|
|
302
432
|
if (rows.length === 0) return [];
|
|
303
433
|
const ids = rows.map((r) => r.id);
|
|
304
434
|
const projectMap = this.#projects.getProjectsForMemories(ids);
|
|
305
|
-
|
|
435
|
+
const eventMap = this.#getEventsForMemories(ids);
|
|
436
|
+
return rows.map((row) => rowToMemory(row, projectMap.get(row.id) ?? [], eventMap.get(row.id) ?? []));
|
|
437
|
+
}
|
|
438
|
+
listFlagged() {
|
|
439
|
+
const rows = this.#db.db.prepare(`SELECT * FROM memories
|
|
440
|
+
WHERE EXISTS (
|
|
441
|
+
SELECT 1 FROM memory_review_events e
|
|
442
|
+
WHERE e.memory_id = memories.id AND e.resolved_at IS NULL
|
|
443
|
+
)
|
|
444
|
+
ORDER BY created_at DESC`).all();
|
|
445
|
+
if (rows.length === 0) return [];
|
|
446
|
+
const ids = rows.map((r) => r.id);
|
|
447
|
+
const projectMap = this.#projects.getProjectsForMemories(ids);
|
|
448
|
+
const eventMap = this.#getEventsForMemories(ids, { unresolvedOnly: true });
|
|
449
|
+
return rows.map((row) => rowToMemory(row, projectMap.get(row.id) ?? [], eventMap.get(row.id) ?? []));
|
|
450
|
+
}
|
|
451
|
+
listReviewEvents(memoryId, opts) {
|
|
452
|
+
const where = opts?.unresolvedOnly === true ? "WHERE memory_id = ? AND resolved_at IS NULL" : "WHERE memory_id = ?";
|
|
453
|
+
return this.#db.db.prepare(`SELECT * FROM memory_review_events ${where} ORDER BY created_at DESC`).all(memoryId).map((r) => rowToReviewEvent(ReviewEventRowSchema.parse(r)));
|
|
454
|
+
}
|
|
455
|
+
resolveReviewEvents(memoryId) {
|
|
456
|
+
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
457
|
+
this.#db.db.prepare(`UPDATE memory_review_events SET resolved_at = ? WHERE memory_id = ? AND resolved_at IS NULL`).run(now, memoryId);
|
|
458
|
+
}
|
|
459
|
+
#getEventsForMemories(ids, opts) {
|
|
460
|
+
if (ids.length === 0) return /* @__PURE__ */ new Map();
|
|
461
|
+
const placeholders = ids.map(() => "?").join(", ");
|
|
462
|
+
const unresolvedClause = opts?.unresolvedOnly === true ? "AND resolved_at IS NULL" : "";
|
|
463
|
+
const rows = this.#db.db.prepare(`SELECT * FROM memory_review_events
|
|
464
|
+
WHERE memory_id IN (${placeholders}) ${unresolvedClause}
|
|
465
|
+
ORDER BY created_at DESC`).all(...ids);
|
|
466
|
+
const map = /* @__PURE__ */ new Map();
|
|
467
|
+
for (const row of rows) {
|
|
468
|
+
const event = rowToReviewEvent(ReviewEventRowSchema.parse(row));
|
|
469
|
+
const existing = map.get(event.memoryId) ?? [];
|
|
470
|
+
existing.push(event);
|
|
471
|
+
map.set(event.memoryId, existing);
|
|
472
|
+
}
|
|
473
|
+
return map;
|
|
306
474
|
}
|
|
307
475
|
stats() {
|
|
308
476
|
const byType = Object.fromEntries(MEMORY_TYPE_VALUES.map((t) => [t, 0]));
|
|
309
477
|
const typeRows = this.#db.db.prepare(`SELECT type, COUNT(*) as count FROM memories GROUP BY type`).all();
|
|
310
|
-
for (const row of typeRows)
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
};
|
|
478
|
+
for (const row of typeRows) {
|
|
479
|
+
const parsed = MemoryTypeSchema.safeParse(row.type);
|
|
480
|
+
if (parsed.success) byType[parsed.data] = row.count;
|
|
481
|
+
}
|
|
482
|
+
const totals = this.#db.db.prepare(`SELECT COUNT(*) as total FROM memories`).get() ?? { total: 0 };
|
|
483
|
+
const reviewRow = this.#db.db.prepare(`SELECT COUNT(DISTINCT memory_id) as needsReview FROM memory_review_events WHERE resolved_at IS NULL`).get() ?? { needsReview: 0 };
|
|
315
484
|
return {
|
|
316
485
|
byType,
|
|
317
486
|
total: totals.total,
|
|
318
|
-
needsReview:
|
|
487
|
+
needsReview: reviewRow.needsReview
|
|
319
488
|
};
|
|
320
489
|
}
|
|
321
490
|
setPin(id, pinned) {
|
|
322
491
|
if (this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id) === void 0) throw new Error(`Memory not found: ${id}`);
|
|
323
492
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
324
493
|
this.#db.db.prepare(`UPDATE memories SET pinned = ?, updated_at = ? WHERE id = ?`).run(pinned ? 1 : 0, now, id);
|
|
325
|
-
|
|
494
|
+
const updated = MemoryRowSchema.parse(this.#db.db.prepare(`SELECT * FROM memories WHERE id = ?`).get(id));
|
|
495
|
+
const projectMap = this.#projects.getProjectsForMemories([id]);
|
|
496
|
+
const events = this.#getEventsForMemories([id]);
|
|
497
|
+
return rowToMemory(updated, projectMap.get(id) ?? [], events.get(id) ?? []);
|
|
326
498
|
}
|
|
327
499
|
incrementAccessCount(id) {
|
|
328
500
|
this.#db.db.prepare(`UPDATE memories SET access_count = access_count + 1 WHERE id = ?`).run(id);
|
|
@@ -400,7 +572,7 @@ var ProjectRepository = class {
|
|
|
400
572
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
401
573
|
const id = (0, node_crypto.randomUUID)();
|
|
402
574
|
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));
|
|
575
|
+
return rowToProject(ProjectRowSchema.parse(this.#db.db.prepare(`SELECT * FROM projects WHERE scope_hash = ?`).get(hash)));
|
|
404
576
|
}
|
|
405
577
|
rename(id, name) {
|
|
406
578
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -459,12 +631,13 @@ var QueryEngine = class {
|
|
|
459
631
|
this.#repo = repo;
|
|
460
632
|
}
|
|
461
633
|
async query(options) {
|
|
462
|
-
const { query, type, projectHash, limit = 10 } = options;
|
|
634
|
+
const { query, type, projectHash, limit = 10, includePinned } = QueryOptionsSchema.parse(options);
|
|
463
635
|
const queryEmbedding = await this.#embedding.embed(query);
|
|
464
636
|
const queryBlob = Buffer.from(queryEmbedding.buffer);
|
|
465
637
|
const whereClauses = [];
|
|
466
638
|
const params = [queryBlob];
|
|
467
639
|
let joinClause = "";
|
|
640
|
+
if (!includePinned) whereClauses.push("m.pinned = 0");
|
|
468
641
|
if (type !== void 0) {
|
|
469
642
|
whereClauses.push("m.type = ?");
|
|
470
643
|
params.push(type);
|
|
@@ -524,7 +697,10 @@ var SessionContextBuilder = class {
|
|
|
524
697
|
WHERE p.scope_hash = ? AND m.pinned = 1`).all(projectHash).map((row) => rowToMemory(row, []));
|
|
525
698
|
const typeCounts = this.#db.db.prepare("SELECT type, COUNT(*) as count FROM memories GROUP BY type").all();
|
|
526
699
|
const stats = Object.fromEntries(MEMORY_TYPE_VALUES.map((t) => [t, 0]));
|
|
527
|
-
for (const row of typeCounts)
|
|
700
|
+
for (const row of typeCounts) {
|
|
701
|
+
const parsed = MemoryTypeSchema.safeParse(row.type);
|
|
702
|
+
if (parsed.success) stats[parsed.data] = row.count;
|
|
703
|
+
}
|
|
528
704
|
return {
|
|
529
705
|
stats,
|
|
530
706
|
pinnedGlobal,
|
|
@@ -539,12 +715,26 @@ exports.EmbeddingService = EmbeddingService;
|
|
|
539
715
|
exports.MEMORY_TYPE_VALUES = MEMORY_TYPE_VALUES;
|
|
540
716
|
exports.MIGRATIONS = MIGRATIONS;
|
|
541
717
|
exports.MembankError = MembankError;
|
|
718
|
+
exports.MemoryPatchSchema = MemoryPatchSchema;
|
|
542
719
|
exports.MemoryRepository = MemoryRepository;
|
|
720
|
+
exports.MemoryRowSchema = MemoryRowSchema;
|
|
721
|
+
exports.MemorySchema = MemorySchema;
|
|
722
|
+
exports.MemoryTypeSchema = MemoryTypeSchema;
|
|
543
723
|
exports.ProjectRepository = ProjectRepository;
|
|
724
|
+
exports.ProjectRowSchema = ProjectRowSchema;
|
|
725
|
+
exports.ProjectSchema = ProjectSchema;
|
|
544
726
|
exports.QueryEngine = QueryEngine;
|
|
727
|
+
exports.QueryOptionsSchema = QueryOptionsSchema;
|
|
728
|
+
exports.ReviewEventRowSchema = ReviewEventRowSchema;
|
|
729
|
+
exports.ReviewEventSchema = ReviewEventSchema;
|
|
730
|
+
exports.ReviewReasonSchema = ReviewReasonSchema;
|
|
731
|
+
exports.SaveOptionsSchema = SaveOptionsSchema;
|
|
545
732
|
exports.SessionContextBuilder = SessionContextBuilder;
|
|
733
|
+
exports.SessionContextSchema = SessionContextSchema;
|
|
734
|
+
exports.TagsJsonSchema = TagsJsonSchema;
|
|
546
735
|
exports.listMemoryTypes = listMemoryTypes;
|
|
547
736
|
exports.resolveProject = resolveProject;
|
|
548
737
|
exports.resolveScope = resolveScope;
|
|
549
738
|
exports.rowToMemory = rowToMemory;
|
|
739
|
+
exports.rowToProject = rowToProject;
|
|
550
740
|
exports.runScopeToProjectsMigration = runScopeToProjectsMigration;
|