claude-memory-layer 1.0.26 → 1.0.28

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 (328) hide show
  1. package/.env.example +7 -0
  2. package/AGENTS.md +11 -0
  3. package/README.md +184 -41
  4. package/benchmarks/replay/anonymized-real-sessions.json +48 -0
  5. package/dist/cli/index.js +10097 -6003
  6. package/dist/cli/index.js.map +4 -4
  7. package/dist/core/index.js +9745 -5587
  8. package/dist/core/index.js.map +4 -4
  9. package/dist/hooks/post-tool-use.js +6545 -5270
  10. package/dist/hooks/post-tool-use.js.map +4 -4
  11. package/dist/hooks/semantic-daemon.js +6646 -5354
  12. package/dist/hooks/semantic-daemon.js.map +4 -4
  13. package/dist/hooks/session-end.js +6618 -5347
  14. package/dist/hooks/session-end.js.map +4 -4
  15. package/dist/hooks/session-start.js +6619 -5354
  16. package/dist/hooks/session-start.js.map +4 -4
  17. package/dist/hooks/stop.js +6614 -5325
  18. package/dist/hooks/stop.js.map +4 -4
  19. package/dist/hooks/user-prompt-submit.js +6702 -5356
  20. package/dist/hooks/user-prompt-submit.js.map +4 -4
  21. package/dist/index.js +13537 -0
  22. package/dist/index.js.map +7 -0
  23. package/dist/mcp/index.js +20770 -0
  24. package/dist/mcp/index.js.map +7 -0
  25. package/dist/server/api/index.js +6632 -5319
  26. package/dist/server/api/index.js.map +4 -4
  27. package/dist/server/index.js +6667 -5340
  28. package/dist/server/index.js.map +4 -4
  29. package/dist/services/memory-service.js +6568 -5350
  30. package/dist/services/memory-service.js.map +4 -4
  31. package/dist/ui/assets/js/bootstrap.js +244 -0
  32. package/dist/ui/assets/js/chat.js +373 -0
  33. package/dist/ui/assets/js/disclosure.js +232 -0
  34. package/dist/ui/assets/js/modals.js +298 -0
  35. package/dist/ui/assets/js/overview.js +655 -0
  36. package/dist/ui/assets/js/state.js +72 -0
  37. package/dist/ui/assets/js/views.js +468 -0
  38. package/dist/ui/index.html +43 -1
  39. package/dist/ui/index.ts +3 -0
  40. package/dist/ui/style.css +222 -0
  41. package/docs/ARCHITECTURE_COMPARISON_AND_RECOMMENDATIONS.md +627 -0
  42. package/docs/HERMES_MEMORY_INGESTION_ANALYSIS.md +440 -0
  43. package/docs/MEMORY_USEFULNESS_AUDIT.md +371 -0
  44. package/docs/MEMORY_USEFULNESS_AUDIT_RAW.json +80 -0
  45. package/docs/MEMSEARCH_PROJECT_STRUCTURE_ANALYSIS.md +333 -0
  46. package/docs/PRODUCT_VALIDATION_MATRIX.md +82 -0
  47. package/docs/PROJECT_STRUCTURE_ANALYSIS.md +421 -0
  48. package/docs/REFACTORING_MILESTONES_AND_ISSUES.md +501 -0
  49. package/docs/REFACTORING_PLAN_THIN_CORE.md +414 -0
  50. package/docs/REFERENCE_PROJECT_ANALYSES.md +25 -0
  51. package/docs/SUPERLOCALMEMORY_PROJECT_STRUCTURE_ANALYSIS.md +452 -0
  52. package/docs/TARGET_ARCHITECTURE_AND_FOLDER_STRUCTURE.md +446 -0
  53. package/docs/architecture/comparison-index.md +47 -0
  54. package/docs/reports/codex-real-data-validation-20260505T040447Z.md +46 -0
  55. package/package.json +9 -5
  56. package/scripts/build.ts +25 -8
  57. package/scripts/generate-session-qrels.ts +126 -0
  58. package/scripts/replay-retrieval-benchmark.ts +69 -0
  59. package/specs/thin-core-refactor/context.md +275 -0
  60. package/specs/thin-core-refactor/plan.md +536 -0
  61. package/specs/thin-core-refactor/spec.md +465 -0
  62. package/src/adapters/claude/capture/index.ts +3 -0
  63. package/src/adapters/claude/context/index.ts +3 -0
  64. package/src/adapters/claude/hooks/index.ts +21 -0
  65. package/src/adapters/claude/hooks/post-tool-use.ts +239 -0
  66. package/src/adapters/claude/hooks/prompt-injection-policy.ts +104 -0
  67. package/src/adapters/claude/hooks/semantic-daemon-client.ts +209 -0
  68. package/src/adapters/claude/hooks/semantic-daemon.ts +283 -0
  69. package/src/adapters/claude/hooks/session-end.ts +59 -0
  70. package/src/adapters/claude/hooks/session-start.ts +73 -0
  71. package/src/adapters/claude/hooks/stop.ts +128 -0
  72. package/src/adapters/claude/hooks/user-prompt-submit.ts +361 -0
  73. package/src/adapters/claude/index.ts +4 -0
  74. package/src/adapters/claude/transcript/index.ts +4 -0
  75. package/src/adapters/claude/transcript/transcript-reader.ts +57 -0
  76. package/src/adapters/claude/transcript/turn-reconstructor.ts +65 -0
  77. package/src/apps/cli/claude-settings-hooks.ts +138 -0
  78. package/src/apps/cli/codex-import-runner.ts +125 -0
  79. package/src/apps/cli/codex-validation-output.ts +95 -0
  80. package/src/apps/cli/hermes-import-runner.ts +130 -0
  81. package/src/apps/cli/hermes-validation-output.ts +91 -0
  82. package/src/apps/cli/index.ts +1731 -0
  83. package/src/apps/cli/mcp-install.ts +106 -0
  84. package/src/apps/cli/retrieval-disclosure-output.ts +196 -0
  85. package/src/apps/dashboard/assets/js/bootstrap.js +244 -0
  86. package/src/apps/dashboard/assets/js/chat.js +373 -0
  87. package/src/apps/dashboard/assets/js/disclosure.js +232 -0
  88. package/src/apps/dashboard/assets/js/modals.js +298 -0
  89. package/src/apps/dashboard/assets/js/overview.js +655 -0
  90. package/src/apps/dashboard/assets/js/state.js +72 -0
  91. package/src/apps/dashboard/assets/js/views.js +468 -0
  92. package/src/{ui → apps/dashboard}/index.html +43 -1
  93. package/src/apps/dashboard/index.ts +3 -0
  94. package/src/{ui → apps/dashboard}/style.css +222 -0
  95. package/src/apps/index.ts +5 -0
  96. package/src/apps/server/api/chat.ts +244 -0
  97. package/src/apps/server/api/citations.ts +105 -0
  98. package/src/apps/server/api/events.ts +137 -0
  99. package/src/apps/server/api/health.ts +53 -0
  100. package/src/apps/server/api/index.ts +26 -0
  101. package/src/apps/server/api/projects.ts +74 -0
  102. package/src/apps/server/api/search.ts +184 -0
  103. package/src/apps/server/api/sessions.ts +115 -0
  104. package/src/apps/server/api/stats.ts +723 -0
  105. package/src/apps/server/api/turns.ts +143 -0
  106. package/src/apps/server/api/utils.ts +65 -0
  107. package/src/apps/server/index.ts +111 -0
  108. package/src/cli/index.ts +2 -1311
  109. package/src/cli/retrieval-disclosure-output.ts +2 -0
  110. package/src/compat/index.ts +5 -0
  111. package/src/core/derive/fact-deriver.ts +170 -0
  112. package/src/core/derive/index.ts +2 -0
  113. package/src/core/derive/summary-deriver.ts +76 -0
  114. package/src/core/embedder.ts +4 -152
  115. package/src/core/engine/embedding-maintenance-service.ts +187 -0
  116. package/src/core/engine/endless-memory-services.ts +4 -0
  117. package/src/core/engine/index.ts +19 -0
  118. package/src/core/engine/memory-engine-services.ts +170 -0
  119. package/src/core/engine/memory-ingest-service.ts +317 -0
  120. package/src/core/engine/memory-query-service.ts +173 -0
  121. package/src/core/engine/memory-runtime-service.ts +162 -0
  122. package/src/core/engine/memory-service-composition.ts +231 -0
  123. package/src/core/engine/retrieval-analytics-service.ts +181 -0
  124. package/src/core/engine/retrieval-disclosure-service.ts +420 -0
  125. package/src/core/engine/retrieval-orchestrator.ts +377 -0
  126. package/src/core/engine/retrieval-services.ts +176 -0
  127. package/src/core/engine/shared-memory-services.ts +4 -0
  128. package/src/core/entity-repo.ts +1 -3
  129. package/src/core/event-store.ts +3 -3
  130. package/src/core/evidence-aligner.ts +2 -2
  131. package/src/core/external-market-context.ts +582 -0
  132. package/src/core/graduation.ts +2 -3
  133. package/src/core/index.ts +21 -0
  134. package/src/core/matcher.ts +2 -4
  135. package/src/core/model/memory-fact.ts +30 -0
  136. package/src/core/model/memory-rule.ts +14 -0
  137. package/src/core/model/memory-summary.ts +21 -0
  138. package/src/core/model/raw-event.ts +28 -0
  139. package/src/core/model/retrieval-result.ts +35 -0
  140. package/src/core/privacy/filter.ts +21 -10
  141. package/src/core/product-validation-matrix.ts +314 -0
  142. package/src/core/progressive-retriever.ts +1 -2
  143. package/src/core/registry/project-path.ts +54 -0
  144. package/src/core/registry/session-registry.ts +69 -0
  145. package/src/core/replay-evaluator.ts +625 -0
  146. package/src/core/retrieval-benchmark.ts +117 -0
  147. package/src/core/retrieval-quality.ts +109 -0
  148. package/src/core/retriever.ts +53 -15
  149. package/src/core/session-qrels.ts +360 -0
  150. package/src/core/shared-event-store.ts +1 -1
  151. package/src/core/sqlite-event-store.ts +35 -11
  152. package/src/core/task/blocker-resolver.ts +2 -2
  153. package/src/core/task/task-resolver.ts +0 -1
  154. package/src/core/vector-outbox.ts +1 -10
  155. package/src/core/vector-worker.ts +1 -1
  156. package/src/extensions/endless-memory/endless-memory-services.ts +350 -0
  157. package/src/extensions/endless-memory/index.ts +1 -0
  158. package/src/extensions/index.ts +5 -0
  159. package/src/extensions/mcp/handlers.ts +960 -0
  160. package/src/extensions/mcp/index.ts +48 -0
  161. package/src/extensions/mcp/tools.ts +252 -0
  162. package/src/extensions/shared-memory/index.ts +1 -0
  163. package/src/extensions/shared-memory/shared-memory-services.ts +211 -0
  164. package/src/extensions/vector/embedder.ts +197 -0
  165. package/src/extensions/vector/index.ts +1 -0
  166. package/src/hooks/post-tool-use.ts +3 -236
  167. package/src/hooks/semantic-daemon-client.ts +1 -208
  168. package/src/hooks/semantic-daemon.ts +6 -271
  169. package/src/hooks/session-end.ts +4 -79
  170. package/src/hooks/session-start.ts +4 -73
  171. package/src/hooks/stop.ts +3 -173
  172. package/src/hooks/user-prompt-submit.ts +3 -338
  173. package/src/index.ts +13 -0
  174. package/src/mcp/handlers.ts +2 -212
  175. package/src/mcp/index.ts +3 -46
  176. package/src/mcp/tools.ts +2 -78
  177. package/src/server/api/chat.ts +2 -244
  178. package/src/server/api/citations.ts +2 -105
  179. package/src/server/api/events.ts +2 -137
  180. package/src/server/api/health.ts +2 -53
  181. package/src/server/api/index.ts +2 -26
  182. package/src/server/api/projects.ts +2 -74
  183. package/src/server/api/search.ts +2 -102
  184. package/src/server/api/sessions.ts +2 -115
  185. package/src/server/api/stats.ts +2 -724
  186. package/src/server/api/turns.ts +2 -143
  187. package/src/server/api/utils.ts +2 -46
  188. package/src/server/index.ts +2 -100
  189. package/src/services/bootstrap-organizer.ts +46 -26
  190. package/src/services/codex-session-history-importer.ts +521 -29
  191. package/src/services/hermes-session-history-importer.ts +733 -0
  192. package/src/services/memory-service-config.ts +36 -0
  193. package/src/services/memory-service-registry.ts +150 -0
  194. package/src/services/memory-service.ts +211 -1325
  195. package/src/services/session-history-importer.ts +58 -14
  196. package/tests/README.md +23 -0
  197. package/tests/adapters/claude/claude-semantic-daemon-adapter.test.ts +54 -0
  198. package/tests/adapters/claude/claude-transcript-reconstructor.test.ts +98 -0
  199. package/tests/adapters/claude-hook-prompt-injection-policy.test.ts +99 -0
  200. package/tests/apps/app-layer-boundary.test.ts +48 -0
  201. package/tests/apps/claude-settings-hooks.test.ts +107 -0
  202. package/tests/apps/cli-disclosure-output.test.ts +212 -0
  203. package/tests/apps/codex-import-runner.test.ts +99 -0
  204. package/tests/apps/codex-validation-output.test.ts +100 -0
  205. package/tests/apps/hermes-import-runner.test.ts +99 -0
  206. package/tests/apps/mcp-install-command.test.ts +59 -0
  207. package/tests/apps/package-build-entrypoints.test.ts +30 -0
  208. package/tests/apps/search-api-disclosure.test.ts +162 -0
  209. package/tests/apps/stats-api-lightweight.test.ts +67 -0
  210. package/tests/apps/ui-disclosure-output.test.ts +140 -0
  211. package/tests/{bootstrap-organizer.test.ts → core/bootstrap-organizer.test.ts} +1 -1
  212. package/tests/{canonical-key.test.ts → core/canonical-key.test.ts} +1 -1
  213. package/tests/core/codex-session-history-importer-validation.test.ts +185 -0
  214. package/tests/{consolidation-worker.test.ts → core/consolidation-worker.test.ts} +2 -2
  215. package/tests/core/embedding-maintenance-service.test.ts +282 -0
  216. package/tests/{evidence-aligner.test.ts → core/evidence-aligner.test.ts} +1 -1
  217. package/tests/core/external-market-context.test.ts +209 -0
  218. package/tests/core/fact-deriver.test.ts +79 -0
  219. package/tests/core/hermes-session-history-importer-validation.test.ts +609 -0
  220. package/tests/{ingest-interceptor.test.ts → core/ingest-interceptor.test.ts} +1 -1
  221. package/tests/{markdown-mirror.test.ts → core/markdown-mirror.test.ts} +2 -2
  222. package/tests/{matcher.test.ts → core/matcher.test.ts} +1 -1
  223. package/tests/{md-mirror.test.ts → core/md-mirror.test.ts} +2 -2
  224. package/tests/core/memory-engine-services.test.ts +240 -0
  225. package/tests/core/memory-ingest-service.test.ts +296 -0
  226. package/tests/core/memory-query-service.test.ts +129 -0
  227. package/tests/core/memory-runtime-service.test.ts +201 -0
  228. package/tests/core/memory-service-composition.test.ts +192 -0
  229. package/tests/core/memory-service-config.test.ts +41 -0
  230. package/tests/core/memory-service-facade.test.ts +30 -0
  231. package/tests/core/memory-service-registry.test.ts +206 -0
  232. package/tests/core/product-validation-matrix.test.ts +61 -0
  233. package/tests/core/project-registry.test.ts +78 -0
  234. package/tests/core/replay-evaluator.test.ts +181 -0
  235. package/tests/core/retrieval-analytics-service.test.ts +210 -0
  236. package/tests/core/retrieval-benchmark.test.ts +93 -0
  237. package/tests/core/retrieval-disclosure-service.test.ts +264 -0
  238. package/tests/core/retrieval-orchestrator.test.ts +403 -0
  239. package/tests/core/retrieval-quality.test.ts +31 -0
  240. package/tests/core/retrieval-services.test.ts +185 -0
  241. package/tests/{retriever-fallback-chain.test.ts → core/retriever-fallback-chain.test.ts} +3 -3
  242. package/tests/{retriever-strategy-scope.test.ts → core/retriever-strategy-scope.test.ts} +70 -3
  243. package/tests/{retriever.memu-adoption.test.ts → core/retriever.memu-adoption.test.ts} +3 -3
  244. package/tests/core/session-history-importer-filter.test.ts +78 -0
  245. package/tests/core/session-qrels.test.ts +250 -0
  246. package/tests/{sqlite-event-store-replication.test.ts → core/sqlite-event-store-replication.test.ts} +36 -1
  247. package/tests/core/summary-deriver.test.ts +66 -0
  248. package/tests/extensions/embedder-warning-suppression.test.ts +53 -0
  249. package/tests/extensions/endless-memory-extension-boundary.test.ts +17 -0
  250. package/tests/extensions/endless-memory-services.test.ts +325 -0
  251. package/tests/extensions/mcp-context-tools.test.ts +905 -0
  252. package/tests/extensions/mcp-extension-boundary.test.ts +21 -0
  253. package/tests/extensions/mcp-package-build.test.ts +22 -0
  254. package/tests/extensions/mcp-project-aware-tools.test.ts +102 -0
  255. package/tests/extensions/shared-memory-extension-boundary.test.ts +24 -0
  256. package/tests/extensions/shared-memory-services.test.ts +309 -0
  257. package/tests/extensions/vector-extension-boundary.test.ts +21 -0
  258. package/.claude/settings.local.json +0 -25
  259. package/.npm-cache/_cacache/content-v2/sha512/04/76/c098f88dfe584a2b80870bff7421b05d17d3d9ee1027f77772332a22d3f93a9a57101a2855107f6ad82077a818bba912b2bc317f2361b5ddb09ad284d9ce +0 -0
  260. package/.npm-cache/_cacache/content-v2/sha512/60/25/d2ecd39cfc7cab58351162814be77f935c6d6491c10c3745d456da7ddb2117ffd90c10e53fe3c0f1ed16b403307841543634504398b16ee4e6b6dd8e0c45 +0 -0
  261. package/.npm-cache/_cacache/index-v5/2b/9a/7f8f40206ed8a2e0a84efaa953ccaed1f5d001e14b931083f2e7a0738007 +0 -2
  262. package/.npm-cache/_cacache/index-v5/2e/d9/fcfa5c6a6abdc2a3644ab84a95936047298c465a2f47ee03db8f7fe1e946 +0 -3
  263. package/.npm-cache/_cacache/index-v5/a9/42/e519633356d12d3d2f19da66a8301016d496c8f5c3e0554124aaa62dc043 +0 -2
  264. package/.npm-cache/_logs/2026-02-26T12_04_52_729Z-debug-0.log +0 -256
  265. package/.npm-cache/_logs/2026-02-26T12_05_36_835Z-debug-0.log +0 -18
  266. package/.npm-cache/_logs/2026-02-26T12_05_45_982Z-debug-0.log +0 -32
  267. package/.npm-cache/_logs/2026-02-26T12_05_48_515Z-debug-0.log +0 -260
  268. package/.npm-cache/_logs/2026-02-26T12_05_53_567Z-debug-0.log +0 -69
  269. package/.npm-cache/_update-notifier-last-checked +0 -0
  270. package/bootstrap-kb/decisions/decisions.md +0 -244
  271. package/bootstrap-kb/glossary/glossary.md +0 -46
  272. package/bootstrap-kb/modules/.claude-plugin.md +0 -22
  273. package/bootstrap-kb/modules/agents.md.md +0 -15
  274. package/bootstrap-kb/modules/claude.md.md +0 -15
  275. package/bootstrap-kb/modules/context.md.md +0 -15
  276. package/bootstrap-kb/modules/docs.md +0 -18
  277. package/bootstrap-kb/modules/handoff.md.md +0 -15
  278. package/bootstrap-kb/modules/package-lock.json.md +0 -15
  279. package/bootstrap-kb/modules/package.json.md +0 -15
  280. package/bootstrap-kb/modules/plan.md.md +0 -15
  281. package/bootstrap-kb/modules/readme.md.md +0 -15
  282. package/bootstrap-kb/modules/scripts.md +0 -26
  283. package/bootstrap-kb/modules/spec.md.md +0 -15
  284. package/bootstrap-kb/modules/specs.md +0 -20
  285. package/bootstrap-kb/modules/src.md +0 -51
  286. package/bootstrap-kb/modules/tests.md +0 -42
  287. package/bootstrap-kb/modules/tsconfig.json.md +0 -15
  288. package/bootstrap-kb/modules/vitest.config.ts.md +0 -15
  289. package/bootstrap-kb/overview/overview.md +0 -40
  290. package/bootstrap-kb/sources/manifest.json +0 -950
  291. package/bootstrap-kb/sources/manifest.md +0 -227
  292. package/bootstrap-kb/timeline/timeline.md +0 -57
  293. package/claude-memory-layer-1.0.14.tgz +0 -0
  294. package/d.sh +0 -3
  295. package/deploy.sh +0 -3
  296. package/dist/ui/app.js +0 -2101
  297. package/memory/.claude-plugin/commands/2026-02-25.md +0 -263
  298. package/memory/_index.md +0 -418
  299. package/memory/agent_response/uncategorized/2026-02-26.md +0 -176
  300. package/memory/agent_response/uncategorized/2026-03-03.md +0 -14
  301. package/memory/agent_response/uncategorized/2026-03-04.md +0 -1421
  302. package/memory/agent_response/uncategorized/2026-03-05.md +0 -48
  303. package/memory/default/uncategorized/2026-02-25.md +0 -4839
  304. package/memory/session_summary/uncategorized/2026-02-26.md +0 -13
  305. package/memory/session_summary/uncategorized/2026-03-03.md +0 -5
  306. package/memory/session_summary/uncategorized/2026-03-04.md +0 -50
  307. package/memory/specs/20260207-dashboard-upgrade/2026-02-25.md +0 -142
  308. package/memory/specs/citations-system/2026-02-25.md +0 -1121
  309. package/memory/specs/endless-mode/2026-02-25.md +0 -1392
  310. package/memory/specs/entity-edge-model/2026-02-25.md +0 -1263
  311. package/memory/specs/evidence-aligner-v2/2026-02-25.md +0 -1028
  312. package/memory/specs/mcp-desktop-integration/2026-02-25.md +0 -1334
  313. package/memory/specs/post-tool-use-hook/2026-02-25.md +0 -1164
  314. package/memory/specs/private-tags/2026-02-25.md +0 -1057
  315. package/memory/specs/progressive-disclosure/2026-02-25.md +0 -1436
  316. package/memory/specs/task-entity-system/2026-02-25.md +0 -924
  317. package/memory/specs/vector-outbox-v2/2026-02-25.md +0 -1510
  318. package/memory/specs/web-viewer-ui/2026-02-25.md +0 -1709
  319. package/memory/tool_observation/uncategorized/2026-02-26.md +0 -209
  320. package/memory/tool_observation/uncategorized/2026-03-03.md +0 -21
  321. package/memory/tool_observation/uncategorized/2026-03-04.md +0 -1033
  322. package/memory/tool_observation/uncategorized/2026-03-05.md +0 -29
  323. package/memory/user_prompt/uncategorized/2026-02-26.md +0 -25
  324. package/memory/user_prompt/uncategorized/2026-03-04.md +0 -634
  325. package/specs/optional-duckdb/context.md +0 -77
  326. package/specs/optional-duckdb/plan.md +0 -142
  327. package/specs/optional-duckdb/spec.md +0 -35
  328. package/src/ui/app.js +0 -2101
@@ -0,0 +1,162 @@
1
+ /**
2
+ * Memory Runtime Service
3
+ * Owns MemoryService lifecycle concerns: initialization, background workers,
4
+ * lightweight/read-only modes, and orderly shutdown.
5
+ */
6
+
7
+ import type { EventStore } from '../event-store.js';
8
+ import type { Embedder } from '../embedder.js';
9
+ import type { GraduationPipeline } from '../graduation.js';
10
+ import {
11
+ createGraduationWorker as defaultCreateGraduationWorker,
12
+ type GraduationRunResult,
13
+ type GraduationWorker
14
+ } from '../graduation-worker.js';
15
+ import type { Retriever } from '../retriever.js';
16
+ import type { VectorStore } from '../vector-store.js';
17
+ import {
18
+ createVectorWorker as defaultCreateVectorWorker,
19
+ type VectorWorker
20
+ } from '../vector-worker.js';
21
+
22
+ export interface RuntimeSQLiteStore {
23
+ initialize(): Promise<void>;
24
+ close(): Promise<void>;
25
+ }
26
+
27
+ export interface RuntimeEndlessMemoryServices {
28
+ initializeFromSavedMode(): Promise<void>;
29
+ shutdown(): void;
30
+ }
31
+
32
+ export interface RuntimeSharedMemoryServices {
33
+ initialize(): Promise<void>;
34
+ close(): Promise<void>;
35
+ }
36
+
37
+ export interface MemoryRuntimeServicesFactories {
38
+ createVectorWorker?: typeof defaultCreateVectorWorker;
39
+ createGraduationWorker?: typeof defaultCreateGraduationWorker;
40
+ }
41
+
42
+ export interface MemoryRuntimeServicesDeps {
43
+ sqliteStore: RuntimeSQLiteStore;
44
+ eventStore: EventStore;
45
+ vectorStore: VectorStore;
46
+ embedder: Embedder;
47
+ retriever: Retriever;
48
+ graduation: GraduationPipeline;
49
+ endlessMemoryServices: RuntimeEndlessMemoryServices;
50
+ sharedMemoryServices: RuntimeSharedMemoryServices;
51
+ readOnly: boolean;
52
+ lightweightMode: boolean;
53
+ embeddingOnly: boolean;
54
+ factories?: MemoryRuntimeServicesFactories;
55
+ }
56
+
57
+ export interface MemoryRuntimeService {
58
+ initialize(): Promise<void>;
59
+ shutdown(): Promise<void>;
60
+ processPendingEmbeddings(): Promise<number>;
61
+ forceGraduation(): Promise<GraduationRunResult>;
62
+ recordMemoryAccess(eventId: string, sessionId: string, confidence?: number): void;
63
+ getVectorWorker(): VectorWorker | null;
64
+ isInitialized(): boolean;
65
+ }
66
+
67
+ function createEmptyGraduationResult(): GraduationRunResult {
68
+ return { evaluated: 0, graduated: 0, byLevel: {} };
69
+ }
70
+
71
+ export function createMemoryRuntimeService(deps: MemoryRuntimeServicesDeps): MemoryRuntimeService {
72
+ const createVectorWorker = deps.factories?.createVectorWorker ?? defaultCreateVectorWorker;
73
+ const createGraduationWorker = deps.factories?.createGraduationWorker ?? defaultCreateGraduationWorker;
74
+
75
+ let initialized = false;
76
+ let vectorWorker: VectorWorker | null = null;
77
+ let graduationWorker: GraduationWorker | null = null;
78
+
79
+ return {
80
+ async initialize(): Promise<void> {
81
+ if (initialized) return;
82
+
83
+ // Initialize PRIMARY store: SQLite (always)
84
+ await deps.sqliteStore.initialize();
85
+
86
+ // Lightweight mode: only SQLite, no embedder/vector/workers.
87
+ // Used for hooks that just need to store data quickly.
88
+ if (deps.lightweightMode) {
89
+ initialized = true;
90
+ return;
91
+ }
92
+
93
+ await deps.vectorStore.initialize();
94
+ await deps.embedder.initialize();
95
+
96
+ // Skip write-related workers in read-only mode.
97
+ if (!deps.readOnly) {
98
+ vectorWorker = createVectorWorker(
99
+ deps.eventStore,
100
+ deps.vectorStore,
101
+ deps.embedder
102
+ );
103
+ vectorWorker.start();
104
+
105
+ if (!deps.embeddingOnly) {
106
+ deps.retriever.setGraduationPipeline(deps.graduation);
107
+ graduationWorker = createGraduationWorker(
108
+ deps.eventStore,
109
+ deps.graduation
110
+ );
111
+ graduationWorker.start();
112
+ }
113
+
114
+ await deps.endlessMemoryServices.initializeFromSavedMode();
115
+ await deps.sharedMemoryServices.initialize();
116
+ }
117
+
118
+ initialized = true;
119
+ },
120
+
121
+ async shutdown(): Promise<void> {
122
+ if (graduationWorker) {
123
+ graduationWorker.stop();
124
+ }
125
+
126
+ deps.endlessMemoryServices.shutdown();
127
+
128
+ if (vectorWorker) {
129
+ vectorWorker.stop();
130
+ }
131
+
132
+ await deps.sharedMemoryServices.close();
133
+ await deps.sqliteStore.close();
134
+ },
135
+
136
+ async processPendingEmbeddings(): Promise<number> {
137
+ if (vectorWorker) {
138
+ return vectorWorker.processAll();
139
+ }
140
+ return 0;
141
+ },
142
+
143
+ async forceGraduation(): Promise<GraduationRunResult> {
144
+ if (!graduationWorker) {
145
+ return createEmptyGraduationResult();
146
+ }
147
+ return graduationWorker.forceRun();
148
+ },
149
+
150
+ recordMemoryAccess(eventId: string, sessionId: string, confidence: number = 1.0): void {
151
+ deps.graduation.recordAccess(eventId, sessionId, confidence);
152
+ },
153
+
154
+ getVectorWorker(): VectorWorker | null {
155
+ return vectorWorker;
156
+ },
157
+
158
+ isInitialized(): boolean {
159
+ return initialized;
160
+ }
161
+ };
162
+ }
@@ -0,0 +1,231 @@
1
+ /**
2
+ * Memory Service Composition
3
+ *
4
+ * Owns constructor-time service graph wiring for MemoryService so the public
5
+ * facade can stay focused on state assignment and method delegation.
6
+ */
7
+
8
+ import * as os from 'os';
9
+ import * as path from 'path';
10
+
11
+ import type { EventStore } from '../event-store.js';
12
+ import type { Embedder } from '../embedder.js';
13
+ import type { GraduationPipeline } from '../graduation.js';
14
+ import { createToolObservationEmbedding as defaultCreateToolObservationEmbedding } from '../metadata-extractor.js';
15
+ import type { Retriever } from '../retriever.js';
16
+ import type { SQLiteEventStore } from '../sqlite-event-store.js';
17
+ import type { ToolObservationPayload, SharedStoreConfig } from '../types.js';
18
+ import type { VectorStore } from '../vector-store.js';
19
+ import {
20
+ createEmbeddingMaintenanceService as defaultCreateEmbeddingMaintenanceService,
21
+ type EmbeddingMaintenanceService,
22
+ type EmbeddingMaintenanceServiceOptions
23
+ } from './embedding-maintenance-service.js';
24
+ import {
25
+ createEndlessMemoryServices as defaultCreateEndlessMemoryServices,
26
+ type EndlessMemoryServices,
27
+ type EndlessMemoryServicesOptions
28
+ } from './endless-memory-services.js';
29
+ import {
30
+ createMemoryEngineServices as defaultCreateMemoryEngineServices,
31
+ type MemoryEngineServices,
32
+ type MemoryEngineServicesOptions
33
+ } from './memory-engine-services.js';
34
+ import {
35
+ createMemoryRuntimeService as defaultCreateMemoryRuntimeService,
36
+ type MemoryRuntimeService,
37
+ type MemoryRuntimeServicesDeps
38
+ } from './memory-runtime-service.js';
39
+ import type {
40
+ MemoryIngestService
41
+ } from './memory-ingest-service.js';
42
+ import type {
43
+ MemoryQueryService
44
+ } from './memory-query-service.js';
45
+ import {
46
+ createSharedMemoryServices as defaultCreateSharedMemoryServices,
47
+ type SharedMemoryServices,
48
+ type SharedMemoryServicesOptions
49
+ } from './shared-memory-services.js';
50
+ import type {
51
+ RetrievalAnalyticsService,
52
+ RetrievalDisclosureService,
53
+ RetrievalOrchestrator
54
+ } from './retrieval-services.js';
55
+
56
+ export interface MemoryServiceCompositionConfig {
57
+ storagePath: string;
58
+ embeddingModel?: string;
59
+ readOnly?: boolean;
60
+ lightweightMode?: boolean;
61
+ embeddingOnly?: boolean;
62
+ projectHash?: string;
63
+ projectPath?: string;
64
+ sharedStoreConfig?: SharedStoreConfig;
65
+ }
66
+
67
+ export interface MemoryServiceCompositionFactories {
68
+ expandPath?: (targetPath: string) => string;
69
+ createToolObservationEmbedding?: (
70
+ toolName: string,
71
+ metadata: Record<string, unknown>,
72
+ success: boolean
73
+ ) => string;
74
+ createMemoryEngineServices?: (options: MemoryEngineServicesOptions) => MemoryEngineServices;
75
+ createEndlessMemoryServices?: (options: EndlessMemoryServicesOptions) => EndlessMemoryServices;
76
+ createSharedMemoryServices?: (options: SharedMemoryServicesOptions) => SharedMemoryServices;
77
+ createMemoryRuntimeService?: (deps: MemoryRuntimeServicesDeps) => MemoryRuntimeService;
78
+ createEmbeddingMaintenanceService?: (
79
+ options: EmbeddingMaintenanceServiceOptions
80
+ ) => EmbeddingMaintenanceService;
81
+ }
82
+
83
+ export interface MemoryServiceCompositionOptions {
84
+ config: MemoryServiceCompositionConfig;
85
+ defaultSharedStoragePath: string;
86
+ defaultSharedStoreConfig?: SharedStoreConfig;
87
+ initialize: () => Promise<void>;
88
+ getProjectHash: () => string | null;
89
+ getProjectPath?: () => string | null;
90
+ factories?: MemoryServiceCompositionFactories;
91
+ }
92
+
93
+ export interface MemoryServiceComposition {
94
+ storagePath: string;
95
+ readOnly: boolean;
96
+ lightweightMode: boolean;
97
+ embeddingOnly: boolean;
98
+ sqliteStore: SQLiteEventStore;
99
+ vectorStore: VectorStore;
100
+ embedder: Embedder;
101
+ retriever: Retriever;
102
+ retrievalOrchestrator: RetrievalOrchestrator;
103
+ retrievalDisclosureService: RetrievalDisclosureService;
104
+ retrievalAnalyticsService: RetrievalAnalyticsService;
105
+ embeddingMaintenanceService: EmbeddingMaintenanceService;
106
+ runtimeService: MemoryRuntimeService;
107
+ graduation: GraduationPipeline;
108
+ endlessMemoryServices: EndlessMemoryServices;
109
+ sharedMemoryServices: SharedMemoryServices;
110
+ ingestService: MemoryIngestService;
111
+ queryService: MemoryQueryService;
112
+ }
113
+
114
+ export function createMemoryServiceComposition(
115
+ options: MemoryServiceCompositionOptions
116
+ ): MemoryServiceComposition {
117
+ const factories = options.factories ?? {};
118
+ const expandPath = factories.expandPath ?? defaultExpandPath;
119
+ const createToolEmbedding = factories.createToolObservationEmbedding ?? defaultCreateToolObservationEmbedding;
120
+
121
+ const storagePath = expandPath(options.config.storagePath);
122
+ const projectPathForMirror = options.getProjectPath?.() ?? options.config.projectPath ?? process.cwd();
123
+ const readOnly = options.config.readOnly ?? false;
124
+ const lightweightMode = options.config.lightweightMode ?? false;
125
+ const embeddingOnly = options.config.embeddingOnly ?? false;
126
+ const sharedStoreConfig = options.config.sharedStoreConfig ?? options.defaultSharedStoreConfig ?? {
127
+ enabled: true,
128
+ autoPromote: true,
129
+ searchShared: true,
130
+ minConfidenceForPromotion: 0.8,
131
+ sharedStoragePath: options.defaultSharedStoragePath
132
+ };
133
+
134
+ let sharedMemoryServices: SharedMemoryServices | null = null;
135
+
136
+ const engineServices = (factories.createMemoryEngineServices ?? defaultCreateMemoryEngineServices)({
137
+ storagePath,
138
+ readOnly,
139
+ embeddingModel: options.config.embeddingModel,
140
+ cwd: projectPathForMirror,
141
+ initialize: options.initialize,
142
+ getProjectHash: options.getProjectHash,
143
+ getProjectPath: options.getProjectPath,
144
+ hasSharedStore: () => sharedMemoryServices?.isEnabled() ?? false,
145
+ sharedStore: {
146
+ get: (entryId: string) => sharedMemoryServices?.getEntryForDisclosure(entryId) ?? Promise.resolve(null)
147
+ },
148
+ createToolObservationEmbedding: (payload: ToolObservationPayload) => createToolEmbedding(
149
+ payload.toolName,
150
+ payload.metadata || {},
151
+ payload.success
152
+ )
153
+ });
154
+
155
+ const endlessMemoryServices = (factories.createEndlessMemoryServices ?? defaultCreateEndlessMemoryServices)({
156
+ eventStore: engineServices.sqliteStore as unknown as EventStore,
157
+ configStore: engineServices.sqliteStore,
158
+ initialize: options.initialize
159
+ });
160
+
161
+ sharedMemoryServices = (factories.createSharedMemoryServices ?? defaultCreateSharedMemoryServices)({
162
+ config: sharedStoreConfig,
163
+ defaultSharedStoragePath: options.defaultSharedStoragePath,
164
+ readOnly,
165
+ expandPath,
166
+ embedder: engineServices.embedder,
167
+ retriever: engineServices.retriever
168
+ });
169
+
170
+ const runtimeService = (factories.createMemoryRuntimeService ?? defaultCreateMemoryRuntimeService)({
171
+ sqliteStore: engineServices.sqliteStore,
172
+ eventStore: engineServices.sqliteStore as unknown as EventStore,
173
+ vectorStore: engineServices.vectorStore,
174
+ embedder: engineServices.embedder,
175
+ retriever: engineServices.retriever,
176
+ graduation: engineServices.graduation,
177
+ endlessMemoryServices,
178
+ sharedMemoryServices,
179
+ readOnly,
180
+ lightweightMode,
181
+ embeddingOnly
182
+ });
183
+
184
+ const embeddingMaintenanceService = (
185
+ factories.createEmbeddingMaintenanceService ?? defaultCreateEmbeddingMaintenanceService
186
+ )({
187
+ storagePath,
188
+ initialize: options.initialize,
189
+ getEmbeddingModelName: () => engineServices.embedder.getModelName(),
190
+ vectorStore: engineServices.vectorStore,
191
+ eventStore: {
192
+ clearEmbeddingOutbox: () => engineServices.sqliteStore.clearEmbeddingOutbox(),
193
+ getEventsPage: async (limit, offset) => {
194
+ const events = await engineServices.sqliteStore.getEventsPage(limit, offset);
195
+ return events.map((event) => ({ id: event.id, content: event.content }));
196
+ },
197
+ enqueueForEmbedding: async (eventId, content) => {
198
+ await engineServices.sqliteStore.enqueueForEmbedding(eventId, content);
199
+ }
200
+ },
201
+ getVectorWorker: () => runtimeService.getVectorWorker()
202
+ });
203
+
204
+ return {
205
+ storagePath,
206
+ readOnly,
207
+ lightweightMode,
208
+ embeddingOnly,
209
+ sqliteStore: engineServices.sqliteStore,
210
+ vectorStore: engineServices.vectorStore,
211
+ embedder: engineServices.embedder,
212
+ retriever: engineServices.retriever,
213
+ retrievalOrchestrator: engineServices.retrievalOrchestrator,
214
+ retrievalDisclosureService: engineServices.retrievalDisclosureService,
215
+ retrievalAnalyticsService: engineServices.retrievalAnalyticsService,
216
+ embeddingMaintenanceService,
217
+ runtimeService,
218
+ graduation: engineServices.graduation,
219
+ endlessMemoryServices,
220
+ sharedMemoryServices,
221
+ ingestService: engineServices.ingestService,
222
+ queryService: engineServices.queryService
223
+ };
224
+ }
225
+
226
+ function defaultExpandPath(targetPath: string): string {
227
+ if (targetPath.startsWith('~')) {
228
+ return path.join(os.homedir(), targetPath.slice(1));
229
+ }
230
+ return targetPath;
231
+ }
@@ -0,0 +1,181 @@
1
+ /**
2
+ * Retrieval Analytics Service
3
+ *
4
+ * Owns retrieval telemetry read-model and helpfulness evaluation workflows so
5
+ * MemoryService can remain a thin facade over focused engine services.
6
+ */
7
+
8
+ import type { MemoryEvent } from '../types.js';
9
+
10
+ export interface RetrievalTraceStats {
11
+ totalQueries: number;
12
+ avgCandidateCount: number;
13
+ avgSelectedCount: number;
14
+ selectionRate: number;
15
+ }
16
+
17
+ export interface HelpfulnessStats {
18
+ avgScore: number;
19
+ totalEvaluated: number;
20
+ totalRetrievals: number;
21
+ helpful: number;
22
+ neutral: number;
23
+ unhelpful: number;
24
+ }
25
+
26
+ export interface HelpfulMemory {
27
+ eventId: string;
28
+ summary: string;
29
+ helpfulnessScore: number;
30
+ accessCount: number;
31
+ evaluationCount: number;
32
+ }
33
+
34
+ export interface RetrievalTraceDetail {
35
+ eventId: string;
36
+ score: number;
37
+ semanticScore?: number;
38
+ lexicalScore?: number;
39
+ recencyScore?: number;
40
+ }
41
+
42
+ export interface RetrievalTrace {
43
+ traceId: string;
44
+ sessionId?: string;
45
+ projectHash?: string;
46
+ queryText: string;
47
+ strategy?: string;
48
+ candidateEventIds: string[];
49
+ selectedEventIds: string[];
50
+ candidateDetails: RetrievalTraceDetail[];
51
+ selectedDetails: RetrievalTraceDetail[];
52
+ candidateCount: number;
53
+ selectedCount: number;
54
+ confidence?: string;
55
+ fallbackTrace: string[];
56
+ createdAt: Date;
57
+ }
58
+
59
+ export interface AccessedMemory {
60
+ memoryId: string;
61
+ summary: string;
62
+ topics: string[];
63
+ accessCount: number;
64
+ lastAccessed: string | null;
65
+ confidence: number;
66
+ createdAt: Date;
67
+ }
68
+
69
+ type AccessedMemoryEvent = MemoryEvent & {
70
+ access_count?: number;
71
+ last_accessed_at?: string | null;
72
+ };
73
+
74
+ export interface RetrievalAnalyticsStore {
75
+ getRetrievalTraceStats(): Promise<RetrievalTraceStats>;
76
+ getRecentRetrievalTraces(limit?: number): Promise<RetrievalTrace[]>;
77
+ getMostAccessed(limit?: number): Promise<AccessedMemoryEvent[]>;
78
+ evaluateSessionHelpfulness(sessionId: string): Promise<void>;
79
+ getUnevaluatedSessions(currentSessionId: string, limit?: number): Promise<string[]>;
80
+ getHelpfulMemories(limit?: number): Promise<HelpfulMemory[]>;
81
+ getHelpfulnessStats(): Promise<HelpfulnessStats>;
82
+ }
83
+
84
+ export interface RetrievalAnalyticsServiceDeps {
85
+ initialize: () => Promise<void>;
86
+ retrievalStore: RetrievalAnalyticsStore;
87
+ }
88
+
89
+ export class RetrievalAnalyticsService {
90
+ constructor(private readonly deps: RetrievalAnalyticsServiceDeps) {}
91
+
92
+ async getRetrievalTraceStats(): Promise<RetrievalTraceStats> {
93
+ await this.deps.initialize();
94
+ return this.deps.retrievalStore.getRetrievalTraceStats();
95
+ }
96
+
97
+ async getRecentRetrievalTraces(limit: number = 50): Promise<RetrievalTrace[]> {
98
+ await this.deps.initialize();
99
+ return this.deps.retrievalStore.getRecentRetrievalTraces(limit);
100
+ }
101
+
102
+ async getMostAccessedMemories(limit: number = 10): Promise<AccessedMemory[]> {
103
+ // Preserve the historical lightweight path: SQLiteEventStore.getMostAccessed()
104
+ // initializes itself and no-ops safely in read-only scenarios, so dashboard
105
+ // access summaries should not trigger vector/embedder/worker initialization.
106
+ const events = await this.deps.retrievalStore.getMostAccessed(limit);
107
+
108
+ return events.map((event) => ({
109
+ memoryId: event.id,
110
+ summary: event.content.substring(0, 200) + (event.content.length > 200 ? '...' : ''),
111
+ topics: this.extractTopicsFromContent(event.content),
112
+ accessCount: event.access_count || 0,
113
+ lastAccessed: event.last_accessed_at || null,
114
+ confidence: 1.0,
115
+ createdAt: event.timestamp,
116
+ }));
117
+ }
118
+
119
+ async evaluateSessionHelpfulness(sessionId: string): Promise<void> {
120
+ await this.deps.initialize();
121
+ await this.deps.retrievalStore.evaluateSessionHelpfulness(sessionId);
122
+ }
123
+
124
+ async evaluatePendingSessions(currentSessionId: string, limit: number = 5): Promise<void> {
125
+ await this.deps.initialize();
126
+ const sessions = await this.deps.retrievalStore.getUnevaluatedSessions(currentSessionId, limit);
127
+
128
+ for (const sessionId of sessions) {
129
+ try {
130
+ await this.deps.retrievalStore.evaluateSessionHelpfulness(sessionId);
131
+ } catch {
132
+ // Best-effort backfill: one broken session should not block hook startup.
133
+ }
134
+ }
135
+ }
136
+
137
+ async getHelpfulMemories(limit: number = 10): Promise<HelpfulMemory[]> {
138
+ await this.deps.initialize();
139
+ return this.deps.retrievalStore.getHelpfulMemories(limit);
140
+ }
141
+
142
+ async getHelpfulnessStats(): Promise<HelpfulnessStats> {
143
+ await this.deps.initialize();
144
+ return this.deps.retrievalStore.getHelpfulnessStats();
145
+ }
146
+
147
+ /**
148
+ * Extract topic keywords from event content (markdown headings and key terms).
149
+ */
150
+ private extractTopicsFromContent(content: string): string[] {
151
+ const topics: Set<string> = new Set();
152
+
153
+ const headings = content.match(/^#{1,3}\s+(.+)$/gm);
154
+ if (headings) {
155
+ for (const heading of headings.slice(0, 5)) {
156
+ const text = heading.replace(/^#+\s+/, '').replace(/[*_`#]/g, '').trim();
157
+ if (text.length > 2 && text.length < 50) {
158
+ topics.add(text);
159
+ }
160
+ }
161
+ }
162
+
163
+ const boldTerms = content.match(/\*\*([^*]+)\*\*/g);
164
+ if (boldTerms) {
165
+ for (const boldTerm of boldTerms.slice(0, 5)) {
166
+ const text = boldTerm.replace(/\*\*/g, '').trim();
167
+ if (text.length > 2 && text.length < 30) {
168
+ topics.add(text);
169
+ }
170
+ }
171
+ }
172
+
173
+ return Array.from(topics).slice(0, 5);
174
+ }
175
+ }
176
+
177
+ export function createRetrievalAnalyticsService(
178
+ deps: RetrievalAnalyticsServiceDeps
179
+ ): RetrievalAnalyticsService {
180
+ return new RetrievalAnalyticsService(deps);
181
+ }