claude-memory-layer 1.0.27 → 1.0.29

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 (331) hide show
  1. package/.env.example +7 -0
  2. package/AGENTS.md +11 -0
  3. package/README.md +374 -49
  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 +12 -5
  56. package/scripts/build.ts +25 -8
  57. package/scripts/generate-session-qrels.ts +126 -0
  58. package/scripts/postinstall-embedding-backend.cjs +142 -0
  59. package/scripts/replay-retrieval-benchmark.ts +69 -0
  60. package/specs/thin-core-refactor/context.md +275 -0
  61. package/specs/thin-core-refactor/plan.md +536 -0
  62. package/specs/thin-core-refactor/spec.md +465 -0
  63. package/src/adapters/claude/capture/index.ts +3 -0
  64. package/src/adapters/claude/context/index.ts +3 -0
  65. package/src/adapters/claude/hooks/index.ts +21 -0
  66. package/src/adapters/claude/hooks/post-tool-use.ts +239 -0
  67. package/src/adapters/claude/hooks/prompt-injection-policy.ts +104 -0
  68. package/src/adapters/claude/hooks/semantic-daemon-client.ts +209 -0
  69. package/src/adapters/claude/hooks/semantic-daemon.ts +283 -0
  70. package/src/adapters/claude/hooks/session-end.ts +59 -0
  71. package/src/adapters/claude/hooks/session-start.ts +73 -0
  72. package/src/adapters/claude/hooks/stop.ts +128 -0
  73. package/src/adapters/claude/hooks/user-prompt-submit.ts +361 -0
  74. package/src/adapters/claude/index.ts +4 -0
  75. package/src/adapters/claude/transcript/index.ts +4 -0
  76. package/src/adapters/claude/transcript/transcript-reader.ts +57 -0
  77. package/src/adapters/claude/transcript/turn-reconstructor.ts +65 -0
  78. package/src/apps/cli/claude-settings-hooks.ts +138 -0
  79. package/src/apps/cli/codex-import-runner.ts +125 -0
  80. package/src/apps/cli/codex-validation-output.ts +95 -0
  81. package/src/apps/cli/hermes-import-runner.ts +130 -0
  82. package/src/apps/cli/hermes-validation-output.ts +91 -0
  83. package/src/apps/cli/index.ts +1731 -0
  84. package/src/apps/cli/mcp-install.ts +106 -0
  85. package/src/apps/cli/retrieval-disclosure-output.ts +196 -0
  86. package/src/apps/dashboard/assets/js/bootstrap.js +244 -0
  87. package/src/apps/dashboard/assets/js/chat.js +373 -0
  88. package/src/apps/dashboard/assets/js/disclosure.js +232 -0
  89. package/src/apps/dashboard/assets/js/modals.js +298 -0
  90. package/src/apps/dashboard/assets/js/overview.js +655 -0
  91. package/src/apps/dashboard/assets/js/state.js +72 -0
  92. package/src/apps/dashboard/assets/js/views.js +468 -0
  93. package/src/{ui → apps/dashboard}/index.html +43 -1
  94. package/src/apps/dashboard/index.ts +3 -0
  95. package/src/{ui → apps/dashboard}/style.css +222 -0
  96. package/src/apps/index.ts +5 -0
  97. package/src/apps/server/api/chat.ts +244 -0
  98. package/src/apps/server/api/citations.ts +105 -0
  99. package/src/apps/server/api/events.ts +137 -0
  100. package/src/apps/server/api/health.ts +53 -0
  101. package/src/apps/server/api/index.ts +26 -0
  102. package/src/apps/server/api/projects.ts +74 -0
  103. package/src/apps/server/api/search.ts +184 -0
  104. package/src/apps/server/api/sessions.ts +115 -0
  105. package/src/apps/server/api/stats.ts +723 -0
  106. package/src/apps/server/api/turns.ts +143 -0
  107. package/src/apps/server/api/utils.ts +65 -0
  108. package/src/apps/server/index.ts +111 -0
  109. package/src/cli/index.ts +2 -1311
  110. package/src/cli/retrieval-disclosure-output.ts +2 -0
  111. package/src/compat/index.ts +5 -0
  112. package/src/core/derive/fact-deriver.ts +170 -0
  113. package/src/core/derive/index.ts +2 -0
  114. package/src/core/derive/summary-deriver.ts +76 -0
  115. package/src/core/embedder.ts +4 -152
  116. package/src/core/engine/embedding-maintenance-service.ts +187 -0
  117. package/src/core/engine/endless-memory-services.ts +4 -0
  118. package/src/core/engine/index.ts +19 -0
  119. package/src/core/engine/memory-engine-services.ts +170 -0
  120. package/src/core/engine/memory-ingest-service.ts +317 -0
  121. package/src/core/engine/memory-query-service.ts +173 -0
  122. package/src/core/engine/memory-runtime-service.ts +162 -0
  123. package/src/core/engine/memory-service-composition.ts +231 -0
  124. package/src/core/engine/retrieval-analytics-service.ts +181 -0
  125. package/src/core/engine/retrieval-disclosure-service.ts +420 -0
  126. package/src/core/engine/retrieval-orchestrator.ts +377 -0
  127. package/src/core/engine/retrieval-services.ts +176 -0
  128. package/src/core/engine/shared-memory-services.ts +4 -0
  129. package/src/core/entity-repo.ts +1 -3
  130. package/src/core/event-store.ts +3 -3
  131. package/src/core/evidence-aligner.ts +2 -2
  132. package/src/core/external-market-context.ts +582 -0
  133. package/src/core/graduation.ts +2 -3
  134. package/src/core/index.ts +21 -0
  135. package/src/core/matcher.ts +2 -4
  136. package/src/core/model/memory-fact.ts +30 -0
  137. package/src/core/model/memory-rule.ts +14 -0
  138. package/src/core/model/memory-summary.ts +21 -0
  139. package/src/core/model/raw-event.ts +28 -0
  140. package/src/core/model/retrieval-result.ts +35 -0
  141. package/src/core/privacy/filter.ts +21 -10
  142. package/src/core/product-validation-matrix.ts +314 -0
  143. package/src/core/progressive-retriever.ts +1 -2
  144. package/src/core/registry/project-path.ts +54 -0
  145. package/src/core/registry/session-registry.ts +69 -0
  146. package/src/core/replay-evaluator.ts +625 -0
  147. package/src/core/retrieval-benchmark.ts +117 -0
  148. package/src/core/retrieval-quality.ts +109 -0
  149. package/src/core/retriever.ts +53 -15
  150. package/src/core/session-qrels.ts +360 -0
  151. package/src/core/shared-event-store.ts +1 -1
  152. package/src/core/sqlite-event-store.ts +35 -11
  153. package/src/core/task/blocker-resolver.ts +2 -2
  154. package/src/core/task/task-resolver.ts +0 -1
  155. package/src/core/vector-outbox.ts +1 -10
  156. package/src/core/vector-worker.ts +1 -1
  157. package/src/extensions/endless-memory/endless-memory-services.ts +350 -0
  158. package/src/extensions/endless-memory/index.ts +1 -0
  159. package/src/extensions/index.ts +5 -0
  160. package/src/extensions/mcp/handlers.ts +960 -0
  161. package/src/extensions/mcp/index.ts +48 -0
  162. package/src/extensions/mcp/tools.ts +252 -0
  163. package/src/extensions/shared-memory/index.ts +1 -0
  164. package/src/extensions/shared-memory/shared-memory-services.ts +211 -0
  165. package/src/extensions/vector/embedder.ts +197 -0
  166. package/src/extensions/vector/index.ts +1 -0
  167. package/src/hooks/post-tool-use.ts +3 -236
  168. package/src/hooks/semantic-daemon-client.ts +1 -208
  169. package/src/hooks/semantic-daemon.ts +6 -271
  170. package/src/hooks/session-end.ts +4 -79
  171. package/src/hooks/session-start.ts +4 -73
  172. package/src/hooks/stop.ts +3 -173
  173. package/src/hooks/user-prompt-submit.ts +3 -338
  174. package/src/index.ts +13 -0
  175. package/src/mcp/handlers.ts +2 -212
  176. package/src/mcp/index.ts +3 -46
  177. package/src/mcp/tools.ts +2 -78
  178. package/src/server/api/chat.ts +2 -244
  179. package/src/server/api/citations.ts +2 -105
  180. package/src/server/api/events.ts +2 -137
  181. package/src/server/api/health.ts +2 -53
  182. package/src/server/api/index.ts +2 -26
  183. package/src/server/api/projects.ts +2 -74
  184. package/src/server/api/search.ts +2 -102
  185. package/src/server/api/sessions.ts +2 -115
  186. package/src/server/api/stats.ts +2 -724
  187. package/src/server/api/turns.ts +2 -143
  188. package/src/server/api/utils.ts +2 -46
  189. package/src/server/index.ts +2 -100
  190. package/src/services/bootstrap-organizer.ts +46 -26
  191. package/src/services/codex-session-history-importer.ts +521 -29
  192. package/src/services/hermes-session-history-importer.ts +733 -0
  193. package/src/services/memory-service-config.ts +36 -0
  194. package/src/services/memory-service-registry.ts +150 -0
  195. package/src/services/memory-service.ts +211 -1325
  196. package/src/services/session-history-importer.ts +58 -14
  197. package/tests/README.md +23 -0
  198. package/tests/adapters/claude/claude-semantic-daemon-adapter.test.ts +54 -0
  199. package/tests/adapters/claude/claude-transcript-reconstructor.test.ts +98 -0
  200. package/tests/adapters/claude-hook-prompt-injection-policy.test.ts +99 -0
  201. package/tests/apps/app-layer-boundary.test.ts +48 -0
  202. package/tests/apps/claude-settings-hooks.test.ts +107 -0
  203. package/tests/apps/cli-disclosure-output.test.ts +212 -0
  204. package/tests/apps/codex-import-runner.test.ts +99 -0
  205. package/tests/apps/codex-validation-output.test.ts +100 -0
  206. package/tests/apps/hermes-import-runner.test.ts +99 -0
  207. package/tests/apps/mcp-install-command.test.ts +59 -0
  208. package/tests/apps/package-build-entrypoints.test.ts +30 -0
  209. package/tests/apps/postinstall-embedding-backend.test.ts +167 -0
  210. package/tests/apps/search-api-disclosure.test.ts +162 -0
  211. package/tests/apps/stats-api-lightweight.test.ts +67 -0
  212. package/tests/apps/ui-disclosure-output.test.ts +140 -0
  213. package/tests/{bootstrap-organizer.test.ts → core/bootstrap-organizer.test.ts} +1 -1
  214. package/tests/{canonical-key.test.ts → core/canonical-key.test.ts} +1 -1
  215. package/tests/core/codex-session-history-importer-validation.test.ts +185 -0
  216. package/tests/{consolidation-worker.test.ts → core/consolidation-worker.test.ts} +2 -2
  217. package/tests/core/embedding-maintenance-service.test.ts +282 -0
  218. package/tests/{evidence-aligner.test.ts → core/evidence-aligner.test.ts} +1 -1
  219. package/tests/core/external-market-context.test.ts +209 -0
  220. package/tests/core/fact-deriver.test.ts +79 -0
  221. package/tests/core/hermes-session-history-importer-validation.test.ts +609 -0
  222. package/tests/{ingest-interceptor.test.ts → core/ingest-interceptor.test.ts} +1 -1
  223. package/tests/{markdown-mirror.test.ts → core/markdown-mirror.test.ts} +2 -2
  224. package/tests/{matcher.test.ts → core/matcher.test.ts} +1 -1
  225. package/tests/{md-mirror.test.ts → core/md-mirror.test.ts} +2 -2
  226. package/tests/core/memory-engine-services.test.ts +240 -0
  227. package/tests/core/memory-ingest-service.test.ts +296 -0
  228. package/tests/core/memory-query-service.test.ts +129 -0
  229. package/tests/core/memory-runtime-service.test.ts +201 -0
  230. package/tests/core/memory-service-composition.test.ts +192 -0
  231. package/tests/core/memory-service-config.test.ts +41 -0
  232. package/tests/core/memory-service-facade.test.ts +30 -0
  233. package/tests/core/memory-service-registry.test.ts +206 -0
  234. package/tests/core/product-validation-matrix.test.ts +61 -0
  235. package/tests/core/project-registry.test.ts +78 -0
  236. package/tests/core/replay-evaluator.test.ts +181 -0
  237. package/tests/core/retrieval-analytics-service.test.ts +210 -0
  238. package/tests/core/retrieval-benchmark.test.ts +93 -0
  239. package/tests/core/retrieval-disclosure-service.test.ts +264 -0
  240. package/tests/core/retrieval-orchestrator.test.ts +403 -0
  241. package/tests/core/retrieval-quality.test.ts +31 -0
  242. package/tests/core/retrieval-services.test.ts +185 -0
  243. package/tests/{retriever-fallback-chain.test.ts → core/retriever-fallback-chain.test.ts} +3 -3
  244. package/tests/{retriever-strategy-scope.test.ts → core/retriever-strategy-scope.test.ts} +70 -3
  245. package/tests/{retriever.memu-adoption.test.ts → core/retriever.memu-adoption.test.ts} +3 -3
  246. package/tests/core/session-history-importer-filter.test.ts +78 -0
  247. package/tests/core/session-qrels.test.ts +250 -0
  248. package/tests/{sqlite-event-store-replication.test.ts → core/sqlite-event-store-replication.test.ts} +36 -1
  249. package/tests/core/summary-deriver.test.ts +66 -0
  250. package/tests/extensions/embedder-warning-suppression.test.ts +53 -0
  251. package/tests/extensions/endless-memory-extension-boundary.test.ts +17 -0
  252. package/tests/extensions/endless-memory-services.test.ts +325 -0
  253. package/tests/extensions/mcp-context-tools.test.ts +905 -0
  254. package/tests/extensions/mcp-extension-boundary.test.ts +21 -0
  255. package/tests/extensions/mcp-package-build.test.ts +22 -0
  256. package/tests/extensions/mcp-project-aware-tools.test.ts +102 -0
  257. package/tests/extensions/shared-memory-extension-boundary.test.ts +24 -0
  258. package/tests/extensions/shared-memory-services.test.ts +309 -0
  259. package/tests/extensions/vector-extension-boundary.test.ts +21 -0
  260. package/.claude/settings.local.json +0 -25
  261. package/.npm-cache/_cacache/content-v2/sha512/04/76/c098f88dfe584a2b80870bff7421b05d17d3d9ee1027f77772332a22d3f93a9a57101a2855107f6ad82077a818bba912b2bc317f2361b5ddb09ad284d9ce +0 -0
  262. package/.npm-cache/_cacache/content-v2/sha512/60/25/d2ecd39cfc7cab58351162814be77f935c6d6491c10c3745d456da7ddb2117ffd90c10e53fe3c0f1ed16b403307841543634504398b16ee4e6b6dd8e0c45 +0 -0
  263. package/.npm-cache/_cacache/index-v5/2b/9a/7f8f40206ed8a2e0a84efaa953ccaed1f5d001e14b931083f2e7a0738007 +0 -2
  264. package/.npm-cache/_cacache/index-v5/2e/d9/fcfa5c6a6abdc2a3644ab84a95936047298c465a2f47ee03db8f7fe1e946 +0 -3
  265. package/.npm-cache/_cacache/index-v5/a9/42/e519633356d12d3d2f19da66a8301016d496c8f5c3e0554124aaa62dc043 +0 -2
  266. package/.npm-cache/_logs/2026-02-26T12_04_52_729Z-debug-0.log +0 -256
  267. package/.npm-cache/_logs/2026-02-26T12_05_36_835Z-debug-0.log +0 -18
  268. package/.npm-cache/_logs/2026-02-26T12_05_45_982Z-debug-0.log +0 -32
  269. package/.npm-cache/_logs/2026-02-26T12_05_48_515Z-debug-0.log +0 -260
  270. package/.npm-cache/_logs/2026-02-26T12_05_53_567Z-debug-0.log +0 -69
  271. package/.npm-cache/_update-notifier-last-checked +0 -0
  272. package/bootstrap-kb/decisions/decisions.md +0 -244
  273. package/bootstrap-kb/glossary/glossary.md +0 -46
  274. package/bootstrap-kb/modules/.claude-plugin.md +0 -22
  275. package/bootstrap-kb/modules/agents.md.md +0 -15
  276. package/bootstrap-kb/modules/claude.md.md +0 -15
  277. package/bootstrap-kb/modules/context.md.md +0 -15
  278. package/bootstrap-kb/modules/docs.md +0 -18
  279. package/bootstrap-kb/modules/handoff.md.md +0 -15
  280. package/bootstrap-kb/modules/package-lock.json.md +0 -15
  281. package/bootstrap-kb/modules/package.json.md +0 -15
  282. package/bootstrap-kb/modules/plan.md.md +0 -15
  283. package/bootstrap-kb/modules/readme.md.md +0 -15
  284. package/bootstrap-kb/modules/scripts.md +0 -26
  285. package/bootstrap-kb/modules/spec.md.md +0 -15
  286. package/bootstrap-kb/modules/specs.md +0 -20
  287. package/bootstrap-kb/modules/src.md +0 -51
  288. package/bootstrap-kb/modules/tests.md +0 -42
  289. package/bootstrap-kb/modules/tsconfig.json.md +0 -15
  290. package/bootstrap-kb/modules/vitest.config.ts.md +0 -15
  291. package/bootstrap-kb/overview/overview.md +0 -40
  292. package/bootstrap-kb/sources/manifest.json +0 -950
  293. package/bootstrap-kb/sources/manifest.md +0 -227
  294. package/bootstrap-kb/timeline/timeline.md +0 -57
  295. package/claude-memory-layer-1.0.14.tgz +0 -0
  296. package/d.sh +0 -3
  297. package/deploy.sh +0 -3
  298. package/dist/ui/app.js +0 -2101
  299. package/memory/.claude-plugin/commands/2026-02-25.md +0 -263
  300. package/memory/_index.md +0 -419
  301. package/memory/agent_response/uncategorized/2026-02-26.md +0 -176
  302. package/memory/agent_response/uncategorized/2026-03-03.md +0 -14
  303. package/memory/agent_response/uncategorized/2026-03-04.md +0 -1421
  304. package/memory/agent_response/uncategorized/2026-03-05.md +0 -157
  305. package/memory/default/uncategorized/2026-02-25.md +0 -4839
  306. package/memory/session_summary/uncategorized/2026-02-26.md +0 -13
  307. package/memory/session_summary/uncategorized/2026-03-03.md +0 -5
  308. package/memory/session_summary/uncategorized/2026-03-04.md +0 -50
  309. package/memory/specs/20260207-dashboard-upgrade/2026-02-25.md +0 -142
  310. package/memory/specs/citations-system/2026-02-25.md +0 -1121
  311. package/memory/specs/endless-mode/2026-02-25.md +0 -1392
  312. package/memory/specs/entity-edge-model/2026-02-25.md +0 -1263
  313. package/memory/specs/evidence-aligner-v2/2026-02-25.md +0 -1028
  314. package/memory/specs/mcp-desktop-integration/2026-02-25.md +0 -1334
  315. package/memory/specs/post-tool-use-hook/2026-02-25.md +0 -1164
  316. package/memory/specs/private-tags/2026-02-25.md +0 -1057
  317. package/memory/specs/progressive-disclosure/2026-02-25.md +0 -1436
  318. package/memory/specs/task-entity-system/2026-02-25.md +0 -924
  319. package/memory/specs/vector-outbox-v2/2026-02-25.md +0 -1510
  320. package/memory/specs/web-viewer-ui/2026-02-25.md +0 -1709
  321. package/memory/tool_observation/uncategorized/2026-02-26.md +0 -209
  322. package/memory/tool_observation/uncategorized/2026-03-03.md +0 -21
  323. package/memory/tool_observation/uncategorized/2026-03-04.md +0 -1033
  324. package/memory/tool_observation/uncategorized/2026-03-05.md +0 -33
  325. package/memory/user_prompt/uncategorized/2026-02-26.md +0 -25
  326. package/memory/user_prompt/uncategorized/2026-03-04.md +0 -634
  327. package/memory/user_prompt/uncategorized/2026-03-05.md +0 -6
  328. package/specs/optional-duckdb/context.md +0 -77
  329. package/specs/optional-duckdb/plan.md +0 -142
  330. package/specs/optional-duckdb/spec.md +0 -35
  331. 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
+ }