@hasna/mementos 0.14.63 → 0.14.65
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/cli/commands/agent.d.ts.map +1 -1
- package/dist/cli/commands/io-clean.d.ts.map +1 -1
- package/dist/cli/commands/system-doctor.d.ts.map +1 -1
- package/dist/cli/helpers.d.ts.map +1 -1
- package/dist/cli/index.js +182 -33
- package/dist/db/entities.d.ts.map +1 -1
- package/dist/index.js +36 -15
- package/dist/lib/retention.d.ts.map +1 -1
- package/dist/mcp/index.js +36 -15
- package/dist/server/index.js +204 -17
- package/dist/server/router.d.ts.map +1 -1
- package/package.json +1 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,
|
|
1
|
+
{"version":3,"file":"agent.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/agent.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAgBzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAkN5D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"io-clean.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/io-clean.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"io-clean.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/io-clean.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmCzC,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwC3D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/system-doctor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;
|
|
1
|
+
{"version":3,"file":"system-doctor.d.ts","sourceRoot":"","sources":["../../../src/cli/commands/system-doctor.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AA2CzC,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAwP5D"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/cli/helpers.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AACzC,OAAO,KAAK,EACV,MAAM,EACN,cAAc,EACd,WAAW,EAEZ,MAAM,mBAAmB,CAAC;AAC3B,OAAO,KAAK,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAC;AAM5D,wBAAgB,iBAAiB,IAAI,MAAM,CAe1C;AAsBD,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,CAAC,CAAC,EAAE,MAAM,KAAK,MAAM,CAKzE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,WAAW,GAAG,MAAM,CAErD;AAED,wBAAgB,aAAa,CAAC,QAAQ,EAAE,cAAc,GAAG,MAAM,CAE9D;AAED,wBAAgB,eAAe,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE1D;AAaD,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAGpD;AAED,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,CAAC,EAAE,UAAU,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"helpers.d.ts","sourceRoot":"","sources":["../../src/cli/helpers.ts"],"names":[],"mappings":"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"}
|
package/dist/cli/index.js
CHANGED
|
@@ -5422,7 +5422,8 @@ function getEntity(id, db) {
|
|
|
5422
5422
|
return data;
|
|
5423
5423
|
}
|
|
5424
5424
|
const d = db || getDatabase();
|
|
5425
|
-
const
|
|
5425
|
+
const resolvedId = resolvePartialId(d, "entities", id) ?? id;
|
|
5426
|
+
const row = d.query("SELECT * FROM entities WHERE id = ?").get(resolvedId);
|
|
5426
5427
|
if (!row)
|
|
5427
5428
|
throw new EntityNotFoundError(id);
|
|
5428
5429
|
return parseEntityRow(row);
|
|
@@ -5517,19 +5518,39 @@ function mergeEntities(sourceId, targetId, db) {
|
|
|
5517
5518
|
return data;
|
|
5518
5519
|
}
|
|
5519
5520
|
const d = db || getDatabase();
|
|
5520
|
-
getEntity(sourceId, d);
|
|
5521
|
-
getEntity(targetId, d);
|
|
5522
|
-
d.run(`
|
|
5523
|
-
|
|
5524
|
-
|
|
5525
|
-
|
|
5526
|
-
|
|
5527
|
-
|
|
5528
|
-
|
|
5529
|
-
|
|
5530
|
-
d.run(
|
|
5531
|
-
d.run(
|
|
5532
|
-
|
|
5521
|
+
const src = getEntity(sourceId, d).id;
|
|
5522
|
+
const tgt = getEntity(targetId, d).id;
|
|
5523
|
+
d.run(`DELETE FROM relations
|
|
5524
|
+
WHERE source_entity_id = ?
|
|
5525
|
+
AND EXISTS (
|
|
5526
|
+
SELECT 1 FROM relations e
|
|
5527
|
+
WHERE e.source_entity_id = ?
|
|
5528
|
+
AND e.target_entity_id = relations.target_entity_id
|
|
5529
|
+
AND e.relation_type = relations.relation_type
|
|
5530
|
+
)`, [src, tgt]);
|
|
5531
|
+
d.run(`UPDATE relations SET source_entity_id = ? WHERE source_entity_id = ?`, [tgt, src]);
|
|
5532
|
+
d.run(`DELETE FROM relations
|
|
5533
|
+
WHERE target_entity_id = ?
|
|
5534
|
+
AND EXISTS (
|
|
5535
|
+
SELECT 1 FROM relations e
|
|
5536
|
+
WHERE e.target_entity_id = ?
|
|
5537
|
+
AND e.source_entity_id = relations.source_entity_id
|
|
5538
|
+
AND e.relation_type = relations.relation_type
|
|
5539
|
+
)`, [src, tgt]);
|
|
5540
|
+
d.run(`UPDATE relations SET target_entity_id = ? WHERE target_entity_id = ?`, [tgt, src]);
|
|
5541
|
+
d.run("DELETE FROM relations WHERE source_entity_id = ? OR target_entity_id = ?", [src, src]);
|
|
5542
|
+
d.run(`DELETE FROM entity_memories
|
|
5543
|
+
WHERE entity_id = ?
|
|
5544
|
+
AND EXISTS (
|
|
5545
|
+
SELECT 1 FROM entity_memories e
|
|
5546
|
+
WHERE e.entity_id = ?
|
|
5547
|
+
AND e.memory_id = entity_memories.memory_id
|
|
5548
|
+
)`, [src, tgt]);
|
|
5549
|
+
d.run(`UPDATE entity_memories SET entity_id = ? WHERE entity_id = ?`, [tgt, src]);
|
|
5550
|
+
d.run("DELETE FROM entity_memories WHERE entity_id = ?", [src]);
|
|
5551
|
+
d.run("DELETE FROM entities WHERE id = ?", [src]);
|
|
5552
|
+
d.run("UPDATE entities SET updated_at = ? WHERE id = ?", [now2(), tgt]);
|
|
5553
|
+
return getEntity(tgt, d);
|
|
5533
5554
|
}
|
|
5534
5555
|
var init_entities = __esm(() => {
|
|
5535
5556
|
init_database();
|
|
@@ -5617,6 +5638,14 @@ function resolveEntityArg(nameOrId, type) {
|
|
|
5617
5638
|
const byName = getEntityByName(nameOrId, type);
|
|
5618
5639
|
if (byName)
|
|
5619
5640
|
return byName;
|
|
5641
|
+
if (isApiMode()) {
|
|
5642
|
+
try {
|
|
5643
|
+
return getEntity(nameOrId);
|
|
5644
|
+
} catch {
|
|
5645
|
+
console.error(chalk.red(`Entity not found: ${nameOrId}`));
|
|
5646
|
+
process.exit(1);
|
|
5647
|
+
}
|
|
5648
|
+
}
|
|
5620
5649
|
const db = getDatabase();
|
|
5621
5650
|
const id = resolvePartialId(db, "entities", nameOrId);
|
|
5622
5651
|
if (id)
|
|
@@ -62222,7 +62251,7 @@ function deprioritizeStale(days, db) {
|
|
|
62222
62251
|
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${deprioWhere}`).get(cutoff).c;
|
|
62223
62252
|
if (count > 0) {
|
|
62224
62253
|
d.run(`UPDATE memories
|
|
62225
|
-
SET importance =
|
|
62254
|
+
SET importance = importance - 1,
|
|
62226
62255
|
version = version + 1,
|
|
62227
62256
|
updated_at = ?
|
|
62228
62257
|
WHERE ${deprioWhere}`, [timestamp, cutoff]);
|
|
@@ -62240,14 +62269,22 @@ function runCleanup(config, db) {
|
|
|
62240
62269
|
}
|
|
62241
62270
|
|
|
62242
62271
|
// src/cli/commands/io-clean.ts
|
|
62272
|
+
init_api_mode();
|
|
62243
62273
|
init_helpers();
|
|
62274
|
+
function runCleanupViaApi() {
|
|
62275
|
+
const empty = { expired: 0, evicted: 0, archived: 0, unused_archived: 0, deprioritized: 0 };
|
|
62276
|
+
const { status, data } = apiJson("POST", "/maintenance/cleanup");
|
|
62277
|
+
if (status !== 404 && data)
|
|
62278
|
+
return { ...empty, ...data };
|
|
62279
|
+
const legacy = apiJson("POST", "/memories/clean");
|
|
62280
|
+
return { ...empty, expired: legacy.data?.cleaned ?? 0 };
|
|
62281
|
+
}
|
|
62244
62282
|
function registerCleanCommand(program2) {
|
|
62245
62283
|
const handleError = makeHandleError(program2);
|
|
62246
62284
|
program2.command("clean").description("Remove expired memories and enforce quotas").action(() => {
|
|
62247
62285
|
try {
|
|
62248
62286
|
const globalOpts = program2.opts();
|
|
62249
|
-
const
|
|
62250
|
-
const result = runCleanup(config);
|
|
62287
|
+
const result = isApiMode() ? runCleanupViaApi() : runCleanup(loadConfig());
|
|
62251
62288
|
if (globalOpts.json) {
|
|
62252
62289
|
outputJson(result);
|
|
62253
62290
|
} else {
|
|
@@ -62640,24 +62677,28 @@ function registerAgentCommands(program2) {
|
|
|
62640
62677
|
console.log(chalk22.green(`\u2665 ${agent.name} (${agent.id}) \u2014 heartbeat sent`));
|
|
62641
62678
|
});
|
|
62642
62679
|
program2.command("set-focus [project]").description("Focus this agent on a project (or clear focus if no project given)").option("--agent <id>", "Agent ID").action((project, opts) => {
|
|
62643
|
-
|
|
62644
|
-
|
|
62645
|
-
|
|
62646
|
-
|
|
62680
|
+
try {
|
|
62681
|
+
const globalOpts = program2.opts();
|
|
62682
|
+
const agentId = opts?.agent || globalOpts.agent;
|
|
62683
|
+
if (!agentId) {
|
|
62684
|
+
process.stderr.write(`Agent ID required. Use --agent.
|
|
62647
62685
|
`);
|
|
62648
|
-
|
|
62649
|
-
|
|
62650
|
-
|
|
62651
|
-
|
|
62652
|
-
|
|
62653
|
-
|
|
62654
|
-
|
|
62686
|
+
process.exit(1);
|
|
62687
|
+
}
|
|
62688
|
+
let target = project ?? null;
|
|
62689
|
+
if (project) {
|
|
62690
|
+
const proj = getProject(project);
|
|
62691
|
+
if (proj)
|
|
62692
|
+
target = proj.id;
|
|
62693
|
+
}
|
|
62694
|
+
setFocus(agentId, target);
|
|
62695
|
+
if (project)
|
|
62696
|
+
console.log(chalk22.green(`Focused: ${agentId} \u2192 project ${project}`));
|
|
62697
|
+
else
|
|
62698
|
+
console.log(chalk22.dim(`Focus cleared for ${agentId}`));
|
|
62699
|
+
} catch (e) {
|
|
62700
|
+
handleError(e);
|
|
62655
62701
|
}
|
|
62656
|
-
setFocus(agentId, target);
|
|
62657
|
-
if (project)
|
|
62658
|
-
console.log(chalk22.green(`Focused: ${agentId} \u2192 project ${project}`));
|
|
62659
|
-
else
|
|
62660
|
-
console.log(chalk22.dim(`Focus cleared for ${agentId}`));
|
|
62661
62702
|
});
|
|
62662
62703
|
program2.command("get-focus").description("Show the current project focus for an agent").option("--agent <id>", "Agent ID").action((opts) => {
|
|
62663
62704
|
const globalOpts = program2.opts();
|
|
@@ -63551,6 +63592,7 @@ import {
|
|
|
63551
63592
|
statSync as statSync3,
|
|
63552
63593
|
constants as fsConstants
|
|
63553
63594
|
} from "fs";
|
|
63595
|
+
init_api_mode();
|
|
63554
63596
|
init_helpers();
|
|
63555
63597
|
async function runCommandWithTimeout(args, timeoutMs) {
|
|
63556
63598
|
const proc = Bun.spawn(args, { stdout: "pipe", stderr: "pipe" });
|
|
@@ -63572,6 +63614,10 @@ function registerDoctorCommand(program2) {
|
|
|
63572
63614
|
program2.command("doctor").description("Diagnose common issues with the mementos installation").action(async () => {
|
|
63573
63615
|
const globalOpts = program2.opts();
|
|
63574
63616
|
const checks = [];
|
|
63617
|
+
if (isApiMode()) {
|
|
63618
|
+
await runCloudDoctor(globalOpts, checks);
|
|
63619
|
+
return;
|
|
63620
|
+
}
|
|
63575
63621
|
const version = getPackageVersion();
|
|
63576
63622
|
checks.push({ name: "Version", status: "ok", detail: version });
|
|
63577
63623
|
const dbPath = getDbPath();
|
|
@@ -63758,6 +63804,109 @@ function registerDoctorCommand(program2) {
|
|
|
63758
63804
|
outputDoctorResults(globalOpts, checks);
|
|
63759
63805
|
});
|
|
63760
63806
|
}
|
|
63807
|
+
async function runCloudDoctor(globalOpts, checks) {
|
|
63808
|
+
checks.push({ name: "Version", status: "ok", detail: getPackageVersion() });
|
|
63809
|
+
const cfg = getApiConfig();
|
|
63810
|
+
checks.push({
|
|
63811
|
+
name: "Storage mode",
|
|
63812
|
+
status: "ok",
|
|
63813
|
+
detail: `self-hosted API (${cfg?.baseUrl ?? "unknown endpoint"})`
|
|
63814
|
+
});
|
|
63815
|
+
let healthy = false;
|
|
63816
|
+
try {
|
|
63817
|
+
const { status, data } = apiJson("GET", "/health");
|
|
63818
|
+
healthy = status >= 200 && status < 300 && !!data;
|
|
63819
|
+
if (healthy && data) {
|
|
63820
|
+
const serverStatus = data.status === "warn" ? "warn" : "ok";
|
|
63821
|
+
checks.push({
|
|
63822
|
+
name: "Cloud connection",
|
|
63823
|
+
status: serverStatus,
|
|
63824
|
+
detail: `reachable \u2014 server v${data.version ?? "?"} (${data.status ?? "ok"})`
|
|
63825
|
+
});
|
|
63826
|
+
const total = data.memories?.total ?? 0;
|
|
63827
|
+
const expired = data.memories?.expired ?? 0;
|
|
63828
|
+
checks.push({ name: "Memories", status: "ok", detail: `${total} total` });
|
|
63829
|
+
checks.push({
|
|
63830
|
+
name: " Expired",
|
|
63831
|
+
status: expired > 10 ? "warn" : "ok",
|
|
63832
|
+
detail: expired > 10 ? `${expired} (run 'mementos clean' to remove)` : String(expired)
|
|
63833
|
+
});
|
|
63834
|
+
checks.push({ name: "Agents", status: "ok", detail: String(data.agents ?? 0) });
|
|
63835
|
+
checks.push({ name: "Projects", status: "ok", detail: String(data.projects ?? 0) });
|
|
63836
|
+
} else {
|
|
63837
|
+
checks.push({ name: "Cloud connection", status: "fail", detail: "health endpoint returned no data" });
|
|
63838
|
+
}
|
|
63839
|
+
} catch (e) {
|
|
63840
|
+
checks.push({
|
|
63841
|
+
name: "Cloud connection",
|
|
63842
|
+
status: "fail",
|
|
63843
|
+
detail: e instanceof Error ? e.message : String(e)
|
|
63844
|
+
});
|
|
63845
|
+
}
|
|
63846
|
+
try {
|
|
63847
|
+
loadConfig();
|
|
63848
|
+
checks.push({ name: "Config", status: "ok", detail: "valid" });
|
|
63849
|
+
} catch (e) {
|
|
63850
|
+
checks.push({ name: "Config", status: "fail", detail: e instanceof Error ? e.message : String(e) });
|
|
63851
|
+
}
|
|
63852
|
+
try {
|
|
63853
|
+
const activeProfile = getActiveProfile();
|
|
63854
|
+
const profiles = listProfiles();
|
|
63855
|
+
checks.push({
|
|
63856
|
+
name: "Active profile",
|
|
63857
|
+
status: "ok",
|
|
63858
|
+
detail: activeProfile ? `${activeProfile} (${profiles.length} total)` : `default \u2014 ${profiles.length} profile(s) available`
|
|
63859
|
+
});
|
|
63860
|
+
} catch (e) {
|
|
63861
|
+
checks.push({ name: "Active profile", status: "warn", detail: e instanceof Error ? e.message : String(e) });
|
|
63862
|
+
}
|
|
63863
|
+
try {
|
|
63864
|
+
const { stdout: mcpOut, exitCode: mcpExit, timedOut } = await runCommandWithTimeout(["claude", "mcp", "list"], 1500);
|
|
63865
|
+
if (timedOut) {
|
|
63866
|
+
checks.push({ name: "MCP server", status: "warn", detail: "health check timed out" });
|
|
63867
|
+
} else if (mcpExit === 0 && mcpOut.includes("mementos")) {
|
|
63868
|
+
checks.push({ name: "MCP server", status: "ok", detail: "registered with Claude Code" });
|
|
63869
|
+
} else if (mcpExit !== 0) {
|
|
63870
|
+
checks.push({ name: "MCP server", status: "warn", detail: "claude not installed or not accessible" });
|
|
63871
|
+
} else {
|
|
63872
|
+
checks.push({ name: "MCP server", status: "warn", detail: "not registered \u2192 run: mementos init" });
|
|
63873
|
+
}
|
|
63874
|
+
} catch {
|
|
63875
|
+
checks.push({ name: "MCP server", status: "warn", detail: "could not check (is claude CLI installed?)" });
|
|
63876
|
+
}
|
|
63877
|
+
try {
|
|
63878
|
+
const settingsFilePath = join7(homedir4(), ".claude", "settings.json");
|
|
63879
|
+
if (existsSync7(settingsFilePath)) {
|
|
63880
|
+
const settings = JSON.parse(readFileSync5(settingsFilePath, "utf-8"));
|
|
63881
|
+
const hooksObj = settings["hooks"] || {};
|
|
63882
|
+
const stopHooks = hooksObj["Stop"] || [];
|
|
63883
|
+
const hasMementos = stopHooks.some((e) => e.hooks?.some((h) => h.command && h.command.includes("mementos")));
|
|
63884
|
+
checks.push({
|
|
63885
|
+
name: "Stop hook",
|
|
63886
|
+
status: hasMementos ? "ok" : "warn",
|
|
63887
|
+
detail: hasMementos ? "installed (sessions \u2192 memories)" : "not installed \u2192 run: mementos init"
|
|
63888
|
+
});
|
|
63889
|
+
} else {
|
|
63890
|
+
checks.push({ name: "Stop hook", status: "warn", detail: "~/.claude/settings.json not found \u2192 run: mementos init" });
|
|
63891
|
+
}
|
|
63892
|
+
} catch {
|
|
63893
|
+
checks.push({ name: "Stop hook", status: "warn", detail: "could not check stop hook" });
|
|
63894
|
+
}
|
|
63895
|
+
if (process.platform === "darwin") {
|
|
63896
|
+
const plistFilePath = join7(homedir4(), "Library", "LaunchAgents", "com.hasna.mementos.plist");
|
|
63897
|
+
checks.push({
|
|
63898
|
+
name: "Auto-start",
|
|
63899
|
+
status: existsSync7(plistFilePath) ? "ok" : "warn",
|
|
63900
|
+
detail: existsSync7(plistFilePath) ? "configured (starts on login)" : "not configured \u2192 run: mementos init"
|
|
63901
|
+
});
|
|
63902
|
+
} else {
|
|
63903
|
+
checks.push({ name: "Auto-start", status: "ok", detail: `n/a on ${process.platform}` });
|
|
63904
|
+
}
|
|
63905
|
+
outputDoctorResults(globalOpts, checks);
|
|
63906
|
+
if (checks.some((c) => c.status === "fail")) {
|
|
63907
|
+
process.exitCode = 1;
|
|
63908
|
+
}
|
|
63909
|
+
}
|
|
63761
63910
|
function outputDoctorResults(globalOpts, checks) {
|
|
63762
63911
|
if (globalOpts.json) {
|
|
63763
63912
|
outputJson({ checks, healthy: checks.every((c) => c.status === "ok") });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../src/db/entities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAI1D,OAAO,KAAK,EACV,MAAM,EACN,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACX,MAAM,mBAAmB,CAAC;AAQ3B,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAWnE;AAMD,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAmE5E;AAMD,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"entities.d.ts","sourceRoot":"","sources":["../../src/db/entities.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAI1D,OAAO,KAAK,EACV,MAAM,EACN,iBAAiB,EACjB,iBAAiB,EACjB,UAAU,EACX,MAAM,mBAAmB,CAAC;AAQ3B,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GAAG,MAAM,CAWnE;AAMD,wBAAgB,YAAY,CAAC,KAAK,EAAE,iBAAiB,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAmE5E;AAMD,wBAAgB,SAAS,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAkB3D;AAED,wBAAgB,eAAe,CAC7B,IAAI,EAAE,MAAM,EACZ,IAAI,CAAC,EAAE,UAAU,EACjB,SAAS,CAAC,EAAE,MAAM,EAClB,EAAE,CAAC,EAAE,QAAQ,GACZ,MAAM,GAAG,IAAI,CAgCf;AAMD,wBAAgB,YAAY,CAC1B,MAAM,GAAE;IACN,IAAI,CAAC,EAAE,UAAU,CAAC;IAClB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,MAAM,CAAC,EAAE,MAAM,CAAC;CACZ,EACN,EAAE,CAAC,EAAE,QAAQ,GACZ,MAAM,EAAE,CA+CV;AAMD,wBAAgB,YAAY,CAC1B,EAAE,EAAE,MAAM,EACV,KAAK,EAAE,iBAAiB,EACxB,EAAE,CAAC,EAAE,QAAQ,GACZ,MAAM,CAsCR;AAMD,wBAAgB,YAAY,CAAC,EAAE,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,IAAI,CAS5D;AAMD,wBAAgB,aAAa,CAC3B,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,EAAE,CAAC,EAAE,QAAQ,GACZ,MAAM,CAyER;AAgCD,MAAM,WAAW,mBAAmB;IAClC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;CACpB;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,CACnC,SAAS,GAAE,MAAY,EACvB,EAAE,CAAC,EAAE,QAAQ,GACZ,mBAAmB,EAAE,CA2CvB;AAMD,MAAM,WAAW,kBAAkB;IACjC,QAAQ,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IAC5D,SAAS,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACxE,KAAK,EAAE,MAAM,CAAC;CACf;AAED,MAAM,WAAW,oBAAoB;IACnC,KAAK,EAAE,kBAAkB,EAAE,CAAC;IAC5B,gBAAgB,EAAE,KAAK,CAAC;QAAE,EAAE,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAC;QAAC,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;IACpE,WAAW,EAAE,MAAM,CAAC;CACrB;AAED;;;;;;GAMG;AACH,wBAAgB,aAAa,CAC3B,aAAa,EAAE,MAAM,EACrB,OAAO,GAAE;IACP,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,cAAc,CAAC,EAAE,MAAM,EAAE,CAAC;IAC1B,SAAS,CAAC,EAAE,UAAU,GAAG,UAAU,GAAG,MAAM,CAAC;IAC7C,KAAK,CAAC,EAAE,MAAM,CAAC;CACX,EACN,EAAE,CAAC,EAAE,QAAQ,GACZ,oBAAoB,CA4JtB"}
|
package/dist/index.js
CHANGED
|
@@ -51318,7 +51318,8 @@ function getEntity(id, db) {
|
|
|
51318
51318
|
return data;
|
|
51319
51319
|
}
|
|
51320
51320
|
const d = db || getDatabase();
|
|
51321
|
-
const
|
|
51321
|
+
const resolvedId = resolvePartialId(d, "entities", id) ?? id;
|
|
51322
|
+
const row = d.query("SELECT * FROM entities WHERE id = ?").get(resolvedId);
|
|
51322
51323
|
if (!row)
|
|
51323
51324
|
throw new EntityNotFoundError(id);
|
|
51324
51325
|
return parseEntityRow2(row);
|
|
@@ -51446,19 +51447,39 @@ function mergeEntities(sourceId, targetId, db) {
|
|
|
51446
51447
|
return data;
|
|
51447
51448
|
}
|
|
51448
51449
|
const d = db || getDatabase();
|
|
51449
|
-
getEntity(sourceId, d);
|
|
51450
|
-
getEntity(targetId, d);
|
|
51451
|
-
d.run(`
|
|
51452
|
-
|
|
51453
|
-
|
|
51454
|
-
|
|
51455
|
-
|
|
51456
|
-
|
|
51457
|
-
|
|
51458
|
-
|
|
51459
|
-
d.run(
|
|
51460
|
-
d.run(
|
|
51461
|
-
|
|
51450
|
+
const src = getEntity(sourceId, d).id;
|
|
51451
|
+
const tgt = getEntity(targetId, d).id;
|
|
51452
|
+
d.run(`DELETE FROM relations
|
|
51453
|
+
WHERE source_entity_id = ?
|
|
51454
|
+
AND EXISTS (
|
|
51455
|
+
SELECT 1 FROM relations e
|
|
51456
|
+
WHERE e.source_entity_id = ?
|
|
51457
|
+
AND e.target_entity_id = relations.target_entity_id
|
|
51458
|
+
AND e.relation_type = relations.relation_type
|
|
51459
|
+
)`, [src, tgt]);
|
|
51460
|
+
d.run(`UPDATE relations SET source_entity_id = ? WHERE source_entity_id = ?`, [tgt, src]);
|
|
51461
|
+
d.run(`DELETE FROM relations
|
|
51462
|
+
WHERE target_entity_id = ?
|
|
51463
|
+
AND EXISTS (
|
|
51464
|
+
SELECT 1 FROM relations e
|
|
51465
|
+
WHERE e.target_entity_id = ?
|
|
51466
|
+
AND e.source_entity_id = relations.source_entity_id
|
|
51467
|
+
AND e.relation_type = relations.relation_type
|
|
51468
|
+
)`, [src, tgt]);
|
|
51469
|
+
d.run(`UPDATE relations SET target_entity_id = ? WHERE target_entity_id = ?`, [tgt, src]);
|
|
51470
|
+
d.run("DELETE FROM relations WHERE source_entity_id = ? OR target_entity_id = ?", [src, src]);
|
|
51471
|
+
d.run(`DELETE FROM entity_memories
|
|
51472
|
+
WHERE entity_id = ?
|
|
51473
|
+
AND EXISTS (
|
|
51474
|
+
SELECT 1 FROM entity_memories e
|
|
51475
|
+
WHERE e.entity_id = ?
|
|
51476
|
+
AND e.memory_id = entity_memories.memory_id
|
|
51477
|
+
)`, [src, tgt]);
|
|
51478
|
+
d.run(`UPDATE entity_memories SET entity_id = ? WHERE entity_id = ?`, [tgt, src]);
|
|
51479
|
+
d.run("DELETE FROM entity_memories WHERE entity_id = ?", [src]);
|
|
51480
|
+
d.run("DELETE FROM entities WHERE id = ?", [src]);
|
|
51481
|
+
d.run("UPDATE entities SET updated_at = ? WHERE id = ?", [now(), tgt]);
|
|
51482
|
+
return getEntity(tgt, d);
|
|
51462
51483
|
}
|
|
51463
51484
|
|
|
51464
51485
|
// src/lib/decay.ts
|
|
@@ -52827,7 +52848,7 @@ function deprioritizeStale(days, db) {
|
|
|
52827
52848
|
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${deprioWhere}`).get(cutoff).c;
|
|
52828
52849
|
if (count > 0) {
|
|
52829
52850
|
d.run(`UPDATE memories
|
|
52830
|
-
SET importance =
|
|
52851
|
+
SET importance = importance - 1,
|
|
52831
52852
|
version = version + 1,
|
|
52832
52853
|
updated_at = ?
|
|
52833
52854
|
WHERE ${deprioWhere}`, [timestamp, cutoff]);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"retention.d.ts","sourceRoot":"","sources":["../../src/lib/retention.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,mBAAmB,CAAC;AAUrE,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CA0C3E;AAMD,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAwBrE;AAMD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAoBjE;AAMD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"retention.d.ts","sourceRoot":"","sources":["../../src/lib/retention.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,aAAa,IAAI,QAAQ,EAAE,MAAM,eAAe,CAAC;AAC/D,OAAO,KAAK,EAAE,cAAc,EAAe,MAAM,mBAAmB,CAAC;AAUrE,wBAAgB,aAAa,CAAC,MAAM,EAAE,cAAc,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CA0C3E;AAMD,wBAAgB,YAAY,CAAC,SAAS,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAwBrE;AAMD,wBAAgB,aAAa,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAoBjE;AAMD,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,QAAQ,GAAG,MAAM,CAgCrE;AAMD,wBAAgB,UAAU,CACxB,MAAM,EAAE,cAAc,EACtB,EAAE,CAAC,EAAE,QAAQ,GACZ;IAAE,OAAO,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,eAAe,EAAE,MAAM,CAAC;IAAC,aAAa,EAAE,MAAM,CAAA;CAAE,CAgBxG;AAOD,wBAAgB,mBAAmB,CACjC,SAAS,CAAC,EAAE,MAAM,EAClB,EAAE,CAAC,EAAE,QAAQ,GACZ;IAAE,QAAQ,EAAE,MAAM,CAAA;CAAE,CAuEtB"}
|
package/dist/mcp/index.js
CHANGED
|
@@ -3591,7 +3591,8 @@ function getEntity(id, db) {
|
|
|
3591
3591
|
return data;
|
|
3592
3592
|
}
|
|
3593
3593
|
const d = db || getDatabase();
|
|
3594
|
-
const
|
|
3594
|
+
const resolvedId = resolvePartialId(d, "entities", id) ?? id;
|
|
3595
|
+
const row = d.query("SELECT * FROM entities WHERE id = ?").get(resolvedId);
|
|
3595
3596
|
if (!row)
|
|
3596
3597
|
throw new EntityNotFoundError(id);
|
|
3597
3598
|
return parseEntityRow2(row);
|
|
@@ -3719,19 +3720,39 @@ function mergeEntities(sourceId, targetId, db) {
|
|
|
3719
3720
|
return data;
|
|
3720
3721
|
}
|
|
3721
3722
|
const d = db || getDatabase();
|
|
3722
|
-
getEntity(sourceId, d);
|
|
3723
|
-
getEntity(targetId, d);
|
|
3724
|
-
d.run(`
|
|
3725
|
-
|
|
3726
|
-
|
|
3727
|
-
|
|
3728
|
-
|
|
3729
|
-
|
|
3730
|
-
|
|
3731
|
-
|
|
3732
|
-
d.run(
|
|
3733
|
-
d.run(
|
|
3734
|
-
|
|
3723
|
+
const src = getEntity(sourceId, d).id;
|
|
3724
|
+
const tgt = getEntity(targetId, d).id;
|
|
3725
|
+
d.run(`DELETE FROM relations
|
|
3726
|
+
WHERE source_entity_id = ?
|
|
3727
|
+
AND EXISTS (
|
|
3728
|
+
SELECT 1 FROM relations e
|
|
3729
|
+
WHERE e.source_entity_id = ?
|
|
3730
|
+
AND e.target_entity_id = relations.target_entity_id
|
|
3731
|
+
AND e.relation_type = relations.relation_type
|
|
3732
|
+
)`, [src, tgt]);
|
|
3733
|
+
d.run(`UPDATE relations SET source_entity_id = ? WHERE source_entity_id = ?`, [tgt, src]);
|
|
3734
|
+
d.run(`DELETE FROM relations
|
|
3735
|
+
WHERE target_entity_id = ?
|
|
3736
|
+
AND EXISTS (
|
|
3737
|
+
SELECT 1 FROM relations e
|
|
3738
|
+
WHERE e.target_entity_id = ?
|
|
3739
|
+
AND e.source_entity_id = relations.source_entity_id
|
|
3740
|
+
AND e.relation_type = relations.relation_type
|
|
3741
|
+
)`, [src, tgt]);
|
|
3742
|
+
d.run(`UPDATE relations SET target_entity_id = ? WHERE target_entity_id = ?`, [tgt, src]);
|
|
3743
|
+
d.run("DELETE FROM relations WHERE source_entity_id = ? OR target_entity_id = ?", [src, src]);
|
|
3744
|
+
d.run(`DELETE FROM entity_memories
|
|
3745
|
+
WHERE entity_id = ?
|
|
3746
|
+
AND EXISTS (
|
|
3747
|
+
SELECT 1 FROM entity_memories e
|
|
3748
|
+
WHERE e.entity_id = ?
|
|
3749
|
+
AND e.memory_id = entity_memories.memory_id
|
|
3750
|
+
)`, [src, tgt]);
|
|
3751
|
+
d.run(`UPDATE entity_memories SET entity_id = ? WHERE entity_id = ?`, [tgt, src]);
|
|
3752
|
+
d.run("DELETE FROM entity_memories WHERE entity_id = ?", [src]);
|
|
3753
|
+
d.run("DELETE FROM entities WHERE id = ?", [src]);
|
|
3754
|
+
d.run("UPDATE entities SET updated_at = ? WHERE id = ?", [now(), tgt]);
|
|
3755
|
+
return getEntity(tgt, d);
|
|
3735
3756
|
}
|
|
3736
3757
|
function trigramSimilarity(a, b) {
|
|
3737
3758
|
const trigramsOf = (s) => {
|
|
@@ -11746,7 +11767,7 @@ function deprioritizeStale(days, db) {
|
|
|
11746
11767
|
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${deprioWhere}`).get(cutoff).c;
|
|
11747
11768
|
if (count > 0) {
|
|
11748
11769
|
d.run(`UPDATE memories
|
|
11749
|
-
SET importance =
|
|
11770
|
+
SET importance = importance - 1,
|
|
11750
11771
|
version = version + 1,
|
|
11751
11772
|
updated_at = ?
|
|
11752
11773
|
WHERE ${deprioWhere}`, [timestamp, cutoff]);
|
package/dist/server/index.js
CHANGED
|
@@ -3132,7 +3132,8 @@ function getEntity(id, db) {
|
|
|
3132
3132
|
return data;
|
|
3133
3133
|
}
|
|
3134
3134
|
const d = db || getDatabase();
|
|
3135
|
-
const
|
|
3135
|
+
const resolvedId = resolvePartialId(d, "entities", id) ?? id;
|
|
3136
|
+
const row = d.query("SELECT * FROM entities WHERE id = ?").get(resolvedId);
|
|
3136
3137
|
if (!row)
|
|
3137
3138
|
throw new EntityNotFoundError(id);
|
|
3138
3139
|
return parseEntityRow2(row);
|
|
@@ -3260,19 +3261,39 @@ function mergeEntities(sourceId, targetId, db) {
|
|
|
3260
3261
|
return data;
|
|
3261
3262
|
}
|
|
3262
3263
|
const d = db || getDatabase();
|
|
3263
|
-
getEntity(sourceId, d);
|
|
3264
|
-
getEntity(targetId, d);
|
|
3265
|
-
d.run(`
|
|
3266
|
-
|
|
3267
|
-
|
|
3268
|
-
|
|
3269
|
-
|
|
3270
|
-
|
|
3271
|
-
|
|
3272
|
-
|
|
3273
|
-
d.run(
|
|
3274
|
-
d.run(
|
|
3275
|
-
|
|
3264
|
+
const src = getEntity(sourceId, d).id;
|
|
3265
|
+
const tgt = getEntity(targetId, d).id;
|
|
3266
|
+
d.run(`DELETE FROM relations
|
|
3267
|
+
WHERE source_entity_id = ?
|
|
3268
|
+
AND EXISTS (
|
|
3269
|
+
SELECT 1 FROM relations e
|
|
3270
|
+
WHERE e.source_entity_id = ?
|
|
3271
|
+
AND e.target_entity_id = relations.target_entity_id
|
|
3272
|
+
AND e.relation_type = relations.relation_type
|
|
3273
|
+
)`, [src, tgt]);
|
|
3274
|
+
d.run(`UPDATE relations SET source_entity_id = ? WHERE source_entity_id = ?`, [tgt, src]);
|
|
3275
|
+
d.run(`DELETE FROM relations
|
|
3276
|
+
WHERE target_entity_id = ?
|
|
3277
|
+
AND EXISTS (
|
|
3278
|
+
SELECT 1 FROM relations e
|
|
3279
|
+
WHERE e.target_entity_id = ?
|
|
3280
|
+
AND e.source_entity_id = relations.source_entity_id
|
|
3281
|
+
AND e.relation_type = relations.relation_type
|
|
3282
|
+
)`, [src, tgt]);
|
|
3283
|
+
d.run(`UPDATE relations SET target_entity_id = ? WHERE target_entity_id = ?`, [tgt, src]);
|
|
3284
|
+
d.run("DELETE FROM relations WHERE source_entity_id = ? OR target_entity_id = ?", [src, src]);
|
|
3285
|
+
d.run(`DELETE FROM entity_memories
|
|
3286
|
+
WHERE entity_id = ?
|
|
3287
|
+
AND EXISTS (
|
|
3288
|
+
SELECT 1 FROM entity_memories e
|
|
3289
|
+
WHERE e.entity_id = ?
|
|
3290
|
+
AND e.memory_id = entity_memories.memory_id
|
|
3291
|
+
)`, [src, tgt]);
|
|
3292
|
+
d.run(`UPDATE entity_memories SET entity_id = ? WHERE entity_id = ?`, [tgt, src]);
|
|
3293
|
+
d.run("DELETE FROM entity_memories WHERE entity_id = ?", [src]);
|
|
3294
|
+
d.run("DELETE FROM entities WHERE id = ?", [src]);
|
|
3295
|
+
d.run("UPDATE entities SET updated_at = ? WHERE id = ?", [now(), tgt]);
|
|
3296
|
+
return getEntity(tgt, d);
|
|
3276
3297
|
}
|
|
3277
3298
|
function graphTraverse(startEntityId, options = {}, db) {
|
|
3278
3299
|
if (!db && isApiMode()) {
|
|
@@ -5689,6 +5710,13 @@ function addRoute(method, path, handler) {
|
|
|
5689
5710
|
handler
|
|
5690
5711
|
});
|
|
5691
5712
|
}
|
|
5713
|
+
function safeDecodeParam(value) {
|
|
5714
|
+
try {
|
|
5715
|
+
return decodeURIComponent(value);
|
|
5716
|
+
} catch {
|
|
5717
|
+
return value;
|
|
5718
|
+
}
|
|
5719
|
+
}
|
|
5692
5720
|
function matchRoute(method, pathname) {
|
|
5693
5721
|
let bestMatch = null;
|
|
5694
5722
|
for (const route of routes) {
|
|
@@ -5698,7 +5726,7 @@ function matchRoute(method, pathname) {
|
|
|
5698
5726
|
if (match) {
|
|
5699
5727
|
const params = {};
|
|
5700
5728
|
route.paramNames.forEach((name, i) => {
|
|
5701
|
-
params[name] = match[i + 1];
|
|
5729
|
+
params[name] = safeDecodeParam(match[i + 1]);
|
|
5702
5730
|
});
|
|
5703
5731
|
if (!bestMatch || route.specificity > bestMatch.route.specificity || route.specificity === bestMatch.route.specificity && route.order < bestMatch.route.order) {
|
|
5704
5732
|
bestMatch = { route, params };
|
|
@@ -53400,6 +53428,88 @@ function isInMemoryDb(path) {
|
|
|
53400
53428
|
function homeDir() {
|
|
53401
53429
|
return process.env["HOME"] || process.env["USERPROFILE"] || homedir();
|
|
53402
53430
|
}
|
|
53431
|
+
var DEFAULT_CONFIG = {
|
|
53432
|
+
default_scope: "private",
|
|
53433
|
+
default_category: "knowledge",
|
|
53434
|
+
default_importance: 5,
|
|
53435
|
+
max_entries: 1000,
|
|
53436
|
+
max_entries_per_scope: {
|
|
53437
|
+
global: 500,
|
|
53438
|
+
shared: 300,
|
|
53439
|
+
private: 200,
|
|
53440
|
+
working: 100
|
|
53441
|
+
},
|
|
53442
|
+
injection: {
|
|
53443
|
+
max_tokens: 500,
|
|
53444
|
+
min_importance: 5,
|
|
53445
|
+
categories: ["preference", "fact"],
|
|
53446
|
+
refresh_interval: 5
|
|
53447
|
+
},
|
|
53448
|
+
extraction: {
|
|
53449
|
+
enabled: true,
|
|
53450
|
+
min_confidence: 0.5
|
|
53451
|
+
},
|
|
53452
|
+
sync_agents: ["claude", "codex", "gemini"],
|
|
53453
|
+
auto_cleanup: {
|
|
53454
|
+
enabled: true,
|
|
53455
|
+
expired_check_interval: 3600,
|
|
53456
|
+
unused_archive_days: 7,
|
|
53457
|
+
stale_deprioritize_days: 14
|
|
53458
|
+
}
|
|
53459
|
+
};
|
|
53460
|
+
function deepMerge(target, source) {
|
|
53461
|
+
const result = { ...target };
|
|
53462
|
+
for (const key of Object.keys(source)) {
|
|
53463
|
+
const sourceVal = source[key];
|
|
53464
|
+
const targetVal = result[key];
|
|
53465
|
+
if (sourceVal !== null && typeof sourceVal === "object" && !Array.isArray(sourceVal) && targetVal !== null && typeof targetVal === "object" && !Array.isArray(targetVal)) {
|
|
53466
|
+
result[key] = deepMerge(targetVal, sourceVal);
|
|
53467
|
+
} else {
|
|
53468
|
+
result[key] = sourceVal;
|
|
53469
|
+
}
|
|
53470
|
+
}
|
|
53471
|
+
return result;
|
|
53472
|
+
}
|
|
53473
|
+
var VALID_SCOPES = ["global", "shared", "private", "working"];
|
|
53474
|
+
var VALID_CATEGORIES = [
|
|
53475
|
+
"preference",
|
|
53476
|
+
"fact",
|
|
53477
|
+
"knowledge",
|
|
53478
|
+
"history"
|
|
53479
|
+
];
|
|
53480
|
+
function isValidScope(value) {
|
|
53481
|
+
return VALID_SCOPES.includes(value);
|
|
53482
|
+
}
|
|
53483
|
+
function isValidCategory(value) {
|
|
53484
|
+
return VALID_CATEGORIES.includes(value);
|
|
53485
|
+
}
|
|
53486
|
+
function loadConfig() {
|
|
53487
|
+
const configPath = join(homeDir(), ".hasna", "mementos", "config.json");
|
|
53488
|
+
let fileConfig = {};
|
|
53489
|
+
if (existsSync(configPath)) {
|
|
53490
|
+
try {
|
|
53491
|
+
const raw = readFileSync(configPath, "utf-8");
|
|
53492
|
+
fileConfig = JSON.parse(raw);
|
|
53493
|
+
} catch {}
|
|
53494
|
+
}
|
|
53495
|
+
const merged = deepMerge(DEFAULT_CONFIG, fileConfig);
|
|
53496
|
+
const envScope = process.env["MEMENTOS_DEFAULT_SCOPE"];
|
|
53497
|
+
if (envScope && isValidScope(envScope)) {
|
|
53498
|
+
merged.default_scope = envScope;
|
|
53499
|
+
}
|
|
53500
|
+
const envCategory = process.env["MEMENTOS_DEFAULT_CATEGORY"];
|
|
53501
|
+
if (envCategory && isValidCategory(envCategory)) {
|
|
53502
|
+
merged.default_category = envCategory;
|
|
53503
|
+
}
|
|
53504
|
+
const envImportance = process.env["MEMENTOS_DEFAULT_IMPORTANCE"];
|
|
53505
|
+
if (envImportance) {
|
|
53506
|
+
const parsed = parseInt(envImportance, 10);
|
|
53507
|
+
if (!Number.isNaN(parsed) && parsed >= 1 && parsed <= 10) {
|
|
53508
|
+
merged.default_importance = parsed;
|
|
53509
|
+
}
|
|
53510
|
+
}
|
|
53511
|
+
return merged;
|
|
53512
|
+
}
|
|
53403
53513
|
function findFileWalkingUp(filename) {
|
|
53404
53514
|
let dir = process.cwd();
|
|
53405
53515
|
const legacyHomeMementosDb = resolve(homeDir(), ".mementos", "mementos.db");
|
|
@@ -56410,6 +56520,79 @@ addRoute("POST", "/api/memories/bulk-upsert", async (req) => {
|
|
|
56410
56520
|
// src/server/routes/memories-misc.ts
|
|
56411
56521
|
init_memories();
|
|
56412
56522
|
|
|
56523
|
+
// src/lib/retention.ts
|
|
56524
|
+
init_database();
|
|
56525
|
+
init_memories();
|
|
56526
|
+
function enforceQuotas(config, db) {
|
|
56527
|
+
const d = db || getDatabase();
|
|
56528
|
+
let totalEvicted = 0;
|
|
56529
|
+
const scopes = ["global", "shared", "private", "working"];
|
|
56530
|
+
for (const scope of scopes) {
|
|
56531
|
+
const limit = config.max_entries_per_scope[scope];
|
|
56532
|
+
if (!limit || limit <= 0)
|
|
56533
|
+
continue;
|
|
56534
|
+
const countRow = d.query("SELECT COUNT(*) as cnt FROM memories WHERE scope = ? AND status = 'active'").get(scope);
|
|
56535
|
+
const count = countRow.cnt;
|
|
56536
|
+
if (count <= limit)
|
|
56537
|
+
continue;
|
|
56538
|
+
const excess = count - limit;
|
|
56539
|
+
const subquery = `SELECT id FROM memories
|
|
56540
|
+
WHERE scope = ? AND status = 'active' AND pinned = 0
|
|
56541
|
+
ORDER BY importance ASC, created_at ASC
|
|
56542
|
+
LIMIT ?`;
|
|
56543
|
+
const delCount = d.query(`SELECT COUNT(*) as c FROM (${subquery})`).get(scope, excess).c;
|
|
56544
|
+
d.run(`DELETE FROM memories WHERE id IN (${subquery})`, [scope, excess]);
|
|
56545
|
+
totalEvicted += delCount;
|
|
56546
|
+
}
|
|
56547
|
+
return totalEvicted;
|
|
56548
|
+
}
|
|
56549
|
+
function archiveStale(staleDays, db) {
|
|
56550
|
+
const d = db || getDatabase();
|
|
56551
|
+
const timestamp = now();
|
|
56552
|
+
const cutoff = new Date(Date.now() - staleDays * 24 * 60 * 60 * 1000).toISOString();
|
|
56553
|
+
const archiveWhere = `status = 'active' AND pinned = 0 AND COALESCE(accessed_at, created_at) < ?`;
|
|
56554
|
+
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${archiveWhere}`).get(cutoff).c;
|
|
56555
|
+
if (count > 0) {
|
|
56556
|
+
d.run(`UPDATE memories SET status = 'archived', updated_at = ? WHERE ${archiveWhere}`, [timestamp, cutoff]);
|
|
56557
|
+
}
|
|
56558
|
+
return count;
|
|
56559
|
+
}
|
|
56560
|
+
function archiveUnused(days, db) {
|
|
56561
|
+
const d = db || getDatabase();
|
|
56562
|
+
const timestamp = now();
|
|
56563
|
+
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
56564
|
+
const unusedWhere = `status = 'active' AND pinned = 0 AND access_count = 0 AND created_at < ?`;
|
|
56565
|
+
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${unusedWhere}`).get(cutoff).c;
|
|
56566
|
+
if (count > 0) {
|
|
56567
|
+
d.run(`UPDATE memories SET status = 'archived', updated_at = ? WHERE ${unusedWhere}`, [timestamp, cutoff]);
|
|
56568
|
+
}
|
|
56569
|
+
return count;
|
|
56570
|
+
}
|
|
56571
|
+
function deprioritizeStale(days, db) {
|
|
56572
|
+
const d = db || getDatabase();
|
|
56573
|
+
const timestamp = now();
|
|
56574
|
+
const cutoff = new Date(Date.now() - days * 24 * 60 * 60 * 1000).toISOString();
|
|
56575
|
+
const deprioWhere = `status = 'active' AND pinned = 0 AND importance > 1 AND COALESCE(accessed_at, updated_at) < ?`;
|
|
56576
|
+
const count = d.query(`SELECT COUNT(*) as c FROM memories WHERE ${deprioWhere}`).get(cutoff).c;
|
|
56577
|
+
if (count > 0) {
|
|
56578
|
+
d.run(`UPDATE memories
|
|
56579
|
+
SET importance = importance - 1,
|
|
56580
|
+
version = version + 1,
|
|
56581
|
+
updated_at = ?
|
|
56582
|
+
WHERE ${deprioWhere}`, [timestamp, cutoff]);
|
|
56583
|
+
}
|
|
56584
|
+
return count;
|
|
56585
|
+
}
|
|
56586
|
+
function runCleanup(config, db) {
|
|
56587
|
+
const d = db || getDatabase();
|
|
56588
|
+
const expired = cleanExpiredMemories(d);
|
|
56589
|
+
const evicted = enforceQuotas(config, d);
|
|
56590
|
+
const archived = archiveStale(90, d);
|
|
56591
|
+
const unused_archived = archiveUnused(config.auto_cleanup.unused_archive_days ?? 7, d);
|
|
56592
|
+
const deprioritized = deprioritizeStale(config.auto_cleanup.stale_deprioritize_days ?? 14, d);
|
|
56593
|
+
return { expired, evicted, archived, unused_archived, deprioritized };
|
|
56594
|
+
}
|
|
56595
|
+
|
|
56413
56596
|
// src/lib/machine-visibility.ts
|
|
56414
56597
|
function resolveVisibleMachineId(machineId, db) {
|
|
56415
56598
|
if (machineId !== undefined) {
|
|
@@ -56532,6 +56715,10 @@ addRoute("POST", "/api/memories/clean", () => {
|
|
|
56532
56715
|
const cleaned = cleanExpiredMemories();
|
|
56533
56716
|
return json({ cleaned });
|
|
56534
56717
|
});
|
|
56718
|
+
addRoute("POST", "/api/maintenance/cleanup", () => {
|
|
56719
|
+
const result = runCleanup(loadConfig());
|
|
56720
|
+
return json(result);
|
|
56721
|
+
});
|
|
56535
56722
|
addRoute("GET", "/api/inject", (_req, url) => {
|
|
56536
56723
|
const q = getSearchParams(url);
|
|
56537
56724
|
const maxTokens = q["max_tokens"] ? parseInt(q["max_tokens"], 10) : 500;
|
|
@@ -58697,7 +58884,7 @@ function registerSystemToolRoutes() {
|
|
|
58697
58884
|
});
|
|
58698
58885
|
addRoute("GET", "/api/tool-insights/:tool_name", (_req, url, params) => {
|
|
58699
58886
|
const q = getSearchParams(url);
|
|
58700
|
-
const toolName =
|
|
58887
|
+
const toolName = params["tool_name"];
|
|
58701
58888
|
const projectId = q["project_id"];
|
|
58702
58889
|
const lessonsLimit = q["limit"] ? parseInt(q["limit"], 10) : 20;
|
|
58703
58890
|
const stats = getToolStats(toolName, projectId || undefined);
|
|
@@ -58712,7 +58899,7 @@ init_memories();
|
|
|
58712
58899
|
init_router();
|
|
58713
58900
|
function registerSystemChainRoutes() {
|
|
58714
58901
|
addRoute("GET", "/api/chains/:sequence_group", (_req, url, params) => {
|
|
58715
|
-
const sequenceGroup =
|
|
58902
|
+
const sequenceGroup = params["sequence_group"];
|
|
58716
58903
|
const projectId = getSearchParams(url)["project_id"];
|
|
58717
58904
|
const chain = getMemoryChain(sequenceGroup, projectId, getDatabase());
|
|
58718
58905
|
return json({ chain, count: chain.length, sequence_group: sequenceGroup });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,GAAG,CACzB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;AAElC,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,YAAY,CAAC;CACvB;AAED,eAAO,MAAM,MAAM,EAAE,KAAK,EAAO,CAAC;AAUlC,wBAAgB,QAAQ,CACtB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,GACpB,IAAI,CAeN;
|
|
1
|
+
{"version":3,"file":"router.d.ts","sourceRoot":"","sources":["../../src/server/router.ts"],"names":[],"mappings":"AAIA,MAAM,MAAM,YAAY,GAAG,CACzB,GAAG,EAAE,OAAO,EACZ,GAAG,EAAE,GAAG,EACR,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,KAC3B,OAAO,CAAC,QAAQ,CAAC,GAAG,QAAQ,CAAC;AAElC,MAAM,WAAW,KAAK;IACpB,MAAM,EAAE,MAAM,CAAC;IACf,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,YAAY,CAAC;CACvB;AAED,eAAO,MAAM,MAAM,EAAE,KAAK,EAAO,CAAC;AAUlC,wBAAgB,QAAQ,CACtB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,YAAY,GACpB,IAAI,CAeN;AAWD,wBAAgB,UAAU,CACxB,MAAM,EAAE,MAAM,EACd,QAAQ,EAAE,MAAM,GACf;IAAE,OAAO,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;CAAE,GAAG,IAAI,CAiClE"}
|