nlm-memory 0.20.1 → 0.21.12

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 (475) hide show
  1. package/README.md +69 -12
  2. package/assets/replay-eval-dark.svg +26 -0
  3. package/assets/replay-eval-light.svg +26 -0
  4. package/dist/cli/digest.js +69 -4
  5. package/dist/cli/digest.js.map +1 -1
  6. package/dist/cli/nlm.d.ts +14 -0
  7. package/dist/cli/nlm.js +556 -71
  8. package/dist/cli/nlm.js.map +1 -1
  9. package/dist/cli/reprocess-job-adapters.d.ts +35 -0
  10. package/dist/cli/reprocess-job-adapters.js +80 -0
  11. package/dist/cli/reprocess-job-adapters.js.map +1 -0
  12. package/dist/cli/scope-backfill.d.ts +34 -0
  13. package/dist/cli/scope-backfill.js +237 -0
  14. package/dist/cli/scope-backfill.js.map +1 -0
  15. package/dist/cli/scope-coverage.d.ts +44 -0
  16. package/dist/cli/scope-coverage.js +208 -0
  17. package/dist/cli/scope-coverage.js.map +1 -0
  18. package/dist/cli/supersede.js +8 -7
  19. package/dist/cli/supersede.js.map +1 -1
  20. package/dist/core/actions/actions-log.d.ts +65 -8
  21. package/dist/core/actions/actions-log.js +134 -17
  22. package/dist/core/actions/actions-log.js.map +1 -1
  23. package/dist/core/actions/overlay.d.ts +11 -2
  24. package/dist/core/actions/overlay.js +18 -6
  25. package/dist/core/actions/overlay.js.map +1 -1
  26. package/dist/core/adapters/claude-code.d.ts +14 -0
  27. package/dist/core/adapters/claude-code.js +30 -0
  28. package/dist/core/adapters/claude-code.js.map +1 -1
  29. package/dist/core/adapters/from-source.js +11 -3
  30. package/dist/core/adapters/from-source.js.map +1 -1
  31. package/dist/core/adapters/fs-wiki-writer.d.ts +44 -0
  32. package/dist/core/adapters/fs-wiki-writer.js +132 -0
  33. package/dist/core/adapters/fs-wiki-writer.js.map +1 -0
  34. package/dist/core/adapters/hermes-agent.d.ts +15 -2
  35. package/dist/core/adapters/hermes-agent.js +57 -11
  36. package/dist/core/adapters/hermes-agent.js.map +1 -1
  37. package/dist/core/adapters/memory-wiki-writer.d.ts +8 -0
  38. package/dist/core/adapters/memory-wiki-writer.js +16 -0
  39. package/dist/core/adapters/memory-wiki-writer.js.map +1 -0
  40. package/dist/core/adapters/muse.d.ts +51 -0
  41. package/dist/core/adapters/muse.js +271 -0
  42. package/dist/core/adapters/muse.js.map +1 -0
  43. package/dist/core/adapters/opencode.d.ts +11 -4
  44. package/dist/core/adapters/opencode.js +41 -7
  45. package/dist/core/adapters/opencode.js.map +1 -1
  46. package/dist/core/alerts/alert-state.d.ts +17 -0
  47. package/dist/core/alerts/alert-state.js +45 -0
  48. package/dist/core/alerts/alert-state.js.map +1 -0
  49. package/dist/core/alerts/check-and-alert.d.ts +28 -0
  50. package/dist/core/alerts/check-and-alert.js +53 -0
  51. package/dist/core/alerts/check-and-alert.js.map +1 -0
  52. package/dist/core/alerts/drift-transition.d.ts +27 -0
  53. package/dist/core/alerts/drift-transition.js +56 -0
  54. package/dist/core/alerts/drift-transition.js.map +1 -0
  55. package/dist/core/alerts/embedder-transition.d.ts +23 -0
  56. package/dist/core/alerts/embedder-transition.js +40 -0
  57. package/dist/core/alerts/embedder-transition.js.map +1 -0
  58. package/dist/core/alerts/fire-alert.d.ts +24 -0
  59. package/dist/core/alerts/fire-alert.js +72 -0
  60. package/dist/core/alerts/fire-alert.js.map +1 -0
  61. package/dist/core/alerts/job-alert.d.ts +12 -0
  62. package/dist/core/alerts/job-alert.js +37 -0
  63. package/dist/core/alerts/job-alert.js.map +1 -0
  64. package/dist/core/alerts/types.d.ts +104 -0
  65. package/dist/core/alerts/types.js +11 -0
  66. package/dist/core/alerts/types.js.map +1 -0
  67. package/dist/core/alerts/wiki-alert.d.ts +15 -0
  68. package/dist/core/alerts/wiki-alert.js +31 -0
  69. package/dist/core/alerts/wiki-alert.js.map +1 -0
  70. package/dist/core/classifier/prompt.d.ts +13 -0
  71. package/dist/core/classifier/prompt.js +52 -2
  72. package/dist/core/classifier/prompt.js.map +1 -1
  73. package/dist/core/dataset/build-dataset.d.ts +16 -1
  74. package/dist/core/dataset/build-dataset.js +46 -13
  75. package/dist/core/dataset/build-dataset.js.map +1 -1
  76. package/dist/core/digest/compose.d.ts +11 -3
  77. package/dist/core/digest/compose.js +70 -17
  78. package/dist/core/digest/compose.js.map +1 -1
  79. package/dist/core/digest/hook-injection.d.ts +43 -0
  80. package/dist/core/digest/hook-injection.js +87 -0
  81. package/dist/core/digest/hook-injection.js.map +1 -0
  82. package/dist/core/digest/hook-version-parity.d.ts +31 -0
  83. package/dist/core/digest/hook-version-parity.js +56 -0
  84. package/dist/core/digest/hook-version-parity.js.map +1 -0
  85. package/dist/core/embedding/pg-embed-backfill.js +1 -1
  86. package/dist/core/embedding/pg-embed-backfill.js.map +1 -1
  87. package/dist/core/exemplars/capture-from-session.d.ts +2 -1
  88. package/dist/core/exemplars/capture-from-session.js +4 -4
  89. package/dist/core/exemplars/capture-from-session.js.map +1 -1
  90. package/dist/core/exemplars/embed-backfill.d.ts +9 -0
  91. package/dist/core/exemplars/embed-backfill.js +9 -1
  92. package/dist/core/exemplars/embed-backfill.js.map +1 -1
  93. package/dist/core/exemplars/extract-exemplar.d.ts +2 -0
  94. package/dist/core/exemplars/extract-exemplar.js +7 -1
  95. package/dist/core/exemplars/extract-exemplar.js.map +1 -1
  96. package/dist/core/exemplars/ingest-exemplar.d.ts +1 -0
  97. package/dist/core/exemplars/ingest-exemplar.js +1 -0
  98. package/dist/core/exemplars/ingest-exemplar.js.map +1 -1
  99. package/dist/core/exemplars/recall-code.d.ts +1 -1
  100. package/dist/core/exemplars/recall-code.js +2 -2
  101. package/dist/core/exemplars/recall-code.js.map +1 -1
  102. package/dist/core/facts/backfill-facts.d.ts +1 -1
  103. package/dist/core/facts/backfill-facts.js +4 -4
  104. package/dist/core/facts/backfill-facts.js.map +1 -1
  105. package/dist/core/facts/embed-backfill.d.ts +54 -0
  106. package/dist/core/facts/embed-backfill.js +109 -0
  107. package/dist/core/facts/embed-backfill.js.map +1 -0
  108. package/dist/core/facts/reconcile-facts.d.ts +42 -0
  109. package/dist/core/facts/reconcile-facts.js +133 -0
  110. package/dist/core/facts/reconcile-facts.js.map +1 -0
  111. package/dist/core/health/embed-failure-state.d.ts +4 -0
  112. package/dist/core/health/embed-failure-state.js +12 -0
  113. package/dist/core/health/embed-failure-state.js.map +1 -0
  114. package/dist/core/health/warmup-retry.d.ts +27 -0
  115. package/dist/core/health/warmup-retry.js +53 -0
  116. package/dist/core/health/warmup-retry.js.map +1 -0
  117. package/dist/core/health/warmup-state.d.ts +15 -0
  118. package/dist/core/health/warmup-state.js +15 -1
  119. package/dist/core/health/warmup-state.js.map +1 -1
  120. package/dist/core/hook/cite-memo.d.ts +11 -7
  121. package/dist/core/hook/cite-memo.js +25 -17
  122. package/dist/core/hook/cite-memo.js.map +1 -1
  123. package/dist/core/hook/claude-settings.d.ts +1 -1
  124. package/dist/core/hook/claude-settings.js +0 -1
  125. package/dist/core/hook/claude-settings.js.map +1 -1
  126. package/dist/core/hook/hook-log.d.ts +13 -2
  127. package/dist/core/hook/hook-log.js +16 -8
  128. package/dist/core/hook/hook-log.js.map +1 -1
  129. package/dist/core/hook/memo.d.ts +10 -6
  130. package/dist/core/hook/memo.js +25 -17
  131. package/dist/core/hook/memo.js.map +1 -1
  132. package/dist/core/hook/pointer-block.d.ts +8 -1
  133. package/dist/core/hook/pointer-block.js +17 -4
  134. package/dist/core/hook/pointer-block.js.map +1 -1
  135. package/dist/core/hook/resolve-conversation-by-query.d.ts +6 -5
  136. package/dist/core/hook/resolve-conversation-by-query.js +24 -12
  137. package/dist/core/hook/resolve-conversation-by-query.js.map +1 -1
  138. package/dist/core/ingest/backfill-derivables.d.ts +92 -0
  139. package/dist/core/ingest/backfill-derivables.js +175 -0
  140. package/dist/core/ingest/backfill-derivables.js.map +1 -0
  141. package/dist/core/ingest/ingest-session.d.ts +1 -1
  142. package/dist/core/ingest/ingest-session.js +23 -3
  143. package/dist/core/ingest/ingest-session.js.map +1 -1
  144. package/dist/core/ingest/reclassify-oversized.d.ts +1 -1
  145. package/dist/core/ingest/reclassify-oversized.js +8 -2
  146. package/dist/core/ingest/reclassify-oversized.js.map +1 -1
  147. package/dist/core/ingest/reprocess.d.ts +1 -1
  148. package/dist/core/ingest/reprocess.js +7 -2
  149. package/dist/core/ingest/reprocess.js.map +1 -1
  150. package/dist/core/ingest/transcript-derivables.d.ts +27 -0
  151. package/dist/core/ingest/transcript-derivables.js +138 -0
  152. package/dist/core/ingest/transcript-derivables.js.map +1 -0
  153. package/dist/core/jobs/job-supervisor.d.ts +168 -0
  154. package/dist/core/jobs/job-supervisor.js +335 -0
  155. package/dist/core/jobs/job-supervisor.js.map +1 -0
  156. package/dist/core/learner/model.d.ts +63 -0
  157. package/dist/core/learner/model.js +30 -0
  158. package/dist/core/learner/model.js.map +1 -0
  159. package/dist/core/learner/service.d.ts +42 -0
  160. package/dist/core/learner/service.js +74 -0
  161. package/dist/core/learner/service.js.map +1 -0
  162. package/dist/core/learner/summary.d.ts +28 -0
  163. package/dist/core/learner/summary.js +70 -0
  164. package/dist/core/learner/summary.js.map +1 -0
  165. package/dist/core/learner/validate.d.ts +18 -0
  166. package/dist/core/learner/validate.js +95 -0
  167. package/dist/core/learner/validate.js.map +1 -0
  168. package/dist/core/metrics/re-derivation.d.ts +31 -2
  169. package/dist/core/metrics/re-derivation.js +36 -4
  170. package/dist/core/metrics/re-derivation.js.map +1 -1
  171. package/dist/core/outcome/coverage.d.ts +33 -0
  172. package/dist/core/outcome/coverage.js +46 -0
  173. package/dist/core/outcome/coverage.js.map +1 -0
  174. package/dist/core/outcome/rollup.d.ts +33 -0
  175. package/dist/core/outcome/rollup.js +113 -0
  176. package/dist/core/outcome/rollup.js.map +1 -0
  177. package/dist/core/providers/provider-registry.d.ts +40 -23
  178. package/dist/core/providers/provider-registry.js +99 -81
  179. package/dist/core/providers/provider-registry.js.map +1 -1
  180. package/dist/core/recall/citation-log.d.ts +10 -5
  181. package/dist/core/recall/citation-log.js +21 -10
  182. package/dist/core/recall/citation-log.js.map +1 -1
  183. package/dist/core/recall/hook-recall-log.d.ts +7 -4
  184. package/dist/core/recall/hook-recall-log.js +14 -8
  185. package/dist/core/recall/hook-recall-log.js.map +1 -1
  186. package/dist/core/recall/miss-log.d.ts +7 -4
  187. package/dist/core/recall/miss-log.js +18 -11
  188. package/dist/core/recall/miss-log.js.map +1 -1
  189. package/dist/core/recall/query-log.d.ts +8 -5
  190. package/dist/core/recall/query-log.js +16 -9
  191. package/dist/core/recall/query-log.js.map +1 -1
  192. package/dist/core/recall/recall-service.d.ts +10 -1
  193. package/dist/core/recall/recall-service.js +31 -12
  194. package/dist/core/recall/recall-service.js.map +1 -1
  195. package/dist/core/recall/recent-log.d.ts +6 -1
  196. package/dist/core/recall/recent-log.js +13 -5
  197. package/dist/core/recall/recent-log.js.map +1 -1
  198. package/dist/core/recall/related-concepts.d.ts +29 -0
  199. package/dist/core/recall/related-concepts.js +67 -0
  200. package/dist/core/recall/related-concepts.js.map +1 -0
  201. package/dist/core/recall/related-exemplars.d.ts +1 -1
  202. package/dist/core/recall/related-exemplars.js +2 -2
  203. package/dist/core/recall/related-exemplars.js.map +1 -1
  204. package/dist/core/recall/related-facts.d.ts +1 -1
  205. package/dist/core/recall/related-facts.js +3 -3
  206. package/dist/core/recall/related-facts.js.map +1 -1
  207. package/dist/core/recall-facts/fact-query-log.d.ts +8 -4
  208. package/dist/core/recall-facts/fact-query-log.js +16 -8
  209. package/dist/core/recall-facts/fact-query-log.js.map +1 -1
  210. package/dist/core/recall-facts/fact-recall-service.d.ts +2 -2
  211. package/dist/core/recall-facts/fact-recall-service.js +13 -12
  212. package/dist/core/recall-facts/fact-recall-service.js.map +1 -1
  213. package/dist/core/scheduler/scan-once.js +15 -12
  214. package/dist/core/scheduler/scan-once.js.map +1 -1
  215. package/dist/core/scheduler/scheduler.d.ts +3 -0
  216. package/dist/core/scheduler/scheduler.js +45 -10
  217. package/dist/core/scheduler/scheduler.js.map +1 -1
  218. package/dist/core/scope/alias-map.d.ts +10 -0
  219. package/dist/core/scope/alias-map.js +41 -0
  220. package/dist/core/scope/alias-map.js.map +1 -0
  221. package/dist/core/scope/derive-scope.d.ts +8 -0
  222. package/dist/core/scope/derive-scope.js +54 -0
  223. package/dist/core/scope/derive-scope.js.map +1 -0
  224. package/dist/core/scope/scope-clause.d.ts +16 -0
  225. package/dist/core/scope/scope-clause.js +21 -0
  226. package/dist/core/scope/scope-clause.js.map +1 -0
  227. package/dist/core/scope/stamp-flag.d.ts +1 -0
  228. package/dist/core/scope/stamp-flag.js +4 -0
  229. package/dist/core/scope/stamp-flag.js.map +1 -0
  230. package/dist/core/signals/code-signal.d.ts +1 -0
  231. package/dist/core/signals/code-signal.js +1 -0
  232. package/dist/core/signals/code-signal.js.map +1 -1
  233. package/dist/core/signals/failure-mode-recall.d.ts +1 -1
  234. package/dist/core/signals/failure-mode-recall.js +2 -2
  235. package/dist/core/signals/failure-mode-recall.js.map +1 -1
  236. package/dist/core/signals/ingest-signal.d.ts +1 -1
  237. package/dist/core/signals/ingest-signal.js +3 -1
  238. package/dist/core/signals/ingest-signal.js.map +1 -1
  239. package/dist/core/signals/stamp-scope.d.ts +18 -0
  240. package/dist/core/signals/stamp-scope.js +28 -0
  241. package/dist/core/signals/stamp-scope.js.map +1 -0
  242. package/dist/core/sources/source-registry.d.ts +49 -28
  243. package/dist/core/sources/source-registry.js +113 -70
  244. package/dist/core/sources/source-registry.js.map +1 -1
  245. package/dist/core/storage/pg-code-exemplar-store.d.ts +19 -10
  246. package/dist/core/storage/pg-code-exemplar-store.js +62 -27
  247. package/dist/core/storage/pg-code-exemplar-store.js.map +1 -1
  248. package/dist/core/storage/pg-entity-store.d.ts +6 -1
  249. package/dist/core/storage/pg-entity-store.js +33 -18
  250. package/dist/core/storage/pg-entity-store.js.map +1 -1
  251. package/dist/core/storage/pg-fact-ingest.d.ts +1 -1
  252. package/dist/core/storage/pg-fact-ingest.js +10 -7
  253. package/dist/core/storage/pg-fact-ingest.js.map +1 -1
  254. package/dist/core/storage/pg-fact-store.d.ts +29 -17
  255. package/dist/core/storage/pg-fact-store.js +99 -46
  256. package/dist/core/storage/pg-fact-store.js.map +1 -1
  257. package/dist/core/storage/pg-learner-store.d.ts +27 -0
  258. package/dist/core/storage/pg-learner-store.js +174 -0
  259. package/dist/core/storage/pg-learner-store.js.map +1 -0
  260. package/dist/core/storage/pg-session-store.d.ts +25 -21
  261. package/dist/core/storage/pg-session-store.js +186 -114
  262. package/dist/core/storage/pg-session-store.js.map +1 -1
  263. package/dist/core/storage/pg-signal-store.d.ts +10 -5
  264. package/dist/core/storage/pg-signal-store.js +26 -13
  265. package/dist/core/storage/pg-signal-store.js.map +1 -1
  266. package/dist/core/storage/pg-storage.d.ts +4 -0
  267. package/dist/core/storage/pg-storage.js +6 -0
  268. package/dist/core/storage/pg-storage.js.map +1 -1
  269. package/dist/core/storage/pg-workstream-store.d.ts +17 -11
  270. package/dist/core/storage/pg-workstream-store.js +47 -29
  271. package/dist/core/storage/pg-workstream-store.js.map +1 -1
  272. package/dist/core/storage/sqlite-code-exemplar-store.d.ts +24 -10
  273. package/dist/core/storage/sqlite-code-exemplar-store.js +86 -40
  274. package/dist/core/storage/sqlite-code-exemplar-store.js.map +1 -1
  275. package/dist/core/storage/sqlite-entity-store.d.ts +8 -1
  276. package/dist/core/storage/sqlite-entity-store.js +46 -27
  277. package/dist/core/storage/sqlite-entity-store.js.map +1 -1
  278. package/dist/core/storage/sqlite-fact-store.d.ts +45 -19
  279. package/dist/core/storage/sqlite-fact-store.js +175 -64
  280. package/dist/core/storage/sqlite-fact-store.js.map +1 -1
  281. package/dist/core/storage/sqlite-learner-store.d.ts +33 -0
  282. package/dist/core/storage/sqlite-learner-store.js +178 -0
  283. package/dist/core/storage/sqlite-learner-store.js.map +1 -0
  284. package/dist/core/storage/sqlite-outcome-store.d.ts +104 -0
  285. package/dist/core/storage/sqlite-outcome-store.js +211 -0
  286. package/dist/core/storage/sqlite-outcome-store.js.map +1 -0
  287. package/dist/core/storage/sqlite-session-store.d.ts +50 -21
  288. package/dist/core/storage/sqlite-session-store.js +233 -149
  289. package/dist/core/storage/sqlite-session-store.js.map +1 -1
  290. package/dist/core/storage/sqlite-signal-store.d.ts +12 -5
  291. package/dist/core/storage/sqlite-signal-store.js +29 -15
  292. package/dist/core/storage/sqlite-signal-store.js.map +1 -1
  293. package/dist/core/storage/sqlite-storage.d.ts +4 -0
  294. package/dist/core/storage/sqlite-storage.js +10 -2
  295. package/dist/core/storage/sqlite-storage.js.map +1 -1
  296. package/dist/core/storage/sqlite-workstream-store.d.ts +17 -11
  297. package/dist/core/storage/sqlite-workstream-store.js +53 -31
  298. package/dist/core/storage/sqlite-workstream-store.js.map +1 -1
  299. package/dist/core/storage/supersedence-log.d.ts +10 -7
  300. package/dist/core/storage/supersedence-log.js +21 -14
  301. package/dist/core/storage/supersedence-log.js.map +1 -1
  302. package/dist/core/telemetry/probe-filter.d.ts +35 -0
  303. package/dist/core/telemetry/probe-filter.js +56 -0
  304. package/dist/core/telemetry/probe-filter.js.map +1 -0
  305. package/dist/core/tenancy/default-team.d.ts +6 -0
  306. package/dist/core/tenancy/default-team.js +7 -0
  307. package/dist/core/tenancy/default-team.js.map +1 -0
  308. package/dist/core/tenancy/hosted-mode.d.ts +9 -0
  309. package/dist/core/tenancy/hosted-mode.js +12 -0
  310. package/dist/core/tenancy/hosted-mode.js.map +1 -0
  311. package/dist/core/tenancy/team-auth.d.ts +16 -0
  312. package/dist/core/tenancy/team-auth.js +22 -0
  313. package/dist/core/tenancy/team-auth.js.map +1 -0
  314. package/dist/core/tenancy/team-token-store.d.ts +45 -0
  315. package/dist/core/tenancy/team-token-store.js +52 -0
  316. package/dist/core/tenancy/team-token-store.js.map +1 -0
  317. package/dist/core/tenancy/tenant-clause.d.ts +37 -0
  318. package/dist/core/tenancy/tenant-clause.js +11 -0
  319. package/dist/core/tenancy/tenant-clause.js.map +1 -0
  320. package/dist/core/tenancy/tenant-state-path.d.ts +28 -0
  321. package/dist/core/tenancy/tenant-state-path.js +49 -0
  322. package/dist/core/tenancy/tenant-state-path.js.map +1 -0
  323. package/dist/core/update-check/check.d.ts +6 -0
  324. package/dist/core/update-check/check.js +35 -0
  325. package/dist/core/update-check/check.js.map +1 -1
  326. package/dist/core/wiki/project.d.ts +17 -0
  327. package/dist/core/wiki/project.js +37 -0
  328. package/dist/core/wiki/project.js.map +1 -0
  329. package/dist/core/wiki/reconcile.d.ts +15 -0
  330. package/dist/core/wiki/reconcile.js +14 -0
  331. package/dist/core/wiki/reconcile.js.map +1 -0
  332. package/dist/core/wiki/render.d.ts +5 -0
  333. package/dist/core/wiki/render.js +84 -0
  334. package/dist/core/wiki/render.js.map +1 -0
  335. package/dist/core/wiki/rollup.d.ts +28 -0
  336. package/dist/core/wiki/rollup.js +91 -0
  337. package/dist/core/wiki/rollup.js.map +1 -0
  338. package/dist/core/wiki/select.d.ts +8 -0
  339. package/dist/core/wiki/select.js +7 -0
  340. package/dist/core/wiki/select.js.map +1 -0
  341. package/dist/core/wiki/slug.d.ts +36 -0
  342. package/dist/core/wiki/slug.js +71 -0
  343. package/dist/core/wiki/slug.js.map +1 -0
  344. package/dist/core/wiki/types.d.ts +37 -0
  345. package/dist/core/wiki/types.js +2 -0
  346. package/dist/core/wiki/types.js.map +1 -0
  347. package/dist/core/work-digest/build-work-digest.d.ts +1 -1
  348. package/dist/core/work-digest/build-work-digest.js +3 -3
  349. package/dist/core/work-digest/build-work-digest.js.map +1 -1
  350. package/dist/core/workstream/bind.d.ts +3 -2
  351. package/dist/core/workstream/bind.js +29 -10
  352. package/dist/core/workstream/bind.js.map +1 -1
  353. package/dist/core/workstream/model.d.ts +1 -0
  354. package/dist/core/workstream/model.js.map +1 -1
  355. package/dist/core/workstream/rollup.d.ts +1 -1
  356. package/dist/core/workstream/rollup.js +6 -6
  357. package/dist/core/workstream/rollup.js.map +1 -1
  358. package/dist/hook/hook-helpers.d.ts +14 -0
  359. package/dist/hook/hook-helpers.js +29 -2
  360. package/dist/hook/hook-helpers.js.map +1 -1
  361. package/dist/hook/pre-compact-hook.js +8 -5
  362. package/dist/hook/pre-compact-hook.js.map +1 -1
  363. package/dist/hook/prompt-recall-hook.d.ts +7 -3
  364. package/dist/hook/prompt-recall-hook.js +35 -20
  365. package/dist/hook/prompt-recall-hook.js.map +1 -1
  366. package/dist/hook/recall-over-http.d.ts +28 -3
  367. package/dist/hook/recall-over-http.js +58 -12
  368. package/dist/hook/recall-over-http.js.map +1 -1
  369. package/dist/hook/session-end-hook.js +7 -5
  370. package/dist/hook/session-end-hook.js.map +1 -1
  371. package/dist/hook/session-start-hook.d.ts +14 -1
  372. package/dist/hook/session-start-hook.js +57 -16
  373. package/dist/hook/session-start-hook.js.map +1 -1
  374. package/dist/hook/stop-hook.js +11 -8
  375. package/dist/hook/stop-hook.js.map +1 -1
  376. package/dist/http/app.d.ts +47 -3
  377. package/dist/http/app.js +379 -132
  378. package/dist/http/app.js.map +1 -1
  379. package/dist/install/claude-code.d.ts +17 -0
  380. package/dist/install/claude-code.js +44 -5
  381. package/dist/install/claude-code.js.map +1 -1
  382. package/dist/install/codex.d.ts +23 -2
  383. package/dist/install/codex.js +111 -14
  384. package/dist/install/codex.js.map +1 -1
  385. package/dist/install/cursor.d.ts +2 -2
  386. package/dist/install/cursor.js +7 -7
  387. package/dist/install/cursor.js.map +1 -1
  388. package/dist/install/hermes.d.ts +8 -0
  389. package/dist/install/hermes.js +28 -5
  390. package/dist/install/hermes.js.map +1 -1
  391. package/dist/install/local-source.d.ts +20 -0
  392. package/dist/install/local-source.js +28 -0
  393. package/dist/install/local-source.js.map +1 -0
  394. package/dist/install/mcp-block.d.ts +77 -0
  395. package/dist/install/mcp-block.js +99 -0
  396. package/dist/install/mcp-block.js.map +1 -0
  397. package/dist/install/pi.d.ts +26 -0
  398. package/dist/install/pi.js +43 -0
  399. package/dist/install/pi.js.map +1 -1
  400. package/dist/install/setup.js +6 -0
  401. package/dist/install/setup.js.map +1 -1
  402. package/dist/install/windsurf.d.ts +2 -2
  403. package/dist/install/windsurf.js +7 -7
  404. package/dist/install/windsurf.js.map +1 -1
  405. package/dist/llm/classifier-box.d.ts +5 -0
  406. package/dist/llm/classifier-box.js +5 -0
  407. package/dist/llm/classifier-box.js.map +1 -1
  408. package/dist/mcp/server.d.ts +94 -15
  409. package/dist/mcp/server.js +402 -79
  410. package/dist/mcp/server.js.map +1 -1
  411. package/dist/ports/clock.d.ts +12 -0
  412. package/dist/ports/clock.js +10 -0
  413. package/dist/ports/clock.js.map +1 -0
  414. package/dist/ports/code-exemplar-store.d.ts +13 -13
  415. package/dist/ports/entity-store.d.ts +5 -1
  416. package/dist/ports/fact-store.d.ts +0 -0
  417. package/dist/ports/fact-store.js +0 -0
  418. package/dist/ports/fact-store.js.map +1 -1
  419. package/dist/ports/learner-store.d.ts +80 -0
  420. package/dist/ports/learner-store.js +19 -0
  421. package/dist/ports/learner-store.js.map +1 -0
  422. package/dist/ports/outcome.d.ts +85 -0
  423. package/dist/ports/outcome.js +11 -0
  424. package/dist/ports/outcome.js.map +1 -0
  425. package/dist/ports/session-store.d.ts +20 -20
  426. package/dist/ports/session-store.js +5 -0
  427. package/dist/ports/session-store.js.map +1 -1
  428. package/dist/ports/signal-store.d.ts +12 -8
  429. package/dist/ports/spawn-child.d.ts +14 -0
  430. package/dist/ports/spawn-child.js +10 -0
  431. package/dist/ports/spawn-child.js.map +1 -0
  432. package/dist/ports/storage.d.ts +6 -0
  433. package/dist/ports/transcript-adapter.d.ts +11 -0
  434. package/dist/ports/wiki-writer.d.ts +19 -0
  435. package/dist/ports/wiki-writer.js +12 -0
  436. package/dist/ports/wiki-writer.js.map +1 -0
  437. package/dist/ports/workstream-store.d.ts +20 -12
  438. package/dist/shared/net.d.ts +3 -0
  439. package/dist/shared/net.js +4 -0
  440. package/dist/shared/net.js.map +1 -0
  441. package/dist/shared/types.d.ts +55 -0
  442. package/dist/shared/types.js +4 -1
  443. package/dist/shared/types.js.map +1 -1
  444. package/dist/shared/version.d.ts +9 -0
  445. package/dist/shared/version.js +11 -0
  446. package/dist/shared/version.js.map +1 -0
  447. package/dist/ui/assets/index-D6F3xAis.js +11 -0
  448. package/dist/ui/index.html +1 -1
  449. package/migrations/029_project_scope.sql +21 -0
  450. package/migrations/032_session_derivables.sql +11 -0
  451. package/migrations/033_actions_kind_check.sql +58 -0
  452. package/migrations/034_tenancy_teams_and_stamps.sql +40 -0
  453. package/migrations/035_tenancy_entity_rekey.sql +75 -0
  454. package/migrations/036_tenant_name_uniqueness.sql +59 -0
  455. package/migrations/037_sessions_covering_index.sql +25 -0
  456. package/migrations/038_sources_muse.sql +33 -0
  457. package/migrations/039_learner_evidence.sql +51 -0
  458. package/migrations/pg/030_project_scope.sql +23 -0
  459. package/migrations/pg/031_widen_session_edges_kind.sql +11 -0
  460. package/migrations/pg/032_session_derivables.sql +17 -0
  461. package/migrations/pg/033_actions_kind_check.sql +17 -0
  462. package/migrations/pg/034_tenancy.sql +77 -0
  463. package/migrations/pg/035_tenant_name_uniqueness.sql +15 -0
  464. package/migrations/pg/036_sources_muse.sql +12 -0
  465. package/migrations/pg/037_learner_evidence.sql +55 -0
  466. package/nlm/index.js +258 -59
  467. package/package.json +10 -5
  468. package/plugin/.codex-plugin/plugin.json +1 -1
  469. package/plugin/scripts/prompt-recall-hook.mjs +256 -58
  470. package/plugin/scripts/session-start-hook.mjs +283 -55
  471. package/plugin/scripts/stop-hook.mjs +199 -38
  472. package/dist/hook/subagent-start-hook.d.ts +0 -28
  473. package/dist/hook/subagent-start-hook.js +0 -81
  474. package/dist/hook/subagent-start-hook.js.map +0 -1
  475. package/dist/ui/assets/index-CMpQkbQy.js +0 -11
@@ -1,20 +1,163 @@
1
1
  #!/usr/bin/env node
2
2
 
3
3
  // src/hook/session-start-hook.ts
4
- import { pathToFileURL } from "node:url";
4
+ import { execFileSync } from "node:child_process";
5
5
 
6
6
  // src/core/hook/hook-log.ts
7
7
  import { appendFileSync, mkdirSync } from "node:fs";
8
+ import { dirname } from "node:path";
9
+
10
+ // src/core/tenancy/tenant-state-path.ts
11
+ import { createHash } from "node:crypto";
8
12
  import { homedir } from "node:os";
9
- import { dirname, join } from "node:path";
10
- function logPath() {
11
- return process.env["NLM_HOOK_LOG"] ?? join(homedir(), ".nlm", "hook-log.jsonl");
13
+ import { join } from "node:path";
14
+
15
+ // src/core/tenancy/default-team.ts
16
+ var DEFAULT_TEAM_ID = "team_local";
17
+
18
+ // src/core/tenancy/tenant-state-path.ts
19
+ var TENANTS_DIRNAME = "tenants";
20
+ var SAFE_TENANT_ID = /^[A-Za-z0-9_-]+$/;
21
+ function sanitizeTenantId(tenantId) {
22
+ if (SAFE_TENANT_ID.test(tenantId)) return tenantId;
23
+ const sanitized = tenantId.replace(/[^A-Za-z0-9_-]/g, "_") || "unknown";
24
+ const hash = createHash("sha256").update(tenantId).digest("hex").slice(0, 8);
25
+ return `${sanitized}_${hash}`;
26
+ }
27
+ function stateRoot() {
28
+ return process.env["NLM_STATE_ROOT"] || join(homedir(), ".nlm");
29
+ }
30
+ function tenantStatePath(tenantId, ...segments) {
31
+ const base = stateRoot();
32
+ if (tenantId === DEFAULT_TEAM_ID) return join(base, ...segments);
33
+ return join(base, TENANTS_DIRNAME, sanitizeTenantId(tenantId), ...segments);
34
+ }
35
+
36
+ // package.json
37
+ var package_default = {
38
+ name: "nlm-memory",
39
+ version: "0.21.12",
40
+ description: "Local-first non-linear memory operating system for AI operators.",
41
+ type: "module",
42
+ license: "Apache-2.0",
43
+ engines: {
44
+ node: ">=22.0.0"
45
+ },
46
+ repository: {
47
+ type: "git",
48
+ url: "git+https://github.com/pbmagnet4/nlm-memory.git"
49
+ },
50
+ homepage: "https://github.com/pbmagnet4/nlm-memory#readme",
51
+ bugs: {
52
+ url: "https://github.com/pbmagnet4/nlm-memory/issues"
53
+ },
54
+ keywords: [
55
+ "ai",
56
+ "memory",
57
+ "mcp",
58
+ "claude-code",
59
+ "codex",
60
+ "hermes",
61
+ "local-first",
62
+ "recall",
63
+ "session-memory"
64
+ ],
65
+ files: [
66
+ "dist",
67
+ "migrations",
68
+ "fixtures",
69
+ "templates",
70
+ "plugin",
71
+ "plugin-hermes-agent",
72
+ "nlm",
73
+ "assets",
74
+ "LICENSE",
75
+ "README.md"
76
+ ],
77
+ bin: {
78
+ nlm: "dist/cli/nlm.js"
79
+ },
80
+ scripts: {
81
+ dev: "tsx watch src/cli/nlm.ts start",
82
+ start: "node dist/cli/nlm.js start",
83
+ "build:server": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
84
+ "build:ui": "vite build --config src/ui/vite.config.ts",
85
+ "build:codex-plugin": "node scripts/build-codex-plugin.mjs",
86
+ "verify:codex-release": "node scripts/verify-codex-release.mjs",
87
+ build: "npm run build:server && npm run build:ui && npm run build:codex-plugin",
88
+ prepare: "[ -d src ] && npm run build || true",
89
+ "ui:dev": "vite --config src/ui/vite.config.ts",
90
+ test: "vitest run",
91
+ "test:watch": "vitest",
92
+ "test:unit": "vitest run tests/unit",
93
+ "test:integration": "vitest run tests/integration",
94
+ "test:pg": "vitest run .pg.test.ts --test-timeout=20000",
95
+ typecheck: "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json && tsc -p tsconfig.scripts.json",
96
+ "bench:longmemeval": "tsx scripts/longmemeval/run-harness.ts",
97
+ "bench:classifier": "tsx scripts/longmemeval/run-harness.ts --classifier",
98
+ "bench:compare": "tsx scripts/longmemeval/compare-classifiers.ts",
99
+ "eval:signals": "tsx scripts/eval/signals-eval.ts",
100
+ "eval:classifier": "tsx scripts/eval/classifier-eval.ts",
101
+ "eval:fact-recall": "tsx scripts/eval/fact-recall-eval.ts",
102
+ "eval:recall-impact-replay": "tsx scripts/eval/recall-impact-replay.ts",
103
+ "eval:code-exemplar": "tsx scripts/eval/code-exemplar-eval.ts",
104
+ "eval:reranker": "tsx scripts/eval/reranker-ablation.ts",
105
+ "eval:floor": "tsx scripts/eval/floor-calibration.ts",
106
+ "eval:matcher": "tsx scripts/eval/tune-matcher.ts",
107
+ "eval:naming": "tsx scripts/eval/tune-naming.ts",
108
+ "eval:rederiv-sample": "tsx scripts/eval/re-derivation-sample.ts",
109
+ "eval:rederiv-label": "tsx scripts/eval/re-derivation-label.ts",
110
+ "eval:rederiv-calibrate": "tsx scripts/eval/re-derivation-calibrate.ts"
111
+ },
112
+ dependencies: {
113
+ "@clack/prompts": "^1.4.0",
114
+ "@hono/node-server": "^2.0.3",
115
+ "@huggingface/transformers": "4.2.0",
116
+ "@modelcontextprotocol/sdk": "^1.29.0",
117
+ "@toon-format/toon": "^2.3.0",
118
+ "better-sqlite3": "^13.0.1",
119
+ commander: "^15.0.0",
120
+ hono: "^4.6.0",
121
+ pg: "^8.21.0",
122
+ pgvector: "^0.3.0",
123
+ "sqlite-vec": "^0.1.6",
124
+ yaml: "^2.9.0",
125
+ zod: "^4.4.3"
126
+ },
127
+ devDependencies: {
128
+ "@types/better-sqlite3": "^7.6.13",
129
+ "@types/node": "^22.10.0",
130
+ "@types/pg": "^8.20.0",
131
+ "@types/react": "^19.2.17",
132
+ "@types/react-dom": "^19.2.3",
133
+ "@vitejs/plugin-react": "^6.0.2",
134
+ esbuild: "^0.28.0",
135
+ react: "^19.2.7",
136
+ "react-dom": "^19.2.7",
137
+ "react-router-dom": "^6.30.3",
138
+ "tsc-alias": "^1.8.17",
139
+ tsx: "^4.19.0",
140
+ typescript: "^6.0.3",
141
+ vite: "^8.0.16",
142
+ vitest: "^4.1.8"
143
+ }
144
+ };
145
+
146
+ // src/shared/version.ts
147
+ var NLM_VERSION = package_default.version;
148
+
149
+ // src/core/hook/hook-log.ts
150
+ function logPath(tenantId) {
151
+ if (tenantId === DEFAULT_TEAM_ID) {
152
+ return process.env["NLM_HOOK_LOG"] ?? tenantStatePath(tenantId, "hook-log.jsonl");
153
+ }
154
+ return tenantStatePath(tenantId, "hook-log.jsonl");
12
155
  }
13
- function appendHookLog(entry) {
156
+ function appendHookLog(tenantId, entry) {
14
157
  try {
15
- const path = logPath();
158
+ const path = logPath(tenantId);
16
159
  mkdirSync(dirname(path), { recursive: true });
17
- appendFileSync(path, `${JSON.stringify(entry)}
160
+ appendFileSync(path, `${JSON.stringify({ ...entry, v: NLM_VERSION })}
18
161
  `, "utf8");
19
162
  } catch {
20
163
  }
@@ -30,18 +173,20 @@ import {
30
173
  statSync,
31
174
  writeFileSync
32
175
  } from "node:fs";
33
- import { homedir as homedir2 } from "node:os";
34
176
  import { join as join2 } from "node:path";
35
- function stateDir() {
36
- return process.env["NLM_HOOK_STATE_DIR"] ?? join2(homedir2(), ".nlm", "hook-state");
177
+ function stateDir(tenantId) {
178
+ if (tenantId === DEFAULT_TEAM_ID) {
179
+ return process.env["NLM_HOOK_STATE_DIR"] ?? tenantStatePath(tenantId, "hook-state");
180
+ }
181
+ return tenantStatePath(tenantId, "hook-state");
37
182
  }
38
- function memoPath(conversationId) {
183
+ function memoPath(tenantId, conversationId) {
39
184
  const safe = conversationId.replace(/[^A-Za-z0-9_-]/g, "_") || "unknown";
40
- return join2(stateDir(), `${safe}.json`);
185
+ return join2(stateDir(tenantId), `${safe}.json`);
41
186
  }
42
- function loadSurfaced(conversationId) {
187
+ function loadSurfaced(tenantId, conversationId) {
43
188
  try {
44
- const path = memoPath(conversationId);
189
+ const path = memoPath(tenantId, conversationId);
45
190
  if (!existsSync(path)) return /* @__PURE__ */ new Set();
46
191
  const parsed = JSON.parse(readFileSync(path, "utf8"));
47
192
  if (!Array.isArray(parsed)) return /* @__PURE__ */ new Set();
@@ -50,12 +195,12 @@ function loadSurfaced(conversationId) {
50
195
  return /* @__PURE__ */ new Set();
51
196
  }
52
197
  }
53
- function recordSurfaced(conversationId, ids) {
198
+ function recordSurfaced(tenantId, conversationId, ids) {
54
199
  try {
55
- const merged = loadSurfaced(conversationId);
200
+ const merged = loadSurfaced(tenantId, conversationId);
56
201
  for (const id of ids) merged.add(id);
57
- mkdirSync2(stateDir(), { recursive: true });
58
- writeFileSync(memoPath(conversationId), JSON.stringify([...merged]), "utf8");
202
+ mkdirSync2(stateDir(tenantId), { recursive: true });
203
+ writeFileSync(memoPath(tenantId, conversationId), JSON.stringify([...merged]), "utf8");
59
204
  } catch {
60
205
  }
61
206
  }
@@ -81,8 +226,8 @@ function truncateSummary(s, max = 200) {
81
226
  }
82
227
  return window + " ...";
83
228
  }
84
- function formatPointerBlock(hits, facts = [], exemplars = []) {
85
- if (hits.length === 0 && facts.length === 0 && exemplars.length === 0) return "";
229
+ function formatPointerBlock(hits, facts = [], exemplars = [], concepts = []) {
230
+ if (hits.length === 0 && facts.length === 0 && exemplars.length === 0 && concepts.length === 0) return "";
86
231
  const out = [];
87
232
  if (hits.length > 0) {
88
233
  out.push("## Possibly-relevant prior sessions (nlm-memory)");
@@ -111,7 +256,19 @@ function formatPointerBlock(hits, facts = [], exemplars = []) {
111
256
  out.push(`- [${e.outcome}] ${langPart}${e.repo} - ${truncateSummary(e.taskContext)}`);
112
257
  }
113
258
  }
114
- const tools = exemplars.length > 0 ? "NLM tools: recall_sessions (search), get_session (full transcript), recall_facts (prior decisions), get_fact_history (how a decision evolved), recall_code (pull the full code for a related exemplar)." : "NLM tools: recall_sessions (search), get_session (full transcript), recall_facts (prior decisions), get_fact_history (how a decision evolved).";
259
+ if (concepts.length > 0) {
260
+ if (out.length > 0) out.push("");
261
+ out.push("## Learning state (nlm-memory)");
262
+ for (const c of concepts) {
263
+ const n = c.attemptCount === 1 ? "1 attempt" : `${c.attemptCount} attempts`;
264
+ out.push(`- [${c.status}] ${c.concept} (${n})`);
265
+ }
266
+ const nextSteps = [...new Set(concepts.map((c) => c.nextStep).filter((s) => !!s))].slice(0, 2);
267
+ for (const next of nextSteps) {
268
+ out.push(`Next: ${truncateSummary(next, 120)}`);
269
+ }
270
+ }
271
+ const tools = exemplars.length > 0 ? "NLM tools: recall_sessions (search), get_session (full transcript), recall_facts (prior decisions), get_fact_history (how a decision evolved), recall_code (pull the full code for a related exemplar), learner_summary (concept mastery + next step)." : "NLM tools: recall_sessions (search), get_session (full transcript), recall_facts (prior decisions), get_fact_history (how a decision evolved), learner_summary (concept mastery + next step).";
115
272
  out.push(tools);
116
273
  return out.join("\n");
117
274
  }
@@ -123,10 +280,10 @@ function medianScore(hits) {
123
280
  return sorted[Math.floor(sorted.length / 2)] ?? 0;
124
281
  }
125
282
  function selectHits(params) {
126
- const { hits, surfaced, scoreThreshold, perFireCap, perConversationCap, relativeFloor = 0 } = params;
127
- const relCut = relativeFloor > 0 ? relativeFloor * medianScore(hits) : 0;
283
+ const { hits, surfaced, scoreThreshold: scoreThreshold2, perFireCap, perConversationCap, relativeFloor: relativeFloor2 = 0 } = params;
284
+ const relCut = relativeFloor2 > 0 ? relativeFloor2 * medianScore(hits) : 0;
128
285
  const eligible = hits.filter(
129
- (h) => h.matchScore >= scoreThreshold && h.matchScore >= relCut && !surfaced.has(h.id)
286
+ (h) => h.matchScore >= scoreThreshold2 && h.matchScore >= relCut && !surfaced.has(h.id)
130
287
  );
131
288
  const budget = Math.max(0, perConversationCap - surfaced.size);
132
289
  const limit = Math.min(perFireCap, budget);
@@ -135,7 +292,7 @@ function selectHits(params) {
135
292
 
136
293
  // src/llm/env-autoload.ts
137
294
  import { readFileSync as readFileSync2, existsSync as existsSync2 } from "node:fs";
138
- import { homedir as homedir3 } from "node:os";
295
+ import { homedir as homedir2 } from "node:os";
139
296
  import { resolve } from "node:path";
140
297
  var DEFAULT_SEARCH_PATHS = [
141
298
  "~/.nlm/.env",
@@ -144,7 +301,7 @@ var DEFAULT_SEARCH_PATHS = [
144
301
  "../../.env"
145
302
  ];
146
303
  function expandHome(p) {
147
- if (p.startsWith("~/")) return resolve(homedir3(), p.slice(2));
304
+ if (p.startsWith("~/")) return resolve(homedir2(), p.slice(2));
148
305
  return p;
149
306
  }
150
307
  function autoloadEnv(extraPaths = []) {
@@ -340,6 +497,18 @@ function extractRecallQuery(prompt) {
340
497
  }
341
498
 
342
499
  // src/hook/hook-helpers.ts
500
+ import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync3, realpathSync } from "node:fs";
501
+ import { pathToFileURL } from "node:url";
502
+ function isMainModule(metaUrl, argv1) {
503
+ if (!argv1) return false;
504
+ let resolved;
505
+ try {
506
+ resolved = realpathSync(argv1);
507
+ } catch {
508
+ return false;
509
+ }
510
+ return metaUrl === pathToFileURL(resolved).href;
511
+ }
343
512
  function readStdin() {
344
513
  return new Promise((resolve2) => {
345
514
  let data = "";
@@ -362,29 +531,46 @@ function hookModeFromEnv() {
362
531
  return process.env["NLM_HOOK_MODE"] === "live" ? "live" : "shadow";
363
532
  }
364
533
 
534
+ // src/shared/net.ts
535
+ var DEFAULT_NLM_PORT = "3940";
536
+
365
537
  // src/hook/recall-over-http.ts
366
538
  var RECALL_LIMIT = 5;
367
- var RECALL_TIMEOUT_MS = 2e3;
368
- async function recallOverHttp(prompt, runtime, conversationId, mode = "keyword") {
539
+ function parseRecallTimeout(raw) {
540
+ if (raw === void 0) return 4e3;
541
+ const n = Number(raw);
542
+ return Number.isFinite(n) && n > 0 ? n : 4e3;
543
+ }
544
+ function recallTimeoutMs() {
545
+ return parseRecallTimeout(process.env["NLM_HOOK_RECALL_TIMEOUT_MS"]);
546
+ }
547
+ var emptyResult = (outcome) => ({
548
+ hits: [],
549
+ facts: [],
550
+ exemplars: [],
551
+ concepts: [],
552
+ outcome
553
+ });
554
+ async function recallOverHttp(prompt, runtime, conversationId, mode = "keyword", source = "hook") {
369
555
  const query = extractRecallQuery(prompt);
370
- if (query === null) return { hits: [], facts: [], exemplars: [] };
371
- const portValue = process.env["NLM_PORT"] ?? "3940";
556
+ if (query === null) return emptyResult("skipped");
557
+ const portValue = process.env["NLM_PORT"] ?? DEFAULT_NLM_PORT;
372
558
  const url = (
373
559
  // 127.0.0.1, not localhost: each hook is a fresh process with no connection
374
560
  // reuse, and Node resolves localhost to IPv6 ::1 first — a measured ~50-300ms
375
561
  // per-fire connect penalty vs ~3ms on the explicit IPv4 loopback.
376
- `http://127.0.0.1:${portValue}/api/recall?q=${encodeURIComponent(query)}&mode=${mode}&limit=${RECALL_LIMIT}&withFacts=true&withExemplars=true` + (conversationId ? `&conversation_id=${encodeURIComponent(conversationId)}` : "")
562
+ `http://127.0.0.1:${portValue}/api/recall?q=${encodeURIComponent(query)}&mode=${mode}&limit=${RECALL_LIMIT}&withFacts=true&withExemplars=true&withConcepts=true` + (conversationId ? `&conversation_id=${encodeURIComponent(conversationId)}` : "")
377
563
  );
378
564
  try {
379
- const extra = { "x-recall-source": "hook" };
565
+ const extra = { "x-recall-source": source };
380
566
  if (runtime) extra["x-recall-runtime"] = runtime;
381
- const res = await fetchWithTimeout(url, { headers: hookAuthHeaders(extra) }, RECALL_TIMEOUT_MS);
382
- if (!res.ok) return { hits: [], facts: [], exemplars: [] };
567
+ const res = await fetchWithTimeout(url, { headers: hookAuthHeaders(extra) }, recallTimeoutMs());
568
+ if (!res.ok) return emptyResult("http-error");
383
569
  let body;
384
570
  try {
385
571
  body = await res.json();
386
572
  } catch {
387
- return { hits: [], facts: [], exemplars: [] };
573
+ return emptyResult("http-error");
388
574
  }
389
575
  const hits = (body.results ?? []).map((r) => ({
390
576
  id: r.id,
@@ -405,37 +591,47 @@ async function recallOverHttp(prompt, runtime, conversationId, mode = "keyword")
405
591
  repo: e.repo,
406
592
  taskContext: e.taskContext
407
593
  }));
408
- return { hits, facts, exemplars };
409
- } catch {
410
- return { hits: [], facts: [], exemplars: [] };
594
+ const concepts = (body.relatedConcepts ?? []).map((c) => ({
595
+ concept: c.concept,
596
+ status: c.status,
597
+ attemptCount: c.attemptCount,
598
+ nextStep: c.nextStep
599
+ }));
600
+ return { hits, facts, exemplars, concepts, outcome: "ok" };
601
+ } catch (err) {
602
+ const aborted = err instanceof Error && err.name === "AbortError";
603
+ return emptyResult(aborted ? "timeout" : "unreachable");
411
604
  }
412
605
  }
413
606
 
414
607
  // src/hook/session-start-hook.ts
415
- var SCORE_THRESHOLD = parseScoreFloor(process.env["NLM_RECALL_SCORE_FLOOR"]);
416
- var RELATIVE_FLOOR = parseRelativeFloor(process.env["NLM_RECALL_REL_FLOOR"], 0.9);
608
+ var scoreThreshold = () => parseScoreFloor(process.env["NLM_RECALL_SCORE_FLOOR"]);
609
+ var relativeFloor = () => parseRelativeFloor(process.env["NLM_RECALL_REL_FLOOR"], 0.9);
417
610
  var PER_FIRE_CAP = 3;
418
611
  var PER_CONVERSATION_CAP = 10;
419
- var RECALL_TIMEOUT_MS2 = 2e3;
612
+ var RECALL_TIMEOUT_MS = 2e3;
420
613
  async function runHook(input, deps) {
421
614
  let hits = [];
615
+ let recallOutcome = "unreachable";
422
616
  try {
423
- hits = await deps.recall(input.query, input.conversationId);
617
+ const fetched = await deps.recall(input.query, input.conversationId);
618
+ hits = fetched.hits;
619
+ recallOutcome = fetched.outcome;
424
620
  } catch {
425
621
  hits = [];
426
622
  }
427
- const surfaced = loadSurfaced(input.conversationId);
623
+ const surfaced = loadSurfaced(DEFAULT_TEAM_ID, input.conversationId);
428
624
  const selected = selectHits({
429
625
  hits,
430
626
  surfaced,
431
- scoreThreshold: SCORE_THRESHOLD,
432
- relativeFloor: RELATIVE_FLOOR,
627
+ scoreThreshold: scoreThreshold(),
628
+ relativeFloor: relativeFloor(),
433
629
  perFireCap: PER_FIRE_CAP,
434
630
  perConversationCap: PER_CONVERSATION_CAP
435
631
  });
436
632
  const block = formatPointerBlock(selected);
437
633
  const estTokens = Math.ceil(block.length / 4);
438
- appendHookLog({
634
+ appendHookLog(DEFAULT_TEAM_ID, {
439
635
  ts: (/* @__PURE__ */ new Date()).toISOString(),
440
636
  conversationId: input.conversationId,
441
637
  promptPreview: input.query,
@@ -443,10 +639,11 @@ async function runHook(input, deps) {
443
639
  hits: hits.map((h) => ({ id: h.id, score: h.matchScore })),
444
640
  wouldInject: selected.map((h) => h.id),
445
641
  estTokens,
446
- mode: deps.mode
642
+ mode: deps.mode,
643
+ recallOutcome
447
644
  });
448
645
  if (deps.mode === "live" && selected.length > 0) {
449
- recordSurfaced(input.conversationId, selected.map((h) => h.id));
646
+ recordSurfaced(DEFAULT_TEAM_ID, input.conversationId, selected.map((h) => h.id));
450
647
  return block;
451
648
  }
452
649
  return "";
@@ -456,12 +653,12 @@ function composeSessionStartOutput(failureModeBlock, recallBlock) {
456
653
  }
457
654
  async function fetchFailureModeBlock(repo) {
458
655
  if (!repo) return "";
459
- const portValue = process.env["NLM_PORT"] ?? "3940";
656
+ const portValue = process.env["NLM_PORT"] ?? DEFAULT_NLM_PORT;
460
657
  const url = `http://127.0.0.1:${portValue}/api/signals/failure-modes?repo=${encodeURIComponent(repo)}`;
461
658
  try {
462
659
  const res = await fetchWithTimeout(url, {
463
660
  headers: hookAuthHeaders({ "x-recall-source": "session-start-hook" })
464
- }, RECALL_TIMEOUT_MS2);
661
+ }, RECALL_TIMEOUT_MS);
465
662
  if (!res.ok) return "";
466
663
  const body = await res.json();
467
664
  return typeof body.block === "string" ? body.block : "";
@@ -469,9 +666,29 @@ async function fetchFailureModeBlock(repo) {
469
666
  return "";
470
667
  }
471
668
  }
472
- function buildQuery(workingDirectory, projectName) {
669
+ var GIT_TIMEOUT_MS = 300;
670
+ var RECENT_COMMITS = 3;
671
+ function git(cwd, args) {
672
+ try {
673
+ return execFileSync("git", ["-C", cwd, ...args], {
674
+ encoding: "utf8",
675
+ timeout: GIT_TIMEOUT_MS,
676
+ stdio: ["ignore", "pipe", "ignore"]
677
+ }).trim();
678
+ } catch {
679
+ return "";
680
+ }
681
+ }
682
+ function readGitContext(workingDirectory) {
683
+ if (!workingDirectory) return "";
684
+ const branch = git(workingDirectory, ["rev-parse", "--abbrev-ref", "HEAD"]);
685
+ const subjects = git(workingDirectory, ["log", `-${RECENT_COMMITS}`, "--format=%s"]);
686
+ const branchWords = branch === "HEAD" ? "" : branch.replace(/[/_-]+/g, " ");
687
+ return [branchWords, subjects.replace(/\n/g, " ")].filter(Boolean).join(" ");
688
+ }
689
+ function buildQuery(workingDirectory, projectName, gitContext) {
473
690
  const dirTail = workingDirectory.split("/").filter(Boolean).at(-1) ?? "";
474
- const parts = [dirTail, projectName].filter(Boolean);
691
+ const parts = [dirTail, projectName, gitContext].filter(Boolean);
475
692
  return parts.join(" ").trim() || "session start";
476
693
  }
477
694
  async function main() {
@@ -482,14 +699,23 @@ async function main() {
482
699
  const conversationId = typeof payload.session_id === "string" ? payload.session_id : "unknown";
483
700
  const workingDirectory = typeof payload.cwd === "string" ? payload.cwd : typeof payload.working_directory === "string" ? payload.working_directory : "";
484
701
  const projectName = typeof payload.project_name === "string" ? payload.project_name : "";
485
- const query = buildQuery(workingDirectory, projectName);
702
+ const query = buildQuery(workingDirectory, projectName, readGitContext(workingDirectory));
486
703
  const mode = hookModeFromEnv();
487
704
  const [out, failureModes] = await Promise.all([
488
705
  runHook(
489
706
  { conversationId, query },
490
707
  {
491
708
  mode,
492
- recall: async (q, cid) => (await recallOverHttp(q, "claude-code", cid === "unknown" ? void 0 : cid, "hybrid")).hits
709
+ recall: async (q, cid) => {
710
+ const r = await recallOverHttp(
711
+ q,
712
+ "claude-code",
713
+ cid === "unknown" ? void 0 : cid,
714
+ "hybrid",
715
+ "session-start-hook"
716
+ );
717
+ return { hits: r.hits, outcome: r.outcome };
718
+ }
493
719
  }
494
720
  ),
495
721
  mode === "live" ? fetchFailureModeBlock(workingDirectory) : Promise.resolve("")
@@ -499,10 +725,12 @@ async function main() {
499
725
  } catch {
500
726
  }
501
727
  }
502
- if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
728
+ if (isMainModule(import.meta.url, process.argv[1])) {
503
729
  void main();
504
730
  }
505
731
  export {
732
+ buildQuery,
506
733
  composeSessionStartOutput,
734
+ readGitContext,
507
735
  runHook
508
736
  };