nodedex 0.1.0

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 (469) hide show
  1. package/adapters/claude-code-watcher.mjs +336 -0
  2. package/adapters/hermes-statedb-watcher.mjs +234 -0
  3. package/adapters/nodedex-capture-core.mjs +129 -0
  4. package/adapters/nodedex-capture.mjs +169 -0
  5. package/dist/agent-protocol.d.ts +7 -0
  6. package/dist/agent-protocol.d.ts.map +1 -0
  7. package/dist/agent-protocol.js +38 -0
  8. package/dist/agent-protocol.js.map +1 -0
  9. package/dist/api-server.d.ts +5 -0
  10. package/dist/api-server.d.ts.map +1 -0
  11. package/dist/api-server.js +351 -0
  12. package/dist/api-server.js.map +1 -0
  13. package/dist/boot-env.d.ts +2 -0
  14. package/dist/boot-env.d.ts.map +1 -0
  15. package/dist/boot-env.js +12 -0
  16. package/dist/boot-env.js.map +1 -0
  17. package/dist/engine/__tests__/search-core.test.d.ts +2 -0
  18. package/dist/engine/__tests__/search-core.test.d.ts.map +1 -0
  19. package/dist/engine/__tests__/search-core.test.js +139 -0
  20. package/dist/engine/__tests__/search-core.test.js.map +1 -0
  21. package/dist/engine/ai-provider.d.ts +45 -0
  22. package/dist/engine/ai-provider.d.ts.map +1 -0
  23. package/dist/engine/ai-provider.js +5 -0
  24. package/dist/engine/ai-provider.js.map +1 -0
  25. package/dist/engine/embeddings.d.ts +51 -0
  26. package/dist/engine/embeddings.d.ts.map +1 -0
  27. package/dist/engine/embeddings.js +89 -0
  28. package/dist/engine/embeddings.js.map +1 -0
  29. package/dist/engine/providers/__tests__/failure-policy.test.d.ts +2 -0
  30. package/dist/engine/providers/__tests__/failure-policy.test.d.ts.map +1 -0
  31. package/dist/engine/providers/__tests__/failure-policy.test.js +134 -0
  32. package/dist/engine/providers/__tests__/failure-policy.test.js.map +1 -0
  33. package/dist/engine/providers/__tests__/model-caps.test.d.ts +2 -0
  34. package/dist/engine/providers/__tests__/model-caps.test.d.ts.map +1 -0
  35. package/dist/engine/providers/__tests__/model-caps.test.js +38 -0
  36. package/dist/engine/providers/__tests__/model-caps.test.js.map +1 -0
  37. package/dist/engine/providers/__tests__/openai-structured.test.d.ts +2 -0
  38. package/dist/engine/providers/__tests__/openai-structured.test.d.ts.map +1 -0
  39. package/dist/engine/providers/__tests__/openai-structured.test.js +73 -0
  40. package/dist/engine/providers/__tests__/openai-structured.test.js.map +1 -0
  41. package/dist/engine/providers/__tests__/usage-ledger.test.d.ts +2 -0
  42. package/dist/engine/providers/__tests__/usage-ledger.test.d.ts.map +1 -0
  43. package/dist/engine/providers/__tests__/usage-ledger.test.js +108 -0
  44. package/dist/engine/providers/__tests__/usage-ledger.test.js.map +1 -0
  45. package/dist/engine/providers/anthropic.d.ts +17 -0
  46. package/dist/engine/providers/anthropic.d.ts.map +1 -0
  47. package/dist/engine/providers/anthropic.js +125 -0
  48. package/dist/engine/providers/anthropic.js.map +1 -0
  49. package/dist/engine/providers/failure-policy.d.ts +56 -0
  50. package/dist/engine/providers/failure-policy.d.ts.map +1 -0
  51. package/dist/engine/providers/failure-policy.js +120 -0
  52. package/dist/engine/providers/failure-policy.js.map +1 -0
  53. package/dist/engine/providers/gemini.d.ts +22 -0
  54. package/dist/engine/providers/gemini.d.ts.map +1 -0
  55. package/dist/engine/providers/gemini.js +180 -0
  56. package/dist/engine/providers/gemini.js.map +1 -0
  57. package/dist/engine/providers/index.d.ts +8 -0
  58. package/dist/engine/providers/index.d.ts.map +1 -0
  59. package/dist/engine/providers/index.js +67 -0
  60. package/dist/engine/providers/index.js.map +1 -0
  61. package/dist/engine/providers/local.d.ts +12 -0
  62. package/dist/engine/providers/local.d.ts.map +1 -0
  63. package/dist/engine/providers/local.js +46 -0
  64. package/dist/engine/providers/local.js.map +1 -0
  65. package/dist/engine/providers/model-caps.d.ts +6 -0
  66. package/dist/engine/providers/model-caps.d.ts.map +1 -0
  67. package/dist/engine/providers/model-caps.js +49 -0
  68. package/dist/engine/providers/model-caps.js.map +1 -0
  69. package/dist/engine/providers/openai.d.ts +30 -0
  70. package/dist/engine/providers/openai.d.ts.map +1 -0
  71. package/dist/engine/providers/openai.js +309 -0
  72. package/dist/engine/providers/openai.js.map +1 -0
  73. package/dist/engine/providers/usage-ledger.d.ts +69 -0
  74. package/dist/engine/providers/usage-ledger.d.ts.map +1 -0
  75. package/dist/engine/providers/usage-ledger.js +209 -0
  76. package/dist/engine/providers/usage-ledger.js.map +1 -0
  77. package/dist/engine/search-core.d.ts +40 -0
  78. package/dist/engine/search-core.d.ts.map +1 -0
  79. package/dist/engine/search-core.js +109 -0
  80. package/dist/engine/search-core.js.map +1 -0
  81. package/dist/engine/vector-math.d.ts +5 -0
  82. package/dist/engine/vector-math.d.ts.map +1 -0
  83. package/dist/engine/vector-math.js +25 -0
  84. package/dist/engine/vector-math.js.map +1 -0
  85. package/dist/home-env.d.ts +26 -0
  86. package/dist/home-env.d.ts.map +1 -0
  87. package/dist/home-env.js +87 -0
  88. package/dist/home-env.js.map +1 -0
  89. package/dist/mcp-server.d.ts +13 -0
  90. package/dist/mcp-server.d.ts.map +1 -0
  91. package/dist/mcp-server.js +79 -0
  92. package/dist/mcp-server.js.map +1 -0
  93. package/dist/middleware/auth.d.ts +23 -0
  94. package/dist/middleware/auth.d.ts.map +1 -0
  95. package/dist/middleware/auth.js +104 -0
  96. package/dist/middleware/auth.js.map +1 -0
  97. package/dist/middleware/auto-recall.d.ts +7 -0
  98. package/dist/middleware/auto-recall.d.ts.map +1 -0
  99. package/dist/middleware/auto-recall.js +257 -0
  100. package/dist/middleware/auto-recall.js.map +1 -0
  101. package/dist/middleware/auto-reflect.d.ts +4 -0
  102. package/dist/middleware/auto-reflect.d.ts.map +1 -0
  103. package/dist/middleware/auto-reflect.js +5 -0
  104. package/dist/middleware/auto-reflect.js.map +1 -0
  105. package/dist/middleware/reflect/apply-flag-verdict.d.ts +27 -0
  106. package/dist/middleware/reflect/apply-flag-verdict.d.ts.map +1 -0
  107. package/dist/middleware/reflect/apply-flag-verdict.js +57 -0
  108. package/dist/middleware/reflect/apply-flag-verdict.js.map +1 -0
  109. package/dist/middleware/reflect/arc-entity-resolve.d.ts +29 -0
  110. package/dist/middleware/reflect/arc-entity-resolve.d.ts.map +1 -0
  111. package/dist/middleware/reflect/arc-entity-resolve.js +356 -0
  112. package/dist/middleware/reflect/arc-entity-resolve.js.map +1 -0
  113. package/dist/middleware/reflect/arc-inactivity-timer.d.ts +47 -0
  114. package/dist/middleware/reflect/arc-inactivity-timer.d.ts.map +1 -0
  115. package/dist/middleware/reflect/arc-inactivity-timer.js +175 -0
  116. package/dist/middleware/reflect/arc-inactivity-timer.js.map +1 -0
  117. package/dist/middleware/reflect/arc-pipeline.d.ts +33 -0
  118. package/dist/middleware/reflect/arc-pipeline.d.ts.map +1 -0
  119. package/dist/middleware/reflect/arc-pipeline.js +498 -0
  120. package/dist/middleware/reflect/arc-pipeline.js.map +1 -0
  121. package/dist/middleware/reflect/comprehend-pergroup.d.ts +100 -0
  122. package/dist/middleware/reflect/comprehend-pergroup.d.ts.map +1 -0
  123. package/dist/middleware/reflect/comprehend-pergroup.js +610 -0
  124. package/dist/middleware/reflect/comprehend-pergroup.js.map +1 -0
  125. package/dist/middleware/reflect/comprehend.d.ts +237 -0
  126. package/dist/middleware/reflect/comprehend.d.ts.map +1 -0
  127. package/dist/middleware/reflect/comprehend.js +706 -0
  128. package/dist/middleware/reflect/comprehend.js.map +1 -0
  129. package/dist/middleware/reflect/config.d.ts +34 -0
  130. package/dist/middleware/reflect/config.d.ts.map +1 -0
  131. package/dist/middleware/reflect/config.js +131 -0
  132. package/dist/middleware/reflect/config.js.map +1 -0
  133. package/dist/middleware/reflect/context.d.ts +138 -0
  134. package/dist/middleware/reflect/context.d.ts.map +1 -0
  135. package/dist/middleware/reflect/context.js +619 -0
  136. package/dist/middleware/reflect/context.js.map +1 -0
  137. package/dist/middleware/reflect/cost-breakdown.d.ts +69 -0
  138. package/dist/middleware/reflect/cost-breakdown.d.ts.map +1 -0
  139. package/dist/middleware/reflect/cost-breakdown.js +63 -0
  140. package/dist/middleware/reflect/cost-breakdown.js.map +1 -0
  141. package/dist/middleware/reflect/cost-guard.d.ts +102 -0
  142. package/dist/middleware/reflect/cost-guard.d.ts.map +1 -0
  143. package/dist/middleware/reflect/cost-guard.js +243 -0
  144. package/dist/middleware/reflect/cost-guard.js.map +1 -0
  145. package/dist/middleware/reflect/cost-pricing.d.ts +54 -0
  146. package/dist/middleware/reflect/cost-pricing.d.ts.map +1 -0
  147. package/dist/middleware/reflect/cost-pricing.js +148 -0
  148. package/dist/middleware/reflect/cost-pricing.js.map +1 -0
  149. package/dist/middleware/reflect/cross-group-link.d.ts +61 -0
  150. package/dist/middleware/reflect/cross-group-link.d.ts.map +1 -0
  151. package/dist/middleware/reflect/cross-group-link.js +212 -0
  152. package/dist/middleware/reflect/cross-group-link.js.map +1 -0
  153. package/dist/middleware/reflect/dedup-by-source-and-value.d.ts +70 -0
  154. package/dist/middleware/reflect/dedup-by-source-and-value.d.ts.map +1 -0
  155. package/dist/middleware/reflect/dedup-by-source-and-value.js +0 -0
  156. package/dist/middleware/reflect/dedup-by-source-and-value.js.map +1 -0
  157. package/dist/middleware/reflect/describe-roots.d.ts +58 -0
  158. package/dist/middleware/reflect/describe-roots.d.ts.map +1 -0
  159. package/dist/middleware/reflect/describe-roots.js +266 -0
  160. package/dist/middleware/reflect/describe-roots.js.map +1 -0
  161. package/dist/middleware/reflect/flag-reviewer-startup.d.ts +16 -0
  162. package/dist/middleware/reflect/flag-reviewer-startup.d.ts.map +1 -0
  163. package/dist/middleware/reflect/flag-reviewer-startup.js +107 -0
  164. package/dist/middleware/reflect/flag-reviewer-startup.js.map +1 -0
  165. package/dist/middleware/reflect/flag-reviewer.d.ts +69 -0
  166. package/dist/middleware/reflect/flag-reviewer.d.ts.map +1 -0
  167. package/dist/middleware/reflect/flag-reviewer.js +520 -0
  168. package/dist/middleware/reflect/flag-reviewer.js.map +1 -0
  169. package/dist/middleware/reflect/inline-dedup.d.ts +26 -0
  170. package/dist/middleware/reflect/inline-dedup.d.ts.map +1 -0
  171. package/dist/middleware/reflect/inline-dedup.js +131 -0
  172. package/dist/middleware/reflect/inline-dedup.js.map +1 -0
  173. package/dist/middleware/reflect/justify-decisions.d.ts +37 -0
  174. package/dist/middleware/reflect/justify-decisions.d.ts.map +1 -0
  175. package/dist/middleware/reflect/justify-decisions.js +159 -0
  176. package/dist/middleware/reflect/justify-decisions.js.map +1 -0
  177. package/dist/middleware/reflect/nl-accept.d.ts +35 -0
  178. package/dist/middleware/reflect/nl-accept.d.ts.map +1 -0
  179. package/dist/middleware/reflect/nl-accept.js +167 -0
  180. package/dist/middleware/reflect/nl-accept.js.map +1 -0
  181. package/dist/middleware/reflect/pass0.d.ts +20 -0
  182. package/dist/middleware/reflect/pass0.d.ts.map +1 -0
  183. package/dist/middleware/reflect/pass0.js +423 -0
  184. package/dist/middleware/reflect/pass0.js.map +1 -0
  185. package/dist/middleware/reflect/pass1.d.ts +17 -0
  186. package/dist/middleware/reflect/pass1.d.ts.map +1 -0
  187. package/dist/middleware/reflect/pass1.js +241 -0
  188. package/dist/middleware/reflect/pass1.js.map +1 -0
  189. package/dist/middleware/reflect/pass2-quarantine.d.ts +129 -0
  190. package/dist/middleware/reflect/pass2-quarantine.d.ts.map +1 -0
  191. package/dist/middleware/reflect/pass2-quarantine.js +272 -0
  192. package/dist/middleware/reflect/pass2-quarantine.js.map +1 -0
  193. package/dist/middleware/reflect/pass2-seams.d.ts +205 -0
  194. package/dist/middleware/reflect/pass2-seams.d.ts.map +1 -0
  195. package/dist/middleware/reflect/pass2-seams.js +279 -0
  196. package/dist/middleware/reflect/pass2-seams.js.map +1 -0
  197. package/dist/middleware/reflect/pass2-split-orchestrator.d.ts +37 -0
  198. package/dist/middleware/reflect/pass2-split-orchestrator.d.ts.map +1 -0
  199. package/dist/middleware/reflect/pass2-split-orchestrator.js +531 -0
  200. package/dist/middleware/reflect/pass2-split-orchestrator.js.map +1 -0
  201. package/dist/middleware/reflect/pass2.d.ts +17 -0
  202. package/dist/middleware/reflect/pass2.d.ts.map +1 -0
  203. package/dist/middleware/reflect/pass2.js +324 -0
  204. package/dist/middleware/reflect/pass2.js.map +1 -0
  205. package/dist/middleware/reflect/pass2a.d.ts +141 -0
  206. package/dist/middleware/reflect/pass2a.d.ts.map +1 -0
  207. package/dist/middleware/reflect/pass2a.js +404 -0
  208. package/dist/middleware/reflect/pass2a.js.map +1 -0
  209. package/dist/middleware/reflect/pass2b.d.ts +108 -0
  210. package/dist/middleware/reflect/pass2b.d.ts.map +1 -0
  211. package/dist/middleware/reflect/pass2b.js +480 -0
  212. package/dist/middleware/reflect/pass2b.js.map +1 -0
  213. package/dist/middleware/reflect/pass2c.d.ts +113 -0
  214. package/dist/middleware/reflect/pass2c.d.ts.map +1 -0
  215. package/dist/middleware/reflect/pass2c.js +360 -0
  216. package/dist/middleware/reflect/pass2c.js.map +1 -0
  217. package/dist/middleware/reflect/pass3-batch.d.ts +62 -0
  218. package/dist/middleware/reflect/pass3-batch.d.ts.map +1 -0
  219. package/dist/middleware/reflect/pass3-batch.js +139 -0
  220. package/dist/middleware/reflect/pass3-batch.js.map +1 -0
  221. package/dist/middleware/reflect/pass3.d.ts +23 -0
  222. package/dist/middleware/reflect/pass3.d.ts.map +1 -0
  223. package/dist/middleware/reflect/pass3.js +371 -0
  224. package/dist/middleware/reflect/pass3.js.map +1 -0
  225. package/dist/middleware/reflect/pass4-slice.d.ts +25 -0
  226. package/dist/middleware/reflect/pass4-slice.d.ts.map +1 -0
  227. package/dist/middleware/reflect/pass4-slice.js +315 -0
  228. package/dist/middleware/reflect/pass4-slice.js.map +1 -0
  229. package/dist/middleware/reflect/pass4.d.ts +30 -0
  230. package/dist/middleware/reflect/pass4.d.ts.map +1 -0
  231. package/dist/middleware/reflect/pass4.js +193 -0
  232. package/dist/middleware/reflect/pass4.js.map +1 -0
  233. package/dist/middleware/reflect/pass5.d.ts +22 -0
  234. package/dist/middleware/reflect/pass5.d.ts.map +1 -0
  235. package/dist/middleware/reflect/pass5.js +178 -0
  236. package/dist/middleware/reflect/pass5.js.map +1 -0
  237. package/dist/middleware/reflect/pass_judge.d.ts +44 -0
  238. package/dist/middleware/reflect/pass_judge.d.ts.map +1 -0
  239. package/dist/middleware/reflect/pass_judge.js +263 -0
  240. package/dist/middleware/reflect/pass_judge.js.map +1 -0
  241. package/dist/middleware/reflect/pipeline-flags.d.ts +140 -0
  242. package/dist/middleware/reflect/pipeline-flags.d.ts.map +1 -0
  243. package/dist/middleware/reflect/pipeline-flags.js +314 -0
  244. package/dist/middleware/reflect/pipeline-flags.js.map +1 -0
  245. package/dist/middleware/reflect/pipeline.d.ts +237 -0
  246. package/dist/middleware/reflect/pipeline.d.ts.map +1 -0
  247. package/dist/middleware/reflect/pipeline.js +3114 -0
  248. package/dist/middleware/reflect/pipeline.js.map +1 -0
  249. package/dist/middleware/reflect/promptOverride.d.ts +14 -0
  250. package/dist/middleware/reflect/promptOverride.d.ts.map +1 -0
  251. package/dist/middleware/reflect/promptOverride.js +28 -0
  252. package/dist/middleware/reflect/promptOverride.js.map +1 -0
  253. package/dist/middleware/reflect/provenance-check.d.ts +48 -0
  254. package/dist/middleware/reflect/provenance-check.d.ts.map +1 -0
  255. package/dist/middleware/reflect/provenance-check.js +180 -0
  256. package/dist/middleware/reflect/provenance-check.js.map +1 -0
  257. package/dist/middleware/reflect/provenance-reviewer.d.ts +52 -0
  258. package/dist/middleware/reflect/provenance-reviewer.d.ts.map +1 -0
  259. package/dist/middleware/reflect/provenance-reviewer.js +253 -0
  260. package/dist/middleware/reflect/provenance-reviewer.js.map +1 -0
  261. package/dist/middleware/reflect/prune-collapsed-types.d.ts +11 -0
  262. package/dist/middleware/reflect/prune-collapsed-types.d.ts.map +1 -0
  263. package/dist/middleware/reflect/prune-collapsed-types.js +32 -0
  264. package/dist/middleware/reflect/prune-collapsed-types.js.map +1 -0
  265. package/dist/middleware/reflect/recognize-root.d.ts +75 -0
  266. package/dist/middleware/reflect/recognize-root.d.ts.map +1 -0
  267. package/dist/middleware/reflect/recognize-root.js +204 -0
  268. package/dist/middleware/reflect/recognize-root.js.map +1 -0
  269. package/dist/middleware/reflect/render-agent-flag.d.ts +25 -0
  270. package/dist/middleware/reflect/render-agent-flag.d.ts.map +1 -0
  271. package/dist/middleware/reflect/render-agent-flag.js +39 -0
  272. package/dist/middleware/reflect/render-agent-flag.js.map +1 -0
  273. package/dist/middleware/reflect/retrieve-graph-slice.d.ts +54 -0
  274. package/dist/middleware/reflect/retrieve-graph-slice.d.ts.map +1 -0
  275. package/dist/middleware/reflect/retrieve-graph-slice.js +173 -0
  276. package/dist/middleware/reflect/retrieve-graph-slice.js.map +1 -0
  277. package/dist/middleware/reflect/root-relatedness.d.ts +31 -0
  278. package/dist/middleware/reflect/root-relatedness.d.ts.map +1 -0
  279. package/dist/middleware/reflect/root-relatedness.js +92 -0
  280. package/dist/middleware/reflect/root-relatedness.js.map +1 -0
  281. package/dist/middleware/reflect/schema-heal.d.ts +22 -0
  282. package/dist/middleware/reflect/schema-heal.d.ts.map +1 -0
  283. package/dist/middleware/reflect/schema-heal.js +119 -0
  284. package/dist/middleware/reflect/schema-heal.js.map +1 -0
  285. package/dist/middleware/reflect/schema-validator.d.ts +85 -0
  286. package/dist/middleware/reflect/schema-validator.d.ts.map +1 -0
  287. package/dist/middleware/reflect/schema-validator.js +196 -0
  288. package/dist/middleware/reflect/schema-validator.js.map +1 -0
  289. package/dist/middleware/reflect/stage-audit-graph.d.ts +115 -0
  290. package/dist/middleware/reflect/stage-audit-graph.d.ts.map +1 -0
  291. package/dist/middleware/reflect/stage-audit-graph.js +563 -0
  292. package/dist/middleware/reflect/stage-audit-graph.js.map +1 -0
  293. package/dist/middleware/reflect/stage-d-resolve-graph.d.ts +87 -0
  294. package/dist/middleware/reflect/stage-d-resolve-graph.d.ts.map +1 -0
  295. package/dist/middleware/reflect/stage-d-resolve-graph.js +256 -0
  296. package/dist/middleware/reflect/stage-d-resolve-graph.js.map +1 -0
  297. package/dist/middleware/reflect/synthesizeFromSceneCard.d.ts +15 -0
  298. package/dist/middleware/reflect/synthesizeFromSceneCard.d.ts.map +1 -0
  299. package/dist/middleware/reflect/synthesizeFromSceneCard.js +91 -0
  300. package/dist/middleware/reflect/synthesizeFromSceneCard.js.map +1 -0
  301. package/dist/middleware/reflect/types.d.ts +261 -0
  302. package/dist/middleware/reflect/types.d.ts.map +1 -0
  303. package/dist/middleware/reflect/types.js +3 -0
  304. package/dist/middleware/reflect/types.js.map +1 -0
  305. package/dist/middleware/reflect/v2-integrate.d.ts +120 -0
  306. package/dist/middleware/reflect/v2-integrate.d.ts.map +1 -0
  307. package/dist/middleware/reflect/v2-integrate.js +388 -0
  308. package/dist/middleware/reflect/v2-integrate.js.map +1 -0
  309. package/dist/middleware/reflect/v2-judge.d.ts +44 -0
  310. package/dist/middleware/reflect/v2-judge.d.ts.map +1 -0
  311. package/dist/middleware/reflect/v2-judge.js +191 -0
  312. package/dist/middleware/reflect/v2-judge.js.map +1 -0
  313. package/dist/relation-sets.d.ts +2 -0
  314. package/dist/relation-sets.d.ts.map +1 -0
  315. package/dist/relation-sets.js +35 -0
  316. package/dist/relation-sets.js.map +1 -0
  317. package/dist/routes/__tests__/flags.test.d.ts +2 -0
  318. package/dist/routes/__tests__/flags.test.d.ts.map +1 -0
  319. package/dist/routes/__tests__/flags.test.js +257 -0
  320. package/dist/routes/__tests__/flags.test.js.map +1 -0
  321. package/dist/routes/__tests__/models-catalog.test.d.ts +2 -0
  322. package/dist/routes/__tests__/models-catalog.test.d.ts.map +1 -0
  323. package/dist/routes/__tests__/models-catalog.test.js +130 -0
  324. package/dist/routes/__tests__/models-catalog.test.js.map +1 -0
  325. package/dist/routes/__tests__/reflect-pause-drain.test.d.ts +2 -0
  326. package/dist/routes/__tests__/reflect-pause-drain.test.d.ts.map +1 -0
  327. package/dist/routes/__tests__/reflect-pause-drain.test.js +38 -0
  328. package/dist/routes/__tests__/reflect-pause-drain.test.js.map +1 -0
  329. package/dist/routes/__tests__/spend-pause-drain.test.d.ts +2 -0
  330. package/dist/routes/__tests__/spend-pause-drain.test.d.ts.map +1 -0
  331. package/dist/routes/__tests__/spend-pause-drain.test.js +38 -0
  332. package/dist/routes/__tests__/spend-pause-drain.test.js.map +1 -0
  333. package/dist/routes/admin.d.ts +49 -0
  334. package/dist/routes/admin.d.ts.map +1 -0
  335. package/dist/routes/admin.js +471 -0
  336. package/dist/routes/admin.js.map +1 -0
  337. package/dist/routes/blocks.d.ts +4 -0
  338. package/dist/routes/blocks.d.ts.map +1 -0
  339. package/dist/routes/blocks.js +893 -0
  340. package/dist/routes/blocks.js.map +1 -0
  341. package/dist/routes/chat-proxy.d.ts +5 -0
  342. package/dist/routes/chat-proxy.d.ts.map +1 -0
  343. package/dist/routes/chat-proxy.js +225 -0
  344. package/dist/routes/chat-proxy.js.map +1 -0
  345. package/dist/routes/conversations.d.ts +4 -0
  346. package/dist/routes/conversations.d.ts.map +1 -0
  347. package/dist/routes/conversations.js +139 -0
  348. package/dist/routes/conversations.js.map +1 -0
  349. package/dist/routes/flags.d.ts +4 -0
  350. package/dist/routes/flags.d.ts.map +1 -0
  351. package/dist/routes/flags.js +151 -0
  352. package/dist/routes/flags.js.map +1 -0
  353. package/dist/routes/inject.d.ts +4 -0
  354. package/dist/routes/inject.d.ts.map +1 -0
  355. package/dist/routes/inject.js +183 -0
  356. package/dist/routes/inject.js.map +1 -0
  357. package/dist/routes/mcp-http.d.ts +5 -0
  358. package/dist/routes/mcp-http.d.ts.map +1 -0
  359. package/dist/routes/mcp-http.js +94 -0
  360. package/dist/routes/mcp-http.js.map +1 -0
  361. package/dist/routes/quarantine.d.ts +4 -0
  362. package/dist/routes/quarantine.d.ts.map +1 -0
  363. package/dist/routes/quarantine.js +66 -0
  364. package/dist/routes/quarantine.js.map +1 -0
  365. package/dist/routes/recall.d.ts +5 -0
  366. package/dist/routes/recall.d.ts.map +1 -0
  367. package/dist/routes/recall.js +573 -0
  368. package/dist/routes/recall.js.map +1 -0
  369. package/dist/routes/reflect.d.ts +5 -0
  370. package/dist/routes/reflect.d.ts.map +1 -0
  371. package/dist/routes/reflect.js +231 -0
  372. package/dist/routes/reflect.js.map +1 -0
  373. package/dist/routes/session.d.ts +4 -0
  374. package/dist/routes/session.d.ts.map +1 -0
  375. package/dist/routes/session.js +418 -0
  376. package/dist/routes/session.js.map +1 -0
  377. package/dist/routes/state.d.ts +116 -0
  378. package/dist/routes/state.d.ts.map +1 -0
  379. package/dist/routes/state.js +621 -0
  380. package/dist/routes/state.js.map +1 -0
  381. package/dist/routes/usage.d.ts +3 -0
  382. package/dist/routes/usage.d.ts.map +1 -0
  383. package/dist/routes/usage.js +141 -0
  384. package/dist/routes/usage.js.map +1 -0
  385. package/dist/routes/workspace.d.ts +5 -0
  386. package/dist/routes/workspace.d.ts.map +1 -0
  387. package/dist/routes/workspace.js +435 -0
  388. package/dist/routes/workspace.js.map +1 -0
  389. package/dist/server.d.ts +13 -0
  390. package/dist/server.d.ts.map +1 -0
  391. package/dist/server.js +298 -0
  392. package/dist/server.js.map +1 -0
  393. package/dist/store/__tests__/backup.test.d.ts +2 -0
  394. package/dist/store/__tests__/backup.test.d.ts.map +1 -0
  395. package/dist/store/__tests__/backup.test.js +53 -0
  396. package/dist/store/__tests__/backup.test.js.map +1 -0
  397. package/dist/store/__tests__/quality.test.d.ts +2 -0
  398. package/dist/store/__tests__/quality.test.d.ts.map +1 -0
  399. package/dist/store/__tests__/quality.test.js +75 -0
  400. package/dist/store/__tests__/quality.test.js.map +1 -0
  401. package/dist/store/backup.d.ts +14 -0
  402. package/dist/store/backup.d.ts.map +1 -0
  403. package/dist/store/backup.js +95 -0
  404. package/dist/store/backup.js.map +1 -0
  405. package/dist/store/database.d.ts +407 -0
  406. package/dist/store/database.d.ts.map +1 -0
  407. package/dist/store/database.js +2004 -0
  408. package/dist/store/database.js.map +1 -0
  409. package/dist/store/quality.d.ts +25 -0
  410. package/dist/store/quality.d.ts.map +1 -0
  411. package/dist/store/quality.js +48 -0
  412. package/dist/store/quality.js.map +1 -0
  413. package/dist/tools/__tests__/assemble-block-chains.test.d.ts +2 -0
  414. package/dist/tools/__tests__/assemble-block-chains.test.d.ts.map +1 -0
  415. package/dist/tools/__tests__/assemble-block-chains.test.js +118 -0
  416. package/dist/tools/__tests__/assemble-block-chains.test.js.map +1 -0
  417. package/dist/tools/__tests__/filter-roots-by-concepts.test.d.ts +2 -0
  418. package/dist/tools/__tests__/filter-roots-by-concepts.test.d.ts.map +1 -0
  419. package/dist/tools/__tests__/filter-roots-by-concepts.test.js +68 -0
  420. package/dist/tools/__tests__/filter-roots-by-concepts.test.js.map +1 -0
  421. package/dist/tools/__tests__/flag-surface.test.d.ts +2 -0
  422. package/dist/tools/__tests__/flag-surface.test.d.ts.map +1 -0
  423. package/dist/tools/__tests__/flag-surface.test.js +130 -0
  424. package/dist/tools/__tests__/flag-surface.test.js.map +1 -0
  425. package/dist/tools/core.d.ts +5 -0
  426. package/dist/tools/core.d.ts.map +1 -0
  427. package/dist/tools/core.js +962 -0
  428. package/dist/tools/core.js.map +1 -0
  429. package/dist/tools/derive.d.ts +5 -0
  430. package/dist/tools/derive.d.ts.map +1 -0
  431. package/dist/tools/derive.js +182 -0
  432. package/dist/tools/derive.js.map +1 -0
  433. package/dist/tools/flag-surface.d.ts +26 -0
  434. package/dist/tools/flag-surface.d.ts.map +1 -0
  435. package/dist/tools/flag-surface.js +59 -0
  436. package/dist/tools/flag-surface.js.map +1 -0
  437. package/dist/tools/helpers.d.ts +99 -0
  438. package/dist/tools/helpers.d.ts.map +1 -0
  439. package/dist/tools/helpers.js +243 -0
  440. package/dist/tools/helpers.js.map +1 -0
  441. package/dist/tools/projects.d.ts +5 -0
  442. package/dist/tools/projects.d.ts.map +1 -0
  443. package/dist/tools/projects.js +175 -0
  444. package/dist/tools/projects.js.map +1 -0
  445. package/dist/tools/system.d.ts +5 -0
  446. package/dist/tools/system.d.ts.map +1 -0
  447. package/dist/tools/system.js +1361 -0
  448. package/dist/tools/system.js.map +1 -0
  449. package/dist/tools/tasks.d.ts +5 -0
  450. package/dist/tools/tasks.d.ts.map +1 -0
  451. package/dist/tools/tasks.js +289 -0
  452. package/dist/tools/tasks.js.map +1 -0
  453. package/package.json +69 -0
  454. package/scripts/nodedex-entry.mjs +396 -0
  455. package/tui-dist/App.js +185 -0
  456. package/tui-dist/api.js +197 -0
  457. package/tui-dist/cli.js +53 -0
  458. package/tui-dist/components.js +63 -0
  459. package/tui-dist/config.js +242 -0
  460. package/tui-dist/connect-snippets.js +98 -0
  461. package/tui-dist/feed.js +51 -0
  462. package/tui-dist/health.js +465 -0
  463. package/tui-dist/hooks.js +23 -0
  464. package/tui-dist/memory.js +220 -0
  465. package/tui-dist/onboarding.js +498 -0
  466. package/tui-dist/review.js +193 -0
  467. package/tui-dist/servers.js +556 -0
  468. package/tui-dist/smoke.js +15 -0
  469. package/tui-dist/theme.js +106 -0
@@ -0,0 +1,573 @@
1
+ // routes/recall.ts — recall-fast, recall-smart, recall-chain, keyword search
2
+ // Reference: api-server.v1.ts lines 1472–2476
3
+ import { Router } from "express";
4
+ import { cosineSim } from "../engine/vector-math.js";
5
+ import { searchBlocks, rootContextFor, allWeak } from "../engine/search-core.js";
6
+ import { sessionEvents, SESSION_EVENT_MAX, evaluateAlertsAfterRecall, incrementSessionEventCounter, } from "./state.js";
7
+ const RECALL_STOPWORDS = new Set([
8
+ "the", "is", "a", "an", "to", "of", "in", "for", "on", "with", "and", "or", "but",
9
+ "it", "this", "that", "how", "what", "why", "can", "do", "be", "are", "was", "were",
10
+ "will", "you", "your", "me", "my", "we", "our", "so", "now", "get", "got", "let",
11
+ "go", "just", "also", "very", "more", "most", "some", "any", "all", "no", "not",
12
+ "have", "has", "had", "been", "would", "could", "should", "may", "might", "must",
13
+ "about", "from", "than", "then", "there", "here", "when", "where", "which", "who",
14
+ "did", "does", "its", "their", "them", "they", "these", "those", "into", "out",
15
+ "yes", "okay", "great", "done", "right", "sure", "good", "bad", "new", "old",
16
+ "system", "model", "approach", "method", "result", "results", "process",
17
+ "way", "means", "make", "makes", "show", "shows", "use", "uses", "using",
18
+ "work", "works", "need", "needs", "find", "found", "see", "tell", "know",
19
+ "think", "look", "try", "like", "much", "many", "well", "true", "false",
20
+ "ahead", "alright", "fixed", "things", "thing", "something", "anything",
21
+ "session", "fix", "build", "run", "runs", "running", "restart", "kill", "start", "stop",
22
+ "test", "tests", "testing", "done", "check", "checks", "update", "updates", "updated",
23
+ "change", "changes", "changed", "add", "added", "adding", "remove", "removed", "implement",
24
+ "implemented", "deploy", "deployed", "server", "process", "command", "script", "file", "code",
25
+ "solution", "solutions", "problem", "problems", "issue", "issues", "approach", "approaches",
26
+ "remediation", "cause", "causes", "reason", "reasons", "error", "errors", "case", "cases",
27
+ "based", "given", "these", "those", "such", "each", "both", "only", "even", "just",
28
+ ]);
29
+ export function createRecallRouter(db, embeddings) {
30
+ const router = Router();
31
+ // ─── Search ────────────────────────────────────────────────────────────────
32
+ // Same three-signal scorer as the MCP workspace_search (engine/search-core.ts) —
33
+ // every door ranks the same way. Was: bare LIKE scan ORDERED BY access_count,
34
+ // i.e. popularity — recently-poked blocks outranked actual matches.
35
+ router.get("/api/search", async (req, res) => {
36
+ try {
37
+ const q = req.query.q || "";
38
+ const limit = Number(req.query.limit) || 5;
39
+ const type = req.query.type || undefined;
40
+ if (!q)
41
+ return res.json([]);
42
+ const { hits } = await searchBlocks(db, embeddings, { query: q, type, limit });
43
+ // Currency annotation — superseded blocks stay active (edge = currency, not status);
44
+ // a bare search hit must carry what replaced it so stale can't read as current.
45
+ const supersededBy = db.getSupersededByLabels(hits.map(({ block }) => block.id));
46
+ // Root context per hit — judge relevance from the root's one-liner without
47
+ // resolving project_id block-by-block.
48
+ const rootCtx = rootContextFor(db, hits.map(({ block }) => block));
49
+ // Response is a bare array (back-compat), so the weak-result label rides on
50
+ // each hit: weak_match=true ⇒ nearest-neighbor shrug, not an answer.
51
+ const weak = allWeak(hits);
52
+ const slim = hits.map(({ block, score, matchTypes }) => {
53
+ const { embedding: _e, content: _c, ...b } = block;
54
+ return {
55
+ ...b,
56
+ score: Math.round(score * 100) / 100,
57
+ match_types: matchTypes,
58
+ ...(weak ? { weak_match: true } : {}),
59
+ ...(typeof block.project_id === "string" && rootCtx.has(block.project_id)
60
+ ? rootCtx.get(block.project_id)
61
+ : {}),
62
+ ...(supersededBy.has(block.id) ? { superseded_by: supersededBy.get(block.id) } : {}),
63
+ };
64
+ });
65
+ res.json(slim);
66
+ }
67
+ catch (e) {
68
+ res.status(500).json({ error: String(e) });
69
+ }
70
+ });
71
+ // ─── recall-fast ────────────────────────────────────────────────────────────
72
+ router.get("/api/recall-fast", async (req, res) => {
73
+ try {
74
+ const q = req.query.q || "";
75
+ const limit = Number(req.query.limit) || 3;
76
+ const projectIds = (req.query.project || "").split(",").map(s => s.trim()).filter(Boolean);
77
+ const blockTypes = (req.query.types || "").split(",").map(s => s.trim()).filter(Boolean);
78
+ const strictScope = req.query.strict === "1";
79
+ if (!q)
80
+ return res.json([]);
81
+ let scopedBlockIds = null;
82
+ if (projectIds.length > 0) {
83
+ const resolvedProjectIds = projectIds.map(pid => db.getBlock(pid)?.id ?? pid);
84
+ const projectIdSet = new Set(resolvedProjectIds);
85
+ const allActiveBlocks = db.getAllBlocks();
86
+ scopedBlockIds = new Set(resolvedProjectIds);
87
+ for (const b of allActiveBlocks) {
88
+ if (b.project_id && projectIdSet.has(b.project_id))
89
+ scopedBlockIds.add(b.id);
90
+ }
91
+ }
92
+ const allTokens = q.toLowerCase().replace(/[^a-z0-9_ ]/g, " ").split(/\s+/)
93
+ .filter((w) => w.length > 2 && !RECALL_STOPWORDS.has(w));
94
+ if (allTokens.length === 0)
95
+ return res.json([]);
96
+ const conceptTerms = allTokens;
97
+ const scored = new Map();
98
+ const kwResults = db.keywordSearch(allTokens.join(" "), limit * 5);
99
+ for (const b of kwResults) {
100
+ if (scopedBlockIds && !scopedBlockIds.has(b.id))
101
+ continue;
102
+ const labelLower = (b.label || "").toLowerCase();
103
+ const labelHits = allTokens.filter(t => labelLower.includes(t.toLowerCase())).length;
104
+ const labelScore = labelHits >= 3 ? 1.8 : labelHits === 2 ? 1.5 : labelHits === 1 ? 1.2 : 1.0;
105
+ scored.set(b.id, { block: b, score: labelScore });
106
+ }
107
+ if (conceptTerms.length > 0) {
108
+ const conceptMatches = db.conceptSearch(conceptTerms);
109
+ for (const [id, { block, matches }] of conceptMatches) {
110
+ if (scopedBlockIds && !scopedBlockIds.has(id))
111
+ continue;
112
+ const bonus = Math.min(matches * 0.5, 0.6);
113
+ const existing = scored.get(id);
114
+ if (existing) {
115
+ existing.score += bonus;
116
+ }
117
+ else {
118
+ scored.set(id, { block, score: bonus });
119
+ }
120
+ }
121
+ }
122
+ const hop2Ids = new Set();
123
+ const hopConcepts = new Set();
124
+ const top5Hop1 = Array.from(scored.values()).sort((a, b) => b.score - a.score).slice(0, 5);
125
+ for (const { block } of top5Hop1) {
126
+ try {
127
+ const blockConcepts = JSON.parse(block.concepts || "[]");
128
+ for (const c of blockConcepts) {
129
+ if (hopConcepts.size >= 20)
130
+ break;
131
+ hopConcepts.add(c.toLowerCase());
132
+ }
133
+ }
134
+ catch { /* ignore */ }
135
+ }
136
+ if (hopConcepts.size > 0 && allTokens.length >= 1) {
137
+ const totalBlocks = db.getTotalBlockCount();
138
+ const idfThreshold = Math.max(5, Math.floor(totalBlocks * 0.10));
139
+ const specificConcepts = [...hopConcepts].filter(c => db.countBlocksWithConcept(c) <= idfThreshold);
140
+ const hopMatches = specificConcepts.length > 0 ? db.conceptSearch(specificConcepts) : new Map();
141
+ for (const [id, { block, matches }] of hopMatches) {
142
+ if (scopedBlockIds && !scopedBlockIds.has(id))
143
+ continue;
144
+ const bonus = Math.min(matches * 0.25, 0.75);
145
+ const existing = scored.get(id);
146
+ if (existing) {
147
+ existing.score += bonus * 0.5;
148
+ }
149
+ else {
150
+ scored.set(id, { block, score: bonus });
151
+ hop2Ids.add(id);
152
+ }
153
+ }
154
+ }
155
+ if (projectIds.length > 0) {
156
+ const allRelations = db.getAllRelations(false);
157
+ const projectLinkedIds = new Set(projectIds);
158
+ for (const r of allRelations) {
159
+ if (projectIds.includes(r.source_id))
160
+ projectLinkedIds.add(r.target_id);
161
+ if (projectIds.includes(r.target_id))
162
+ projectLinkedIds.add(r.source_id);
163
+ }
164
+ for (const entry of scored.values()) {
165
+ if (projectLinkedIds.has(entry.block.id))
166
+ entry.score *= 1.1;
167
+ }
168
+ }
169
+ for (const entry of scored.values()) {
170
+ if (entry.block.type === "insight")
171
+ entry.score *= 1.3;
172
+ try {
173
+ const c = JSON.parse(entry.block.content || "{}");
174
+ if (c?.reasoning_chain || c?.derivation)
175
+ entry.score *= 1.2;
176
+ }
177
+ catch { /* ignore */ }
178
+ const st = entry.block.source_type || "agent_derived";
179
+ if (st === "agent_derived" || st === "derived_from_blocks")
180
+ entry.score *= 1.05;
181
+ }
182
+ for (const [id, entry] of scored.entries()) {
183
+ if (hop2Ids.has(id))
184
+ continue;
185
+ const raw = entry.block.quality_score;
186
+ const qScore = (typeof raw === "number" && raw > 0) ? raw : 3;
187
+ entry.score *= 0.75 + (qScore / 6) * 0.25;
188
+ }
189
+ const minQuality = Number(req.query.min_quality) || 0;
190
+ // Bug 1 fix (2026-05-28): q=0 used to be an unconditional reject — but
191
+ // STRUCTURAL_TYPES (project, process) historically shipped at q=0
192
+ // (pipeline didn't call computeQualityScore on them; only manual POST
193
+ // paths did). That conflated "junk content" with "structurally-empty
194
+ // container," making recall-fast?types=project return zero hits for any
195
+ // query. Part A (stampQualityScore in pipeline) now sets a real score on
196
+ // new structural blocks; this guard catches the long tail (old blocks +
197
+ // any code path that misses Part A). Charter rule 6: defense-in-depth.
198
+ const STRUCTURAL_TYPES = ["project", "process"];
199
+ let ranked = Array.from(scored.values()).filter(({ score, block }) => {
200
+ if (score < 0.2)
201
+ return false;
202
+ const q = block.quality_score ?? 0;
203
+ if (q === 0 && !STRUCTURAL_TYPES.includes(block.type))
204
+ return false;
205
+ if (minQuality > 0 && q < minQuality)
206
+ return false;
207
+ if (blockTypes.length > 0 && !blockTypes.includes(block.type))
208
+ return false;
209
+ return true;
210
+ }).sort((a, b) => b.score - a.score).slice(0, limit);
211
+ if (scopedBlockIds && ranked.length < 2 && !strictScope) {
212
+ const unscopedScored = new Map();
213
+ const kwAll = db.keywordSearch(allTokens.join(" "), limit * 5);
214
+ for (const b of kwAll) {
215
+ if (scopedBlockIds.has(b.id))
216
+ continue;
217
+ const labelLower = (b.label || "").toLowerCase();
218
+ const labelHits = allTokens.filter(t => labelLower.includes(t.toLowerCase())).length;
219
+ const labelScore = labelHits >= 3 ? 1.8 : labelHits === 2 ? 1.5 : labelHits === 1 ? 1.2 : 1.0;
220
+ unscopedScored.set(b.id, { block: b, score: labelScore });
221
+ }
222
+ if (conceptTerms.length > 0) {
223
+ const conceptMatches = db.conceptSearch(conceptTerms);
224
+ for (const [id, { block, matches }] of conceptMatches) {
225
+ if (scopedBlockIds.has(id))
226
+ continue;
227
+ const bonus = Math.min(matches * 0.5, 0.6);
228
+ const existing = unscopedScored.get(id);
229
+ if (existing) {
230
+ existing.score += bonus;
231
+ }
232
+ else {
233
+ unscopedScored.set(id, { block, score: bonus });
234
+ }
235
+ }
236
+ }
237
+ for (const entry of unscopedScored.values()) {
238
+ const raw = entry.block.quality_score;
239
+ const qScore = (typeof raw === "number" && raw > 0) ? raw : 3;
240
+ entry.score *= 0.75 + (qScore / 6) * 0.25;
241
+ }
242
+ const fallback = Array.from(unscopedScored.values()).filter(({ score, block }) => {
243
+ if (score < 0.2)
244
+ return false;
245
+ const q = block.quality_score ?? 0;
246
+ // Bug 1 fix: same structural-type exemption as the primary filter above.
247
+ if (q === 0 && !STRUCTURAL_TYPES.includes(block.type))
248
+ return false;
249
+ if (blockTypes.length > 0 && !blockTypes.includes(block.type))
250
+ return false;
251
+ return true;
252
+ }).sort((a, b) => b.score - a.score).slice(0, limit - ranked.length);
253
+ ranked = [...ranked, ...fallback];
254
+ }
255
+ const resultIds = ranked.map(({ block }) => block.id);
256
+ const challengesMap = db.getChallengesForBlocks(resultIds);
257
+ const incomingMap = db.getIncomingCounts(resultIds);
258
+ const decayRates = { session: 2.0, "1hr": 1.0, "24hr": 0.5, "1week": 0.1, project: 0.01, permanent: 0.001 };
259
+ const maxBaseScore = Math.max(...ranked.map(r => r.score), 1);
260
+ const rankedWithComposite = ranked.map(({ block, score: rawScore }) => {
261
+ const normScore = rawScore / maxBaseScore;
262
+ const ageDays = (Date.now() - new Date(block.created_at).getTime()) / 86400000;
263
+ const decayRate = decayRates[block.ttl ?? "permanent"] ?? 0.01;
264
+ const recency = 1 / (1 + ageDays * decayRate);
265
+ const compositeScore = normScore * recency;
266
+ return { block, similarity: normScore, composite_score: compositeScore, pick_components: { similarity: Math.round(normScore * 10000) / 10000, recency: Math.round(recency * 10000) / 10000 } };
267
+ }).sort((a, b) => b.composite_score - a.composite_score);
268
+ const pickReason = undefined;
269
+ const _allBlocksForCoord = db.getAllBlocks();
270
+ const _blockMapForCoord = new Map(_allBlocksForCoord.map((b) => [b.id, b]));
271
+ function resolveProject(blockId) {
272
+ const b = _blockMapForCoord.get(blockId);
273
+ if (!b)
274
+ return null;
275
+ if (b.type === "project")
276
+ return { id: b.id, label: b.label };
277
+ if (!b.project_id)
278
+ return null;
279
+ const proj = _blockMapForCoord.get(b.project_id);
280
+ return proj ? { id: proj.id, label: proj.label } : null;
281
+ }
282
+ const results = rankedWithComposite.map(({ block, composite_score, pick_components }, idx) => {
283
+ const proj = resolveProject(block.id);
284
+ return {
285
+ id: block.id, label: block.label, type: block.type, essence: block.essence,
286
+ quality_score: block.quality_score,
287
+ source_type: block.source_type || "agent_derived",
288
+ incoming_count: incomingMap.get(block.id) ?? 0,
289
+ challenges: challengesMap.get(block.id) ?? [],
290
+ composite_score: Math.round(composite_score * 10000) / 10000,
291
+ project_id: proj?.id ?? null, project_label: proj?.label ?? null,
292
+ pick_components: { similarity: Math.round(pick_components.similarity * 10000) / 10000, recency: Math.round(pick_components.recency * 10000) / 10000 },
293
+ ...(idx === 0 && pickReason ? { pick_reason: pickReason } : {}),
294
+ };
295
+ });
296
+ if (sessionEvents.length < SESSION_EVENT_MAX) {
297
+ const recalledItems = results.map((r) => ({
298
+ label: r.label, type: r.type,
299
+ project: r.project_label ?? (r.label || "").split("_")[0] ?? "unknown",
300
+ quality: r.quality_score ?? 0,
301
+ }));
302
+ const activeProj = results[0]?.project_label ?? "";
303
+ const crossProjectCount = activeProj ? recalledItems.filter(r => r.project !== activeProj && r.project !== "unknown").length : 0;
304
+ const projectCount = db.getAllBlocks().filter((b) => b.type === "project").length;
305
+ sessionEvents.push({ id: incrementSessionEventCounter(), timestamp: new Date().toISOString(), type: "recall", query: q, recalled: recalledItems, cross_project_count: crossProjectCount, total_injected: recalledItems.length, project_count: projectCount });
306
+ evaluateAlertsAfterRecall(sessionEvents[sessionEvents.length - 1]);
307
+ }
308
+ res.json(results);
309
+ }
310
+ catch (e) {
311
+ res.status(500).json({ error: String(e) });
312
+ }
313
+ });
314
+ // ─── recall-smart ────────────────────────────────────────────────────────────
315
+ router.get("/api/recall-smart", async (req, res) => {
316
+ try {
317
+ const q = req.query.q || "";
318
+ const limit = Math.min(Number(req.query.limit) || 5, 20);
319
+ const agentId = req.query.agent_id || "";
320
+ const explicitProject = req.query.project || "";
321
+ const minTicks = Number(req.query.min_ticks) || 1;
322
+ if (!q)
323
+ return res.json({ results: [], meta: { query_tokens: [], active_project: null, total_candidates: 0 } });
324
+ function stem(word) {
325
+ if (word.length < 4)
326
+ return word;
327
+ if (word.endsWith("ation"))
328
+ return word.slice(0, -5);
329
+ if (word.endsWith("tion"))
330
+ return word.slice(0, -4);
331
+ if (word.endsWith("sion"))
332
+ return word.slice(0, -4);
333
+ if (word.endsWith("ment"))
334
+ return word.slice(0, -4);
335
+ if (word.endsWith("ness"))
336
+ return word.slice(0, -4);
337
+ if (word.endsWith("ity"))
338
+ return word.slice(0, -3);
339
+ if (word.endsWith("age"))
340
+ return word.slice(0, -3);
341
+ if (word.endsWith("ing"))
342
+ return word.slice(0, -3);
343
+ if (word.endsWith("ed"))
344
+ return word.slice(0, -2);
345
+ if (word.endsWith("er"))
346
+ return word.slice(0, -2);
347
+ if (word.endsWith("ion"))
348
+ return word.slice(0, -3);
349
+ if (word.endsWith("al"))
350
+ return word.slice(0, -2);
351
+ if (word.endsWith("ly"))
352
+ return word.slice(0, -2);
353
+ if (word.endsWith("s") && word.length > 4)
354
+ return word.slice(0, -1);
355
+ return word;
356
+ }
357
+ const rawTokens = q.toLowerCase().replace(/[^a-z0-9_\- ]/g, " ").split(/\s+/).filter(w => w.length > 1 && !RECALL_STOPWORDS.has(w));
358
+ const tokenPairs = rawTokens.map(w => ({ raw: w, stem: stem(w) }));
359
+ const tokens = rawTokens;
360
+ if (tokens.length === 0)
361
+ return res.json({ results: [], meta: { query_tokens: [], active_project: null, total_candidates: 0 } });
362
+ let queryEmbedding = null;
363
+ if (embeddings?.isAvailable())
364
+ queryEmbedding = await embeddings.embed(q).catch(() => null);
365
+ let activeProjectLabel = null;
366
+ if (explicitProject) {
367
+ const projBlock = db.getBlock(explicitProject);
368
+ activeProjectLabel = projBlock?.label ?? explicitProject;
369
+ }
370
+ else if (agentId) {
371
+ const cutoff = Date.now() - 30 * 60 * 1000;
372
+ const recentAccessed = db.getAllBlocks().filter((b) => b.last_accessed && new Date(b.last_accessed).getTime() > cutoff && b.type !== "project" && b.status === "active").sort((a, b) => new Date(b.last_accessed).getTime() - new Date(a.last_accessed).getTime()).slice(0, 15);
373
+ if (recentAccessed.length > 0) {
374
+ const projectCounts = new Map();
375
+ for (const b of recentAccessed) {
376
+ const prefix = b.label?.split("_")[0];
377
+ if (prefix && prefix.length > 1)
378
+ projectCounts.set(prefix, (projectCounts.get(prefix) || 0) + 1);
379
+ }
380
+ if (projectCounts.size > 0)
381
+ activeProjectLabel = [...projectCounts.entries()].sort((a, b) => b[1] - a[1])[0][0];
382
+ }
383
+ }
384
+ const kwCandidates = db.keywordSearch(tokens.join(" "), 200);
385
+ const conceptCandidates = tokens.length > 0 ? [...db.conceptSearch(tokens).values()].map((v) => v.block) : [];
386
+ const candidateMap = new Map();
387
+ for (const b of [...kwCandidates, ...conceptCandidates]) {
388
+ if (b && b.id && b.status === "active")
389
+ candidateMap.set(b.id, b);
390
+ }
391
+ const candidates = candidateMap.size >= 10 ? [...candidateMap.values()] : db.getAllBlocks().filter((b) => b.status === "active" && b.type !== "project");
392
+ const scored = [];
393
+ const embeddingMap = new Map();
394
+ if (queryEmbedding) {
395
+ for (const b of candidates) {
396
+ if (b.embedding) {
397
+ try {
398
+ const vec = typeof b.embedding === "string" ? JSON.parse(b.embedding) : b.embedding;
399
+ if (Array.isArray(vec))
400
+ embeddingMap.set(b.id, vec);
401
+ }
402
+ catch { /* skip */ }
403
+ }
404
+ }
405
+ }
406
+ function matchesToken(text, pair) {
407
+ if (text.includes(pair.raw))
408
+ return true;
409
+ const stemText = stem(text.replace(/[-_]/g, ""));
410
+ return stemText.includes(pair.stem) || text.includes(pair.stem);
411
+ }
412
+ for (const block of candidates) {
413
+ const bd = { label_segments: [], essence: [], unique_keys: [], unique_values: [], concepts: [], project_context: [] };
414
+ const segs = (block.label || "").toLowerCase().split("_");
415
+ for (let i = 1; i < segs.length; i++) {
416
+ const seg = segs[i].replace(/-/g, " ");
417
+ const dimLabel = i === 1 ? "entity" : i === segs.length - 1 ? "concept" : "type";
418
+ for (const pair of tokenPairs) {
419
+ if (matchesToken(seg, pair))
420
+ bd.label_segments.push(`${pair.raw}→${dimLabel}:${segs[i]}`);
421
+ }
422
+ }
423
+ const essenceLower = (block.essence || "").toLowerCase();
424
+ for (const pair of tokenPairs) {
425
+ if (matchesToken(essenceLower, pair))
426
+ bd.essence.push(pair.raw);
427
+ }
428
+ try {
429
+ const raw = typeof block.content === "string" ? JSON.parse(block.content) : (block.content || {});
430
+ const unique = raw?.unique || {};
431
+ for (const [key, val] of Object.entries(unique)) {
432
+ const keyLower = key.toLowerCase().replace(/_/g, " ");
433
+ const valLower = String(val).toLowerCase();
434
+ for (const pair of tokenPairs) {
435
+ if (matchesToken(keyLower, pair)) {
436
+ bd.unique_keys.push(`${pair.raw}→key:${key}`);
437
+ }
438
+ else if (matchesToken(valLower, pair)) {
439
+ bd.unique_values.push(`${pair.raw}→val:${key}`);
440
+ }
441
+ }
442
+ }
443
+ }
444
+ catch { /* malformed content */ }
445
+ try {
446
+ const conceptTags = JSON.parse(block.concepts || "[]");
447
+ for (const c of conceptTags) {
448
+ const cNorm = c.toLowerCase().replace(/[-_]/g, " ");
449
+ for (const pair of tokenPairs) {
450
+ if (matchesToken(cNorm, pair))
451
+ bd.concepts.push(`${pair.raw}→${c}`);
452
+ }
453
+ }
454
+ }
455
+ catch { /* skip */ }
456
+ if (activeProjectLabel && (block.label || "").startsWith(activeProjectLabel + "_"))
457
+ bd.project_context.push(`project:${activeProjectLabel}`);
458
+ const ticks = bd.label_segments.length + bd.essence.length + bd.unique_keys.length + bd.unique_values.length + bd.concepts.length + bd.project_context.length;
459
+ const blockVec = embeddingMap.get(block.id);
460
+ const semanticSim = (queryEmbedding && blockVec) ? cosineSim(queryEmbedding, blockVec) : 0;
461
+ if (ticks < minTicks && semanticSim < 0.5)
462
+ continue;
463
+ let structScore = 0;
464
+ structScore += bd.label_segments.length * 2.0;
465
+ structScore += bd.essence.length * 1.5;
466
+ structScore += bd.unique_keys.length * 2.5;
467
+ structScore += bd.unique_values.length * 1.0;
468
+ structScore += bd.concepts.length * 0.5;
469
+ structScore += bd.project_context.length * 1.5;
470
+ const normStruct = Math.min(structScore / 20, 1.0);
471
+ const blended = (normStruct * 0.6) + (semanticSim * 0.4);
472
+ const DEAD_END_SIGNALS = ["why", "rejected", "failed", "abandoned", "not", "avoid", "revert", "dropped", "gave up"];
473
+ const queryHasDeadEndSignal = DEAD_END_SIGNALS.some(s => q.toLowerCase().includes(s));
474
+ const deadEndBoost = (block.type === "dead_end" && queryHasDeadEndSignal) ? 1.5 : 1.0;
475
+ const qScore = typeof block.quality_score === "number" && block.quality_score > 0 ? block.quality_score : 3;
476
+ const finalScore = blended * (0.75 + (qScore / 6) * 0.25) * deadEndBoost;
477
+ scored.push({ block, score: finalScore, ticks, breakdown: bd, semanticSim });
478
+ }
479
+ scored.sort((a, b) => b.score === a.score ? b.ticks - a.ticks : b.score - a.score);
480
+ const scopedScored = explicitProject && activeProjectLabel ? scored.filter(({ block }) => (block.label || "").startsWith(activeProjectLabel + "_") || block.label === activeProjectLabel) : scored;
481
+ const toSlice = (explicitProject && scopedScored.length === 0) ? scored : scopedScored;
482
+ const top = toSlice.slice(0, limit);
483
+ const results = top.map(({ block, score, ticks, breakdown, semanticSim }) => {
484
+ const parts = [];
485
+ if (breakdown.label_segments.length)
486
+ parts.push(`label[${breakdown.label_segments.join(", ")}]`);
487
+ if (breakdown.essence.length)
488
+ parts.push(`essence[${breakdown.essence.join(", ")}]`);
489
+ if (breakdown.unique_keys.length)
490
+ parts.push(`field[${breakdown.unique_keys.join(", ")}]`);
491
+ if (breakdown.unique_values.length)
492
+ parts.push(`value[${breakdown.unique_values.join(", ")}]`);
493
+ if (breakdown.concepts.length)
494
+ parts.push(`concept[${breakdown.concepts.join(", ")}]`);
495
+ if (breakdown.project_context.length)
496
+ parts.push(`context[${breakdown.project_context[0]}]`);
497
+ if (ticks === 0 && semanticSim > 0.5)
498
+ parts.push(`semantic[sim:${Math.round(semanticSim * 100)}%]`);
499
+ return { id: block.id, label: block.label, type: block.type, essence: block.essence, quality_score: block.quality_score, ticks, score: Math.round(score * 1000) / 1000, semantic_sim: Math.round(semanticSim * 1000) / 1000, match_reason: parts.join(" | "), breakdown };
500
+ });
501
+ if (sessionEvents.length < SESSION_EVENT_MAX) {
502
+ const activeProj = activeProjectLabel ?? "";
503
+ const recalledItems = results.map((r) => { const proj = (r.label || "").split("_")[0] ?? "unknown"; return { label: r.label, type: r.type, project: proj, quality: r.quality_score ?? 0 }; });
504
+ const crossProjectCount = activeProj ? recalledItems.filter((r) => r.project !== activeProj && r.project !== "unknown").length : 0;
505
+ const projectCount = db.getAllBlocks().filter((b) => b.type === "project").length;
506
+ sessionEvents.push({ id: incrementSessionEventCounter(), timestamp: new Date().toISOString(), type: "recall", query: q, recalled: recalledItems, cross_project_count: crossProjectCount, total_injected: recalledItems.length, project_count: projectCount });
507
+ evaluateAlertsAfterRecall(sessionEvents[sessionEvents.length - 1]);
508
+ }
509
+ res.json({ results, meta: { query_tokens: tokens, stemmed_pairs: tokenPairs.map(p => p.raw !== p.stem ? `${p.raw}→${p.stem}` : p.raw), semantic_enabled: !!queryEmbedding, active_project: activeProjectLabel, total_candidates: candidates.length, total_scored: scored.length } });
510
+ }
511
+ catch (e) {
512
+ res.status(500).json({ error: String(e) });
513
+ }
514
+ });
515
+ // ─── recall-chain ────────────────────────────────────────────────────────────
516
+ router.get("/api/recall-chain", (req, res) => {
517
+ try {
518
+ const q = req.query.q || "";
519
+ const limit = Math.min(Number(req.query.limit) || 2, 4);
520
+ const minQuality = Number(req.query.min_quality) || 3;
521
+ if (!q)
522
+ return res.json({ chains: [] });
523
+ const queryTerms = q.toLowerCase().replace(/[^a-z0-9_ ]/g, " ").split(/\s+/).filter(w => w.length > 3);
524
+ if (queryTerms.length === 0)
525
+ return res.json({ chains: [] });
526
+ const allBlocks = db.getAllBlocks();
527
+ const candidates = allBlocks.filter(b => {
528
+ if (b.status === "archived")
529
+ return false;
530
+ let content = {};
531
+ try {
532
+ content = JSON.parse(b.content || "{}");
533
+ }
534
+ catch {
535
+ return false;
536
+ }
537
+ const hasDerivation = !!(content.derivation);
538
+ const hasProblem = !!(content.save_context?.problem_being_solved);
539
+ if (!hasDerivation && !hasProblem)
540
+ return false;
541
+ if (!hasDerivation && (b.quality_score ?? 0) < minQuality)
542
+ return false;
543
+ return true;
544
+ });
545
+ const scored = candidates.map(block => {
546
+ let content = {};
547
+ try {
548
+ content = JSON.parse(block.content || "{}");
549
+ }
550
+ catch { /* ok */ }
551
+ const saveCtx = content.save_context;
552
+ const derivation = content.derivation;
553
+ const searchText = [block.essence, saveCtx?.problem_being_solved, derivation?.logic].filter(Boolean).join(" ").toLowerCase();
554
+ const matches = queryTerms.filter(t => searchText.includes(t)).length;
555
+ return { block, score: matches / Math.max(queryTerms.length, 1), saveCtx, derivation };
556
+ }).filter(x => x.score > 0).sort((a, b) => b.score - a.score).slice(0, limit);
557
+ const chains = scored.map(({ block, saveCtx, derivation }) => {
558
+ const inputs = derivation?.inputs || [];
559
+ return {
560
+ problem: saveCtx?.problem_being_solved || block.essence.slice(0, 80),
561
+ tip: { id: block.id, label: block.label, conclusion: block.essence, type: block.type, role: "synthesis", logic: derivation?.logic?.slice(0, 200) || null },
562
+ chain: inputs.map(inp => ({ id: inp.id, label: inp.label, essence: (inp.essence || "").slice(0, 100), role: "premise" })),
563
+ };
564
+ });
565
+ res.json({ chains });
566
+ }
567
+ catch (e) {
568
+ res.status(500).json({ error: String(e) });
569
+ }
570
+ });
571
+ return router;
572
+ }
573
+ //# sourceMappingURL=recall.js.map