gitnexus 1.6.5-rc.8 → 1.6.5

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/dist/_shared/scope-resolution/finalize-algorithm.js +10 -2
  2. package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
  3. package/dist/_shared/scope-resolution/method-dispatch-index.d.ts +26 -0
  4. package/dist/_shared/scope-resolution/method-dispatch-index.d.ts.map +1 -1
  5. package/dist/_shared/scope-resolution/method-dispatch-index.js +22 -3
  6. package/dist/_shared/scope-resolution/method-dispatch-index.js.map +1 -1
  7. package/dist/_shared/scope-resolution/registries/lookup-core.js +18 -1
  8. package/dist/_shared/scope-resolution/registries/lookup-core.js.map +1 -1
  9. package/dist/_shared/scope-resolution/symbol-definition.d.ts +2 -0
  10. package/dist/_shared/scope-resolution/symbol-definition.d.ts.map +1 -1
  11. package/dist/cli/ai-context.d.ts +1 -0
  12. package/dist/cli/ai-context.js +70 -16
  13. package/dist/cli/analyze.d.ts +30 -2
  14. package/dist/cli/analyze.js +45 -5
  15. package/dist/cli/index.js +8 -1
  16. package/dist/cli/setup.js +18 -0
  17. package/dist/cli/wiki.d.ts +2 -0
  18. package/dist/cli/wiki.js +11 -0
  19. package/dist/core/augmentation/engine.js +24 -4
  20. package/dist/core/embeddings/http-client.js +22 -6
  21. package/dist/core/incremental/shadow-candidates.d.ts +44 -0
  22. package/dist/core/incremental/shadow-candidates.js +74 -0
  23. package/dist/core/incremental/subgraph-extract.d.ts +64 -0
  24. package/dist/core/incremental/subgraph-extract.js +111 -0
  25. package/dist/core/ingestion/call-processor.d.ts +12 -1
  26. package/dist/core/ingestion/call-processor.js +183 -47
  27. package/dist/core/ingestion/class-extractors/configs/c-cpp.js +38 -0
  28. package/dist/core/ingestion/class-extractors/generic.js +8 -0
  29. package/dist/core/ingestion/class-types.d.ts +15 -0
  30. package/dist/core/ingestion/community-processor.js +18 -0
  31. package/dist/core/ingestion/import-resolvers/standard.d.ts +5 -0
  32. package/dist/core/ingestion/import-resolvers/standard.js +31 -1
  33. package/dist/core/ingestion/import-resolvers/utils.js +4 -0
  34. package/dist/core/ingestion/languages/c-cpp.js +20 -2
  35. package/dist/core/ingestion/languages/cpp/adl.d.ts +141 -0
  36. package/dist/core/ingestion/languages/cpp/adl.js +478 -0
  37. package/dist/core/ingestion/languages/cpp/arity-metadata.d.ts +18 -0
  38. package/dist/core/ingestion/languages/cpp/arity-metadata.js +170 -0
  39. package/dist/core/ingestion/languages/cpp/arity.d.ts +17 -0
  40. package/dist/core/ingestion/languages/cpp/arity.js +31 -0
  41. package/dist/core/ingestion/languages/cpp/captures.d.ts +2 -0
  42. package/dist/core/ingestion/languages/cpp/captures.js +1131 -0
  43. package/dist/core/ingestion/languages/cpp/conversion-rank.d.ts +31 -0
  44. package/dist/core/ingestion/languages/cpp/conversion-rank.js +47 -0
  45. package/dist/core/ingestion/languages/cpp/file-local-linkage.d.ts +118 -0
  46. package/dist/core/ingestion/languages/cpp/file-local-linkage.js +266 -0
  47. package/dist/core/ingestion/languages/cpp/header-scan.d.ts +8 -0
  48. package/dist/core/ingestion/languages/cpp/header-scan.js +50 -0
  49. package/dist/core/ingestion/languages/cpp/import-decomposer.d.ts +19 -0
  50. package/dist/core/ingestion/languages/cpp/import-decomposer.js +111 -0
  51. package/dist/core/ingestion/languages/cpp/import-target.d.ts +10 -0
  52. package/dist/core/ingestion/languages/cpp/import-target.js +13 -0
  53. package/dist/core/ingestion/languages/cpp/index.d.ts +11 -0
  54. package/dist/core/ingestion/languages/cpp/index.js +11 -0
  55. package/dist/core/ingestion/languages/cpp/inline-namespaces.d.ts +67 -0
  56. package/dist/core/ingestion/languages/cpp/inline-namespaces.js +176 -0
  57. package/dist/core/ingestion/languages/cpp/interpret.d.ts +35 -0
  58. package/dist/core/ingestion/languages/cpp/interpret.js +113 -0
  59. package/dist/core/ingestion/languages/cpp/merge-bindings.d.ts +13 -0
  60. package/dist/core/ingestion/languages/cpp/merge-bindings.js +29 -0
  61. package/dist/core/ingestion/languages/cpp/query.d.ts +3 -0
  62. package/dist/core/ingestion/languages/cpp/query.js +508 -0
  63. package/dist/core/ingestion/languages/cpp/range-bindings.d.ts +20 -0
  64. package/dist/core/ingestion/languages/cpp/range-bindings.js +212 -0
  65. package/dist/core/ingestion/languages/cpp/scope-resolver.d.ts +17 -0
  66. package/dist/core/ingestion/languages/cpp/scope-resolver.js +246 -0
  67. package/dist/core/ingestion/languages/cpp/simple-hooks.d.ts +24 -0
  68. package/dist/core/ingestion/languages/cpp/simple-hooks.js +62 -0
  69. package/dist/core/ingestion/languages/cpp/two-phase-lookup.d.ts +76 -0
  70. package/dist/core/ingestion/languages/cpp/two-phase-lookup.js +195 -0
  71. package/dist/core/ingestion/languages/java/arity-metadata.d.ts +18 -0
  72. package/dist/core/ingestion/languages/java/arity-metadata.js +40 -0
  73. package/dist/core/ingestion/languages/java/arity.d.ts +10 -0
  74. package/dist/core/ingestion/languages/java/arity.js +24 -0
  75. package/dist/core/ingestion/languages/java/cache-stats.d.ts +15 -0
  76. package/dist/core/ingestion/languages/java/cache-stats.js +26 -0
  77. package/dist/core/ingestion/languages/java/captures.d.ts +17 -0
  78. package/dist/core/ingestion/languages/java/captures.js +187 -0
  79. package/dist/core/ingestion/languages/java/import-decomposer.d.ts +18 -0
  80. package/dist/core/ingestion/languages/java/import-decomposer.js +85 -0
  81. package/dist/core/ingestion/languages/java/import-target.d.ts +17 -0
  82. package/dist/core/ingestion/languages/java/import-target.js +100 -0
  83. package/dist/core/ingestion/languages/java/index.d.ts +29 -0
  84. package/dist/core/ingestion/languages/java/index.js +29 -0
  85. package/dist/core/ingestion/languages/java/interpret.d.ts +13 -0
  86. package/dist/core/ingestion/languages/java/interpret.js +131 -0
  87. package/dist/core/ingestion/languages/java/merge-bindings.d.ts +12 -0
  88. package/dist/core/ingestion/languages/java/merge-bindings.js +40 -0
  89. package/dist/core/ingestion/languages/java/query.d.ts +30 -0
  90. package/dist/core/ingestion/languages/java/query.js +192 -0
  91. package/dist/core/ingestion/languages/java/receiver-binding.d.ts +11 -0
  92. package/dist/core/ingestion/languages/java/receiver-binding.js +95 -0
  93. package/dist/core/ingestion/languages/java/scope-resolver.d.ts +50 -0
  94. package/dist/core/ingestion/languages/java/scope-resolver.js +74 -0
  95. package/dist/core/ingestion/languages/java/simple-hooks.d.ts +13 -0
  96. package/dist/core/ingestion/languages/java/simple-hooks.js +34 -0
  97. package/dist/core/ingestion/languages/java.js +11 -0
  98. package/dist/core/ingestion/languages/php/arity-metadata.d.ts +28 -0
  99. package/dist/core/ingestion/languages/php/arity-metadata.js +63 -0
  100. package/dist/core/ingestion/languages/php/arity.d.ts +25 -0
  101. package/dist/core/ingestion/languages/php/arity.js +40 -0
  102. package/dist/core/ingestion/languages/php/cache-stats.d.ts +15 -0
  103. package/dist/core/ingestion/languages/php/cache-stats.js +26 -0
  104. package/dist/core/ingestion/languages/php/captures.d.ts +34 -0
  105. package/dist/core/ingestion/languages/php/captures.js +739 -0
  106. package/dist/core/ingestion/languages/php/import-decomposer.d.ts +28 -0
  107. package/dist/core/ingestion/languages/php/import-decomposer.js +265 -0
  108. package/dist/core/ingestion/languages/php/import-target.d.ts +47 -0
  109. package/dist/core/ingestion/languages/php/import-target.js +100 -0
  110. package/dist/core/ingestion/languages/php/index.d.ts +68 -0
  111. package/dist/core/ingestion/languages/php/index.js +72 -0
  112. package/dist/core/ingestion/languages/php/interpret.d.ts +36 -0
  113. package/dist/core/ingestion/languages/php/interpret.js +241 -0
  114. package/dist/core/ingestion/languages/php/merge-bindings.d.ts +19 -0
  115. package/dist/core/ingestion/languages/php/merge-bindings.js +47 -0
  116. package/dist/core/ingestion/languages/php/namespace-siblings.d.ts +51 -0
  117. package/dist/core/ingestion/languages/php/namespace-siblings.js +288 -0
  118. package/dist/core/ingestion/languages/php/query.d.ts +32 -0
  119. package/dist/core/ingestion/languages/php/query.js +326 -0
  120. package/dist/core/ingestion/languages/php/receiver-binding.d.ts +36 -0
  121. package/dist/core/ingestion/languages/php/receiver-binding.js +128 -0
  122. package/dist/core/ingestion/languages/php/scope-resolver.d.ts +23 -0
  123. package/dist/core/ingestion/languages/php/scope-resolver.js +358 -0
  124. package/dist/core/ingestion/languages/php/simple-hooks.d.ts +42 -0
  125. package/dist/core/ingestion/languages/php/simple-hooks.js +111 -0
  126. package/dist/core/ingestion/languages/php.d.ts +0 -7
  127. package/dist/core/ingestion/languages/php.js +15 -0
  128. package/dist/core/ingestion/markdown-processor.js +6 -1
  129. package/dist/core/ingestion/model/symbol-table.d.ts +1 -0
  130. package/dist/core/ingestion/model/symbol-table.js +3 -0
  131. package/dist/core/ingestion/parsing-processor.d.ts +22 -2
  132. package/dist/core/ingestion/parsing-processor.js +123 -50
  133. package/dist/core/ingestion/pipeline-phases/cross-file-impl.js +54 -2
  134. package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +5 -0
  135. package/dist/core/ingestion/pipeline-phases/parse-impl.js +119 -11
  136. package/dist/core/ingestion/pipeline-phases/parse.d.ts +14 -0
  137. package/dist/core/ingestion/pipeline.d.ts +13 -0
  138. package/dist/core/ingestion/registry-primary-flag.js +2 -0
  139. package/dist/core/ingestion/scope-extractor.js +4 -0
  140. package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +167 -0
  141. package/dist/core/ingestion/scope-resolution/contract/scope-resolver.js +3 -0
  142. package/dist/core/ingestion/scope-resolution/graph-bridge/ids.d.ts +1 -0
  143. package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +12 -0
  144. package/dist/core/ingestion/scope-resolution/graph-bridge/method-dispatch.d.ts +1 -1
  145. package/dist/core/ingestion/scope-resolution/graph-bridge/method-dispatch.js +12 -2
  146. package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +16 -0
  147. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +36 -0
  148. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +204 -13
  149. package/dist/core/ingestion/scope-resolution/passes/imported-return-types.js +1 -1
  150. package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.d.ts +55 -4
  151. package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.js +186 -5
  152. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +10 -1
  153. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +207 -9
  154. package/dist/core/ingestion/scope-resolution/pipeline/phase.js +13 -1
  155. package/dist/core/ingestion/scope-resolution/pipeline/registry.js +6 -0
  156. package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +17 -0
  157. package/dist/core/ingestion/scope-resolution/pipeline/run.js +86 -8
  158. package/dist/core/ingestion/scope-resolution/scope/walkers.d.ts +30 -0
  159. package/dist/core/ingestion/scope-resolution/scope/walkers.js +90 -8
  160. package/dist/core/ingestion/tree-sitter-queries.d.ts +2 -2
  161. package/dist/core/ingestion/tree-sitter-queries.js +23 -0
  162. package/dist/core/ingestion/utils/ast-helpers.js +6 -1
  163. package/dist/core/ingestion/utils/template-arguments.d.ts +11 -0
  164. package/dist/core/ingestion/utils/template-arguments.js +65 -0
  165. package/dist/core/ingestion/workers/parse-worker.d.ts +3 -0
  166. package/dist/core/ingestion/workers/parse-worker.js +42 -1
  167. package/dist/core/lbug/lbug-adapter.d.ts +39 -0
  168. package/dist/core/lbug/lbug-adapter.js +348 -48
  169. package/dist/core/run-analyze.d.ts +2 -0
  170. package/dist/core/run-analyze.js +323 -29
  171. package/dist/core/search/hybrid-search.d.ts +3 -0
  172. package/dist/core/search/hybrid-search.js +23 -6
  173. package/dist/core/wiki/generator.js +4 -3
  174. package/dist/core/wiki/html-viewer.js +2 -1
  175. package/dist/core/wiki/llm-client.d.ts +4 -0
  176. package/dist/core/wiki/llm-client.js +3 -3
  177. package/dist/core/wiki/mermaid-sanitizer.d.ts +2 -0
  178. package/dist/core/wiki/mermaid-sanitizer.js +100 -0
  179. package/dist/mcp/local/local-backend.js +20 -7
  180. package/dist/storage/file-hash.d.ts +47 -0
  181. package/dist/storage/file-hash.js +86 -0
  182. package/dist/storage/parse-cache.d.ts +73 -0
  183. package/dist/storage/parse-cache.js +253 -0
  184. package/dist/storage/repo-manager.d.ts +41 -1
  185. package/dist/storage/repo-manager.js +61 -6
  186. package/hooks/claude/gitnexus-hook.cjs +42 -4
  187. package/hooks/claude/hook-db-lock-probe.cjs +238 -0
  188. package/hooks/claude/hook-lock.cjs +119 -0
  189. package/hooks/claude/win-rm-list-json.ps1 +76 -0
  190. package/package.json +1 -1
  191. package/scripts/build.js +6 -2
  192. package/vendor/node_modules/node-addon-api/node_addon_api.target.mk +16 -16
  193. package/vendor/node_modules/node-addon-api/node_addon_api_except.target.mk +16 -16
  194. package/vendor/node_modules/node-addon-api/node_addon_api_except_all.target.mk +16 -16
  195. package/vendor/node_modules/node-addon-api/node_addon_api_maybe.target.mk +16 -16
  196. package/web/assets/{agent-BpHQleHE.js → agent-D2kLt6Dl.js} +91 -91
  197. package/web/assets/architecture-7EHR7CIX-6QZW5X65-BETj2x4g.js +1 -0
  198. package/web/assets/architectureDiagram-UL44E2DR-DvIkEGkp.js +36 -0
  199. package/web/assets/blockDiagram-7IZFK4PR-B4niSLvR.js +132 -0
  200. package/web/assets/{c4Diagram-DFAF54RM-DeJV1rCn.js → c4Diagram-Y2BXMSZH-DIzEXalR.js} +6 -6
  201. package/web/assets/chunk-2T2R6R2M-n6s9JZqv.js +4 -0
  202. package/web/assets/chunk-2UTLFMKG-CMBB1TMN.js +1 -0
  203. package/web/assets/{chunk-7RZVMHOQ-BdIU-RGO.js → chunk-3SSMPTDK-BzGeeheI.js} +1 -1
  204. package/web/assets/chunk-4R4BOZG6-mKhL59ul.js +159 -0
  205. package/web/assets/chunk-5IMINLNL-CnTLsXIV.js +1 -0
  206. package/web/assets/chunk-5VCL7Z4A-w1BCx98Z.js +1 -0
  207. package/web/assets/chunk-6764PJDD-ChwMM2z4.js +1 -0
  208. package/web/assets/chunk-67TQ5CYL-CChC2cAv.js +124 -0
  209. package/web/assets/chunk-7J6CGLKN-DT-b53FT.js +10 -0
  210. package/web/assets/chunk-7W6UQGC5-CgFyfZ6k.js +1 -0
  211. package/web/assets/chunk-AQ6EADP3-CCFje6lL.js +1 -0
  212. package/web/assets/{chunk-KSICW3F5-C2tZmXwv.js → chunk-AZZRMDJM-5E9ARdDQ.js} +1 -1
  213. package/web/assets/chunk-C62D2QBJ-CDAWj26E.js +1 -0
  214. package/web/assets/chunk-CEXFNPSA-D68Tk6ls.js +1 -0
  215. package/web/assets/chunk-INKRHTLW-ELpfuk9h.js +70 -0
  216. package/web/assets/chunk-J5EP6P6S-DxWW0yvu.js +1 -0
  217. package/web/assets/{chunk-AEOMTBSW-D7qjBMHW.js → chunk-JQRUD6KW-Dcq_Qnyy.js} +1 -1
  218. package/web/assets/chunk-KGFNY3KK-W-VR57xb.js +62 -0
  219. package/web/assets/chunk-KGYTTC2M-C6PHeuay.js +1 -0
  220. package/web/assets/chunk-KNLZD3CH-BuZBOcso.js +1 -0
  221. package/web/assets/chunk-KRXBNO2N-DH2NPM7I.js +1 -0
  222. package/web/assets/chunk-LCXTWHL2-CqJ0oo1x.js +231 -0
  223. package/web/assets/chunk-LII3EMHJ-3X33tCpU.js +1 -0
  224. package/web/assets/chunk-QA3QBVWF-D5Ha3GgB.js +2 -0
  225. package/web/assets/chunk-RERM46MO-DQNbXtfw.js +1 -0
  226. package/web/assets/chunk-RG4AUYOV-D0M6vdq9.js +206 -0
  227. package/web/assets/chunk-RKZBBQEN-BmTPLSyv.js +1 -0
  228. package/web/assets/chunk-RLI5ZMPA-DExu2DOK.js +1 -0
  229. package/web/assets/chunk-T2UQINTJ-kGYG7ppP.js +1 -0
  230. package/web/assets/chunk-T5OCTHI4--9wWpVws.js +1 -0
  231. package/web/assets/chunk-UP6H54XL-DsKdC6jC.js +1 -0
  232. package/web/assets/chunk-UXSXWOXI-DR81EqLr.js +1 -0
  233. package/web/assets/chunk-UY5QBCOK-Du-c56gs.js +1 -0
  234. package/web/assets/chunk-W44A43WB-lrCpuupA.js +1 -0
  235. package/web/assets/chunk-ZXARS5L4-CSZRiyOf.js +1 -0
  236. package/web/assets/classDiagram-KGZ6W3CR-BB-saqC1.js +1 -0
  237. package/web/assets/classDiagram-v2-72OJOZXJ-Bp2bAlS5.js +1 -0
  238. package/web/assets/cose-bilkent-UX7MHV2Q-BHv2bbtl.js +1 -0
  239. package/web/assets/dagre-ND4H6XIP-DsIr9MOv.js +4 -0
  240. package/web/assets/diagram-3NCE3AQN-BUxnDPOY.js +43 -0
  241. package/web/assets/diagram-GF46GFSD-BJTyqqvI.js +24 -0
  242. package/web/assets/diagram-HNR7UZ2L-fUWreZzx.js +3 -0
  243. package/web/assets/diagram-QXG6HAR7-DilMHamP.js +24 -0
  244. package/web/assets/diagram-WEQXMOUZ-8KUrarg1.js +10 -0
  245. package/web/assets/erDiagram-L5TCEMPS-Doj9mSiW.js +85 -0
  246. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-B3myHUst.js +1 -0
  247. package/web/assets/{flowDiagram-OTCZ4VVT-aAZw4c_M.js → flowDiagram-H6V6AXG4-BOSR-i3p.js} +12 -12
  248. package/web/assets/ganttDiagram-JCBTUEKG-BHQssTz6.js +292 -0
  249. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DF3rtf4A.js +1 -0
  250. package/web/assets/gitGraphDiagram-S2ZK5IYY-CCwVLT__.js +106 -0
  251. package/web/assets/index-j4-NuleT.js +623 -0
  252. package/web/assets/info-J43DQDTF-KCYPFFUO-R4XV_akJ.js +1 -0
  253. package/web/assets/infoDiagram-3YFTVSEB-Ce_TvtaV.js +2 -0
  254. package/web/assets/{ishikawaDiagram-YMYX4NHK-BF8AtDaj.js → ishikawaDiagram-BNXS4ZKH-4MXIDCSF.js} +6 -6
  255. package/web/assets/journeyDiagram-M6C3CM3L-DNPYCpvq.js +139 -0
  256. package/web/assets/kanban-definition-75IXJCU3-yYdfm8Kk.js +89 -0
  257. package/web/assets/{katex-GD7MH7QM-CJiOjBBJ.js → katex-K3KEBU37-CrVLz8l7.js} +1 -1
  258. package/web/assets/mindmap-definition-2TDM6QVE-DFNEKM77.js +96 -0
  259. package/web/assets/packet-YPE3B663-LP52Z2RK-CgQPdNZa.js +1 -0
  260. package/web/assets/pie-LRSECV5Y-TCRJHUBD-BzWOwc_c.js +1 -0
  261. package/web/assets/pieDiagram-CU6KROY3-iZAqpvhd.js +30 -0
  262. package/web/assets/quadrantDiagram-VICAPDV7-bAm6Hi_5.js +7 -0
  263. package/web/assets/radar-GUYGQ44K-RDLRG3WG-B7KG0FN7.js +1 -0
  264. package/web/assets/requirementDiagram-JXO7QTGE-CtDijhnf.js +84 -0
  265. package/web/assets/sankeyDiagram-URQDO5SZ-LFJz53u5.js +40 -0
  266. package/web/assets/sequenceDiagram-VS2MUI6T-BdjvyCHM.js +162 -0
  267. package/web/assets/stateDiagram-7D4R322I-e5odN9fG.js +1 -0
  268. package/web/assets/stateDiagram-v2-36443NZ5-vPsvjR2D.js +1 -0
  269. package/web/assets/timeline-definition-O6YCAMPW-DPAksNQp.js +120 -0
  270. package/web/assets/treeView-BLDUP644-QA4HXRO3-CRSxEwLO.js +1 -0
  271. package/web/assets/treemap-LRROVOQU-LLAWBHMP-a0PfKoVn.js +1 -0
  272. package/web/assets/vennDiagram-MWXL3ELB-Dtlfdt7J.js +34 -0
  273. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-BKQ6e5mC.js +1 -0
  274. package/web/assets/wardleyDiagram-CUQ6CDDI-B23uRMUC.js +78 -0
  275. package/web/assets/{xychartDiagram-ZHJ5623Y-DZ7fP1_3.js → xychartDiagram-N2JHSOCM-DxwHeksW.js} +6 -6
  276. package/web/index.html +13 -2
  277. package/web/assets/architecture-YZFGNWBL-S5CXDPWN-BUzkWgDl.js +0 -1
  278. package/web/assets/architectureDiagram-EMZXCZ2Q-CXbzok1G.js +0 -36
  279. package/web/assets/blockDiagram-IGV67L2C-DA1QJ4ZB.js +0 -132
  280. package/web/assets/chunk-3GS5O3IE-B8hpnia8.js +0 -231
  281. package/web/assets/chunk-3YCYZ6SJ-B-BVu21C.js +0 -1
  282. package/web/assets/chunk-6NTNNK5N-DW-jYSDr.js +0 -1
  283. package/web/assets/chunk-A34GCYZU-BbZl-IKy.js +0 -1
  284. package/web/assets/chunk-DJ7UZH7F-B5tMfF87.js +0 -1
  285. package/web/assets/chunk-DKKBVRCY-Djm-6K_e.js +0 -4
  286. package/web/assets/chunk-DU5LTGQ6-QPoynYcp.js +0 -1
  287. package/web/assets/chunk-FXACKDTF-jieSmbe2.js +0 -159
  288. package/web/assets/chunk-H3VCZNTA-8EMHZ3SV.js +0 -1
  289. package/web/assets/chunk-HN6EAY2L-CgE_agsD.js +0 -1
  290. package/web/assets/chunk-O5ABG6QK-DEZV1O19.js +0 -1
  291. package/web/assets/chunk-PK6DOVAG-BXv0JnsJ.js +0 -206
  292. package/web/assets/chunk-RNJOYNJ4-BiBkF9dN.js +0 -1
  293. package/web/assets/chunk-RWUO3TPN-DTWzAhQ1.js +0 -1
  294. package/web/assets/chunk-TBF5ZNIQ-BSl6s9lT.js +0 -1
  295. package/web/assets/chunk-TU3PZOEN-DE5Qhc0N.js +0 -1
  296. package/web/assets/chunk-TYMNRAUI-D1NDLIMG.js +0 -1
  297. package/web/assets/chunk-VELTKBKT-C9dVN39o.js +0 -1
  298. package/web/assets/chunk-W7ZLLLMY-Bu-cdLzs.js +0 -1
  299. package/web/assets/chunk-WSB5WSVC-Dor71SOz.js +0 -1
  300. package/web/assets/chunk-XGPFEOL4-CUonLRle.js +0 -1
  301. package/web/assets/classDiagram-PPOCWD7C-Cdd6UdVv.js +0 -1
  302. package/web/assets/classDiagram-v2-23LJLIIU-DNhxY2Ib.js +0 -1
  303. package/web/assets/cose-bilkent-PNC4W37J-DdZq7Qz_.js +0 -1
  304. package/web/assets/dagre-E77IOHMT-Cfj_6e17.js +0 -4
  305. package/web/assets/diagram-H7BISOXX-BNvpsrBv.js +0 -43
  306. package/web/assets/diagram-JC5VWROH-Cn0rtDbJ.js +0 -24
  307. package/web/assets/diagram-LXUTUG65-CHfoVKNm.js +0 -10
  308. package/web/assets/diagram-WEHSV5V5-BLxHksnu.js +0 -24
  309. package/web/assets/erDiagram-GCSMX5X6-DfdN6iqF.js +0 -85
  310. package/web/assets/ganttDiagram-MUNLMDZQ-BEfC_7Or.js +0 -292
  311. package/web/assets/gitGraph-7Q5UKJZL-54BCDZD5-B6ZeRLP0.js +0 -1
  312. package/web/assets/gitGraphDiagram-3HKGZ4G3-CG0kC8Q5.js +0 -106
  313. package/web/assets/index-3NUCUW2s.js +0 -886
  314. package/web/assets/info-OMHHGYJF-BF2H5H6G-BIOsZy0W.js +0 -1
  315. package/web/assets/infoDiagram-MN7RKWGX-DUoMH-pq.js +0 -2
  316. package/web/assets/journeyDiagram-SO5T7YLQ-BW8oKa3N.js +0 -139
  317. package/web/assets/kanban-definition-LJHFXRCJ-DzbOsR-2.js +0 -89
  318. package/web/assets/mindmap-definition-2EUWGEK5-BIXGQALq.js +0 -96
  319. package/web/assets/packet-4T2RLAQJ-EV4IVRXR-Bs7ysNMU.js +0 -1
  320. package/web/assets/pie-ZZUOXDRM-N23DN5KN-Csi8nnbH.js +0 -1
  321. package/web/assets/pieDiagram-3IATQBI2-QY-u7P6a.js +0 -30
  322. package/web/assets/quadrantDiagram-E256RVCF-Di4aNiU8.js +0 -7
  323. package/web/assets/radar-PYXPWWZC-P6TP7ZYP-DJlyXh2-.js +0 -1
  324. package/web/assets/requirementDiagram-M5DCFWZL-CzUUrhQD.js +0 -84
  325. package/web/assets/sankeyDiagram-L3NBLAOT-D2fbMiIU.js +0 -10
  326. package/web/assets/sequenceDiagram-ZOUHS735-BNdkqguh.js +0 -157
  327. package/web/assets/stateDiagram-MLPALWAM-51_Q2w2L.js +0 -1
  328. package/web/assets/stateDiagram-v2-B5LQ5ZB2-8nHs2aNE.js +0 -1
  329. package/web/assets/timeline-definition-5SPVSISX-DkMiGj4Z.js +0 -120
  330. package/web/assets/treeView-SZITEDCU-5DXDK3XO-Cy6P0_CZ.js +0 -1
  331. package/web/assets/treemap-W4RFUUIX-WYLRDWKO-C_pp1R7A.js +0 -1
  332. package/web/assets/vennDiagram-IE5QUKF5-BCxMmf9q.js +0 -34
  333. package/web/assets/wardley-RL74JXVD-BCRCBASE-CMStJhpn.js +0 -1
  334. package/web/assets/wardleyDiagram-XU3VSMPF-ijlLF77s.js +0 -20
  335. /package/web/assets/{context-builder-CqQNhRj1.js → context-builder-_HS0v2ma.js} +0 -0
@@ -87,6 +87,9 @@
87
87
  * attempting emission (even on dedup-collapse), because the
88
88
  * per-(caller, target) collapse semantics require multiple call
89
89
  * sites in the same caller body not produce multiple edges.
90
+ * `preEmitInheritanceEdges` also pre-marks every `inherits` site so
91
+ * the generic bridge cannot remap class heritage into method-owned
92
+ * EXTENDS edges via `resolveCallerGraphId`.
90
93
  *
91
94
  * - **I3 — `propagateImportedReturnTypes` mutation timing + ordering.**
92
95
  * The pass mutates `Scope.typeBindings` (a plain `new Map(...)` from
@@ -253,6 +256,7 @@ import type { GraphNodeLookup } from '../graph-bridge/node-lookup.js';
253
256
  import { LanguageProvider } from '../../language-provider.js';
254
257
  import { ScopeResolutionIndexes } from '../../model/scope-resolution-indexes.js';
255
258
  import type { SemanticModel } from '../../model/semantic-model.js';
259
+ import type { ConversionRankFn } from '../passes/overload-narrowing.js';
256
260
  /** A LinearizeStrategy receives the full ancestor map so C3-style
257
261
  * algorithms (which need to merge each parent's MRO) can implement
258
262
  * themselves. Python's depth-first first-seen only consumes
@@ -342,6 +346,21 @@ export interface ScopeResolver {
342
346
  * inheritance).
343
347
  */
344
348
  buildMro(graph: KnowledgeGraph, parsedFiles: readonly ParsedFile[], nodeLookup: GraphNodeLookup): Map<string, string[]>;
349
+ /**
350
+ * Optional parallel MRO that EXCLUDES mixin-like augmentation (e.g., PHP
351
+ * traits). Returns the inheritance-only ancestor chain — the same kind
352
+ * of map as `buildMro` but built only from inheritance edges (EXTENDS).
353
+ *
354
+ * Used by the shared super-branch dispatch in `receiver-bound-calls`
355
+ * so that `parent::method()` walks the inheritance chain only, not the
356
+ * trait-augmented one. PHP semantics: `parent::` explicitly bypasses
357
+ * traits, even when a composed trait shadows a same-named parent method.
358
+ *
359
+ * Languages without mixin-like semantics leave this undefined — callers
360
+ * fall back to `buildMro`/`mroFor`, which for those languages is already
361
+ * the inheritance chain.
362
+ */
363
+ readonly buildExtendsOnlyMro?: (graph: KnowledgeGraph, parsedFiles: readonly ParsedFile[], nodeLookup: GraphNodeLookup) => Map<string, string[]>;
345
364
  /**
346
365
  * Mutate `parsed.localDefs[i].ownerId` to point at the structural
347
366
  * owner. Python's rule: methods (Function defs whose parent scope
@@ -365,8 +384,41 @@ export interface ScopeResolver {
365
384
  * `/^super\s*\(/.test(t)`. Java returns `t === 'super'`. C++ may
366
385
  * also need `this` capture. Languages without inheritance return
367
386
  * constant `false`.
387
+ *
388
+ * For languages where the answer depends on caller context (e.g.
389
+ * C++, where `Base::method()` is a super call ONLY when `Base` is
390
+ * actually a base of the caller's enclosing class, and namespace-
391
+ * qualified calls like `Singleton::getInstance()` must NOT be
392
+ * misclassified), implement the optional `isSuperReceiverInContext`
393
+ * variant below. The receiver-bound-calls pass prefers the context-
394
+ * aware variant when both are defined.
368
395
  */
369
396
  isSuperReceiver(receiverText: string): boolean;
397
+ /**
398
+ * Optional context-aware variant of `isSuperReceiver`. When defined,
399
+ * the receiver-bound-calls pass prefers this hook over the simple
400
+ * `isSuperReceiver(text)` form. Languages where super classification
401
+ * is purely text-driven (Python, Java, PHP) omit this hook and the
402
+ * simple form is used unchanged.
403
+ *
404
+ * C++ uses this to distinguish `Base::method()` (super call when
405
+ * `Base` is in the caller's MRO) from `Singleton::getInstance()`
406
+ * (ordinary namespace-qualified call). Without this, the regex
407
+ * heuristic `/^[A-Z]\w*::/` misclassifies any uppercase-qualified
408
+ * call as a super-receiver call and routes it through the wrong
409
+ * resolution branch.
410
+ *
411
+ * Returns `true` ONLY when:
412
+ * - the receiver text parses as `<Name>::<...>` (or another super-
413
+ * form the language recognizes), AND
414
+ * - `<Name>` resolves (via scope chain) to a class-like def, AND
415
+ * - that class is in the MRO of the caller's enclosing class.
416
+ *
417
+ * Returns `false` for namespace-qualified calls, unresolved names,
418
+ * class-qualified calls where the class is NOT in the caller's MRO,
419
+ * and any text the simple `isSuperReceiver` hook also rejects.
420
+ */
421
+ readonly isSuperReceiverInContext?: (receiverText: string, callerScope: ScopeId, scopes: ScopeResolutionIndexes) => boolean;
370
422
  /**
371
423
  * Whether the orchestrator should run `propagateImportedReturnTypes`
372
424
  * after finalize. Default `true`. TypeScript with explicit type
@@ -414,6 +466,19 @@ export interface ScopeResolver {
414
466
  * but is too loose as a default for strict module systems.
415
467
  */
416
468
  readonly allowGlobalFreeCallFallback?: boolean;
469
+ /**
470
+ * Optional per-slot conversion-rank function for overload resolution.
471
+ * When provided, `narrowOverloadCandidates` uses ranked scoring as a
472
+ * fallback when the exact-type filter produces no match. The function
473
+ * returns a numeric cost (0 = exact, 1 = promotion, 2 = standard
474
+ * conversion, Infinity = incompatible) for converting an argument
475
+ * type to a parameter type.
476
+ *
477
+ * The conversion-rank table is language-specific (issue #1578 pitfall:
478
+ * keep it out of shared overload-narrowing). C++ provides
479
+ * `cppConversionRank`; other languages define their own if needed.
480
+ */
481
+ readonly conversionRankFn?: ConversionRankFn;
417
482
  /**
418
483
  * Optional predicate to identify definitions with file-local linkage
419
484
  * (e.g. C `static` functions). When provided, `pickUniqueGlobalCallable`
@@ -425,6 +490,88 @@ export interface ScopeResolver {
425
490
  * Languages without file-local linkage semantics leave this undefined.
426
491
  */
427
492
  readonly isFileLocalDef?: (def: SymbolDefinition) => boolean;
493
+ /**
494
+ * Optional predicate to gate free-call fallback emission by caller-side
495
+ * visibility. When provided, `pickUniqueGlobalCallable` rejects candidates
496
+ * the caller cannot legally reach — e.g., a PHP function in a different
497
+ * namespace with no `use function` import, which PHP runtime would treat
498
+ * as `Call to undefined function`. Returning `false` blocks the candidate;
499
+ * returning `true` allows it; undefined-default keeps current behavior
500
+ * (no visibility filtering, equivalent to "all candidates visible").
501
+ *
502
+ * The hook receives the caller's `ParsedFile` (so it can consult
503
+ * `parsedImports`, `moduleScope`, etc.) and the candidate `SymbolDefinition`.
504
+ * The predicate must be pure: same inputs → same answer.
505
+ *
506
+ * Languages without namespace-scoped function resolution leave this undefined.
507
+ */
508
+ readonly isCallableVisibleFromCaller?: (ctx: {
509
+ readonly callerParsed: ParsedFile;
510
+ readonly candidate: SymbolDefinition;
511
+ /** Caller's enclosing scope id. Languages that gate visibility on
512
+ * caller scope (e.g. C++ two-phase template lookup) consult it;
513
+ * others ignore. Optional so existing implementations stay valid. */
514
+ readonly callerScope?: ScopeId;
515
+ /** ScopeResolutionIndexes for scope-tree walks. Optional for the
516
+ * same reason as `callerScope`. */
517
+ readonly scopes?: ScopeResolutionIndexes;
518
+ }) => boolean;
519
+ /**
520
+ * Optional argument-dependent-lookup (ADL / Koenig lookup) hook for
521
+ * languages with C++-style associated-namespace candidate addition.
522
+ *
523
+ * Runs in the free-call fallback alongside ordinary unqualified lookup.
524
+ * The fallback merges ordinary candidates with ADL candidates and applies
525
+ * overload narrowing over the union.
526
+ *
527
+ * The hook inspects the call site's argument types, computes the
528
+ * associated namespace set, and returns either:
529
+ * - an array of candidate `SymbolDefinition`s to add to the
530
+ * ordinary-lookup candidate pool.
531
+ * - `undefined` when ADL contributes no candidates.
532
+ *
533
+ * Languages without C++-style ADL leave this undefined. The
534
+ * cross-language contract is "additive tier" — defining the hook never
535
+ * removes candidates the prior tier would have produced.
536
+ */
537
+ readonly resolveAdlCandidates?: (site: {
538
+ readonly name: string;
539
+ readonly arity?: number;
540
+ readonly argumentTypes?: readonly string[];
541
+ readonly atRange: {
542
+ readonly startLine: number;
543
+ readonly startCol: number;
544
+ };
545
+ }, callerParsed: ParsedFile, scopes: ScopeResolutionIndexes, parsedFiles: readonly ParsedFile[]) => readonly SymbolDefinition[] | undefined;
546
+ /**
547
+ * Optional resolver for qualified-receiver member calls where the
548
+ * receiver is a namespace (not a class) and ordinary scope-chain /
549
+ * import resolution doesn't find the member. C++ uses this for
550
+ * `outer::foo()` style calls and to walk through inline-namespace
551
+ * children transitively (`outer::v1::foo` reachable as `outer::foo`).
552
+ *
553
+ * Languages whose qualified-name semantics are already covered by the
554
+ * receiver-bound-calls Case-1 namespace-targets path (e.g., Python's
555
+ * `import X; X.foo()`) leave this undefined.
556
+ *
557
+ * Receiver-bound-calls invokes this hook AFTER Case 1 (namespace
558
+ * imports) and AFTER Case 2 (class-name receiver) fail to resolve.
559
+ * Returns the target def, `'ambiguous'` when multiple inline-namespace
560
+ * children declare the same name (suppresses edge emission), or
561
+ * `undefined` to fall through to the remaining cases.
562
+ */
563
+ readonly resolveQualifiedReceiverMember?: (receiverName: string, memberName: string, callerScope: ScopeId, scopes: ScopeResolutionIndexes, parsedFiles: readonly ParsedFile[]) => SymbolDefinition | 'ambiguous' | undefined;
564
+ /**
565
+ * Enable the receiver-bound Case 0.5 fallback for explicit `this`
566
+ * receivers (`this->m()` / `this.m()`) that resolves against the
567
+ * enclosing class + MRO even when no explicit `this` typeBinding is
568
+ * present in scope.
569
+ *
570
+ * Keep disabled for languages where the existing type-binding path
571
+ * (Case 4) already handles `this` correctly and overload ambiguity
572
+ * suppression must remain unchanged.
573
+ */
574
+ readonly resolveThisViaEnclosingClass?: boolean;
428
575
  /**
429
576
  * Optional post-finalize hook to inject cross-file bindings that
430
577
  * aren't modeled via explicit imports. Runs after
@@ -501,4 +648,24 @@ export interface ScopeResolver {
501
648
  get(filePath: string): unknown;
502
649
  };
503
650
  }) => void;
651
+ /**
652
+ * Optional post-resolution pass: emit CALLS edges for member-call sites
653
+ * whose receiver cannot be typed by the scope chain (no `TypeRef`).
654
+ * Dynamically-typed languages with untyped/`mixed`/`Any` parameters use
655
+ * this hook to recover the call edge via workspace-wide method-name
656
+ * lookup, mirroring what their legacy resolvers did.
657
+ *
658
+ * Runs AFTER `emitReceiverBoundCalls` and BEFORE `emitFreeCallFallback`.
659
+ * Implementations MUST:
660
+ * - Skip sites already in `handledSites` (Invariant I2).
661
+ * - Add resolved site keys to `handledSites` before returning.
662
+ * - Stay narrow: a unique workspace-wide match is the safe baseline.
663
+ * Multi-candidate fallbacks should narrow by arity / argument types
664
+ * before emitting to keep false-positive rate bounded.
665
+ *
666
+ * Returns the number of edges emitted (for telemetry).
667
+ *
668
+ * Default: undefined (no unresolved-receiver fallback).
669
+ */
670
+ readonly emitUnresolvedReceiverEdges?: (graph: KnowledgeGraph, scopes: ScopeResolutionIndexes, parsedFiles: readonly ParsedFile[], nodeLookup: GraphNodeLookup, handledSites: Set<string>, model: SemanticModel) => number;
504
671
  }
@@ -87,6 +87,9 @@
87
87
  * attempting emission (even on dedup-collapse), because the
88
88
  * per-(caller, target) collapse semantics require multiple call
89
89
  * sites in the same caller body not produce multiple edges.
90
+ * `preEmitInheritanceEdges` also pre-marks every `inherits` site so
91
+ * the generic bridge cannot remap class heritage into method-owned
92
+ * EXTENDS edges via `resolveCallerGraphId`.
90
93
  *
91
94
  * - **I3 — `propagateImportedReturnTypes` mutation timing + ordering.**
92
95
  * The pass mutates `Scope.typeBindings` (a plain `new Map(...)` from
@@ -40,6 +40,7 @@ export declare function resolveDefGraphId(filePath: string, def: {
40
40
  qualifiedName?: string;
41
41
  type?: NodeLabel;
42
42
  parameterTypes?: readonly string[];
43
+ templateArguments?: readonly string[];
43
44
  }, nodeLookup: GraphNodeLookup): string | undefined;
44
45
  /** Derive the simple (unqualified) name of a def from its `qualifiedName`. */
45
46
  export declare function simpleQualifiedName(def: SymbolDefinition): string | undefined;
@@ -79,6 +79,18 @@ export function resolveDefGraphId(filePath, def, nodeLookup) {
79
79
  if (pHit !== undefined)
80
80
  return pHit;
81
81
  }
82
+ if ((def.type === 'Class' ||
83
+ def.type === 'Struct' ||
84
+ def.type === 'Interface' ||
85
+ def.type === 'Enum' ||
86
+ def.type === 'Record') &&
87
+ def.templateArguments !== undefined &&
88
+ def.templateArguments.length > 0) {
89
+ const tKey = qualifiedKey(filePath, def.type, `${qn}~${def.templateArguments.join(',')}`);
90
+ const tHit = nodeLookup.get(tKey);
91
+ if (tHit !== undefined)
92
+ return tHit;
93
+ }
82
94
  const qualifiedHit = nodeLookup.get(qualifiedKey(filePath, def.type, qn));
83
95
  if (qualifiedHit !== undefined)
84
96
  return qualifiedHit;
@@ -16,4 +16,4 @@
16
16
  * can extend the return shape without breaking existing consumers.
17
17
  */
18
18
  import type { MethodDispatchIndex } from '../../../../_shared/index.js';
19
- export declare function buildPopulatedMethodDispatch(mroByDefId: ReadonlyMap<string, readonly string[]>): MethodDispatchIndex;
19
+ export declare function buildPopulatedMethodDispatch(mroByDefId: ReadonlyMap<string, readonly string[]>, extendsOnlyMroByDefId?: ReadonlyMap<string, readonly string[]>): MethodDispatchIndex;
@@ -16,8 +16,8 @@
16
16
  * can extend the return shape without breaking existing consumers.
17
17
  */
18
18
  const EMPTY_DEFS = Object.freeze([]);
19
- export function buildPopulatedMethodDispatch(mroByDefId) {
20
- return {
19
+ export function buildPopulatedMethodDispatch(mroByDefId, extendsOnlyMroByDefId) {
20
+ const base = {
21
21
  mroByOwnerDefId: mroByDefId,
22
22
  implsByInterfaceDefId: new Map(),
23
23
  mroFor(ownerDefId) {
@@ -27,4 +27,14 @@ export function buildPopulatedMethodDispatch(mroByDefId) {
27
27
  return EMPTY_DEFS;
28
28
  },
29
29
  };
30
+ if (extendsOnlyMroByDefId !== undefined) {
31
+ return {
32
+ ...base,
33
+ extendsOnlyMroByOwnerDefId: extendsOnlyMroByDefId,
34
+ extendsOnlyMroFor(ownerDefId) {
35
+ return extendsOnlyMroByDefId.get(ownerDefId) ?? EMPTY_DEFS;
36
+ },
37
+ };
38
+ }
39
+ return base;
30
40
  }
@@ -86,6 +86,17 @@ export function buildGraphNodeLookup(graph) {
86
86
  // Each overload is unique — set unconditionally.
87
87
  lookup.set(pKey, node.id);
88
88
  }
89
+ if ((node.label === 'Class' ||
90
+ node.label === 'Struct' ||
91
+ node.label === 'Interface' ||
92
+ node.label === 'Enum' ||
93
+ node.label === 'Record') &&
94
+ props.templateArguments !== undefined &&
95
+ props.templateArguments.length > 0) {
96
+ const tKey = qualifiedKey(props.filePath, node.label, `${qualified}~${props.templateArguments.join(',')}`);
97
+ if (!lookup.has(tKey))
98
+ lookup.set(tKey, node.id);
99
+ }
89
100
  }
90
101
  // Fallback key: simple name. First-wins within a file — used when
91
102
  // the caller doesn't know the qualifier (unqualified free-call
@@ -105,6 +116,11 @@ export function isLinkableLabel(label) {
105
116
  label === 'Interface' ||
106
117
  label === 'Struct' ||
107
118
  label === 'Enum' ||
119
+ // Trait nodes are linkable so MRO builders can bridge PHP/Rust trait
120
+ // defs between scope-resolution DefIds and the graph's node ids.
121
+ // IMPLEMENTS edges from classes to traits are otherwise invisible to
122
+ // the scope-resolution MRO pass.
123
+ label === 'Trait' ||
108
124
  // Variable / Property are linkable too — receiver-bound write/read
109
125
  // ACCESSES edges target field nodes (e.g. `user.name = "x"` →
110
126
  // ACCESSES edge to User's `name` Variable/Property node).
@@ -22,9 +22,45 @@ import type { ScopeResolutionIndexes } from '../../model/scope-resolution-indexe
22
22
  import type { SemanticModel } from '../../model/semantic-model.js';
23
23
  import type { WorkspaceResolutionIndex } from '../workspace-index.js';
24
24
  import type { GraphNodeLookup } from '../graph-bridge/node-lookup.js';
25
+ import { type ConversionRankFn } from './overload-narrowing.js';
25
26
  export declare function emitFreeCallFallback(graph: KnowledgeGraph, scopes: ScopeResolutionIndexes, parsedFiles: readonly ParsedFile[], nodeLookup: GraphNodeLookup, _referenceIndex: {
26
27
  readonly bySourceScope: ReadonlyMap<ScopeId, readonly Reference[]>;
27
28
  }, handledSites: Set<string>, model: SemanticModel, workspaceIndex: WorkspaceResolutionIndex, options?: {
28
29
  readonly allowGlobalFallback?: boolean;
29
30
  readonly isFileLocalDef?: (def: SymbolDefinition) => boolean;
31
+ readonly isCallableVisibleFromCaller?: (ctx: {
32
+ readonly callerParsed: ParsedFile;
33
+ readonly candidate: SymbolDefinition;
34
+ readonly callerScope?: ScopeId;
35
+ readonly scopes?: ScopeResolutionIndexes;
36
+ }) => boolean;
37
+ readonly resolveAdlCandidates?: (site: {
38
+ readonly name: string;
39
+ readonly arity?: number;
40
+ readonly argumentTypes?: readonly string[];
41
+ readonly atRange: {
42
+ readonly startLine: number;
43
+ readonly startCol: number;
44
+ };
45
+ }, callerParsed: ParsedFile, scopes: ScopeResolutionIndexes, parsedFiles: readonly ParsedFile[]) => readonly SymbolDefinition[] | undefined;
46
+ readonly conversionRankFn?: ConversionRankFn;
30
47
  }): number;
48
+ /** Walk up from the call-site scope to the enclosing class scope,
49
+ * pick a method member by name with overload narrowing on arity +
50
+ * argument types. Returns undefined if there's no enclosing class,
51
+ * no matching method, OR narrowing leaves multiple compatible
52
+ * candidates — in the multi-candidate case, picking
53
+ * `candidates[0]` would emit a high-confidence CALLS edge whose
54
+ * target depends on registration order rather than a defensible
55
+ * resolution. Mirrors `pickUniqueGlobalCallable`'s uniqueness check
56
+ * in the same file (Codex PR #1497 review, finding 2).
57
+ *
58
+ * Exported for unit testing — language-agnostic logic, exercised
59
+ * via synthetic stubs in `pick-implicit-this-overload.test.ts`. The
60
+ * production call site is `applyFreeCallFallback` immediately above. */
61
+ export declare function pickImplicitThisOverload(site: {
62
+ readonly inScope: ScopeId;
63
+ readonly name: string;
64
+ readonly arity?: number;
65
+ readonly argumentTypes?: readonly string[];
66
+ }, scopes: ScopeResolutionIndexes, workspaceIndex: WorkspaceResolutionIndex, model: SemanticModel, conversionRankFn?: ConversionRankFn): SymbolDefinition | undefined;
@@ -17,8 +17,8 @@
17
17
  * generalization plan.
18
18
  */
19
19
  import { resolveCallerGraphId, resolveDefGraphId } from '../graph-bridge/ids.js';
20
- import { findCallableBindingInScope, findClassBindingInScope } from '../scope/walkers.js';
21
- import { narrowOverloadCandidates } from './overload-narrowing.js';
20
+ import { findAllCallableBindingsInScope, findCallableBindingInScope, findCallableBindingsAndAdlBlocker, findClassBindingInScope, } from '../scope/walkers.js';
21
+ import { isOverloadAmbiguousAfterNormalization, narrowOverloadCandidates, } from './overload-narrowing.js';
22
22
  export function emitFreeCallFallback(graph, scopes, parsedFiles, nodeLookup, _referenceIndex, handledSites, model, workspaceIndex, options = {}) {
23
23
  let emitted = 0;
24
24
  const seen = new Set();
@@ -45,17 +45,134 @@ export function emitFreeCallFallback(graph, scopes, parsedFiles, nodeLookup, _re
45
45
  // the same name in a single class, choose the best match by
46
46
  // arity + argument types.
47
47
  if (fnDef === undefined) {
48
- fnDef = pickImplicitThisOverload(site, scopes, workspaceIndex, model);
48
+ fnDef = pickImplicitThisOverload(site, scopes, workspaceIndex, model, options.conversionRankFn);
49
49
  }
50
+ // Scope-chain callable lookup. First-match preserves scope-chain
51
+ // precedence (local shadows import). When a conversion-rank function
52
+ // is available AND the binding scope contains multiple overloads,
53
+ // refine with `narrowOverloadCandidates` to pick the best overload
54
+ // by argument types (#1578). The first-match result is kept as a
55
+ // fallback when narrowing is indeterminate.
50
56
  if (fnDef === undefined) {
51
- fnDef = findCallableBindingInScope(site.inScope, site.name, scopes);
57
+ if (options.resolveAdlCandidates === undefined) {
58
+ // Non-ADL path: first-match preserves scope-chain precedence
59
+ // (local shadows import). When a conversion-rank function is
60
+ // available AND the binding scope contains multiple overloads,
61
+ // refine with narrowOverloadCandidates (#1578).
62
+ fnDef = findCallableBindingInScope(site.inScope, site.name, scopes);
63
+ if (fnDef !== undefined && options.conversionRankFn !== undefined) {
64
+ const allCallables = findAllCallableBindingsInScope(site.inScope, site.name, scopes);
65
+ if (allCallables.length > 1) {
66
+ const narrowed = narrowOverloadCandidates(allCallables, site.arity, site.argumentTypes, options.conversionRankFn);
67
+ if (narrowed.length === 1) {
68
+ fnDef = narrowed[0];
69
+ }
70
+ else if (narrowed.length > 1) {
71
+ // Multiple survivors after conversion-rank scoring.
72
+ // Suppress when all candidates share the same file (true
73
+ // overloads) — mirrors ADL merged-candidate path behavior.
74
+ // Cross-file candidates are shadowing; keep first-match.
75
+ const sameFile = narrowed.every((d) => d.filePath === narrowed[0].filePath);
76
+ if (sameFile) {
77
+ handledSites.add(`${parsed.filePath}:${site.atRange.startLine}:${site.atRange.startCol}`);
78
+ continue;
79
+ }
80
+ }
81
+ // narrowed.length === 0: keep the first-match fnDef —
82
+ // preserves local-shadows-import.
83
+ }
84
+ }
85
+ }
86
+ else {
87
+ // ADL path: ISO C++ `[basic.lookup.unqual]` §7 — ADL is suppressed
88
+ // when ordinary lookup finds a non-function name or a block-scope
89
+ // function declaration.
90
+ const { callables: ordinary, nonCallableFound, blockScopeDeclFound, } = findCallableBindingsAndAdlBlocker(site.inScope, site.name, scopes);
91
+ const adlSuppressed = nonCallableFound || blockScopeDeclFound;
92
+ const adl = adlSuppressed
93
+ ? undefined
94
+ : options.resolveAdlCandidates({
95
+ name: site.name,
96
+ arity: site.arity,
97
+ argumentTypes: site.argumentTypes,
98
+ atRange: { startLine: site.atRange.startLine, startCol: site.atRange.startCol },
99
+ }, parsed, scopes, parsedFiles);
100
+ // When ADL contributed no candidates, narrow ordinary candidates
101
+ // with conversion-rank scoring when multiple overloads exist.
102
+ // Single candidate or empty falls through to first-match.
103
+ if (adl === undefined || adl.length === 0) {
104
+ if (ordinary.length <= 1 || options.conversionRankFn === undefined) {
105
+ fnDef = ordinary[0];
106
+ }
107
+ else {
108
+ const siteKey = `${parsed.filePath}:${site.atRange.startLine}:${site.atRange.startCol}`;
109
+ const narrowed = narrowOverloadCandidates(ordinary, site.arity, site.argumentTypes, options.conversionRankFn);
110
+ if (narrowed.length === 1) {
111
+ fnDef = narrowed[0];
112
+ }
113
+ else if (narrowed.length > 1) {
114
+ // Multiple survivors — suppress when same-file (true
115
+ // overloads), mirrors ADL merged-candidate behavior.
116
+ const sameFile = narrowed.every((d) => d.filePath === narrowed[0].filePath);
117
+ if (sameFile) {
118
+ handledSites.add(siteKey);
119
+ continue;
120
+ }
121
+ fnDef = ordinary[0]; // cross-file shadowing → first-match
122
+ }
123
+ else {
124
+ fnDef = ordinary[0]; // narrowed empty → first-match
125
+ }
126
+ }
127
+ }
128
+ else {
129
+ const siteKey = `${parsed.filePath}:${site.atRange.startLine}:${site.atRange.startCol}`;
130
+ const merged = [];
131
+ const seenMerge = new Set();
132
+ const push = (defs) => {
133
+ for (const d of defs) {
134
+ if (seenMerge.has(d.nodeId))
135
+ continue;
136
+ seenMerge.add(d.nodeId);
137
+ merged.push(d);
138
+ }
139
+ };
140
+ push(ordinary);
141
+ push(adl);
142
+ const narrowed = narrowOverloadCandidates(merged, site.arity, site.argumentTypes, options.conversionRankFn);
143
+ if (narrowed.length === 1) {
144
+ fnDef = narrowed[0];
145
+ }
146
+ else if (narrowed.length === 0) {
147
+ handledSites.add(siteKey);
148
+ continue;
149
+ }
150
+ else if (narrowed.length > 1) {
151
+ if (isOverloadAmbiguousAfterNormalization(narrowed, site.arity)) {
152
+ handledSites.add(siteKey);
153
+ continue;
154
+ }
155
+ // Multiple survivors remain after conversion-rank scoring;
156
+ // suppress instead of picking arbitrarily.
157
+ handledSites.add(siteKey);
158
+ continue;
159
+ }
160
+ }
161
+ }
52
162
  }
53
163
  // V1: pickUniqueGlobalCallable ignores import context — resolves to any
54
164
  // globally-unique callable. False cross-package edges are possible when
55
165
  // the caller does not import the target package. Same-package calls are
56
- // caught by findCallableBindingInScope above before reaching here.
166
+ // usually caught by nearest-scope lookup before reaching here.
57
167
  if (fnDef === undefined && options.allowGlobalFallback === true) {
58
- fnDef = pickUniqueGlobalCallable(site.name, model, scopes, parsed.filePath, options.isFileLocalDef);
168
+ fnDef = pickUniqueGlobalCallable(site.name, model, scopes, parsed.filePath, options.isFileLocalDef, site.arity, options.isCallableVisibleFromCaller !== undefined
169
+ ? (candidate) => options.isCallableVisibleFromCaller({
170
+ callerParsed: parsed,
171
+ candidate,
172
+ callerScope: site.inScope,
173
+ scopes,
174
+ })
175
+ : undefined, site.argumentTypes, options.conversionRankFn);
59
176
  }
60
177
  if (fnDef === undefined)
61
178
  continue;
@@ -88,7 +205,7 @@ export function emitFreeCallFallback(graph, scopes, parsedFiles, nodeLookup, _re
88
205
  }
89
206
  return emitted;
90
207
  }
91
- function pickUniqueGlobalCallable(name, model, scopes, callerFilePath, isFileLocalDef) {
208
+ function pickUniqueGlobalCallable(name, model, scopes, callerFilePath, isFileLocalDef, callArity, isCallerVisible, callArgTypes, conversionRankFn) {
92
209
  const scopeDefs = [];
93
210
  const scopeSeen = new Set();
94
211
  for (const def of scopes.defs.byId.values()) {
@@ -102,6 +219,13 @@ function pickUniqueGlobalCallable(name, model, scopes, callerFilePath, isFileLoc
102
219
  if (isFileLocalDef !== undefined && def.filePath !== callerFilePath && isFileLocalDef(def)) {
103
220
  continue;
104
221
  }
222
+ // Caller-side visibility filter (e.g., PHP namespace + use-function
223
+ // import gating). When defined, blocks candidates the caller cannot
224
+ // legally reach. Languages without namespace-scoped function resolution
225
+ // leave this undefined → no filtering.
226
+ if (isCallerVisible !== undefined && !isCallerVisible(def)) {
227
+ continue;
228
+ }
105
229
  const key = logicalCallableKey(def);
106
230
  if (scopeSeen.has(key))
107
231
  continue;
@@ -110,6 +234,24 @@ function pickUniqueGlobalCallable(name, model, scopes, callerFilePath, isFileLoc
110
234
  }
111
235
  if (scopeDefs.length === 1)
112
236
  return scopeDefs[0];
237
+ // When multiple scope-index candidates exist, attempt arity narrowing
238
+ // before falling back to the semantic-model lookup. This handles
239
+ // registry-primary languages where the model is not populated for the
240
+ // migrated language's files (call-processor skips them).
241
+ if (scopeDefs.length > 1 && callArity !== undefined) {
242
+ const arityMatch = narrowByArity(scopeDefs, callArity);
243
+ if (arityMatch !== undefined)
244
+ return arityMatch;
245
+ }
246
+ // When arity narrowing left >1 candidate, try overload narrowing with
247
+ // argument types + conversion ranking (#1578). This picks the unique
248
+ // best-rank candidate when exact-type or conversion-rank scoring can
249
+ // disambiguate (e.g., `f(int)` vs `f(double)` called with `f(2.5)`).
250
+ if (scopeDefs.length > 1) {
251
+ const narrowed = narrowOverloadCandidates(scopeDefs, callArity, callArgTypes, conversionRankFn);
252
+ if (narrowed.length === 1)
253
+ return narrowed[0];
254
+ }
113
255
  const defs = [];
114
256
  const seen = new Set();
115
257
  const push = (pool) => {
@@ -120,6 +262,10 @@ function pickUniqueGlobalCallable(name, model, scopes, callerFilePath, isFileLoc
120
262
  if (isFileLocalDef !== undefined && def.filePath !== callerFilePath && isFileLocalDef(def)) {
121
263
  continue;
122
264
  }
265
+ // Same caller-visibility filter applied to the model-side pool.
266
+ if (isCallerVisible !== undefined && !isCallerVisible(def)) {
267
+ continue;
268
+ }
123
269
  const key = logicalCallableKey(def);
124
270
  if (seen.has(key))
125
271
  continue;
@@ -129,7 +275,38 @@ function pickUniqueGlobalCallable(name, model, scopes, callerFilePath, isFileLoc
129
275
  };
130
276
  push(model.symbols.lookupCallableByName(name));
131
277
  push(model.methods.lookupMethodByName(name));
132
- return defs.length === 1 ? defs[0] : undefined;
278
+ if (defs.length === 1)
279
+ return defs[0];
280
+ // When multiple candidates exist and the call site has a known arity,
281
+ // narrow by parameter count.
282
+ if (defs.length > 1 && callArity !== undefined) {
283
+ const arityMatch = narrowByArity(defs, callArity);
284
+ if (arityMatch !== undefined)
285
+ return arityMatch;
286
+ }
287
+ // Same argument-type + conversion-rank narrowing for the model pool.
288
+ if (defs.length > 1) {
289
+ const narrowed = narrowOverloadCandidates(defs, callArity, callArgTypes, conversionRankFn);
290
+ if (narrowed.length === 1)
291
+ return narrowed[0];
292
+ }
293
+ return undefined;
294
+ }
295
+ /**
296
+ * Narrow a list of callable candidates by call-site arity.
297
+ * A def is compatible when `requiredParameterCount <= arity <= parameterCount`.
298
+ * Defs with `parameterCount === undefined` (variadic/unknown) are always kept.
299
+ * Returns the single compatible def, or `undefined` when zero or multiple match.
300
+ */
301
+ function narrowByArity(defs, callArity) {
302
+ const compatible = defs.filter((d) => {
303
+ const total = d.parameterCount;
304
+ if (total === undefined)
305
+ return true; // unknown arity — keep
306
+ const required = d.requiredParameterCount ?? total;
307
+ return required <= callArity && callArity <= total;
308
+ });
309
+ return compatible.length === 1 ? compatible[0] : undefined;
133
310
  }
134
311
  function logicalCallableKey(def) {
135
312
  return [
@@ -157,10 +334,18 @@ function pickConstructorOrClass(classDef, workspaceIndex) {
157
334
  }
158
335
  /** Walk up from the call-site scope to the enclosing class scope,
159
336
  * pick a method member by name with overload narrowing on arity +
160
- * argument types. Returns undefined if there's no enclosing class
161
- * or no matching method. Used for implicit-this calls inside a
162
- * class body where multiple overloads share the call name. */
163
- function pickImplicitThisOverload(site, scopes, workspaceIndex, model) {
337
+ * argument types. Returns undefined if there's no enclosing class,
338
+ * no matching method, OR narrowing leaves multiple compatible
339
+ * candidates — in the multi-candidate case, picking
340
+ * `candidates[0]` would emit a high-confidence CALLS edge whose
341
+ * target depends on registration order rather than a defensible
342
+ * resolution. Mirrors `pickUniqueGlobalCallable`'s uniqueness check
343
+ * in the same file (Codex PR #1497 review, finding 2).
344
+ *
345
+ * Exported for unit testing — language-agnostic logic, exercised
346
+ * via synthetic stubs in `pick-implicit-this-overload.test.ts`. The
347
+ * production call site is `applyFreeCallFallback` immediately above. */
348
+ export function pickImplicitThisOverload(site, scopes, workspaceIndex, model, conversionRankFn) {
164
349
  // Find the enclosing Class scope by walking parents.
165
350
  let curId = site.inScope;
166
351
  let classScopeId;
@@ -185,6 +370,12 @@ function pickImplicitThisOverload(site, scopes, workspaceIndex, model) {
185
370
  return undefined;
186
371
  if (overloads.length === 1)
187
372
  return overloads[0];
188
- const candidates = narrowOverloadCandidates(overloads, site.arity, site.argumentTypes);
373
+ // Narrow on arity + argument types. Require a UNIQUE survivor —
374
+ // ambiguous narrowing (multiple compatible candidates with no
375
+ // disambiguating signal) leaves the call unresolved rather than
376
+ // routing to an arbitrary first overload by registration order.
377
+ const candidates = narrowOverloadCandidates(overloads, site.arity, site.argumentTypes, conversionRankFn);
378
+ if (candidates.length !== 1)
379
+ return undefined;
189
380
  return candidates[0];
190
381
  }
@@ -140,7 +140,7 @@ export function propagateImportedReturnTypes(parsedFiles, indexes, index) {
140
140
  continue;
141
141
  const refs = lookupBindingsAt(importerModule.id, localName, indexes);
142
142
  for (const ref of refs) {
143
- if (ref.origin !== 'import' && ref.origin !== 'reexport')
143
+ if (ref.origin !== 'import' && ref.origin !== 'reexport' && ref.origin !== 'wildcard')
144
144
  continue;
145
145
  const sourceModule = moduleScopeByFile.get(ref.def.filePath);
146
146
  if (sourceModule === undefined)