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,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 => {