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,209 @@
1
+ // ═══════════════════════════════════════════════════════════════════════════════
2
+ // USAGE LEDGER — call-level API-key metering (2026-06-01)
3
+ //
4
+ // Why this exists:
5
+ // The existing cost telemetry (reflectTokenStats / cost-breakdown) is PER-PASS
6
+ // and, by design, incomplete. That left a blind spot: "was the API key called
7
+ // at all, and how much did THIS call cost?" When credit drops there was no local
8
+ // ground-truth ledger to diff against the provider dashboard.
9
+ //
10
+ // This wraps the LLM provider at the ONE seam every structured key call goes
11
+ // through — getLLMProvider() — so EVERY generateStructured() (every provider,
12
+ // every caller, present and future) is metered into an append-only JSONL ledger
13
+ // (default ~/.nodedex/api-usage.jsonl), one line per call:
14
+ // { ts, model, input, output, thinking, cost_usd, cost_source, wall_ms }
15
+ //
16
+ // Design invariants:
17
+ // - Metering NEVER breaks a generation. The inner result is sacred; all ledger
18
+ // work is wrapped in try/catch and swallowed on failure.
19
+ // - Only real key calls are recorded — gated on `result.model` being set (the
20
+ // no-API-key early return carries no model, so it's correctly skipped).
21
+ // - cost_usd prefers the provider's ACTUAL billed cost (usage.costUsd, populated
22
+ // on the OpenRouter path) and falls back to the static-table estimate; every
23
+ // line is tagged with cost_source so the total is never a silent mix.
24
+ // - Default ON (observability before optimization). NODEDEX_USAGE_LEDGER=off to
25
+ // disable; NODEDEX_USAGE_LEDGER_PATH to relocate (tests point it at a temp file).
26
+ //
27
+ // Layering note: imports computeCost from middleware/reflect/cost-pricing, a pure
28
+ // LEAF module (zero internal imports). No cycle.
29
+ // ═══════════════════════════════════════════════════════════════════════════════
30
+ import { appendFileSync, readFileSync, existsSync, mkdirSync } from "fs";
31
+ import { homedir } from "os";
32
+ import path from "path";
33
+ import { computeCost } from "../../middleware/reflect/cost-pricing.js";
34
+ function ledgerPath() {
35
+ return (process.env.NODEDEX_USAGE_LEDGER_PATH ??
36
+ path.join(homedir(), ".nodedex", "api-usage.jsonl"));
37
+ }
38
+ function ledgerEnabled() {
39
+ return (process.env.NODEDEX_USAGE_LEDGER ?? "on").toLowerCase() !== "off";
40
+ }
41
+ /** Append one call to the ledger file. Best-effort — callers must not depend on it. */
42
+ function recordCall(res, wallMs) {
43
+ const u = res.usage; // { input, thinking, output, costUsd? }
44
+ const tokens = u ? { input: u.input, output: u.output, thinking: u.thinking } : undefined;
45
+ // Prefer the provider's ACTUAL billed cost; else the static-table estimate.
46
+ const actual = u?.costUsd;
47
+ const estimated = computeCost(tokens, res.model);
48
+ const cost_usd = actual ?? estimated;
49
+ const cost_source = actual !== undefined && actual !== null
50
+ ? "openrouter_actual"
51
+ : estimated !== null
52
+ ? "estimated"
53
+ : "unknown";
54
+ const entry = {
55
+ ts: new Date().toISOString(),
56
+ model: res.model ?? "(unknown)",
57
+ input: tokens?.input ?? null,
58
+ output: tokens?.output ?? null,
59
+ thinking: tokens?.thinking ?? null,
60
+ cost_usd,
61
+ cost_source,
62
+ wall_ms: wallMs,
63
+ };
64
+ const p = ledgerPath();
65
+ const dir = path.dirname(p);
66
+ if (!existsSync(dir))
67
+ mkdirSync(dir, { recursive: true });
68
+ appendFileSync(p, JSON.stringify(entry) + "\n", "utf8");
69
+ }
70
+ /**
71
+ * Wrap a provider so every generateStructured() call is metered into the ledger.
72
+ * The single seam — applied once in getLLMProvider(). All other methods delegate
73
+ * untouched. Only calls that actually hit the API (result.model set) are recorded.
74
+ */
75
+ export function wrapWithUsageLedger(inner) {
76
+ return {
77
+ getName: () => inner.getName(),
78
+ isAvailable: () => inner.isAvailable(),
79
+ ping: () => inner.ping(),
80
+ generate: (prompt) => inner.generate(prompt), // free-form: no usage to meter
81
+ async generateStructured(systemPrompt, userInput, schema, options) {
82
+ const t0 = Date.now();
83
+ const res = await inner.generateStructured(systemPrompt, userInput, schema, options);
84
+ try {
85
+ // Only record genuine key calls — the no-client early return has no model.
86
+ if (ledgerEnabled() && res.model !== undefined)
87
+ recordCall(res, Date.now() - t0);
88
+ }
89
+ catch {
90
+ /* metering must never break a generation */
91
+ }
92
+ return res;
93
+ },
94
+ };
95
+ }
96
+ function emptyModelTotal() {
97
+ return { calls: 0, input: 0, output: 0, thinking: 0, cost_usd: 0 };
98
+ }
99
+ /**
100
+ * Summarize the ledger file (all-time — survives restarts, unlike any in-memory
101
+ * counter). Returns zeros if the ledger doesn't exist. Reads the whole file per
102
+ * call (fine for a local dev ledger); `recent` caps the tail (default 20).
103
+ * Malformed lines are skipped, not fatal.
104
+ */
105
+ export function getUsageSummary(opts = {}) {
106
+ const recentN = opts.recent ?? 20;
107
+ const p = ledgerPath();
108
+ const summary = {
109
+ ledger_path: p,
110
+ enabled: ledgerEnabled(),
111
+ total: { ...emptyModelTotal(), unpriced_calls: 0 },
112
+ cost_sources: { openrouter_actual: 0, estimated: 0, unknown: 0 },
113
+ by_model: {},
114
+ since: null,
115
+ latest: null,
116
+ recent: [],
117
+ };
118
+ if (!existsSync(p))
119
+ return summary;
120
+ let lines;
121
+ try {
122
+ lines = readFileSync(p, "utf8").split("\n").filter((l) => l.trim().length > 0);
123
+ }
124
+ catch {
125
+ return summary;
126
+ }
127
+ const parsed = [];
128
+ for (const line of lines) {
129
+ let e;
130
+ try {
131
+ e = JSON.parse(line);
132
+ }
133
+ catch {
134
+ continue;
135
+ }
136
+ parsed.push(e);
137
+ summary.total.calls += 1;
138
+ summary.total.input += e.input ?? 0;
139
+ summary.total.output += e.output ?? 0;
140
+ summary.total.thinking += e.thinking ?? 0;
141
+ if (e.cost_usd === null || e.cost_usd === undefined) {
142
+ summary.total.unpriced_calls += 1;
143
+ }
144
+ else {
145
+ summary.total.cost_usd += e.cost_usd;
146
+ }
147
+ const src = e.cost_source ?? "estimated";
148
+ summary.cost_sources[src] = (summary.cost_sources[src] ?? 0) + 1;
149
+ const m = (summary.by_model[e.model] ??= emptyModelTotal());
150
+ m.calls += 1;
151
+ m.input += e.input ?? 0;
152
+ m.output += e.output ?? 0;
153
+ m.thinking += e.thinking ?? 0;
154
+ m.cost_usd += e.cost_usd ?? 0;
155
+ }
156
+ if (parsed.length > 0) {
157
+ summary.since = parsed[0].ts ?? null;
158
+ summary.latest = parsed[parsed.length - 1].ts ?? null;
159
+ summary.recent = parsed.slice(-recentN);
160
+ }
161
+ // Round money so the JSON isn't float-noise.
162
+ summary.total.cost_usd = Math.round(summary.total.cost_usd * 1e6) / 1e6;
163
+ for (const m of Object.values(summary.by_model)) {
164
+ m.cost_usd = Math.round(m.cost_usd * 1e6) / 1e6;
165
+ }
166
+ return summary;
167
+ }
168
+ /**
169
+ * Sum cost_usd for ledger entries with `startMs <= ts <= endMs` (epoch millis) —
170
+ * the fast, LOCAL windowed-spend read. Two consumers: the cost breaker's
171
+ * rolling-window guard (via getSpendSince), and per-stage v2 front-half cost
172
+ * attribution (each stage's [start,end] timing window → its spend, since the
173
+ * stages run sequentially so windows don't overlap). Accurate because 97.8% of
174
+ * entries carry the real billed cost; the blind spots (free-form generate(),
175
+ * embeddings) aren't ledgered. Missing/unreadable ledger → 0. Malformed lines
176
+ * skipped; null-cost entries contribute 0.
177
+ */
178
+ export function getSpendBetween(startMs, endMs) {
179
+ const p = ledgerPath();
180
+ if (!existsSync(p))
181
+ return 0;
182
+ let lines;
183
+ try {
184
+ lines = readFileSync(p, "utf8").split("\n").filter((l) => l.trim().length > 0);
185
+ }
186
+ catch {
187
+ return 0;
188
+ }
189
+ let sum = 0;
190
+ for (const line of lines) {
191
+ let e;
192
+ try {
193
+ e = JSON.parse(line);
194
+ }
195
+ catch {
196
+ continue;
197
+ }
198
+ const t = Date.parse(e.ts);
199
+ if (!Number.isFinite(t) || t < startMs || t > endMs)
200
+ continue;
201
+ if (typeof e.cost_usd === "number")
202
+ sum += e.cost_usd;
203
+ }
204
+ return Math.round(sum * 1e6) / 1e6;
205
+ }
206
+ export function getSpendSince(sinceMs) {
207
+ return getSpendBetween(sinceMs, Number.POSITIVE_INFINITY);
208
+ }
209
+ //# sourceMappingURL=usage-ledger.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"usage-ledger.js","sourceRoot":"","sources":["../../../src/engine/providers/usage-ledger.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,40 @@
1
+ import { WorkspaceDB, Block } from "../store/database.js";
2
+ import { EmbeddingEngine } from "./embeddings.js";
3
+ export interface SearchHit {
4
+ block: Block;
5
+ score: number;
6
+ matchTypes: string[];
7
+ }
8
+ export interface SearchSignals {
9
+ semantic: boolean;
10
+ keyword: boolean;
11
+ concept: boolean;
12
+ }
13
+ export interface SearchOptions {
14
+ query: string;
15
+ type?: string;
16
+ limit?: number;
17
+ }
18
+ /** Three-signal search: semantic similarity (embedding cosine) + keyword match +
19
+ * concept overlap. Signals ADD, so a block matching two ways beats one matching
20
+ * once; each hit carries matchTypes explaining why it surfaced. Embeddings are
21
+ * optional — without them the semantic signal is skipped and the other two
22
+ * still work (signals.semantic reports what actually ran). */
23
+ export declare function searchBlocks(db: WorkspaceDB, embeddings: EmbeddingEngine | undefined, opts: SearchOptions): Promise<{
24
+ hits: SearchHit[];
25
+ signals: SearchSignals;
26
+ }>;
27
+ /** True when the ENTIRE result set is weak (semantic-only, sub-0.3): the graph
28
+ * likely has nothing on this topic. One strong hit anywhere → not weak. */
29
+ export declare function allWeak(hits: SearchHit[]): boolean;
30
+ export declare const WEAK_NOTE = "weak matches only \u2014 nothing matched by keyword or concept; the graph likely has nothing on this topic. These are just the nearest blocks, not an answer.";
31
+ export interface RootContext {
32
+ root_label: string;
33
+ root_essence: string;
34
+ }
35
+ /** Root context for a set of hits — the same containment the tree query renders,
36
+ * attached to retrieval results so the agent can judge "which world is this hit
37
+ * from?" per line instead of resolving project_id block-by-block. One lookup per
38
+ * DISTINCT root. */
39
+ export declare function rootContextFor(db: WorkspaceDB, blocks: Block[]): Map<string, RootContext>;
40
+ //# sourceMappingURL=search-core.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-core.d.ts","sourceRoot":"","sources":["../../src/engine/search-core.ts"],"names":[],"mappings":"AAiBA,OAAO,EAAE,WAAW,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAC1D,OAAO,EAAE,eAAe,EAAE,MAAM,iBAAiB,CAAC;AASlD,MAAM,WAAW,SAAS;IACxB,KAAK,EAAE,KAAK,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;IACd,UAAU,EAAE,MAAM,EAAE,CAAC;CACtB;AAED,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,OAAO,CAAC;IAClB,OAAO,EAAE,OAAO,CAAC;IACjB,OAAO,EAAE,OAAO,CAAC;CAClB;AAED,MAAM,WAAW,aAAa;IAC5B,KAAK,EAAE,MAAM,CAAC;IACd,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED;;;;+DAI+D;AAC/D,wBAAsB,YAAY,CAChC,EAAE,EAAE,WAAW,EACf,UAAU,EAAE,eAAe,GAAG,SAAS,EACvC,IAAI,EAAE,aAAa,GAClB,OAAO,CAAC;IAAE,IAAI,EAAE,SAAS,EAAE,CAAC;IAAC,OAAO,EAAE,aAAa,CAAA;CAAE,CAAC,CAiExD;AAaD;4EAC4E;AAC5E,wBAAgB,OAAO,CAAC,IAAI,EAAE,SAAS,EAAE,GAAG,OAAO,CAIlD;AAED,eAAO,MAAM,SAAS,kKACsI,CAAC;AAE7J,MAAM,WAAW,WAAW;IAC1B,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;CACtB;AAED;;;qBAGqB;AACrB,wBAAgB,cAAc,CAAC,EAAE,EAAE,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,GAAG,GAAG,CAAC,MAAM,EAAE,WAAW,CAAC,CAczF"}
@@ -0,0 +1,109 @@
1
+ import { cosineSim } from "./vector-math.js";
2
+ const SEARCH_STOPWORDS = new Set([
3
+ "the", "is", "a", "an", "to", "of", "in", "for", "on", "with", "and", "or", "but", "it",
4
+ "this", "that", "how", "what", "why", "can", "do", "be", "are", "was", "were", "will",
5
+ "i", "my", "we", "our",
6
+ ]);
7
+ /** Three-signal search: semantic similarity (embedding cosine) + keyword match +
8
+ * concept overlap. Signals ADD, so a block matching two ways beats one matching
9
+ * once; each hit carries matchTypes explaining why it surfaced. Embeddings are
10
+ * optional — without them the semantic signal is skipped and the other two
11
+ * still work (signals.semantic reports what actually ran). */
12
+ export async function searchBlocks(db, embeddings, opts) {
13
+ const limit = opts.limit || 10;
14
+ const queryConcepts = opts.query
15
+ .toLowerCase().replace(/[^a-z0-9_ ]/g, " ").split(/\s+/)
16
+ .filter((w) => w.length > 2 && !SEARCH_STOPWORDS.has(w));
17
+ const scoreMap = new Map();
18
+ const add = (block, delta, tag) => {
19
+ const e = scoreMap.get(block.id);
20
+ if (e) {
21
+ e.score += delta;
22
+ e.matchTypes.add(tag);
23
+ }
24
+ else
25
+ scoreMap.set(block.id, { block, score: delta, matchTypes: new Set([tag]) });
26
+ };
27
+ // ── 1. Semantic — meaning, not wording ("auth" finds the "login" block) ──
28
+ const queryEmbedding = embeddings ? await embeddings.embed(opts.query) : null;
29
+ if (queryEmbedding) {
30
+ const semResults = db.semanticSearch(queryEmbedding, limit * 2, opts.type);
31
+ for (const block of semResults) {
32
+ const bv = JSON.parse(block.embedding);
33
+ add(block, cosineSim(queryEmbedding, bv) * 0.5, "semantic");
34
+ }
35
+ }
36
+ // ── 2. Keyword — exact words in label/essence/content ──
37
+ const kwResults = db.keywordSearch(opts.query, limit * 2, opts.type);
38
+ for (const block of kwResults)
39
+ add(block, 0.3, "keyword");
40
+ // ── 3. Concept overlap — pipeline-stamped tags bridge domains ──
41
+ if (queryConcepts.length > 0) {
42
+ const allBlocks = db.getAllBlocks().filter((b) => b.status !== "archived" && (!opts.type || b.type === opts.type));
43
+ for (const block of allBlocks) {
44
+ let blockConcepts = [];
45
+ try {
46
+ const c = typeof block.content === "string" ? JSON.parse(block.content) : block.content;
47
+ blockConcepts = (c?.concepts || []).map((x) => x.toLowerCase());
48
+ }
49
+ catch { /* ignore */ }
50
+ if (!blockConcepts.length)
51
+ continue;
52
+ const matched = queryConcepts.filter((qc) => blockConcepts.some((bc) => bc.includes(qc) || qc.includes(bc)));
53
+ if (matched.length > 0) {
54
+ add(block, Math.min(matched.length * 0.2, 0.6) * 0.4, `concept(${matched.join(",")})`);
55
+ }
56
+ }
57
+ }
58
+ const hits = Array.from(scoreMap.values())
59
+ .sort((a, b) => b.score - a.score ||
60
+ String(b.block.updated_at ?? "").localeCompare(String(a.block.updated_at ?? "")))
61
+ .slice(0, limit)
62
+ .map(({ block, score, matchTypes }) => ({ block, score, matchTypes: [...matchTypes] }));
63
+ return {
64
+ hits,
65
+ signals: {
66
+ semantic: !!queryEmbedding,
67
+ keyword: true,
68
+ concept: queryConcepts.length > 0,
69
+ },
70
+ };
71
+ }
72
+ // ── Weak-result detection ─────────────────────────────────────────────────────
73
+ // The semantic signal is nearest-neighbor: it always returns the CLOSEST blocks,
74
+ // even when nothing is actually close — so an off-graph query ("kubernetes" on a
75
+ // garden db) still yields hits. Measured signature of that noise (dogfood graph,
76
+ // 2026-07-03): EVERY hit semantic-only at a flat ~0.26, while any real result
77
+ // set has at least one multi-signal hit scoring 0.4+. We LABEL it, never drop
78
+ // it: a silent [] can't be told apart from "search broke" (fail-loud rule), and
79
+ // a weak semantic hit is occasionally a true one (measured: a relevant dead-end
80
+ // at 0.22).
81
+ const WEAK_SCORE = 0.3;
82
+ /** True when the ENTIRE result set is weak (semantic-only, sub-0.3): the graph
83
+ * likely has nothing on this topic. One strong hit anywhere → not weak. */
84
+ export function allWeak(hits) {
85
+ return hits.length > 0 && hits.every((h) => h.score < WEAK_SCORE && h.matchTypes.length === 1 && h.matchTypes[0] === "semantic");
86
+ }
87
+ export const WEAK_NOTE = "weak matches only — nothing matched by keyword or concept; the graph likely has nothing on this topic. These are just the nearest blocks, not an answer.";
88
+ /** Root context for a set of hits — the same containment the tree query renders,
89
+ * attached to retrieval results so the agent can judge "which world is this hit
90
+ * from?" per line instead of resolving project_id block-by-block. One lookup per
91
+ * DISTINCT root. */
92
+ export function rootContextFor(db, blocks) {
93
+ const out = new Map();
94
+ for (const b of blocks) {
95
+ const pid = b.project_id;
96
+ if (!pid || typeof pid !== "string" || out.has(pid))
97
+ continue;
98
+ const root = db.getBlock(pid);
99
+ if (!root)
100
+ continue;
101
+ const ess = root.essence || "";
102
+ out.set(pid, {
103
+ root_label: root.label,
104
+ root_essence: ess.length > 100 ? ess.slice(0, 100) + "…" : ess,
105
+ });
106
+ }
107
+ return out;
108
+ }
109
+ //# sourceMappingURL=search-core.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"search-core.js","sourceRoot":"","sources":["../../src/engine/search-core.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /** Cosine similarity of two equal-length numeric vectors. Returns 0 on any
2
+ * degenerate input: null/undefined, empty, length mismatch, or a zero-magnitude
3
+ * vector. */
4
+ export declare function cosineSim(a: number[], b: number[]): number;
5
+ //# sourceMappingURL=vector-math.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector-math.d.ts","sourceRoot":"","sources":["../../src/engine/vector-math.ts"],"names":[],"mappings":"AASA;;cAEc;AACd,wBAAgB,SAAS,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,CAAC,EAAE,MAAM,EAAE,GAAG,MAAM,CAU1D"}
@@ -0,0 +1,25 @@
1
+ // ─────────────────────────────────────────────────────────────────────────────
2
+ // Vector math — the single cosine-similarity implementation.
3
+ //
4
+ // Consolidated 2026-06-14 from SEVEN divergent copies (context, pass4-slice,
5
+ // retrieve-graph-slice, stage-audit-graph, recall, database, tools/helpers) that
6
+ // computed the same value but carried different degenerate-input guards. This is
7
+ // the UNION of those guards. Pure / side-effect-free.
8
+ // ─────────────────────────────────────────────────────────────────────────────
9
+ /** Cosine similarity of two equal-length numeric vectors. Returns 0 on any
10
+ * degenerate input: null/undefined, empty, length mismatch, or a zero-magnitude
11
+ * vector. */
12
+ export function cosineSim(a, b) {
13
+ if (!a || !b || a.length === 0 || a.length !== b.length)
14
+ return 0;
15
+ let dot = 0, na = 0, nb = 0;
16
+ for (let i = 0; i < a.length; i++) {
17
+ dot += a[i] * b[i];
18
+ na += a[i] * a[i];
19
+ nb += b[i] * b[i];
20
+ }
21
+ if (na === 0 || nb === 0)
22
+ return 0;
23
+ return dot / (Math.sqrt(na) * Math.sqrt(nb));
24
+ }
25
+ //# sourceMappingURL=vector-math.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"vector-math.js","sourceRoot":"","sources":["../../src/engine/vector-math.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,6DAA6D;AAC7D,EAAE;AACF,6EAA6E;AAC7E,iFAAiF;AACjF,iFAAiF;AACjF,sDAAsD;AACtD,gFAAgF;AAEhF;;cAEc;AACd,MAAM,UAAU,SAAS,CAAC,CAAW,EAAE,CAAW;IAChD,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,IAAI,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,MAAM;QAAE,OAAO,CAAC,CAAC;IAClE,IAAI,GAAG,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,EAAE,EAAE,GAAG,CAAC,CAAC;IAC5B,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,CAAC,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QAClC,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QACnB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;QAClB,EAAE,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACpB,CAAC;IACD,IAAI,EAAE,KAAK,CAAC,IAAI,EAAE,KAAK,CAAC;QAAE,OAAO,CAAC,CAAC;IACnC,OAAO,GAAG,GAAG,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;AAC/C,CAAC"}
@@ -0,0 +1,26 @@
1
+ export declare const NODEDEX_HOME: string;
2
+ export declare const HOME_ENV_PATH: string;
3
+ /** Strip a trailing inline ` # comment` (whitespace-then-#, standard .env semantics) and
4
+ * surrounding whitespace. A bare `#` with NO preceding whitespace (e.g. a hex `#ff0000`)
5
+ * is kept as part of the value. */
6
+ export declare function stripInlineComment(value: string): string;
7
+ /** Parse a flat KEY=VALUE .env file into a map. Ignores blank lines + full-line `#`
8
+ * comments, and strips trailing inline `# comments` from values (so an annotated
9
+ * `KEY=2 # note` parses to `2`, not `2 # note` → which would `Number()`→`NaN`).
10
+ * The first `=` splits key/value (values may contain `=`). Pure / testable. */
11
+ export declare function parseEnvFile(content: string): Map<string, string>;
12
+ /** An EXISTING repo `.env`, or null. */
13
+ export declare function findExistingRepoEnv(): string | null;
14
+ /** Where the config endpoint WRITES settings: an existing repo `.env` (so dev keeps using
15
+ * server/.env) else the user-home `~/.nodedex/.env` (created on first write — the
16
+ * fresh-install target). NEVER null, so a fresh install always has somewhere to persist. */
17
+ export declare function resolveEnvWriteTarget(): string;
18
+ /** Apply a key→value map to process.env, but ONLY keys not already set (so an explicit
19
+ * env / --env-file / repo .env wins). Returns how many were applied. Pure-ish (mutates
20
+ * process.env, which is the point); separated for testability. */
21
+ export declare function applyUnsetEnv(map: Map<string, string>): number;
22
+ /** Load ~/.nodedex/.env at boot, applying only keys not already set. Returns the count
23
+ * applied (0 if the file is absent / unreadable). This is what makes web-UI-saved
24
+ * settings take effect on the next restart. `envPath` is injectable for tests. */
25
+ export declare function loadHomeEnv(envPath?: string): number;
26
+ //# sourceMappingURL=home-env.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"home-env.d.ts","sourceRoot":"","sources":["../src/home-env.ts"],"names":[],"mappings":"AAiBA,eAAO,MAAM,YAAY,QAAiC,CAAC;AAC3D,eAAO,MAAM,aAAa,QAAgC,CAAC;AAE3D;;oCAEoC;AACpC,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAGxD;AAED;;;gFAGgF;AAChF,wBAAgB,YAAY,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,CAUjE;AASD,wCAAwC;AACxC,wBAAgB,mBAAmB,IAAI,MAAM,GAAG,IAAI,CAGnD;AAED;;6FAE6F;AAC7F,wBAAgB,qBAAqB,IAAI,MAAM,CAE9C;AAED;;mEAEmE;AACnE,wBAAgB,aAAa,CAAC,GAAG,EAAE,GAAG,CAAC,MAAM,EAAE,MAAM,CAAC,GAAG,MAAM,CAM9D;AAED;;mFAEmF;AACnF,wBAAgB,WAAW,CAAC,OAAO,GAAE,MAAsB,GAAG,MAAM,CAOnE"}
@@ -0,0 +1,87 @@
1
+ // home-env.ts — the user-home config home (~/.nodedex/.env).
2
+ //
3
+ // WHY: the engine is env-var-native (every setting is read from process.env). A FRESH
4
+ // install has no repo `server/.env`, so settings set via the web-UI config endpoint had
5
+ // nowhere durable to live (applied in-memory, lost on restart). This makes ~/.nodedex/.env
6
+ // that durable home — the same ~/.nodedex/ dir that already holds reflect-pause, pidfiles,
7
+ // and the TUI config. ONE config model end-to-end (env vars), no JSON↔env mapping layer.
8
+ //
9
+ // PRECEDENCE (highest → lowest): explicit process env / --env-file (e.g. dev server/.env)
10
+ // > ~/.nodedex/.env. loadHomeEnv only fills keys NOT already set, so a dev .env or a real
11
+ // env var always wins; the home file is the fallback that a fresh install relies on.
12
+ import { homedir } from "os";
13
+ import { resolve, dirname } from "path";
14
+ import { fileURLToPath } from "url";
15
+ import { existsSync, readFileSync } from "fs";
16
+ export const NODEDEX_HOME = resolve(homedir(), ".nodedex");
17
+ export const HOME_ENV_PATH = resolve(NODEDEX_HOME, ".env");
18
+ /** Strip a trailing inline ` # comment` (whitespace-then-#, standard .env semantics) and
19
+ * surrounding whitespace. A bare `#` with NO preceding whitespace (e.g. a hex `#ff0000`)
20
+ * is kept as part of the value. */
21
+ export function stripInlineComment(value) {
22
+ const m = value.match(/\s#/);
23
+ return (m ? value.slice(0, m.index) : value).trim();
24
+ }
25
+ /** Parse a flat KEY=VALUE .env file into a map. Ignores blank lines + full-line `#`
26
+ * comments, and strips trailing inline `# comments` from values (so an annotated
27
+ * `KEY=2 # note` parses to `2`, not `2 # note` → which would `Number()`→`NaN`).
28
+ * The first `=` splits key/value (values may contain `=`). Pure / testable. */
29
+ export function parseEnvFile(content) {
30
+ const map = new Map();
31
+ for (const line of (content ?? "").split("\n")) {
32
+ const t = line.trim();
33
+ if (!t || t.startsWith("#"))
34
+ continue;
35
+ const eq = t.indexOf("=");
36
+ if (eq < 0)
37
+ continue;
38
+ map.set(t.slice(0, eq).trim(), stripInlineComment(t.slice(eq + 1)));
39
+ }
40
+ return map;
41
+ }
42
+ /** Repo `.env` candidates (the DEV file): server/.env (one level up from src|dist) or
43
+ * the cwd .env. */
44
+ function repoEnvCandidates() {
45
+ const here = dirname(fileURLToPath(import.meta.url)); // server/src or server/dist
46
+ return [resolve(here, "../.env"), resolve(process.cwd(), ".env")];
47
+ }
48
+ /** An EXISTING repo `.env`, or null. */
49
+ export function findExistingRepoEnv() {
50
+ for (const p of repoEnvCandidates())
51
+ if (existsSync(p))
52
+ return p;
53
+ return null;
54
+ }
55
+ /** Where the config endpoint WRITES settings: an existing repo `.env` (so dev keeps using
56
+ * server/.env) else the user-home `~/.nodedex/.env` (created on first write — the
57
+ * fresh-install target). NEVER null, so a fresh install always has somewhere to persist. */
58
+ export function resolveEnvWriteTarget() {
59
+ return findExistingRepoEnv() ?? HOME_ENV_PATH;
60
+ }
61
+ /** Apply a key→value map to process.env, but ONLY keys not already set (so an explicit
62
+ * env / --env-file / repo .env wins). Returns how many were applied. Pure-ish (mutates
63
+ * process.env, which is the point); separated for testability. */
64
+ export function applyUnsetEnv(map) {
65
+ let applied = 0;
66
+ for (const [k, v] of map) {
67
+ if (process.env[k] === undefined) {
68
+ process.env[k] = v;
69
+ applied++;
70
+ }
71
+ }
72
+ return applied;
73
+ }
74
+ /** Load ~/.nodedex/.env at boot, applying only keys not already set. Returns the count
75
+ * applied (0 if the file is absent / unreadable). This is what makes web-UI-saved
76
+ * settings take effect on the next restart. `envPath` is injectable for tests. */
77
+ export function loadHomeEnv(envPath = HOME_ENV_PATH) {
78
+ try {
79
+ if (!existsSync(envPath))
80
+ return 0;
81
+ return applyUnsetEnv(parseEnvFile(readFileSync(envPath, "utf8")));
82
+ }
83
+ catch {
84
+ return 0;
85
+ }
86
+ }
87
+ //# sourceMappingURL=home-env.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"home-env.js","sourceRoot":"","sources":["../src/home-env.ts"],"names":[],"mappings":"AAAA,6DAA6D;AAC7D,EAAE;AACF,sFAAsF;AACtF,wFAAwF;AACxF,2FAA2F;AAC3F,2FAA2F;AAC3F,yFAAyF;AACzF,EAAE;AACF,0FAA0F;AAC1F,0FAA0F;AAC1F,qFAAqF;AAErF,OAAO,EAAE,OAAO,EAAE,MAAM,IAAI,CAAC;AAC7B,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,EAAE,aAAa,EAAE,MAAM,KAAK,CAAC;AACpC,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,MAAM,IAAI,CAAC;AAE9C,MAAM,CAAC,MAAM,YAAY,GAAG,OAAO,CAAC,OAAO,EAAE,EAAE,UAAU,CAAC,CAAC;AAC3D,MAAM,CAAC,MAAM,aAAa,GAAG,OAAO,CAAC,YAAY,EAAE,MAAM,CAAC,CAAC;AAE3D;;oCAEoC;AACpC,MAAM,UAAU,kBAAkB,CAAC,KAAa;IAC9C,MAAM,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC;IAC7B,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,IAAI,EAAE,CAAC;AACtD,CAAC;AAED;;;gFAGgF;AAChF,MAAM,UAAU,YAAY,CAAC,OAAe;IAC1C,MAAM,GAAG,GAAG,IAAI,GAAG,EAAkB,CAAC;IACtC,KAAK,MAAM,IAAI,IAAI,CAAC,OAAO,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/C,MAAM,CAAC,GAAG,IAAI,CAAC,IAAI,EAAE,CAAC;QACtB,IAAI,CAAC,CAAC,IAAI,CAAC,CAAC,UAAU,CAAC,GAAG,CAAC;YAAE,SAAS;QACtC,MAAM,EAAE,GAAG,CAAC,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;QAC1B,IAAI,EAAE,GAAG,CAAC;YAAE,SAAS;QACrB,GAAG,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,EAAE,kBAAkB,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACtE,CAAC;IACD,OAAO,GAAG,CAAC;AACb,CAAC;AAED;oBACoB;AACpB,SAAS,iBAAiB;IACxB,MAAM,IAAI,GAAG,OAAO,CAAC,aAAa,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,4BAA4B;IAClF,OAAO,CAAC,OAAO,CAAC,IAAI,EAAE,SAAS,CAAC,EAAE,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,EAAE,MAAM,CAAC,CAAC,CAAC;AACpE,CAAC;AAED,wCAAwC;AACxC,MAAM,UAAU,mBAAmB;IACjC,KAAK,MAAM,CAAC,IAAI,iBAAiB,EAAE;QAAE,IAAI,UAAU,CAAC,CAAC,CAAC;YAAE,OAAO,CAAC,CAAC;IACjE,OAAO,IAAI,CAAC;AACd,CAAC;AAED;;6FAE6F;AAC7F,MAAM,UAAU,qBAAqB;IACnC,OAAO,mBAAmB,EAAE,IAAI,aAAa,CAAC;AAChD,CAAC;AAED;;mEAEmE;AACnE,MAAM,UAAU,aAAa,CAAC,GAAwB;IACpD,IAAI,OAAO,GAAG,CAAC,CAAC;IAChB,KAAK,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,IAAI,GAAG,EAAE,CAAC;QACzB,IAAI,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,SAAS,EAAE,CAAC;YAAC,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC;YAAC,OAAO,EAAE,CAAC;QAAC,CAAC;IACtE,CAAC;IACD,OAAO,OAAO,CAAC;AACjB,CAAC;AAED;;mFAEmF;AACnF,MAAM,UAAU,WAAW,CAAC,UAAkB,aAAa;IACzD,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC;YAAE,OAAO,CAAC,CAAC;QACnC,OAAO,aAAa,CAAC,YAAY,CAAC,YAAY,CAAC,OAAO,EAAE,MAAM,CAAC,CAAC,CAAC,CAAC;IACpE,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,CAAC;IACX,CAAC;AACH,CAAC"}
@@ -0,0 +1,13 @@
1
+ import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
2
+ import { WorkspaceDB } from "./store/database.js";
3
+ import { EmbeddingEngine } from "./engine/embeddings.js";
4
+ export declare const WORKSPACE_INSTRUCTIONS = "Nodedex is your persistent memory \u2014 a graph of what was decided, tried, ABANDONED, and constrained across sessions. You did NOT write it \u2014 a background pipeline extracts it from your conversation, so DON'T call save/write tools in normal work (they're for fixing graph errors only). READ before you act.\n\nREACH THE GRAPH ONLY THROUGH THESE TOOLS. Don't go hunting the filesystem or shell \u2014 never read Nodedex's database, log, or config files directly, and don't run raw SQL: you'd get rows stripped of the chains that carry the meaning, and you'd miss the dedup/heal the tools apply. NAVIGATE (traverse), don't blindly query. Touch the underlying DB/files ONLY if you genuinely need something no tool can reach \u2014 that's the rare exception, not the default.\n\nTWO REFLEXES \u2014 do these unprompted:\n1. BEFORE proposing ANY approach, check what already failed \u2014 suggesting something abandoned, or that breaks a constraint, is the worst outcome. \u2192 workspace_filter the approach's concepts (or workspace_get a dead_end label); read the dead_ends + constraints FIRST.\n2. When you need context, TRAVERSE \u2014 don't keyword-search. A block is a headline; the causal CHAIN it sits on is the story. Anchor on a block, then walk.\n\nTHE LOOP (traversal-first):\n- New task, no anchor? \u2192 workspace_filter(concepts) \u2014 first-principle terms of your task (technologies, mechanisms, failure-modes; NOT \"fix\"/\"issue\"). Returns relevant project ROOTS + entry blocks.\n- Know it exists but not the label? \u2192 workspace_search (fuzzy \u2014 the FALLBACK; isolated matches).\n- Know exactly what you want? \u2192 CONSTRUCT the label and get it directly: {project}_{entity}_{type}_{concept} ('_' between dimensions, '-' within a concept, entity optional).\n- Have a block? \u2192 workspace_get(label, detail=\"relations\") \u2014 returns the block PLUS the chain(s) it sits on AND the chains they lead to / rest on (the connected story). That is the unit of meaning; read it, open the next block, keep walking.\n\ndetail: surface (scan) \u2192 relations (block + its chain \u2014 the traversal default) \u2192 full. Graph knowledge is established; your own conclusions are hypotheses until the graph agrees.\n\nFirst time connecting in this project? Call workspace_onboard ONCE \u2014 it offers to persist these reflexes into your own standing config (it checks whether you can, and you explain why + ask the user first). If you can't persist, this advisory copy still applies for the session.";
5
+ /** Whether write/admin/maintenance tools are exposed (default off → read-only surface). */
6
+ export declare function writesExposed(): boolean;
7
+ /** The tool names the agent surface exposes given current env flags (for boot logging). */
8
+ export declare function agentToolAllowlist(): Set<string>;
9
+ /** Build a Workspace MCP server: instructions, read-only gating, and every tool registered.
10
+ * A fresh instance is cheap (registration is pure) — the HTTP path builds one per session;
11
+ * db + embeddings are shared singletons passed in. */
12
+ export declare function buildWorkspaceServer(db: WorkspaceDB, embeddings: EmbeddingEngine): McpServer;
13
+ //# sourceMappingURL=mcp-server.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"mcp-server.d.ts","sourceRoot":"","sources":["../src/mcp-server.ts"],"names":[],"mappings":"AAUA,OAAO,EAAE,SAAS,EAAE,MAAM,yCAAyC,CAAC;AACpE,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,eAAe,EAAE,MAAM,wBAAwB,CAAC;AAWzD,eAAO,MAAM,sBAAsB,q+EAEmP,CAAC;AAYvR,2FAA2F;AAC3F,wBAAgB,aAAa,IAAI,OAAO,CAEvC;AAED,2FAA2F;AAC3F,wBAAgB,kBAAkB,IAAI,GAAG,CAAC,MAAM,CAAC,CAMhD;AAED;;uDAEuD;AACvD,wBAAgB,oBAAoB,CAAC,EAAE,EAAE,WAAW,EAAE,UAAU,EAAE,eAAe,GAAG,SAAS,CAmC5F"}