@aroman22/codegraph-vba-darwin-arm64 1.5.2 → 1.6.1

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 (335) hide show
  1. package/bin/codegraph +5 -0
  2. package/lib/dist/bin/codegraph.d.ts +1 -1
  3. package/lib/dist/bin/codegraph.d.ts.map +1 -1
  4. package/lib/dist/bin/codegraph.js +307 -81
  5. package/lib/dist/bin/codegraph.js.map +1 -1
  6. package/lib/dist/bin/command-supervision.d.ts +38 -1
  7. package/lib/dist/bin/command-supervision.d.ts.map +1 -1
  8. package/lib/dist/bin/command-supervision.js +22 -3
  9. package/lib/dist/bin/command-supervision.js.map +1 -1
  10. package/lib/dist/db/index.d.ts +84 -5
  11. package/lib/dist/db/index.d.ts.map +1 -1
  12. package/lib/dist/db/index.js +209 -12
  13. package/lib/dist/db/index.js.map +1 -1
  14. package/lib/dist/db/migrations.d.ts +1 -1
  15. package/lib/dist/db/migrations.d.ts.map +1 -1
  16. package/lib/dist/db/migrations.js +80 -3
  17. package/lib/dist/db/migrations.js.map +1 -1
  18. package/lib/dist/db/queries.d.ts +116 -4
  19. package/lib/dist/db/queries.d.ts.map +1 -1
  20. package/lib/dist/db/queries.js +294 -7
  21. package/lib/dist/db/queries.js.map +1 -1
  22. package/lib/dist/db/schema.sql +43 -1
  23. package/lib/dist/db/wal-valve.d.ts +106 -0
  24. package/lib/dist/db/wal-valve.d.ts.map +1 -0
  25. package/lib/dist/db/wal-valve.js +208 -0
  26. package/lib/dist/db/wal-valve.js.map +1 -0
  27. package/lib/dist/directory.d.ts +9 -5
  28. package/lib/dist/directory.d.ts.map +1 -1
  29. package/lib/dist/directory.js +210 -19
  30. package/lib/dist/directory.js.map +1 -1
  31. package/lib/dist/extraction/cfml-extractor.d.ts +107 -0
  32. package/lib/dist/extraction/cfml-extractor.d.ts.map +1 -0
  33. package/lib/dist/extraction/cfml-extractor.js +494 -0
  34. package/lib/dist/extraction/cfml-extractor.js.map +1 -0
  35. package/lib/dist/extraction/grammars.d.ts +25 -1
  36. package/lib/dist/extraction/grammars.d.ts.map +1 -1
  37. package/lib/dist/extraction/grammars.js +177 -23
  38. package/lib/dist/extraction/grammars.js.map +1 -1
  39. package/lib/dist/extraction/index.d.ts +47 -2
  40. package/lib/dist/extraction/index.d.ts.map +1 -1
  41. package/lib/dist/extraction/index.js +568 -51
  42. package/lib/dist/extraction/index.js.map +1 -1
  43. package/lib/dist/extraction/languages/arkts.d.ts +3 -0
  44. package/lib/dist/extraction/languages/arkts.d.ts.map +1 -0
  45. package/lib/dist/extraction/languages/arkts.js +127 -0
  46. package/lib/dist/extraction/languages/arkts.js.map +1 -0
  47. package/lib/dist/extraction/languages/c-cpp.d.ts +98 -0
  48. package/lib/dist/extraction/languages/c-cpp.d.ts.map +1 -1
  49. package/lib/dist/extraction/languages/c-cpp.js +563 -1
  50. package/lib/dist/extraction/languages/c-cpp.js.map +1 -1
  51. package/lib/dist/extraction/languages/cfquery.d.ts +12 -0
  52. package/lib/dist/extraction/languages/cfquery.d.ts.map +1 -0
  53. package/lib/dist/extraction/languages/cfquery.js +28 -0
  54. package/lib/dist/extraction/languages/cfquery.js.map +1 -0
  55. package/lib/dist/extraction/languages/cfscript.d.ts +3 -0
  56. package/lib/dist/extraction/languages/cfscript.d.ts.map +1 -0
  57. package/lib/dist/extraction/languages/cfscript.js +73 -0
  58. package/lib/dist/extraction/languages/cfscript.js.map +1 -0
  59. package/lib/dist/extraction/languages/cobol.d.ts +33 -0
  60. package/lib/dist/extraction/languages/cobol.d.ts.map +1 -0
  61. package/lib/dist/extraction/languages/cobol.js +499 -0
  62. package/lib/dist/extraction/languages/cobol.js.map +1 -0
  63. package/lib/dist/extraction/languages/erlang.d.ts +3 -0
  64. package/lib/dist/extraction/languages/erlang.d.ts.map +1 -0
  65. package/lib/dist/extraction/languages/erlang.js +350 -0
  66. package/lib/dist/extraction/languages/erlang.js.map +1 -0
  67. package/lib/dist/extraction/languages/index.d.ts.map +1 -1
  68. package/lib/dist/extraction/languages/index.js +18 -0
  69. package/lib/dist/extraction/languages/index.js.map +1 -1
  70. package/lib/dist/extraction/languages/nix.d.ts +3 -0
  71. package/lib/dist/extraction/languages/nix.d.ts.map +1 -0
  72. package/lib/dist/extraction/languages/nix.js +294 -0
  73. package/lib/dist/extraction/languages/nix.js.map +1 -0
  74. package/lib/dist/extraction/languages/solidity.d.ts +3 -0
  75. package/lib/dist/extraction/languages/solidity.d.ts.map +1 -0
  76. package/lib/dist/extraction/languages/solidity.js +293 -0
  77. package/lib/dist/extraction/languages/solidity.js.map +1 -0
  78. package/lib/dist/extraction/languages/terraform.d.ts +3 -0
  79. package/lib/dist/extraction/languages/terraform.d.ts.map +1 -0
  80. package/lib/dist/extraction/languages/terraform.js +641 -0
  81. package/lib/dist/extraction/languages/terraform.js.map +1 -0
  82. package/lib/dist/extraction/languages/vbnet.d.ts +11 -0
  83. package/lib/dist/extraction/languages/vbnet.d.ts.map +1 -0
  84. package/lib/dist/extraction/languages/vbnet.js +141 -0
  85. package/lib/dist/extraction/languages/vbnet.js.map +1 -0
  86. package/lib/dist/extraction/mybatis-extractor.d.ts +30 -10
  87. package/lib/dist/extraction/mybatis-extractor.d.ts.map +1 -1
  88. package/lib/dist/extraction/mybatis-extractor.js +140 -38
  89. package/lib/dist/extraction/mybatis-extractor.js.map +1 -1
  90. package/lib/dist/extraction/parse-pool.d.ts +28 -1
  91. package/lib/dist/extraction/parse-pool.d.ts.map +1 -1
  92. package/lib/dist/extraction/parse-pool.js +76 -7
  93. package/lib/dist/extraction/parse-pool.js.map +1 -1
  94. package/lib/dist/extraction/parse-worker.js +11 -4
  95. package/lib/dist/extraction/parse-worker.js.map +1 -1
  96. package/lib/dist/extraction/tree-sitter-helpers.d.ts.map +1 -1
  97. package/lib/dist/extraction/tree-sitter-helpers.js +1 -0
  98. package/lib/dist/extraction/tree-sitter-helpers.js.map +1 -1
  99. package/lib/dist/extraction/tree-sitter-types.d.ts +20 -1
  100. package/lib/dist/extraction/tree-sitter-types.d.ts.map +1 -1
  101. package/lib/dist/extraction/tree-sitter.d.ts +60 -1
  102. package/lib/dist/extraction/tree-sitter.d.ts.map +1 -1
  103. package/lib/dist/extraction/tree-sitter.js +905 -20
  104. package/lib/dist/extraction/tree-sitter.js.map +1 -1
  105. package/lib/dist/extraction/vba/call-sweep.d.ts +3 -0
  106. package/lib/dist/extraction/vba/call-sweep.d.ts.map +1 -0
  107. package/lib/dist/extraction/vba/call-sweep.js +206 -0
  108. package/lib/dist/extraction/vba/call-sweep.js.map +1 -0
  109. package/lib/dist/extraction/vba/calls.d.ts +55 -0
  110. package/lib/dist/extraction/vba/calls.d.ts.map +1 -0
  111. package/lib/dist/extraction/vba/calls.js +439 -0
  112. package/lib/dist/extraction/vba/calls.js.map +1 -0
  113. package/lib/dist/extraction/vba/constants.d.ts +42 -0
  114. package/lib/dist/extraction/vba/constants.d.ts.map +1 -0
  115. package/lib/dist/extraction/vba/constants.js +112 -0
  116. package/lib/dist/extraction/vba/constants.js.map +1 -0
  117. package/lib/dist/extraction/vba/context.d.ts +175 -0
  118. package/lib/dist/extraction/vba/context.d.ts.map +1 -0
  119. package/lib/dist/extraction/vba/context.js +268 -0
  120. package/lib/dist/extraction/vba/context.js.map +1 -0
  121. package/lib/dist/extraction/vba/controls.d.ts +24 -0
  122. package/lib/dist/extraction/vba/controls.d.ts.map +1 -0
  123. package/lib/dist/extraction/vba/controls.js +89 -0
  124. package/lib/dist/extraction/vba/controls.js.map +1 -0
  125. package/lib/dist/extraction/vba/declarations.d.ts +3 -0
  126. package/lib/dist/extraction/vba/declarations.d.ts.map +1 -0
  127. package/lib/dist/extraction/vba/declarations.js +154 -0
  128. package/lib/dist/extraction/vba/declarations.js.map +1 -0
  129. package/lib/dist/extraction/vba/dims.d.ts +3 -0
  130. package/lib/dist/extraction/vba/dims.d.ts.map +1 -0
  131. package/lib/dist/extraction/vba/dims.js +186 -0
  132. package/lib/dist/extraction/vba/dims.js.map +1 -0
  133. package/lib/dist/extraction/vba/docmd.d.ts +16 -0
  134. package/lib/dist/extraction/vba/docmd.d.ts.map +1 -0
  135. package/lib/dist/extraction/vba/docmd.js +179 -0
  136. package/lib/dist/extraction/vba/docmd.js.map +1 -0
  137. package/lib/dist/extraction/vba/enums-consts.d.ts +15 -0
  138. package/lib/dist/extraction/vba/enums-consts.d.ts.map +1 -0
  139. package/lib/dist/extraction/vba/enums-consts.js +178 -0
  140. package/lib/dist/extraction/vba/enums-consts.js.map +1 -0
  141. package/lib/dist/extraction/vba/implements.d.ts +3 -0
  142. package/lib/dist/extraction/vba/implements.d.ts.map +1 -0
  143. package/lib/dist/extraction/vba/implements.js +52 -0
  144. package/lib/dist/extraction/vba/implements.js.map +1 -0
  145. package/lib/dist/extraction/vba/procedures.d.ts +3 -0
  146. package/lib/dist/extraction/vba/procedures.d.ts.map +1 -0
  147. package/lib/dist/extraction/vba/procedures.js +239 -0
  148. package/lib/dist/extraction/vba/procedures.js.map +1 -0
  149. package/lib/dist/extraction/vba/sql-wrapper.d.ts +17 -0
  150. package/lib/dist/extraction/vba/sql-wrapper.d.ts.map +1 -0
  151. package/lib/dist/extraction/vba/sql-wrapper.js +212 -0
  152. package/lib/dist/extraction/vba/sql-wrapper.js.map +1 -0
  153. package/lib/dist/extraction/vba/tempvars.d.ts +10 -0
  154. package/lib/dist/extraction/vba/tempvars.d.ts.map +1 -0
  155. package/lib/dist/extraction/vba/tempvars.js +138 -0
  156. package/lib/dist/extraction/vba/tempvars.js.map +1 -0
  157. package/lib/dist/extraction/vba/text-utils.d.ts +73 -0
  158. package/lib/dist/extraction/vba/text-utils.d.ts.map +1 -0
  159. package/lib/dist/extraction/vba/text-utils.js +195 -0
  160. package/lib/dist/extraction/vba/text-utils.js.map +1 -0
  161. package/lib/dist/extraction/vba-extractor.d.ts +3 -951
  162. package/lib/dist/extraction/vba-extractor.d.ts.map +1 -1
  163. package/lib/dist/extraction/vba-extractor.js +46 -2934
  164. package/lib/dist/extraction/vba-extractor.js.map +1 -1
  165. package/lib/dist/extraction/vba-preprocess.d.ts +1 -1
  166. package/lib/dist/extraction/vba-preprocess.d.ts.map +1 -1
  167. package/lib/dist/extraction/vba-preprocess.js +300 -88
  168. package/lib/dist/extraction/vba-preprocess.js.map +1 -1
  169. package/lib/dist/extraction/wasm/tree-sitter-arkts.wasm +0 -0
  170. package/lib/dist/extraction/wasm/tree-sitter-cfml.wasm +0 -0
  171. package/lib/dist/extraction/wasm/tree-sitter-cfquery.wasm +0 -0
  172. package/lib/dist/extraction/wasm/tree-sitter-cfscript.wasm +0 -0
  173. package/lib/dist/extraction/wasm/tree-sitter-cobol.wasm +0 -0
  174. package/lib/dist/extraction/wasm/tree-sitter-erlang.wasm +0 -0
  175. package/lib/dist/extraction/wasm/tree-sitter-nix.wasm +0 -0
  176. package/lib/dist/extraction/wasm/tree-sitter-terraform.wasm +0 -0
  177. package/lib/dist/extraction/wasm/tree-sitter-vbnet.wasm +0 -0
  178. package/lib/dist/graph/traversal.d.ts.map +1 -1
  179. package/lib/dist/graph/traversal.js +76 -17
  180. package/lib/dist/graph/traversal.js.map +1 -1
  181. package/lib/dist/index.d.ts +81 -1
  182. package/lib/dist/index.d.ts.map +1 -1
  183. package/lib/dist/index.js +460 -10
  184. package/lib/dist/index.js.map +1 -1
  185. package/lib/dist/installer/index.d.ts +42 -0
  186. package/lib/dist/installer/index.d.ts.map +1 -1
  187. package/lib/dist/installer/index.js +97 -2
  188. package/lib/dist/installer/index.js.map +1 -1
  189. package/lib/dist/mcp/daemon.d.ts +35 -3
  190. package/lib/dist/mcp/daemon.d.ts.map +1 -1
  191. package/lib/dist/mcp/daemon.js +101 -9
  192. package/lib/dist/mcp/daemon.js.map +1 -1
  193. package/lib/dist/mcp/dynamic-boundaries.d.ts.map +1 -1
  194. package/lib/dist/mcp/dynamic-boundaries.js +2 -1
  195. package/lib/dist/mcp/dynamic-boundaries.js.map +1 -1
  196. package/lib/dist/mcp/early-ppid.d.ts +26 -0
  197. package/lib/dist/mcp/early-ppid.d.ts.map +1 -0
  198. package/lib/dist/mcp/early-ppid.js +29 -0
  199. package/lib/dist/mcp/early-ppid.js.map +1 -0
  200. package/lib/dist/mcp/index.d.ts.map +1 -1
  201. package/lib/dist/mcp/index.js +29 -4
  202. package/lib/dist/mcp/index.js.map +1 -1
  203. package/lib/dist/mcp/liveness-watchdog.d.ts +18 -1
  204. package/lib/dist/mcp/liveness-watchdog.d.ts.map +1 -1
  205. package/lib/dist/mcp/liveness-watchdog.js +73 -13
  206. package/lib/dist/mcp/liveness-watchdog.js.map +1 -1
  207. package/lib/dist/mcp/proxy.d.ts.map +1 -1
  208. package/lib/dist/mcp/proxy.js +30 -4
  209. package/lib/dist/mcp/proxy.js.map +1 -1
  210. package/lib/dist/mcp/query-pool.d.ts +14 -0
  211. package/lib/dist/mcp/query-pool.d.ts.map +1 -1
  212. package/lib/dist/mcp/query-pool.js +18 -0
  213. package/lib/dist/mcp/query-pool.js.map +1 -1
  214. package/lib/dist/mcp/session.d.ts +14 -0
  215. package/lib/dist/mcp/session.d.ts.map +1 -1
  216. package/lib/dist/mcp/session.js +28 -1
  217. package/lib/dist/mcp/session.js.map +1 -1
  218. package/lib/dist/mcp/startup-handshake.d.ts +44 -0
  219. package/lib/dist/mcp/startup-handshake.d.ts.map +1 -0
  220. package/lib/dist/mcp/startup-handshake.js +73 -0
  221. package/lib/dist/mcp/startup-handshake.js.map +1 -0
  222. package/lib/dist/mcp/tools.d.ts +22 -0
  223. package/lib/dist/mcp/tools.d.ts.map +1 -1
  224. package/lib/dist/mcp/tools.js +289 -23
  225. package/lib/dist/mcp/tools.js.map +1 -1
  226. package/lib/dist/mcp/transport.d.ts.map +1 -1
  227. package/lib/dist/mcp/transport.js +18 -0
  228. package/lib/dist/mcp/transport.js.map +1 -1
  229. package/lib/dist/project-config.d.ts +44 -0
  230. package/lib/dist/project-config.d.ts.map +1 -1
  231. package/lib/dist/project-config.js +151 -2
  232. package/lib/dist/project-config.js.map +1 -1
  233. package/lib/dist/resolution/c-fnptr-synthesizer.d.ts +2 -1
  234. package/lib/dist/resolution/c-fnptr-synthesizer.d.ts.map +1 -1
  235. package/lib/dist/resolution/c-fnptr-synthesizer.js +170 -146
  236. package/lib/dist/resolution/c-fnptr-synthesizer.js.map +1 -1
  237. package/lib/dist/resolution/callback-synthesizer.d.ts +1 -1
  238. package/lib/dist/resolution/callback-synthesizer.d.ts.map +1 -1
  239. package/lib/dist/resolution/callback-synthesizer.js +1109 -97
  240. package/lib/dist/resolution/callback-synthesizer.js.map +1 -1
  241. package/lib/dist/resolution/cooperative-yield.d.ts +32 -0
  242. package/lib/dist/resolution/cooperative-yield.d.ts.map +1 -0
  243. package/lib/dist/resolution/cooperative-yield.js +42 -0
  244. package/lib/dist/resolution/cooperative-yield.js.map +1 -0
  245. package/lib/dist/resolution/frameworks/cics.d.ts +20 -0
  246. package/lib/dist/resolution/frameworks/cics.d.ts.map +1 -0
  247. package/lib/dist/resolution/frameworks/cics.js +90 -0
  248. package/lib/dist/resolution/frameworks/cics.js.map +1 -0
  249. package/lib/dist/resolution/frameworks/index.d.ts.map +1 -1
  250. package/lib/dist/resolution/frameworks/index.js +6 -0
  251. package/lib/dist/resolution/frameworks/index.js.map +1 -1
  252. package/lib/dist/resolution/frameworks/java.d.ts.map +1 -1
  253. package/lib/dist/resolution/frameworks/java.js +14 -6
  254. package/lib/dist/resolution/frameworks/java.js.map +1 -1
  255. package/lib/dist/resolution/frameworks/terraform.d.ts +38 -0
  256. package/lib/dist/resolution/frameworks/terraform.d.ts.map +1 -0
  257. package/lib/dist/resolution/frameworks/terraform.js +277 -0
  258. package/lib/dist/resolution/frameworks/terraform.js.map +1 -0
  259. package/lib/dist/resolution/goframe-synthesizer.d.ts +2 -1
  260. package/lib/dist/resolution/goframe-synthesizer.d.ts.map +1 -1
  261. package/lib/dist/resolution/goframe-synthesizer.js +8 -3
  262. package/lib/dist/resolution/goframe-synthesizer.js.map +1 -1
  263. package/lib/dist/resolution/import-resolver.d.ts +7 -0
  264. package/lib/dist/resolution/import-resolver.d.ts.map +1 -1
  265. package/lib/dist/resolution/import-resolver.js +129 -4
  266. package/lib/dist/resolution/import-resolver.js.map +1 -1
  267. package/lib/dist/resolution/index.d.ts +64 -2
  268. package/lib/dist/resolution/index.d.ts.map +1 -1
  269. package/lib/dist/resolution/index.js +476 -58
  270. package/lib/dist/resolution/index.js.map +1 -1
  271. package/lib/dist/resolution/name-matcher.d.ts +22 -3
  272. package/lib/dist/resolution/name-matcher.d.ts.map +1 -1
  273. package/lib/dist/resolution/name-matcher.js +613 -39
  274. package/lib/dist/resolution/name-matcher.js.map +1 -1
  275. package/lib/dist/resolution/strip-comments.d.ts +1 -1
  276. package/lib/dist/resolution/strip-comments.d.ts.map +1 -1
  277. package/lib/dist/resolution/strip-comments.js +49 -0
  278. package/lib/dist/resolution/strip-comments.js.map +1 -1
  279. package/lib/dist/resolution/types.d.ts +29 -0
  280. package/lib/dist/resolution/types.d.ts.map +1 -1
  281. package/lib/dist/resolution/workspace-packages.d.ts +10 -0
  282. package/lib/dist/resolution/workspace-packages.d.ts.map +1 -1
  283. package/lib/dist/resolution/workspace-packages.js +142 -4
  284. package/lib/dist/resolution/workspace-packages.js.map +1 -1
  285. package/lib/dist/search/identifier-segments.d.ts +60 -0
  286. package/lib/dist/search/identifier-segments.d.ts.map +1 -0
  287. package/lib/dist/search/identifier-segments.js +176 -0
  288. package/lib/dist/search/identifier-segments.js.map +1 -0
  289. package/lib/dist/sync/git-hooks.d.ts.map +1 -1
  290. package/lib/dist/sync/git-hooks.js +2 -0
  291. package/lib/dist/sync/git-hooks.js.map +1 -1
  292. package/lib/dist/sync/watcher.d.ts +10 -5
  293. package/lib/dist/sync/watcher.d.ts.map +1 -1
  294. package/lib/dist/sync/watcher.js +51 -14
  295. package/lib/dist/sync/watcher.js.map +1 -1
  296. package/lib/dist/sync/worktree.d.ts +9 -0
  297. package/lib/dist/sync/worktree.d.ts.map +1 -1
  298. package/lib/dist/sync/worktree.js +45 -0
  299. package/lib/dist/sync/worktree.js.map +1 -1
  300. package/lib/dist/types.d.ts +25 -2
  301. package/lib/dist/types.d.ts.map +1 -1
  302. package/lib/dist/types.js +10 -0
  303. package/lib/dist/types.js.map +1 -1
  304. package/lib/dist/upgrade/index.d.ts +34 -2
  305. package/lib/dist/upgrade/index.d.ts.map +1 -1
  306. package/lib/dist/upgrade/index.js +164 -15
  307. package/lib/dist/upgrade/index.js.map +1 -1
  308. package/lib/dist/upgrade/remove-binary.d.ts +87 -0
  309. package/lib/dist/upgrade/remove-binary.d.ts.map +1 -0
  310. package/lib/dist/upgrade/remove-binary.js +289 -0
  311. package/lib/dist/upgrade/remove-binary.js.map +1 -0
  312. package/lib/dist/upgrade/update-check.d.ts +92 -0
  313. package/lib/dist/upgrade/update-check.d.ts.map +1 -0
  314. package/lib/dist/upgrade/update-check.js +258 -0
  315. package/lib/dist/upgrade/update-check.js.map +1 -0
  316. package/lib/node_modules/.modules.yaml +1 -1
  317. package/lib/node_modules/.pnpm-workspace-state-v1.json +1 -1
  318. package/lib/package.json +1 -1
  319. package/package.json +1 -1
  320. package/lib/dist/reasoning/config.d.ts +0 -45
  321. package/lib/dist/reasoning/config.d.ts.map +0 -1
  322. package/lib/dist/reasoning/config.js +0 -171
  323. package/lib/dist/reasoning/config.js.map +0 -1
  324. package/lib/dist/reasoning/credentials.d.ts +0 -5
  325. package/lib/dist/reasoning/credentials.d.ts.map +0 -1
  326. package/lib/dist/reasoning/credentials.js +0 -83
  327. package/lib/dist/reasoning/credentials.js.map +0 -1
  328. package/lib/dist/reasoning/login.d.ts +0 -21
  329. package/lib/dist/reasoning/login.d.ts.map +0 -1
  330. package/lib/dist/reasoning/login.js +0 -85
  331. package/lib/dist/reasoning/login.js.map +0 -1
  332. package/lib/dist/reasoning/reasoner.d.ts +0 -43
  333. package/lib/dist/reasoning/reasoner.d.ts.map +0 -1
  334. package/lib/dist/reasoning/reasoner.js +0 -308
  335. package/lib/dist/reasoning/reasoner.js.map +0 -1
package/lib/dist/index.js CHANGED
@@ -45,6 +45,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
45
45
  exports.CodeGraph = 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.CodeGraphError = exports.loadAllGrammars = exports.loadGrammarsForLanguages = exports.initGrammars = exports.getSupportedLanguages = exports.isGrammarLoaded = exports.isLanguageSupported = exports.detectLanguage = exports.CODEGRAPH_DIR = exports.findNearestCodeGraphRoot = exports.isInitialized = exports.getCodeGraphDir = exports.QueryBuilder = exports.DatabaseConnection = exports.getDatabasePath = void 0;
46
46
  const path = __importStar(require("path"));
47
47
  const db_1 = require("./db");
48
+ const wal_valve_1 = require("./db/wal-valve");
48
49
  const queries_1 = require("./db/queries");
49
50
  const directory_1 = require("./directory");
50
51
  const extraction_1 = require("./extraction");
@@ -57,6 +58,8 @@ const extraction_version_1 = require("./extraction/extraction-version");
57
58
  const directory_2 = require("./directory");
58
59
  const query_utils_1 = require("./search/query-utils");
59
60
  const version_1 = require("./mcp/version");
61
+ const identifier_segments_1 = require("./search/identifier-segments");
62
+ const cooperative_yield_1 = require("./resolution/cooperative-yield");
60
63
  // Re-export types for consumers
61
64
  __exportStar(require("./types"), exports);
62
65
  // Storage building blocks for embedded/SDK consumers that drive the graph
@@ -269,6 +272,48 @@ class CodeGraph {
269
272
  }
270
273
  return instance;
271
274
  }
275
+ /**
276
+ * Rebuild the project's database from scratch and return a fresh, empty
277
+ * instance — the "same result as a fresh init" semantics that `codegraph
278
+ * index` documents.
279
+ *
280
+ * Unlike `open()` followed by `clear()`, this DISCARDS the existing
281
+ * `.codegraph/codegraph.db` (and its `-wal`/`-shm` sidecars) before
282
+ * re-initializing, instead of opening the old database and DELETE-ing every
283
+ * row. On a large or pre-fix poisoned index — e.g. an old graph that scanned
284
+ * an ignored gitlink corpus (#1065) into ~1.6M nodes with a multi-GB WAL —
285
+ * the per-row `nodes_fts` delete-trigger churn blocks the main thread long
286
+ * enough to trip the #850 liveness watchdog before indexing even starts, so a
287
+ * full re-index could never recover the bad state (#1067). Discarding the
288
+ * files is O(1) regardless of size, reclaims the disk, and sidesteps opening
289
+ * (and running migrations against) the poisoned database entirely.
290
+ */
291
+ static async recreate(projectRoot) {
292
+ await (0, extraction_1.initGrammars)();
293
+ const resolvedRoot = path.resolve(projectRoot);
294
+ // Check if initialized — recreate REBUILDS an existing project; it is not a
295
+ // first-time `init`.
296
+ if (!(0, directory_1.isInitialized)(resolvedRoot)) {
297
+ throw new Error(`CodeGraph not initialized in ${resolvedRoot}. Run init() first.`);
298
+ }
299
+ const dbPath = (0, db_1.getDatabasePath)(resolvedRoot);
300
+ try {
301
+ (0, db_1.removeDatabaseFiles)(dbPath);
302
+ }
303
+ catch (err) {
304
+ // POSIX unlinks an open file fine; this fires mainly on Windows when a
305
+ // live daemon/MCP server still holds the database. Turn the raw EBUSY into
306
+ // an actionable instruction instead of a generic failure.
307
+ const reason = err instanceof Error ? err.message : String(err);
308
+ throw new Error(`Could not rebuild the index — the database file is in use (${reason}). ` +
309
+ `Stop any running CodeGraph MCP server/daemon for this project and retry, ` +
310
+ `or remove the ${(0, directory_2.getCodeGraphDir)(resolvedRoot)} directory and run "codegraph init".`);
311
+ }
312
+ // Re-create an empty, freshly-schema'd database at the same path.
313
+ const db = db_1.DatabaseConnection.initialize(dbPath);
314
+ const queries = new queries_1.QueryBuilder(db.getDb());
315
+ return new CodeGraph(db, queries, resolvedRoot);
316
+ }
272
317
  /**
273
318
  * Open synchronously (without sync)
274
319
  */
@@ -326,9 +371,49 @@ class CodeGraph {
326
371
  catch {
327
372
  return { success: false, filesIndexed: 0, filesSkipped: 0, filesErrored: 0, nodesCreated: 0, edgesCreated: 0, errors: [{ message: 'Could not acquire file lock - another process may be indexing', severity: 'error' }], durationMs: 0 };
328
373
  }
374
+ // Defer WAL auto-checkpointing for the whole bulk run (#1231): the
375
+ // default 1000-page interval re-writes hot pages into the main DB file
376
+ // over and over — ~95% of all disk I/O during a bulk index, and a
377
+ // 19+min → 45s difference on HDD-class storage. The valve bounds WAL
378
+ // growth by backfilling PASSIVEly on a worker thread (never blocking
379
+ // the writer or the #850 watchdog heartbeat); runMaintenance below does
380
+ // the final fold-up before the interval is restored in the finally.
381
+ // Kill switch: CODEGRAPH_NO_WAL_DEFER=1. Non-WAL journal modes (some
382
+ // network filesystems) have no WAL to defer — skip.
383
+ const deferWal = process.env.CODEGRAPH_NO_WAL_DEFER !== '1' && this.db.getJournalMode() === 'wal';
384
+ let walValve = null;
385
+ let priorAutocheckpoint = 1000;
386
+ if (deferWal) {
387
+ priorAutocheckpoint = this.db.getWalAutocheckpoint();
388
+ this.db.setWalAutocheckpoint(0);
389
+ walValve = new wal_valve_1.WalCheckpointValve(this.db, undefined, undefined, options.verbose ? (m) => console.log(`[wal-valve] ${m}`) : undefined);
390
+ walValve.start();
391
+ }
329
392
  try {
330
393
  const before = this.queries.getNodeAndEdgeCount();
331
- const result = await this.orchestrator.indexAll(options.onProgress, options.signal, options.verbose);
394
+ // Mark the index as in-flight BEFORE any writes: a run killed
395
+ // mid-index (OOM, SIGKILL, the #850 liveness watchdog) leaves this
396
+ // marker behind, so `codegraph status` can tell a truncated index
397
+ // from a completed one instead of silently serving partial results.
398
+ try {
399
+ this.queries.setMetadata('index_state', 'indexing');
400
+ }
401
+ catch { /* metadata is advisory */ }
402
+ // Segment vocabulary starts empty and is repopulated by the node write
403
+ // path as every file (re-)indexes below — so a full index is also the
404
+ // orphan-cleanup pass for names deleted since the last one.
405
+ try {
406
+ this.queries.clearNameSegmentVocab();
407
+ }
408
+ catch { /* vocab is advisory — never fail an index over it */ }
409
+ const result = await this.orchestrator.indexAll(options.onProgress, options.signal, options.verbose, walValve ? () => walValve.backpressure() : undefined);
410
+ // Fold the parse phase's WAL BEFORE the first post-parse reads
411
+ // (resolver re-init and resolution both read on the main thread):
412
+ // paging a bulk-write-sized WAL there is what blew the #850
413
+ // watchdog's 60s window in the #1231 repro. Off-thread + awaited,
414
+ // so the event loop keeps turning.
415
+ if (walValve)
416
+ await walValve.foldNow();
332
417
  // Re-detect frameworks now that the index is populated. The resolver
333
418
  // is constructed with createResolver() before any files exist, so
334
419
  // framework resolvers whose detect() consults the indexed file list
@@ -362,10 +447,16 @@ class CodeGraph {
362
447
  // receiver conforms to (protocol-extension / inherited / default-
363
448
  // interface). Needs the implements/extends edges the main pass just
364
449
  // built, so it runs after resolution (#750).
365
- this.resolver.resolveChainedCallsViaConformance();
450
+ const tChained = Date.now();
451
+ await this.resolver.resolveChainedCallsViaConformance();
452
+ if (process.env.CODEGRAPH_SYNTH_TIMINGS)
453
+ console.error(`[synth-timing] chainedConformance: ${Date.now() - tChained}ms`);
366
454
  // Same lifecycle for `this.<member>` callback registrations whose
367
455
  // member is inherited from a supertype (#808).
368
- this.resolver.resolveDeferredThisMemberRefs();
456
+ const tDeferred = Date.now();
457
+ await this.resolver.resolveDeferredThisMemberRefs();
458
+ if (process.env.CODEGRAPH_SYNTH_TIMINGS)
459
+ console.error(`[synth-timing] deferredThisMember: ${Date.now() - tDeferred}ms`);
369
460
  // VBA #12b: repoint qualified call-stub edges to their real
370
461
  // cross-file target now that the whole project has been indexed
371
462
  // (needs every file's nodes/edges to be resolvable candidates).
@@ -376,15 +467,30 @@ class CodeGraph {
376
467
  this.resolver.resolveVbaReferenceStubs();
377
468
  }
378
469
  // Refresh planner stats + checkpoint the WAL after bulk writes.
379
- // Cheap and non-blocking; never load-bearing for correctness.
470
+ // Off-thread (worker connection): on a multi-GB index this is minutes
471
+ // of IO, and inline it starved the #850 watchdog AFTER a fully
472
+ // successful index. Never load-bearing for correctness.
380
473
  if (result.success && result.filesIndexed > 0) {
381
- this.db.runMaintenance();
474
+ const tMaint = Date.now();
475
+ // Quiesce the valve first so its in-flight checkpoint and the
476
+ // maintenance checkpoint don't contend for the checkpointer lock
477
+ // (the loser would silently no-op and leave the WAL unfolded).
478
+ if (walValve) {
479
+ walValve.stop();
480
+ await walValve.drain();
481
+ }
482
+ await this.db.runMaintenance();
483
+ if (process.env.CODEGRAPH_SYNTH_TIMINGS)
484
+ console.error(`[phase-timing] maintenance: ${Date.now() - tMaint}ms`);
382
485
  }
383
486
  // The orchestrator only sees extraction-phase counts; resolution and
384
487
  // synthesizer edges (often >50% of the graph on JVM repos) come later.
385
488
  // Recompute against the DB so the CLI summary reports the true totals.
386
489
  if (result.success && result.filesIndexed > 0) {
490
+ const tCount = Date.now();
387
491
  const after = this.queries.getNodeAndEdgeCount();
492
+ if (process.env.CODEGRAPH_SYNTH_TIMINGS)
493
+ console.error(`[phase-timing] count-recompute: ${Date.now() - tCount}ms`);
388
494
  result.nodesCreated = after.nodes - before.nodes;
389
495
  result.edgesCreated = after.edges - before.edges;
390
496
  }
@@ -400,9 +506,57 @@ class CodeGraph {
400
506
  }
401
507
  catch { /* metadata is advisory — never fail an index over it */ }
402
508
  }
509
+ // Reconcile the scan's ground truth against what the pipeline
510
+ // accounted for. A shortfall means files were silently dropped
511
+ // (observed in the wild: a run under heavy load came up 37 files
512
+ // short with no error) — record it and tell the user, don't let the
513
+ // index pass as complete.
514
+ try {
515
+ if (!result.success) {
516
+ this.queries.setMetadata('index_state', 'failed');
517
+ }
518
+ else {
519
+ const accounted = result.filesIndexed + result.filesSkipped + result.filesErrored;
520
+ const discovered = result.filesDiscovered;
521
+ const shortfall = discovered !== undefined ? discovered - accounted : 0;
522
+ if (discovered !== undefined && shortfall > 0) {
523
+ this.queries.setMetadata('index_state', 'partial');
524
+ this.queries.setMetadata('index_files_discovered', String(discovered));
525
+ this.queries.setMetadata('index_files_accounted', String(accounted));
526
+ result.errors.push({
527
+ message: `Index is missing ${shortfall} of ${discovered} discovered files (indexed ${result.filesIndexed}, skipped ${result.filesSkipped}, errored ${result.filesErrored}). The index is PARTIAL — re-run \`codegraph index\`.`,
528
+ severity: 'warning',
529
+ code: 'index_partial',
530
+ });
531
+ }
532
+ else {
533
+ this.queries.setMetadata('index_state', 'complete');
534
+ if (discovered !== undefined) {
535
+ this.queries.setMetadata('index_files_discovered', String(discovered));
536
+ this.queries.setMetadata('index_files_accounted', String(accounted));
537
+ }
538
+ }
539
+ }
540
+ }
541
+ catch { /* metadata is advisory — never fail an index over it */ }
403
542
  return result;
404
543
  }
405
544
  finally {
545
+ // Restore the auto-checkpoint interval AFTER the fold-up above so the
546
+ // next ordinary write doesn't inherit a giant inline checkpoint. On
547
+ // the error path the WAL may still be large; correctness is unchanged
548
+ // (SQLite replays the WAL on the next open) and the follow-up write
549
+ // that folds it is the known cost of a failed run.
550
+ if (walValve) {
551
+ walValve.stop();
552
+ await walValve.drain();
553
+ }
554
+ if (deferWal) {
555
+ try {
556
+ this.db.setWalAutocheckpoint(priorAutocheckpoint);
557
+ }
558
+ catch { /* connection may be closing */ }
559
+ }
406
560
  this.fileLock.release();
407
561
  }
408
562
  });
@@ -442,6 +596,18 @@ class CodeGraph {
442
596
  return { filesChecked: 0, filesAdded: 0, filesModified: 0, filesRemoved: 0, nodesUpdated: 0, durationMs: 0 };
443
597
  }
444
598
  try {
599
+ // Captured BEFORE the sync runs: the sync's own incremental writes
600
+ // populate vocab rows for the files it touches, so an end-of-sync
601
+ // emptiness check would see "non-empty" and skip the backfill forever,
602
+ // leaving every unchanged file's names unsegmented.
603
+ const vocabWasEmpty = (() => {
604
+ try {
605
+ return this.queries.isNameSegmentVocabEmpty();
606
+ }
607
+ catch {
608
+ return false;
609
+ }
610
+ })();
445
611
  const result = await this.orchestrator.sync(options.onProgress);
446
612
  // Cross-file finalization (e.g. NestJS RouterModule prefixes). Run on
447
613
  // every sync that touched files so edits to `app.module.ts` propagate
@@ -450,11 +616,25 @@ class CodeGraph {
450
616
  if (result.filesAdded > 0 || result.filesModified > 0) {
451
617
  this.resolver.runPostExtract();
452
618
  }
619
+ else if (result.filesRemoved > 0) {
620
+ // A pure-removal sync still resolves refs below — the deletion path
621
+ // resurrects the removed file's incoming edges as pending refs
622
+ // (#1240 removal case) and the orphan sweep consumes them. In a
623
+ // long-lived process (daemon) the resolver's name caches were
624
+ // warmed against the pre-removal graph; drop them so resolution
625
+ // sees the post-removal state. (runPostExtract above clears caches
626
+ // itself, so the changed-files branch is already covered.)
627
+ this.resolver.clearCaches();
628
+ }
453
629
  // Resolve references if files were updated
454
- if (result.filesAdded > 0 || result.filesModified > 0) {
630
+ const filesChanged = result.filesAdded > 0 || result.filesModified > 0;
631
+ if (filesChanged) {
455
632
  if (result.changedFilePaths) {
456
633
  // Scope resolution to changed files (git fast path — bounded set)
634
+ const tRefLoad = Date.now();
457
635
  const unresolvedRefs = this.queries.getUnresolvedReferencesByFiles(result.changedFilePaths);
636
+ if (process.env.CODEGRAPH_SYNTH_TIMINGS)
637
+ console.error(`[phase-timing] sync-ref-load: ${Date.now() - tRefLoad}ms (${unresolvedRefs.length} refs)`);
458
638
  options.onProgress?.({
459
639
  phase: 'resolving',
460
640
  current: 0,
@@ -467,6 +647,32 @@ class CodeGraph {
467
647
  total,
468
648
  });
469
649
  });
650
+ // Retry previously-failed refs the changed files may now satisfy
651
+ // (#1240). Scoped resolution above only re-resolves refs FROM the
652
+ // changed files — but when a changed file gains an export/symbol,
653
+ // refs in UNCHANGED files that failed against the old graph can
654
+ // now resolve, and nothing else ever revisits them (their rows
655
+ // were parked as status='failed' by an earlier completed pass).
656
+ // Look them up by the symbol names the changed files now carry
657
+ // and re-resolve just that set. On a sync where no failed ref
658
+ // matches, this is one indexed lookup.
659
+ const tRetry = Date.now();
660
+ const retryable = this.queries.getRetryableFailedReferences(this.queries.getNodeNamesByFiles(result.changedFilePaths));
661
+ if (retryable.length > 0) {
662
+ options.onProgress?.({
663
+ phase: 'resolving',
664
+ current: 0,
665
+ total: retryable.length,
666
+ });
667
+ await this.resolver.resolveAndPersistListYielding(retryable);
668
+ options.onProgress?.({
669
+ phase: 'resolving',
670
+ current: retryable.length,
671
+ total: retryable.length,
672
+ });
673
+ }
674
+ if (process.env.CODEGRAPH_SYNTH_TIMINGS)
675
+ console.error(`[phase-timing] sync-failed-ref-retry: ${Date.now() - tRetry}ms (${retryable.length} refs)`);
470
676
  }
471
677
  else {
472
678
  // No git info — use batched resolution to avoid OOM
@@ -484,13 +690,43 @@ class CodeGraph {
484
690
  });
485
691
  });
486
692
  }
693
+ }
694
+ // Orphan sweep (#1187). A resolution pass that dies mid-run — the #850
695
+ // daemon liveness watchdog's SIGKILL (#1122), Ctrl-C, a crash — leaves
696
+ // the refs it never reached in unresolved_refs, and the git-scoped fast
697
+ // path above never revisits them (it reads only the changed files'
698
+ // rows). Those files' call edges were then missing PERMANENTLY, with
699
+ // nothing to see except a too-small blast radius, until a full
700
+ // re-index. A completed pass takes every row it processed out of the
701
+ // PENDING set (resolved rows are deleted, unresolvable ones parked as
702
+ // status='failed' for the #1240 retry above), so any pending row now
703
+ // is such an orphan — or a row from an older engine's scoped pass.
704
+ // Grind them down with the batched resolver; this also makes a bare
705
+ // `codegraph sync` the recovery command for a wedged index. On a
706
+ // healthy index this is one COUNT query.
707
+ const orphanCount = this.queries.getUnresolvedReferencesCount();
708
+ if (orphanCount > 0) {
709
+ options.onProgress?.({
710
+ phase: 'resolving',
711
+ current: 0,
712
+ total: orphanCount,
713
+ });
714
+ await this.resolveReferencesBatched((current, total) => {
715
+ options.onProgress?.({
716
+ phase: 'resolving',
717
+ current,
718
+ total,
719
+ });
720
+ });
721
+ }
722
+ if (filesChanged || orphanCount > 0) {
487
723
  // Second pass: chained calls whose method lives on a supertype the
488
724
  // receiver conforms to (protocol-extension / inherited). Needs the
489
725
  // implements/extends edges built above (#750).
490
- this.resolver.resolveChainedCallsViaConformance();
726
+ await this.resolver.resolveChainedCallsViaConformance();
491
727
  // Same lifecycle for `this.<member>` callback registrations whose
492
728
  // member is inherited from a supertype (#808).
493
- this.resolver.resolveDeferredThisMemberRefs();
729
+ await this.resolver.resolveDeferredThisMemberRefs();
494
730
  // VBA #12b: same lifecycle — repoint any newly-emitted qualified
495
731
  // call-stub edges to their real cross-file target (#12).
496
732
  this.resolver.resolveVbaCallStubs();
@@ -499,9 +735,22 @@ class CodeGraph {
499
735
  this.resolver.resolveVbaReferenceStubs();
500
736
  }
501
737
  // Refresh planner stats + checkpoint the WAL after bulk writes.
502
- if (result.filesAdded > 0 || result.filesModified > 0 || result.filesRemoved > 0) {
503
- this.db.runMaintenance();
738
+ // Off-thread see indexAll's call site.
739
+ if (filesChanged || result.filesRemoved > 0 || orphanCount > 0) {
740
+ await this.db.runMaintenance();
741
+ }
742
+ // Heal the segment vocabulary on indexes built before the table
743
+ // existed (upgrade path): incremental writes above only cover changed
744
+ // files, so a vocab that was empty when this sync STARTED means the
745
+ // bulk was never segmented — backfill it (INSERT OR IGNORE, so the
746
+ // rows the sync just wrote are fine). Batched + yielding — sync can
747
+ // run on the daemon's liveness-watchdog thread (#850/#1091).
748
+ try {
749
+ if (vocabWasEmpty && this.queries.getNodeAndEdgeCount().nodes > 0) {
750
+ await this.rebuildNameSegmentVocab();
751
+ }
504
752
  }
753
+ catch { /* vocab is advisory — never fail a sync over it */ }
505
754
  return result;
506
755
  }
507
756
  finally {
@@ -612,6 +861,21 @@ class CodeGraph {
612
861
  getLastIndexedAt() {
613
862
  return this.queries.getLastIndexedAt();
614
863
  }
864
+ /**
865
+ * Completeness of the last full index run. `'complete'` is the only good
866
+ * state. `'indexing'` after the fact means a run was killed mid-index (OOM,
867
+ * SIGKILL, liveness watchdog) and the on-disk index is truncated;
868
+ * `'partial'` means the run finished but silently dropped files
869
+ * (discovered > indexed+skipped+errored); `'failed'` means it reported
870
+ * failure. `null` = index predates this marker. Surfaced by
871
+ * `codegraph status`.
872
+ */
873
+ getIndexState() {
874
+ const raw = this.queries.getMetadata('index_state');
875
+ return raw === 'indexing' || raw === 'complete' || raw === 'partial' || raw === 'failed'
876
+ ? raw
877
+ : null;
878
+ }
615
879
  /**
616
880
  * Which engine built the current index: the package version + extraction
617
881
  * version stamped at the last full `indexAll`. Either field is null for an
@@ -667,6 +931,16 @@ class CodeGraph {
667
931
  async resolveReferencesBatched(onProgress) {
668
932
  return this.resolver.resolveAndPersistBatched(onProgress);
669
933
  }
934
+ /**
935
+ * References extracted but never attempted by a resolution pass. Zero on a
936
+ * healthy index — a completed pass consumes every pending row (resolving it
937
+ * or parking it as failed, #1240). Non-zero at rest means a pass was
938
+ * interrupted mid-run (killed indexer, crash — #1187), so some files' call
939
+ * edges are missing; the next `sync` sweeps them.
940
+ */
941
+ getPendingReferenceCount() {
942
+ return this.queries.getUnresolvedReferencesCount();
943
+ }
670
944
  /**
671
945
  * Get detected frameworks in the project
672
946
  */
@@ -736,12 +1010,188 @@ class CodeGraph {
736
1010
  getNodesByName(name) {
737
1011
  return this.queries.getNodesByName(name);
738
1012
  }
1013
+ /** Nodes whose name starts with `prefix` (index range scan, capped). */
1014
+ getNodesByNamePrefix(prefix, limit = 20) {
1015
+ return this.queries.getNodesByNamePrefix(prefix, limit);
1016
+ }
739
1017
  /**
740
1018
  * Search nodes by text
741
1019
  */
742
1020
  searchNodes(query, options) {
743
1021
  return this.queries.searchNodes(query, options);
744
1022
  }
1023
+ /**
1024
+ * Graph-derived prompt matching for the front-load hook's MEDIUM tier:
1025
+ * which indexed symbols do these prose words name? "state machine des
1026
+ * commandes" → `OrderStateMachine`, in any human language whose technical
1027
+ * nouns are Latin script — no keyword list involved.
1028
+ *
1029
+ * Precision comes from the repo's own naming statistics, not vocabulary:
1030
+ * - CO-OCCURRENCE: ≥2 words that are segments of the SAME name ("state" +
1031
+ * "machine" → OrderStateMachine) is strong evidence and always qualifies.
1032
+ * - RARITY: a single matched word qualifies only when its segment is
1033
+ * discriminative here (≤ {@link SEGMENT_RARITY_CEILING} distinct names) —
1034
+ * "checkout" in a shop backend yes, "state" in a react app no.
1035
+ * Every candidate is re-verified against `nodes` before being returned
1036
+ * (vocab rows are proposals; deletions leave orphans by design), so a
1037
+ * returned symbol is guaranteed to exist right now.
1038
+ */
1039
+ getSegmentMatches(words, limit = 6) {
1040
+ if (words.length === 0)
1041
+ return [];
1042
+ // Variant → original word (plural folding), for coverage accounting.
1043
+ const variantToWord = new Map();
1044
+ for (const word of words) {
1045
+ for (const variant of (0, identifier_segments_1.segmentLookupVariants)(word)) {
1046
+ if (!variantToWord.has(variant))
1047
+ variantToWord.set(variant, word);
1048
+ }
1049
+ }
1050
+ const variants = [...variantToWord.keys()];
1051
+ // Tier A: co-occurrence. The SQL folds variants back to their original
1052
+ // word (#1146), so minWords=2 means two distinct PROMPT WORDS — a name
1053
+ // matching both `service` and `services` can't tie with (or crowd past
1054
+ // the LIMIT) a genuine two-word match. The JS re-check below recomputes
1055
+ // the fold from live segments as the honesty layer.
1056
+ const variantPairs = [...variantToWord.entries()].map(([segment, word]) => ({ segment, word }));
1057
+ const candidates = [];
1058
+ for (const hit of this.queries.getSegmentCoOccurrence(variantPairs, 2, 24)) {
1059
+ const matched = this.wordsMatchingName(hit.name, variantToWord);
1060
+ if (matched.size >= 2)
1061
+ candidates.push({ name: hit.name, matchedWords: matched });
1062
+ }
1063
+ // Tier B: single rare word. Only when co-occurrence found nothing — a
1064
+ // co-occurring name is categorically stronger evidence — and under
1065
+ // stricter rules, because one word is thin: the word must be ≥5 chars
1066
+ // (measured FPs: "this", "typo"); the segment must appear in AT LEAST TWO
1067
+ // names (a concept the codebase is about clusters across names —
1068
+ // CheckoutService/CheckoutController — while a prose coincidence is a
1069
+ // singleton: measured FP "deploy to PRODUCTION" → the one name
1070
+ // matchesNonProductionDir); and the candidate name must have ≥2 segments
1071
+ // (a bare common verb matching a bare function name — "write" → `write` —
1072
+ // is prose coincidence, not the user naming a symbol).
1073
+ if (candidates.length === 0) {
1074
+ const singleWordVariants = variants.filter((v) => variantToWord.get(v).length >= 5);
1075
+ const counts = this.queries.getSegmentNameCounts(singleWordVariants);
1076
+ const rare = [...counts.entries()]
1077
+ .filter(([, n]) => n >= 2 && n <= CodeGraph.SEGMENT_RARITY_CEILING)
1078
+ .sort((a, b) => a[1] - b[1])
1079
+ .slice(0, 2);
1080
+ for (const [variant] of rare) {
1081
+ const word = variantToWord.get(variant);
1082
+ for (const name of this.queries.getNamesForSegment(variant, 12)) {
1083
+ if ((0, identifier_segments_1.splitIdentifierSegments)(name).length < 2)
1084
+ continue;
1085
+ candidates.push({ name, matchedWords: new Set([word]) });
1086
+ }
1087
+ }
1088
+ }
1089
+ // Verify against nodes (the honesty gate) and pick a representative
1090
+ // definition per name. A name whose only nodes are file/import kind has
1091
+ // no real definition to point at — surfacing the import statement instead
1092
+ // reads as a matched symbol but isn't one (#1144) — so it's skipped, the
1093
+ // same way an orphaned vocab row is. (Import names no longer enter the
1094
+ // vocab at write time, but rows written before that exclusion persist
1095
+ // until the next full index.)
1096
+ const out = [];
1097
+ const seen = new Set();
1098
+ candidates.sort((a, b) => b.matchedWords.size - a.matchedWords.size || a.name.length - b.name.length);
1099
+ for (const candidate of candidates) {
1100
+ if (out.length >= limit)
1101
+ break;
1102
+ if (seen.has(candidate.name))
1103
+ continue;
1104
+ seen.add(candidate.name);
1105
+ const nodes = this.queries.getNodesByName(candidate.name);
1106
+ if (nodes.length === 0)
1107
+ continue; // orphaned vocab row — name no longer exists
1108
+ const rep = nodes.find((n) => n.kind !== 'file' && n.kind !== 'import');
1109
+ if (!rep)
1110
+ continue; // no real definition — don't surface an import/file as one
1111
+ out.push({
1112
+ name: candidate.name,
1113
+ kind: rep.kind,
1114
+ filePath: rep.filePath,
1115
+ startLine: rep.startLine ?? 0,
1116
+ matchedWords: [...candidate.matchedWords].sort(),
1117
+ });
1118
+ }
1119
+ return out;
1120
+ }
1121
+ /** A single word ("state") can match hundreds of names in a big repo — that
1122
+ * is noise, not signal. Ceiling for the single-word tier; co-occurrence is
1123
+ * exempt because two words on one name is already discriminative. */
1124
+ static SEGMENT_RARITY_CEILING = 25;
1125
+ /** Which of the prompt's original words match `name`'s segments (via
1126
+ * variants). Segments are recomputed in JS — a name-keyed vocab lookup
1127
+ * would scan the (segment, name) primary key. */
1128
+ wordsMatchingName(name, variantToWord) {
1129
+ const segments = new Set((0, identifier_segments_1.splitIdentifierSegments)(name));
1130
+ const matched = new Set();
1131
+ for (const [variant, word] of variantToWord) {
1132
+ if (segments.has(variant))
1133
+ matched.add(word);
1134
+ }
1135
+ return matched;
1136
+ }
1137
+ /**
1138
+ * One-shot upgrade heal for callers that open the graph WITHOUT syncing —
1139
+ * concretely the prompt hook, whose MEDIUM tier reads the segment
1140
+ * vocabulary: a database migrated from before the vocab table existed
1141
+ * starts with it empty, and the only other backfill lives inside `sync()`,
1142
+ * which such callers never run (#1142). Returns true when the vocab is
1143
+ * usable (already populated — the overwhelmingly common one-SELECT case —
1144
+ * or healed here); false when it isn't (empty graph, or another process
1145
+ * holds the index lock — that process's own sync heals it).
1146
+ */
1147
+ async healSegmentVocabIfEmpty() {
1148
+ const empty = (() => {
1149
+ try {
1150
+ return this.queries.isNameSegmentVocabEmpty();
1151
+ }
1152
+ catch {
1153
+ return false;
1154
+ }
1155
+ })();
1156
+ if (!empty)
1157
+ return true;
1158
+ if (this.queries.getNodeAndEdgeCount().nodes === 0)
1159
+ return false;
1160
+ return this.indexMutex.withLock(async () => {
1161
+ try {
1162
+ this.fileLock.acquire();
1163
+ }
1164
+ catch {
1165
+ return false; // an index/sync is running — it backfills the vocab itself
1166
+ }
1167
+ try {
1168
+ if (!this.queries.isNameSegmentVocabEmpty())
1169
+ return true; // raced: healed meanwhile
1170
+ await this.rebuildNameSegmentVocab();
1171
+ return true;
1172
+ }
1173
+ finally {
1174
+ this.fileLock.release();
1175
+ }
1176
+ });
1177
+ }
1178
+ /**
1179
+ * Rebuild the segment vocabulary from the current graph, batched and
1180
+ * yielding — the upgrade-heal path for indexes built before the vocab table
1181
+ * existed. Runs inside the index mutex/lock (sync and
1182
+ * healSegmentVocabIfEmpty hold them).
1183
+ */
1184
+ async rebuildNameSegmentVocab() {
1185
+ const maybeYield = (0, cooperative_yield_1.createYielder)();
1186
+ const BATCH = 2000;
1187
+ for (let offset = 0;; offset += BATCH) {
1188
+ const names = this.queries.getDistinctNodeNames(BATCH, offset);
1189
+ if (names.length === 0)
1190
+ break;
1191
+ this.queries.insertNameSegmentsBatch(names);
1192
+ await maybeYield();
1193
+ }
1194
+ }
745
1195
  /**
746
1196
  * Normalized project-name tokens (go.mod / package.json / repo dir) used to
747
1197
  * down-weight the non-discriminative project name in search ranking (#720).