@agentmemory/agentmemory 0.9.20 → 0.9.22

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 (55) hide show
  1. package/.env.example +2 -0
  2. package/README.md +166 -12
  3. package/dist/.env.example +2 -0
  4. package/dist/cli.d.mts +5 -1
  5. package/dist/cli.d.mts.map +1 -0
  6. package/dist/cli.mjs +122 -693
  7. package/dist/cli.mjs.map +1 -1
  8. package/dist/connect-BQQXpyDS.mjs +763 -0
  9. package/dist/connect-BQQXpyDS.mjs.map +1 -0
  10. package/dist/hooks/post-tool-use.mjs +1 -1
  11. package/dist/hooks/post-tool-use.mjs.map +1 -1
  12. package/dist/hooks/stop.mjs +8 -0
  13. package/dist/hooks/stop.mjs.map +1 -1
  14. package/dist/{image-refs-R3tin9MR.mjs → image-refs-CJS5B9Gq.mjs} +2 -2
  15. package/dist/{image-refs-R3tin9MR.mjs.map → image-refs-CJS5B9Gq.mjs.map} +1 -1
  16. package/dist/{image-store-DyrKZKqZ.mjs → image-store-CdE0amb1.mjs} +1 -1
  17. package/dist/index.mjs +881 -281
  18. package/dist/index.mjs.map +1 -1
  19. package/dist/logger-xlVlvCWX.mjs +43 -0
  20. package/dist/logger-xlVlvCWX.mjs.map +1 -0
  21. package/dist/schema-BkALl7Z_.mjs +74 -0
  22. package/dist/schema-BkALl7Z_.mjs.map +1 -0
  23. package/dist/{src-DPSaLB5-.mjs → src-gpTAJuBy.mjs} +861 -287
  24. package/dist/src-gpTAJuBy.mjs.map +1 -0
  25. package/dist/{standalone-DMLk7YxP.mjs → standalone-C4i7ktpn.mjs} +48 -12
  26. package/dist/standalone-C4i7ktpn.mjs.map +1 -0
  27. package/dist/standalone.d.mts.map +1 -1
  28. package/dist/standalone.mjs +45 -10
  29. package/dist/standalone.mjs.map +1 -1
  30. package/dist/{tools-registry-Dz8ssuMf.mjs → tools-registry-B7Y6nJsr.mjs} +39 -11
  31. package/dist/tools-registry-B7Y6nJsr.mjs.map +1 -0
  32. package/dist/version-DvQMNbEH.mjs +6 -0
  33. package/dist/version-DvQMNbEH.mjs.map +1 -0
  34. package/dist/viewer/index.html +134 -21
  35. package/package.json +6 -4
  36. package/plugin/.claude-plugin/plugin.json +1 -1
  37. package/plugin/.codex-plugin/plugin.json +1 -1
  38. package/plugin/.mcp.json +3 -2
  39. package/plugin/hooks/hooks.codex.json +6 -6
  40. package/plugin/hooks/hooks.json +12 -12
  41. package/plugin/opencode/README.md +229 -0
  42. package/plugin/opencode/agentmemory-capture.ts +687 -0
  43. package/plugin/opencode/commands/recall.md +19 -0
  44. package/plugin/opencode/commands/remember.md +19 -0
  45. package/plugin/opencode/plugin.json +12 -0
  46. package/plugin/scripts/diagnostics.d.mts +17 -0
  47. package/plugin/scripts/diagnostics.d.mts.map +1 -0
  48. package/plugin/scripts/diagnostics.mjs.map +1 -0
  49. package/plugin/scripts/post-tool-use.mjs +1 -1
  50. package/plugin/scripts/post-tool-use.mjs.map +1 -1
  51. package/plugin/scripts/stop.mjs +8 -0
  52. package/plugin/scripts/stop.mjs.map +1 -1
  53. package/dist/src-DPSaLB5-.mjs.map +0 -1
  54. package/dist/standalone-DMLk7YxP.mjs.map +0 -1
  55. package/dist/tools-registry-Dz8ssuMf.mjs.map +0 -1
@@ -0,0 +1,43 @@
1
+ //#region src/logger.ts
2
+ function fmt(level, msg, fields) {
3
+ if (!fields || Object.keys(fields).length === 0) return `[agentmemory] ${level} ${msg}`;
4
+ try {
5
+ return `[agentmemory] ${level} ${msg} ${JSON.stringify(fields)}`;
6
+ } catch {
7
+ return `[agentmemory] ${level} ${msg}`;
8
+ }
9
+ }
10
+ function emit(level, msg, fields) {
11
+ try {
12
+ process.stderr.write(fmt(level, msg, fields) + "\n");
13
+ } catch {}
14
+ }
15
+ const logger = {
16
+ info(msg, fields) {
17
+ emit("info", msg, fields);
18
+ },
19
+ warn(msg, fields) {
20
+ emit("warn", msg, fields);
21
+ },
22
+ error(msg, fields) {
23
+ emit("error", msg, fields);
24
+ }
25
+ };
26
+ let bootVerbose = process.env["AGENTMEMORY_VERBOSE"] === "1" || process.env["AGENTMEMORY_VERBOSE"] === "true";
27
+ const bootBuffer = [];
28
+ function setBootVerbose(enabled) {
29
+ bootVerbose = enabled;
30
+ }
31
+ function bootLog(msg) {
32
+ if (bootVerbose) {
33
+ try {
34
+ process.stderr.write(`[agentmemory] ${msg}\n`);
35
+ } catch {}
36
+ return;
37
+ }
38
+ if (bootBuffer.length < 500) bootBuffer.push(msg);
39
+ }
40
+
41
+ //#endregion
42
+ export { logger as n, setBootVerbose as r, bootLog as t };
43
+ //# sourceMappingURL=logger-xlVlvCWX.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"logger-xlVlvCWX.mjs","names":[],"sources":["../src/logger.ts"],"sourcesContent":["// Thin logging shim for agentmemory.\n//\n// iii-sdk v0.11 dropped `getContext()`, which had been the source of a\n// contextual logger in every function handler (`getContext().logger`).\n// Migrating directly to the v0.11 OTEL-based `getLogger()` would force\n// every call site to care about the OTEL Logger API shape (`emit(...)`\n// with severity numbers and attributes maps). Instead, this module\n// exposes a single `logger` singleton with the same `.info/.warn/.error`\n// signature the old code used, so the mechanical replacement across\n// 30+ function files is: drop the `getContext` import, drop the\n// `const ctx = getContext();` line, and rename `ctx.logger.*` to\n// `logger.*`. Nothing else changes.\n//\n// Output goes to stderr as `[agentmemory] <level> <msg> <json-fields>`.\n// The iii-engine's `iii-exec` worker runs the agentmemory binary as a\n// child process and forwards stderr into `docker logs\n// agentmemory-iii-engine-1`, so these lines end up next to the engine's\n// own output without needing any OTEL wiring. If we later want\n// structured OTEL logs, this file is the only thing that changes.\n//\n// See rohitg00/agentmemory#143 follow-up — the #116 migration updated\n// test mocks but left the real `getContext()` imports in place, which\n// passed `npm test` (tests mock iii-sdk) and `npm run build` (tsdown\n// doesn't type-check) but crashed `node dist/index.mjs` on first\n// import.\n\ntype Fields = Record<string, unknown> | undefined;\n\nfunction fmt(level: string, msg: string, fields: Fields): string {\n if (!fields || Object.keys(fields).length === 0) {\n return `[agentmemory] ${level} ${msg}`;\n }\n try {\n return `[agentmemory] ${level} ${msg} ${JSON.stringify(fields)}`;\n } catch {\n // Fields contained a circular reference or a BigInt — fall back\n // to the plain message so a log line never throws.\n return `[agentmemory] ${level} ${msg}`;\n }\n}\n\nfunction emit(level: string, msg: string, fields: Fields): void {\n try {\n process.stderr.write(fmt(level, msg, fields) + \"\\n\");\n } catch {\n // stderr is unavailable in some weird test/worker contexts — swallow\n // so no log line can ever crash a handler.\n }\n}\n\nexport const logger = {\n info(msg: string, fields?: Fields): void {\n emit(\"info\", msg, fields);\n },\n warn(msg: string, fields?: Fields): void {\n emit(\"warn\", msg, fields);\n },\n error(msg: string, fields?: Fields): void {\n emit(\"error\", msg, fields);\n },\n};\n\n// ---------- boot log ----------\n//\n// `bootLog` is for the one-shot status lines that every register-*\n// function used to dump via `console.log` during engine startup. On a\n// fresh install that's ~25 lines of `[agentmemory] X enabled` noise\n// before the user can see a prompt. In quiet mode (default), each\n// line is captured into a buffer and discarded; the CLI surfaces a\n// single compressed summary instead. In verbose mode (set by\n// `--verbose` or `AGENTMEMORY_VERBOSE=1`) the lines pass straight\n// through to stderr exactly like the old console.log calls.\n\nlet bootVerbose =\n process.env[\"AGENTMEMORY_VERBOSE\"] === \"1\" ||\n process.env[\"AGENTMEMORY_VERBOSE\"] === \"true\";\n\nconst bootBuffer: string[] = [];\n\nexport function setBootVerbose(enabled: boolean): void {\n bootVerbose = enabled;\n}\n\nexport function isBootVerbose(): boolean {\n return bootVerbose;\n}\n\nexport function bootLog(msg: string): void {\n if (bootVerbose) {\n try {\n process.stderr.write(`[agentmemory] ${msg}\\n`);\n } catch {\n // stderr unavailable — drop.\n }\n return;\n }\n if (bootBuffer.length < 500) bootBuffer.push(msg);\n}\n\nexport function bootWarn(msg: string): void {\n // Warnings always surface; they're rare and the user needs to see\n // them even when the rest of the boot log is suppressed.\n try {\n process.stderr.write(`[agentmemory] warn ${msg}\\n`);\n } catch {}\n}\n\nexport function getBootBuffer(): readonly string[] {\n return bootBuffer;\n}\n"],"mappings":";AA4BA,SAAS,IAAI,OAAe,KAAa,QAAwB;AAC/D,KAAI,CAAC,UAAU,OAAO,KAAK,OAAO,CAAC,WAAW,EAC5C,QAAO,iBAAiB,MAAM,GAAG;AAEnC,KAAI;AACF,SAAO,iBAAiB,MAAM,GAAG,IAAI,GAAG,KAAK,UAAU,OAAO;SACxD;AAGN,SAAO,iBAAiB,MAAM,GAAG;;;AAIrC,SAAS,KAAK,OAAe,KAAa,QAAsB;AAC9D,KAAI;AACF,UAAQ,OAAO,MAAM,IAAI,OAAO,KAAK,OAAO,GAAG,KAAK;SAC9C;;AAMV,MAAa,SAAS;CACpB,KAAK,KAAa,QAAuB;AACvC,OAAK,QAAQ,KAAK,OAAO;;CAE3B,KAAK,KAAa,QAAuB;AACvC,OAAK,QAAQ,KAAK,OAAO;;CAE3B,MAAM,KAAa,QAAuB;AACxC,OAAK,SAAS,KAAK,OAAO;;CAE7B;AAaD,IAAI,cACF,QAAQ,IAAI,2BAA2B,OACvC,QAAQ,IAAI,2BAA2B;AAEzC,MAAM,aAAuB,EAAE;AAE/B,SAAgB,eAAe,SAAwB;AACrD,eAAc;;AAOhB,SAAgB,QAAQ,KAAmB;AACzC,KAAI,aAAa;AACf,MAAI;AACF,WAAQ,OAAO,MAAM,iBAAiB,IAAI,IAAI;UACxC;AAGR;;AAEF,KAAI,WAAW,SAAS,IAAK,YAAW,KAAK,IAAI"}
@@ -0,0 +1,74 @@
1
+ import { createHash } from "node:crypto";
2
+
3
+ //#region src/state/schema.ts
4
+ const KV = {
5
+ sessions: "mem:sessions",
6
+ observations: (sessionId) => `mem:obs:${sessionId}`,
7
+ memories: "mem:memories",
8
+ summaries: "mem:summaries",
9
+ config: "mem:config",
10
+ metrics: "mem:metrics",
11
+ health: "mem:health",
12
+ embeddings: (obsId) => `mem:emb:${obsId}`,
13
+ bm25Index: "mem:index:bm25",
14
+ relations: "mem:relations",
15
+ profiles: "mem:profiles",
16
+ claudeBridge: "mem:claude-bridge",
17
+ graphNodes: "mem:graph:nodes",
18
+ graphEdges: "mem:graph:edges",
19
+ semantic: "mem:semantic",
20
+ procedural: "mem:procedural",
21
+ teamShared: (teamId) => `mem:team:${teamId}:shared`,
22
+ teamUsers: (teamId, userId) => `mem:team:${teamId}:users:${userId}`,
23
+ teamProfile: (teamId) => `mem:team:${teamId}:profile`,
24
+ audit: "mem:audit",
25
+ actions: "mem:actions",
26
+ actionEdges: "mem:action-edges",
27
+ leases: "mem:leases",
28
+ routines: "mem:routines",
29
+ routineRuns: "mem:routine-runs",
30
+ signals: "mem:signals",
31
+ checkpoints: "mem:checkpoints",
32
+ mesh: "mem:mesh",
33
+ sketches: "mem:sketches",
34
+ facets: "mem:facets",
35
+ sentinels: "mem:sentinels",
36
+ crystals: "mem:crystals",
37
+ lessons: "mem:lessons",
38
+ insights: "mem:insights",
39
+ graphEdgeHistory: "mem:graph:edge-history",
40
+ enrichedChunks: (sessionId) => `mem:enriched:${sessionId}`,
41
+ latentEmbeddings: (obsId) => `mem:latent:${obsId}`,
42
+ retentionScores: "mem:retention",
43
+ accessLog: "mem:access",
44
+ imageRefs: "mem:image-refs",
45
+ imageEmbeddings: "mem:image-embeddings",
46
+ slots: "mem:slots",
47
+ globalSlots: "mem:slots:global",
48
+ state: "mem:state",
49
+ commits: "mem:commits"
50
+ };
51
+ const STREAM = {
52
+ name: "mem-live",
53
+ group: (sessionId) => sessionId,
54
+ viewerGroup: "viewer"
55
+ };
56
+ function generateId(prefix) {
57
+ return `${prefix}_${Date.now().toString(36)}_${crypto.randomUUID().replace(/-/g, "").slice(0, 12)}`;
58
+ }
59
+ function fingerprintId(prefix, content) {
60
+ return `${prefix}_${createHash("sha256").update(content).digest("hex").slice(0, 16)}`;
61
+ }
62
+ function jaccardSimilarity(a, b) {
63
+ const setA = new Set(a.split(/\s+/).filter((t) => t.length > 2));
64
+ const setB = new Set(b.split(/\s+/).filter((t) => t.length > 2));
65
+ if (setA.size === 0 && setB.size === 0) return 1;
66
+ if (setA.size === 0 || setB.size === 0) return 0;
67
+ let intersection = 0;
68
+ for (const word of setA) if (setB.has(word)) intersection++;
69
+ return intersection / (setA.size + setB.size - intersection);
70
+ }
71
+
72
+ //#endregion
73
+ export { jaccardSimilarity as a, generateId as i, STREAM as n, fingerprintId as r, KV as t };
74
+ //# sourceMappingURL=schema-BkALl7Z_.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"schema-BkALl7Z_.mjs","names":[],"sources":["../src/state/schema.ts"],"sourcesContent":["import { createHash } from \"node:crypto\";\n\nexport const KV = {\n sessions: \"mem:sessions\",\n observations: (sessionId: string) => `mem:obs:${sessionId}`,\n memories: \"mem:memories\",\n summaries: \"mem:summaries\",\n config: \"mem:config\",\n metrics: \"mem:metrics\",\n health: \"mem:health\",\n embeddings: (obsId: string) => `mem:emb:${obsId}`,\n bm25Index: \"mem:index:bm25\",\n relations: \"mem:relations\",\n profiles: \"mem:profiles\",\n claudeBridge: \"mem:claude-bridge\",\n graphNodes: \"mem:graph:nodes\",\n graphEdges: \"mem:graph:edges\",\n semantic: \"mem:semantic\",\n procedural: \"mem:procedural\",\n teamShared: (teamId: string) => `mem:team:${teamId}:shared`,\n teamUsers: (teamId: string, userId: string) =>\n `mem:team:${teamId}:users:${userId}`,\n teamProfile: (teamId: string) => `mem:team:${teamId}:profile`,\n audit: \"mem:audit\",\n actions: \"mem:actions\",\n actionEdges: \"mem:action-edges\",\n leases: \"mem:leases\",\n routines: \"mem:routines\",\n routineRuns: \"mem:routine-runs\",\n signals: \"mem:signals\",\n checkpoints: \"mem:checkpoints\",\n mesh: \"mem:mesh\",\n sketches: \"mem:sketches\",\n facets: \"mem:facets\",\n sentinels: \"mem:sentinels\",\n crystals: \"mem:crystals\",\n lessons: \"mem:lessons\",\n insights: \"mem:insights\",\n graphEdgeHistory: \"mem:graph:edge-history\",\n enrichedChunks: (sessionId: string) => `mem:enriched:${sessionId}`,\n latentEmbeddings: (obsId: string) => `mem:latent:${obsId}`,\n retentionScores: \"mem:retention\",\n accessLog: \"mem:access\",\n imageRefs: \"mem:image-refs\",\n imageEmbeddings: \"mem:image-embeddings\",\n slots: \"mem:slots\",\n globalSlots: \"mem:slots:global\",\n state: \"mem:state\",\n commits: \"mem:commits\",\n} as const;\n\nexport const STREAM = {\n name: \"mem-live\",\n group: (sessionId: string) => sessionId,\n viewerGroup: \"viewer\",\n} as const;\n\nexport function generateId(prefix: string): string {\n const ts = Date.now().toString(36);\n const rand = crypto.randomUUID().replace(/-/g, \"\").slice(0, 12);\n return `${prefix}_${ts}_${rand}`;\n}\n\nexport function fingerprintId(prefix: string, content: string): string {\n const hash = createHash(\"sha256\").update(content).digest(\"hex\");\n return `${prefix}_${hash.slice(0, 16)}`;\n}\n\nexport function jaccardSimilarity(a: string, b: string): number {\n const setA = new Set(a.split(/\\s+/).filter((t) => t.length > 2));\n const setB = new Set(b.split(/\\s+/).filter((t) => t.length > 2));\n if (setA.size === 0 && setB.size === 0) return 1;\n if (setA.size === 0 || setB.size === 0) return 0;\n let intersection = 0;\n for (const word of setA) {\n if (setB.has(word)) intersection++;\n }\n return intersection / (setA.size + setB.size - intersection);\n}\n"],"mappings":";;;AAEA,MAAa,KAAK;CAChB,UAAU;CACV,eAAe,cAAsB,WAAW;CAChD,UAAU;CACV,WAAW;CACX,QAAQ;CACR,SAAS;CACT,QAAQ;CACR,aAAa,UAAkB,WAAW;CAC1C,WAAW;CACX,WAAW;CACX,UAAU;CACV,cAAc;CACd,YAAY;CACZ,YAAY;CACZ,UAAU;CACV,YAAY;CACZ,aAAa,WAAmB,YAAY,OAAO;CACnD,YAAY,QAAgB,WAC1B,YAAY,OAAO,SAAS;CAC9B,cAAc,WAAmB,YAAY,OAAO;CACpD,OAAO;CACP,SAAS;CACT,aAAa;CACb,QAAQ;CACR,UAAU;CACV,aAAa;CACb,SAAS;CACT,aAAa;CACb,MAAM;CACN,UAAU;CACV,QAAQ;CACR,WAAW;CACX,UAAU;CACV,SAAS;CACT,UAAU;CACV,kBAAkB;CAClB,iBAAiB,cAAsB,gBAAgB;CACvD,mBAAmB,UAAkB,cAAc;CACnD,iBAAiB;CACjB,WAAW;CACX,WAAW;CACX,iBAAiB;CACjB,OAAO;CACP,aAAa;CACb,OAAO;CACP,SAAS;CACV;AAED,MAAa,SAAS;CACpB,MAAM;CACN,QAAQ,cAAsB;CAC9B,aAAa;CACd;AAED,SAAgB,WAAW,QAAwB;AAGjD,QAAO,GAAG,OAAO,GAFN,KAAK,KAAK,CAAC,SAAS,GAAG,CAEX,GADV,OAAO,YAAY,CAAC,QAAQ,MAAM,GAAG,CAAC,MAAM,GAAG,GAAG;;AAIjE,SAAgB,cAAc,QAAgB,SAAyB;AAErE,QAAO,GAAG,OAAO,GADJ,WAAW,SAAS,CAAC,OAAO,QAAQ,CAAC,OAAO,MAAM,CACtC,MAAM,GAAG,GAAG;;AAGvC,SAAgB,kBAAkB,GAAW,GAAmB;CAC9D,MAAM,OAAO,IAAI,IAAI,EAAE,MAAM,MAAM,CAAC,QAAQ,MAAM,EAAE,SAAS,EAAE,CAAC;CAChE,MAAM,OAAO,IAAI,IAAI,EAAE,MAAM,MAAM,CAAC,QAAQ,MAAM,EAAE,SAAS,EAAE,CAAC;AAChE,KAAI,KAAK,SAAS,KAAK,KAAK,SAAS,EAAG,QAAO;AAC/C,KAAI,KAAK,SAAS,KAAK,KAAK,SAAS,EAAG,QAAO;CAC/C,IAAI,eAAe;AACnB,MAAK,MAAM,QAAQ,KACjB,KAAI,KAAK,IAAI,KAAK,CAAE;AAEtB,QAAO,gBAAgB,KAAK,OAAO,KAAK,OAAO"}