claude-memory-layer 1.0.27 → 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 (329) 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 -419
  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 -157
  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 -33
  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/memory/user_prompt/uncategorized/2026-03-05.md +0 -6
  326. package/specs/optional-duckdb/context.md +0 -77
  327. package/specs/optional-duckdb/plan.md +0 -142
  328. package/specs/optional-duckdb/spec.md +0 -35
  329. package/src/ui/app.js +0 -2101
@@ -0,0 +1,377 @@
1
+ /**
2
+ * Retrieval Orchestrator
3
+ *
4
+ * Coordinates MemoryService-level retrieval concerns around the lower-level
5
+ * Retriever: initialization, rerank policy, project/shared scoping, optional
6
+ * intent rewriting, and non-blocking retrieval trace telemetry.
7
+ */
8
+
9
+ import {
10
+ Retriever,
11
+ type ProjectScopeMode,
12
+ type RetrievalResult,
13
+ type RetrievalStrategy,
14
+ type UnifiedRetrievalResult
15
+ } from '../retriever.js';
16
+
17
+ export interface RetrieveMemoriesOptions {
18
+ topK?: number;
19
+ minScore?: number;
20
+ sessionId?: string;
21
+ includeShared?: boolean;
22
+ adaptiveRerank?: boolean;
23
+ intentRewrite?: boolean;
24
+ projectScopeMode?: ProjectScopeMode;
25
+ allowedProjectHashes?: string[];
26
+ strategy?: RetrievalStrategy;
27
+ /**
28
+ * Disable automatic retrieval trace writes for read-only/navigation callers
29
+ * that may receive secret-bearing ad-hoc queries.
30
+ */
31
+ recordTrace?: boolean;
32
+ }
33
+
34
+ export interface RecordQueryTraceInput {
35
+ sessionId: string;
36
+ queryText: string;
37
+ strategy: string;
38
+ candidateEventIds: string[];
39
+ selectedEventIds: string[];
40
+ confidence: string;
41
+ }
42
+
43
+ interface HelpfulnessStats {
44
+ avgScore: number;
45
+ totalEvaluated: number;
46
+ totalRetrievals: number;
47
+ helpful: number;
48
+ neutral: number;
49
+ unhelpful: number;
50
+ }
51
+
52
+ type RerankWeights = {
53
+ semantic: number;
54
+ lexical: number;
55
+ recency: number;
56
+ };
57
+
58
+ interface RetrievalTraceDetail {
59
+ eventId: string;
60
+ score: number;
61
+ semanticScore?: number;
62
+ lexicalScore?: number;
63
+ recencyScore?: number;
64
+ }
65
+
66
+ export interface RetrievalTraceStore {
67
+ getHelpfulnessStats(): Promise<HelpfulnessStats>;
68
+ recordRetrievalTrace(input: {
69
+ sessionId?: string;
70
+ projectHash?: string;
71
+ queryText: string;
72
+ strategy?: string;
73
+ candidateEventIds: string[];
74
+ selectedEventIds: string[];
75
+ candidateDetails?: RetrievalTraceDetail[];
76
+ selectedDetails?: RetrievalTraceDetail[];
77
+ confidence?: string;
78
+ fallbackTrace?: string[];
79
+ }): Promise<void>;
80
+ }
81
+
82
+ export interface RetrievalAccessStore {
83
+ incrementAccessCount(eventIds: string[]): Promise<void>;
84
+ recordRetrieval(eventId: string, sessionId: string, score: number, query: string): Promise<void>;
85
+ }
86
+
87
+ export interface RetrievalOrchestratorDeps {
88
+ initialize: () => Promise<void>;
89
+ retriever: Retriever;
90
+ traceStore: RetrievalTraceStore;
91
+ accessStore: RetrievalAccessStore;
92
+ getProjectHash: () => string | null;
93
+ hasSharedStore: () => boolean;
94
+ }
95
+
96
+ export class RetrievalOrchestrator {
97
+ constructor(private readonly deps: RetrievalOrchestratorDeps) {
98
+ this.deps.retriever.setQueryRewriter((query) => this.rewriteQueryIntent(query));
99
+ }
100
+
101
+ /**
102
+ * Retrieve relevant memories for a query.
103
+ */
104
+ async retrieveMemories(
105
+ query: string,
106
+ options?: RetrieveMemoriesOptions
107
+ ): Promise<UnifiedRetrievalResult> {
108
+ const { recordTrace = true, ...retrieverOptions } = options ?? {};
109
+ const lightweightFastRead = this.isLightweightFastRead(options);
110
+ if (!lightweightFastRead) {
111
+ await this.deps.initialize();
112
+ }
113
+
114
+ // Note: Pending embeddings are processed by the background worker.
115
+ // Don't block retrieval - search with whatever vectors are available.
116
+ const rerankWeights = lightweightFastRead
117
+ ? undefined
118
+ : await this.getRerankWeights(options?.adaptiveRerank === true);
119
+ const projectHash = this.deps.getProjectHash();
120
+ const projectScopeMode = retrieverOptions.projectScopeMode ?? (projectHash ? 'strict' : 'global');
121
+
122
+ let result: UnifiedRetrievalResult;
123
+
124
+ if (retrieverOptions.includeShared && this.deps.hasSharedStore()) {
125
+ result = await this.deps.retriever.retrieveUnified(query, {
126
+ ...retrieverOptions,
127
+ intentRewrite: retrieverOptions.intentRewrite === true,
128
+ rerankWeights,
129
+ includeShared: true,
130
+ projectHash: projectHash || undefined,
131
+ projectScopeMode,
132
+ allowedProjectHashes: retrieverOptions.allowedProjectHashes
133
+ });
134
+ } else {
135
+ result = await this.deps.retriever.retrieve(query, {
136
+ ...retrieverOptions,
137
+ intentRewrite: retrieverOptions.intentRewrite === true,
138
+ rerankWeights,
139
+ projectHash: projectHash || undefined,
140
+ projectScopeMode,
141
+ allowedProjectHashes: retrieverOptions.allowedProjectHashes
142
+ });
143
+ }
144
+
145
+ if (recordTrace) {
146
+ try {
147
+ await this.recordAutomaticTrace(query, result, options, projectHash);
148
+ } catch {
149
+ // Non-blocking telemetry.
150
+ }
151
+ }
152
+
153
+ return result;
154
+ }
155
+
156
+ /**
157
+ * Format retrieval results as context for Claude.
158
+ */
159
+ formatAsContext(result: RetrievalResult): string {
160
+ if (!result.context) {
161
+ return '';
162
+ }
163
+
164
+ const confidence = result.matchResult.confidence;
165
+ let header = '';
166
+
167
+ if (confidence === 'high') {
168
+ header = '🎯 **High-confidence memory match found:**\n\n';
169
+ } else if (confidence === 'suggested') {
170
+ header = '💡 **Suggested memories (may be relevant):**\n\n';
171
+ }
172
+
173
+ return header + result.context;
174
+ }
175
+
176
+ /**
177
+ * Record a query-level retrieval trace used by hooks and dashboard stats.
178
+ */
179
+ async recordQueryTrace(input: RecordQueryTraceInput): Promise<void> {
180
+ await this.deps.initialize();
181
+ await this.deps.traceStore.recordRetrievalTrace({
182
+ ...input,
183
+ projectHash: this.deps.getProjectHash() || undefined,
184
+ candidateDetails: [],
185
+ selectedDetails: [],
186
+ fallbackTrace: [],
187
+ });
188
+ }
189
+
190
+ /**
191
+ * Increment access count for memories that were injected into prompts.
192
+ *
193
+ * Access count writes are intentionally store-scoped: the SQLite access store
194
+ * initializes itself and no-ops in read-only mode, so this avoids triggering
195
+ * the heavier retrieval/vector initialization path for prompt telemetry.
196
+ */
197
+ async incrementMemoryAccess(eventIds: string[]): Promise<void> {
198
+ if (eventIds.length === 0) return;
199
+
200
+ await this.deps.accessStore.incrementAccessCount(eventIds);
201
+ }
202
+
203
+ /**
204
+ * Record a selected retrieval for helpfulness analytics.
205
+ */
206
+ async recordRetrieval(
207
+ eventId: string,
208
+ sessionId: string,
209
+ score: number,
210
+ query: string
211
+ ): Promise<void> {
212
+ await this.deps.initialize();
213
+ await this.deps.accessStore.recordRetrieval(eventId, sessionId, score, query);
214
+ }
215
+
216
+ private async recordAutomaticTrace(
217
+ query: string,
218
+ result: UnifiedRetrievalResult,
219
+ options: RetrieveMemoriesOptions | undefined,
220
+ projectHash: string | null
221
+ ): Promise<void> {
222
+ const selectedEventIds = result.memories.map((memory) => memory.event.id);
223
+ const selectedDetails = (result.selectedDebug || []).map((detail) => ({
224
+ eventId: detail.eventId,
225
+ score: detail.score,
226
+ semanticScore: detail.semanticScore,
227
+ lexicalScore: detail.lexicalScore,
228
+ recencyScore: detail.recencyScore,
229
+ }));
230
+ const candidateDetails = (result.candidateDebug || []).map((detail) => ({
231
+ eventId: detail.eventId,
232
+ score: detail.score,
233
+ semanticScore: detail.semanticScore,
234
+ lexicalScore: detail.lexicalScore,
235
+ recencyScore: detail.recencyScore,
236
+ }));
237
+ const candidateEventIds = candidateDetails.length > 0
238
+ ? candidateDetails.map((detail) => detail.eventId)
239
+ : selectedEventIds;
240
+
241
+ await this.deps.traceStore.recordRetrievalTrace({
242
+ sessionId: options?.sessionId,
243
+ projectHash: projectHash || undefined,
244
+ queryText: query,
245
+ strategy: options?.strategy || 'auto',
246
+ candidateEventIds,
247
+ selectedEventIds,
248
+ candidateDetails,
249
+ selectedDetails,
250
+ confidence: result.matchResult.confidence,
251
+ fallbackTrace: result.fallbackTrace || []
252
+ });
253
+ }
254
+
255
+ private isLightweightFastRead(options: RetrieveMemoriesOptions | undefined): boolean {
256
+ const requiresSharedRuntime = options?.includeShared === true && this.deps.hasSharedStore();
257
+
258
+ return options?.strategy === 'fast'
259
+ && !requiresSharedRuntime
260
+ && options.adaptiveRerank !== true;
261
+ }
262
+
263
+ private getConfiguredRerankWeights(): RerankWeights | undefined {
264
+ const semantic = Number(process.env.MEMORY_RERANK_WEIGHT_SEMANTIC ?? '');
265
+ const lexical = Number(process.env.MEMORY_RERANK_WEIGHT_LEXICAL ?? '');
266
+ const recency = Number(process.env.MEMORY_RERANK_WEIGHT_RECENCY ?? '');
267
+
268
+ const allFinite = [semantic, lexical, recency].every((value) => Number.isFinite(value));
269
+ if (!allFinite) return undefined;
270
+
271
+ const nonNegative = [semantic, lexical, recency].every((value) => value >= 0);
272
+ const total = semantic + lexical + recency;
273
+ if (!nonNegative || total <= 0) return undefined;
274
+
275
+ return {
276
+ semantic: semantic / total,
277
+ lexical: lexical / total,
278
+ recency: recency / total,
279
+ };
280
+ }
281
+
282
+ private async getRerankWeights(adaptive: boolean): Promise<RerankWeights | undefined> {
283
+ const configured = this.getConfiguredRerankWeights();
284
+ if (configured) return configured;
285
+ if (adaptive) return this.getAdaptiveRerankWeights();
286
+ return undefined;
287
+ }
288
+
289
+ private async getAdaptiveRerankWeights(): Promise<RerankWeights | undefined> {
290
+ try {
291
+ const stats = await this.deps.traceStore.getHelpfulnessStats();
292
+ if (stats.totalEvaluated < 20) return undefined;
293
+
294
+ // Base weights.
295
+ let semantic = 0.7;
296
+ let lexical = 0.2;
297
+ let recency = 0.1;
298
+
299
+ if (stats.avgScore < 0.45) {
300
+ semantic -= 0.1;
301
+ lexical += 0.1;
302
+ } else if (stats.avgScore > 0.75) {
303
+ semantic += 0.05;
304
+ lexical -= 0.05;
305
+ }
306
+
307
+ if (stats.unhelpful > stats.helpful) {
308
+ recency += 0.05;
309
+ semantic -= 0.03;
310
+ lexical -= 0.02;
311
+ }
312
+
313
+ return { semantic, lexical, recency };
314
+ } catch {
315
+ return undefined;
316
+ }
317
+ }
318
+
319
+ private async rewriteQueryIntent(query: string): Promise<string | null> {
320
+ if (process.env.MEMORY_INTENT_REWRITE_ENABLED !== '1') return null;
321
+
322
+ const apiUrl = process.env.COMPANY_STOCK_API_URL || process.env.COMPANY_INT_API_URL;
323
+ if (!apiUrl) return null;
324
+
325
+ const controller = new AbortController();
326
+ const timeoutMs = Number(process.env.MEMORY_INTENT_REWRITE_TIMEOUT_MS || 5000);
327
+ const timeout = setTimeout(() => controller.abort(), timeoutMs);
328
+
329
+ try {
330
+ const prompt = [
331
+ 'Rewrite user query for memory retrieval intent expansion.',
332
+ 'Return plain text only, one line, no markdown.',
333
+ `Query: ${query}`,
334
+ ].join('\n');
335
+
336
+ const res = await fetch(apiUrl, {
337
+ method: 'POST',
338
+ headers: {
339
+ 'Content-Type': 'application/json',
340
+ Accept: '*/*',
341
+ Origin: process.env.COMPANY_INT_ORIGIN || 'http://company-int.aplusai.ai',
342
+ Referer: process.env.COMPANY_INT_REFERER || 'http://company-int.aplusai.ai/',
343
+ },
344
+ body: JSON.stringify({
345
+ question: prompt,
346
+ company_name: null,
347
+ conversation_id: null,
348
+ }),
349
+ signal: controller.signal,
350
+ });
351
+
352
+ const text = (await res.text()).trim();
353
+ if (!text) return null;
354
+
355
+ const oneLine = text
356
+ .replace(/^data:\s*/gm, '')
357
+ .split(/\r?\n/)
358
+ .map((line) => line.trim())
359
+ .filter(Boolean)
360
+ .join(' ')
361
+ .slice(0, 240);
362
+
363
+ if (!oneLine || oneLine.toLowerCase() === query.toLowerCase()) return null;
364
+ return oneLine;
365
+ } catch {
366
+ return null;
367
+ } finally {
368
+ clearTimeout(timeout);
369
+ }
370
+ }
371
+ }
372
+
373
+ export function createRetrievalOrchestrator(
374
+ deps: RetrievalOrchestratorDeps
375
+ ): RetrievalOrchestrator {
376
+ return new RetrievalOrchestrator(deps);
377
+ }
@@ -0,0 +1,176 @@
1
+ /**
2
+ * Retrieval Services Bundle
3
+ *
4
+ * Owns construction and wiring for retrieval-facing engine services so
5
+ * MemoryService can hold a thin facade boundary instead of directly
6
+ * instantiating each retrieval collaborator.
7
+ */
8
+
9
+ import type { Embedder } from '../embedder.js';
10
+ import type { EventStore } from '../event-store.js';
11
+ import type { Matcher } from '../matcher.js';
12
+ import type { MemoryEvent } from '../types.js';
13
+ import {
14
+ createRetriever as createCoreRetriever,
15
+ type Retriever
16
+ } from '../retriever.js';
17
+ import type { VectorStore } from '../vector-store.js';
18
+ import {
19
+ createRetrievalAnalyticsService,
20
+ type RetrievalAnalyticsService,
21
+ type RetrievalAnalyticsStore
22
+ } from './retrieval-analytics-service.js';
23
+ import {
24
+ createRetrievalDisclosureService,
25
+ type RetrievalDisclosureEventStore,
26
+ type RetrievalDisclosureService,
27
+ type RetrievalDisclosureSharedStore
28
+ } from './retrieval-disclosure-service.js';
29
+ import {
30
+ createRetrievalOrchestrator,
31
+ type RetrievalAccessStore,
32
+ type RetrievalOrchestrator,
33
+ type RetrievalTraceStore
34
+ } from './retrieval-orchestrator.js';
35
+
36
+ export interface RetrievalSourceStore {
37
+ getRecentEvents(limit?: number): Promise<MemoryEvent[]>;
38
+ }
39
+
40
+ export type RetrievalEventStore = RetrievalTraceStore
41
+ & RetrievalAccessStore
42
+ & RetrievalDisclosureEventStore
43
+ & RetrievalAnalyticsStore
44
+ & RetrievalSourceStore;
45
+
46
+ export type CreateRetrieverFn = (
47
+ eventStore: RetrievalEventStore,
48
+ vectorStore: VectorStore,
49
+ embedder: Embedder,
50
+ matcher: Matcher
51
+ ) => Retriever;
52
+
53
+ export interface RetrievalServicesDeps {
54
+ initialize: () => Promise<void>;
55
+ eventStore: RetrievalEventStore;
56
+ vectorStore: VectorStore;
57
+ embedder: Embedder;
58
+ matcher: Matcher;
59
+ getProjectHash: () => string | null;
60
+ hasSharedStore: () => boolean;
61
+ sharedStore?: RetrievalDisclosureSharedStore;
62
+ createRetriever?: CreateRetrieverFn;
63
+ }
64
+
65
+ export interface RetrievalServices {
66
+ retriever: Retriever;
67
+ retrievalOrchestrator: RetrievalOrchestrator;
68
+ retrievalDisclosureService: RetrievalDisclosureService;
69
+ retrievalAnalyticsService: RetrievalAnalyticsService;
70
+ }
71
+
72
+ export function createRetrievalServices(deps: RetrievalServicesDeps): RetrievalServices {
73
+ const retrieverFactory = deps.createRetriever ?? defaultCreateRetriever;
74
+ const retriever = retrieverFactory(
75
+ deps.eventStore,
76
+ deps.vectorStore,
77
+ deps.embedder,
78
+ deps.matcher
79
+ );
80
+ const retrievalOrchestrator = createRetrievalOrchestrator({
81
+ initialize: deps.initialize,
82
+ retriever,
83
+ traceStore: deps.eventStore,
84
+ accessStore: deps.eventStore,
85
+ getProjectHash: deps.getProjectHash,
86
+ hasSharedStore: deps.hasSharedStore
87
+ });
88
+ const retrievalDisclosureService = createRetrievalDisclosureService({
89
+ initialize: deps.initialize,
90
+ retrievalOrchestrator,
91
+ eventStore: deps.eventStore,
92
+ sharedStore: deps.sharedStore
93
+ });
94
+ const retrievalAnalyticsService = createRetrievalAnalyticsService({
95
+ initialize: deps.initialize,
96
+ retrievalStore: deps.eventStore
97
+ });
98
+
99
+ return {
100
+ retriever,
101
+ retrievalOrchestrator,
102
+ retrievalDisclosureService,
103
+ retrievalAnalyticsService
104
+ };
105
+ }
106
+
107
+ function defaultCreateRetriever(
108
+ eventStore: RetrievalEventStore,
109
+ vectorStore: VectorStore,
110
+ embedder: Embedder,
111
+ matcher: Matcher
112
+ ): Retriever {
113
+ assertDefaultRetrieverStore(eventStore);
114
+ return createCoreRetriever(
115
+ eventStore as unknown as EventStore,
116
+ vectorStore,
117
+ embedder,
118
+ matcher
119
+ );
120
+ }
121
+
122
+ function assertDefaultRetrieverStore(eventStore: RetrievalEventStore): void {
123
+ const store = eventStore as unknown as Record<string, unknown>;
124
+ for (const method of ['getEvent', 'getSessionEvents', 'getRecentEvents']) {
125
+ if (typeof store[method] !== 'function') {
126
+ throw new TypeError(`Default retrieval service eventStore requires ${method}()`);
127
+ }
128
+ }
129
+ }
130
+
131
+ export {
132
+ RetrievalAnalyticsService,
133
+ createRetrievalAnalyticsService
134
+ } from './retrieval-analytics-service.js';
135
+ export type {
136
+ AccessedMemory,
137
+ HelpfulMemory,
138
+ HelpfulnessStats,
139
+ RetrievalAnalyticsServiceDeps,
140
+ RetrievalAnalyticsStore,
141
+ RetrievalTrace,
142
+ RetrievalTraceStats
143
+ } from './retrieval-analytics-service.js';
144
+ export {
145
+ RetrievalDisclosureService,
146
+ createRetrievalDisclosureService,
147
+ parseDisclosureResultId,
148
+ parseDisclosureResultRef,
149
+ toDisclosureResultId
150
+ } from './retrieval-disclosure-service.js';
151
+ export type {
152
+ RetrievalDisclosureEnvelope,
153
+ RetrievalDisclosureEventStore,
154
+ RetrievalDisclosureExpansion,
155
+ RetrievalDisclosureExpandOptions,
156
+ RetrievalDisclosureOrchestrator,
157
+ RetrievalDisclosureReason,
158
+ RetrievalDisclosureSearchOptions,
159
+ RetrievalDisclosureSearchResponse,
160
+ RetrievalDisclosureServiceDeps,
161
+ RetrievalDisclosureSharedStore,
162
+ RetrievalDisclosureSource,
163
+ RetrievalDisclosureSourceReference,
164
+ RetrievalDisclosureSourceType
165
+ } from './retrieval-disclosure-service.js';
166
+ export {
167
+ RetrievalOrchestrator,
168
+ createRetrievalOrchestrator
169
+ } from './retrieval-orchestrator.js';
170
+ export type {
171
+ RecordQueryTraceInput,
172
+ RetrievalAccessStore,
173
+ RetrievalOrchestratorDeps,
174
+ RetrievalTraceStore,
175
+ RetrieveMemoriesOptions
176
+ } from './retrieval-orchestrator.js';
@@ -0,0 +1,4 @@
1
+ // Compatibility re-export. Shared memory is an optional extension, but existing
2
+ // engine/facade imports still resolve through this path during the strangler
3
+ // migration.
4
+ export * from '../../extensions/shared-memory/index.js';
@@ -9,9 +9,7 @@ import type {
9
9
  Entity,
10
10
  EntityType,
11
11
  EntityStage,
12
- EntityStatus,
13
- EntityAlias,
14
- TaskCurrentJson
12
+ EntityStatus
15
13
  } from './types.js';
16
14
  import { makeEntityCanonicalKey } from './canonical-key.js';
17
15
 
@@ -23,7 +23,7 @@ export class EventStore {
23
23
  private initialized = false;
24
24
  private readonly readOnly: boolean;
25
25
 
26
- constructor(private dbPath: string, options?: EventStoreOptions) {
26
+ constructor(dbPath: string, options?: EventStoreOptions) {
27
27
  this.readOnly = options?.readOnly ?? false;
28
28
  this.db = createDatabase(dbPath, { readOnly: this.readOnly });
29
29
  }
@@ -739,7 +739,7 @@ export class EventStore {
739
739
  /**
740
740
  * Increment access count for events (stub for compatibility)
741
741
  */
742
- async incrementAccessCount(eventIds: string[]): Promise<void> {
742
+ async incrementAccessCount(_eventIds: string[]): Promise<void> {
743
743
  // This is a stub method for compatibility
744
744
  // Actual implementation is in SQLiteEventStore
745
745
  return Promise.resolve();
@@ -748,7 +748,7 @@ export class EventStore {
748
748
  /**
749
749
  * Get most accessed memories (stub for compatibility)
750
750
  */
751
- async getMostAccessed(limit: number = 10): Promise<MemoryEvent[]> {
751
+ async getMostAccessed(_limit: number = 10): Promise<MemoryEvent[]> {
752
752
  // This is a stub method for compatibility
753
753
  // Actual implementation is in SQLiteEventStore
754
754
  return [];
@@ -212,8 +212,8 @@ export class EvidenceAligner {
212
212
  * Splits on sentence boundaries and filters short sentences
213
213
  */
214
214
  extractClaims(text: string): string[] {
215
- // Split on sentence boundaries
216
- const sentences = text.split(/[.!?]+/).map(s => s.trim()).filter(s => s.length > 0);
215
+ // Keep terminal punctuation while splitting so questions can be filtered reliably.
216
+ const sentences = text.match(/[^.!?]+[.!?]?/g)?.map(s => s.trim()).filter(s => s.length > 0) || [];
217
217
 
218
218
  // Filter out very short sentences and questions
219
219
  return sentences.filter(s => {