@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
@@ -6,6 +6,7 @@
6
6
  */
7
7
  Object.defineProperty(exports, "__esModule", { value: true });
8
8
  exports.ToolHandler = exports.tools = exports.PathRefusalError = exports.NotIndexedError = void 0;
9
+ exports.normalizeQuerySpelling = normalizeQuerySpelling;
9
10
  exports.getExploreBudget = getExploreBudget;
10
11
  exports.getExploreOutputBudget = getExploreOutputBudget;
11
12
  exports.formatStaleBanner = formatStaleBanner;
@@ -25,6 +26,7 @@ const fs_1 = require("fs");
25
26
  const utils_1 = require("../utils");
26
27
  const generated_detection_1 = require("../extraction/generated-detection");
27
28
  const dynamic_boundaries_1 = require("./dynamic-boundaries");
29
+ const update_check_1 = require("../upgrade/update-check");
28
30
  /**
29
31
  * An expected, recoverable "codegraph can't serve this" condition — most
30
32
  * importantly a project with no index. The dispatch catch converts these to
@@ -85,6 +87,32 @@ function lastQualifierPart(symbol) {
85
87
  const parts = symbol.split(/::|[./]/).filter((p) => p.length > 0);
86
88
  return parts[parts.length - 1] ?? symbol;
87
89
  }
90
+ /**
91
+ * Normalize Erlang-native symbol spellings in an explore query into the shapes
92
+ * the rest of the pipeline already understands. Agents working Erlang code
93
+ * name symbols the way the language spells them — `mod:fn/3`, `init/2` — and
94
+ * those tokens previously died in both consumers: the flow-builder's token
95
+ * filter rejects `:` and `/arity` outright, and the search-side field parser
96
+ * eats `mod:fn` as an unknown `field:value`. Measured on cowboy: the agent
97
+ * named `cowboy_stream_h:request_process/3` in two queries, got no body back
98
+ * either time, and fell back to Read.
99
+ *
100
+ * - `fn/3` → `fn` (arity tail after an identifier; a path segment like
101
+ * `src/2fa` doesn't match because the tail must be all digits)
102
+ * - `mod:fn` → `mod.fn` (exactly one colon between identifiers, so it rides
103
+ * the existing Class.method qualified handling; `::`, URLs, drive letters,
104
+ * and times don't match, and the query language's own field prefixes —
105
+ * kind:/lang:/language:/path:/name: — are left alone)
106
+ *
107
+ * Safe cross-language: Lua's `t:m` spelling maps to the same `t.m` its
108
+ * qualified names use, and no other supported spelling contains a bare
109
+ * single-colon identifier pair.
110
+ */
111
+ function normalizeQuerySpelling(query) {
112
+ return query
113
+ .replace(/\b([A-Za-z_][\w@]*)\/(\d{1,3})(?=$|[\s,()[\]/])/g, '$1')
114
+ .replace(/(^|[\s,()[\]])(?!(?:kind|lang|language|path|name):)([a-z_][\w@]*):([A-Za-z_][\w@]*)(?=$|[\s,()[\]])/g, '$1$2.$3');
115
+ }
88
116
  /**
89
117
  * Calculate the recommended number of codegraph_explore calls based on project size.
90
118
  * Larger codebases need more exploration calls to cover their surface area,
@@ -274,10 +302,15 @@ function numberSourceLines(slice, firstLineNumber) {
274
302
  * extension) stop blowing every header up to H1–H4. The path is bold + a code
275
303
  * span so it still reads as a header, and the leading ``**` `` stays a UNIQUE,
276
304
  * greppable marker — no other explore line begins with it — that the explore
277
- * truncation boundary (`handleExplore`) and the offload chunker
278
- * (`reasoning/reasoner.ts`) both key off to cut on whole file sections.
305
+ * truncation boundary (`handleExplore`) keys off to cut on whole file sections.
279
306
  */
280
307
  const FILE_SECTION_PREFIX = '**`';
308
+ // Placeholder for codegraph_explore's "Found N symbols across M files." line.
309
+ // The honest N/M can only be known after the final truncation drops trailing
310
+ // sections (#1046), so the header is emitted as this sentinel and substituted
311
+ // at the very end. This bracketed token never occurs in rendered source or a
312
+ // file path, so the final string-replace can't collide.
313
+ const SUMMARY_SENTINEL = '[[codegraph-explore-summary]]';
281
314
  function fileSectionHeader(filePath, suffix) {
282
315
  return suffix
283
316
  ? `${FILE_SECTION_PREFIX}${filePath}\`** — ${suffix}`
@@ -1202,15 +1235,20 @@ class ToolHandler {
1202
1235
  return await this.handleStatus(args);
1203
1236
  }
1204
1237
  // Read tools: off-load the CPU-heavy dispatch to the worker pool when one
1205
- // is attached and healthy (daemon mode), so the daemon's single event loop
1206
- // stays free for the MCP transport under concurrent load otherwise N
1207
- // concurrent explores serialize AND starve the transport until the whole
1208
- // batch drains (clients then time out). With no pool (direct mode) or a
1209
- // degraded one, dispatch runs in-process exactly as before. Either way the
1210
- // result flows through the cross-cutting notices worktree-index mismatch
1211
- // (#155) and per-file staleness (#403) which need the watched MAIN
1212
- // instance and so are always applied here, never in the worker.
1213
- const result = (this.queryPool && this.queryPool.healthy)
1238
+ // is attached, healthy, AND has finished its first cold start (daemon
1239
+ // mode), so the daemon's single event loop stays free for the MCP
1240
+ // transport under concurrent load otherwise N concurrent explores
1241
+ // serialize AND starve the transport until the whole batch drains
1242
+ // (clients then time out). Before the first worker is warm, calls run
1243
+ // in-process: a call queued behind a cold start sat invisible until the
1244
+ // 45s busy backstop the daemon's first tool call stalling for however
1245
+ // long a worker spawn takes on a loaded machine (the #662 flake). With
1246
+ // no pool (direct mode) or a degraded one, dispatch runs in-process
1247
+ // exactly as before. Either way the result flows through the
1248
+ // cross-cutting notices — worktree-index mismatch (#155) and per-file
1249
+ // staleness (#403) — which need the watched MAIN instance and so are
1250
+ // always applied here, never in the worker.
1251
+ const result = (this.queryPool && this.queryPool.healthy && this.queryPool.ready)
1214
1252
  ? await this.queryPool.run(toolName, args)
1215
1253
  : await this.executeReadTool(toolName, args);
1216
1254
  const withWorktree = this.withWorktreeNotice(result, args.projectPath);
@@ -1654,7 +1692,7 @@ class ToolHandler {
1654
1692
  // names (Class.method / Class::method) — the agent's most precise input,
1655
1693
  // resolved exactly by findAllSymbols. (The old strip mangled Class.method
1656
1694
  // into Class, throwing the method away.)
1657
- const FILE_EXT = /\.(?:java|kt|kts|ts|tsx|js|jsx|mjs|cjs|cs|py|go|rb|php|swift|rs|cpp|cc|cxx|c|h|hpp|scala|lua|dart|vue|svelte|astro)$/i;
1695
+ const FILE_EXT = /\.(?:java|kt|kts|ts|tsx|js|jsx|mjs|cjs|cs|py|go|rb|php|swift|rs|cpp|cc|cxx|c|h|hpp|scala|lua|dart|vue|svelte|astro|erl|hrl)$/i;
1658
1696
  const tokens = [...new Set(query.split(/[\s,()[\]]+/)
1659
1697
  .map((t) => t.replace(FILE_EXT, '').trim())
1660
1698
  .filter((t) => t.length >= 3 && /^[A-Za-z_$][\w$]*(?:(?:::|\.)[\w$]+)*$/.test(t)))].slice(0, 16);
@@ -1716,13 +1754,19 @@ class ToolHandler {
1716
1754
  }
1717
1755
  // Same token, non-callable synth endpoints (capped, precision-gated on an
1718
1756
  // actual heuristic edge so plain config constants never qualify).
1757
+ // Per-token sub-cap so one token's many endpoints (10 nix option writes
1758
+ // of `programs.git.enable` across test configs) can't fill the pool
1759
+ // before later tokens (`home.file`) get a slot.
1719
1760
  if (dynNamed.size < 12) {
1761
+ let tokenDyn = 0;
1720
1762
  for (const n of hits) {
1721
1763
  if (CALLABLE.has(n.kind) || !DYN_KINDS.has(n.kind) || dynNamed.has(n.id))
1722
1764
  continue;
1723
- if (hasHeuristicEdge(n.id))
1765
+ if (hasHeuristicEdge(n.id)) {
1724
1766
  dynNamed.set(n.id, n);
1725
- if (dynNamed.size >= 12)
1767
+ tokenDyn++;
1768
+ }
1769
+ if (dynNamed.size >= 12 || tokenDyn >= 4)
1726
1770
  break;
1727
1771
  }
1728
1772
  }
@@ -2353,9 +2397,12 @@ class ToolHandler {
2353
2397
  * tax on small projects while earning its keep on large ones.
2354
2398
  */
2355
2399
  async handleExplore(args) {
2356
- const query = this.validateString(args.query, 'query');
2357
- if (typeof query !== 'string')
2358
- return query;
2400
+ const rawQuery = this.validateString(args.query, 'query');
2401
+ if (typeof rawQuery !== 'string')
2402
+ return rawQuery;
2403
+ // One normalization point so the flow-builder, relevance search, and
2404
+ // ranking all see the same canonical spelling (Erlang `mod:fn/arity`).
2405
+ const query = normalizeQuerySpelling(rawQuery);
2359
2406
  const cg = this.getCodeGraph(args.projectPath);
2360
2407
  const projectRoot = cg.getProjectRoot();
2361
2408
  // Resolve adaptive output budget from project size. Falls back to the
@@ -2429,11 +2476,24 @@ class ToolHandler {
2429
2476
  // trace endpoint picker uses) and inject it as an entry, so every symbol the
2430
2477
  // agent explicitly named is in the subgraph and its file is scored.
2431
2478
  const namedSeedIds = new Set();
2479
+ // The subset of named seeds that earns the named-FIRST sort tier. We still
2480
+ // SEED every ≤3-def name (so RWR / flow ranking is unchanged), but only the
2481
+ // most-substantive def is tiered — a bare name's unrelated namesakes (Go's
2482
+ // `NewClient` = real client + test fake + xds pool) must not fill the tier
2483
+ // and crowd out the real answer file (grpc's `dialoptions.go`). Corroborated
2484
+ // overloads (the query also named the type) all earn it. (#1064)
2485
+ const tierSeedIds = new Set();
2432
2486
  {
2433
- const FILE_EXT = /\.(?:java|kt|kts|ts|tsx|js|jsx|mjs|cjs|cs|py|go|rb|php|swift|rs|cpp|cc|cxx|c|h|hpp|scala|lua|dart|vue|svelte|astro)$/i;
2487
+ const FILE_EXT = /\.(?:java|kt|kts|ts|tsx|js|jsx|mjs|cjs|cs|py|go|rb|php|swift|rs|cpp|cc|cxx|c|h|hpp|scala|lua|dart|vue|svelte|astro|erl|hrl)$/i;
2434
2488
  const CALLABLE = new Set(['method', 'function', 'component', 'constructor']);
2435
2489
  const isTestPath = (p) => /(^|\/)(tests?|specs?|__tests__|testdata|mocks?|fixtures?)\//i.test(p) || /\.(test|spec)\.[a-z]+$/i.test(p);
2436
2490
  const bodyLines = (n) => Math.max(0, (n.endLine ?? n.startLine) - n.startLine);
2491
+ const callerCount = (n) => { try {
2492
+ return cg.getCallers(n.id).length;
2493
+ }
2494
+ catch {
2495
+ return 0;
2496
+ } };
2437
2497
  const tokens = [...new Set(query.split(/[\s,()[\]]+/)
2438
2498
  .map((t) => t.replace(FILE_EXT, '').trim())
2439
2499
  .filter((t) => t.length >= 3 && /^[A-Za-z_$][\w$]*(?:(?:::|\.)[\w$]+)*$/.test(t)))].slice(0, 16);
@@ -2451,6 +2511,38 @@ class ToolHandler {
2451
2511
  const lc = ct.toLowerCase();
2452
2512
  return n.filePath.toLowerCase().includes(lc) || n.qualifiedName.toLowerCase().includes(lc);
2453
2513
  });
2514
+ // NL-stopword guard: this seeding treats every token as "a symbol the
2515
+ // agent named", but explore also takes natural-language questions, whose
2516
+ // ordinary English words collide with real callables — "…check the latest
2517
+ // version…" exact-matched a lone `check()` method, which then earned the
2518
+ // named-FIRST sort tier and displaced the corroborated answer files from
2519
+ // the whole render budget (the agent fell back to Read). A shape-precise
2520
+ // token (camelCase, PascalCase, snake_case, qualified) is an unambiguous
2521
+ // symbol reference and seeds unconditionally; a BARE lowercase word seeds
2522
+ // only where the query corroborates the file — another query token is
2523
+ // itself a symbol defined in that same file (the "check drain fire"
2524
+ // sibling-bag case), which an incidental English-word collision never is.
2525
+ const lcTokens = new Set(tokens.map((x) => x.toLowerCase()));
2526
+ const isPreciseToken = (x) => /[._$]|::|\//.test(x) || /[a-z][A-Z]/.test(x) || /^[A-Z]/.test(x);
2527
+ const fileNameSets = new Map();
2528
+ const coNamedInFile = (t, fp) => {
2529
+ let names = fileNameSets.get(fp);
2530
+ if (!names) {
2531
+ names = new Set();
2532
+ try {
2533
+ for (const n of cg.getNodesInFile(fp))
2534
+ names.add(n.name.toLowerCase());
2535
+ }
2536
+ catch { /* unreadable file entry — treat as uncorroborated */ }
2537
+ fileNameSets.set(fp, names);
2538
+ }
2539
+ const self = t.toLowerCase();
2540
+ for (const o of lcTokens) {
2541
+ if (o !== self && names.has(o))
2542
+ return true;
2543
+ }
2544
+ return false;
2545
+ };
2454
2546
  for (const t of tokens) {
2455
2547
  // Enumerate ALL defs of a bare token via the direct index, not FTS — a
2456
2548
  // 50+-overload name (tokio `poll`) ranks the wanted def (`Harness::poll`)
@@ -2459,9 +2551,17 @@ class ToolHandler {
2459
2551
  // codegraph_node's findSymbolMatches.) Qualified tokens keep findAllSymbols.
2460
2552
  const isQual = /[.\/]|::/.test(t);
2461
2553
  const raw = isQual ? this.findAllSymbols(cg, t).nodes : cg.getNodesByName(t);
2462
- const cands = raw
2554
+ let cands = raw
2463
2555
  .filter((n) => CALLABLE.has(n.kind) && !isTestPath(n.filePath))
2464
2556
  .sort((a, b) => (bodyLines(b) > 1 ? 1 : 0) - (bodyLines(a) > 1 ? 1 : 0) || bodyLines(b) - bodyLines(a));
2557
+ // Bare lowercase words only seed defs their query-siblings corroborate
2558
+ // (see the NL-stopword guard above). Filtering CANDS (not picks) applies
2559
+ // the guard uniformly to both branches below, including the >3-def
2560
+ // single-pick fallback — an uncorroborated bare `run` must not tier its
2561
+ // most-substantive namesake any more than a 1-def `check` may.
2562
+ if (!isPreciseToken(t)) {
2563
+ cands = cands.filter((n) => coNamedInFile(t, n.filePath));
2564
+ }
2465
2565
  // A specific name (<=3 defs) injects all its defs. An overloaded name
2466
2566
  // (`validate` = 10, `request` = 44) would flood the subgraph, so inject
2467
2567
  // only: the overloads whose file/class the query ALSO names (the agent
@@ -2469,12 +2569,23 @@ class ToolHandler {
2469
2569
  // capped; else fall back to the single most-substantive def. This is the
2470
2570
  // explore-side mirror of codegraph_node's overload disambiguation.
2471
2571
  let picks;
2572
+ let tierPicks; // subset that earns the named-first tier (#1064)
2472
2573
  if (cands.length <= 3) {
2473
2574
  picks = cands;
2575
+ // Centrality de-noise: tier the most-substantive def PLUS any co-named
2576
+ // def of comparable centrality (a real overload/wrapper — excalidraw's
2577
+ // `mutateElement` lives in mutateElement.ts, App.tsx AND Scene.ts, all
2578
+ // within ~2x callers). EXCLUDE a vastly-less-central namesake (Go's
2579
+ // `NewClient`: real client 492 callers vs xds-pool 11, test-fake 3 →
2580
+ // ratio <0.025) so it doesn't fill the tier and crowd out the answer.
2581
+ const counts = new Map(cands.map((c) => [c.id, callerCount(c)]));
2582
+ const maxCallers = Math.max(1, ...counts.values());
2583
+ tierPicks = cands.filter((c, i) => i === 0 || (counts.get(c.id) ?? 0) >= maxCallers * 0.25);
2474
2584
  }
2475
2585
  else {
2476
2586
  const ctx = cands.filter(inNamedContext);
2477
2587
  picks = ctx.length > 0 ? ctx.slice(0, 4) : cands.slice(0, 1);
2588
+ tierPicks = picks; // corroborated overloads (or the single fallback) all earn it
2478
2589
  }
2479
2590
  for (const n of picks) {
2480
2591
  if (!subgraph.nodes.has(n.id))
@@ -2486,6 +2597,8 @@ class ToolHandler {
2486
2597
  // so a named symbol FTS already gathered never sorted to the top.)
2487
2598
  namedSeedIds.add(n.id);
2488
2599
  }
2600
+ for (const n of tierPicks)
2601
+ tierSeedIds.add(n.id);
2489
2602
  }
2490
2603
  }
2491
2604
  // Step 2: Group nodes by file, score by relevance
@@ -2499,6 +2612,46 @@ class ToolHandler {
2499
2612
  if (entryNodeIds.has(edge.target))
2500
2613
  connectedToEntry.add(edge.source);
2501
2614
  }
2615
+ // CHANGE SURFACE (#1064): a named method's signature types — its parameter
2616
+ // and return types — are part of what you'd edit to "add a parameter to X",
2617
+ // yet they can be lexically dissimilar to the query ("add a parameter to
2618
+ // NewClient" shares no words with `dialoptions.go`, which defines NewClient's
2619
+ // `DialOption`) and sit a hop away. COLLECT them here from each named-seed
2620
+ // callable's outgoing signature edges (full graph — the type is often not in
2621
+ // the subgraph); the decision to surface one is DEFERRED to the buried-rescue
2622
+ // pass below, which fires only when the type's file would otherwise be
2623
+ // dropped — so a well-connected type (excalidraw's element types, Alamofire's
2624
+ // `DataRequest` on a flow query) is left to rank on its own and never
2625
+ // displaces a flow-central file. Bounded: only the few named seeds, only the
2626
+ // types in their signatures.
2627
+ const CALLABLE_KINDS = new Set(['method', 'function', 'component', 'constructor']);
2628
+ const TYPE_KINDS = new Set(['class', 'struct', 'interface', 'trait', 'protocol', 'enum', 'type_alias']);
2629
+ const SIG_EDGE = new Set(['references', 'type_of', 'returns']);
2630
+ const changeSurfaceCandidates = [];
2631
+ const seenChangeSurface = new Set();
2632
+ for (const seedId of tierSeedIds) {
2633
+ const seedNode = subgraph.nodes.get(seedId);
2634
+ if (!seedNode || !CALLABLE_KINDS.has(seedNode.kind))
2635
+ continue;
2636
+ let outs = [];
2637
+ try {
2638
+ outs = cg.getOutgoingEdges(seedId);
2639
+ }
2640
+ catch {
2641
+ continue;
2642
+ }
2643
+ for (const e of outs) {
2644
+ if (!SIG_EDGE.has(e.kind))
2645
+ continue;
2646
+ const tgt = cg.getNode(e.target);
2647
+ if (!tgt || !TYPE_KINDS.has(tgt.kind) || namedSeedIds.has(tgt.id))
2648
+ continue;
2649
+ if (seenChangeSurface.has(tgt.id))
2650
+ continue;
2651
+ seenChangeSurface.add(tgt.id);
2652
+ changeSurfaceCandidates.push(tgt);
2653
+ }
2654
+ }
2502
2655
  for (const node of subgraph.nodes.values()) {
2503
2656
  // Skip import/export nodes — they add noise without information
2504
2657
  if (node.kind === 'import' || node.kind === 'export')
@@ -2618,6 +2771,36 @@ class ToolHandler {
2618
2771
  if (n)
2619
2772
  entryFiles.add(n.filePath);
2620
2773
  }
2774
+ // Buried-rescue pass (#1064): surface a named method's signature type ONLY
2775
+ // when its file is genuinely buried — near-zero graph mass AND not lexically
2776
+ // matched. That is the invisible case (grpc's `DialOption` → `dialoptions.go`,
2777
+ // g≈0, 0 term hits): reachable but ranked nowhere, so the agent greps. A
2778
+ // well-connected type file (excalidraw element types, Alamofire `DataRequest`)
2779
+ // is NOT buried and is left alone — rescuing it would displace a flow-central
2780
+ // file (App.tsx, Validation.swift). Buried is judged on the PRE-rescue graph,
2781
+ // so injecting the type below can't make it look connected. A rescued file is
2782
+ // injected (so it renders), force-kept (gate + relevantFiles), and tiered.
2783
+ const changeSurfaceFiles = new Set();
2784
+ for (const t of changeSurfaceCandidates) {
2785
+ const fp = t.filePath;
2786
+ const buried = (fileGraphScore.get(fp) ?? 0) < maxGraph * 0.06
2787
+ && (fileTermHits.get(fp) ?? 0) < 2;
2788
+ if (!buried)
2789
+ continue;
2790
+ changeSurfaceFiles.add(fp);
2791
+ if (!subgraph.nodes.has(t.id))
2792
+ subgraph.nodes.set(t.id, t);
2793
+ let group = fileGroups.get(fp);
2794
+ if (!group) {
2795
+ group = { nodes: [], score: 0 };
2796
+ fileGroups.set(fp, group);
2797
+ }
2798
+ if (!group.nodes.some((n) => n.id === t.id))
2799
+ group.nodes.push(t);
2800
+ group.score = Math.max(group.score, 45);
2801
+ if (!relevantFiles.some(([f]) => f === fp))
2802
+ relevantFiles.push([fp, group]);
2803
+ }
2621
2804
  // Relevance gate (so the generous budget is a CEILING, not a target): keep a
2622
2805
  // file only if it is STRUCTURALLY relevant by ANY of:
2623
2806
  // - graph score within a fraction of the top (it's on/near the flow), OR
@@ -2634,6 +2817,7 @@ class ToolHandler {
2634
2817
  const gated = relevantFiles.filter(([fp]) => (fileGraphScore.get(fp) ?? 0) >= maxGraph * 0.06
2635
2818
  || centralFiles.has(fp)
2636
2819
  || entryFiles.has(fp)
2820
+ || changeSurfaceFiles.has(fp)
2637
2821
  || (fileTermHits.get(fp) ?? 0) >= 2);
2638
2822
  if (gated.length >= 2)
2639
2823
  relevantFiles = gated;
@@ -2648,11 +2832,16 @@ class ToolHandler {
2648
2832
  // in other files (`Validation.swift`), falls outside the budget, and the
2649
2833
  // agent Reads it. The named file is the answer — rank it at the top.
2650
2834
  const namedSeedFiles = new Set();
2651
- for (const id of namedSeedIds) {
2835
+ for (const id of tierSeedIds) {
2652
2836
  const n = subgraph.nodes.get(id);
2653
2837
  if (n)
2654
2838
  namedSeedFiles.add(n.filePath);
2655
2839
  }
2840
+ // A rescued change-surface file (only the genuinely-buried ones — see the
2841
+ // buried-rescue pass) is the lexically-dissimilar answer; give it the named
2842
+ // tier so it isn't buried under files that merely share surface words (#1064).
2843
+ for (const fp of changeSurfaceFiles)
2844
+ namedSeedFiles.add(fp);
2656
2845
  // Multi-term corroboration tier: a file that is BOTH (a) an entry/central file
2657
2846
  // (a search root, named seed, or graph-central hub — i.e. structurally part of
2658
2847
  // the answer) AND (b) matched by ≥2 DISTINCT query terms must not be buried by
@@ -2717,9 +2906,16 @@ class ToolHandler {
2717
2906
  const lines = [
2718
2907
  `**Exploration: ${query}**`,
2719
2908
  '',
2720
- `Found ${subgraph.nodes.size} symbols across ${fileGroups.size} files.`,
2909
+ // Curated summary filled in after the source loop (see below). We do NOT
2910
+ // report `subgraph.nodes.size` / `fileGroups.size` here: that's the raw
2911
+ // candidate gather, which a broad natural-language query inflates wildly
2912
+ // (260 symbols / 124 files on a 636-file repo) even though only a handful
2913
+ // render. Reporting the pool read as "260 results to wade through" when the
2914
+ // real, correctly-ranked answer is the few files below (#1046).
2915
+ '',
2721
2916
  '',
2722
2917
  ];
2918
+ const summaryLineIdx = 2;
2723
2919
  // Blast radius (always-on, compact): for the entry symbols, who depends on
2724
2920
  // them + which tests cover them — locations only, no source — so the agent
2725
2921
  // knows what to update/verify before editing without a separate call.
@@ -2821,6 +3017,9 @@ class ToolHandler {
2821
3017
  lines.push('');
2822
3018
  let totalChars = lines.join('\n').length;
2823
3019
  let filesIncluded = 0;
3020
+ // Paths we actually render source for below. Drives the curated header count
3021
+ // (#1046) — it must reflect what we show, not the raw candidate gather.
3022
+ const renderedFilePaths = [];
2824
3023
  let anyFileTrimmed = false;
2825
3024
  for (const [filePath, group] of sortedFiles) {
2826
3025
  if (filesIncluded >= maxFiles)
@@ -2972,6 +3171,7 @@ class ToolHandler {
2972
3171
  : 'skeleton (signatures only — codegraph_explore a name for its full body; do NOT Read)';
2973
3172
  lines.push(fileSectionHeader(filePath, `${names} · ${tag}`), '', '```' + lang, skel.join('\n'), '```', '');
2974
3173
  totalChars += skel.join('\n').length + 120;
3174
+ renderedFilePaths.push(filePath);
2975
3175
  filesIncluded++;
2976
3176
  continue;
2977
3177
  }
@@ -3018,6 +3218,7 @@ class ToolHandler {
3018
3218
  }
3019
3219
  lines.push(wholeHeader, '', '```' + lang, wholeSection, '```', '');
3020
3220
  totalChars += wholeSection.length + 200;
3221
+ renderedFilePaths.push(filePath);
3021
3222
  filesIncluded++;
3022
3223
  continue;
3023
3224
  }
@@ -3306,8 +3507,14 @@ class ToolHandler {
3306
3507
  lines.push('```');
3307
3508
  lines.push('');
3308
3509
  totalChars += fileSection.length + 200;
3510
+ renderedFilePaths.push(filePath);
3309
3511
  filesIncluded++;
3310
3512
  }
3513
+ // The curated header count is computed from the files that SURVIVE the final
3514
+ // truncation (see end of method) — `filesIncluded` can over-count when the
3515
+ // hard ceiling drops trailing sections — so leave a sentinel here and fill it
3516
+ // in once the output is final.
3517
+ lines[summaryLineIdx] = SUMMARY_SENTINEL;
3311
3518
  // Add remaining files as references (from both relevant and peripheral files).
3312
3519
  // Small projects (per budget) skip this — the relevant story already fits
3313
3520
  // in the source section, and a trailing pointer list is pure overhead.
@@ -3364,6 +3571,7 @@ class ToolHandler {
3364
3571
  // externalize territory.
3365
3572
  const output = flow.text + lines.join('\n');
3366
3573
  const hardCeiling = Math.min(Math.round(budget.maxOutputChars * 1.5), 25000);
3574
+ let finalText;
3367
3575
  if (output.length > hardCeiling) {
3368
3576
  // Cut at a FILE-SECTION boundary (the last ``**` `` file header before the
3369
3577
  // ceiling) so we drop whole trailing file-sections rather than slicing
@@ -3374,9 +3582,30 @@ class ToolHandler {
3374
3582
  const lastSection = cut.lastIndexOf('\n' + FILE_SECTION_PREFIX);
3375
3583
  const boundary = lastSection > hardCeiling * 0.5 ? lastSection : cut.lastIndexOf('\n');
3376
3584
  const safe = boundary > 0 ? cut.slice(0, boundary) : cut;
3377
- return this.textResult(safe + '\n\n... (output truncated to budget; the source above is complete and verbatim — treat it as already Read. For any area not covered, run another codegraph_explore with the specific names — do NOT Read these files.)');
3585
+ finalText = safe + '\n\n... (output truncated to budget; the source above is complete and verbatim — treat it as already Read. For any area not covered, run another codegraph_explore with the specific names — do NOT Read these files.)';
3378
3586
  }
3379
- return this.textResult(output);
3587
+ else {
3588
+ finalText = output;
3589
+ }
3590
+ // Curated header (#1046): substitute the sentinel with the count of files
3591
+ // whose source SURVIVES in the final text — not `subgraph`/`fileGroups` (the
3592
+ // raw gather a broad query inflates) and not `filesIncluded` (which can
3593
+ // over-count when the ceiling above drops trailing sections). A file counts
3594
+ // only if its section header is still present; its relevant (non-import)
3595
+ // symbols are summed for N. Files we couldn't fit are still named under "Not
3596
+ // shown above" + the budget note, so nothing is silently dropped.
3597
+ const survivors = renderedFilePaths.filter((fp) => finalText.includes(`${FILE_SECTION_PREFIX}${fp}\``));
3598
+ const shownSymbols = survivors.reduce((sum, fp) => {
3599
+ const g = fileGroups.get(fp);
3600
+ if (!g)
3601
+ return sum;
3602
+ return sum + new Set(g.nodes.filter((n) => n.kind !== 'import' && n.kind !== 'export').map((n) => n.id)).size;
3603
+ }, 0);
3604
+ const summaryLine = survivors.length > 0
3605
+ ? `Found ${shownSymbols} symbol${shownSymbols === 1 ? '' : 's'} across ${survivors.length} file${survivors.length === 1 ? '' : 's'}.`
3606
+ : `Found ${subgraph.nodes.size} symbol${subgraph.nodes.size === 1 ? '' : 's'} across ${fileGroups.size} file${fileGroups.size === 1 ? '' : 's'}.`;
3607
+ finalText = finalText.replace(SUMMARY_SENTINEL, summaryLine);
3608
+ return this.textResult(finalText);
3380
3609
  }
3381
3610
  /**
3382
3611
  * Handle codegraph_node
@@ -3726,6 +3955,23 @@ class ToolHandler {
3726
3955
  lines.push(`**Journal mode:** ⚠ ${journalMode || 'unknown'} — WAL not active, so reads ` +
3727
3956
  `can block on a concurrent write (WAL appears unsupported on this filesystem)`);
3728
3957
  }
3958
+ // A newer release exists (#1243) — status is where users and agents look
3959
+ // when something seems off, so surface the drift here too. Cheap memoized
3960
+ // cache read; absent entirely when up to date or opted out.
3961
+ const updateNotice = (0, update_check_1.getUpdateNotice)();
3962
+ if (updateNotice) {
3963
+ lines.push(`**Update available:** ${updateNotice}`);
3964
+ }
3965
+ // Non-zero at rest means a resolution pass was interrupted mid-run, so
3966
+ // some files' call/impact edges are missing until the next sync sweeps
3967
+ // the leftovers (#1187). Surface it — an agent trusting an incomplete
3968
+ // blast radius is worse than one that knows to re-sync.
3969
+ const pendingRefs = cg.getPendingReferenceCount();
3970
+ if (pendingRefs > 0) {
3971
+ lines.push(`**Pending resolution:** ⚠ ${pendingRefs} references from an interrupted ` +
3972
+ `index run — some caller/impact edges are missing until the next sync ` +
3973
+ `(any file change triggers it, or run \`codegraph sync\`)`);
3974
+ }
3729
3975
  lines.push('', '**Nodes by Kind:**');
3730
3976
  for (const [kind, count] of Object.entries(stats.nodesByKind)) {
3731
3977
  if (count > 0) {
@@ -4039,6 +4285,26 @@ class ToolHandler {
4039
4285
  * results across all matching symbols (e.g., multiple classes with an `execute` method).
4040
4286
  */
4041
4287
  findAllSymbols(cg, symbol) {
4288
+ // Nix option paths: the declaration is stored as `options.<path>` and
4289
+ // config writes carry longer/quoted tails (`<path>."git/config".text`),
4290
+ // so a dotted option token (`xdg.configFile`, `launchd.user.agents`) has
4291
+ // no exact-name node and would degrade to bare-tail FTS soup — burying
4292
+ // the declaration hub the nix-option-path edges hang off. Resolve the
4293
+ // convention directly: declaration first, then the exact write, then a
4294
+ // capped prefix scan of write sites. Three index hits; non-nix graphs
4295
+ // fall straight through.
4296
+ if (/^[a-z][\w'-]*(?:\.[\w'-]+)+$/.test(symbol)) {
4297
+ const optionHits = [
4298
+ ...cg.getNodesByName(`options.${symbol}`),
4299
+ ...cg.getNodesByName(symbol),
4300
+ ...cg.getNodesByNamePrefix(`${symbol}.`, 12),
4301
+ ].filter((n) => n.language === 'nix');
4302
+ if (optionHits.length > 0) {
4303
+ const seen = new Set();
4304
+ const nodes = optionHits.filter((n) => !seen.has(n.id) && !!seen.add(n.id)).slice(0, 10);
4305
+ return { nodes, note: '' };
4306
+ }
4307
+ }
4042
4308
  let results = cg.searchNodes(symbol, { limit: 50 });
4043
4309
  // Mirror the fallback in `findSymbol` for qualified queries — FTS
4044
4310
  // strips colons, so a module-qualified lookup needs a second pass