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
package/nlm/index.js CHANGED
@@ -191,6 +191,133 @@ function extractRecallQuery(prompt) {
191
191
  }
192
192
 
193
193
  // src/hook/hook-helpers.ts
194
+ import { appendFileSync, mkdirSync, realpathSync } from "node:fs";
195
+ import { pathToFileURL } from "node:url";
196
+
197
+ // package.json
198
+ var package_default = {
199
+ name: "nlm-memory",
200
+ version: "0.21.12",
201
+ description: "Local-first non-linear memory operating system for AI operators.",
202
+ type: "module",
203
+ license: "Apache-2.0",
204
+ engines: {
205
+ node: ">=22.0.0"
206
+ },
207
+ repository: {
208
+ type: "git",
209
+ url: "git+https://github.com/pbmagnet4/nlm-memory.git"
210
+ },
211
+ homepage: "https://github.com/pbmagnet4/nlm-memory#readme",
212
+ bugs: {
213
+ url: "https://github.com/pbmagnet4/nlm-memory/issues"
214
+ },
215
+ keywords: [
216
+ "ai",
217
+ "memory",
218
+ "mcp",
219
+ "claude-code",
220
+ "codex",
221
+ "hermes",
222
+ "local-first",
223
+ "recall",
224
+ "session-memory"
225
+ ],
226
+ files: [
227
+ "dist",
228
+ "migrations",
229
+ "fixtures",
230
+ "templates",
231
+ "plugin",
232
+ "plugin-hermes-agent",
233
+ "nlm",
234
+ "assets",
235
+ "LICENSE",
236
+ "README.md"
237
+ ],
238
+ bin: {
239
+ nlm: "dist/cli/nlm.js"
240
+ },
241
+ scripts: {
242
+ dev: "tsx watch src/cli/nlm.ts start",
243
+ start: "node dist/cli/nlm.js start",
244
+ "build:server": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
245
+ "build:ui": "vite build --config src/ui/vite.config.ts",
246
+ "build:codex-plugin": "node scripts/build-codex-plugin.mjs",
247
+ "verify:codex-release": "node scripts/verify-codex-release.mjs",
248
+ build: "npm run build:server && npm run build:ui && npm run build:codex-plugin",
249
+ prepare: "[ -d src ] && npm run build || true",
250
+ "ui:dev": "vite --config src/ui/vite.config.ts",
251
+ test: "vitest run",
252
+ "test:watch": "vitest",
253
+ "test:unit": "vitest run tests/unit",
254
+ "test:integration": "vitest run tests/integration",
255
+ "test:pg": "vitest run .pg.test.ts --test-timeout=20000",
256
+ typecheck: "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json && tsc -p tsconfig.scripts.json",
257
+ "bench:longmemeval": "tsx scripts/longmemeval/run-harness.ts",
258
+ "bench:classifier": "tsx scripts/longmemeval/run-harness.ts --classifier",
259
+ "bench:compare": "tsx scripts/longmemeval/compare-classifiers.ts",
260
+ "eval:signals": "tsx scripts/eval/signals-eval.ts",
261
+ "eval:classifier": "tsx scripts/eval/classifier-eval.ts",
262
+ "eval:fact-recall": "tsx scripts/eval/fact-recall-eval.ts",
263
+ "eval:recall-impact-replay": "tsx scripts/eval/recall-impact-replay.ts",
264
+ "eval:code-exemplar": "tsx scripts/eval/code-exemplar-eval.ts",
265
+ "eval:reranker": "tsx scripts/eval/reranker-ablation.ts",
266
+ "eval:floor": "tsx scripts/eval/floor-calibration.ts",
267
+ "eval:matcher": "tsx scripts/eval/tune-matcher.ts",
268
+ "eval:naming": "tsx scripts/eval/tune-naming.ts",
269
+ "eval:rederiv-sample": "tsx scripts/eval/re-derivation-sample.ts",
270
+ "eval:rederiv-label": "tsx scripts/eval/re-derivation-label.ts",
271
+ "eval:rederiv-calibrate": "tsx scripts/eval/re-derivation-calibrate.ts"
272
+ },
273
+ dependencies: {
274
+ "@clack/prompts": "^1.4.0",
275
+ "@hono/node-server": "^2.0.3",
276
+ "@huggingface/transformers": "4.2.0",
277
+ "@modelcontextprotocol/sdk": "^1.29.0",
278
+ "@toon-format/toon": "^2.3.0",
279
+ "better-sqlite3": "^13.0.1",
280
+ commander: "^15.0.0",
281
+ hono: "^4.6.0",
282
+ pg: "^8.21.0",
283
+ pgvector: "^0.3.0",
284
+ "sqlite-vec": "^0.1.6",
285
+ yaml: "^2.9.0",
286
+ zod: "^4.4.3"
287
+ },
288
+ devDependencies: {
289
+ "@types/better-sqlite3": "^7.6.13",
290
+ "@types/node": "^22.10.0",
291
+ "@types/pg": "^8.20.0",
292
+ "@types/react": "^19.2.17",
293
+ "@types/react-dom": "^19.2.3",
294
+ "@vitejs/plugin-react": "^6.0.2",
295
+ esbuild: "^0.28.0",
296
+ react: "^19.2.7",
297
+ "react-dom": "^19.2.7",
298
+ "react-router-dom": "^6.30.3",
299
+ "tsc-alias": "^1.8.17",
300
+ tsx: "^4.19.0",
301
+ typescript: "^6.0.3",
302
+ vite: "^8.0.16",
303
+ vitest: "^4.1.8"
304
+ }
305
+ };
306
+
307
+ // src/shared/version.ts
308
+ var NLM_VERSION = package_default.version;
309
+
310
+ // src/hook/hook-helpers.ts
311
+ function isMainModule(metaUrl, argv1) {
312
+ if (!argv1) return false;
313
+ let resolved;
314
+ try {
315
+ resolved = realpathSync(argv1);
316
+ } catch {
317
+ return false;
318
+ }
319
+ return metaUrl === pathToFileURL(resolved).href;
320
+ }
194
321
  function readStdin() {
195
322
  return new Promise((resolve2) => {
196
323
  let data = "";
@@ -213,29 +340,46 @@ function hookModeFromEnv() {
213
340
  return process.env["NLM_HOOK_MODE"] === "live" ? "live" : "shadow";
214
341
  }
215
342
 
343
+ // src/shared/net.ts
344
+ var DEFAULT_NLM_PORT = "3940";
345
+
216
346
  // src/hook/recall-over-http.ts
217
347
  var RECALL_LIMIT = 5;
218
- var RECALL_TIMEOUT_MS = 2e3;
219
- async function recallOverHttp(prompt, runtime, conversationId, mode = "keyword") {
348
+ function parseRecallTimeout(raw) {
349
+ if (raw === void 0) return 4e3;
350
+ const n = Number(raw);
351
+ return Number.isFinite(n) && n > 0 ? n : 4e3;
352
+ }
353
+ function recallTimeoutMs() {
354
+ return parseRecallTimeout(process.env["NLM_HOOK_RECALL_TIMEOUT_MS"]);
355
+ }
356
+ var emptyResult = (outcome) => ({
357
+ hits: [],
358
+ facts: [],
359
+ exemplars: [],
360
+ concepts: [],
361
+ outcome
362
+ });
363
+ async function recallOverHttp(prompt, runtime, conversationId, mode = "keyword", source = "hook") {
220
364
  const query = extractRecallQuery(prompt);
221
- if (query === null) return { hits: [], facts: [], exemplars: [] };
222
- const portValue = process.env["NLM_PORT"] ?? "3940";
365
+ if (query === null) return emptyResult("skipped");
366
+ const portValue = process.env["NLM_PORT"] ?? DEFAULT_NLM_PORT;
223
367
  const url = (
224
368
  // 127.0.0.1, not localhost: each hook is a fresh process with no connection
225
369
  // reuse, and Node resolves localhost to IPv6 ::1 first — a measured ~50-300ms
226
370
  // per-fire connect penalty vs ~3ms on the explicit IPv4 loopback.
227
- `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)}` : "")
371
+ `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)}` : "")
228
372
  );
229
373
  try {
230
- const extra = { "x-recall-source": "hook" };
374
+ const extra = { "x-recall-source": source };
231
375
  if (runtime) extra["x-recall-runtime"] = runtime;
232
- const res = await fetchWithTimeout(url, { headers: hookAuthHeaders(extra) }, RECALL_TIMEOUT_MS);
233
- if (!res.ok) return { hits: [], facts: [], exemplars: [] };
376
+ const res = await fetchWithTimeout(url, { headers: hookAuthHeaders(extra) }, recallTimeoutMs());
377
+ if (!res.ok) return emptyResult("http-error");
234
378
  let body;
235
379
  try {
236
380
  body = await res.json();
237
381
  } catch {
238
- return { hits: [], facts: [], exemplars: [] };
382
+ return emptyResult("http-error");
239
383
  }
240
384
  const hits = (body.results ?? []).map((r) => ({
241
385
  id: r.id,
@@ -256,15 +400,19 @@ async function recallOverHttp(prompt, runtime, conversationId, mode = "keyword")
256
400
  repo: e.repo,
257
401
  taskContext: e.taskContext
258
402
  }));
259
- return { hits, facts, exemplars };
260
- } catch {
261
- return { hits: [], facts: [], exemplars: [] };
403
+ const concepts = (body.relatedConcepts ?? []).map((c) => ({
404
+ concept: c.concept,
405
+ status: c.status,
406
+ attemptCount: c.attemptCount,
407
+ nextStep: c.nextStep
408
+ }));
409
+ return { hits, facts, exemplars, concepts, outcome: "ok" };
410
+ } catch (err) {
411
+ const aborted = err instanceof Error && err.name === "AbortError";
412
+ return emptyResult(aborted ? "timeout" : "unreachable");
262
413
  }
263
414
  }
264
415
 
265
- // src/hook/prompt-recall-hook.ts
266
- import { pathToFileURL } from "node:url";
267
-
268
416
  // src/core/hook/gate.ts
269
417
  var LEADING_FILLER = /^(please|can you|could you|would you|will you|i need you to|i'd like you to|i want you to|i would like you to|help me|let's|lets|hey|ok|okay)\b[\s,]*/i;
270
418
  var GENERATIVE_OPENER = /^(write|draft|create|compose|generate|brainstorm|design|outline|sketch|invent|rename|come up with)\b/i;
@@ -455,17 +603,47 @@ function recentConversationContext(transcriptPath, opts = {}) {
455
603
  }
456
604
 
457
605
  // src/core/hook/hook-log.ts
458
- import { appendFileSync, mkdirSync } from "node:fs";
606
+ import { appendFileSync as appendFileSync2, mkdirSync as mkdirSync2 } from "node:fs";
607
+ import { dirname } from "node:path";
608
+
609
+ // src/core/tenancy/tenant-state-path.ts
610
+ import { createHash } from "node:crypto";
459
611
  import { homedir as homedir2 } from "node:os";
460
- import { dirname, join } from "node:path";
461
- function logPath() {
462
- return process.env["NLM_HOOK_LOG"] ?? join(homedir2(), ".nlm", "hook-log.jsonl");
612
+ import { join } from "node:path";
613
+
614
+ // src/core/tenancy/default-team.ts
615
+ var DEFAULT_TEAM_ID = "team_local";
616
+
617
+ // src/core/tenancy/tenant-state-path.ts
618
+ var TENANTS_DIRNAME = "tenants";
619
+ var SAFE_TENANT_ID = /^[A-Za-z0-9_-]+$/;
620
+ function sanitizeTenantId(tenantId) {
621
+ if (SAFE_TENANT_ID.test(tenantId)) return tenantId;
622
+ const sanitized = tenantId.replace(/[^A-Za-z0-9_-]/g, "_") || "unknown";
623
+ const hash = createHash("sha256").update(tenantId).digest("hex").slice(0, 8);
624
+ return `${sanitized}_${hash}`;
463
625
  }
464
- function appendHookLog(entry) {
626
+ function stateRoot() {
627
+ return process.env["NLM_STATE_ROOT"] || join(homedir2(), ".nlm");
628
+ }
629
+ function tenantStatePath(tenantId, ...segments) {
630
+ const base = stateRoot();
631
+ if (tenantId === DEFAULT_TEAM_ID) return join(base, ...segments);
632
+ return join(base, TENANTS_DIRNAME, sanitizeTenantId(tenantId), ...segments);
633
+ }
634
+
635
+ // src/core/hook/hook-log.ts
636
+ function logPath(tenantId) {
637
+ if (tenantId === DEFAULT_TEAM_ID) {
638
+ return process.env["NLM_HOOK_LOG"] ?? tenantStatePath(tenantId, "hook-log.jsonl");
639
+ }
640
+ return tenantStatePath(tenantId, "hook-log.jsonl");
641
+ }
642
+ function appendHookLog(tenantId, entry) {
465
643
  try {
466
- const path = logPath();
467
- mkdirSync(dirname(path), { recursive: true });
468
- appendFileSync(path, `${JSON.stringify(entry)}
644
+ const path = logPath(tenantId);
645
+ mkdirSync2(dirname(path), { recursive: true });
646
+ appendFileSync2(path, `${JSON.stringify({ ...entry, v: NLM_VERSION })}
469
647
  `, "utf8");
470
648
  } catch {
471
649
  }
@@ -474,25 +652,27 @@ function appendHookLog(entry) {
474
652
  // src/core/hook/memo.ts
475
653
  import {
476
654
  existsSync as existsSync3,
477
- mkdirSync as mkdirSync2,
655
+ mkdirSync as mkdirSync3,
478
656
  readdirSync,
479
657
  readFileSync as readFileSync2,
480
658
  rmSync,
481
659
  statSync,
482
660
  writeFileSync
483
661
  } from "node:fs";
484
- import { homedir as homedir3 } from "node:os";
485
662
  import { join as join2 } from "node:path";
486
- function stateDir() {
487
- return process.env["NLM_HOOK_STATE_DIR"] ?? join2(homedir3(), ".nlm", "hook-state");
663
+ function stateDir(tenantId) {
664
+ if (tenantId === DEFAULT_TEAM_ID) {
665
+ return process.env["NLM_HOOK_STATE_DIR"] ?? tenantStatePath(tenantId, "hook-state");
666
+ }
667
+ return tenantStatePath(tenantId, "hook-state");
488
668
  }
489
- function memoPath(conversationId) {
669
+ function memoPath(tenantId, conversationId) {
490
670
  const safe = conversationId.replace(/[^A-Za-z0-9_-]/g, "_") || "unknown";
491
- return join2(stateDir(), `${safe}.json`);
671
+ return join2(stateDir(tenantId), `${safe}.json`);
492
672
  }
493
- function loadSurfaced(conversationId) {
673
+ function loadSurfaced(tenantId, conversationId) {
494
674
  try {
495
- const path = memoPath(conversationId);
675
+ const path = memoPath(tenantId, conversationId);
496
676
  if (!existsSync3(path)) return /* @__PURE__ */ new Set();
497
677
  const parsed = JSON.parse(readFileSync2(path, "utf8"));
498
678
  if (!Array.isArray(parsed)) return /* @__PURE__ */ new Set();
@@ -501,12 +681,12 @@ function loadSurfaced(conversationId) {
501
681
  return /* @__PURE__ */ new Set();
502
682
  }
503
683
  }
504
- function recordSurfaced(conversationId, ids) {
684
+ function recordSurfaced(tenantId, conversationId, ids) {
505
685
  try {
506
- const merged = loadSurfaced(conversationId);
686
+ const merged = loadSurfaced(tenantId, conversationId);
507
687
  for (const id of ids) merged.add(id);
508
- mkdirSync2(stateDir(), { recursive: true });
509
- writeFileSync(memoPath(conversationId), JSON.stringify([...merged]), "utf8");
688
+ mkdirSync3(stateDir(tenantId), { recursive: true });
689
+ writeFileSync(memoPath(tenantId, conversationId), JSON.stringify([...merged]), "utf8");
510
690
  } catch {
511
691
  }
512
692
  }
@@ -532,8 +712,8 @@ function truncateSummary(s, max = 200) {
532
712
  }
533
713
  return window + " ...";
534
714
  }
535
- function formatPointerBlock(hits, facts = [], exemplars = []) {
536
- if (hits.length === 0 && facts.length === 0 && exemplars.length === 0) return "";
715
+ function formatPointerBlock(hits, facts = [], exemplars = [], concepts = []) {
716
+ if (hits.length === 0 && facts.length === 0 && exemplars.length === 0 && concepts.length === 0) return "";
537
717
  const out = [];
538
718
  if (hits.length > 0) {
539
719
  out.push("## Possibly-relevant prior sessions (nlm-memory)");
@@ -562,7 +742,19 @@ function formatPointerBlock(hits, facts = [], exemplars = []) {
562
742
  out.push(`- [${e.outcome}] ${langPart}${e.repo} - ${truncateSummary(e.taskContext)}`);
563
743
  }
564
744
  }
565
- 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).";
745
+ if (concepts.length > 0) {
746
+ if (out.length > 0) out.push("");
747
+ out.push("## Learning state (nlm-memory)");
748
+ for (const c of concepts) {
749
+ const n = c.attemptCount === 1 ? "1 attempt" : `${c.attemptCount} attempts`;
750
+ out.push(`- [${c.status}] ${c.concept} (${n})`);
751
+ }
752
+ const nextSteps = [...new Set(concepts.map((c) => c.nextStep).filter((s) => !!s))].slice(0, 2);
753
+ for (const next of nextSteps) {
754
+ out.push(`Next: ${truncateSummary(next, 120)}`);
755
+ }
756
+ }
757
+ 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).";
566
758
  out.push(tools);
567
759
  return out.join("\n");
568
760
  }
@@ -574,10 +766,10 @@ function medianScore(hits) {
574
766
  return sorted[Math.floor(sorted.length / 2)] ?? 0;
575
767
  }
576
768
  function selectHits(params) {
577
- const { hits, surfaced, scoreThreshold, perFireCap, perConversationCap, relativeFloor = 0 } = params;
578
- const relCut = relativeFloor > 0 ? relativeFloor * medianScore(hits) : 0;
769
+ const { hits, surfaced, scoreThreshold: scoreThreshold2, perFireCap, perConversationCap, relativeFloor: relativeFloor2 = 0 } = params;
770
+ const relCut = relativeFloor2 > 0 ? relativeFloor2 * medianScore(hits) : 0;
579
771
  const eligible = hits.filter(
580
- (h) => h.matchScore >= scoreThreshold && h.matchScore >= relCut && !surfaced.has(h.id)
772
+ (h) => h.matchScore >= scoreThreshold2 && h.matchScore >= relCut && !surfaced.has(h.id)
581
773
  );
582
774
  const budget = Math.max(0, perConversationCap - surfaced.size);
583
775
  const limit = Math.min(perFireCap, budget);
@@ -647,17 +839,19 @@ ${candidate}` }
647
839
  }
648
840
 
649
841
  // src/hook/prompt-recall-hook.ts
650
- var SCORE_THRESHOLD = parseScoreFloor(process.env["NLM_RECALL_SCORE_FLOOR"]);
651
- var RELATIVE_FLOOR = parseRelativeFloor(process.env["NLM_RECALL_REL_FLOOR"], 0.9);
842
+ var scoreThreshold = () => parseScoreFloor(process.env["NLM_RECALL_SCORE_FLOOR"]);
843
+ var relativeFloor = () => parseRelativeFloor(process.env["NLM_RECALL_REL_FLOOR"], 0.9);
652
844
  var PER_FIRE_CAP = 3;
653
845
  var PER_CONVERSATION_CAP = 10;
654
846
  var PROMPT_PREVIEW_CHARS = 200;
655
- function parseHookDeadline(raw) {
656
- if (raw === void 0) return 4e3;
847
+ function parseHookDeadline(raw, defaultMs = 4e3) {
848
+ if (raw === void 0) return defaultMs;
657
849
  const n = Number(raw);
658
- return Number.isFinite(n) && n > 0 ? n : 4e3;
850
+ return Number.isFinite(n) && n > 0 ? n : defaultMs;
851
+ }
852
+ function hookDeadlineMs() {
853
+ return parseHookDeadline(process.env["NLM_HOOK_DEADLINE_MS"], 6e3);
659
854
  }
660
- var HOOK_DEADLINE_MS = parseHookDeadline(process.env["NLM_HOOK_DEADLINE_MS"]);
661
855
  async function withDeadline(p, ms, fallback) {
662
856
  if (ms <= 0) return fallback;
663
857
  let timer;
@@ -695,7 +889,7 @@ async function runHook(input, deps) {
695
889
  const gate = classifyPrompt(input.prompt);
696
890
  const preview = input.prompt.slice(0, PROMPT_PREVIEW_CHARS);
697
891
  if (gate === "generative" || gate === "skip") {
698
- appendHookLog({
892
+ appendHookLog(DEFAULT_TEAM_ID, {
699
893
  ts: (/* @__PURE__ */ new Date()).toISOString(),
700
894
  conversationId: input.conversationId,
701
895
  promptPreview: preview,
@@ -707,22 +901,26 @@ async function runHook(input, deps) {
707
901
  });
708
902
  return "";
709
903
  }
710
- const deadline = Date.now() + (deps.deadlineMs ?? HOOK_DEADLINE_MS);
711
- let fetched = { hits: [], facts: [] };
904
+ const deadline = Date.now() + (deps.deadlineMs ?? hookDeadlineMs());
905
+ let fetched = { hits: [], facts: [], outcome: "timeout" };
712
906
  try {
713
907
  fetched = normalizeRecall(
714
- await withDeadline(deps.recall(buildRecallQuery(input)), deadline - Date.now(), { hits: [], facts: [] })
908
+ await withDeadline(
909
+ deps.recall(buildRecallQuery(input)),
910
+ deadline - Date.now(),
911
+ { hits: [], facts: [], outcome: "timeout" }
912
+ )
715
913
  );
716
914
  } catch {
717
- fetched = { hits: [], facts: [] };
915
+ fetched = { hits: [], facts: [], outcome: "unreachable" };
718
916
  }
719
917
  const hits = fetched.hits;
720
- const surfaced = loadSurfaced(input.conversationId);
918
+ const surfaced = loadSurfaced(DEFAULT_TEAM_ID, input.conversationId);
721
919
  const selected = selectHits({
722
920
  hits,
723
921
  surfaced,
724
- scoreThreshold: SCORE_THRESHOLD,
725
- relativeFloor: RELATIVE_FLOOR,
922
+ scoreThreshold: scoreThreshold(),
923
+ relativeFloor: relativeFloor(),
726
924
  perFireCap: PER_FIRE_CAP,
727
925
  perConversationCap: PER_CONVERSATION_CAP
728
926
  });
@@ -748,9 +946,9 @@ ${h.summary ?? ""}`) }))),
748
946
  injected = selected.filter((h) => !drop.has(h.id));
749
947
  }
750
948
  }
751
- const block = formatPointerBlock(injected, fetched.facts, fetched.exemplars);
949
+ const block = formatPointerBlock(injected, fetched.facts, fetched.exemplars, fetched.concepts ?? []);
752
950
  const estTokens = Math.ceil(block.length / 4);
753
- appendHookLog({
951
+ appendHookLog(DEFAULT_TEAM_ID, {
754
952
  ts: (/* @__PURE__ */ new Date()).toISOString(),
755
953
  conversationId: input.conversationId,
756
954
  promptPreview: preview,
@@ -759,10 +957,11 @@ ${h.summary ?? ""}`) }))),
759
957
  wouldInject: injected.map((h) => h.id),
760
958
  estTokens,
761
959
  mode: deps.mode,
960
+ ...fetched.outcome ? { recallOutcome: fetched.outcome } : {},
762
961
  ...gateDecisions ? { gateDecisions } : {}
763
962
  });
764
963
  if (deps.mode === "live" && injected.length > 0) {
765
- recordSurfaced(input.conversationId, injected.map((h) => h.id));
964
+ recordSurfaced(DEFAULT_TEAM_ID, input.conversationId, injected.map((h) => h.id));
766
965
  return block;
767
966
  }
768
967
  return "";
@@ -794,7 +993,7 @@ async function main() {
794
993
  } catch {
795
994
  }
796
995
  }
797
- if (process.argv[1] && import.meta.url === pathToFileURL(process.argv[1]).href) {
996
+ if (isMainModule(import.meta.url, process.argv[1])) {
798
997
  void main();
799
998
  }
800
999
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nlm-memory",
3
- "version": "0.20.1",
3
+ "version": "0.21.12",
4
4
  "description": "Local-first non-linear memory operating system for AI operators.",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -47,6 +47,7 @@
47
47
  "build:server": "tsc -p tsconfig.json && tsc-alias -p tsconfig.json",
48
48
  "build:ui": "vite build --config src/ui/vite.config.ts",
49
49
  "build:codex-plugin": "node scripts/build-codex-plugin.mjs",
50
+ "verify:codex-release": "node scripts/verify-codex-release.mjs",
50
51
  "build": "npm run build:server && npm run build:ui && npm run build:codex-plugin",
51
52
  "prepare": "[ -d src ] && npm run build || true",
52
53
  "ui:dev": "vite --config src/ui/vite.config.ts",
@@ -54,19 +55,23 @@
54
55
  "test:watch": "vitest",
55
56
  "test:unit": "vitest run tests/unit",
56
57
  "test:integration": "vitest run tests/integration",
57
- "test:pg": "vitest run --no-file-parallelism .pg.test.ts",
58
- "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json",
58
+ "test:pg": "vitest run .pg.test.ts --test-timeout=20000",
59
+ "typecheck": "tsc -p tsconfig.json --noEmit && tsc -p tsconfig.test.json && tsc -p tsconfig.scripts.json",
59
60
  "bench:longmemeval": "tsx scripts/longmemeval/run-harness.ts",
60
61
  "bench:classifier": "tsx scripts/longmemeval/run-harness.ts --classifier",
61
62
  "bench:compare": "tsx scripts/longmemeval/compare-classifiers.ts",
62
63
  "eval:signals": "tsx scripts/eval/signals-eval.ts",
63
64
  "eval:classifier": "tsx scripts/eval/classifier-eval.ts",
64
65
  "eval:fact-recall": "tsx scripts/eval/fact-recall-eval.ts",
66
+ "eval:recall-impact-replay": "tsx scripts/eval/recall-impact-replay.ts",
65
67
  "eval:code-exemplar": "tsx scripts/eval/code-exemplar-eval.ts",
66
68
  "eval:reranker": "tsx scripts/eval/reranker-ablation.ts",
67
69
  "eval:floor": "tsx scripts/eval/floor-calibration.ts",
68
70
  "eval:matcher": "tsx scripts/eval/tune-matcher.ts",
69
- "eval:naming": "tsx scripts/eval/tune-naming.ts"
71
+ "eval:naming": "tsx scripts/eval/tune-naming.ts",
72
+ "eval:rederiv-sample": "tsx scripts/eval/re-derivation-sample.ts",
73
+ "eval:rederiv-label": "tsx scripts/eval/re-derivation-label.ts",
74
+ "eval:rederiv-calibrate": "tsx scripts/eval/re-derivation-calibrate.ts"
70
75
  },
71
76
  "dependencies": {
72
77
  "@clack/prompts": "^1.4.0",
@@ -74,7 +79,7 @@
74
79
  "@huggingface/transformers": "4.2.0",
75
80
  "@modelcontextprotocol/sdk": "^1.29.0",
76
81
  "@toon-format/toon": "^2.3.0",
77
- "better-sqlite3": "^12.10.0",
82
+ "better-sqlite3": "^13.0.1",
78
83
  "commander": "^15.0.0",
79
84
  "hono": "^4.6.0",
80
85
  "pg": "^8.21.0",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "nlm-memory",
3
- "version": "0.20.1",
3
+ "version": "0.21.12",
4
4
  "description": "Local-first persistent memory for AI coding agents. Recalls relevant prior sessions on every prompt; learns which sessions actually get cited. Owner-edited timeline beats append-only memory layers.",
5
5
  "author": {
6
6
  "name": "Edward Chalupa",