gitnexus 1.6.9 → 1.6.10-aptos.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (539) hide show
  1. package/README.md +211 -53
  2. package/dist/_shared/graph/types.d.ts +67 -3
  3. package/dist/_shared/graph/types.d.ts.map +1 -1
  4. package/dist/_shared/index.d.ts +1 -0
  5. package/dist/_shared/index.d.ts.map +1 -1
  6. package/dist/_shared/index.js.map +1 -1
  7. package/dist/_shared/integrations/resilient-fetch.d.ts +3 -1
  8. package/dist/_shared/integrations/resilient-fetch.d.ts.map +1 -1
  9. package/dist/_shared/integrations/resilient-fetch.js +4 -3
  10. package/dist/_shared/integrations/resilient-fetch.js.map +1 -1
  11. package/dist/_shared/language-detection.d.ts.map +1 -1
  12. package/dist/_shared/language-detection.js +2 -0
  13. package/dist/_shared/language-detection.js.map +1 -1
  14. package/dist/_shared/languages.d.ts +2 -0
  15. package/dist/_shared/languages.d.ts.map +1 -1
  16. package/dist/_shared/languages.js +2 -0
  17. package/dist/_shared/languages.js.map +1 -1
  18. package/dist/_shared/lbug/schema-constants.d.ts +2 -2
  19. package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
  20. package/dist/_shared/lbug/schema-constants.js +8 -0
  21. package/dist/_shared/lbug/schema-constants.js.map +1 -1
  22. package/dist/_shared/pipeline.d.ts +1 -1
  23. package/dist/_shared/pipeline.d.ts.map +1 -1
  24. package/dist/_shared/scope-resolution/callable-flow-site.d.ts +110 -0
  25. package/dist/_shared/scope-resolution/callable-flow-site.d.ts.map +1 -0
  26. package/dist/_shared/scope-resolution/callable-flow-site.js +11 -0
  27. package/dist/_shared/scope-resolution/callable-flow-site.js.map +1 -0
  28. package/dist/_shared/scope-resolution/finalize-algorithm.d.ts +1 -1
  29. package/dist/_shared/scope-resolution/finalize-algorithm.d.ts.map +1 -1
  30. package/dist/_shared/scope-resolution/finalize-algorithm.js +1 -1
  31. package/dist/_shared/scope-resolution/finalize-algorithm.js.map +1 -1
  32. package/dist/_shared/scope-resolution/language-classification.d.ts.map +1 -1
  33. package/dist/_shared/scope-resolution/language-classification.js +1 -0
  34. package/dist/_shared/scope-resolution/language-classification.js.map +1 -1
  35. package/dist/_shared/scope-resolution/parsed-file.d.ts +7 -0
  36. package/dist/_shared/scope-resolution/parsed-file.d.ts.map +1 -1
  37. package/dist/_shared/scope-resolution/reference-site.d.ts +9 -1
  38. package/dist/_shared/scope-resolution/reference-site.d.ts.map +1 -1
  39. package/dist/_shared/scope-resolution/types.d.ts +20 -3
  40. package/dist/_shared/scope-resolution/types.d.ts.map +1 -1
  41. package/dist/cli/ai-context.d.ts +1 -1
  42. package/dist/cli/ai-context.js +25 -44
  43. package/dist/cli/analyze.d.ts +5 -2
  44. package/dist/cli/analyze.js +197 -11
  45. package/dist/cli/clean.js +17 -3
  46. package/dist/cli/cli-message.d.ts +1 -1
  47. package/dist/cli/doctor.d.ts +18 -0
  48. package/dist/cli/doctor.js +96 -5
  49. package/dist/cli/editor-targets.d.ts +17 -2
  50. package/dist/cli/editor-targets.js +44 -0
  51. package/dist/cli/embeddings.d.ts +12 -0
  52. package/dist/cli/embeddings.js +49 -0
  53. package/dist/cli/eval-server.d.ts +23 -1
  54. package/dist/cli/eval-server.js +126 -8
  55. package/dist/cli/help-i18n.js +6 -0
  56. package/dist/cli/i18n/en.d.ts +18 -8
  57. package/dist/cli/i18n/en.js +18 -8
  58. package/dist/cli/i18n/resources.d.ts +28 -8
  59. package/dist/cli/i18n/zh-CN.d.ts +10 -0
  60. package/dist/cli/i18n/zh-CN.js +18 -8
  61. package/dist/cli/index.js +21 -7
  62. package/dist/cli/lazy-action.d.ts +7 -0
  63. package/dist/cli/lazy-action.js +27 -0
  64. package/dist/cli/mcp.js +6 -3
  65. package/dist/cli/move-availability.d.ts +5 -0
  66. package/dist/cli/move-availability.js +11 -0
  67. package/dist/cli/setup.d.ts +8 -0
  68. package/dist/cli/setup.js +230 -32
  69. package/dist/cli/skill-gen.js +38 -18
  70. package/dist/cli/standard-skills.d.ts +76 -0
  71. package/dist/cli/standard-skills.js +45 -0
  72. package/dist/cli/status.d.ts +4 -1
  73. package/dist/cli/status.js +57 -4
  74. package/dist/cli/tool.js +11 -0
  75. package/dist/cli/uninstall.js +77 -18
  76. package/dist/cli/wiki.d.ts +1 -0
  77. package/dist/cli/wiki.js +7 -1
  78. package/dist/config/ignore-service.d.ts +2 -0
  79. package/dist/config/ignore-service.js +27 -0
  80. package/dist/core/analysis-features.d.ts +21 -0
  81. package/dist/core/analysis-features.js +59 -0
  82. package/dist/core/analyzer-identity.d.ts +74 -0
  83. package/dist/core/analyzer-identity.js +1820 -0
  84. package/dist/core/augmentation/engine.js +13 -8
  85. package/dist/core/embeddings/embedder.d.ts +3 -2
  86. package/dist/core/embeddings/embedder.js +24 -7
  87. package/dist/core/embeddings/embedding-identity.d.ts +11 -0
  88. package/dist/core/embeddings/embedding-identity.js +24 -0
  89. package/dist/core/embeddings/embedding-pipeline.d.ts +36 -1
  90. package/dist/core/embeddings/embedding-pipeline.js +100 -9
  91. package/dist/core/embeddings/http-client.d.ts +33 -3
  92. package/dist/core/embeddings/http-client.js +237 -25
  93. package/dist/core/embeddings/node-module-compat.d.ts +25 -0
  94. package/dist/core/embeddings/node-module-compat.js +25 -0
  95. package/dist/core/embeddings/onnxruntime-common-resolver.js +8 -5
  96. package/dist/core/embeddings/onnxruntime-node-resolver.js +33 -7
  97. package/dist/core/embeddings/runtime-install.d.ts +119 -0
  98. package/dist/core/embeddings/runtime-install.js +372 -0
  99. package/dist/core/embeddings/runtime-support.d.ts +48 -17
  100. package/dist/core/embeddings/runtime-support.js +96 -0
  101. package/dist/core/git-staleness.js +1 -1
  102. package/dist/core/group/bridge-db.js +2 -0
  103. package/dist/core/group/extractors/http-patterns/python.js +246 -108
  104. package/dist/core/group/extractors/manifest-extractor.js +4 -0
  105. package/dist/core/incremental/escalation-gate.d.ts +38 -0
  106. package/dist/core/incremental/escalation-gate.js +48 -0
  107. package/dist/core/incremental/shadow-candidates.d.ts +3 -3
  108. package/dist/core/incremental/shadow-candidates.js +3 -3
  109. package/dist/core/incremental/subgraph-extract.d.ts +2 -2
  110. package/dist/core/incremental/subgraph-extract.js +2 -2
  111. package/dist/core/index-freshness.d.ts +5 -0
  112. package/dist/core/index-freshness.js +13 -0
  113. package/dist/core/ingestion/class-extractors/configs/jvm.js +29 -0
  114. package/dist/core/ingestion/cobol/cobol-preprocessor.js +1 -1
  115. package/dist/core/ingestion/cobol/jcl-processor.js +9 -8
  116. package/dist/core/ingestion/cobol-processor.js +27 -26
  117. package/dist/core/ingestion/community-processor.d.ts +51 -1
  118. package/dist/core/ingestion/community-processor.js +323 -64
  119. package/dist/core/ingestion/emit-references.js +7 -2
  120. package/dist/core/ingestion/filesystem-walker.js +4 -0
  121. package/dist/core/ingestion/frameworks/spring/analysis-features.d.ts +3 -0
  122. package/dist/core/ingestion/frameworks/spring/analysis-features.js +7 -0
  123. package/dist/core/ingestion/frameworks/spring/bean-candidates.d.ts +30 -0
  124. package/dist/core/ingestion/frameworks/spring/bean-candidates.js +182 -0
  125. package/dist/core/ingestion/frameworks/spring/bean-catalog.d.ts +12 -0
  126. package/dist/core/ingestion/frameworks/spring/bean-catalog.js +26 -0
  127. package/dist/core/ingestion/frameworks/spring/config-bindings.d.ts +24 -0
  128. package/dist/core/ingestion/frameworks/spring/config-bindings.js +115 -0
  129. package/dist/core/ingestion/languages/c/captures.js +56 -0
  130. package/dist/core/ingestion/languages/c/query.js +17 -0
  131. package/dist/core/ingestion/languages/c/scope-resolver.js +6 -0
  132. package/dist/core/ingestion/languages/cobol/captures.js +93 -0
  133. package/dist/core/ingestion/languages/cobol/scope-resolver.js +7 -0
  134. package/dist/core/ingestion/languages/cpp/captures.js +365 -75
  135. package/dist/core/ingestion/languages/cpp/scope-resolver.js +14 -0
  136. package/dist/core/ingestion/languages/csharp/captures.js +25 -0
  137. package/dist/core/ingestion/languages/dart/captures.js +90 -2
  138. package/dist/core/ingestion/languages/dart/extension-type-preprocess.d.ts +7 -0
  139. package/dist/core/ingestion/languages/dart/extension-type-preprocess.js +30 -0
  140. package/dist/core/ingestion/languages/dart.js +2 -0
  141. package/dist/core/ingestion/languages/go/captures.js +34 -0
  142. package/dist/core/ingestion/languages/index.d.ts +1 -0
  143. package/dist/core/ingestion/languages/index.js +2 -0
  144. package/dist/core/ingestion/languages/java/analysis-features.d.ts +3 -0
  145. package/dist/core/ingestion/languages/java/analysis-features.js +13 -0
  146. package/dist/core/ingestion/languages/java/capture-side-channel.d.ts +22 -0
  147. package/dist/core/ingestion/languages/java/capture-side-channel.js +58 -0
  148. package/dist/core/ingestion/languages/java/captures.d.ts +4 -3
  149. package/dist/core/ingestion/languages/java/captures.js +193 -17
  150. package/dist/core/ingestion/languages/java/package-facts.d.ts +5 -0
  151. package/dist/core/ingestion/languages/java/package-facts.js +9 -0
  152. package/dist/core/ingestion/languages/java/package-siblings.d.ts +3 -16
  153. package/dist/core/ingestion/languages/java/package-siblings.js +8 -147
  154. package/dist/core/ingestion/languages/java/query.js +23 -0
  155. package/dist/core/ingestion/languages/java/scope-resolver.js +23 -0
  156. package/dist/core/ingestion/languages/java/spring-bean-metadata.d.ts +2 -0
  157. package/dist/core/ingestion/languages/java/spring-bean-metadata.js +8 -0
  158. package/dist/core/ingestion/languages/java/spring-config-bindings.d.ts +23 -0
  159. package/dist/core/ingestion/languages/java/spring-config-bindings.js +215 -0
  160. package/dist/core/ingestion/languages/java.js +3 -0
  161. package/dist/core/ingestion/languages/javascript/captures.js +16 -0
  162. package/dist/core/ingestion/languages/javascript/query.js +21 -0
  163. package/dist/core/ingestion/languages/jvm/package-facts.d.ts +35 -0
  164. package/dist/core/ingestion/languages/jvm/package-facts.js +40 -0
  165. package/dist/core/ingestion/languages/jvm/package-siblings.d.ts +14 -0
  166. package/dist/core/ingestion/languages/jvm/package-siblings.js +129 -0
  167. package/dist/core/ingestion/languages/kotlin/capture-side-channel.d.ts +17 -3
  168. package/dist/core/ingestion/languages/kotlin/capture-side-channel.js +42 -8
  169. package/dist/core/ingestion/languages/kotlin/captures.js +59 -0
  170. package/dist/core/ingestion/languages/kotlin/package-facts.d.ts +5 -0
  171. package/dist/core/ingestion/languages/kotlin/package-facts.js +9 -0
  172. package/dist/core/ingestion/languages/kotlin/package-siblings.d.ts +4 -0
  173. package/dist/core/ingestion/languages/kotlin/package-siblings.js +8 -0
  174. package/dist/core/ingestion/languages/kotlin/query.js +19 -0
  175. package/dist/core/ingestion/languages/kotlin/scope-resolver.js +9 -1
  176. package/dist/core/ingestion/languages/kotlin/spring-bean-metadata.d.ts +2 -0
  177. package/dist/core/ingestion/languages/kotlin/spring-bean-metadata.js +8 -0
  178. package/dist/core/ingestion/languages/kotlin.js +5 -6
  179. package/dist/core/ingestion/languages/move.d.ts +1 -0
  180. package/dist/core/ingestion/languages/move.js +27 -0
  181. package/dist/core/ingestion/languages/php/captures.js +40 -0
  182. package/dist/core/ingestion/languages/php/import-decomposer.js +12 -0
  183. package/dist/core/ingestion/languages/php/import-target.d.ts +2 -1
  184. package/dist/core/ingestion/languages/php/import-target.js +110 -2
  185. package/dist/core/ingestion/languages/php/interpret.js +10 -0
  186. package/dist/core/ingestion/languages/php/scope-resolver.js +1 -1
  187. package/dist/core/ingestion/languages/python/captures.d.ts +3 -4
  188. package/dist/core/ingestion/languages/python/captures.js +24 -5
  189. package/dist/core/ingestion/languages/python/interpret.js +4 -0
  190. package/dist/core/ingestion/languages/python/receiver-binding.d.ts +15 -2
  191. package/dist/core/ingestion/languages/python/receiver-binding.js +96 -2
  192. package/dist/core/ingestion/languages/python/simple-hooks.d.ts +5 -5
  193. package/dist/core/ingestion/languages/python/simple-hooks.js +15 -5
  194. package/dist/core/ingestion/languages/ruby/captures.js +42 -0
  195. package/dist/core/ingestion/languages/rust/captures.js +13 -0
  196. package/dist/core/ingestion/languages/rust/interpret.js +18 -0
  197. package/dist/core/ingestion/languages/rust/query.js +9 -0
  198. package/dist/core/ingestion/languages/rust/range-binding.js +6 -2
  199. package/dist/core/ingestion/languages/swift/captures.js +12 -0
  200. package/dist/core/ingestion/languages/typescript/captures.js +21 -0
  201. package/dist/core/ingestion/languages/typescript/nuxt-auto-imports.js +2 -1
  202. package/dist/core/ingestion/languages/typescript/query.js +37 -0
  203. package/dist/core/ingestion/markdown-processor.js +3 -2
  204. package/dist/core/ingestion/model/registration-table.js +1 -0
  205. package/dist/core/ingestion/parsing-processor.d.ts +3 -1
  206. package/dist/core/ingestion/parsing-processor.js +36 -1
  207. package/dist/core/ingestion/pipeline-phases/index.d.ts +2 -0
  208. package/dist/core/ingestion/pipeline-phases/index.js +2 -0
  209. package/dist/core/ingestion/pipeline-phases/parse-impl.js +56 -2
  210. package/dist/core/ingestion/pipeline-phases/parse.d.ts +0 -2
  211. package/dist/core/ingestion/pipeline-phases/parse.js +12 -3
  212. package/dist/core/ingestion/pipeline-phases/processes.d.ts +8 -0
  213. package/dist/core/ingestion/pipeline-phases/processes.js +11 -1
  214. package/dist/core/ingestion/pipeline-phases/spring-config.d.ts +37 -0
  215. package/dist/core/ingestion/pipeline-phases/spring-config.js +433 -0
  216. package/dist/core/ingestion/pipeline-phases/standalone-ingest.d.ts +10 -0
  217. package/dist/core/ingestion/pipeline-phases/standalone-ingest.js +6 -0
  218. package/dist/core/ingestion/pipeline.d.ts +4 -2
  219. package/dist/core/ingestion/pipeline.js +5 -2
  220. package/dist/core/ingestion/resolve-references.js +12 -0
  221. package/dist/core/ingestion/route-extractors/constant-resolver.d.ts +83 -0
  222. package/dist/core/ingestion/route-extractors/constant-resolver.js +131 -0
  223. package/dist/core/ingestion/route-extractors/python-const-resolver.d.ts +75 -0
  224. package/dist/core/ingestion/route-extractors/python-const-resolver.js +299 -0
  225. package/dist/core/ingestion/scope-extractor.js +306 -43
  226. package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +71 -2
  227. package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.d.ts +7 -7
  228. package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.js +8 -7
  229. package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +3 -1
  230. package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +6 -0
  231. package/dist/core/ingestion/scope-resolution/graph-bridge/ids.js +1 -0
  232. package/dist/core/ingestion/scope-resolution/graph-bridge/node-lookup.js +4 -1
  233. package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +7 -2
  234. package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.d.ts +47 -0
  235. package/dist/core/ingestion/scope-resolution/passes/callable-value-flow.js +1138 -0
  236. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +16 -4
  237. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +97 -1
  238. package/dist/core/ingestion/scope-resolution/passes/property-dispatch.d.ts +60 -0
  239. package/dist/core/ingestion/scope-resolution/passes/property-dispatch.js +111 -0
  240. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +4 -3
  241. package/dist/core/ingestion/scope-resolution/pipeline/phase.d.ts +5 -0
  242. package/dist/core/ingestion/scope-resolution/pipeline/phase.js +25 -38
  243. package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +6 -0
  244. package/dist/core/ingestion/scope-resolution/pipeline/run.js +147 -35
  245. package/dist/core/ingestion/scope-resolution/resolution-outcome.d.ts +1 -1
  246. package/dist/core/ingestion/scope-resolution/scope/walkers.js +73 -44
  247. package/dist/core/ingestion/taint/typescript-model.js +34 -2
  248. package/dist/core/ingestion/tree-sitter-queries.d.ts +2 -2
  249. package/dist/core/ingestion/tree-sitter-queries.js +23 -2
  250. package/dist/core/ingestion/type-extractors/jvm.js +17 -2
  251. package/dist/core/ingestion/utils/ast-helpers.d.ts +1 -0
  252. package/dist/core/ingestion/utils/ast-helpers.js +153 -2
  253. package/dist/core/ingestion/utils/callable-flow-captures.d.ts +94 -0
  254. package/dist/core/ingestion/utils/callable-flow-captures.js +878 -0
  255. package/dist/core/ingestion/utils/line-base.d.ts +20 -0
  256. package/dist/core/ingestion/utils/line-base.js +20 -0
  257. package/dist/core/ingestion/utils/symbol-labels.d.ts +21 -0
  258. package/dist/core/ingestion/utils/symbol-labels.js +45 -0
  259. package/dist/core/ingestion/workers/parse-worker.d.ts +34 -0
  260. package/dist/core/ingestion/workers/parse-worker.js +40 -5
  261. package/dist/core/ingestion/workers/result-merge.js +4 -0
  262. package/dist/core/ingestion/workers/worker-pool.d.ts +28 -0
  263. package/dist/core/ingestion/workers/worker-pool.js +128 -28
  264. package/dist/core/lbug/csv-generator.d.ts +15 -0
  265. package/dist/core/lbug/csv-generator.js +124 -27
  266. package/dist/core/lbug/cypher-escape.d.ts +20 -0
  267. package/dist/core/lbug/cypher-escape.js +20 -0
  268. package/dist/core/lbug/extension-load-error.d.ts +67 -0
  269. package/dist/core/lbug/extension-load-error.js +326 -0
  270. package/dist/core/lbug/extension-loader.d.ts +17 -2
  271. package/dist/core/lbug/extension-loader.js +38 -13
  272. package/dist/core/lbug/lbug-adapter.d.ts +203 -2
  273. package/dist/core/lbug/lbug-adapter.js +527 -86
  274. package/dist/core/lbug/lbug-config.d.ts +56 -2
  275. package/dist/core/lbug/lbug-config.js +267 -7
  276. package/dist/core/lbug/move-columns.d.ts +7 -0
  277. package/dist/core/lbug/move-columns.js +86 -0
  278. package/dist/core/lbug/native-check.d.ts +40 -0
  279. package/dist/core/lbug/native-check.js +90 -0
  280. package/dist/core/lbug/node-table-layout.d.ts +29 -0
  281. package/dist/core/lbug/node-table-layout.js +119 -0
  282. package/dist/core/lbug/pool-adapter.d.ts +23 -1
  283. package/dist/core/lbug/pool-adapter.js +115 -8
  284. package/dist/core/lbug/schema.d.ts +4 -3
  285. package/dist/core/lbug/schema.js +16 -16
  286. package/dist/core/lbug/sidecar-recovery.d.ts +172 -0
  287. package/dist/core/lbug/sidecar-recovery.js +418 -16
  288. package/dist/core/lbug/wal-checkpoint-driver.js +3 -0
  289. package/dist/core/move/artifact-download.d.ts +19 -0
  290. package/dist/core/move/artifact-download.js +179 -0
  291. package/dist/core/move/compiler-facts.d.ts +120 -0
  292. package/dist/core/move/compiler-facts.js +9 -0
  293. package/dist/core/move/consistency.d.ts +28 -0
  294. package/dist/core/move/consistency.js +98 -0
  295. package/dist/core/move/constants.d.ts +98 -0
  296. package/dist/core/move/constants.js +136 -0
  297. package/dist/core/move/discovery.d.ts +10 -0
  298. package/dist/core/move/discovery.js +22 -0
  299. package/dist/core/move/entry-points.d.ts +14 -0
  300. package/dist/core/move/entry-points.js +40 -0
  301. package/dist/core/move/facts-mapper.d.ts +75 -0
  302. package/dist/core/move/facts-mapper.js +534 -0
  303. package/dist/core/move/install-lock.d.ts +14 -0
  304. package/dist/core/move/install-lock.js +102 -0
  305. package/dist/core/move/install.d.ts +39 -0
  306. package/dist/core/move/install.js +391 -0
  307. package/dist/core/move/mcp-client.d.ts +115 -0
  308. package/dist/core/move/mcp-client.js +436 -0
  309. package/dist/core/move/move-ingest.d.ts +49 -0
  310. package/dist/core/move/move-ingest.js +320 -0
  311. package/dist/core/move/provision.d.ts +19 -0
  312. package/dist/core/move/provision.js +91 -0
  313. package/dist/core/move/release.d.ts +6 -0
  314. package/dist/core/move/release.js +10 -0
  315. package/dist/core/move/symbol-id.d.ts +35 -0
  316. package/dist/core/move/symbol-id.js +65 -0
  317. package/dist/core/move/type-parser.d.ts +11 -0
  318. package/dist/core/move/type-parser.js +38 -0
  319. package/dist/core/platform/capabilities.d.ts +0 -1
  320. package/dist/core/platform/capabilities.js +39 -8
  321. package/dist/core/run-analyze.d.ts +3 -3
  322. package/dist/core/run-analyze.js +1001 -184
  323. package/dist/core/search/fts-indexes.d.ts +31 -0
  324. package/dist/core/search/fts-indexes.js +73 -0
  325. package/dist/core/search/fts-schema.js +2 -0
  326. package/dist/core/tree-sitter/safe-parse.d.ts +8 -3
  327. package/dist/core/tree-sitter/safe-parse.js +21 -7
  328. package/dist/core/wiki/graph-queries.js +6 -5
  329. package/dist/core/wiki/llm-client.d.ts +8 -2
  330. package/dist/core/wiki/llm-client.js +41 -5
  331. package/dist/mcp/core/embedder.js +16 -2
  332. package/dist/mcp/http-transport.d.ts +5 -0
  333. package/dist/mcp/http-transport.js +19 -5
  334. package/dist/mcp/local/bean-metadata.d.ts +2 -0
  335. package/dist/mcp/local/bean-metadata.js +25 -0
  336. package/dist/mcp/local/line-display.d.ts +22 -0
  337. package/dist/mcp/local/line-display.js +3 -0
  338. package/dist/mcp/local/local-backend.d.ts +19 -1
  339. package/dist/mcp/local/local-backend.js +402 -155
  340. package/dist/mcp/local/pdg-impact.d.ts +5 -3
  341. package/dist/mcp/local/pdg-impact.js +5 -2
  342. package/dist/mcp/output-budget.d.ts +5 -0
  343. package/dist/mcp/output-budget.js +52 -0
  344. package/dist/mcp/read-only-policy.d.ts +12 -0
  345. package/dist/mcp/read-only-policy.js +102 -0
  346. package/dist/mcp/repository-policy.d.ts +34 -0
  347. package/dist/mcp/repository-policy.js +328 -0
  348. package/dist/mcp/resources.js +32 -5
  349. package/dist/mcp/server.d.ts +5 -2
  350. package/dist/mcp/server.js +29 -9
  351. package/dist/mcp/tools.d.ts +0 -8
  352. package/dist/mcp/tools.js +102 -5
  353. package/dist/server/analyze-job.d.ts +3 -0
  354. package/dist/server/analyze-job.js +17 -0
  355. package/dist/server/analyze-launch.d.ts +6 -0
  356. package/dist/server/analyze-launch.js +82 -6
  357. package/dist/server/analyze-worker-core.d.ts +2 -1
  358. package/dist/server/analyze-worker-core.js +5 -2
  359. package/dist/server/analyze-worker.js +29 -6
  360. package/dist/server/api.d.ts +30 -0
  361. package/dist/server/api.js +120 -34
  362. package/dist/server/mcp-http.d.ts +1 -1
  363. package/dist/server/mcp-http.js +4 -2
  364. package/dist/server/upload-ingest.js +2 -1
  365. package/dist/server/validation.js +2 -1
  366. package/dist/storage/git.d.ts +31 -0
  367. package/dist/storage/git.js +111 -1
  368. package/dist/storage/parse-cache.js +7 -1
  369. package/dist/storage/parsedfile-store.d.ts +8 -0
  370. package/dist/storage/parsedfile-store.js +165 -1
  371. package/dist/storage/repo-manager.d.ts +194 -2
  372. package/dist/storage/repo-manager.js +56 -1
  373. package/hooks/antigravity/gitnexus-antigravity-hook.cjs +50 -3
  374. package/hooks/claude/gitnexus-hook.cjs +59 -9
  375. package/hooks/claude/pre-tool-use.sh +0 -0
  376. package/hooks/claude/session-start.sh +0 -0
  377. package/package.json +21 -15
  378. package/scripts/cross-platform-tests.ts +56 -0
  379. package/scripts/ensure-fts.ts +43 -0
  380. package/scripts/install-duckdb-extension.mjs +85 -24
  381. package/scripts/run-cross-platform.ts +61 -6
  382. package/scripts/shard-arg.ts +30 -0
  383. package/scripts/sync-plugin-manifests.mjs +192 -0
  384. package/skills/gitnexus-lfg/README.md +55 -0
  385. package/skills/gitnexus-lfg/SKILL.md +86 -0
  386. package/skills/gitnexus-plan/README.md +142 -0
  387. package/skills/gitnexus-plan/SKILL.md +348 -0
  388. package/skills/gitnexus-plan/references/context-ledger.md +137 -0
  389. package/skills/gitnexus-plan/references/context-pack.md +126 -0
  390. package/skills/gitnexus-plan/references/evidence-provenance.md +272 -0
  391. package/skills/gitnexus-plan/references/pdg-slice.md +109 -0
  392. package/skills/gitnexus-plan/references/plan-template.md +201 -0
  393. package/skills/gitnexus-plan/scripts/evidence-provenance.mjs +2084 -0
  394. package/skills/gitnexus-review/SKILL.md +273 -0
  395. package/skills/gitnexus-review/ci-personas/ci-adversarial-lens.md +42 -0
  396. package/skills/gitnexus-review/ci-personas/ci-blast-radius-lens.md +39 -0
  397. package/skills/gitnexus-review/ci-personas/ci-correctness-lens.md +37 -0
  398. package/skills/gitnexus-review/ci-personas/ci-coverage-lens.md +40 -0
  399. package/skills/gitnexus-review/ci-personas/ci-critic-lens.md +42 -0
  400. package/skills/gitnexus-review/ci-personas/ci-security-lens.md +39 -0
  401. package/skills/gitnexus-work/README.md +71 -0
  402. package/skills/gitnexus-work/SKILL.md +269 -0
  403. package/skills/gitnexus-work/references/evidence-provenance.md +272 -0
  404. package/skills/gitnexus-work/scripts/evidence-provenance.mjs +2084 -0
  405. package/web/assets/ProcessFlowModal-B_bfBySy.js +22 -0
  406. package/web/assets/__vite-browser-external-bMKyYQkO.js +1 -0
  407. package/web/assets/agent-Bqxn-abU.js +626 -0
  408. package/web/assets/architecture-7EHR7CIX-6QZW5X65-BVWFvYz2.js +1 -0
  409. package/web/assets/architectureDiagram-UL44E2DR-CmG3uPWf.js +36 -0
  410. package/web/assets/{blockDiagram-7IZFK4PR-BkWhpzWB.js → blockDiagram-7IZFK4PR-DBefcjof.js} +7 -7
  411. package/web/assets/{c4Diagram-Y2BXMSZH-DtBvpzWD.js → c4Diagram-Y2BXMSZH-EjWnjEJl.js} +6 -6
  412. package/web/assets/chunk-2T2R6R2M-Bb6Sy3_j.js +4 -0
  413. package/web/assets/chunk-2UTLFMKG-CXlhF3Pt.js +1 -0
  414. package/web/assets/chunk-3SSMPTDK-rPsRM1x0.js +321 -0
  415. package/web/assets/chunk-4R4BOZG6-Be_F0JoX.js +159 -0
  416. package/web/assets/{chunk-6764PJDD-DpIS7hxD.js → chunk-6764PJDD-C7xxk063.js} +1 -1
  417. package/web/assets/chunk-67TQ5CYL-CA7OhIEf.js +124 -0
  418. package/web/assets/chunk-7FYTHRHK-CsmYIswB.js +32 -0
  419. package/web/assets/chunk-7J6CGLKN-BlKwgXKs.js +10 -0
  420. package/web/assets/chunk-7W6UQGC5-pyKGssV3.js +1 -0
  421. package/web/assets/chunk-C62D2QBJ-3gdL8EKc.js +1 -0
  422. package/web/assets/chunk-CEXFNPSA-CjwtMDkc.js +1 -0
  423. package/web/assets/{chunk-INKRHTLW-Nu4ri9P-.js → chunk-INKRHTLW-Ckl3_KkO.js} +13 -13
  424. package/web/assets/chunk-J5EP6P6S-L19oz55R.js +1 -0
  425. package/web/assets/{chunk-KGFNY3KK-JGMJvKCK.js → chunk-KGFNY3KK-BZeP-55u.js} +17 -17
  426. package/web/assets/chunk-KGYTTC2M-zm6n242I.js +1 -0
  427. package/web/assets/{chunk-KRXBNO2N-BW5o0KUN.js → chunk-KRXBNO2N-C-UNuKKf.js} +1 -1
  428. package/web/assets/{chunk-LCXTWHL2-CfLLCywY.js → chunk-LCXTWHL2-C162wE5z.js} +5 -5
  429. package/web/assets/chunk-LII3EMHJ-BL6lKJ_P.js +1 -0
  430. package/web/assets/chunk-LRIF4GLE-n59lhprL.js +1 -0
  431. package/web/assets/chunk-QA3QBVWF-DVXPOIxe.js +2 -0
  432. package/web/assets/chunk-RERM46MO-B5dAdWpP.js +1 -0
  433. package/web/assets/chunk-RG4AUYOV-ZNgyLFq6.js +206 -0
  434. package/web/assets/chunk-RKZBBQEN-MyIQbGgD.js +1 -0
  435. package/web/assets/chunk-RLI5ZMPA-CkXZ0y0U.js +1 -0
  436. package/web/assets/chunk-T2UQINTJ-BEyXhZWe.js +1 -0
  437. package/web/assets/chunk-UP6H54XL-BG-n7qDp.js +1 -0
  438. package/web/assets/chunk-UXSXWOXI-CW1_r5cS.js +1 -0
  439. package/web/assets/chunk-UY5QBCOK-ByqTVLvh.js +1 -0
  440. package/web/assets/chunk-VU6ZFW4Y-BLeasdkU.js +2 -0
  441. package/web/assets/{chunk-W44A43WB-JqMLIpR0.js → chunk-W44A43WB-BN8EQc_u.js} +1 -1
  442. package/web/assets/chunk-ZXARS5L4-C3v-4Fsw.js +1 -0
  443. package/web/assets/classDiagram-KGZ6W3CR-olpO3fMe.js +1 -0
  444. package/web/assets/classDiagram-v2-72OJOZXJ-olpO3fMe.js +1 -0
  445. package/web/assets/cose-bilkent-UX7MHV2Q-BmnZ7Mvj.js +1 -0
  446. package/web/assets/dagre-ND4H6XIP-CY4iIF7v.js +4 -0
  447. package/web/assets/diagram-3NCE3AQN-CO6QpzEE.js +43 -0
  448. package/web/assets/diagram-GF46GFSD-B2atbzmU.js +24 -0
  449. package/web/assets/diagram-HNR7UZ2L-DVRltWbL.js +3 -0
  450. package/web/assets/diagram-QXG6HAR7-DR6AHD2h.js +24 -0
  451. package/web/assets/diagram-WEQXMOUZ-DkpoMwTL.js +10 -0
  452. package/web/assets/erDiagram-L5TCEMPS-n8g_90bc.js +85 -0
  453. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-CgFBM7e-.js +1 -0
  454. package/web/assets/flowDiagram-H6V6AXG4-SGMDiCkB.js +162 -0
  455. package/web/assets/ganttDiagram-JCBTUEKG-Cb3UBqRS.js +292 -0
  456. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DCJv7SII.js +1 -0
  457. package/web/assets/gitGraphDiagram-S2ZK5IYY-Bs9CR7tq.js +106 -0
  458. package/web/assets/index-CX_fADmQ.css +2 -0
  459. package/web/assets/index-D1Z3dGGz.js +575 -0
  460. package/web/assets/info-J43DQDTF-KCYPFFUO-BfNy-9Nd.js +1 -0
  461. package/web/assets/infoDiagram-3YFTVSEB-T368on4D.js +2 -0
  462. package/web/assets/{ishikawaDiagram-BNXS4ZKH-DfYpxnE5.js → ishikawaDiagram-BNXS4ZKH-XpjJRU9h.js} +6 -6
  463. package/web/assets/journeyDiagram-M6C3CM3L-C6wjooas.js +139 -0
  464. package/web/assets/kanban-definition-75IXJCU3-5_UVY79g.js +89 -0
  465. package/web/assets/{katex-K3KEBU37-CTc5BslQ.js → katex-K3KEBU37-qRQBy-EZ.js} +2 -2
  466. package/web/assets/{mindmap-definition-2TDM6QVE-DypvbOMQ.js → mindmap-definition-2TDM6QVE-8xDLzk2e.js} +29 -29
  467. package/web/assets/node-Ct_zna8U.js +8 -0
  468. package/web/assets/packet-YPE3B663-LP52Z2RK-D4qkeG9k.js +1 -0
  469. package/web/assets/pie-LRSECV5Y-TCRJHUBD-B_yMKyQa.js +1 -0
  470. package/web/assets/pieDiagram-CU6KROY3-Bv4LpAbr.js +30 -0
  471. package/web/assets/preload-helper-Czpn1I53.js +1 -0
  472. package/web/assets/{quadrantDiagram-VICAPDV7-yXSZ2lLz.js → quadrantDiagram-VICAPDV7-DR54jOeR.js} +6 -6
  473. package/web/assets/radar-GUYGQ44K-RDLRG3WG-DeD6yN_0.js +1 -0
  474. package/web/assets/requirementDiagram-JXO7QTGE-PEkg7sKC.js +84 -0
  475. package/web/assets/rolldown-runtime-QTnfLwEv.js +1 -0
  476. package/web/assets/sankeyDiagram-URQDO5SZ-DDWEtjcs.js +40 -0
  477. package/web/assets/sdk-CzHHH8tD.js +37 -0
  478. package/web/assets/sequenceDiagram-VS2MUI6T-Bv-uwANx.js +162 -0
  479. package/web/assets/src-JV30wyV8.js +1 -0
  480. package/web/assets/stateDiagram-7D4R322I-DVNjmkEq.js +1 -0
  481. package/web/assets/stateDiagram-v2-36443NZ5-CyN4Fh7_.js +1 -0
  482. package/web/assets/timeline-definition-O6YCAMPW-Qmsuo7qS.js +120 -0
  483. package/web/assets/treeView-BLDUP644-QA4HXRO3-CDuSYnd4.js +1 -0
  484. package/web/assets/treemap-LRROVOQU-LLAWBHMP-imazucyJ.js +1 -0
  485. package/web/assets/vennDiagram-MWXL3ELB-BD1iK1SX.js +34 -0
  486. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-DqrT9tB8.js +1 -0
  487. package/web/assets/wardleyDiagram-CUQ6CDDI-D6TzLVob.js +78 -0
  488. package/web/assets/{xychartDiagram-N2JHSOCM-BOLm0eNm.js → xychartDiagram-N2JHSOCM-CoZ_Tits.js} +6 -6
  489. package/web/index.html +18 -10
  490. package/skills/gitnexus-pr-review.md +0 -163
  491. package/web/assets/agent-Dli_x7bU.js +0 -660
  492. package/web/assets/architecture-7EHR7CIX-6QZW5X65-DxJw65fT.js +0 -1
  493. package/web/assets/architectureDiagram-UL44E2DR-dEkqUZN9.js +0 -36
  494. package/web/assets/chunk-3SSMPTDK-B4_etUhr.js +0 -321
  495. package/web/assets/chunk-67TQ5CYL-4sNPJU1q.js +0 -124
  496. package/web/assets/chunk-7W6UQGC5-KyEG0HQg.js +0 -1
  497. package/web/assets/chunk-KGYTTC2M-CWC_c3H9.js +0 -161
  498. package/web/assets/chunk-LII3EMHJ-D-jm-dLa.js +0 -1
  499. package/web/assets/chunk-QA3QBVWF-BgRW3SXd.js +0 -2
  500. package/web/assets/chunk-RG4AUYOV-CqWzWsV3.js +0 -206
  501. package/web/assets/chunk-T2UQINTJ-DSBqkzH7.js +0 -1
  502. package/web/assets/chunk-UY5QBCOK-DyF0vyGd.js +0 -1
  503. package/web/assets/chunk-ZXARS5L4-CxN8oiwI.js +0 -1
  504. package/web/assets/classDiagram-KGZ6W3CR-CMne4tG9.js +0 -1
  505. package/web/assets/classDiagram-v2-72OJOZXJ-CMne4tG9.js +0 -1
  506. package/web/assets/cose-bilkent-UX7MHV2Q-D71wNYRJ.js +0 -1
  507. package/web/assets/dagre-ND4H6XIP-Co5rRx9X.js +0 -4
  508. package/web/assets/diagram-3NCE3AQN-DBp4O00j.js +0 -43
  509. package/web/assets/diagram-GF46GFSD-6N_8yS0i.js +0 -24
  510. package/web/assets/diagram-HNR7UZ2L-DFCfd5LI.js +0 -3
  511. package/web/assets/diagram-QXG6HAR7-Di093rFg.js +0 -24
  512. package/web/assets/diagram-WEQXMOUZ-DZWi4SUN.js +0 -10
  513. package/web/assets/erDiagram-L5TCEMPS-8X1y6R4Y.js +0 -85
  514. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-BQm9QzEa.js +0 -1
  515. package/web/assets/flowDiagram-H6V6AXG4-CMpY8Ufn.js +0 -162
  516. package/web/assets/ganttDiagram-JCBTUEKG-D3iL2Aet.js +0 -292
  517. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-Cr_Bm2Nb.js +0 -1
  518. package/web/assets/gitGraphDiagram-S2ZK5IYY-CPIDgxGm.js +0 -106
  519. package/web/assets/index-KctnI3Vq.js +0 -635
  520. package/web/assets/index-_lgn7hs5.css +0 -2
  521. package/web/assets/info-J43DQDTF-KCYPFFUO-Cs4p2oyk.js +0 -1
  522. package/web/assets/infoDiagram-3YFTVSEB-BaLMZkUg.js +0 -2
  523. package/web/assets/journeyDiagram-M6C3CM3L-CvArszLo.js +0 -139
  524. package/web/assets/kanban-definition-75IXJCU3-CpfVLLf9.js +0 -89
  525. package/web/assets/packet-YPE3B663-LP52Z2RK-CKCrztD2.js +0 -1
  526. package/web/assets/pie-LRSECV5Y-TCRJHUBD-BB7pHqoD.js +0 -1
  527. package/web/assets/pieDiagram-CU6KROY3-s27EFWgP.js +0 -30
  528. package/web/assets/radar-GUYGQ44K-RDLRG3WG-DhoTOcuK.js +0 -1
  529. package/web/assets/requirementDiagram-JXO7QTGE-CWhqInuf.js +0 -84
  530. package/web/assets/sankeyDiagram-URQDO5SZ-1qEjlFIB.js +0 -40
  531. package/web/assets/sequenceDiagram-VS2MUI6T-RyTlZ5cR.js +0 -162
  532. package/web/assets/stateDiagram-7D4R322I-DTjVfX4A.js +0 -1
  533. package/web/assets/stateDiagram-v2-36443NZ5-xY9_k9_Q.js +0 -1
  534. package/web/assets/timeline-definition-O6YCAMPW-DrrqLYAf.js +0 -120
  535. package/web/assets/treeView-BLDUP644-QA4HXRO3-ODehyGKL.js +0 -1
  536. package/web/assets/treemap-LRROVOQU-LLAWBHMP-BfpgC-7o.js +0 -1
  537. package/web/assets/vennDiagram-MWXL3ELB-B0RkWAim.js +0 -34
  538. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-CNeL6VHE.js +0 -1
  539. package/web/assets/wardleyDiagram-CUQ6CDDI-boUxiQ5F.js +0 -78
@@ -0,0 +1,878 @@
1
+ /**
2
+ * Configurable AST-to-`@callable-flow.*` capture synthesis.
3
+ *
4
+ * The traversal is language-neutral: providers supply their grammar's node
5
+ * vocabulary and the small semantic callbacks (true-reference bindings,
6
+ * callable signatures, protocol invocation names). The central extractor
7
+ * never sees a parser node and shared ingestion code never branches on a
8
+ * language name.
9
+ */
10
+ import { nodeToCapture, syntheticCapture } from './ast-helpers.js';
11
+ /**
12
+ * Emit normalized flow captures in deterministic source order.
13
+ *
14
+ * One explicit DFS supplies all phases below. Query-backed emitters may still
15
+ * perform their existing query walk; this helper never reparses and remains
16
+ * linear in AST size (the scope-capture benchmark guards the scaling ratio).
17
+ */
18
+ export function synthesizeCallableFlowCaptures(root, options) {
19
+ const nodes = collectNodes(root);
20
+ const functions = collectFunctions(nodes, options);
21
+ const knownCallableNames = new Set(functions.map((fn) => fn.name));
22
+ const assignments = collectAssignments(nodes, options);
23
+ const valueBindings = buildValueBindingIndex(nodes, assignments, functions, options);
24
+ const out = [];
25
+ for (const assignment of assignments) {
26
+ emitAssignmentFact(assignment, knownCallableNames, valueBindings, options, out);
27
+ }
28
+ for (const fn of functions)
29
+ emitFormalFacts(fn, options, out);
30
+ for (const node of nodes) {
31
+ if (options.callNodeTypes.has(node.type) &&
32
+ (options.isCallNode === undefined || options.isCallNode(node))) {
33
+ emitCallFacts(node, knownCallableNames, valueBindings, options, out);
34
+ }
35
+ }
36
+ out.sort((a, b) => compareCaptures(firstCapture(a), firstCapture(b)));
37
+ return out;
38
+ }
39
+ function collectNodes(root) {
40
+ const out = [];
41
+ const stack = [root];
42
+ while (stack.length > 0) {
43
+ const node = stack.pop();
44
+ out.push(node);
45
+ const children = node.namedChildren;
46
+ for (let i = children.length - 1; i >= 0; i--) {
47
+ const child = children[i];
48
+ if (child !== null)
49
+ stack.push(child);
50
+ }
51
+ }
52
+ return out;
53
+ }
54
+ function collectFunctions(nodes, options) {
55
+ const out = [];
56
+ for (const node of nodes) {
57
+ if (!options.functionNodeTypes.has(node.type))
58
+ continue;
59
+ const name = options.functionName?.(node) ?? defaultFunctionName(node, options);
60
+ if (name === undefined || name.length === 0)
61
+ continue;
62
+ out.push({ node, name, parameters: functionParameters(node, options) });
63
+ }
64
+ return out;
65
+ }
66
+ function defaultFunctionName(node, options) {
67
+ const direct = node.childForFieldName('name');
68
+ if (direct !== null) {
69
+ const id = terminalIdentifier(direct, options);
70
+ if (id !== undefined)
71
+ return id.text;
72
+ }
73
+ const declarator = node.childForFieldName('declarator');
74
+ if (declarator !== null) {
75
+ const id = bindingIdentifier(declarator, options);
76
+ if (id !== undefined)
77
+ return id.text;
78
+ }
79
+ const parent = node.parent;
80
+ if (parent !== null && options.bindingNodeTypes.has(parent.type)) {
81
+ const destination = assignmentParts(parent, options)[0]?.destination;
82
+ if (destination !== undefined)
83
+ return bindingIdentifier(destination, options)?.text;
84
+ }
85
+ return undefined;
86
+ }
87
+ function functionParameters(node, options) {
88
+ const providerParameters = options.extractFunctionParameters?.(node);
89
+ if (providerParameters !== undefined)
90
+ return providerParameters;
91
+ const explicit = node.childForFieldName('parameters') ??
92
+ node.childForFieldName('parameter') ??
93
+ findFirstDescendantOfTypes(node, options.parameterListNodeTypes);
94
+ if (explicit === null)
95
+ return [];
96
+ const direct = explicit.namedChildren.filter((child) => child !== null &&
97
+ (options.parameterNodeTypes.has(child.type) ||
98
+ (options.parameterListNodeTypes.has(explicit.type) &&
99
+ bindingIdentifier(child, options) !== undefined)));
100
+ return direct;
101
+ }
102
+ function collectAssignments(nodes, options) {
103
+ const out = [];
104
+ const seen = new Set();
105
+ for (const node of nodes) {
106
+ if (!options.bindingNodeTypes.has(node.type) && !options.assignmentNodeTypes.has(node.type)) {
107
+ continue;
108
+ }
109
+ if (seen.has(node.id))
110
+ continue;
111
+ const parts = assignmentParts(node, options);
112
+ if (parts.length === 0)
113
+ continue;
114
+ seen.add(node.id);
115
+ out.push(...parts);
116
+ }
117
+ return out;
118
+ }
119
+ function buildValueBindingIndex(nodes, assignments, functions, options) {
120
+ const assignmentRegionIdsByName = new Map();
121
+ const formalByOwner = new Map();
122
+ const signatureByNameAndRegion = new Map();
123
+ const add = (index, owner, name) => {
124
+ let names = index.get(owner);
125
+ if (names === undefined) {
126
+ names = new Set();
127
+ index.set(owner, names);
128
+ }
129
+ names.add(name);
130
+ };
131
+ for (const assignment of assignments) {
132
+ const destinationNames = new Set();
133
+ const destination = operandSyntax(assignment.destination, options, true);
134
+ if (destination !== undefined)
135
+ destinationNames.add(destination.name);
136
+ // Member-path destinations (`o->run = handler`) store into the MEMBER's
137
+ // name-cell — the seed fact is keyed on `run`, so the store must be
138
+ // visible under that name too or the member-call invoke gate never sees
139
+ // it (#2522 review, M3 ops-vtable pattern).
140
+ const terminal = terminalIdentifier(assignment.destination, options);
141
+ if (terminal !== undefined)
142
+ destinationNames.add(terminal.text);
143
+ for (const name of destinationNames) {
144
+ const region = nearestLexicalRegion(assignment.container, options);
145
+ let regionIds = assignmentRegionIdsByName.get(name);
146
+ if (regionIds === undefined) {
147
+ regionIds = new Set();
148
+ assignmentRegionIdsByName.set(name, regionIds);
149
+ }
150
+ regionIds.add(region.id);
151
+ if (options.functionScopedValueBindings === true) {
152
+ const functionOwner = nearestFunctionOwner(assignment.container, options);
153
+ if (functionOwner !== undefined)
154
+ regionIds.add(functionOwner.id);
155
+ }
156
+ }
157
+ }
158
+ for (const fn of functions) {
159
+ for (const parameter of fn.parameters) {
160
+ const binding = bindingIdentifier(parameter, options);
161
+ if (binding !== undefined)
162
+ add(formalByOwner, fn.node.id, binding.text);
163
+ }
164
+ }
165
+ for (const node of nodes) {
166
+ if (options.callableSignatureDeclarationNodeTypes?.has(node.type) !== true)
167
+ continue;
168
+ const binding = bindingIdentifier(node, options);
169
+ const signature = options.expectedSignature?.(node, node);
170
+ if (binding === undefined || signature === undefined)
171
+ continue;
172
+ // Only callable-typed VARIABLE declarations (`void (*fp)(int);`) create
173
+ // value cells — a plain function/method prototype (`void f(int);`)
174
+ // declares a callee, not a value. A variable declarator interposes a
175
+ // pointer/parenthesized declarator between the declaration and its
176
+ // identifier; a prototype's identifier hangs directly off the function
177
+ // declarator. Indexing prototypes here turned every call to a declared
178
+ // function into an indirect invoke — and, with
179
+ // `emitCanonicalInvokeReference`, minted a free-call reference that
180
+ // bypassed the precise passes' two-phase/ambiguity suppression
181
+ // (#2522 CI: eight cpp resolver tests gained a phantom edge).
182
+ if (!bindingInterposesValueDeclarator(node, binding))
183
+ continue;
184
+ const region = nearestLexicalRegion(node, options);
185
+ let byRegion = signatureByNameAndRegion.get(binding.text);
186
+ if (byRegion === undefined) {
187
+ byRegion = new Map();
188
+ signatureByNameAndRegion.set(binding.text, byRegion);
189
+ }
190
+ byRegion.set(region.id, signature);
191
+ if (options.functionScopedValueBindings === true) {
192
+ const functionOwner = nearestFunctionOwner(node, options);
193
+ if (functionOwner !== undefined)
194
+ byRegion.set(functionOwner.id, signature);
195
+ }
196
+ }
197
+ return { assignmentRegionIdsByName, formalByOwner, signatureByNameAndRegion };
198
+ }
199
+ /** True when a pointer/parenthesized declarator sits between the declaration
200
+ * and its binding identifier — the shape of a callable-typed variable, never
201
+ * of a plain prototype. Only C/C++ supply signature-declaration node types,
202
+ * so the type-name sniff stays scoped to those grammars. */
203
+ function bindingInterposesValueDeclarator(declaration, binding) {
204
+ let node = binding.parent;
205
+ while (node !== null && node.id !== declaration.id) {
206
+ if (node.type.includes('pointer') || node.type.includes('parenthesized'))
207
+ return true;
208
+ node = node.parent;
209
+ }
210
+ return false;
211
+ }
212
+ function nearestFunctionOwner(input, options) {
213
+ const providerOwner = options.lexicalFunctionOwner?.(input);
214
+ if (providerOwner !== undefined)
215
+ return providerOwner;
216
+ let node = input;
217
+ while (node !== null) {
218
+ if (options.functionNodeTypes.has(node.type))
219
+ return node;
220
+ node = node.parent;
221
+ }
222
+ return undefined;
223
+ }
224
+ function nearestLexicalRegion(input, options) {
225
+ const providerOwner = options.lexicalFunctionOwner?.(input);
226
+ let node = input.parent;
227
+ let outermost = input;
228
+ while (node !== null) {
229
+ outermost = node;
230
+ if (providerOwner !== undefined && node.id === providerOwner.id)
231
+ return node;
232
+ if (options.functionNodeTypes.has(node.type) || isLexicalRegionNode(node))
233
+ return node;
234
+ node = node.parent;
235
+ }
236
+ return providerOwner ?? outermost;
237
+ }
238
+ function isLexicalRegionNode(node) {
239
+ return /(?:^|_)(?:block|body|compound_statement|source_file|program|module|script)(?:$|_)/.test(node.type);
240
+ }
241
+ function isVisibleValueBinding(input, name, bindings, options) {
242
+ const assignmentRegionIds = bindings.assignmentRegionIdsByName.get(name);
243
+ const providerOwner = options.lexicalFunctionOwner?.(input);
244
+ if (providerOwner !== undefined &&
245
+ (assignmentRegionIds?.has(providerOwner.id) === true ||
246
+ bindings.formalByOwner.get(providerOwner.id)?.has(name) === true)) {
247
+ return true;
248
+ }
249
+ let node = input;
250
+ while (node !== null) {
251
+ if (assignmentRegionIds?.has(node.id) === true)
252
+ return true;
253
+ if (options.functionNodeTypes.has(node.type) &&
254
+ bindings.formalByOwner.get(node.id)?.has(name) === true) {
255
+ return true;
256
+ }
257
+ node = node.parent;
258
+ }
259
+ if (bindings.formalByOwner.get(undefined)?.has(name) === true)
260
+ return true;
261
+ // A declared callable-typed binding (file-scope `void (*fp)(int);`) is a
262
+ // value binding wherever its declaration is visible — its assignments may
263
+ // live in OTHER functions (the init/register callback pattern), so
264
+ // assignment regions alone under-approximate visibility and the cross-
265
+ // function call emitted no invoke fact at all (#2522 review, H1).
266
+ return visibleCallableSignature(input, name, bindings, options) !== undefined;
267
+ }
268
+ function visibleCallableSignature(input, name, bindings, options) {
269
+ const byRegion = bindings.signatureByNameAndRegion.get(name);
270
+ if (byRegion === undefined)
271
+ return undefined;
272
+ const providerOwner = options.lexicalFunctionOwner?.(input);
273
+ if (providerOwner !== undefined) {
274
+ const signature = byRegion.get(providerOwner.id);
275
+ if (signature !== undefined)
276
+ return signature;
277
+ }
278
+ let node = input;
279
+ while (node !== null) {
280
+ const signature = byRegion.get(node.id);
281
+ if (signature !== undefined)
282
+ return signature;
283
+ node = node.parent;
284
+ }
285
+ return undefined;
286
+ }
287
+ function assignmentParts(node, options) {
288
+ const providerParts = options.extractAssignment?.(node);
289
+ if (providerParts !== undefined) {
290
+ const pairs = Array.isArray(providerParts) ? providerParts : [providerParts];
291
+ return pairs.map((pair) => ({ container: node, ...pair }));
292
+ }
293
+ const destination = node.childForFieldName('left') ??
294
+ node.childForFieldName('name') ??
295
+ node.childForFieldName('pattern') ??
296
+ node.childForFieldName('declarator') ??
297
+ node.childForFieldName('target'); // Swift assignment
298
+ const source = node.childForFieldName('right') ??
299
+ node.childForFieldName('value') ??
300
+ node.childForFieldName('initializer') ??
301
+ node.childForFieldName('default_value') ??
302
+ node.childForFieldName('result'); // Swift assignment
303
+ // Declaration wrappers often contain the real initialized declarator one
304
+ // level below (for example a declarator list).
305
+ if (destination === null || source === null) {
306
+ for (const child of node.namedChildren) {
307
+ if (child === null || child.id === node.id)
308
+ continue;
309
+ if (!options.bindingNodeTypes.has(child.type))
310
+ continue;
311
+ const nested = assignmentParts(child, options);
312
+ if (nested.length > 0)
313
+ return nested;
314
+ }
315
+ }
316
+ if (destination === null || source === null)
317
+ return [];
318
+ return [{ container: node, destination, source }];
319
+ }
320
+ function emitAssignmentFact(assignment, knownCallableNames, valueBindings, options, out) {
321
+ const destination = operandSyntax(assignment.destination, options, options.bindingNodeTypes.has(assignment.container.type));
322
+ const source = operandSyntax(assignment.source, options);
323
+ if (destination === undefined || source === undefined)
324
+ return;
325
+ const signature = options.expectedSignature?.(assignment.container, assignment.destination) ??
326
+ visibleCallableSignature(assignment.container, destination.name, valueBindings, options);
327
+ const sourceIsValueBinding = isVisibleValueBinding(assignment.source, source.name, valueBindings, options);
328
+ if (options.bareNamesAreCalls === true &&
329
+ source.directDesignator &&
330
+ !source.callableReference &&
331
+ !source.anonymousCallable &&
332
+ !sourceIsValueBinding) {
333
+ // The RHS is the produced value of a call, not a reference to the callee.
334
+ return;
335
+ }
336
+ const sourceIsKnownCallable = source.callableReference ||
337
+ source.anonymousCallable ||
338
+ (source.directDesignator &&
339
+ !sourceIsValueBinding &&
340
+ (knownCallableNames.has(source.name) ||
341
+ source.qualifiedName !== undefined ||
342
+ signature !== undefined));
343
+ const flowSource = sourceIsKnownCallable ? asCallableDesignator(source) : source;
344
+ // A call/constructor/composite result is not the function designator that
345
+ // appears inside it. This guard must precede the store path: otherwise
346
+ // `*slot = factory()` stores `factory` itself into `slot`.
347
+ if (!source.directDesignator &&
348
+ !sourceIsKnownCallable &&
349
+ source.indirection === 0 &&
350
+ !source.addressOf) {
351
+ return;
352
+ }
353
+ if (destination.indirection > 0) {
354
+ out.push(binaryFact('store', assignment.container, 'pointer', destination, 'source', flowSource));
355
+ return;
356
+ }
357
+ if (source.addressOf && !sourceIsKnownCallable) {
358
+ // An address of a value binding creates an abstract-cell edge. Addresses
359
+ // of named callables are seeds instead (function designator semantics).
360
+ if (sourceIsValueBinding) {
361
+ out.push(binaryFact('address', assignment.container, 'destination', destination, 'source', source));
362
+ }
363
+ else if (source.directDesignator) {
364
+ // A declaration imported from another file is only visible after scope
365
+ // finalization. Preserve both interpretations here: the address relation
366
+ // supports pointer-to-pointer cells, while the copy lets the solver's
367
+ // exact lexical/import lookup recognize `auto fp = &importedTarget`.
368
+ out.push(binaryFact('address', assignment.container, 'destination', destination, 'source', source));
369
+ out.push(binaryFact('copy', assignment.container, 'destination', destination, 'source', source));
370
+ }
371
+ return;
372
+ }
373
+ if (source.indirection > 0 && !sourceIsKnownCallable) {
374
+ out.push(binaryFact('load', assignment.container, 'destination', destination, 'pointer', source));
375
+ return;
376
+ }
377
+ if (sourceIsKnownCallable) {
378
+ const match = {
379
+ '@callable-flow.seed': nodeToCapture('@callable-flow.seed', assignment.container),
380
+ '@callable-flow.destination': operandCapture('@callable-flow.destination', destination),
381
+ '@callable-flow.target': operandCapture('@callable-flow.target', flowSource),
382
+ '@callable-flow.target-name': syntheticCapture('@callable-flow.target-name', flowSource.node, flowSource.anonymousCallable ? destination.name : flowSource.name),
383
+ };
384
+ if (flowSource.qualifiedName !== undefined) {
385
+ match['@callable-flow.target-qualified-name'] = syntheticCapture('@callable-flow.target-qualified-name', flowSource.node, options.normalizeQualifiedName?.(flowSource.qualifiedName) ?? flowSource.qualifiedName);
386
+ }
387
+ addSignatureCaptures(match, assignment.container, signature);
388
+ out.push(match);
389
+ return;
390
+ }
391
+ const kind = options.isTrueReferenceBinding?.(assignment.container, assignment.destination)
392
+ ? 'alias'
393
+ : 'copy';
394
+ out.push(binaryFact(kind, assignment.container, 'destination', destination, 'source', flowSource));
395
+ }
396
+ function emitFormalFacts(fn, options, out) {
397
+ for (let index = 0; index < fn.parameters.length; index++) {
398
+ const parameter = fn.parameters[index];
399
+ const binding = bindingIdentifier(parameter, options);
400
+ if (binding === undefined)
401
+ continue;
402
+ const mode = options.parameterPassingMode?.(parameter) ?? 'value';
403
+ const match = {
404
+ '@callable-flow.formal': nodeToCapture('@callable-flow.formal', fn.node),
405
+ '@callable-flow.owner': syntheticCapture('@callable-flow.owner', fn.node, fn.name),
406
+ '@callable-flow.binding': syntheticCapture('@callable-flow.binding', binding, binding.text),
407
+ '@callable-flow.parameter-index': syntheticCapture('@callable-flow.parameter-index', binding, String(index)),
408
+ '@callable-flow.passing-mode': syntheticCapture('@callable-flow.passing-mode', parameter, mode),
409
+ };
410
+ addSignatureCaptures(match, parameter, options.expectedSignature?.(parameter, parameter));
411
+ out.push(match);
412
+ }
413
+ }
414
+ function emitCallFacts(call, knownCallableNames, valueBindings, options, out) {
415
+ const calleeNode = options.extractCallCallee?.(call) ??
416
+ call.childForFieldName('function') ??
417
+ call.childForFieldName('callee') ??
418
+ call.childForFieldName('name') ??
419
+ call.childForFieldName('method') ??
420
+ call.firstNamedChild;
421
+ if (calleeNode === null)
422
+ return;
423
+ const callSite = options.callSiteNode?.(call) ?? call;
424
+ const args = callArguments(call, options);
425
+ const member = directCallMemberParts(call, options) ?? memberParts(calleeNode, options);
426
+ const callee = operandSyntax(calleeNode, options);
427
+ const calleeIsValueBinding = callee !== undefined && isVisibleValueBinding(call, callee.name, valueBindings, options);
428
+ const directCalleeName = member === undefined &&
429
+ callee !== undefined &&
430
+ callee.indirection === 0 &&
431
+ !calleeIsValueBinding
432
+ ? callee.name
433
+ : undefined;
434
+ for (let index = 0; index < args.length; index++) {
435
+ const rawSource = operandSyntax(args[index], options);
436
+ if (rawSource === undefined)
437
+ continue;
438
+ // A call/constructor/composite result is a produced value, not a reference
439
+ // to the terminal identifier inside the expression.
440
+ if (!rawSource.directDesignator && rawSource.indirection === 0 && !rawSource.addressOf) {
441
+ continue;
442
+ }
443
+ const sourceIsValueBinding = isVisibleValueBinding(args[index], rawSource.name, valueBindings, options);
444
+ if (options.bareNamesAreCalls === true &&
445
+ rawSource.directDesignator &&
446
+ !rawSource.callableReference &&
447
+ !rawSource.anonymousCallable &&
448
+ !sourceIsValueBinding) {
449
+ // Bare argument name = a call's produced value in this language.
450
+ continue;
451
+ }
452
+ const sourceIsKnownCallable = rawSource.callableReference ||
453
+ rawSource.anonymousCallable ||
454
+ (rawSource.directDesignator &&
455
+ !sourceIsValueBinding &&
456
+ (knownCallableNames.has(rawSource.name) || rawSource.qualifiedName !== undefined));
457
+ // Keep unresolved direct identifiers (not arbitrary expressions): imports
458
+ // and cross-file callable bindings are only known after registry finalize.
459
+ // The solver requires an exact callable lexical binding before propagating,
460
+ // so ordinary value arguments remain inert.
461
+ if (!sourceIsValueBinding &&
462
+ !sourceIsKnownCallable &&
463
+ !rawSource.directDesignator &&
464
+ !rawSource.addressOf) {
465
+ continue;
466
+ }
467
+ const source = sourceIsKnownCallable ? asCallableDesignator(rawSource) : rawSource;
468
+ out.push({
469
+ '@callable-flow.argument': nodeToCapture('@callable-flow.argument', callSite),
470
+ '@callable-flow.source': operandCapture('@callable-flow.source', source),
471
+ ...operandMetadataCaptures('source', source),
472
+ ...(source.indirection > 0
473
+ ? {
474
+ '@callable-flow.source-indirection': syntheticCapture('@callable-flow.source-indirection', source.node, String(source.indirection)),
475
+ }
476
+ : {}),
477
+ ...(source.addressOf
478
+ ? {
479
+ '@callable-flow.source-address': syntheticCapture('@callable-flow.source-address', source.node, 'true'),
480
+ }
481
+ : {}),
482
+ '@callable-flow.parameter-index': syntheticCapture('@callable-flow.parameter-index', args[index], String(index)),
483
+ ...(directCalleeName !== undefined
484
+ ? {
485
+ '@callable-flow.direct-callee-name': syntheticCapture('@callable-flow.direct-callee-name', callee.node, directCalleeName),
486
+ }
487
+ : {}),
488
+ });
489
+ }
490
+ if (member !== undefined) {
491
+ if (member.operator !== undefined &&
492
+ options.memberPointerOperators?.has(member.operator) === true) {
493
+ emitInvoke(callSite, member.member, 'member-pointer', args.length, out, options, member.receiver);
494
+ return;
495
+ }
496
+ if (options.callableProtocolMethods?.has(member.member.name) === true) {
497
+ emitInvoke(callSite, member.receiver, 'callable-object', args.length, out, options);
498
+ return;
499
+ }
500
+ // Field-stored callables (`o->run = handler; o->run(1)` — the C ops-vtable
501
+ // pattern): when a visible assignment wrote this member's name-cell, the
502
+ // member call is an indirect invoke through that cell (#2522 review, M3).
503
+ // Gated on the store so plain accessor calls (`map.get(x)`) stay inert;
504
+ // name-keyed field collapse matches the solver's store/load model.
505
+ // ponytail: same-region joins only — cross-function vtable installs need
506
+ // a field-sensitive cell model.
507
+ if (isVisibleValueBinding(call, member.member.name, valueBindings, options)) {
508
+ emitInvoke(callSite, member.member, 'indirect', args.length, out, options, member.receiver);
509
+ }
510
+ return;
511
+ }
512
+ if (callee === undefined)
513
+ return;
514
+ if (callee.indirection > 0 || calleeIsValueBinding) {
515
+ const invokeCallee = !calleeIsValueBinding && knownCallableNames.has(callee.name)
516
+ ? asCallableDesignator(callee)
517
+ : callee;
518
+ emitInvoke(callSite, invokeCallee, 'indirect', args.length, out, options);
519
+ }
520
+ }
521
+ function emitInvoke(call, callee, invocationKind, arity, out, options, receiver) {
522
+ out.push({
523
+ '@callable-flow.invoke': nodeToCapture('@callable-flow.invoke', call),
524
+ '@callable-flow.callee': operandCapture('@callable-flow.callee', callee),
525
+ ...operandMetadataCaptures('callee', callee),
526
+ ...(callee.indirection > 0
527
+ ? {
528
+ '@callable-flow.callee-indirection': syntheticCapture('@callable-flow.callee-indirection', callee.node, String(callee.indirection)),
529
+ }
530
+ : {}),
531
+ ...(receiver !== undefined
532
+ ? {
533
+ '@callable-flow.receiver': operandCapture('@callable-flow.receiver', receiver),
534
+ ...operandMetadataCaptures('receiver', receiver),
535
+ }
536
+ : {}),
537
+ '@callable-flow.invocation-kind': syntheticCapture('@callable-flow.invocation-kind', call, invocationKind),
538
+ '@callable-flow.arity': syntheticCapture('@callable-flow.arity', call, String(arity)),
539
+ });
540
+ if (invocationKind === 'member-pointer' && receiver !== undefined) {
541
+ // Parenthesized member-pointer callees are not matched by the ordinary
542
+ // member-call query shape.
543
+ // Supply the same canonical callsite contract so the shared resolver can
544
+ // exact-join this fact instead of trusting an unanchored/stale side fact.
545
+ out.push({
546
+ '@reference.call.member': nodeToCapture('@reference.call.member', call),
547
+ '@reference.receiver': operandCapture('@reference.receiver', receiver),
548
+ '@reference.name': operandCapture('@reference.name', callee),
549
+ '@reference.arity': syntheticCapture('@reference.arity', call, String(arity)),
550
+ });
551
+ }
552
+ else if (options.emitCanonicalInvokeReference === true) {
553
+ out.push({
554
+ '@reference.call.free': nodeToCapture('@reference.call.free', call),
555
+ '@reference.name': operandCapture('@reference.name', callee),
556
+ '@reference.arity': syntheticCapture('@reference.arity', call, String(arity)),
557
+ });
558
+ }
559
+ }
560
+ function callArguments(call, options) {
561
+ const list = call.childForFieldName('arguments') ??
562
+ call.childForFieldName('argument') ??
563
+ call.namedChildren.find((child) => child !== null && options.parameterListNodeTypes.has(child.type)) ??
564
+ findFirstDescendantOfTypes(call, options.parameterListNodeTypes) ??
565
+ null;
566
+ if (list === null)
567
+ return [];
568
+ if (options.parameterListNodeTypes.has(list.type)) {
569
+ return list.namedChildren.filter((child) => child !== null && child.type !== 'comment');
570
+ }
571
+ return [list];
572
+ }
573
+ function directCallMemberParts(call, options) {
574
+ const receiverNode = call.childForFieldName('object') ?? call.childForFieldName('receiver');
575
+ const memberNode = call.childForFieldName('method') ?? call.childForFieldName('name');
576
+ if (receiverNode === null || memberNode === null)
577
+ return undefined;
578
+ const receiver = operandSyntax(receiverNode, options);
579
+ const member = operandSyntax(memberNode, options);
580
+ return receiver === undefined || member === undefined ? undefined : { receiver, member };
581
+ }
582
+ function memberParts(input, options) {
583
+ const providerParts = options.memberPointerParts?.(input);
584
+ if (providerParts !== undefined) {
585
+ const receiver = operandSyntax(providerParts.receiver, options);
586
+ const member = operandSyntax(providerParts.member, options);
587
+ if (receiver !== undefined && member !== undefined) {
588
+ return { receiver, member, operator: providerParts.operator };
589
+ }
590
+ }
591
+ let node = input;
592
+ for (let guard = 0; guard < 8; guard++) {
593
+ const wrapped = wrappedExpression(node);
594
+ if (wrapped === null)
595
+ break;
596
+ node = wrapped;
597
+ }
598
+ const receiverNode = node.childForFieldName('object') ??
599
+ node.childForFieldName('argument') ??
600
+ node.childForFieldName('receiver');
601
+ const memberNode = node.childForFieldName('property') ??
602
+ node.childForFieldName('field') ??
603
+ node.childForFieldName('method');
604
+ if (receiverNode === null || memberNode === null)
605
+ return undefined;
606
+ const receiver = operandSyntax(receiverNode, options);
607
+ const member = operandSyntax(memberNode, options);
608
+ if (receiver === undefined || member === undefined)
609
+ return undefined;
610
+ const operator = node.children.find((child) => options.memberPointerOperators?.has(child.type) === true ||
611
+ options.memberPointerOperators?.has(child.text) === true);
612
+ return { receiver, member, ...(operator !== undefined ? { operator: operator.text } : {}) };
613
+ }
614
+ function operandSyntax(input, options, declarationBinding = false) {
615
+ if (declarationBinding) {
616
+ const binding = bindingIdentifier(input, options);
617
+ if (binding === undefined)
618
+ return undefined;
619
+ return {
620
+ name: binding.text,
621
+ node: binding,
622
+ indirection: 0,
623
+ addressOf: false,
624
+ directDesignator: false,
625
+ callableReference: false,
626
+ anonymousCallable: false,
627
+ expressionKind: 'binding',
628
+ };
629
+ }
630
+ const providerReference = options.extractCallableReference?.(input);
631
+ if (providerReference !== undefined) {
632
+ return {
633
+ name: providerReference.name,
634
+ node: providerReference.anchor,
635
+ indirection: 0,
636
+ addressOf: false,
637
+ ...(providerReference.qualifiedName !== undefined
638
+ ? { qualifiedName: providerReference.qualifiedName }
639
+ : {}),
640
+ directDesignator: true,
641
+ callableReference: true,
642
+ anonymousCallable: false,
643
+ expressionKind: providerReference.qualifiedName === undefined ? 'callable-designator' : 'bound-member',
644
+ };
645
+ }
646
+ let node = input;
647
+ let indirection = 0;
648
+ let addressOf = false;
649
+ for (let guard = 0; guard < 16; guard++) {
650
+ if (options.functionNodeTypes.has(node.type)) {
651
+ return {
652
+ name: '<anonymous>',
653
+ node,
654
+ indirection,
655
+ addressOf,
656
+ directDesignator: true,
657
+ callableReference: true,
658
+ anonymousCallable: true,
659
+ expressionKind: 'anonymous-callable',
660
+ };
661
+ }
662
+ const operator = unaryOperator(node);
663
+ if (operator === '&')
664
+ addressOf = true;
665
+ if (operator === '*')
666
+ indirection++;
667
+ const wrapped = wrappedExpression(node);
668
+ if (wrapped === null)
669
+ break;
670
+ node = wrapped;
671
+ }
672
+ const id = terminalIdentifier(node, options);
673
+ if (id === undefined)
674
+ return undefined;
675
+ const isQualified = id.id !== node.id && hasMultipleIdentifierLeaves(node, options);
676
+ const singleNameText = node.text.trim().replace(/^[\$@]+/, '');
677
+ const valueProducingExpression = /call|invocation|creation|new_expression|composite_literal/.test(node.type);
678
+ return {
679
+ name: id.text,
680
+ node: id,
681
+ indirection,
682
+ addressOf,
683
+ ...(isQualified ? { qualifiedName: node.text } : {}),
684
+ directDesignator: options.identifierNodeTypes.has(node.type) ||
685
+ (!isQualified && singleNameText === id.text) ||
686
+ (isQualified && !valueProducingExpression && !/[([{]/.test(node.text)),
687
+ callableReference: options.callableReferenceNodeTypes?.has(node.type) === true,
688
+ anonymousCallable: false,
689
+ expressionKind: isQualified
690
+ ? 'bound-member'
691
+ : options.callableReferenceNodeTypes?.has(node.type) === true
692
+ ? 'callable-designator'
693
+ : 'binding',
694
+ };
695
+ }
696
+ function asCallableDesignator(operand) {
697
+ if (operand.expressionKind !== 'binding')
698
+ return operand;
699
+ return { ...operand, expressionKind: 'callable-designator' };
700
+ }
701
+ function wrappedExpression(node) {
702
+ const field = node.childForFieldName('argument') ??
703
+ node.childForFieldName('expression') ??
704
+ node.childForFieldName('value');
705
+ if (field !== null && field.id !== node.id && node.namedChildCount === 1)
706
+ return field;
707
+ if (node.type.includes('parenthesized') ||
708
+ node.type.includes('reference_expression') ||
709
+ node.type.includes('pointer_expression') ||
710
+ node.type.includes('unary_expression') ||
711
+ node.type.includes('cast_expression')) {
712
+ return node.namedChild(node.namedChildCount - 1);
713
+ }
714
+ return null;
715
+ }
716
+ function unaryOperator(node) {
717
+ for (const child of node.children) {
718
+ if (child.text === '&' || child.text === '*')
719
+ return child.text;
720
+ }
721
+ const trimmed = node.text.trimStart();
722
+ if (trimmed.startsWith('&'))
723
+ return '&';
724
+ if (trimmed.startsWith('*'))
725
+ return '*';
726
+ return undefined;
727
+ }
728
+ /**
729
+ * For a subscript/index expression, the identifier of interest is always in
730
+ * the container operand, never the index: `tbl[i] = h` must bind the cell
731
+ * `tbl` (index-insensitive, Andersen-style), not the index variable `i` —
732
+ * seeding `i` both pollutes a same-named formal and misses the later
733
+ * `tbl[i]()` join (#2522 review). Field names cover the grammars that field
734
+ * their subscript nodes; others keep the generic traversal.
735
+ */
736
+ function subscriptBase(node) {
737
+ if (node.childForFieldName('index') === null)
738
+ return null;
739
+ return (node.childForFieldName('argument') ?? // C/C++ subscript_expression
740
+ node.childForFieldName('object') ?? // JS/TS subscript_expression
741
+ node.childForFieldName('value') ?? // Python subscript
742
+ node.childForFieldName('operand') ?? // Go index_expression
743
+ node.childForFieldName('array') // Java array_access
744
+ );
745
+ }
746
+ function bindingIdentifier(node, options) {
747
+ if (options.identifierNodeTypes.has(node.type))
748
+ return node;
749
+ const base = subscriptBase(node);
750
+ if (base !== null)
751
+ return bindingIdentifier(base, options);
752
+ for (const fieldName of ['name', 'declarator', 'pattern', 'left']) {
753
+ const field = node.childForFieldName(fieldName);
754
+ if (field === null || field.id === node.id)
755
+ continue;
756
+ const found = bindingIdentifier(field, options);
757
+ if (found !== undefined)
758
+ return found;
759
+ }
760
+ for (const child of node.namedChildren) {
761
+ if (child === null)
762
+ continue;
763
+ const found = bindingIdentifier(child, options);
764
+ if (found !== undefined)
765
+ return found;
766
+ }
767
+ return undefined;
768
+ }
769
+ function terminalIdentifier(node, options) {
770
+ if (options.identifierNodeTypes.has(node.type))
771
+ return node;
772
+ const base = subscriptBase(node);
773
+ if (base !== null)
774
+ return terminalIdentifier(base, options);
775
+ for (const fieldName of ['name', 'property', 'field', 'method', 'declarator']) {
776
+ const field = node.childForFieldName(fieldName);
777
+ if (field === null || field.id === node.id)
778
+ continue;
779
+ const found = terminalIdentifier(field, options);
780
+ if (found !== undefined)
781
+ return found;
782
+ }
783
+ for (let i = node.namedChildCount - 1; i >= 0; i--) {
784
+ const child = node.namedChild(i);
785
+ if (child === null)
786
+ continue;
787
+ const found = terminalIdentifier(child, options);
788
+ if (found !== undefined)
789
+ return found;
790
+ }
791
+ return undefined;
792
+ }
793
+ function hasMultipleIdentifierLeaves(node, options) {
794
+ let count = 0;
795
+ const stack = [node];
796
+ while (stack.length > 0) {
797
+ const current = stack.pop();
798
+ if (options.identifierNodeTypes.has(current.type)) {
799
+ if (++count > 1)
800
+ return true;
801
+ continue;
802
+ }
803
+ for (const child of current.namedChildren)
804
+ if (child !== null)
805
+ stack.push(child);
806
+ }
807
+ return false;
808
+ }
809
+ function findFirstDescendantOfTypes(root, types) {
810
+ const stack = [...root.namedChildren].filter((child) => child !== null);
811
+ while (stack.length > 0) {
812
+ const node = stack.shift();
813
+ if (types.has(node.type))
814
+ return node;
815
+ for (const child of node.namedChildren)
816
+ if (child !== null)
817
+ stack.push(child);
818
+ }
819
+ return null;
820
+ }
821
+ function binaryFact(kind, anchor, leftRole, left, rightRole, right) {
822
+ return {
823
+ [`@callable-flow.${kind}`]: nodeToCapture(`@callable-flow.${kind}`, anchor),
824
+ [`@callable-flow.${leftRole}`]: operandCapture(`@callable-flow.${leftRole}`, left),
825
+ ...operandMetadataCaptures(leftRole, left),
826
+ ...(left.indirection > 0
827
+ ? {
828
+ [`@callable-flow.${leftRole}-indirection`]: syntheticCapture(`@callable-flow.${leftRole}-indirection`, left.node, String(left.indirection)),
829
+ }
830
+ : {}),
831
+ [`@callable-flow.${rightRole}`]: operandCapture(`@callable-flow.${rightRole}`, right),
832
+ ...operandMetadataCaptures(rightRole, right),
833
+ ...(right.indirection > 0
834
+ ? {
835
+ [`@callable-flow.${rightRole}-indirection`]: syntheticCapture(`@callable-flow.${rightRole}-indirection`, right.node, String(right.indirection)),
836
+ }
837
+ : {}),
838
+ };
839
+ }
840
+ function operandCapture(name, operand) {
841
+ return syntheticCapture(name, operand.node, operand.name);
842
+ }
843
+ function operandMetadataCaptures(role, operand) {
844
+ return {
845
+ [`@callable-flow.${role}-kind`]: syntheticCapture(`@callable-flow.${role}-kind`, operand.node, operand.expressionKind),
846
+ ...(operand.qualifiedName !== undefined
847
+ ? {
848
+ [`@callable-flow.${role}-qualified-name`]: syntheticCapture(`@callable-flow.${role}-qualified-name`, operand.node, operand.qualifiedName),
849
+ }
850
+ : {}),
851
+ };
852
+ }
853
+ function addSignatureCaptures(match, anchor, signature) {
854
+ if (signature?.parameterCount !== undefined) {
855
+ match['@callable-flow.expected-arity'] = syntheticCapture('@callable-flow.expected-arity', anchor, String(signature.parameterCount));
856
+ }
857
+ if (signature?.parameterTypes !== undefined) {
858
+ match['@callable-flow.expected-types'] = syntheticCapture('@callable-flow.expected-types', anchor, JSON.stringify(signature.parameterTypes));
859
+ }
860
+ if (signature?.parameterTypeClasses !== undefined) {
861
+ match['@callable-flow.expected-type-classes'] = syntheticCapture('@callable-flow.expected-type-classes', anchor, JSON.stringify(signature.parameterTypeClasses));
862
+ }
863
+ if (signature?.isConst !== undefined) {
864
+ match['@callable-flow.expected-const'] = syntheticCapture('@callable-flow.expected-const', anchor, String(signature.isConst));
865
+ }
866
+ }
867
+ function firstCapture(match) {
868
+ return Object.values(match)[0];
869
+ }
870
+ function compareCaptures(a, b) {
871
+ if (a === undefined)
872
+ return b === undefined ? 0 : 1;
873
+ if (b === undefined)
874
+ return -1;
875
+ return (a.range.startLine - b.range.startLine ||
876
+ a.range.startCol - b.range.startCol ||
877
+ a.name.localeCompare(b.name));
878
+ }