@membank/core 0.6.0 → 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 +185 -73
- package/dist/index.d.cts +180 -57
- package/dist/index.d.cts.map +1 -1
- package/dist/index.d.mts +180 -57
- package/dist/index.d.mts.map +1 -1
- package/dist/index.mjs +173 -74
- 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,7 @@ 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 = [[1, `
|
|
52
53
|
CREATE TABLE IF NOT EXISTS memories (
|
|
53
54
|
id TEXT PRIMARY KEY,
|
|
54
55
|
content TEXT NOT NULL,
|
|
@@ -143,7 +144,7 @@ var DatabaseManager = class DatabaseManager {
|
|
|
143
144
|
`);
|
|
144
145
|
const row = this.#db.prepare("SELECT value FROM meta WHERE key = 'schema_version'").get();
|
|
145
146
|
const currentVersion = row ? Number.parseInt(row.value, 10) : 0;
|
|
146
|
-
for (const [targetVersion, sql] of MIGRATIONS) if (currentVersion < targetVersion) {
|
|
147
|
+
for (const [targetVersion, sql] of MIGRATIONS$1) if (currentVersion < targetVersion) {
|
|
147
148
|
this.#db.exec(sql);
|
|
148
149
|
this.#db.prepare("INSERT OR REPLACE INTO meta (key, value) VALUES ('schema_version', ?)").run(String(targetVersion));
|
|
149
150
|
}
|
|
@@ -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,16 +295,16 @@ var MemoryRepository = class {
|
|
|
227
295
|
this.#projects = projects;
|
|
228
296
|
}
|
|
229
297
|
async save(options) {
|
|
230
|
-
const { content, type, tags = [],
|
|
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;
|
|
234
|
-
if (
|
|
302
|
+
if (projectScope !== void 0) top = this.#db.db.prepare(`SELECT m.rowid, m.*, (1 - vec_distance_cosine(e.embedding, ?)) AS similarity
|
|
235
303
|
FROM memories m JOIN embeddings e ON e.rowid = m.rowid
|
|
236
304
|
JOIN memory_projects mp ON mp.memory_id = m.id
|
|
237
305
|
JOIN projects p ON p.id = mp.project_id
|
|
238
306
|
WHERE m.type = ? AND p.scope_hash = ?
|
|
239
|
-
ORDER BY similarity DESC LIMIT 1`).get(embeddingBlob, type,
|
|
307
|
+
ORDER BY similarity DESC LIMIT 1`).get(embeddingBlob, type, projectScope.hash);
|
|
240
308
|
else top = this.#db.db.prepare(`SELECT m.rowid, m.*, (1 - vec_distance_cosine(e.embedding, ?)) AS similarity
|
|
241
309
|
FROM memories m JOIN embeddings e ON e.rowid = m.rowid
|
|
242
310
|
WHERE m.type = ?
|
|
@@ -246,41 +314,42 @@ 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)();
|
|
253
321
|
this.#db.db.prepare(`INSERT INTO memories (id, content, type, tags, source, access_count, pinned, needs_review, created_at, updated_at)
|
|
254
322
|
VALUES (?, ?, ?, ?, ?, 0, 0, 0, ?, ?)`).run(id, content, type, JSON.stringify(tags), sourceHarness ?? null, now, now);
|
|
255
323
|
this.#db.db.prepare(`INSERT INTO embeddings (rowid, embedding) SELECT m.rowid, ? FROM memories m WHERE m.id = ?`).run(embeddingBlob, id);
|
|
256
|
-
if (
|
|
257
|
-
const project = this.#projects.upsertByHash(
|
|
324
|
+
if (projectScope !== void 0) {
|
|
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 (
|
|
337
|
+
if (content !== void 0) {
|
|
269
338
|
sets.push("content = ?");
|
|
270
|
-
values.push(
|
|
339
|
+
values.push(content);
|
|
271
340
|
}
|
|
272
|
-
if (
|
|
341
|
+
if (tags !== void 0) {
|
|
273
342
|
sets.push("tags = ?");
|
|
274
|
-
values.push(JSON.stringify(
|
|
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 (
|
|
279
|
-
const embedding = await this.#embedding.embed(
|
|
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)
|
|
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,13 +394,74 @@ 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);
|
|
329
401
|
}
|
|
330
402
|
};
|
|
331
403
|
//#endregion
|
|
404
|
+
//#region src/scope/resolver.ts
|
|
405
|
+
const execFileAsync = (0, node_util.promisify)(node_child_process.execFile);
|
|
406
|
+
function sha256Truncated(input) {
|
|
407
|
+
return (0, node_crypto.createHash)("sha256").update(input).digest("hex").slice(0, 16);
|
|
408
|
+
}
|
|
409
|
+
async function resolveProject() {
|
|
410
|
+
try {
|
|
411
|
+
const { stdout } = await execFileAsync("git", [
|
|
412
|
+
"remote",
|
|
413
|
+
"get-url",
|
|
414
|
+
"origin"
|
|
415
|
+
]);
|
|
416
|
+
const url = stdout.trim();
|
|
417
|
+
if (url) {
|
|
418
|
+
const hash = sha256Truncated(url);
|
|
419
|
+
return {
|
|
420
|
+
hash,
|
|
421
|
+
name: url.split("/").pop()?.replace(/\.git$/, "") ?? hash.slice(0, 8)
|
|
422
|
+
};
|
|
423
|
+
}
|
|
424
|
+
} catch {}
|
|
425
|
+
const cwd = process.cwd();
|
|
426
|
+
const hash = sha256Truncated(cwd);
|
|
427
|
+
return {
|
|
428
|
+
hash,
|
|
429
|
+
name: cwd.split(/[/\\]/).filter(Boolean).pop() ?? hash.slice(0, 8)
|
|
430
|
+
};
|
|
431
|
+
}
|
|
432
|
+
async function resolveScope() {
|
|
433
|
+
try {
|
|
434
|
+
const { stdout } = await execFileAsync("git", [
|
|
435
|
+
"remote",
|
|
436
|
+
"get-url",
|
|
437
|
+
"origin"
|
|
438
|
+
]);
|
|
439
|
+
const url = stdout.trim();
|
|
440
|
+
if (url) return sha256Truncated(url);
|
|
441
|
+
} catch {}
|
|
442
|
+
return sha256Truncated(process.cwd());
|
|
443
|
+
}
|
|
444
|
+
//#endregion
|
|
445
|
+
//#region src/migrations/index.ts
|
|
446
|
+
const MIGRATIONS = [{
|
|
447
|
+
name: "scope-to-projects",
|
|
448
|
+
description: "Rename the auto-migrated project for the current directory from its generic hash-derived name to the resolved repo/directory name."
|
|
449
|
+
}];
|
|
450
|
+
async function runScopeToProjectsMigration(projects) {
|
|
451
|
+
const resolved = await resolveProject();
|
|
452
|
+
const project = projects.getByHash(resolved.hash);
|
|
453
|
+
if (project === void 0) return null;
|
|
454
|
+
const oldName = project.name;
|
|
455
|
+
const memoryCount = projects.countMemories(project.id);
|
|
456
|
+
projects.rename(project.id, resolved.name);
|
|
457
|
+
return {
|
|
458
|
+
migration: "scope-to-projects",
|
|
459
|
+
oldName,
|
|
460
|
+
newName: resolved.name,
|
|
461
|
+
memoryCount
|
|
462
|
+
};
|
|
463
|
+
}
|
|
464
|
+
//#endregion
|
|
332
465
|
//#region src/project/repository.ts
|
|
333
466
|
var ProjectRepository = class {
|
|
334
467
|
#db;
|
|
@@ -339,7 +472,7 @@ var ProjectRepository = class {
|
|
|
339
472
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
340
473
|
const id = (0, node_crypto.randomUUID)();
|
|
341
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);
|
|
342
|
-
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)));
|
|
343
476
|
}
|
|
344
477
|
rename(id, name) {
|
|
345
478
|
const now = (/* @__PURE__ */ new Date()).toISOString();
|
|
@@ -361,6 +494,9 @@ var ProjectRepository = class {
|
|
|
361
494
|
removeAssociation(memoryId, projectId) {
|
|
362
495
|
this.#db.db.prepare(`DELETE FROM memory_projects WHERE memory_id = ? AND project_id = ?`).run(memoryId, projectId);
|
|
363
496
|
}
|
|
497
|
+
countMemories(projectId) {
|
|
498
|
+
return this.#db.db.prepare(`SELECT COUNT(*) AS count FROM memory_projects WHERE project_id = ?`).get(projectId)?.count ?? 0;
|
|
499
|
+
}
|
|
364
500
|
getProjectsForMemories(memoryIds) {
|
|
365
501
|
if (memoryIds.length === 0) return /* @__PURE__ */ new Map();
|
|
366
502
|
const placeholders = memoryIds.map(() => "?").join(",");
|
|
@@ -395,12 +531,13 @@ var QueryEngine = class {
|
|
|
395
531
|
this.#repo = repo;
|
|
396
532
|
}
|
|
397
533
|
async query(options) {
|
|
398
|
-
const { query, type, projectHash, limit = 10 } = options;
|
|
534
|
+
const { query, type, projectHash, limit = 10, includePinned } = QueryOptionsSchema.parse(options);
|
|
399
535
|
const queryEmbedding = await this.#embedding.embed(query);
|
|
400
536
|
const queryBlob = Buffer.from(queryEmbedding.buffer);
|
|
401
537
|
const whereClauses = [];
|
|
402
538
|
const params = [queryBlob];
|
|
403
539
|
let joinClause = "";
|
|
540
|
+
if (!includePinned) whereClauses.push("m.pinned = 0");
|
|
404
541
|
if (type !== void 0) {
|
|
405
542
|
whereClauses.push("m.type = ?");
|
|
406
543
|
params.push(type);
|
|
@@ -441,47 +578,6 @@ var QueryEngine = class {
|
|
|
441
578
|
}
|
|
442
579
|
};
|
|
443
580
|
//#endregion
|
|
444
|
-
//#region src/scope/resolver.ts
|
|
445
|
-
const execFileAsync = (0, node_util.promisify)(node_child_process.execFile);
|
|
446
|
-
function sha256Truncated(input) {
|
|
447
|
-
return (0, node_crypto.createHash)("sha256").update(input).digest("hex").slice(0, 16);
|
|
448
|
-
}
|
|
449
|
-
async function resolveProject() {
|
|
450
|
-
try {
|
|
451
|
-
const { stdout } = await execFileAsync("git", [
|
|
452
|
-
"remote",
|
|
453
|
-
"get-url",
|
|
454
|
-
"origin"
|
|
455
|
-
]);
|
|
456
|
-
const url = stdout.trim();
|
|
457
|
-
if (url) {
|
|
458
|
-
const hash = sha256Truncated(url);
|
|
459
|
-
return {
|
|
460
|
-
hash,
|
|
461
|
-
name: url.split("/").pop()?.replace(/\.git$/, "") ?? hash.slice(0, 8)
|
|
462
|
-
};
|
|
463
|
-
}
|
|
464
|
-
} catch {}
|
|
465
|
-
const cwd = process.cwd();
|
|
466
|
-
const hash = sha256Truncated(cwd);
|
|
467
|
-
return {
|
|
468
|
-
hash,
|
|
469
|
-
name: cwd.split(/[/\\]/).filter(Boolean).pop() ?? hash.slice(0, 8)
|
|
470
|
-
};
|
|
471
|
-
}
|
|
472
|
-
async function resolveScope() {
|
|
473
|
-
try {
|
|
474
|
-
const { stdout } = await execFileAsync("git", [
|
|
475
|
-
"remote",
|
|
476
|
-
"get-url",
|
|
477
|
-
"origin"
|
|
478
|
-
]);
|
|
479
|
-
const url = stdout.trim();
|
|
480
|
-
if (url) return sha256Truncated(url);
|
|
481
|
-
} catch {}
|
|
482
|
-
return sha256Truncated(process.cwd());
|
|
483
|
-
}
|
|
484
|
-
//#endregion
|
|
485
581
|
//#region src/session/builder.ts
|
|
486
582
|
function listMemoryTypes() {
|
|
487
583
|
return [...MEMORY_TYPE_VALUES];
|
|
@@ -501,7 +597,10 @@ var SessionContextBuilder = class {
|
|
|
501
597
|
WHERE p.scope_hash = ? AND m.pinned = 1`).all(projectHash).map((row) => rowToMemory(row, []));
|
|
502
598
|
const typeCounts = this.#db.db.prepare("SELECT type, COUNT(*) as count FROM memories GROUP BY type").all();
|
|
503
599
|
const stats = Object.fromEntries(MEMORY_TYPE_VALUES.map((t) => [t, 0]));
|
|
504
|
-
for (const row of typeCounts)
|
|
600
|
+
for (const row of typeCounts) {
|
|
601
|
+
const parsed = MemoryTypeSchema.safeParse(row.type);
|
|
602
|
+
if (parsed.success) stats[parsed.data] = row.count;
|
|
603
|
+
}
|
|
505
604
|
return {
|
|
506
605
|
stats,
|
|
507
606
|
pinnedGlobal,
|
|
@@ -514,12 +613,25 @@ exports.DatabaseError = DatabaseError;
|
|
|
514
613
|
exports.DatabaseManager = DatabaseManager;
|
|
515
614
|
exports.EmbeddingService = EmbeddingService;
|
|
516
615
|
exports.MEMORY_TYPE_VALUES = MEMORY_TYPE_VALUES;
|
|
616
|
+
exports.MIGRATIONS = MIGRATIONS;
|
|
517
617
|
exports.MembankError = MembankError;
|
|
618
|
+
exports.MemoryPatchSchema = MemoryPatchSchema;
|
|
518
619
|
exports.MemoryRepository = MemoryRepository;
|
|
620
|
+
exports.MemoryRowSchema = MemoryRowSchema;
|
|
621
|
+
exports.MemorySchema = MemorySchema;
|
|
622
|
+
exports.MemoryTypeSchema = MemoryTypeSchema;
|
|
519
623
|
exports.ProjectRepository = ProjectRepository;
|
|
624
|
+
exports.ProjectRowSchema = ProjectRowSchema;
|
|
625
|
+
exports.ProjectSchema = ProjectSchema;
|
|
520
626
|
exports.QueryEngine = QueryEngine;
|
|
627
|
+
exports.QueryOptionsSchema = QueryOptionsSchema;
|
|
628
|
+
exports.SaveOptionsSchema = SaveOptionsSchema;
|
|
521
629
|
exports.SessionContextBuilder = SessionContextBuilder;
|
|
630
|
+
exports.SessionContextSchema = SessionContextSchema;
|
|
631
|
+
exports.TagsJsonSchema = TagsJsonSchema;
|
|
522
632
|
exports.listMemoryTypes = listMemoryTypes;
|
|
523
633
|
exports.resolveProject = resolveProject;
|
|
524
634
|
exports.resolveScope = resolveScope;
|
|
525
635
|
exports.rowToMemory = rowToMemory;
|
|
636
|
+
exports.rowToProject = rowToProject;
|
|
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,62 +22,172 @@ declare class DatabaseManager {
|
|
|
21
22
|
close(): void;
|
|
22
23
|
}
|
|
23
24
|
//#endregion
|
|
24
|
-
//#region src/
|
|
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
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
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>;
|
|
65
187
|
//#endregion
|
|
66
188
|
//#region src/db/row-types.d.ts
|
|
67
|
-
interface MemoryRow {
|
|
68
|
-
id: string;
|
|
69
|
-
content: string;
|
|
70
|
-
type: string;
|
|
71
|
-
tags: string;
|
|
72
|
-
source: string | null;
|
|
73
|
-
access_count: number;
|
|
74
|
-
pinned: number;
|
|
75
|
-
needs_review: number;
|
|
76
|
-
created_at: string;
|
|
77
|
-
updated_at: string;
|
|
78
|
-
}
|
|
79
189
|
declare function rowToMemory(row: MemoryRow, projects: Project[]): Memory;
|
|
190
|
+
declare function rowToProject(row: ProjectRow): Project;
|
|
80
191
|
//#endregion
|
|
81
192
|
//#region src/embedding/service.d.ts
|
|
82
193
|
type ProgressCallback = (progress: {
|
|
@@ -102,6 +213,7 @@ declare class ProjectRepository {
|
|
|
102
213
|
getByHash(hash: string): Project | undefined;
|
|
103
214
|
addAssociation(memoryId: string, projectId: string): void;
|
|
104
215
|
removeAssociation(memoryId: string, projectId: string): void;
|
|
216
|
+
countMemories(projectId: string): number;
|
|
105
217
|
getProjectsForMemories(memoryIds: string[]): Map<string, Project[]>;
|
|
106
218
|
}
|
|
107
219
|
//#endregion
|
|
@@ -110,10 +222,7 @@ declare class MemoryRepository {
|
|
|
110
222
|
#private;
|
|
111
223
|
constructor(db: DatabaseManager, embeddingService: EmbeddingService, projects: ProjectRepository);
|
|
112
224
|
save(options: SaveOptions): Promise<Memory>;
|
|
113
|
-
update(id: string, patch:
|
|
114
|
-
content?: string;
|
|
115
|
-
tags?: string[];
|
|
116
|
-
}): Promise<Memory>;
|
|
225
|
+
update(id: string, patch: MemoryPatch): Promise<Memory>;
|
|
117
226
|
delete(id: string): Promise<void>;
|
|
118
227
|
list(opts?: {
|
|
119
228
|
type?: MemoryType;
|
|
@@ -128,6 +237,20 @@ declare class MemoryRepository {
|
|
|
128
237
|
incrementAccessCount(id: string): void;
|
|
129
238
|
}
|
|
130
239
|
//#endregion
|
|
240
|
+
//#region src/migrations/index.d.ts
|
|
241
|
+
interface MigrationMeta {
|
|
242
|
+
name: string;
|
|
243
|
+
description: string;
|
|
244
|
+
}
|
|
245
|
+
interface ScopeToProjectsResult {
|
|
246
|
+
migration: "scope-to-projects";
|
|
247
|
+
oldName: string;
|
|
248
|
+
newName: string;
|
|
249
|
+
memoryCount: number;
|
|
250
|
+
}
|
|
251
|
+
declare const MIGRATIONS: MigrationMeta[];
|
|
252
|
+
declare function runScopeToProjectsMigration(projects: ProjectRepository): Promise<ScopeToProjectsResult | null>;
|
|
253
|
+
//#endregion
|
|
131
254
|
//#region src/query/engine.d.ts
|
|
132
255
|
declare class QueryEngine {
|
|
133
256
|
#private;
|
|
@@ -152,5 +275,5 @@ declare class SessionContextBuilder {
|
|
|
152
275
|
getSessionContext(projectHash: string): SessionContext;
|
|
153
276
|
}
|
|
154
277
|
//#endregion
|
|
155
|
-
export { DatabaseError, DatabaseManager, EmbeddingService, MEMORY_TYPE_VALUES, MembankError, Memory, MemoryRepository,
|
|
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 };
|
|
156
279
|
//# sourceMappingURL=index.d.cts.map
|