@agentmemory/agentmemory 0.9.28 → 0.9.30

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.
Files changed (158) hide show
  1. package/.env.example +98 -28
  2. package/AGENTS.md +19 -26
  3. package/README.md +619 -274
  4. package/dist/.env.example +98 -28
  5. package/dist/cli.d.mts.map +1 -1
  6. package/dist/cli.mjs +1328 -244
  7. package/dist/cli.mjs.map +1 -1
  8. package/dist/{connect-JnsJXc68.mjs → connect-B4_ca6BD.mjs} +619 -70
  9. package/dist/connect-B4_ca6BD.mjs.map +1 -0
  10. package/dist/docker-compose.yml +42 -16
  11. package/dist/hooks/_capture.d.mts +22 -0
  12. package/dist/hooks/_capture.d.mts.map +1 -0
  13. package/dist/hooks/_capture.mjs +908 -0
  14. package/dist/hooks/_capture.mjs.map +1 -0
  15. package/dist/hooks/antigravity-bridge.d.mts +8 -0
  16. package/dist/hooks/antigravity-bridge.d.mts.map +1 -0
  17. package/dist/hooks/antigravity-bridge.mjs +123 -0
  18. package/dist/hooks/antigravity-bridge.mjs.map +1 -0
  19. package/dist/hooks/notification.mjs +34 -27
  20. package/dist/hooks/notification.mjs.map +1 -1
  21. package/dist/hooks/post-commit.mjs +84 -2
  22. package/dist/hooks/post-commit.mjs.map +1 -1
  23. package/dist/hooks/post-tool-failure.mjs +71 -26
  24. package/dist/hooks/post-tool-failure.mjs.map +1 -1
  25. package/dist/hooks/post-tool-use.mjs +99 -36
  26. package/dist/hooks/post-tool-use.mjs.map +1 -1
  27. package/dist/hooks/pre-compact.mjs +95 -5
  28. package/dist/hooks/pre-compact.mjs.map +1 -1
  29. package/dist/hooks/pre-tool-use.mjs +72 -2
  30. package/dist/hooks/pre-tool-use.mjs.map +1 -1
  31. package/dist/hooks/prompt-submit.mjs +25 -22
  32. package/dist/hooks/prompt-submit.mjs.map +1 -1
  33. package/dist/hooks/session-end.mjs +93 -24
  34. package/dist/hooks/session-end.mjs.map +1 -1
  35. package/dist/hooks/session-start.mjs +101 -6
  36. package/dist/hooks/session-start.mjs.map +1 -1
  37. package/dist/hooks/stop.mjs +72 -8
  38. package/dist/hooks/stop.mjs.map +1 -1
  39. package/dist/hooks/subagent-start.mjs +28 -26
  40. package/dist/hooks/subagent-start.mjs.map +1 -1
  41. package/dist/hooks/subagent-stop.mjs +29 -26
  42. package/dist/hooks/subagent-stop.mjs.map +1 -1
  43. package/dist/hooks/task-completed.mjs +31 -28
  44. package/dist/hooks/task-completed.mjs.map +1 -1
  45. package/dist/iii-config.docker.yaml +10 -10
  46. package/dist/iii-config.yaml +3 -1
  47. package/dist/{image-refs-BKLmp_sD.mjs → image-refs-BaT-9oMU.mjs} +2 -2
  48. package/dist/image-refs-BaT-9oMU.mjs.map +1 -0
  49. package/dist/{image-refs-C2YU7BIm.mjs → image-refs-T_urbwHM.mjs} +3 -3
  50. package/dist/image-refs-T_urbwHM.mjs.map +1 -0
  51. package/dist/{keyed-mutex-DTHtcZrt.mjs → image-store-BsN4vyjr.mjs} +2 -14
  52. package/dist/image-store-BsN4vyjr.mjs.map +1 -0
  53. package/dist/index.mjs +14021 -6494
  54. package/dist/index.mjs.map +1 -1
  55. package/dist/keyed-mutex-DchXsyfP.mjs +221 -0
  56. package/dist/keyed-mutex-DchXsyfP.mjs.map +1 -0
  57. package/dist/secret-store-BnY3A50C.mjs +2348 -0
  58. package/dist/secret-store-BnY3A50C.mjs.map +1 -0
  59. package/dist/{src-CzgoepGU.mjs → src-Jsq9LCeH.mjs} +7349 -2940
  60. package/dist/src-Jsq9LCeH.mjs.map +1 -0
  61. package/dist/{standalone-YsZFFQBM.mjs → standalone-DKCdrf1d.mjs} +62 -24
  62. package/dist/standalone-DKCdrf1d.mjs.map +1 -0
  63. package/dist/standalone.d.mts.map +1 -1
  64. package/dist/standalone.mjs +298 -27
  65. package/dist/standalone.mjs.map +1 -1
  66. package/dist/status-IRz7ta8-.mjs +2344 -0
  67. package/dist/status-IRz7ta8-.mjs.map +1 -0
  68. package/dist/viewer/favicon.svg +35 -1
  69. package/dist/viewer/index.html +7428 -2608
  70. package/docker-compose.yml +42 -16
  71. package/iii-config.docker.yaml +10 -10
  72. package/iii-config.yaml +3 -1
  73. package/integrations/pi/README.md +77 -0
  74. package/integrations/pi/index.ts +402 -0
  75. package/integrations/pi/package.json +32 -0
  76. package/integrations/pi/security.ts +87 -0
  77. package/package.json +15 -7
  78. package/plugin/.claude-plugin/plugin.json +2 -2
  79. package/plugin/.codex-plugin/plugin.json +26 -4
  80. package/plugin/.devin-plugin/plugin.json +32 -0
  81. package/plugin/.mcp.codex.json +12 -0
  82. package/plugin/.mcp.copilot.json +2 -7
  83. package/plugin/.mcp.json +2 -7
  84. package/plugin/assets/icon.svg +35 -0
  85. package/plugin/cursor/hooks.json +41 -0
  86. package/plugin/cursor/mcp.json +12 -0
  87. package/plugin/hooks/hooks.antigravity.json +43 -0
  88. package/plugin/hooks/hooks.copilot.json +11 -11
  89. package/plugin/hooks/hooks.devin.json +67 -0
  90. package/plugin/hooks/hooks.droid.json +55 -0
  91. package/plugin/opencode/README.md +267 -31
  92. package/plugin/opencode/agentmemory-capture.ts +644 -15
  93. package/plugin/opencode/plugin.json +1 -1
  94. package/plugin/plugin.json +2 -2
  95. package/plugin/scripts/_capture.d.mts +22 -0
  96. package/plugin/scripts/_capture.d.mts.map +1 -0
  97. package/plugin/scripts/_capture.mjs +908 -0
  98. package/plugin/scripts/_capture.mjs.map +1 -0
  99. package/plugin/scripts/antigravity-bridge.d.mts +8 -0
  100. package/plugin/scripts/antigravity-bridge.d.mts.map +1 -0
  101. package/plugin/scripts/antigravity-bridge.mjs +123 -0
  102. package/plugin/scripts/antigravity-bridge.mjs.map +1 -0
  103. package/plugin/scripts/notification.mjs +34 -27
  104. package/plugin/scripts/notification.mjs.map +1 -1
  105. package/plugin/scripts/plugin-bridge.mjs +378 -0
  106. package/plugin/scripts/post-commit.mjs +84 -2
  107. package/plugin/scripts/post-commit.mjs.map +1 -1
  108. package/plugin/scripts/post-tool-failure.mjs +71 -26
  109. package/plugin/scripts/post-tool-failure.mjs.map +1 -1
  110. package/plugin/scripts/post-tool-use.mjs +99 -36
  111. package/plugin/scripts/post-tool-use.mjs.map +1 -1
  112. package/plugin/scripts/pre-compact.mjs +95 -5
  113. package/plugin/scripts/pre-compact.mjs.map +1 -1
  114. package/plugin/scripts/pre-tool-use.mjs +72 -2
  115. package/plugin/scripts/pre-tool-use.mjs.map +1 -1
  116. package/plugin/scripts/prompt-submit.mjs +25 -22
  117. package/plugin/scripts/prompt-submit.mjs.map +1 -1
  118. package/plugin/scripts/session-end.mjs +93 -24
  119. package/plugin/scripts/session-end.mjs.map +1 -1
  120. package/plugin/scripts/session-start.mjs +101 -6
  121. package/plugin/scripts/session-start.mjs.map +1 -1
  122. package/plugin/scripts/stop.mjs +72 -8
  123. package/plugin/scripts/stop.mjs.map +1 -1
  124. package/plugin/scripts/subagent-start.mjs +28 -26
  125. package/plugin/scripts/subagent-start.mjs.map +1 -1
  126. package/plugin/scripts/subagent-stop.mjs +29 -26
  127. package/plugin/scripts/subagent-stop.mjs.map +1 -1
  128. package/plugin/scripts/task-completed.mjs +31 -28
  129. package/plugin/scripts/task-completed.mjs.map +1 -1
  130. package/plugin/skills/_shared/TROUBLESHOOTING.md +22 -6
  131. package/plugin/skills/agentmemory-agents/REFERENCE.md +8 -5
  132. package/plugin/skills/agentmemory-config/REFERENCE.md +52 -1
  133. package/plugin/skills/agentmemory-config/SKILL.md +44 -7
  134. package/plugin/skills/agentmemory-mcp-tools/REFERENCE.md +4 -3
  135. package/plugin/skills/agentmemory-rest-api/REFERENCE.md +23 -2
  136. package/plugin/skills/forget/SKILL.md +4 -1
  137. package/plugin/skills/handoff/SKILL.md +4 -2
  138. package/plugin/skills/lesson/SKILL.md +64 -0
  139. package/plugin/skills/memory-discipline/SKILL.md +65 -0
  140. package/plugin/skills/recall/SKILL.md +4 -1
  141. package/plugin/skills/remember/SKILL.md +6 -1
  142. package/dist/config-ChC9EtgV.mjs +0 -259
  143. package/dist/config-ChC9EtgV.mjs.map +0 -1
  144. package/dist/connect-JnsJXc68.mjs.map +0 -1
  145. package/dist/image-refs-BKLmp_sD.mjs.map +0 -1
  146. package/dist/image-refs-C2YU7BIm.mjs.map +0 -1
  147. package/dist/keyed-mutex-DTHtcZrt.mjs.map +0 -1
  148. package/dist/logger-BEB7pCI9.mjs +0 -43
  149. package/dist/logger-BEB7pCI9.mjs.map +0 -1
  150. package/dist/schema-CNiCWzV9.mjs +0 -78
  151. package/dist/schema-CNiCWzV9.mjs.map +0 -1
  152. package/dist/src-CzgoepGU.mjs.map +0 -1
  153. package/dist/standalone-YsZFFQBM.mjs.map +0 -1
  154. package/dist/tools-registry-D3NEoe5m.mjs +0 -1115
  155. package/dist/tools-registry-D3NEoe5m.mjs.map +0 -1
  156. package/plugin/scripts/diagnostics.d.mts +0 -17
  157. package/plugin/scripts/diagnostics.d.mts.map +0 -1
  158. package/plugin/scripts/diagnostics.mjs.map +0 -1
@@ -1,4 +1,5 @@
1
1
  #!/usr/bin/env node
2
+ import { createRequire } from "node:module";
2
3
  import { existsSync, mkdirSync, readFileSync, writeFileSync } from "node:fs";
3
4
  import { dirname, join } from "node:path";
4
5
  import { homedir } from "node:os";
@@ -47,6 +48,13 @@ var InMemoryKV = class {
47
48
  };
48
49
  //#endregion
49
50
  //#region src/mcp/transport.ts
51
+ var JsonRpcError = class extends Error {
52
+ constructor(code, message) {
53
+ super(message);
54
+ this.code = code;
55
+ this.name = "JsonRpcError";
56
+ }
57
+ };
50
58
  function isNotification(req) {
51
59
  return req.id === void 0 || req.id === null;
52
60
  }
@@ -112,7 +120,7 @@ async function processLine(line, handler, writeOut, writeErr = (msg) => process.
112
120
  jsonrpc: "2.0",
113
121
  id: request.id,
114
122
  error: {
115
- code: -32603,
123
+ code: err instanceof JsonRpcError ? err.code : -32603,
116
124
  message: err instanceof Error ? err.message : String(err)
117
125
  }
118
126
  });
@@ -283,6 +291,10 @@ const CORE_TOOLS = [
283
291
  project: {
284
292
  type: "string",
285
293
  description: "Stable canonical project identifier this memory belongs to (e.g. a slug, UUID, or registry key). Must match the value used when the session was started. Do not use filesystem paths or ad-hoc display names — those change across machines and will silently break project scoping."
294
+ },
295
+ agentId: {
296
+ type: "string",
297
+ description: "Agent identity to scope this memory to. When set, agent-scoped recall and search only surface it for the same agentId. Omit for shared memory."
286
298
  }
287
299
  },
288
300
  required: ["content"]
@@ -311,10 +323,16 @@ const CORE_TOOLS = [
311
323
  description: "Detect recurring patterns across sessions.",
312
324
  inputSchema: {
313
325
  type: "object",
314
- properties: { project: {
315
- type: "string",
316
- description: "Project path to analyze"
317
- } }
326
+ properties: {
327
+ project: {
328
+ type: "string",
329
+ description: "Project path to analyze"
330
+ },
331
+ limit: {
332
+ type: "integer",
333
+ description: "Most recent sessions to scan (default 50, max 500)"
334
+ }
335
+ }
318
336
  }
319
337
  },
320
338
  {
@@ -1141,6 +1159,18 @@ const V070_TOOLS = [
1141
1159
  required: ["query"]
1142
1160
  }
1143
1161
  },
1162
+ {
1163
+ name: "memory_lesson_delete",
1164
+ description: "Soft-delete a lesson by id. Deleted lessons are excluded from recall and list; re-saving the same content creates a fresh lesson.",
1165
+ inputSchema: {
1166
+ type: "object",
1167
+ properties: { lessonId: {
1168
+ type: "string",
1169
+ description: "The lesson id (lsn_...)"
1170
+ } },
1171
+ required: ["lessonId"]
1172
+ }
1173
+ },
1144
1174
  {
1145
1175
  name: "memory_obsidian_export",
1146
1176
  description: "Export memories, lessons, and crystals as Obsidian-compatible Markdown files with YAML frontmatter and wikilinks for graph view.",
@@ -1313,8 +1343,13 @@ function getAllTools() {
1313
1343
  ];
1314
1344
  }
1315
1345
  const ENV_FILE = join(join(homedir(), ".agentmemory"), ".env");
1346
+ let envFileCache;
1316
1347
  function loadEnvFile() {
1317
- if (!existsSync(ENV_FILE)) return {};
1348
+ if (envFileCache) return envFileCache;
1349
+ if (!existsSync(ENV_FILE)) {
1350
+ envFileCache = {};
1351
+ return envFileCache;
1352
+ }
1318
1353
  const content = readFileSync(ENV_FILE, "utf-8");
1319
1354
  const vars = {};
1320
1355
  for (const line of content.split("\n")) {
@@ -1334,7 +1369,8 @@ function loadEnvFile() {
1334
1369
  }
1335
1370
  vars[key] = val;
1336
1371
  }
1337
- return vars;
1372
+ envFileCache = vars;
1373
+ return envFileCache;
1338
1374
  }
1339
1375
  function getMergedEnv(overrides) {
1340
1376
  return {
@@ -1348,12 +1384,215 @@ function getStandalonePersistPath() {
1348
1384
  }
1349
1385
  //#endregion
1350
1386
  //#region src/version.ts
1351
- const VERSION = "0.9.28";
1387
+ const VERSION = "0.9.30";
1388
+ createRequire(import.meta.url);
1352
1389
  //#endregion
1353
1390
  //#region src/state/schema.ts
1391
+ const KV = {
1392
+ sessions: "mem:sessions",
1393
+ observations: (sessionId) => `mem:obs:${sessionId}`,
1394
+ memories: "mem:memories",
1395
+ summaries: "mem:summaries",
1396
+ config: "mem:config",
1397
+ metrics: "mem:metrics",
1398
+ health: "mem:health",
1399
+ embeddings: (obsId) => `mem:emb:${obsId}`,
1400
+ bm25Index: "mem:index:bm25",
1401
+ vectorPendingLog: "mem:index:vec-pending",
1402
+ relations: "mem:relations",
1403
+ profiles: "mem:profiles",
1404
+ claudeBridge: "mem:claude-bridge",
1405
+ graphNodes: "mem:graph:nodes",
1406
+ graphEdges: "mem:graph:edges",
1407
+ graphSnapshot: "mem:graph:snapshot",
1408
+ graphNameIndex: "mem:graph:name-index",
1409
+ graphEdgeKey: "mem:graph:edge-key",
1410
+ graphNodeDegree: "mem:graph:node-degree",
1411
+ semantic: "mem:semantic",
1412
+ procedural: "mem:procedural",
1413
+ teamShared: (teamId) => `mem:team:${teamId}:shared`,
1414
+ teamUsers: (teamId, userId) => `mem:team:${teamId}:users:${userId}`,
1415
+ teamProfile: (teamId) => `mem:team:${teamId}:profile`,
1416
+ audit: "mem:audit",
1417
+ auditMonth: (month) => `mem:audit:${month}`,
1418
+ auditMonths: "mem:audit:months",
1419
+ actions: "mem:actions",
1420
+ actionEdges: "mem:action-edges",
1421
+ leases: "mem:leases",
1422
+ routines: "mem:routines",
1423
+ routineRuns: "mem:routine-runs",
1424
+ signals: "mem:signals",
1425
+ checkpoints: "mem:checkpoints",
1426
+ mesh: "mem:mesh",
1427
+ sketches: "mem:sketches",
1428
+ facets: "mem:facets",
1429
+ sentinels: "mem:sentinels",
1430
+ crystals: "mem:crystals",
1431
+ lessons: "mem:lessons",
1432
+ insights: "mem:insights",
1433
+ graphEdgeHistory: "mem:graph:edge-history",
1434
+ enrichedChunks: (sessionId) => `mem:enriched:${sessionId}`,
1435
+ latentEmbeddings: (obsId) => `mem:latent:${obsId}`,
1436
+ retentionScores: "mem:retention",
1437
+ accessLog: "mem:access",
1438
+ imageRefs: "mem:image-refs",
1439
+ imageEmbeddings: "mem:image-embeddings",
1440
+ slots: "mem:slots",
1441
+ globalSlots: "mem:slots:global",
1442
+ state: "mem:state",
1443
+ commits: "mem:commits",
1444
+ recentSearches: "mem:recent-searches",
1445
+ projectSessionsIndex: "mem:idx:project-sessions",
1446
+ obsSessionIndex: (shard) => `mem:idx:obs:${shard}`,
1447
+ captureInbox: "mem:capture:inbox",
1448
+ captureEvents: (shard) => `mem:capture:events:${shard}`,
1449
+ capturePrompts: "mem:capture:prompts"
1450
+ };
1354
1451
  function generateId(prefix) {
1355
1452
  return `${prefix}_${Date.now().toString(36)}_${crypto.randomUUID().replace(/-/g, "").slice(0, 12)}`;
1356
1453
  }
1454
+ process.env["AGENTMEMORY_VERBOSE"] === "1" || process.env["AGENTMEMORY_VERBOSE"];
1455
+ KV.auditMonths;
1456
+ const AUDIT_MIGRATION_STATE_KEY = "migration";
1457
+ async function readAuditMigrationState(kv) {
1458
+ return kv.get(KV.auditMonths, AUDIT_MIGRATION_STATE_KEY);
1459
+ }
1460
+ function monthStartMs(month) {
1461
+ const [year, mon] = month.split("-").map(Number);
1462
+ return Date.UTC(year, mon - 1, 1);
1463
+ }
1464
+ function monthEndMs(month) {
1465
+ const [year, mon] = month.split("-").map(Number);
1466
+ return Date.UTC(year, mon, 1) - 1;
1467
+ }
1468
+ async function readAuditMonthIndex(kv) {
1469
+ return (await kv.get(KV.auditMonths, "index"))?.months ?? [];
1470
+ }
1471
+ async function listAuditMonthsDesc(kv) {
1472
+ return [...await readAuditMonthIndex(kv)].sort().reverse();
1473
+ }
1474
+ async function queryAudit(kv, filter) {
1475
+ const limit = filter?.limit || 100;
1476
+ let fromMs;
1477
+ if (filter?.dateFrom) {
1478
+ fromMs = new Date(filter.dateFrom).getTime();
1479
+ if (Number.isNaN(fromMs)) throw new Error(`Invalid dateFrom: ${filter.dateFrom}`);
1480
+ }
1481
+ const query = filter?.query?.trim().toLowerCase();
1482
+ let toMs;
1483
+ if (filter?.dateTo) {
1484
+ toMs = new Date(filter.dateTo).getTime();
1485
+ if (Number.isNaN(toMs)) throw new Error(`Invalid dateTo: ${filter.dateTo}`);
1486
+ }
1487
+ const matches = (entry) => {
1488
+ if (filter?.operation && entry.operation !== filter.operation) return false;
1489
+ const t = new Date(entry.timestamp).getTime();
1490
+ if (fromMs !== void 0 && t < fromMs) return false;
1491
+ if (toMs !== void 0 && t > toMs) return false;
1492
+ if (query && ![entry.functionId, ...entry.targetIds || []].some((v) => String(v || "").toLowerCase().includes(query))) return false;
1493
+ return true;
1494
+ };
1495
+ const seenIds = /* @__PURE__ */ new Set();
1496
+ const collected = [];
1497
+ const addIfNew = (row) => {
1498
+ if (seenIds.has(row.id)) return;
1499
+ seenIds.add(row.id);
1500
+ if (matches(row)) collected.push(row);
1501
+ };
1502
+ const months = await listAuditMonthsDesc(kv);
1503
+ for (const month of months) {
1504
+ if (collected.length >= limit) break;
1505
+ if (toMs !== void 0 && monthStartMs(month) > toMs) continue;
1506
+ if (fromMs !== void 0 && monthEndMs(month) < fromMs) break;
1507
+ const rows = await kv.list(KV.auditMonth(month));
1508
+ for (const row of rows) addIfNew(row);
1509
+ }
1510
+ let legacyFrozen = false;
1511
+ let legacyFrozenBytes;
1512
+ if (collected.length < limit) {
1513
+ const migrationState = await readAuditMigrationState(kv);
1514
+ if (migrationState?.safeToListLegacy) {
1515
+ const legacyRows = await kv.list(KV.audit);
1516
+ for (const row of legacyRows) addIfNew(row);
1517
+ } else if (migrationState?.status === "too-large" || migrationState?.status === "unreadable") {
1518
+ legacyFrozen = true;
1519
+ legacyFrozenBytes = migrationState.legacySizeBytes;
1520
+ }
1521
+ }
1522
+ collected.sort((a, b) => new Date(b.timestamp).getTime() - new Date(a.timestamp).getTime());
1523
+ return {
1524
+ entries: collected.slice(0, limit),
1525
+ legacyFrozen,
1526
+ legacyFrozenBytes
1527
+ };
1528
+ }
1529
+ //#endregion
1530
+ //#region src/secret-store.ts
1531
+ const SECRET_KEY = "AGENTMEMORY_SECRET";
1532
+ function agentmemoryHomeDir() {
1533
+ return join(homedir(), ".agentmemory");
1534
+ }
1535
+ function secretFilePath() {
1536
+ return join(agentmemoryHomeDir(), "secret");
1537
+ }
1538
+ function usable(value) {
1539
+ if (typeof value !== "string") return "";
1540
+ const trimmed = value.trim();
1541
+ if (!trimmed) return "";
1542
+ if (trimmed.startsWith("${") && trimmed.endsWith("}")) return "";
1543
+ return trimmed;
1544
+ }
1545
+ function unquote(value) {
1546
+ const quote = value[0];
1547
+ if ((quote === "\"" || quote === "'") && value.length > 1) {
1548
+ const close = value.indexOf(quote, 1);
1549
+ if (close !== -1) return value.slice(1, close);
1550
+ }
1551
+ const hash = value.indexOf(" #");
1552
+ return hash === -1 ? value : value.slice(0, hash).trim();
1553
+ }
1554
+ function readEnvFileSecret() {
1555
+ let content;
1556
+ try {
1557
+ content = readFileSync(join(agentmemoryHomeDir(), ".env"), "utf-8");
1558
+ } catch {
1559
+ return "";
1560
+ }
1561
+ if (typeof content !== "string") return "";
1562
+ let found = "";
1563
+ for (const line of content.split("\n")) {
1564
+ const trimmed = line.trim();
1565
+ if (trimmed.startsWith("#")) continue;
1566
+ const eq = trimmed.indexOf("=");
1567
+ if (eq === -1) continue;
1568
+ if (trimmed.slice(0, eq).replace(/^export\s+/, "").trim() !== SECRET_KEY) continue;
1569
+ found = usable(unquote(trimmed.slice(eq + 1).trim()));
1570
+ }
1571
+ return found;
1572
+ }
1573
+ function readStoredSecret() {
1574
+ try {
1575
+ return usable(readFileSync(secretFilePath(), "utf-8"));
1576
+ } catch {
1577
+ return "";
1578
+ }
1579
+ }
1580
+ function isLoopbackUrl(url) {
1581
+ let hostname;
1582
+ try {
1583
+ hostname = new URL(url).hostname.toLowerCase();
1584
+ } catch {
1585
+ return false;
1586
+ }
1587
+ const bare = hostname.replace(/^\[|\]$/g, "");
1588
+ return bare === "localhost" || bare === "::1" || /^127(?:\.\d{1,3}){3}$/.test(bare);
1589
+ }
1590
+ function resolveClientSecret(baseUrl, env = process.env) {
1591
+ const fromEnv = usable(env[SECRET_KEY]);
1592
+ if (fromEnv) return fromEnv;
1593
+ if (!isLoopbackUrl(baseUrl)) return "";
1594
+ return readEnvFileSecret() || readStoredSecret();
1595
+ }
1357
1596
  //#endregion
1358
1597
  //#region src/mcp/rest-proxy.ts
1359
1598
  const DEFAULT_URL = "http://localhost:3111";
@@ -1370,6 +1609,16 @@ function forceProxy() {
1370
1609
  const raw = process.env["AGENTMEMORY_FORCE_PROXY"];
1371
1610
  return raw === "1" || raw === "true";
1372
1611
  }
1612
+ var ProxyCallError = class extends Error {
1613
+ status;
1614
+ body;
1615
+ constructor(message, status, body) {
1616
+ super(message);
1617
+ this.name = "ProxyCallError";
1618
+ this.status = status;
1619
+ this.body = body;
1620
+ }
1621
+ };
1373
1622
  let cached = null;
1374
1623
  let cachedAt = 0;
1375
1624
  let probeInFlight = null;
@@ -1383,7 +1632,7 @@ function baseUrl() {
1383
1632
  return (resolveEnvOrEmpty("AGENTMEMORY_URL") || DEFAULT_URL).replace(/\/+$/, "");
1384
1633
  }
1385
1634
  function authHeader() {
1386
- const secret = resolveEnvOrEmpty("AGENTMEMORY_SECRET");
1635
+ const secret = resolveClientSecret(baseUrl());
1387
1636
  return secret ? { authorization: `Bearer ${secret}` } : {};
1388
1637
  }
1389
1638
  const defaultLivezProbe = async (url, timeoutMs, headers) => {
@@ -1440,7 +1689,16 @@ async function resolveHandle() {
1440
1689
  },
1441
1690
  signal: AbortSignal.timeout(CALL_TIMEOUT_MS)
1442
1691
  });
1443
- if (!res.ok) throw new Error(`${init?.method || "GET"} ${path} -> ${res.status} ${res.statusText}`);
1692
+ if (!res.ok) {
1693
+ const errText = await res.text().catch(() => "");
1694
+ let errBody = void 0;
1695
+ if (errText) try {
1696
+ errBody = JSON.parse(errText);
1697
+ } catch {
1698
+ errBody = void 0;
1699
+ }
1700
+ throw new ProxyCallError(`${init?.method || "GET"} ${path} -> ${res.status} ${res.statusText}`, res.status, errBody);
1701
+ }
1444
1702
  const text = await res.text();
1445
1703
  return text ? JSON.parse(text) : null;
1446
1704
  }
@@ -1471,10 +1729,15 @@ const IMPLEMENTED_TOOLS = new Set([
1471
1729
  "memory_audit",
1472
1730
  "memory_governance_delete"
1473
1731
  ]);
1732
+ const SUPPORTED_PROTOCOL_VERSIONS = [
1733
+ "2025-11-25",
1734
+ "2025-06-18",
1735
+ "2025-03-26",
1736
+ "2024-11-05"
1737
+ ];
1474
1738
  const SERVER_INFO = {
1475
1739
  name: "agentmemory",
1476
- version: VERSION,
1477
- protocolVersion: "2024-11-05"
1740
+ version: VERSION
1478
1741
  };
1479
1742
  const kv = new InMemoryKV(getStandalonePersistPath());
1480
1743
  let modeAnnounced = false;
@@ -1523,6 +1786,8 @@ function validate(toolName, args) {
1523
1786
  v.type = args["type"] || "fact";
1524
1787
  v.concepts = normalizeList(args["concepts"]);
1525
1788
  v.files = normalizeList(args["files"]);
1789
+ if (typeof args["project"] === "string" && args["project"].trim()) v.project = args["project"].trim();
1790
+ if (typeof args["agentId"] === "string" && args["agentId"].trim()) v.agentId = args["agentId"].trim();
1526
1791
  return v;
1527
1792
  }
1528
1793
  case "memory_recall":
@@ -1566,7 +1831,9 @@ async function handleProxy(v, handle) {
1566
1831
  content: v.content,
1567
1832
  type: v.type,
1568
1833
  concepts: v.concepts,
1569
- files: v.files
1834
+ files: v.files,
1835
+ ...v.project !== void 0 && { project: v.project },
1836
+ ...v.agentId !== void 0 && { agentId: v.agentId }
1570
1837
  })
1571
1838
  }));
1572
1839
  case "memory_recall": {
@@ -1601,7 +1868,12 @@ async function handleProxy(v, handle) {
1601
1868
  reason: v.reason
1602
1869
  })
1603
1870
  }));
1604
- case "memory_export": return textResponse(await handle.call("/agentmemory/export", { method: "GET" }), true);
1871
+ case "memory_export": try {
1872
+ return textResponse(await handle.call("/agentmemory/export", { method: "GET" }), true);
1873
+ } catch (err) {
1874
+ if (err instanceof ProxyCallError && err.body != null && typeof err.body === "object" && err.body.oversized === true) return textResponse(err.body, true);
1875
+ throw err;
1876
+ }
1605
1877
  case "memory_audit": return textResponse(await handle.call(`/agentmemory/audit?limit=${v.limit}`, { method: "GET" }), true);
1606
1878
  default: throw new Error(`Unknown tool: ${v.tool}`);
1607
1879
  }
@@ -1670,11 +1942,7 @@ async function handleLocal(v, kvInstance) {
1670
1942
  memories: await kvInstance.list("mem:memories"),
1671
1943
  sessions: await kvInstance.list("mem:sessions")
1672
1944
  }, true);
1673
- case "memory_audit": {
1674
- const entries = await kvInstance.list("mem:audit");
1675
- const limit = v.limit ?? 50;
1676
- return textResponse({ entries: entries.slice(0, limit) }, true);
1677
- }
1945
+ case "memory_audit": return textResponse(await queryAudit(kvInstance, { limit: v.limit ?? 50 }), true);
1678
1946
  default: throw new Error(`Unknown tool: ${v.tool}`);
1679
1947
  }
1680
1948
  }
@@ -1737,14 +2005,17 @@ async function handleToolsList() {
1737
2005
  }
1738
2006
  const transport = createStdioTransport(async (method, params) => {
1739
2007
  switch (method) {
1740
- case "initialize": return {
1741
- protocolVersion: SERVER_INFO.protocolVersion,
1742
- capabilities: { tools: { listChanged: false } },
1743
- serverInfo: {
1744
- name: SERVER_INFO.name,
1745
- version: SERVER_INFO.version
1746
- }
1747
- };
2008
+ case "initialize": {
2009
+ const requested = params?.protocolVersion;
2010
+ return {
2011
+ protocolVersion: typeof requested === "string" && SUPPORTED_PROTOCOL_VERSIONS.includes(requested) ? requested : SUPPORTED_PROTOCOL_VERSIONS[0],
2012
+ capabilities: { tools: { listChanged: false } },
2013
+ serverInfo: {
2014
+ name: SERVER_INFO.name,
2015
+ version: SERVER_INFO.version
2016
+ }
2017
+ };
2018
+ }
1748
2019
  case "notifications/initialized": return {};
1749
2020
  case "tools/list": return handleToolsList();
1750
2021
  case "tools/call": {