@quolu/lattice 0.70.0 → 0.71.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 (602) hide show
  1. package/package.json +1 -1
  2. package/sensor/dist/bin/lattice-sensor.js +746 -323
  3. package/sensor/dist/bin/viewer-gate.d.ts +17 -0
  4. package/sensor/dist/bin/viewer-gate.d.ts.map +1 -0
  5. package/sensor/dist/bin/viewer-gate.js +31 -0
  6. package/sensor/dist/bin/viewer-gate.js.map +1 -0
  7. package/sensor/dist/context/formatter.d.ts +7 -1
  8. package/sensor/dist/context/formatter.d.ts.map +1 -1
  9. package/sensor/dist/context/formatter.js +12 -6
  10. package/sensor/dist/context/formatter.js.map +1 -1
  11. package/sensor/dist/context/index.d.ts +12 -0
  12. package/sensor/dist/context/index.d.ts.map +1 -1
  13. package/sensor/dist/context/index.js +103 -16
  14. package/sensor/dist/context/index.js.map +1 -1
  15. package/sensor/dist/db/index.d.ts +23 -2
  16. package/sensor/dist/db/index.d.ts.map +1 -1
  17. package/sensor/dist/db/index.js +109 -31
  18. package/sensor/dist/db/index.js.map +1 -1
  19. package/sensor/dist/db/migrations.d.ts +1 -1
  20. package/sensor/dist/db/migrations.d.ts.map +1 -1
  21. package/sensor/dist/db/migrations.js +68 -1
  22. package/sensor/dist/db/migrations.js.map +1 -1
  23. package/sensor/dist/db/queries.d.ts +583 -6
  24. package/sensor/dist/db/queries.d.ts.map +1 -1
  25. package/sensor/dist/db/queries.js +1425 -57
  26. package/sensor/dist/db/queries.js.map +1 -1
  27. package/sensor/dist/db/schema.sql +27 -4
  28. package/sensor/dist/db/sqlite-adapter.d.ts +2 -0
  29. package/sensor/dist/db/sqlite-adapter.d.ts.map +1 -1
  30. package/sensor/dist/db/sqlite-adapter.js +56 -7
  31. package/sensor/dist/db/sqlite-adapter.js.map +1 -1
  32. package/sensor/dist/db/synthesis-stage.d.ts +12 -0
  33. package/sensor/dist/db/synthesis-stage.d.ts.map +1 -0
  34. package/sensor/dist/db/synthesis-stage.js +93 -0
  35. package/sensor/dist/db/synthesis-stage.js.map +1 -0
  36. package/sensor/dist/db/wal-valve.d.ts +32 -12
  37. package/sensor/dist/db/wal-valve.d.ts.map +1 -1
  38. package/sensor/dist/db/wal-valve.js +65 -22
  39. package/sensor/dist/db/wal-valve.js.map +1 -1
  40. package/sensor/dist/db/wsl-shared-index.d.ts +53 -0
  41. package/sensor/dist/db/wsl-shared-index.d.ts.map +1 -0
  42. package/sensor/dist/db/wsl-shared-index.js +121 -0
  43. package/sensor/dist/db/wsl-shared-index.js.map +1 -0
  44. package/sensor/dist/directory.d.ts +126 -2
  45. package/sensor/dist/directory.d.ts.map +1 -1
  46. package/sensor/dist/directory.js +285 -16
  47. package/sensor/dist/directory.js.map +1 -1
  48. package/sensor/dist/errors.d.ts +14 -0
  49. package/sensor/dist/errors.d.ts.map +1 -1
  50. package/sensor/dist/errors.js +16 -1
  51. package/sensor/dist/errors.js.map +1 -1
  52. package/sensor/dist/extraction/cfml-extractor.d.ts +1 -0
  53. package/sensor/dist/extraction/cfml-extractor.d.ts.map +1 -1
  54. package/sensor/dist/extraction/cfml-extractor.js +15 -3
  55. package/sensor/dist/extraction/cfml-extractor.js.map +1 -1
  56. package/sensor/dist/extraction/dfm-extractor.d.ts.map +1 -1
  57. package/sensor/dist/extraction/dfm-extractor.js +14 -10
  58. package/sensor/dist/extraction/dfm-extractor.js.map +1 -1
  59. package/sensor/dist/extraction/extraction-version.d.ts +1 -1
  60. package/sensor/dist/extraction/extraction-version.d.ts.map +1 -1
  61. package/sensor/dist/extraction/extraction-version.js +3 -1
  62. package/sensor/dist/extraction/extraction-version.js.map +1 -1
  63. package/sensor/dist/extraction/function-ref.d.ts +6 -4
  64. package/sensor/dist/extraction/function-ref.d.ts.map +1 -1
  65. package/sensor/dist/extraction/function-ref.js +35 -14
  66. package/sensor/dist/extraction/function-ref.js.map +1 -1
  67. package/sensor/dist/extraction/generated-detection.d.ts +48 -12
  68. package/sensor/dist/extraction/generated-detection.d.ts.map +1 -1
  69. package/sensor/dist/extraction/generated-detection.js +176 -11
  70. package/sensor/dist/extraction/generated-detection.js.map +1 -1
  71. package/sensor/dist/extraction/grammars.d.ts +38 -0
  72. package/sensor/dist/extraction/grammars.d.ts.map +1 -1
  73. package/sensor/dist/extraction/grammars.js +115 -3
  74. package/sensor/dist/extraction/grammars.js.map +1 -1
  75. package/sensor/dist/extraction/index.d.ts +218 -14
  76. package/sensor/dist/extraction/index.d.ts.map +1 -1
  77. package/sensor/dist/extraction/index.js +887 -175
  78. package/sensor/dist/extraction/index.js.map +1 -1
  79. package/sensor/dist/extraction/languages/c-cpp.d.ts +58 -0
  80. package/sensor/dist/extraction/languages/c-cpp.d.ts.map +1 -1
  81. package/sensor/dist/extraction/languages/c-cpp.js +310 -19
  82. package/sensor/dist/extraction/languages/c-cpp.js.map +1 -1
  83. package/sensor/dist/extraction/languages/dart.d.ts.map +1 -1
  84. package/sensor/dist/extraction/languages/dart.js +8 -3
  85. package/sensor/dist/extraction/languages/dart.js.map +1 -1
  86. package/sensor/dist/extraction/languages/erlang.d.ts.map +1 -1
  87. package/sensor/dist/extraction/languages/erlang.js +58 -22
  88. package/sensor/dist/extraction/languages/erlang.js.map +1 -1
  89. package/sensor/dist/extraction/languages/javascript.js +1 -1
  90. package/sensor/dist/extraction/languages/javascript.js.map +1 -1
  91. package/sensor/dist/extraction/languages/kotlin.d.ts.map +1 -1
  92. package/sensor/dist/extraction/languages/kotlin.js +169 -36
  93. package/sensor/dist/extraction/languages/kotlin.js.map +1 -1
  94. package/sensor/dist/extraction/languages/lua.d.ts.map +1 -1
  95. package/sensor/dist/extraction/languages/lua.js +4 -1
  96. package/sensor/dist/extraction/languages/lua.js.map +1 -1
  97. package/sensor/dist/extraction/languages/objc.d.ts.map +1 -1
  98. package/sensor/dist/extraction/languages/objc.js +4 -0
  99. package/sensor/dist/extraction/languages/objc.js.map +1 -1
  100. package/sensor/dist/extraction/languages/python.d.ts.map +1 -1
  101. package/sensor/dist/extraction/languages/python.js +71 -0
  102. package/sensor/dist/extraction/languages/python.js.map +1 -1
  103. package/sensor/dist/extraction/languages/rust.d.ts +20 -0
  104. package/sensor/dist/extraction/languages/rust.d.ts.map +1 -1
  105. package/sensor/dist/extraction/languages/rust.js +50 -20
  106. package/sensor/dist/extraction/languages/rust.js.map +1 -1
  107. package/sensor/dist/extraction/languages/scala.d.ts.map +1 -1
  108. package/sensor/dist/extraction/languages/scala.js +18 -3
  109. package/sensor/dist/extraction/languages/scala.js.map +1 -1
  110. package/sensor/dist/extraction/languages/swift.d.ts +15 -0
  111. package/sensor/dist/extraction/languages/swift.d.ts.map +1 -1
  112. package/sensor/dist/extraction/languages/swift.js +50 -0
  113. package/sensor/dist/extraction/languages/swift.js.map +1 -1
  114. package/sensor/dist/extraction/languages/typescript.d.ts.map +1 -1
  115. package/sensor/dist/extraction/languages/typescript.js +9 -2
  116. package/sensor/dist/extraction/languages/typescript.js.map +1 -1
  117. package/sensor/dist/extraction/liquid-extractor.d.ts +18 -0
  118. package/sensor/dist/extraction/liquid-extractor.d.ts.map +1 -1
  119. package/sensor/dist/extraction/liquid-extractor.js +98 -22
  120. package/sensor/dist/extraction/liquid-extractor.js.map +1 -1
  121. package/sensor/dist/extraction/mybatis-extractor.d.ts.map +1 -1
  122. package/sensor/dist/extraction/mybatis-extractor.js +6 -4
  123. package/sensor/dist/extraction/mybatis-extractor.js.map +1 -1
  124. package/sensor/dist/extraction/parse-pool.d.ts +7 -0
  125. package/sensor/dist/extraction/parse-pool.d.ts.map +1 -1
  126. package/sensor/dist/extraction/parse-pool.js +20 -1
  127. package/sensor/dist/extraction/parse-pool.js.map +1 -1
  128. package/sensor/dist/extraction/syntax-tokens.d.ts +103 -0
  129. package/sensor/dist/extraction/syntax-tokens.d.ts.map +1 -0
  130. package/sensor/dist/extraction/syntax-tokens.js +381 -0
  131. package/sensor/dist/extraction/syntax-tokens.js.map +1 -0
  132. package/sensor/dist/extraction/tree-sitter-helpers.d.ts +5 -0
  133. package/sensor/dist/extraction/tree-sitter-helpers.d.ts.map +1 -1
  134. package/sensor/dist/extraction/tree-sitter-helpers.js +17 -0
  135. package/sensor/dist/extraction/tree-sitter-helpers.js.map +1 -1
  136. package/sensor/dist/extraction/tree-sitter-types.d.ts +31 -3
  137. package/sensor/dist/extraction/tree-sitter-types.d.ts.map +1 -1
  138. package/sensor/dist/extraction/tree-sitter.d.ts +101 -18
  139. package/sensor/dist/extraction/tree-sitter.d.ts.map +1 -1
  140. package/sensor/dist/extraction/tree-sitter.js +928 -134
  141. package/sensor/dist/extraction/tree-sitter.js.map +1 -1
  142. package/sensor/dist/extraction/wasm/tree-sitter-scala.wasm +0 -0
  143. package/sensor/dist/file-limits.d.ts +40 -0
  144. package/sensor/dist/file-limits.d.ts.map +1 -0
  145. package/sensor/dist/file-limits.js +147 -0
  146. package/sensor/dist/file-limits.js.map +1 -0
  147. package/sensor/dist/graph/branch-guards.d.ts +265 -0
  148. package/sensor/dist/graph/branch-guards.d.ts.map +1 -0
  149. package/sensor/dist/graph/branch-guards.js +2325 -0
  150. package/sensor/dist/graph/branch-guards.js.map +1 -0
  151. package/sensor/dist/graph/dead-code.d.ts +251 -0
  152. package/sensor/dist/graph/dead-code.d.ts.map +1 -0
  153. package/sensor/dist/graph/dead-code.js +776 -0
  154. package/sensor/dist/graph/dead-code.js.map +1 -0
  155. package/sensor/dist/graph/dynamic-boundary-report.d.ts +121 -0
  156. package/sensor/dist/graph/dynamic-boundary-report.d.ts.map +1 -0
  157. package/sensor/dist/graph/dynamic-boundary-report.js +283 -0
  158. package/sensor/dist/graph/dynamic-boundary-report.js.map +1 -0
  159. package/sensor/dist/graph/index.d.ts +4 -0
  160. package/sensor/dist/graph/index.d.ts.map +1 -1
  161. package/sensor/dist/graph/index.js +16 -1
  162. package/sensor/dist/graph/index.js.map +1 -1
  163. package/sensor/dist/graph/named-symbol-flow.d.ts +125 -0
  164. package/sensor/dist/graph/named-symbol-flow.d.ts.map +1 -0
  165. package/sensor/dist/graph/named-symbol-flow.js +552 -0
  166. package/sensor/dist/graph/named-symbol-flow.js.map +1 -0
  167. package/sensor/dist/graph/queries.d.ts.map +1 -1
  168. package/sensor/dist/graph/queries.js +2 -0
  169. package/sensor/dist/graph/queries.js.map +1 -1
  170. package/sensor/dist/graph/symbol-lookup.d.ts +83 -0
  171. package/sensor/dist/graph/symbol-lookup.d.ts.map +1 -0
  172. package/sensor/dist/graph/symbol-lookup.js +181 -0
  173. package/sensor/dist/graph/symbol-lookup.js.map +1 -0
  174. package/sensor/dist/graph/traversal.d.ts +9 -0
  175. package/sensor/dist/graph/traversal.d.ts.map +1 -1
  176. package/sensor/dist/graph/traversal.js +62 -36
  177. package/sensor/dist/graph/traversal.js.map +1 -1
  178. package/sensor/dist/graph/type-hierarchy.d.ts +155 -0
  179. package/sensor/dist/graph/type-hierarchy.d.ts.map +1 -0
  180. package/sensor/dist/graph/type-hierarchy.js +382 -0
  181. package/sensor/dist/graph/type-hierarchy.js.map +1 -0
  182. package/sensor/dist/index.d.ts +272 -10
  183. package/sensor/dist/index.d.ts.map +1 -1
  184. package/sensor/dist/index.js +510 -34
  185. package/sensor/dist/index.js.map +1 -1
  186. package/sensor/dist/mcp/answer-freshness.d.ts +10 -0
  187. package/sensor/dist/mcp/answer-freshness.d.ts.map +1 -0
  188. package/sensor/dist/mcp/answer-freshness.js +68 -0
  189. package/sensor/dist/mcp/answer-freshness.js.map +1 -0
  190. package/sensor/dist/mcp/daemon-manager.d.ts +1 -1
  191. package/sensor/dist/mcp/daemon-manager.d.ts.map +1 -1
  192. package/sensor/dist/mcp/daemon-manager.js +17 -1
  193. package/sensor/dist/mcp/daemon-manager.js.map +1 -1
  194. package/sensor/dist/mcp/daemon-paths.d.ts +8 -0
  195. package/sensor/dist/mcp/daemon-paths.d.ts.map +1 -1
  196. package/sensor/dist/mcp/daemon-paths.js +65 -2
  197. package/sensor/dist/mcp/daemon-paths.js.map +1 -1
  198. package/sensor/dist/mcp/daemon-registry.d.ts +17 -4
  199. package/sensor/dist/mcp/daemon-registry.d.ts.map +1 -1
  200. package/sensor/dist/mcp/daemon-registry.js +133 -23
  201. package/sensor/dist/mcp/daemon-registry.js.map +1 -1
  202. package/sensor/dist/mcp/daemon.d.ts +26 -13
  203. package/sensor/dist/mcp/daemon.d.ts.map +1 -1
  204. package/sensor/dist/mcp/daemon.js +126 -32
  205. package/sensor/dist/mcp/daemon.js.map +1 -1
  206. package/sensor/dist/mcp/dynamic-boundaries.d.ts +1 -10
  207. package/sensor/dist/mcp/dynamic-boundaries.d.ts.map +1 -1
  208. package/sensor/dist/mcp/dynamic-boundaries.js +46 -42
  209. package/sensor/dist/mcp/dynamic-boundaries.js.map +1 -1
  210. package/sensor/dist/mcp/engine.d.ts +31 -9
  211. package/sensor/dist/mcp/engine.d.ts.map +1 -1
  212. package/sensor/dist/mcp/engine.js +190 -79
  213. package/sensor/dist/mcp/engine.js.map +1 -1
  214. package/sensor/dist/mcp/explore-dedup.d.ts +140 -0
  215. package/sensor/dist/mcp/explore-dedup.d.ts.map +1 -0
  216. package/sensor/dist/mcp/explore-dedup.js +239 -0
  217. package/sensor/dist/mcp/explore-dedup.js.map +1 -0
  218. package/sensor/dist/mcp/explore-diagnostics.d.ts +289 -0
  219. package/sensor/dist/mcp/explore-diagnostics.d.ts.map +1 -0
  220. package/sensor/dist/mcp/explore-diagnostics.js +558 -0
  221. package/sensor/dist/mcp/explore-diagnostics.js.map +1 -0
  222. package/sensor/dist/mcp/explore-session-state.d.ts +217 -0
  223. package/sensor/dist/mcp/explore-session-state.d.ts.map +1 -0
  224. package/sensor/dist/mcp/explore-session-state.js +322 -0
  225. package/sensor/dist/mcp/explore-session-state.js.map +1 -0
  226. package/sensor/dist/mcp/index-freshness-worker.d.ts +2 -0
  227. package/sensor/dist/mcp/index-freshness-worker.d.ts.map +1 -0
  228. package/sensor/dist/mcp/index-freshness-worker.js +30 -0
  229. package/sensor/dist/mcp/index-freshness-worker.js.map +1 -0
  230. package/sensor/dist/mcp/index-freshness.d.ts +7 -0
  231. package/sensor/dist/mcp/index-freshness.d.ts.map +1 -0
  232. package/sensor/dist/mcp/index-freshness.js +94 -0
  233. package/sensor/dist/mcp/index-freshness.js.map +1 -0
  234. package/sensor/dist/mcp/index.d.ts +3 -1
  235. package/sensor/dist/mcp/index.d.ts.map +1 -1
  236. package/sensor/dist/mcp/index.js +109 -12
  237. package/sensor/dist/mcp/index.js.map +1 -1
  238. package/sensor/dist/mcp/liveness-watchdog.d.ts +4 -1
  239. package/sensor/dist/mcp/liveness-watchdog.d.ts.map +1 -1
  240. package/sensor/dist/mcp/liveness-watchdog.js +11 -2
  241. package/sensor/dist/mcp/liveness-watchdog.js.map +1 -1
  242. package/sensor/dist/mcp/project-lifecycle.d.ts +9 -0
  243. package/sensor/dist/mcp/project-lifecycle.d.ts.map +1 -0
  244. package/sensor/dist/mcp/project-lifecycle.js +182 -0
  245. package/sensor/dist/mcp/project-lifecycle.js.map +1 -0
  246. package/sensor/dist/mcp/proxy.d.ts.map +1 -1
  247. package/sensor/dist/mcp/proxy.js +15 -1
  248. package/sensor/dist/mcp/proxy.js.map +1 -1
  249. package/sensor/dist/mcp/query-pool.d.ts +2 -2
  250. package/sensor/dist/mcp/query-pool.d.ts.map +1 -1
  251. package/sensor/dist/mcp/query-pool.js +9 -7
  252. package/sensor/dist/mcp/query-pool.js.map +1 -1
  253. package/sensor/dist/mcp/query-worker.js +2 -2
  254. package/sensor/dist/mcp/query-worker.js.map +1 -1
  255. package/sensor/dist/mcp/server-instructions.d.ts +2 -2
  256. package/sensor/dist/mcp/server-instructions.d.ts.map +1 -1
  257. package/sensor/dist/mcp/server-instructions.js +13 -6
  258. package/sensor/dist/mcp/server-instructions.js.map +1 -1
  259. package/sensor/dist/mcp/session.d.ts +16 -0
  260. package/sensor/dist/mcp/session.d.ts.map +1 -1
  261. package/sensor/dist/mcp/session.js +36 -13
  262. package/sensor/dist/mcp/session.js.map +1 -1
  263. package/sensor/dist/mcp/startup-handshake.d.ts +3 -1
  264. package/sensor/dist/mcp/startup-handshake.d.ts.map +1 -1
  265. package/sensor/dist/mcp/startup-handshake.js +10 -2
  266. package/sensor/dist/mcp/startup-handshake.js.map +1 -1
  267. package/sensor/dist/mcp/tools.d.ts +496 -38
  268. package/sensor/dist/mcp/tools.d.ts.map +1 -1
  269. package/sensor/dist/mcp/tools.js +4021 -772
  270. package/sensor/dist/mcp/tools.js.map +1 -1
  271. package/sensor/dist/mcp/writer-lock.d.ts +61 -0
  272. package/sensor/dist/mcp/writer-lock.d.ts.map +1 -0
  273. package/sensor/dist/mcp/writer-lock.js +260 -0
  274. package/sensor/dist/mcp/writer-lock.js.map +1 -0
  275. package/sensor/dist/project-config.d.ts +23 -0
  276. package/sensor/dist/project-config.d.ts.map +1 -1
  277. package/sensor/dist/project-config.js +39 -2
  278. package/sensor/dist/project-config.js.map +1 -1
  279. package/sensor/dist/resolution/alias-binding.d.ts +56 -0
  280. package/sensor/dist/resolution/alias-binding.d.ts.map +1 -0
  281. package/sensor/dist/resolution/alias-binding.js +127 -0
  282. package/sensor/dist/resolution/alias-binding.js.map +1 -0
  283. package/sensor/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -1
  284. package/sensor/dist/resolution/c-fnptr-synthesizer.js +21 -19
  285. package/sensor/dist/resolution/c-fnptr-synthesizer.js.map +1 -1
  286. package/sensor/dist/resolution/callback-synthesizer.d.ts +23 -1
  287. package/sensor/dist/resolution/callback-synthesizer.d.ts.map +1 -1
  288. package/sensor/dist/resolution/callback-synthesizer.js +356 -155
  289. package/sensor/dist/resolution/callback-synthesizer.js.map +1 -1
  290. package/sensor/dist/resolution/cpp-constructor.d.ts +4 -0
  291. package/sensor/dist/resolution/cpp-constructor.d.ts.map +1 -0
  292. package/sensor/dist/resolution/cpp-constructor.js +123 -0
  293. package/sensor/dist/resolution/cpp-constructor.js.map +1 -0
  294. package/sensor/dist/resolution/cpp-macro-visibility.d.ts +12 -0
  295. package/sensor/dist/resolution/cpp-macro-visibility.d.ts.map +1 -0
  296. package/sensor/dist/resolution/cpp-macro-visibility.js +342 -0
  297. package/sensor/dist/resolution/cpp-macro-visibility.js.map +1 -0
  298. package/sensor/dist/resolution/expo-router-synthesizer.d.ts +32 -0
  299. package/sensor/dist/resolution/expo-router-synthesizer.d.ts.map +1 -0
  300. package/sensor/dist/resolution/expo-router-synthesizer.js +189 -0
  301. package/sensor/dist/resolution/expo-router-synthesizer.js.map +1 -0
  302. package/sensor/dist/resolution/frameworks/csharp.d.ts.map +1 -1
  303. package/sensor/dist/resolution/frameworks/csharp.js +96 -2
  304. package/sensor/dist/resolution/frameworks/csharp.js.map +1 -1
  305. package/sensor/dist/resolution/frameworks/expo-router.d.ts +189 -0
  306. package/sensor/dist/resolution/frameworks/expo-router.d.ts.map +1 -0
  307. package/sensor/dist/resolution/frameworks/expo-router.js +785 -0
  308. package/sensor/dist/resolution/frameworks/expo-router.js.map +1 -0
  309. package/sensor/dist/resolution/frameworks/express.d.ts.map +1 -1
  310. package/sensor/dist/resolution/frameworks/express.js +251 -16
  311. package/sensor/dist/resolution/frameworks/express.js.map +1 -1
  312. package/sensor/dist/resolution/frameworks/index.d.ts +5 -0
  313. package/sensor/dist/resolution/frameworks/index.d.ts.map +1 -1
  314. package/sensor/dist/resolution/frameworks/index.js +29 -1
  315. package/sensor/dist/resolution/frameworks/index.js.map +1 -1
  316. package/sensor/dist/resolution/frameworks/java.d.ts.map +1 -1
  317. package/sensor/dist/resolution/frameworks/java.js +79 -47
  318. package/sensor/dist/resolution/frameworks/java.js.map +1 -1
  319. package/sensor/dist/resolution/frameworks/laravel.d.ts.map +1 -1
  320. package/sensor/dist/resolution/frameworks/laravel.js +294 -4
  321. package/sensor/dist/resolution/frameworks/laravel.js.map +1 -1
  322. package/sensor/dist/resolution/frameworks/nestjs.d.ts.map +1 -1
  323. package/sensor/dist/resolution/frameworks/nestjs.js +6 -14
  324. package/sensor/dist/resolution/frameworks/nestjs.js.map +1 -1
  325. package/sensor/dist/resolution/frameworks/nextjs.d.ts +76 -0
  326. package/sensor/dist/resolution/frameworks/nextjs.d.ts.map +1 -0
  327. package/sensor/dist/resolution/frameworks/nextjs.js +328 -0
  328. package/sensor/dist/resolution/frameworks/nextjs.js.map +1 -0
  329. package/sensor/dist/resolution/frameworks/object-literal.d.ts +32 -0
  330. package/sensor/dist/resolution/frameworks/object-literal.d.ts.map +1 -0
  331. package/sensor/dist/resolution/frameworks/object-literal.js +139 -0
  332. package/sensor/dist/resolution/frameworks/object-literal.js.map +1 -0
  333. package/sensor/dist/resolution/frameworks/package-deps.d.ts +14 -0
  334. package/sensor/dist/resolution/frameworks/package-deps.d.ts.map +1 -0
  335. package/sensor/dist/resolution/frameworks/package-deps.js +78 -0
  336. package/sensor/dist/resolution/frameworks/package-deps.js.map +1 -0
  337. package/sensor/dist/resolution/frameworks/python.d.ts.map +1 -1
  338. package/sensor/dist/resolution/frameworks/python.js +166 -0
  339. package/sensor/dist/resolution/frameworks/python.js.map +1 -1
  340. package/sensor/dist/resolution/frameworks/react-native.d.ts +26 -0
  341. package/sensor/dist/resolution/frameworks/react-native.d.ts.map +1 -1
  342. package/sensor/dist/resolution/frameworks/react-native.js +153 -14
  343. package/sensor/dist/resolution/frameworks/react-native.js.map +1 -1
  344. package/sensor/dist/resolution/frameworks/react-router.d.ts +46 -0
  345. package/sensor/dist/resolution/frameworks/react-router.d.ts.map +1 -0
  346. package/sensor/dist/resolution/frameworks/react-router.js +187 -0
  347. package/sensor/dist/resolution/frameworks/react-router.js.map +1 -0
  348. package/sensor/dist/resolution/frameworks/react.d.ts +2 -1
  349. package/sensor/dist/resolution/frameworks/react.d.ts.map +1 -1
  350. package/sensor/dist/resolution/frameworks/react.js +188 -139
  351. package/sensor/dist/resolution/frameworks/react.js.map +1 -1
  352. package/sensor/dist/resolution/frameworks/svelte.d.ts.map +1 -1
  353. package/sensor/dist/resolution/frameworks/svelte.js +6 -1
  354. package/sensor/dist/resolution/frameworks/svelte.js.map +1 -1
  355. package/sensor/dist/resolution/frameworks/sveltekit-router.d.ts +36 -0
  356. package/sensor/dist/resolution/frameworks/sveltekit-router.d.ts.map +1 -0
  357. package/sensor/dist/resolution/frameworks/sveltekit-router.js +156 -0
  358. package/sensor/dist/resolution/frameworks/sveltekit-router.js.map +1 -0
  359. package/sensor/dist/resolution/frameworks/swift.d.ts.map +1 -1
  360. package/sensor/dist/resolution/frameworks/swift.js +140 -99
  361. package/sensor/dist/resolution/frameworks/swift.js.map +1 -1
  362. package/sensor/dist/resolution/frameworks/tanstack-router.d.ts +84 -0
  363. package/sensor/dist/resolution/frameworks/tanstack-router.d.ts.map +1 -0
  364. package/sensor/dist/resolution/frameworks/tanstack-router.js +437 -0
  365. package/sensor/dist/resolution/frameworks/tanstack-router.js.map +1 -0
  366. package/sensor/dist/resolution/frameworks/vue-router.d.ts +82 -0
  367. package/sensor/dist/resolution/frameworks/vue-router.d.ts.map +1 -0
  368. package/sensor/dist/resolution/frameworks/vue-router.js +377 -0
  369. package/sensor/dist/resolution/frameworks/vue-router.js.map +1 -0
  370. package/sensor/dist/resolution/import-resolver.d.ts +38 -0
  371. package/sensor/dist/resolution/import-resolver.d.ts.map +1 -1
  372. package/sensor/dist/resolution/import-resolver.js +394 -28
  373. package/sensor/dist/resolution/import-resolver.js.map +1 -1
  374. package/sensor/dist/resolution/index.d.ts +89 -25
  375. package/sensor/dist/resolution/index.d.ts.map +1 -1
  376. package/sensor/dist/resolution/index.js +573 -148
  377. package/sensor/dist/resolution/index.js.map +1 -1
  378. package/sensor/dist/resolution/js-builtins.d.ts +13 -0
  379. package/sensor/dist/resolution/js-builtins.d.ts.map +1 -0
  380. package/sensor/dist/resolution/js-builtins.js +46 -0
  381. package/sensor/dist/resolution/js-builtins.js.map +1 -0
  382. package/sensor/dist/resolution/name-matcher.d.ts +99 -22
  383. package/sensor/dist/resolution/name-matcher.d.ts.map +1 -1
  384. package/sensor/dist/resolution/name-matcher.js +2220 -86
  385. package/sensor/dist/resolution/name-matcher.js.map +1 -1
  386. package/sensor/dist/resolution/next-router-synthesizer.d.ts +27 -0
  387. package/sensor/dist/resolution/next-router-synthesizer.d.ts.map +1 -0
  388. package/sensor/dist/resolution/next-router-synthesizer.js +113 -0
  389. package/sensor/dist/resolution/next-router-synthesizer.js.map +1 -0
  390. package/sensor/dist/resolution/path-aliases.d.ts +6 -4
  391. package/sensor/dist/resolution/path-aliases.d.ts.map +1 -1
  392. package/sensor/dist/resolution/path-aliases.js +125 -17
  393. package/sensor/dist/resolution/path-aliases.js.map +1 -1
  394. package/sensor/dist/resolution/react-router-synthesizer.d.ts +33 -0
  395. package/sensor/dist/resolution/react-router-synthesizer.d.ts.map +1 -0
  396. package/sensor/dist/resolution/react-router-synthesizer.js +126 -0
  397. package/sensor/dist/resolution/react-router-synthesizer.js.map +1 -0
  398. package/sensor/dist/resolution/resolver-pool.d.ts +2 -0
  399. package/sensor/dist/resolution/resolver-pool.d.ts.map +1 -1
  400. package/sensor/dist/resolution/resolver-pool.js +4 -0
  401. package/sensor/dist/resolution/resolver-pool.js.map +1 -1
  402. package/sensor/dist/resolution/strip-comments.d.ts +6 -0
  403. package/sensor/dist/resolution/strip-comments.d.ts.map +1 -1
  404. package/sensor/dist/resolution/strip-comments.js +58 -0
  405. package/sensor/dist/resolution/strip-comments.js.map +1 -1
  406. package/sensor/dist/resolution/sveltekit-synthesizer.d.ts +58 -0
  407. package/sensor/dist/resolution/sveltekit-synthesizer.d.ts.map +1 -0
  408. package/sensor/dist/resolution/sveltekit-synthesizer.js +173 -0
  409. package/sensor/dist/resolution/sveltekit-synthesizer.js.map +1 -0
  410. package/sensor/dist/resolution/swift-type-visibility.d.ts +52 -0
  411. package/sensor/dist/resolution/swift-type-visibility.d.ts.map +1 -0
  412. package/sensor/dist/resolution/swift-type-visibility.js +328 -0
  413. package/sensor/dist/resolution/swift-type-visibility.js.map +1 -0
  414. package/sensor/dist/resolution/synth-utils.d.ts +26 -0
  415. package/sensor/dist/resolution/synth-utils.d.ts.map +1 -0
  416. package/sensor/dist/resolution/synth-utils.js +75 -0
  417. package/sensor/dist/resolution/synth-utils.js.map +1 -0
  418. package/sensor/dist/resolution/tanstack-router-synthesizer.d.ts +31 -0
  419. package/sensor/dist/resolution/tanstack-router-synthesizer.d.ts.map +1 -0
  420. package/sensor/dist/resolution/tanstack-router-synthesizer.js +114 -0
  421. package/sensor/dist/resolution/tanstack-router-synthesizer.js.map +1 -0
  422. package/sensor/dist/resolution/tier-synthesizer.d.ts +54 -0
  423. package/sensor/dist/resolution/tier-synthesizer.d.ts.map +1 -0
  424. package/sensor/dist/resolution/tier-synthesizer.js +1294 -0
  425. package/sensor/dist/resolution/tier-synthesizer.js.map +1 -0
  426. package/sensor/dist/resolution/types.d.ts +78 -2
  427. package/sensor/dist/resolution/types.d.ts.map +1 -1
  428. package/sensor/dist/resolution/types.js +64 -0
  429. package/sensor/dist/resolution/types.js.map +1 -1
  430. package/sensor/dist/resolution/vue-router-synthesizer.d.ts +30 -0
  431. package/sensor/dist/resolution/vue-router-synthesizer.d.ts.map +1 -0
  432. package/sensor/dist/resolution/vue-router-synthesizer.js +115 -0
  433. package/sensor/dist/resolution/vue-router-synthesizer.js.map +1 -0
  434. package/sensor/dist/search/identifier-segments.d.ts +10 -0
  435. package/sensor/dist/search/identifier-segments.d.ts.map +1 -1
  436. package/sensor/dist/search/identifier-segments.js +29 -0
  437. package/sensor/dist/search/identifier-segments.js.map +1 -1
  438. package/sensor/dist/search/query-paths.d.ts +106 -0
  439. package/sensor/dist/search/query-paths.d.ts.map +1 -0
  440. package/sensor/dist/search/query-paths.js +513 -0
  441. package/sensor/dist/search/query-paths.js.map +1 -0
  442. package/sensor/dist/search/query-utils.d.ts +22 -2
  443. package/sensor/dist/search/query-utils.d.ts.map +1 -1
  444. package/sensor/dist/search/query-utils.js +56 -16
  445. package/sensor/dist/search/query-utils.js.map +1 -1
  446. package/sensor/dist/sync/watch-policy.d.ts +14 -0
  447. package/sensor/dist/sync/watch-policy.d.ts.map +1 -1
  448. package/sensor/dist/sync/watch-policy.js +19 -0
  449. package/sensor/dist/sync/watch-policy.js.map +1 -1
  450. package/sensor/dist/sync/watcher.d.ts +74 -35
  451. package/sensor/dist/sync/watcher.d.ts.map +1 -1
  452. package/sensor/dist/sync/watcher.js +281 -99
  453. package/sensor/dist/sync/watcher.js.map +1 -1
  454. package/sensor/dist/telemetry/index.d.ts +4 -2
  455. package/sensor/dist/telemetry/index.d.ts.map +1 -1
  456. package/sensor/dist/telemetry/index.js +92 -41
  457. package/sensor/dist/telemetry/index.js.map +1 -1
  458. package/sensor/dist/types.d.ts +18 -2
  459. package/sensor/dist/types.d.ts.map +1 -1
  460. package/sensor/dist/types.js +2 -0
  461. package/sensor/dist/types.js.map +1 -1
  462. package/sensor/dist/ui-server/api/deadcode.d.ts +84 -0
  463. package/sensor/dist/ui-server/api/deadcode.d.ts.map +1 -0
  464. package/sensor/dist/ui-server/api/deadcode.js +136 -0
  465. package/sensor/dist/ui-server/api/deadcode.js.map +1 -0
  466. package/sensor/dist/ui-server/api/effects.d.ts +94 -0
  467. package/sensor/dist/ui-server/api/effects.d.ts.map +1 -0
  468. package/sensor/dist/ui-server/api/effects.js +527 -0
  469. package/sensor/dist/ui-server/api/effects.js.map +1 -0
  470. package/sensor/dist/ui-server/api/entrypoints.d.ts +92 -0
  471. package/sensor/dist/ui-server/api/entrypoints.d.ts.map +1 -0
  472. package/sensor/dist/ui-server/api/entrypoints.js +361 -0
  473. package/sensor/dist/ui-server/api/entrypoints.js.map +1 -0
  474. package/sensor/dist/ui-server/api/events.d.ts +183 -0
  475. package/sensor/dist/ui-server/api/events.d.ts.map +1 -0
  476. package/sensor/dist/ui-server/api/events.js +430 -0
  477. package/sensor/dist/ui-server/api/events.js.map +1 -0
  478. package/sensor/dist/ui-server/api/file.d.ts +66 -0
  479. package/sensor/dist/ui-server/api/file.d.ts.map +1 -0
  480. package/sensor/dist/ui-server/api/file.js +235 -0
  481. package/sensor/dist/ui-server/api/file.js.map +1 -0
  482. package/sensor/dist/ui-server/api/filecode.d.ts +126 -0
  483. package/sensor/dist/ui-server/api/filecode.d.ts.map +1 -0
  484. package/sensor/dist/ui-server/api/filecode.js +205 -0
  485. package/sensor/dist/ui-server/api/filecode.js.map +1 -0
  486. package/sensor/dist/ui-server/api/flow.d.ts +226 -0
  487. package/sensor/dist/ui-server/api/flow.d.ts.map +1 -0
  488. package/sensor/dist/ui-server/api/flow.js +612 -0
  489. package/sensor/dist/ui-server/api/flow.js.map +1 -0
  490. package/sensor/dist/ui-server/api/hierarchy.d.ts +81 -0
  491. package/sensor/dist/ui-server/api/hierarchy.d.ts.map +1 -0
  492. package/sensor/dist/ui-server/api/hierarchy.js +92 -0
  493. package/sensor/dist/ui-server/api/hierarchy.js.map +1 -0
  494. package/sensor/dist/ui-server/api/index.d.ts +90 -0
  495. package/sensor/dist/ui-server/api/index.d.ts.map +1 -0
  496. package/sensor/dist/ui-server/api/index.js +332 -0
  497. package/sensor/dist/ui-server/api/index.js.map +1 -0
  498. package/sensor/dist/ui-server/api/map.d.ts +256 -0
  499. package/sensor/dist/ui-server/api/map.d.ts.map +1 -0
  500. package/sensor/dist/ui-server/api/map.js +760 -0
  501. package/sensor/dist/ui-server/api/map.js.map +1 -0
  502. package/sensor/dist/ui-server/api/node.d.ts +81 -0
  503. package/sensor/dist/ui-server/api/node.d.ts.map +1 -0
  504. package/sensor/dist/ui-server/api/node.js +388 -0
  505. package/sensor/dist/ui-server/api/node.js.map +1 -0
  506. package/sensor/dist/ui-server/api/nodes.d.ts +25 -0
  507. package/sensor/dist/ui-server/api/nodes.d.ts.map +1 -0
  508. package/sensor/dist/ui-server/api/nodes.js +45 -0
  509. package/sensor/dist/ui-server/api/nodes.js.map +1 -0
  510. package/sensor/dist/ui-server/api/program.d.ts +139 -0
  511. package/sensor/dist/ui-server/api/program.d.ts.map +1 -0
  512. package/sensor/dist/ui-server/api/program.js +315 -0
  513. package/sensor/dist/ui-server/api/program.js.map +1 -0
  514. package/sensor/dist/ui-server/api/respond.d.ts +76 -0
  515. package/sensor/dist/ui-server/api/respond.d.ts.map +1 -0
  516. package/sensor/dist/ui-server/api/respond.js +186 -0
  517. package/sensor/dist/ui-server/api/respond.js.map +1 -0
  518. package/sensor/dist/ui-server/api/route-roots.d.ts +39 -0
  519. package/sensor/dist/ui-server/api/route-roots.d.ts.map +1 -0
  520. package/sensor/dist/ui-server/api/route-roots.js +96 -0
  521. package/sensor/dist/ui-server/api/route-roots.js.map +1 -0
  522. package/sensor/dist/ui-server/api/routes.d.ts +59 -0
  523. package/sensor/dist/ui-server/api/routes.d.ts.map +1 -0
  524. package/sensor/dist/ui-server/api/routes.js +108 -0
  525. package/sensor/dist/ui-server/api/routes.js.map +1 -0
  526. package/sensor/dist/ui-server/api/screens.d.ts +117 -0
  527. package/sensor/dist/ui-server/api/screens.d.ts.map +1 -0
  528. package/sensor/dist/ui-server/api/screens.js +611 -0
  529. package/sensor/dist/ui-server/api/screens.js.map +1 -0
  530. package/sensor/dist/ui-server/api/search.d.ts +29 -0
  531. package/sensor/dist/ui-server/api/search.d.ts.map +1 -0
  532. package/sensor/dist/ui-server/api/search.js +232 -0
  533. package/sensor/dist/ui-server/api/search.js.map +1 -0
  534. package/sensor/dist/ui-server/api/session.d.ts +52 -0
  535. package/sensor/dist/ui-server/api/session.d.ts.map +1 -0
  536. package/sensor/dist/ui-server/api/session.js +196 -0
  537. package/sensor/dist/ui-server/api/session.js.map +1 -0
  538. package/sensor/dist/ui-server/api/source.d.ts +200 -0
  539. package/sensor/dist/ui-server/api/source.d.ts.map +1 -0
  540. package/sensor/dist/ui-server/api/source.js +422 -0
  541. package/sensor/dist/ui-server/api/source.js.map +1 -0
  542. package/sensor/dist/ui-server/api/stats.d.ts +27 -0
  543. package/sensor/dist/ui-server/api/stats.d.ts.map +1 -0
  544. package/sensor/dist/ui-server/api/stats.js +164 -0
  545. package/sensor/dist/ui-server/api/stats.js.map +1 -0
  546. package/sensor/dist/ui-server/api/steps.d.ts +274 -0
  547. package/sensor/dist/ui-server/api/steps.d.ts.map +1 -0
  548. package/sensor/dist/ui-server/api/steps.js +1544 -0
  549. package/sensor/dist/ui-server/api/steps.js.map +1 -0
  550. package/sensor/dist/ui-server/api/trail-store.d.ts +142 -0
  551. package/sensor/dist/ui-server/api/trail-store.d.ts.map +1 -0
  552. package/sensor/dist/ui-server/api/trail-store.js +325 -0
  553. package/sensor/dist/ui-server/api/trail-store.js.map +1 -0
  554. package/sensor/dist/ui-server/api/trails.d.ts +163 -0
  555. package/sensor/dist/ui-server/api/trails.d.ts.map +1 -0
  556. package/sensor/dist/ui-server/api/trails.js +369 -0
  557. package/sensor/dist/ui-server/api/trails.js.map +1 -0
  558. package/sensor/dist/ui-server/api/when.d.ts +133 -0
  559. package/sensor/dist/ui-server/api/when.d.ts.map +1 -0
  560. package/sensor/dist/ui-server/api/when.js +275 -0
  561. package/sensor/dist/ui-server/api/when.js.map +1 -0
  562. package/sensor/dist/ui-server/api/wire.d.ts +179 -0
  563. package/sensor/dist/ui-server/api/wire.d.ts.map +1 -0
  564. package/sensor/dist/ui-server/api/wire.js +231 -0
  565. package/sensor/dist/ui-server/api/wire.js.map +1 -0
  566. package/sensor/dist/ui-server/assets.d.ts +40 -0
  567. package/sensor/dist/ui-server/assets.d.ts.map +1 -0
  568. package/sensor/dist/ui-server/assets.js +110 -0
  569. package/sensor/dist/ui-server/assets.js.map +1 -0
  570. package/sensor/dist/ui-server/constants.d.ts +32 -0
  571. package/sensor/dist/ui-server/constants.d.ts.map +1 -0
  572. package/sensor/dist/ui-server/constants.js +35 -0
  573. package/sensor/dist/ui-server/constants.js.map +1 -0
  574. package/sensor/dist/ui-server/highlight/index.d.ts +113 -0
  575. package/sensor/dist/ui-server/highlight/index.d.ts.map +1 -0
  576. package/sensor/dist/ui-server/highlight/index.js +307 -0
  577. package/sensor/dist/ui-server/highlight/index.js.map +1 -0
  578. package/sensor/dist/ui-server/highlight/languages.d.ts +36 -0
  579. package/sensor/dist/ui-server/highlight/languages.d.ts.map +1 -0
  580. package/sensor/dist/ui-server/highlight/languages.js +50 -0
  581. package/sensor/dist/ui-server/highlight/languages.js.map +1 -0
  582. package/sensor/dist/ui-server/index.d.ts +92 -0
  583. package/sensor/dist/ui-server/index.d.ts.map +1 -0
  584. package/sensor/dist/ui-server/index.js +399 -0
  585. package/sensor/dist/ui-server/index.js.map +1 -0
  586. package/sensor/dist/ui-server/open-browser.d.ts +31 -0
  587. package/sensor/dist/ui-server/open-browser.d.ts.map +1 -0
  588. package/sensor/dist/ui-server/open-browser.js +79 -0
  589. package/sensor/dist/ui-server/open-browser.js.map +1 -0
  590. package/sensor/dist/ui-server/security.d.ts +127 -0
  591. package/sensor/dist/ui-server/security.d.ts.map +1 -0
  592. package/sensor/dist/ui-server/security.js +332 -0
  593. package/sensor/dist/ui-server/security.js.map +1 -0
  594. package/sensor/dist/ui-server/static.d.ts +45 -0
  595. package/sensor/dist/ui-server/static.d.ts.map +1 -0
  596. package/sensor/dist/ui-server/static.js +165 -0
  597. package/sensor/dist/ui-server/static.js.map +1 -0
  598. package/sensor/dist/utils.d.ts +14 -2
  599. package/sensor/dist/utils.d.ts.map +1 -1
  600. package/sensor/dist/utils.js +25 -10
  601. package/sensor/dist/utils.js.map +1 -1
  602. package/src/sensor-adapter.mjs +5 -1
@@ -41,8 +41,12 @@ var __importStar = (this && this.__importStar) || (function () {
41
41
  var __exportStar = (this && this.__exportStar) || function(m, exports) {
42
42
  for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
43
43
  };
44
+ var __importDefault = (this && this.__importDefault) || function (mod) {
45
+ return (mod && mod.__esModule) ? mod : { "default": mod };
46
+ };
44
47
  Object.defineProperty(exports, "__esModule", { value: true });
45
48
  exports.LatticeSensor = exports.MCPServer = exports.LockUnavailableError = exports.FileWatcher = exports.MemoryMonitor = exports.throttle = exports.debounce = exports.processInBatches = exports.FileLock = exports.Mutex = exports.defaultLogger = exports.silentLogger = exports.getLogger = exports.setLogger = exports.ConfigError = exports.VectorError = exports.SearchError = exports.DatabaseError = exports.ParseError = exports.FileError = exports.LatticeSensorError = exports.loadAllGrammars = exports.loadGrammarsForLanguages = exports.initGrammars = exports.getSupportedLanguages = exports.isGrammarLoaded = exports.isLanguageSupported = exports.detectLanguage = exports.LATTICE_SENSOR_DIR = exports.findNearestLatticeSensorRoot = exports.isInitialized = exports.getLatticeSensorDir = exports.QueryBuilder = exports.DatabaseConnection = exports.getDatabasePath = void 0;
49
+ const fs = __importStar(require("fs"));
46
50
  const path = __importStar(require("path"));
47
51
  const db_1 = require("./db");
48
52
  const wal_valve_1 = require("./db/wal-valve");
@@ -50,6 +54,7 @@ const queries_1 = require("./db/queries");
50
54
  const directory_1 = require("./directory");
51
55
  const extraction_1 = require("./extraction");
52
56
  const resolution_1 = require("./resolution");
57
+ const callback_synthesizer_1 = require("./resolution/callback-synthesizer");
53
58
  const graph_1 = require("./graph");
54
59
  const context_1 = require("./context");
55
60
  const utils_1 = require("./utils");
@@ -57,6 +62,8 @@ const sync_1 = require("./sync");
57
62
  const extraction_version_1 = require("./extraction/extraction-version");
58
63
  const directory_2 = require("./directory");
59
64
  const query_utils_1 = require("./search/query-utils");
65
+ const ignore_1 = __importDefault(require("ignore"));
66
+ const project_config_1 = require("./project-config");
60
67
  const version_1 = require("./mcp/version");
61
68
  const identifier_segments_1 = require("./search/identifier-segments");
62
69
  const cooperative_yield_1 = require("./resolution/cooperative-yield");
@@ -154,12 +161,64 @@ class LatticeSensor {
154
161
  catch {
155
162
  // Best-effort: ranking still works without it.
156
163
  }
164
+ // Down-weight the peripheral trees the project named in `lattice-sensor.json`
165
+ // `deprioritize` — indexed and findable, but never outranking real code
166
+ // (#982). Ranking-only, so a bad pattern costs relevance, never recall.
167
+ //
168
+ // Read LAZILY, not once here: `wireLayers` runs from the constructor and
169
+ // from `reopenIfReplaced`, so a matcher built here would freeze at whatever
170
+ // the config said when the project opened. The MCP server caches one
171
+ // LatticeSensor per root for its whole lifetime, so editing `lattice-sensor.json`
172
+ // would appear to do nothing until the process restarted — `exclude` and
173
+ // `include` do not behave that way. `loadDeprioritizePatterns` is
174
+ // mtime-cached, so this costs one `stat`; the compiled matcher is memoized
175
+ // on the pattern array's identity, which the cache keeps stable.
176
+ let cachedPatterns;
177
+ let cachedMatcher;
178
+ this.queries.setDeprioritizedPathMatcher((filePath) => {
179
+ try {
180
+ const patterns = (0, project_config_1.loadDeprioritizePatterns)(this.projectRoot);
181
+ if (patterns.length === 0)
182
+ return false;
183
+ if (patterns !== cachedPatterns) {
184
+ cachedPatterns = patterns;
185
+ cachedMatcher = (0, ignore_1.default)().add(patterns);
186
+ }
187
+ const rel = path.isAbsolute(filePath)
188
+ ? path.relative(this.projectRoot, filePath)
189
+ : filePath;
190
+ if (!rel || rel.startsWith('..'))
191
+ return false;
192
+ return cachedMatcher.ignores(rel.split(path.sep).join('/'));
193
+ }
194
+ catch {
195
+ // Ranking must never take the search down with it.
196
+ return false;
197
+ }
198
+ });
157
199
  this.orchestrator = new extraction_1.ExtractionOrchestrator(this.projectRoot, this.queries);
158
200
  this.resolver = (0, resolution_1.createResolver)(this.projectRoot, this.queries);
159
201
  this.graphManager = new graph_1.GraphQueryManager(this.queries);
160
202
  this.traverser = new graph_1.GraphTraverser(this.queries);
161
203
  this.contextBuilder = (0, context_1.createContextBuilder)(this.projectRoot, this.queries, this.traverser);
162
204
  }
205
+ /**
206
+ * Set when this instance followed a database replaced on disk (#1902): the
207
+ * next sync that can run reconciles the whole tree, because whatever the old
208
+ * handle absorbed since the rebuild never reached the new file.
209
+ */
210
+ pendingFullReconcile = false;
211
+ /** How long a recreated, not-yet-indexed database is treated as a rebuild in progress. */
212
+ static RECREATE_GRACE_MS = 120_000;
213
+ /** The database file at the path was written within the recreate grace window. */
214
+ isFreshlyRecreated() {
215
+ try {
216
+ return Date.now() - fs.statSync((0, db_1.getDatabasePath)(this.projectRoot)).mtimeMs < LatticeSensor.RECREATE_GRACE_MS;
217
+ }
218
+ catch {
219
+ return false;
220
+ }
221
+ }
163
222
  /**
164
223
  * Heal a stale database handle in place. If `.lattice/sensor/` was removed and
165
224
  * recreated at the SAME path while this instance held the DB open — a git
@@ -173,19 +232,33 @@ class LatticeSensor {
173
232
  *
174
233
  * POSIX-only in practice: `isReplacedOnDisk` never fires on Windows (an open
175
234
  * file can't be unlinked there, and st_ino is unreliable).
235
+ *
236
+ * Refuses (returns false) while an index/sync holds the index mutex: closing
237
+ * the handle that run is writing through would break it mid-flight. `sync()`
238
+ * performs the same check itself once it holds the mutex (#1902), so the
239
+ * replaced file is still picked up — by that sync, or by the caller's retry.
176
240
  */
177
241
  reopenIfReplaced() {
242
+ if (this.indexMutex.isLocked())
243
+ return false;
244
+ return this.reopenReplacedDatabase();
245
+ }
246
+ /** The body of {@link reopenIfReplaced}, without the in-flight-sync guard. */
247
+ reopenReplacedDatabase() {
178
248
  if (!this.db.isReplacedOnDisk())
179
249
  return false;
180
250
  const dbPath = this.db.getPath();
181
251
  // Open the live file FIRST — if that throws (e.g. mid-recreate), the old
182
252
  // handle stays in place and the caller retries on the next query, rather
183
253
  // than leaving this instance with no connection at all.
184
- const fresh = db_1.DatabaseConnection.open(dbPath);
254
+ const fresh = db_1.DatabaseConnection.open(dbPath, { readOnly: this.db.readOnly });
185
255
  const stale = this.db;
186
256
  this.db = fresh;
187
257
  this.queries = new queries_1.QueryBuilder(fresh.getDb());
188
258
  this.wireLayers();
259
+ // Whoever reopened — a sync, or a tool call's self-heal — the next sync
260
+ // must reconcile the whole tree (#1902).
261
+ this.pendingFullReconcile = true;
189
262
  // Releasing the dead handle also frees the leaked db/-wal/-shm fds that were
190
263
  // pinning the unlinked inode (#925).
191
264
  try {
@@ -264,12 +337,18 @@ class LatticeSensor {
264
337
  }
265
338
  // Open database
266
339
  const dbPath = (0, db_1.getDatabasePath)(resolvedRoot);
267
- const db = db_1.DatabaseConnection.open(dbPath);
340
+ const db = db_1.DatabaseConnection.open(dbPath, { readOnly: options.readOnly });
268
341
  const queries = new queries_1.QueryBuilder(db.getDb());
269
342
  const instance = new LatticeSensor(db, queries, resolvedRoot);
270
343
  // Sync if requested
271
- if (options.sync) {
272
- await instance.sync();
344
+ if (options.sync && !options.readOnly) {
345
+ try {
346
+ await instance.sync();
347
+ }
348
+ catch (err) {
349
+ instance.destroy();
350
+ throw err;
351
+ }
273
352
  }
274
353
  return instance;
275
354
  }
@@ -318,7 +397,7 @@ class LatticeSensor {
318
397
  /**
319
398
  * Open synchronously (without sync)
320
399
  */
321
- static openSync(projectRoot) {
400
+ static openSync(projectRoot, options = {}) {
322
401
  const resolvedRoot = path.resolve(projectRoot);
323
402
  // Check if initialized
324
403
  if (!(0, directory_1.isInitialized)(resolvedRoot)) {
@@ -331,7 +410,7 @@ class LatticeSensor {
331
410
  }
332
411
  // Open database
333
412
  const dbPath = (0, db_1.getDatabasePath)(resolvedRoot);
334
- const db = db_1.DatabaseConnection.open(dbPath);
413
+ const db = db_1.DatabaseConnection.open(dbPath, { readOnly: options.readOnly });
335
414
  const queries = new queries_1.QueryBuilder(db.getDb());
336
415
  return new LatticeSensor(db, queries, resolvedRoot);
337
416
  }
@@ -409,6 +488,7 @@ class LatticeSensor {
409
488
  walValve.start();
410
489
  }
411
490
  try {
491
+ const gitState = this.orchestrator.beginGitIndexState(true);
412
492
  const before = this.queries.getNodeAndEdgeCount();
413
493
  // Mark the index as in-flight BEFORE any writes: a run killed
414
494
  // mid-index (OOM, SIGKILL, the #850 liveness watchdog) leaves this
@@ -594,6 +674,10 @@ class LatticeSensor {
594
674
  }
595
675
  catch { /* metadata is advisory — never fail an index over it */ }
596
676
  }
677
+ if (result.success && result.filesErrored === 0 &&
678
+ (result.filesDiscovered === undefined || result.filesIndexed + result.filesSkipped >= result.filesDiscovered)) {
679
+ this.orchestrator.finishGitIndexState(gitState, true);
680
+ }
597
681
  // Reconcile the scan's ground truth against what the pipeline
598
682
  // accounted for. A shortfall means files were silently dropped
599
683
  // (observed in the wild: a run under heavy load came up 37 files
@@ -680,7 +764,8 @@ class LatticeSensor {
680
764
  });
681
765
  }
682
766
  /**
683
- * Sync with current file state (incremental update)
767
+ * Sync with current file state (incremental update).
768
+ * Throws LockUnavailableError if the cross-process write lock is unavailable.
684
769
  *
685
770
  * Uses a mutex to prevent concurrent indexing operations.
686
771
  */
@@ -689,8 +774,40 @@ class LatticeSensor {
689
774
  try {
690
775
  this.fileLock.acquire();
691
776
  }
692
- catch {
693
- return { filesChecked: 0, filesAdded: 0, filesModified: 0, filesRemoved: 0, nodesUpdated: 0, durationMs: 0 };
777
+ catch (err) {
778
+ throw new sync_1.LockUnavailableError(`Sync could not acquire the file lock; retry when the index is available. ${err instanceof Error ? err.message : String(err)}`);
779
+ }
780
+ // A full rebuild in another process (`lattice sensor index` → recreate)
781
+ // unlinks the database and creates a new file at the same path. A
782
+ // long-lived instance — the MCP daemon's watcher — would otherwise keep
783
+ // "syncing" into the dead inode, and nothing it wrote there is visible
784
+ // to anyone (#1902). Follow the path before writing (one stat), and
785
+ // widen a scoped sync to a full one: whatever the old handle absorbed
786
+ // since the rebuild is gone, so the new file has to be reconciled whole.
787
+ // If the reopen fails (the rebuild is mid-way), report lock contention
788
+ // so the watcher keeps its pending files and retries.
789
+ try {
790
+ this.reopenReplacedDatabase();
791
+ }
792
+ catch (err) {
793
+ this.fileLock.release();
794
+ throw new sync_1.LockUnavailableError(`Sync could not open the rebuilt index yet; retry when the rebuild finishes. ${err instanceof Error ? err.message : String(err)}`);
795
+ }
796
+ if (this.pendingFullReconcile) {
797
+ // `lattice sensor index` recreates the file, THEN takes the write lock in
798
+ // indexAll. A sync landing in that gap would otherwise run a full
799
+ // reconcile of the empty file and hold the lock the rebuild is about
800
+ // to ask for. A fresh file with no index_state yet is that rebuild:
801
+ // step aside (lock contention, the watcher retries) and reconcile in
802
+ // full once it is done. Bounded, so a rebuild that died before
803
+ // indexing does not park the watcher forever.
804
+ if (this.getIndexState() === null && this.isFreshlyRecreated()) {
805
+ this.fileLock.release();
806
+ throw new sync_1.LockUnavailableError('A rebuild of this index is in progress; retry when it finishes.');
807
+ }
808
+ // Cleared only once this run completes (below): a sync that throws
809
+ // must leave the full catch-up for the next one.
810
+ options = { ...options, paths: undefined };
694
811
  }
695
812
  // Defer WAL auto-checkpointing for the whole incremental run, exactly
696
813
  // as indexAll does for the bulk path (#1231): sync's store loop and its
@@ -725,7 +842,28 @@ class LatticeSensor {
725
842
  return false;
726
843
  }
727
844
  })();
728
- const result = await this.orchestrator.sync(options.onProgress, options.paths);
845
+ // Writer-side backstop for deferred WAL checkpointing (#1539): sync
846
+ // previously armed the valve but never called backpressure(), so the
847
+ // hard/file caps were never enforced during daemon catch-up — only
848
+ // timer-driven PASSIVE checkpoints ran, and a query-pool reader could
849
+ // pin frames while the WAL grew without a bound.
850
+ const backpressure = walValve ? () => walValve.backpressure() : undefined;
851
+ const fullReconcile = !options.paths || options.paths.length === 0;
852
+ const gitState = this.orchestrator.beginGitIndexState(fullReconcile);
853
+ // An interrupted index may have absorbed its changed files before
854
+ // resolution/synthesis. Detect those orphans BEFORE this sync adds refs.
855
+ let refreshSynthesis = this.queries.getMetadata('synthesis_pending') === '1' ||
856
+ this.queries.getUnresolvedReferencesCount() > 0;
857
+ if (refreshSynthesis)
858
+ this.queries.setMetadata('synthesis_pending', '1');
859
+ const result = await this.orchestrator.sync(options.onProgress, options.paths, backpressure, (filePath, content) => {
860
+ if (!refreshSynthesis && (this.queries.hasSynthesizedEdgesTouchingFile(filePath) ||
861
+ this.queries.wasSynthesisInput(filePath) ||
862
+ (content !== undefined && (0, callback_synthesizer_1.hasSynthesisPattern)(filePath, content)))) {
863
+ refreshSynthesis = true;
864
+ this.queries.setMetadata('synthesis_pending', '1');
865
+ }
866
+ });
729
867
  // Fold the store phase's WAL BEFORE the post-store reads below
730
868
  // (resolution reads on the main thread) — same rationale as
731
869
  // indexAll's fold between store and resolution.
@@ -816,7 +954,27 @@ class LatticeSensor {
816
954
  current: done,
817
955
  total: totalPasses,
818
956
  });
819
- });
957
+ }, backpressure, false);
958
+ }
959
+ }
960
+ // Re-open resolution edges this sync may have invalidated ELSEWHERE in
961
+ // the repo (CG-33). Everything above re-resolves references in the
962
+ // changed files; this covers the opposite direction — references in
963
+ // files the sync never touched whose answer depended on a definition
964
+ // that just appeared or disappeared. Without it a synced index never
965
+ // converges to a full rebuild: measured at 4.3% of distinct edges wrong
966
+ // on lattice sensor's own index, in both directions, mostly `calls`. The
967
+ // resurrected refs are pending rows, so the orphan sweep immediately
968
+ // below is what resolves them — batched, yielding, multi-pass, exactly
969
+ // as a full index resolves.
970
+ //
971
+ // `definitionDelta` is empty for a body-only edit, so the overwhelmingly
972
+ // common sync pays one branch. LATTICE_SENSOR_NO_REBIND=1 disables it.
973
+ if (result.definitionDelta && process.env.LATTICE_SENSOR_NO_REBIND !== '1') {
974
+ const tRebind = Date.now();
975
+ const rebound = this.orchestrator.resurrectStaleResolutionEdges(result.definitionDelta, result.changedFilePaths ?? []);
976
+ if (process.env.LATTICE_SENSOR_SYNTH_TIMINGS) {
977
+ console.error(`[phase-timing] sync-rebind: ${Date.now() - tRebind}ms (${result.definitionDelta.length} changed names, ${rebound} edges re-opened)`);
820
978
  }
821
979
  }
822
980
  // Orphan sweep (#1187). A resolution pass that dies mid-run — the #850
@@ -832,6 +990,9 @@ class LatticeSensor {
832
990
  // Grind them down with the batched resolver; this also makes a bare
833
991
  // `lattice sensor sync` the recovery command for a wedged index. On a
834
992
  // healthy index this is one COUNT query.
993
+ result.pendingRefsProcessed = 0;
994
+ result.pendingRefsResolved = 0;
995
+ result.pendingRefsUnresolved = 0;
835
996
  const orphanCount = this.queries.getUnresolvedReferencesCount();
836
997
  if (orphanCount > 0) {
837
998
  options.onProgress?.({
@@ -839,7 +1000,7 @@ class LatticeSensor {
839
1000
  current: 0,
840
1001
  total: orphanCount,
841
1002
  });
842
- await this.resolveReferencesBatched((current, total) => {
1003
+ const recovery = await this.resolveReferencesBatched((current, total) => {
843
1004
  options.onProgress?.({
844
1005
  phase: 'resolving',
845
1006
  current,
@@ -851,7 +1012,10 @@ class LatticeSensor {
851
1012
  current: done,
852
1013
  total: totalPasses,
853
1014
  });
854
- });
1015
+ }, backpressure, false);
1016
+ result.pendingRefsProcessed = recovery.stats.total;
1017
+ result.pendingRefsResolved = recovery.stats.resolved;
1018
+ result.pendingRefsUnresolved = recovery.stats.unresolved;
855
1019
  }
856
1020
  if (filesChanged || orphanCount > 0) {
857
1021
  // Second pass: chained calls whose method lives on a supertype the
@@ -862,9 +1026,15 @@ class LatticeSensor {
862
1026
  // member is inherited from a supertype (#808).
863
1027
  await this.resolver.resolveDeferredThisMemberRefs();
864
1028
  }
1029
+ if (refreshSynthesis) {
1030
+ await this.resolver.refreshSynthesis(this.db.getPath(), (done, total) => {
1031
+ options.onProgress?.({ phase: 'linking', current: done, total });
1032
+ }, backpressure);
1033
+ this.queries.setMetadata('synthesis_pending', '0');
1034
+ }
865
1035
  // Refresh planner stats + checkpoint the WAL after bulk writes.
866
1036
  // Off-thread — see indexAll's call site.
867
- if (filesChanged || result.filesRemoved > 0 || orphanCount > 0) {
1037
+ if (filesChanged || result.filesRemoved > 0 || orphanCount > 0 || refreshSynthesis) {
868
1038
  await this.db.runMaintenance();
869
1039
  }
870
1040
  // Heal the segment vocabulary on indexes built before the table
@@ -879,6 +1049,18 @@ class LatticeSensor {
879
1049
  }
880
1050
  }
881
1051
  catch { /* vocab is advisory — never fail a sync over it */ }
1052
+ // A killed full index leaves this marker at `indexing`. Sync repairs
1053
+ // missing files, pending refs, and (on open) dropped indexes, so a
1054
+ // successful recovery must also close the metadata state (#1556).
1055
+ if (fullReconcile && this.getIndexState() === 'indexing') {
1056
+ try {
1057
+ this.queries.setMetadata('index_state', 'complete');
1058
+ }
1059
+ catch { /* advisory */ }
1060
+ }
1061
+ this.orchestrator.finishGitIndexState(gitState, fullReconcile, result.failedFilePaths);
1062
+ if (fullReconcile && result.filesChecked > 0)
1063
+ this.pendingFullReconcile = false;
882
1064
  return result;
883
1065
  }
884
1066
  finally {
@@ -909,6 +1091,29 @@ class LatticeSensor {
909
1091
  // ===========================================================================
910
1092
  // File Watching
911
1093
  // ===========================================================================
1094
+ /**
1095
+ * Whether an OS watcher event points at a file whose index metadata is still
1096
+ * current. Used on Windows to discard NTFS last-access notifications, which
1097
+ * libuv reports through fs.watch as ordinary change events (#1451).
1098
+ */
1099
+ isIndexedFileStateCurrent(filePath) {
1100
+ const tracked = this.queries.getFileByPath(filePath);
1101
+ if (!tracked)
1102
+ return false;
1103
+ try {
1104
+ const stat = fs.statSync(path.join(this.projectRoot, filePath));
1105
+ return (stat.isFile() &&
1106
+ Number.isFinite(stat.mtimeMs) &&
1107
+ Number.isFinite(tracked.modifiedAt) &&
1108
+ stat.size === tracked.size &&
1109
+ Math.floor(stat.mtimeMs) === Math.floor(tracked.modifiedAt));
1110
+ }
1111
+ catch {
1112
+ // Missing/inaccessible files must still reach sync so removals and
1113
+ // transient filesystem failures are reconciled rather than hidden.
1114
+ return false;
1115
+ }
1116
+ }
912
1117
  /**
913
1118
  * Start watching for file changes and auto-syncing.
914
1119
  *
@@ -923,17 +1128,11 @@ class LatticeSensor {
923
1128
  return true;
924
1129
  this.watcher = new sync_1.FileWatcher(this.projectRoot, async (paths) => {
925
1130
  const result = await this.sync({ paths });
926
- // sync() returns this exact zero-shape iff it failed to acquire the
927
- // file lock (a real empty sync always has filesChecked > 0 because
928
- // scanDirectory ran). Surface that to the watcher as a typed error
929
- // so it keeps pendingFiles + reschedules instead of clearing them
930
- // (#449).
931
- if (result.filesChecked === 0 && result.durationMs === 0) {
932
- throw new sync_1.LockUnavailableError();
933
- }
934
1131
  const filesChanged = result.filesAdded + result.filesModified + result.filesRemoved;
935
1132
  return { filesChanged, durationMs: result.durationMs };
936
- }, options);
1133
+ }, options, process.platform === 'win32'
1134
+ ? (filePath) => this.isIndexedFileStateCurrent(filePath)
1135
+ : undefined);
937
1136
  return this.watcher.start();
938
1137
  }
939
1138
  /**
@@ -952,12 +1151,11 @@ class LatticeSensor {
952
1151
  return this.watcher?.isActive() ?? false;
953
1152
  }
954
1153
  /**
955
- * True once live watching has permanently degraded (OS watch-resource
956
- * exhaustion, or a write lock held past the retry budget) and auto-sync is
957
- * disabled until the next {@link watch} call. Distinct from `!isWatching()`:
958
- * a stopped/never-started watcher is inactive but NOT degraded. MCP tools use
959
- * this to surface a whole-index "results may be stale" notice, since
960
- * `getPendingFiles()` goes empty once watching stops (#876).
1154
+ * True once live watching has degraded, or while a re-armed watcher has not
1155
+ * completed its full catch-up. Distinct from `!isWatching()`: a stopped or
1156
+ * never-started watcher is inactive but NOT degraded. MCP tools use this for
1157
+ * a whole-index stale notice, since pending files are lost when watching
1158
+ * stops (#876, #1959).
961
1159
  */
962
1160
  isWatcherDegraded() {
963
1161
  return this.watcher?.isDegraded() ?? false;
@@ -966,6 +1164,14 @@ class LatticeSensor {
966
1164
  getWatcherDegradedReason() {
967
1165
  return this.watcher?.getDegradedReason() ?? null;
968
1166
  }
1167
+ /** Re-arm a lock-degraded watcher; its stale state persists until a full sync. */
1168
+ rearmWatcherAfterLockContention() {
1169
+ return this.watcher?.rearmAfterLockContention() ?? false;
1170
+ }
1171
+ /** True while a re-armed watcher owes a full reconcile of missed changes. */
1172
+ isWatcherRecovering() {
1173
+ return this.watcher?.isRecoveringFromLock() ?? false;
1174
+ }
969
1175
  /**
970
1176
  * Files seen by the file watcher since the last successful sync —
971
1177
  * the per-file "stale" signal MCP tools attach to responses so an agent
@@ -1003,6 +1209,40 @@ class LatticeSensor {
1003
1209
  getLastIndexedAt() {
1004
1210
  return this.queries.getLastIndexedAt();
1005
1211
  }
1212
+ /**
1213
+ * How far the last sync got and how many files it left behind — the cheapest
1214
+ * marker of "has this index moved". One query; safe to call on every
1215
+ * filesystem event a live viewer sees.
1216
+ */
1217
+ getIndexRevision() {
1218
+ return this.queries.getIndexRevision();
1219
+ }
1220
+ /**
1221
+ * Files re-indexed strictly after `since`, newest first — what a sync just
1222
+ * picked up. `total` is the real count, `paths` is capped at `limit`.
1223
+ */
1224
+ getFilesIndexedSince(since, limit) {
1225
+ return this.queries.getFilesIndexedSince(since, limit);
1226
+ }
1227
+ /**
1228
+ * Forget everything held in memory about rows another process may have
1229
+ * changed.
1230
+ *
1231
+ * The query layer keeps an LRU of nodes by id, invalidated by writes made
1232
+ * through THIS instance — which is exactly right for a process that owns the
1233
+ * index, and wrong for one that is only reading a database somebody else is
1234
+ * writing. A long-lived reader (the `lattice sensor ui` server, a daemon holding a
1235
+ * graph open across an agent's edits) will otherwise answer `getNode(id)`
1236
+ * with a row a sync deleted minutes ago, while every SQL-backed query beside
1237
+ * it reports the truth — a disagreement that reads as a bug in whichever
1238
+ * screen shows both.
1239
+ *
1240
+ * Cheap (clearing a bounded Map) and safe to call whenever the database file
1241
+ * looks like it moved.
1242
+ */
1243
+ dropReadCaches() {
1244
+ this.queries.clearCache();
1245
+ }
1006
1246
  /**
1007
1247
  * Completeness of the last full index run. `'complete'` is the only good
1008
1248
  * state. `'indexing'` after the fact means a run was killed mid-index (OOM,
@@ -1087,7 +1327,7 @@ class LatticeSensor {
1087
1327
  // resolution is timer-driven passive checkpoints, which the pool's
1088
1328
  // continuous reads keep perpetually partial — the WAL then accretes the
1089
1329
  // whole phase's write volume (22GB on a 4.6GB DB at kernel scale).
1090
- backpressure) {
1330
+ backpressure, synthesize = true) {
1091
1331
  return this.resolver.resolveAndPersistBatched(onProgress, undefined, onSynthesisProgress, {
1092
1332
  dbPath: this.db.getPath(),
1093
1333
  // Bulk-edge-load hooks: on big runs the resolver drops the non-unique
@@ -1097,14 +1337,15 @@ class LatticeSensor {
1097
1337
  // just degrade to scans until the recreate.
1098
1338
  bulkEdgeLoad: {
1099
1339
  begin: () => this.db.beginBulkEdgeLoad(),
1100
- end: () => this.db.endBulkEdgeLoad(),
1340
+ end: () => this.db.endBulkEdgeLoad({ deferSynthesisSite: true }),
1341
+ deferred: () => this.db.createSynthesisSiteIndex(),
1101
1342
  },
1102
1343
  refIndexLoad: {
1103
1344
  begin: () => this.db.beginBulkRefLoad(),
1104
1345
  end: () => this.db.endBulkRefLoad(),
1105
1346
  },
1106
1347
  backpressure,
1107
- });
1348
+ }, synthesize);
1108
1349
  }
1109
1350
  /**
1110
1351
  * References extracted but never attempted by a resolution pass. Zero on a
@@ -1166,12 +1407,188 @@ class LatticeSensor {
1166
1407
  getNode(id) {
1167
1408
  return this.queries.getNodeById(id);
1168
1409
  }
1410
+ /**
1411
+ * Get many nodes by id in ONE round-trip (LRU-cache aware).
1412
+ *
1413
+ * The batch form of {@link getNode}. Anything resolving a list of edges to
1414
+ * their endpoints — a caller list, a callee rail, an impact set — must use
1415
+ * this rather than a `getNode` per edge: a symbol with 500 callers is 500
1416
+ * queries otherwise. Ids that name nothing are simply absent from the map.
1417
+ */
1418
+ getNodesByIds(ids) {
1419
+ return this.queries.getNodesByIds(ids);
1420
+ }
1421
+ /**
1422
+ * Every symbol carrying an exact qualified name.
1423
+ *
1424
+ * The identity that survives a re-index. A node's id contains its start line,
1425
+ * so any edit ABOVE a symbol gives it a different id — anything that has to
1426
+ * name the same symbol across two indexes (a saved trail, a bookmark, a
1427
+ * review comment) has to key on this instead, and then disambiguate the
1428
+ * result by kind and file. Index-backed; unlike
1429
+ * {@link GraphQueryManager.findByQualifiedName} it takes no pattern and scans
1430
+ * nothing.
1431
+ */
1432
+ getNodesByQualifiedName(qualifiedName) {
1433
+ return this.queries.getNodesByQualifiedNameExact(qualifiedName);
1434
+ }
1435
+ /**
1436
+ * Outgoing edges for many source nodes at once — the batch form of
1437
+ * {@link getOutgoingEdges}. See {@link QueryBuilder.getOutgoingEdgesFrom}.
1438
+ */
1439
+ getOutgoingEdgesFrom(nodeIds, kinds) {
1440
+ return this.queries.getOutgoingEdgesFrom(nodeIds, kinds);
1441
+ }
1442
+ /**
1443
+ * Fan-in (incoming edge count) for many nodes at once — the "hub" signal,
1444
+ * without a query per node. See {@link QueryBuilder.countIncomingEdges}.
1445
+ */
1446
+ getFanIn(ids) {
1447
+ return this.queries.countIncomingEdges(ids);
1448
+ }
1449
+ /**
1450
+ * Incoming edges for many target nodes at once — the mirror of
1451
+ * {@link getOutgoingEdgesFrom}. See {@link QueryBuilder.getIncomingEdgesTo}.
1452
+ */
1453
+ getIncomingEdgesTo(nodeIds, kinds) {
1454
+ return this.queries.getIncomingEdgesTo(nodeIds, kinds);
1455
+ }
1456
+ /**
1457
+ * Fan-out (outgoing edge count) for many nodes at once — the mirror of
1458
+ * {@link getFanIn}. See {@link QueryBuilder.countOutgoingEdges}.
1459
+ */
1460
+ getFanOut(ids) {
1461
+ return this.queries.countOutgoingEdges(ids);
1462
+ }
1463
+ /**
1464
+ * Symbols nothing in the index points at, by kind — the candidate set the
1465
+ * dead code report (`src/graph/dead-code.ts`) applies its exclusions to.
1466
+ *
1467
+ * Every edge kind except `contains` counts as a reference, so a method is
1468
+ * not "reached" by the class that holds it. An unreferenced symbol is not
1469
+ * yet a dead one: see {@link buildDeadCodeReport}.
1470
+ */
1471
+ getUnreferencedNodes(kinds, limit) {
1472
+ return this.queries.getUnreferencedNodes(kinds, limit);
1473
+ }
1474
+ /**
1475
+ * Which of the given names are carried by more than one symbol, at least one
1476
+ * of which something references — the names a "nothing reaches this" claim
1477
+ * must not be made about, because the resolver may have picked the twin.
1478
+ */
1479
+ getAmbiguousReferencedNames(names) {
1480
+ return this.queries.getAmbiguousReferencedNames(names);
1481
+ }
1482
+ /**
1483
+ * Which of the given languages this index records an export marker for. A
1484
+ * language with none has no "reachable from outside" signal at all.
1485
+ */
1486
+ getLanguagesWithExports(languages) {
1487
+ return this.queries.getLanguagesWithExports(languages);
1488
+ }
1489
+ /**
1490
+ * Which of the given names the index holds an unresolved reference to — the
1491
+ * resolver saw the name and could not decide what it meant. A symbol with
1492
+ * such a name can never be called unreferenced.
1493
+ */
1494
+ getUnresolvedNamesAmong(names) {
1495
+ return this.queries.getUnresolvedNamesAmong(names);
1496
+ }
1497
+ /**
1498
+ * Which of the given symbols extend or implement a type outside the index —
1499
+ * an ancestor the resolver could not follow, so it has no edge (#1973).
1500
+ */
1501
+ getUnresolvedSupertypeSourcesAmong(nodeIds) {
1502
+ return this.queries.getUnresolvedSupertypeSourcesAmong(nodeIds);
1503
+ }
1504
+ /**
1505
+ * The symbols with the most distinct dependents, most first — the index's
1506
+ * hubs. Distinct dependents, not edges: a helper called forty times from one
1507
+ * function has one dependent, and it is dependents a blast radius grows from.
1508
+ */
1509
+ getTopDependedOn(limit) {
1510
+ return this.queries.getTopDependedOn(limit);
1511
+ }
1512
+ /**
1513
+ * The graph's executable roots — files that run something at module level (a
1514
+ * CLI, a worker entry, a script), ranked by calls x the number of other files
1515
+ * they reach. A statement at the top level of a file is recorded as an edge
1516
+ * out of the *file* node, which is what makes these visible at all.
1517
+ */
1518
+ getTopCallingFiles(limit) {
1519
+ return this.queries.getTopCallingFiles(limit);
1520
+ }
1521
+ /**
1522
+ * How many other files depend on each of the given files, counted through
1523
+ * their symbols (an `imports` edge points at the symbol, not the file).
1524
+ * A zero means nothing else in the index reaches into that file.
1525
+ */
1526
+ getFileDependentCounts(filePaths) {
1527
+ return new Map(this.queries.getFileDependentCounts(filePaths).map((row) => [row.filePath, row.dependents]));
1528
+ }
1529
+ /**
1530
+ * How far each of the given files reaches out: distinct other files their
1531
+ * symbols touch, and how many references that is. The mirror of
1532
+ * {@link getFileDependentCounts}; a test file's reach is what it exercises.
1533
+ */
1534
+ getFileReachCounts(filePaths) {
1535
+ return new Map(this.queries
1536
+ .getFileReachCounts(filePaths)
1537
+ .map((row) => [row.filePath, { reaches: row.reaches, refs: row.refs }]));
1538
+ }
1539
+ /** The `file` nodes for the given paths, in one query. */
1540
+ getFileNodes(filePaths) {
1541
+ return this.queries.getFileNodes(filePaths);
1542
+ }
1543
+ /**
1544
+ * Roll the edge table up to module granularity, for a file → module
1545
+ * assignment the caller decides.
1546
+ *
1547
+ * The architecture map's single query: cross-module edge counts by kind,
1548
+ * the `declared` subset of each (see {@link QueryBuilder.aggregateModuleGraph}),
1549
+ * and the busiest symbol pairs behind each link. Read-only, and bounded by
1550
+ * the number of modules rather than the number of edges.
1551
+ */
1552
+ getModuleAggregation(assignments, options) {
1553
+ return this.queries.aggregateModuleGraph(assignments, options);
1554
+ }
1555
+ /**
1556
+ * Every ordered pair of files where one reaches into the other — the edge
1557
+ * list a cycle finder runs on. See {@link QueryBuilder.getCrossFileDependencyPairs}.
1558
+ */
1559
+ getFileDependencyPairs(minConfidence = 0) {
1560
+ return this.queries.getCrossFileDependencyPairs(minConfidence);
1561
+ }
1562
+ /**
1563
+ * References from a symbol that never resolved to an indexed node — the
1564
+ * calls and type mentions that leave the index. Lets a reader account for
1565
+ * the call sites that have no callee row instead of implying there are none.
1566
+ */
1567
+ getUnresolvedReferencesFrom(nodeId) {
1568
+ return this.queries.getUnresolvedReferencesFrom(nodeId);
1569
+ }
1570
+ /**
1571
+ * The same, for every symbol in a FILE at once, in line order.
1572
+ *
1573
+ * One indexed lookup instead of one per symbol — the whole-file reader needs
1574
+ * it for every line it draws. See
1575
+ * {@link QueryBuilder.getUnresolvedReferencesInFile}.
1576
+ */
1577
+ getUnresolvedReferencesInFile(filePath, limit) {
1578
+ return this.queries.getUnresolvedReferencesInFile(filePath, limit);
1579
+ }
1169
1580
  /**
1170
1581
  * Get all nodes in a file
1171
1582
  */
1172
1583
  getNodesInFile(filePath) {
1173
1584
  return this.queries.getNodesByFile(filePath);
1174
1585
  }
1586
+ /**
1587
+ * Get all nodes in several files, in one batched query.
1588
+ */
1589
+ getNodesInFiles(filePaths) {
1590
+ return this.queries.getNodesByFiles(filePaths);
1591
+ }
1175
1592
  /**
1176
1593
  * Get all nodes of a specific kind
1177
1594
  */
@@ -1206,6 +1623,10 @@ class LatticeSensor {
1206
1623
  searchNodes(query, options) {
1207
1624
  return this.queries.searchNodes(query, options);
1208
1625
  }
1626
+ /** Lexical evidence for an empty explore result; does not alter retrieval. */
1627
+ getExploreMissDiagnostics(query) {
1628
+ return this.queries.getExploreMissDiagnostics(query);
1629
+ }
1209
1630
  /**
1210
1631
  * Graph-derived prompt matching for the front-load hook's MEDIUM tier:
1211
1632
  * which indexed symbols do these prose words name? "state machine des
@@ -1447,6 +1868,34 @@ class LatticeSensor {
1447
1868
  getFiles() {
1448
1869
  return this.queries.getAllFiles();
1449
1870
  }
1871
+ /**
1872
+ * A `(path) => boolean` generated-file test over a BOUNDED candidate list,
1873
+ * unioning the index-time content-banner flag with the filename convention
1874
+ * (#1500). One query up front, O(1) per call after — built for use inside a
1875
+ * ranking comparator, where re-querying per comparison would be quadratic.
1876
+ *
1877
+ * Pass every path you might ask about; a path outside the list falls back to
1878
+ * the filename check alone.
1879
+ */
1880
+ generatedFilePredicate(filePaths) {
1881
+ return this.queries.generatedPredicateFor(filePaths);
1882
+ }
1883
+ /**
1884
+ * A `(path) => boolean` ambient-declaration test over a BOUNDED candidate
1885
+ * list: true for a file that declares nothing but types, originates no call
1886
+ * edge, and that nothing in the index depends on — an ambient `.d.ts` of
1887
+ * global shims, vendored typings, module augmentation (CG-28). Structural
1888
+ * rather than extension-based, and deliberately narrow: see
1889
+ * `QueryBuilder.getAmbientDeclarationPathsAmong` for why each condition is
1890
+ * there, in particular why a `types.ts` the codebase imports is NOT flagged.
1891
+ */
1892
+ ambientDeclarationFilePredicate(filePaths) {
1893
+ return this.queries.ambientDeclarationPredicateFor(filePaths);
1894
+ }
1895
+ /** How many indexed files are flagged tool-generated. Reported by `status`. */
1896
+ getGeneratedFileCount() {
1897
+ return this.queries.countGeneratedFiles();
1898
+ }
1450
1899
  // ===========================================================================
1451
1900
  // Graph Query Methods
1452
1901
  // ===========================================================================
@@ -1601,7 +2050,17 @@ class LatticeSensor {
1601
2050
  return this.graphManager.findCircularDependencies();
1602
2051
  }
1603
2052
  /**
1604
- * Find dead code (unreferenced symbols)
2053
+ * Find unreferenced symbols — the RAW candidate set.
2054
+ *
2055
+ * Non-exported symbols of the given kinds with no incoming edge but
2056
+ * `contains`. That is a fact, not a claim: on this engine's own index it
2057
+ * returns ~2 500 symbols, of which about 20 are actually unreachable. The
2058
+ * rest are overrides, framework registrations, mis-resolved twins and
2059
+ * references the extractor never recorded.
2060
+ *
2061
+ * For a list anybody should act on, use `buildDeadCodeReport` from
2062
+ * `src/graph/dead-code.ts`, which applies the exclusions and counts every one
2063
+ * of them. This method is kept as-is because it is a published API.
1605
2064
  *
1606
2065
  * @param kinds - Node kinds to check (default: functions, methods, classes)
1607
2066
  * @returns Array of unreferenced nodes
@@ -1643,7 +2102,24 @@ class LatticeSensor {
1643
2102
  * @returns Subgraph of relevant nodes and edges
1644
2103
  */
1645
2104
  async findRelevantContext(query, options) {
1646
- return this.contextBuilder.findRelevantContext(query, options);
2105
+ // Segment-vocab supplement: FTS keeps camelCase names as single tokens,
2106
+ // so a word-level query ("auto-scroll to bottom") can never reach
2107
+ // `pinFeedIfNearBottom` through search alone. Resolve the query's words
2108
+ // against name_segment_vocab (same precision rules as the prompt hook:
2109
+ // co-occurrence, else rare singles, verified against live nodes) and hand
2110
+ // the names down as dampened exact-name seeds. Callers that pass their
2111
+ // own seedNames keep them; failures degrade to no supplement.
2112
+ let seedNames = options?.seedNames;
2113
+ if (seedNames === undefined) {
2114
+ try {
2115
+ seedNames = this.getSegmentMatches((0, identifier_segments_1.extractSegmentSearchWords)(query), 8)
2116
+ .map((m) => m.name);
2117
+ }
2118
+ catch {
2119
+ seedNames = [];
2120
+ }
2121
+ }
2122
+ return this.contextBuilder.findRelevantContext(query, { ...options, seedNames });
1647
2123
  }
1648
2124
  /**
1649
2125
  * Build context for a task