gitnexus 1.6.8-rc.8 → 1.6.8

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 (439) hide show
  1. package/README.md +3 -3
  2. package/dist/_shared/graph/types.d.ts +31 -1
  3. package/dist/_shared/graph/types.d.ts.map +1 -1
  4. package/dist/_shared/language-detection.d.ts.map +1 -1
  5. package/dist/_shared/language-detection.js +11 -1
  6. package/dist/_shared/language-detection.js.map +1 -1
  7. package/dist/_shared/lbug/schema-constants.d.ts +1 -1
  8. package/dist/_shared/lbug/schema-constants.d.ts.map +1 -1
  9. package/dist/_shared/lbug/schema-constants.js +6 -0
  10. package/dist/_shared/lbug/schema-constants.js.map +1 -1
  11. package/dist/_shared/scope-resolution/parsed-file.d.ts +21 -0
  12. package/dist/_shared/scope-resolution/parsed-file.d.ts.map +1 -1
  13. package/dist/_shared/scope-resolution/symbol-definition.d.ts +6 -0
  14. package/dist/_shared/scope-resolution/symbol-definition.d.ts.map +1 -1
  15. package/dist/cli/ai-context.d.ts +31 -1
  16. package/dist/cli/ai-context.js +18 -16
  17. package/dist/cli/analyze-config.js +11 -0
  18. package/dist/cli/analyze.d.ts +14 -0
  19. package/dist/cli/analyze.js +98 -0
  20. package/dist/cli/embedding-dims.d.ts +33 -0
  21. package/dist/cli/embedding-dims.js +39 -0
  22. package/dist/cli/eval-server.d.ts +8 -0
  23. package/dist/cli/eval-server.js +242 -2
  24. package/dist/cli/help-i18n.js +19 -0
  25. package/dist/cli/i18n/en.d.ts +15 -1
  26. package/dist/cli/i18n/en.js +15 -1
  27. package/dist/cli/i18n/resources.d.ts +29 -1
  28. package/dist/cli/i18n/zh-CN.d.ts +14 -0
  29. package/dist/cli/i18n/zh-CN.js +15 -1
  30. package/dist/cli/index.js +89 -1
  31. package/dist/cli/mcp.d.ts +6 -1
  32. package/dist/cli/mcp.js +26 -1
  33. package/dist/cli/optional-grammars.d.ts +6 -8
  34. package/dist/cli/optional-grammars.js +8 -11
  35. package/dist/cli/setup.d.ts +3 -1
  36. package/dist/cli/setup.js +67 -17
  37. package/dist/cli/skill-gen.js +2 -1
  38. package/dist/cli/tool.d.ts +19 -1
  39. package/dist/cli/tool.js +96 -3
  40. package/dist/core/embeddings/hf-env.d.ts +0 -66
  41. package/dist/core/embeddings/http-client.d.ts +7 -0
  42. package/dist/core/embeddings/http-client.js +5 -3
  43. package/dist/core/embeddings/server-mapping.d.ts +1 -1
  44. package/dist/core/embeddings/server-mapping.js +7 -3
  45. package/dist/core/graph/import-cycles.d.ts +10 -0
  46. package/dist/core/graph/import-cycles.js +103 -0
  47. package/dist/core/group/cross-impact.d.ts +2 -1
  48. package/dist/core/group/cross-impact.js +5 -1
  49. package/dist/core/group/extractors/grpc-patterns/proto.js +10 -6
  50. package/dist/core/group/extractors/http-patterns/kotlin.js +7 -7
  51. package/dist/core/group/extractors/http-route-extractor.d.ts +24 -0
  52. package/dist/core/group/extractors/http-route-extractor.js +22 -4
  53. package/dist/core/group/extractors/include-extractor.js +22 -13
  54. package/dist/core/group/sync.d.ts +27 -1
  55. package/dist/core/group/sync.js +0 -0
  56. package/dist/core/incremental/subgraph-extract.js +18 -1
  57. package/dist/core/ingestion/cfg/cfg-builder.d.ts +114 -0
  58. package/dist/core/ingestion/cfg/cfg-builder.js +196 -0
  59. package/dist/core/ingestion/cfg/collect.d.ts +51 -0
  60. package/dist/core/ingestion/cfg/collect.js +77 -0
  61. package/dist/core/ingestion/cfg/control-dependence.d.ts +58 -0
  62. package/dist/core/ingestion/cfg/control-dependence.js +182 -0
  63. package/dist/core/ingestion/cfg/control-flow-context.d.ts +106 -0
  64. package/dist/core/ingestion/cfg/control-flow-context.js +124 -0
  65. package/dist/core/ingestion/cfg/emit.d.ts +293 -0
  66. package/dist/core/ingestion/cfg/emit.js +646 -0
  67. package/dist/core/ingestion/cfg/post-dominators.d.ts +79 -0
  68. package/dist/core/ingestion/cfg/post-dominators.js +176 -0
  69. package/dist/core/ingestion/cfg/reaching-def-reason-codec.d.ts +106 -0
  70. package/dist/core/ingestion/cfg/reaching-def-reason-codec.js +133 -0
  71. package/dist/core/ingestion/cfg/reaching-defs-graph.d.ts +18 -0
  72. package/dist/core/ingestion/cfg/reaching-defs-graph.js +312 -0
  73. package/dist/core/ingestion/cfg/reaching-defs.d.ts +162 -0
  74. package/dist/core/ingestion/cfg/reaching-defs.js +785 -0
  75. package/dist/core/ingestion/cfg/synthetic-escape.d.ts +124 -0
  76. package/dist/core/ingestion/cfg/synthetic-escape.js +300 -0
  77. package/dist/core/ingestion/cfg/traversal-result.d.ts +20 -0
  78. package/dist/core/ingestion/cfg/traversal-result.js +2 -0
  79. package/dist/core/ingestion/cfg/types.d.ts +274 -0
  80. package/dist/core/ingestion/cfg/types.js +13 -0
  81. package/dist/core/ingestion/cfg/visitors/c-cpp-harvest.d.ts +111 -0
  82. package/dist/core/ingestion/cfg/visitors/c-cpp-harvest.js +541 -0
  83. package/dist/core/ingestion/cfg/visitors/c-cpp.d.ts +74 -0
  84. package/dist/core/ingestion/cfg/visitors/c-cpp.js +584 -0
  85. package/dist/core/ingestion/cfg/visitors/call-site-harvest.d.ts +195 -0
  86. package/dist/core/ingestion/cfg/visitors/call-site-harvest.js +350 -0
  87. package/dist/core/ingestion/cfg/visitors/csharp-harvest.d.ts +124 -0
  88. package/dist/core/ingestion/cfg/visitors/csharp-harvest.js +589 -0
  89. package/dist/core/ingestion/cfg/visitors/csharp.d.ts +87 -0
  90. package/dist/core/ingestion/cfg/visitors/csharp.js +867 -0
  91. package/dist/core/ingestion/cfg/visitors/dart-harvest.d.ts +278 -0
  92. package/dist/core/ingestion/cfg/visitors/dart-harvest.js +870 -0
  93. package/dist/core/ingestion/cfg/visitors/dart.d.ts +119 -0
  94. package/dist/core/ingestion/cfg/visitors/dart.js +836 -0
  95. package/dist/core/ingestion/cfg/visitors/go-harvest.d.ts +160 -0
  96. package/dist/core/ingestion/cfg/visitors/go-harvest.js +621 -0
  97. package/dist/core/ingestion/cfg/visitors/go.d.ts +108 -0
  98. package/dist/core/ingestion/cfg/visitors/go.js +638 -0
  99. package/dist/core/ingestion/cfg/visitors/java-harvest.d.ts +108 -0
  100. package/dist/core/ingestion/cfg/visitors/java-harvest.js +513 -0
  101. package/dist/core/ingestion/cfg/visitors/java.d.ts +101 -0
  102. package/dist/core/ingestion/cfg/visitors/java.js +812 -0
  103. package/dist/core/ingestion/cfg/visitors/kotlin-harvest.d.ts +253 -0
  104. package/dist/core/ingestion/cfg/visitors/kotlin-harvest.js +719 -0
  105. package/dist/core/ingestion/cfg/visitors/kotlin.d.ts +121 -0
  106. package/dist/core/ingestion/cfg/visitors/kotlin.js +809 -0
  107. package/dist/core/ingestion/cfg/visitors/php-harvest.d.ts +172 -0
  108. package/dist/core/ingestion/cfg/visitors/php-harvest.js +626 -0
  109. package/dist/core/ingestion/cfg/visitors/php.d.ts +96 -0
  110. package/dist/core/ingestion/cfg/visitors/php.js +721 -0
  111. package/dist/core/ingestion/cfg/visitors/python-harvest.d.ts +212 -0
  112. package/dist/core/ingestion/cfg/visitors/python-harvest.js +739 -0
  113. package/dist/core/ingestion/cfg/visitors/python.d.ts +103 -0
  114. package/dist/core/ingestion/cfg/visitors/python.js +558 -0
  115. package/dist/core/ingestion/cfg/visitors/ruby-harvest.d.ts +223 -0
  116. package/dist/core/ingestion/cfg/visitors/ruby-harvest.js +587 -0
  117. package/dist/core/ingestion/cfg/visitors/ruby.d.ts +112 -0
  118. package/dist/core/ingestion/cfg/visitors/ruby.js +756 -0
  119. package/dist/core/ingestion/cfg/visitors/rust-harvest.d.ts +324 -0
  120. package/dist/core/ingestion/cfg/visitors/rust-harvest.js +873 -0
  121. package/dist/core/ingestion/cfg/visitors/rust.d.ts +95 -0
  122. package/dist/core/ingestion/cfg/visitors/rust.js +558 -0
  123. package/dist/core/ingestion/cfg/visitors/scope-tree-harvest.d.ts +87 -0
  124. package/dist/core/ingestion/cfg/visitors/scope-tree-harvest.js +116 -0
  125. package/dist/core/ingestion/cfg/visitors/swift-harvest.d.ts +255 -0
  126. package/dist/core/ingestion/cfg/visitors/swift-harvest.js +679 -0
  127. package/dist/core/ingestion/cfg/visitors/swift.d.ts +116 -0
  128. package/dist/core/ingestion/cfg/visitors/swift.js +787 -0
  129. package/dist/core/ingestion/cfg/visitors/typescript-harvest.d.ts +149 -0
  130. package/dist/core/ingestion/cfg/visitors/typescript-harvest.js +1056 -0
  131. package/dist/core/ingestion/cfg/visitors/typescript.d.ts +66 -0
  132. package/dist/core/ingestion/cfg/visitors/typescript.js +583 -0
  133. package/dist/core/ingestion/import-resolvers/utils.js +2 -0
  134. package/dist/core/ingestion/language-provider.d.ts +23 -2
  135. package/dist/core/ingestion/languages/c-cpp.js +17 -5
  136. package/dist/core/ingestion/languages/cobol.js +4 -0
  137. package/dist/core/ingestion/languages/cpp/arity-metadata.js +41 -2
  138. package/dist/core/ingestion/languages/cpp/captures.js +50 -1
  139. package/dist/core/ingestion/languages/cpp/conversion-rank.d.ts +2 -0
  140. package/dist/core/ingestion/languages/cpp/conversion-rank.js +89 -0
  141. package/dist/core/ingestion/languages/cpp/header-scan.d.ts +1 -1
  142. package/dist/core/ingestion/languages/cpp/header-scan.js +2 -2
  143. package/dist/core/ingestion/languages/cpp/inline-namespaces.js +7 -2
  144. package/dist/core/ingestion/languages/cpp/member-lookup.js +2 -1
  145. package/dist/core/ingestion/languages/cpp/query.js +23 -0
  146. package/dist/core/ingestion/languages/cpp/scope-resolver.js +2 -1
  147. package/dist/core/ingestion/languages/csharp.js +2 -0
  148. package/dist/core/ingestion/languages/dart.js +2 -0
  149. package/dist/core/ingestion/languages/go.js +2 -0
  150. package/dist/core/ingestion/languages/java.js +3 -0
  151. package/dist/core/ingestion/languages/kotlin/query.js +3 -2
  152. package/dist/core/ingestion/languages/kotlin.js +8 -1
  153. package/dist/core/ingestion/languages/php.js +2 -0
  154. package/dist/core/ingestion/languages/python.js +2 -0
  155. package/dist/core/ingestion/languages/ruby.js +2 -0
  156. package/dist/core/ingestion/languages/rust.js +2 -0
  157. package/dist/core/ingestion/languages/swift.js +2 -0
  158. package/dist/core/ingestion/languages/typescript.js +5 -0
  159. package/dist/core/ingestion/languages/vue.js +6 -0
  160. package/dist/core/ingestion/method-extractors/configs/c-cpp.js +6 -13
  161. package/dist/core/ingestion/method-extractors/generic.js +1 -0
  162. package/dist/core/ingestion/method-types.d.ts +2 -0
  163. package/dist/core/ingestion/model/symbol-table.d.ts +1 -0
  164. package/dist/core/ingestion/model/symbol-table.js +1 -0
  165. package/dist/core/ingestion/mro-processor.js +109 -0
  166. package/dist/core/ingestion/parsing-processor.js +44 -0
  167. package/dist/core/ingestion/pipeline-phases/call-summaries.d.ts +26 -0
  168. package/dist/core/ingestion/pipeline-phases/call-summaries.js +46 -0
  169. package/dist/core/ingestion/pipeline-phases/index.d.ts +2 -0
  170. package/dist/core/ingestion/pipeline-phases/index.js +2 -0
  171. package/dist/core/ingestion/pipeline-phases/parse-impl.d.ts +0 -21
  172. package/dist/core/ingestion/pipeline-phases/parse-impl.js +18 -1
  173. package/dist/core/ingestion/pipeline-phases/routes.d.ts +10 -0
  174. package/dist/core/ingestion/pipeline-phases/routes.js +30 -1
  175. package/dist/core/ingestion/pipeline-phases/taint-summaries.d.ts +30 -0
  176. package/dist/core/ingestion/pipeline-phases/taint-summaries.js +81 -0
  177. package/dist/core/ingestion/pipeline.d.ts +92 -10
  178. package/dist/core/ingestion/pipeline.js +11 -2
  179. package/dist/core/ingestion/scope-extractor.js +12 -2
  180. package/dist/core/ingestion/scope-resolution/contract/scope-resolver.d.ts +9 -0
  181. package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.d.ts +75 -0
  182. package/dist/core/ingestion/scope-resolution/graph-bridge/callee-id-sink.js +67 -0
  183. package/dist/core/ingestion/scope-resolution/graph-bridge/edges.d.ts +12 -2
  184. package/dist/core/ingestion/scope-resolution/graph-bridge/edges.js +14 -2
  185. package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.d.ts +6 -1
  186. package/dist/core/ingestion/scope-resolution/graph-bridge/references-to-edges.js +13 -1
  187. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.d.ts +9 -1
  188. package/dist/core/ingestion/scope-resolution/passes/free-call-fallback.js +28 -2
  189. package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.d.ts +4 -0
  190. package/dist/core/ingestion/scope-resolution/passes/overload-narrowing.js +9 -0
  191. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.d.ts +6 -1
  192. package/dist/core/ingestion/scope-resolution/passes/receiver-bound-calls.js +174 -40
  193. package/dist/core/ingestion/scope-resolution/pipeline/phase.d.ts +24 -0
  194. package/dist/core/ingestion/scope-resolution/pipeline/phase.js +276 -190
  195. package/dist/core/ingestion/scope-resolution/pipeline/reconcile-ownership.js +43 -3
  196. package/dist/core/ingestion/scope-resolution/pipeline/run.d.ts +75 -0
  197. package/dist/core/ingestion/scope-resolution/pipeline/run.js +349 -1
  198. package/dist/core/ingestion/scope-resolution/resolution-outcome.d.ts +1 -1
  199. package/dist/core/ingestion/taint/call-summary-codec.d.ts +75 -0
  200. package/dist/core/ingestion/taint/call-summary-codec.js +128 -0
  201. package/dist/core/ingestion/taint/call-summary-emit.d.ts +43 -0
  202. package/dist/core/ingestion/taint/call-summary-emit.js +70 -0
  203. package/dist/core/ingestion/taint/call-summary-harvest.d.ts +77 -0
  204. package/dist/core/ingestion/taint/call-summary-harvest.js +179 -0
  205. package/dist/core/ingestion/taint/call-summary-model.d.ts +47 -0
  206. package/dist/core/ingestion/taint/call-summary-model.js +25 -0
  207. package/dist/core/ingestion/taint/emit.d.ts +125 -0
  208. package/dist/core/ingestion/taint/emit.js +208 -0
  209. package/dist/core/ingestion/taint/interproc-emit.d.ts +50 -0
  210. package/dist/core/ingestion/taint/interproc-emit.js +88 -0
  211. package/dist/core/ingestion/taint/interproc-solver.d.ts +110 -0
  212. package/dist/core/ingestion/taint/interproc-solver.js +312 -0
  213. package/dist/core/ingestion/taint/match.d.ts +153 -0
  214. package/dist/core/ingestion/taint/match.js +278 -0
  215. package/dist/core/ingestion/taint/path-codec.d.ts +134 -0
  216. package/dist/core/ingestion/taint/path-codec.js +190 -0
  217. package/dist/core/ingestion/taint/propagate.d.ts +216 -0
  218. package/dist/core/ingestion/taint/propagate.js +659 -0
  219. package/dist/core/ingestion/taint/site-safety.d.ts +29 -0
  220. package/dist/core/ingestion/taint/site-safety.js +98 -0
  221. package/dist/core/ingestion/taint/source-sink-config.d.ts +107 -23
  222. package/dist/core/ingestion/taint/source-sink-config.js +35 -12
  223. package/dist/core/ingestion/taint/source-sink-registry.d.ts +6 -4
  224. package/dist/core/ingestion/taint/source-sink-registry.js +6 -4
  225. package/dist/core/ingestion/taint/summary-harvest-driver.d.ts +80 -0
  226. package/dist/core/ingestion/taint/summary-harvest-driver.js +179 -0
  227. package/dist/core/ingestion/taint/summary-harvest.d.ts +89 -0
  228. package/dist/core/ingestion/taint/summary-harvest.js +537 -0
  229. package/dist/core/ingestion/taint/summary-model.d.ts +200 -0
  230. package/dist/core/ingestion/taint/summary-model.js +86 -0
  231. package/dist/core/ingestion/taint/typescript-model.d.ts +38 -0
  232. package/dist/core/ingestion/taint/typescript-model.js +102 -0
  233. package/dist/core/ingestion/type-extractors/c-cpp.js +21 -0
  234. package/dist/core/ingestion/utils/env.d.ts +7 -0
  235. package/dist/core/ingestion/utils/env.js +12 -0
  236. package/dist/core/ingestion/utils/method-props.js +1 -0
  237. package/dist/core/ingestion/workers/clone-safety.d.ts +109 -0
  238. package/dist/core/ingestion/workers/clone-safety.js +465 -0
  239. package/dist/core/ingestion/workers/parse-worker.d.ts +23 -0
  240. package/dist/core/ingestion/workers/parse-worker.js +81 -53
  241. package/dist/core/ingestion/workers/post-result.d.ts +22 -0
  242. package/dist/core/ingestion/workers/post-result.js +87 -0
  243. package/dist/core/ingestion/workers/result-merge.d.ts +20 -0
  244. package/dist/core/ingestion/workers/result-merge.js +43 -0
  245. package/dist/core/ingestion/workers/worker-pool.d.ts +15 -40
  246. package/dist/core/ingestion/workers/worker-pool.js +43 -16
  247. package/dist/core/lbug/csv-generator.d.ts +51 -3
  248. package/dist/core/lbug/csv-generator.js +369 -255
  249. package/dist/core/lbug/lbug-adapter.d.ts +58 -18
  250. package/dist/core/lbug/lbug-adapter.js +346 -84
  251. package/dist/core/lbug/lbug-config.d.ts +19 -0
  252. package/dist/core/lbug/lbug-config.js +29 -0
  253. package/dist/core/lbug/pdg-emit-sink.d.ts +127 -0
  254. package/dist/core/lbug/pdg-emit-sink.js +358 -0
  255. package/dist/core/lbug/pool-adapter.d.ts +35 -0
  256. package/dist/core/lbug/pool-adapter.js +90 -1
  257. package/dist/core/lbug/rel-pair-routing.d.ts +54 -0
  258. package/dist/core/lbug/rel-pair-routing.js +140 -0
  259. package/dist/core/lbug/schema.d.ts +2 -2
  260. package/dist/core/lbug/schema.js +3 -0
  261. package/dist/core/logger.d.ts +0 -5
  262. package/dist/core/run-analyze.d.ts +96 -0
  263. package/dist/core/run-analyze.js +207 -3
  264. package/dist/core/tree-sitter/parser-loader.js +5 -4
  265. package/dist/core/tree-sitter/safe-parse.d.ts +0 -5
  266. package/dist/core/tree-sitter/vendored-grammars.d.ts +39 -0
  267. package/dist/core/tree-sitter/vendored-grammars.js +57 -0
  268. package/dist/core/wiki/generator.js +3 -1
  269. package/dist/core/wiki/graph-queries.d.ts +6 -0
  270. package/dist/core/wiki/graph-queries.js +9 -1
  271. package/dist/mcp/http-transport.d.ts +134 -0
  272. package/dist/mcp/http-transport.js +503 -0
  273. package/dist/mcp/local/local-backend.d.ts +110 -24
  274. package/dist/mcp/local/local-backend.js +1225 -19
  275. package/dist/mcp/local/pdg-impact.d.ts +384 -0
  276. package/dist/mcp/local/pdg-impact.js +1972 -0
  277. package/dist/mcp/resources.js +13 -1
  278. package/dist/mcp/tools.d.ts +12 -0
  279. package/dist/mcp/tools.js +214 -7
  280. package/dist/server/analyze-launch.d.ts +29 -0
  281. package/dist/server/analyze-launch.js +137 -0
  282. package/dist/server/analyze-upload.d.ts +33 -0
  283. package/dist/server/analyze-upload.js +123 -0
  284. package/dist/server/analyze-worker-ipc.d.ts +58 -0
  285. package/dist/server/analyze-worker-ipc.js +16 -0
  286. package/dist/server/analyze-worker.d.ts +17 -1
  287. package/dist/server/analyze-worker.js +7 -1
  288. package/dist/server/api.d.ts +17 -0
  289. package/dist/server/api.js +132 -168
  290. package/dist/server/git-clone.d.ts +43 -2
  291. package/dist/server/git-clone.js +211 -16
  292. package/dist/server/mcp-http.d.ts +5 -6
  293. package/dist/server/mcp-http.js +9 -82
  294. package/dist/server/middleware.d.ts +40 -0
  295. package/dist/server/middleware.js +92 -0
  296. package/dist/server/private-ip.d.ts +1 -0
  297. package/dist/server/private-ip.js +15 -0
  298. package/dist/server/upload-ingest.d.ts +56 -0
  299. package/dist/server/upload-ingest.js +276 -0
  300. package/dist/server/upload-paths.d.ts +37 -0
  301. package/dist/server/upload-paths.js +57 -0
  302. package/dist/server/upload-sweep.d.ts +20 -0
  303. package/dist/server/upload-sweep.js +57 -0
  304. package/dist/storage/git.js +5 -8
  305. package/dist/storage/parse-cache.d.ts +22 -1
  306. package/dist/storage/parse-cache.js +44 -10
  307. package/dist/storage/repo-manager.d.ts +121 -10
  308. package/dist/storage/repo-manager.js +43 -5
  309. package/dist/types/pipeline.d.ts +9 -0
  310. package/hooks/antigravity/gitnexus-antigravity-hook.cjs +110 -10
  311. package/hooks/claude/gitnexus-hook.cjs +110 -13
  312. package/hooks/claude/hook-db-lock-probe.cjs +513 -26
  313. package/package.json +8 -2
  314. package/scripts/assert-publish-grammar-coverage.cjs +31 -0
  315. package/scripts/build-tree-sitter-grammars.cjs +16 -10
  316. package/scripts/cross-platform-tests.ts +1 -0
  317. package/skills/gitnexus-debugging.md +16 -4
  318. package/skills/gitnexus-exploring.md +3 -3
  319. package/skills/gitnexus-guide.md +33 -0
  320. package/skills/gitnexus-pdg-query.md +89 -0
  321. package/skills/gitnexus-refactoring.md +1 -1
  322. package/skills/gitnexus-taint-analysis.md +178 -0
  323. package/vendor/tree-sitter-c/package.json +1 -1
  324. package/vendor/tree-sitter-dart/package.json +1 -1
  325. package/vendor/tree-sitter-kotlin/package.json +1 -1
  326. package/vendor/tree-sitter-proto/package.json +1 -1
  327. package/vendor/tree-sitter-swift/package.json +1 -1
  328. package/web/assets/{agent-CKPMqImC.js → agent-D3Xd7zZE.js} +123 -123
  329. package/web/assets/architecture-7EHR7CIX-6QZW5X65-DxJw65fT.js +1 -0
  330. package/web/assets/architectureDiagram-UL44E2DR-ChH9xW-N.js +36 -0
  331. package/web/assets/{blockDiagram-7IZFK4PR-B4niSLvR.js → blockDiagram-7IZFK4PR-BkWhpzWB.js} +1 -1
  332. package/web/assets/{c4Diagram-Y2BXMSZH-DIzEXalR.js → c4Diagram-Y2BXMSZH-DtBvpzWD.js} +1 -1
  333. package/web/assets/{chunk-3SSMPTDK-BzGeeheI.js → chunk-3SSMPTDK-B4_etUhr.js} +2 -2
  334. package/web/assets/{chunk-5IMINLNL-CnTLsXIV.js → chunk-5IMINLNL-DOdTeQri.js} +1 -1
  335. package/web/assets/{chunk-5VCL7Z4A-w1BCx98Z.js → chunk-5VCL7Z4A-CQ-2dYWj.js} +1 -1
  336. package/web/assets/chunk-6764PJDD-DpIS7hxD.js +1 -0
  337. package/web/assets/{chunk-67TQ5CYL-CChC2cAv.js → chunk-67TQ5CYL-4sNPJU1q.js} +3 -3
  338. package/web/assets/{chunk-7W6UQGC5-CgFyfZ6k.js → chunk-7W6UQGC5-KyEG0HQg.js} +1 -1
  339. package/web/assets/{chunk-AZZRMDJM-5E9ARdDQ.js → chunk-AZZRMDJM-y-xJBuMz.js} +1 -1
  340. package/web/assets/{chunk-INKRHTLW-ELpfuk9h.js → chunk-INKRHTLW-Nu4ri9P-.js} +1 -1
  341. package/web/assets/{chunk-JQRUD6KW-Dcq_Qnyy.js → chunk-JQRUD6KW-Dbva2Z17.js} +1 -1
  342. package/web/assets/{chunk-KGFNY3KK-W-VR57xb.js → chunk-KGFNY3KK-JGMJvKCK.js} +1 -1
  343. package/web/assets/chunk-KGYTTC2M-CWC_c3H9.js +161 -0
  344. package/web/assets/{chunk-KNLZD3CH-BuZBOcso.js → chunk-KNLZD3CH-BGlP6X9R.js} +1 -1
  345. package/web/assets/{chunk-KRXBNO2N-DH2NPM7I.js → chunk-KRXBNO2N-BW5o0KUN.js} +1 -1
  346. package/web/assets/{chunk-LCXTWHL2-Dfmux4m1.js → chunk-LCXTWHL2-zoomRtWX.js} +1 -1
  347. package/web/assets/{chunk-LII3EMHJ-3X33tCpU.js → chunk-LII3EMHJ-D-jm-dLa.js} +1 -1
  348. package/web/assets/{chunk-QA3QBVWF-D5Ha3GgB.js → chunk-QA3QBVWF-BgRW3SXd.js} +1 -1
  349. package/web/assets/{chunk-RG4AUYOV-CAkzcoRj.js → chunk-RG4AUYOV-DD0B2N2B.js} +1 -1
  350. package/web/assets/{chunk-T2UQINTJ-kGYG7ppP.js → chunk-T2UQINTJ-DSBqkzH7.js} +1 -1
  351. package/web/assets/chunk-T5OCTHI4-DdZvN-9i.js +1 -0
  352. package/web/assets/{chunk-UY5QBCOK-Du-c56gs.js → chunk-UY5QBCOK-DyF0vyGd.js} +1 -1
  353. package/web/assets/{chunk-W44A43WB-lrCpuupA.js → chunk-W44A43WB-JqMLIpR0.js} +1 -1
  354. package/web/assets/{chunk-ZXARS5L4-CSZRiyOf.js → chunk-ZXARS5L4-CxN8oiwI.js} +1 -1
  355. package/web/assets/classDiagram-KGZ6W3CR-DJm9BgF-.js +1 -0
  356. package/web/assets/classDiagram-v2-72OJOZXJ-DJm9BgF-.js +1 -0
  357. package/web/assets/{context-builder-_HS0v2ma.js → context-builder-BHiFUA8O.js} +10 -2
  358. package/web/assets/{cose-bilkent-UX7MHV2Q-BHv2bbtl.js → cose-bilkent-UX7MHV2Q-D71wNYRJ.js} +1 -1
  359. package/web/assets/dagre-ND4H6XIP-BIkxmhcu.js +4 -0
  360. package/web/assets/diagram-3NCE3AQN-BTa6iH0T.js +43 -0
  361. package/web/assets/diagram-GF46GFSD-DZDV0vBj.js +24 -0
  362. package/web/assets/{diagram-HNR7UZ2L-fUWreZzx.js → diagram-HNR7UZ2L-DFCfd5LI.js} +2 -2
  363. package/web/assets/diagram-QXG6HAR7-BzM--Jj0.js +24 -0
  364. package/web/assets/diagram-WEQXMOUZ-DFFwz0k4.js +10 -0
  365. package/web/assets/{erDiagram-L5TCEMPS-QN2eEP1e.js → erDiagram-L5TCEMPS-CfHMJJqo.js} +1 -1
  366. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-BQm9QzEa.js +1 -0
  367. package/web/assets/{flowDiagram-H6V6AXG4-CXbXImlN.js → flowDiagram-H6V6AXG4-Be805QiJ.js} +3 -3
  368. package/web/assets/{ganttDiagram-JCBTUEKG-BHQssTz6.js → ganttDiagram-JCBTUEKG-D3iL2Aet.js} +1 -1
  369. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-Cr_Bm2Nb.js +1 -0
  370. package/web/assets/gitGraphDiagram-S2ZK5IYY-CPIDgxGm.js +106 -0
  371. package/web/assets/index-BvYev1UJ.js +635 -0
  372. package/web/assets/index-_lgn7hs5.css +2 -0
  373. package/web/assets/info-J43DQDTF-KCYPFFUO-Cs4p2oyk.js +1 -0
  374. package/web/assets/infoDiagram-3YFTVSEB-Y7BKSoke.js +2 -0
  375. package/web/assets/{ishikawaDiagram-BNXS4ZKH-6LKOvBfp.js → ishikawaDiagram-BNXS4ZKH-CT4SHFuI.js} +1 -1
  376. package/web/assets/{journeyDiagram-M6C3CM3L-DNPYCpvq.js → journeyDiagram-M6C3CM3L-CvArszLo.js} +1 -1
  377. package/web/assets/{kanban-definition-75IXJCU3-DgDi9oJT.js → kanban-definition-75IXJCU3-C6yDxr7N.js} +3 -3
  378. package/web/assets/{katex-K3KEBU37-CrVLz8l7.js → katex-K3KEBU37-CTc5BslQ.js} +1 -1
  379. package/web/assets/{mindmap-definition-2TDM6QVE-CwR5sBB-.js → mindmap-definition-2TDM6QVE-BOc2WEne.js} +1 -1
  380. package/web/assets/packet-YPE3B663-LP52Z2RK-CKCrztD2.js +1 -0
  381. package/web/assets/pie-LRSECV5Y-TCRJHUBD-BB7pHqoD.js +1 -0
  382. package/web/assets/{pieDiagram-CU6KROY3-By8g6f6B.js → pieDiagram-CU6KROY3-Cvc0f_Pd.js} +1 -1
  383. package/web/assets/{quadrantDiagram-VICAPDV7-bAm6Hi_5.js → quadrantDiagram-VICAPDV7-yXSZ2lLz.js} +1 -1
  384. package/web/assets/radar-GUYGQ44K-RDLRG3WG-DhoTOcuK.js +1 -0
  385. package/web/assets/{requirementDiagram-JXO7QTGE-7oDcJ1_J.js → requirementDiagram-JXO7QTGE-BRcZvHs4.js} +1 -1
  386. package/web/assets/{sankeyDiagram-URQDO5SZ-LFJz53u5.js → sankeyDiagram-URQDO5SZ-1qEjlFIB.js} +1 -1
  387. package/web/assets/{sequenceDiagram-VS2MUI6T-FySeKCUy.js → sequenceDiagram-VS2MUI6T-PcSCuvrB.js} +3 -3
  388. package/web/assets/stateDiagram-7D4R322I-D6qYSV1E.js +1 -0
  389. package/web/assets/stateDiagram-v2-36443NZ5-Bg-ImOSX.js +1 -0
  390. package/web/assets/{timeline-definition-O6YCAMPW-Ds2CnVZK.js → timeline-definition-O6YCAMPW-QWkh01xw.js} +1 -1
  391. package/web/assets/treeView-BLDUP644-QA4HXRO3-ODehyGKL.js +1 -0
  392. package/web/assets/treemap-LRROVOQU-LLAWBHMP-BfpgC-7o.js +1 -0
  393. package/web/assets/{vennDiagram-MWXL3ELB-DUIEwXWp.js → vennDiagram-MWXL3ELB-ak4DfwuM.js} +3 -3
  394. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-CNeL6VHE.js +1 -0
  395. package/web/assets/{wardleyDiagram-CUQ6CDDI-DEiFPQih.js → wardleyDiagram-CUQ6CDDI-CTzR4Loq.js} +1 -1
  396. package/web/assets/{xychartDiagram-N2JHSOCM-BUbayhST.js → xychartDiagram-N2JHSOCM-DA1BEaQz.js} +1 -1
  397. package/web/index.html +13 -15
  398. package/scripts/materialize-vendor-grammars.cjs +0 -97
  399. package/web/assets/architecture-7EHR7CIX-6QZW5X65-BETj2x4g.js +0 -1
  400. package/web/assets/architectureDiagram-UL44E2DR-D1EXI0zA.js +0 -36
  401. package/web/assets/chunk-2T2R6R2M-n6s9JZqv.js +0 -4
  402. package/web/assets/chunk-2UTLFMKG-CMBB1TMN.js +0 -1
  403. package/web/assets/chunk-4R4BOZG6-mKhL59ul.js +0 -159
  404. package/web/assets/chunk-6764PJDD-ChwMM2z4.js +0 -1
  405. package/web/assets/chunk-7J6CGLKN-DT-b53FT.js +0 -10
  406. package/web/assets/chunk-C62D2QBJ-CDAWj26E.js +0 -1
  407. package/web/assets/chunk-CEXFNPSA-D68Tk6ls.js +0 -1
  408. package/web/assets/chunk-CilyBKbf.js +0 -1
  409. package/web/assets/chunk-J5EP6P6S-DxWW0yvu.js +0 -1
  410. package/web/assets/chunk-KGYTTC2M-C6PHeuay.js +0 -1
  411. package/web/assets/chunk-RERM46MO-DQNbXtfw.js +0 -1
  412. package/web/assets/chunk-RKZBBQEN-BmTPLSyv.js +0 -1
  413. package/web/assets/chunk-RLI5ZMPA-DExu2DOK.js +0 -1
  414. package/web/assets/chunk-T5OCTHI4--9wWpVws.js +0 -1
  415. package/web/assets/chunk-UP6H54XL-DsKdC6jC.js +0 -1
  416. package/web/assets/chunk-UXSXWOXI-DR81EqLr.js +0 -1
  417. package/web/assets/classDiagram-KGZ6W3CR-Bv93af_b.js +0 -1
  418. package/web/assets/classDiagram-v2-72OJOZXJ-CLfEqHUa.js +0 -1
  419. package/web/assets/dagre-ND4H6XIP-DsIr9MOv.js +0 -4
  420. package/web/assets/diagram-3NCE3AQN-BqAtKUpW.js +0 -43
  421. package/web/assets/diagram-GF46GFSD-CaBG6n6o.js +0 -24
  422. package/web/assets/diagram-QXG6HAR7-CZ-O3rcV.js +0 -24
  423. package/web/assets/diagram-WEQXMOUZ-P4lSL4GH.js +0 -10
  424. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-B3myHUst.js +0 -1
  425. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DF3rtf4A.js +0 -1
  426. package/web/assets/gitGraphDiagram-S2ZK5IYY-CCwVLT__.js +0 -106
  427. package/web/assets/index-BKWA-m7o.css +0 -2
  428. package/web/assets/index-CG6q8eTs.js +0 -626
  429. package/web/assets/info-J43DQDTF-KCYPFFUO-R4XV_akJ.js +0 -1
  430. package/web/assets/infoDiagram-3YFTVSEB-DmLICZx1.js +0 -2
  431. package/web/assets/packet-YPE3B663-LP52Z2RK-CgQPdNZa.js +0 -1
  432. package/web/assets/pie-LRSECV5Y-TCRJHUBD-BzWOwc_c.js +0 -1
  433. package/web/assets/radar-GUYGQ44K-RDLRG3WG-B7KG0FN7.js +0 -1
  434. package/web/assets/stateDiagram-7D4R322I-CB2nABwH.js +0 -1
  435. package/web/assets/stateDiagram-v2-36443NZ5-COBGd2RL.js +0 -1
  436. package/web/assets/treeView-BLDUP644-QA4HXRO3-CRSxEwLO.js +0 -1
  437. package/web/assets/treemap-LRROVOQU-LLAWBHMP-a0PfKoVn.js +0 -1
  438. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-BKQ6e5mC.js +0 -1
  439. /package/web/assets/{chunk-AQ6EADP3-CCFje6lL.js → chunk-AQ6EADP3-CZhslHi-.js} +0 -0
@@ -1,19 +1,19 @@
1
1
  import * as path from 'node:path';
2
2
  import * as fs from 'node:fs/promises';
3
- import { createRequire } from 'node:module';
4
3
  import { glob } from 'glob';
5
4
  import Parser from 'tree-sitter';
6
5
  import Cpp from 'tree-sitter-cpp';
7
- // `tree-sitter-c` is vendored prebuild-only (#2116) and may be absent on a
8
- // toolchain-less / `--ignore-scripts` install. Load it via a guarded `_require`
9
- // rather than a top-level `import C from 'tree-sitter-c'`, which would throw
10
- // ERR_MODULE_NOT_FOUND at module-load and crash analyze (#2091/#2093). When the
6
+ import { requireVendoredGrammar } from '../../tree-sitter/vendored-grammars.js';
7
+ // `tree-sitter-c` is vendored (#2116), loaded from `vendor/` by absolute path
8
+ // (NEVER copied into node_modules see vendored-grammars.ts / #2111). Load it
9
+ // via a guarded call rather than a top-level `import C from 'tree-sitter-c'`,
10
+ // which would throw ERR_MODULE_NOT_FOUND at module-load and crash analyze
11
+ // (#2091/#2093). It may be absent on a platform without a prebuild; when the
11
12
  // binding is absent, `getLanguageForFile` returns null for `.c`/`.h` so C
12
13
  // include-extraction is skipped (C++ is unaffected — its binding always ships).
13
- const _require = createRequire(import.meta.url);
14
14
  let C = null;
15
15
  try {
16
- C = _require('tree-sitter-c');
16
+ C = requireVendoredGrammar('tree-sitter-c');
17
17
  }
18
18
  catch {
19
19
  /* C grammar unavailable — C include extraction degrades to a no-op. */
@@ -27,7 +27,7 @@ import { logger } from '../../logger.js';
27
27
  /**
28
28
  * Cross-repo C/C++ `#include` dependency extractor.
29
29
  *
30
- * **Provider side:** registers every `.h/.hpp/.hxx/.hh` file in the repo
30
+ * **Provider side:** registers every `.h/.hpp/.hxx/.hh/.cuh` file in the repo
31
31
  * as a provider contract with `include::<relative-path>`.
32
32
  *
33
33
  * **Consumer side:** parses all C/C++ source/header files for `#include "…"`
@@ -40,12 +40,19 @@ import { logger } from '../../logger.js';
40
40
  * exact contract-id equality in `runExactMatch`.
41
41
  */
42
42
  // ---------- constants ----------
43
- const HEADER_EXTENSIONS = new Set(['.h', '.hpp', '.hxx', '.hh']);
44
- // Source = headers (provider-eligible) ∪ implementation files (.c/.cpp/.cc/.cxx).
43
+ const HEADER_EXTENSIONS = new Set(['.h', '.hpp', '.hxx', '.hh', '.cuh']);
44
+ // Source = headers (provider-eligible) ∪ implementation files (.c/.cpp/.cc/.cxx/.cu).
45
45
  // Spread keeps the subset relationship explicit so a future contributor adding
46
46
  // a new header extension to HEADER_EXTENSIONS does not have to remember to
47
47
  // also add it here.
48
- const SOURCE_EXTENSIONS = new Set([...HEADER_EXTENSIONS, '.c', '.cpp', '.cc', '.cxx']);
48
+ const SOURCE_EXTENSIONS = new Set([
49
+ ...HEADER_EXTENSIONS,
50
+ '.c',
51
+ '.cpp',
52
+ '.cc',
53
+ '.cxx',
54
+ '.cu',
55
+ ]);
49
56
  const INCLUDE_QUERY_SRC = '(preproc_include path: (_) @import.source) @import';
50
57
  /**
51
58
  * Well-known C/C++ standard library headers that can appear in `#include "…"`
@@ -259,6 +266,8 @@ function getLanguageForFile(filePath) {
259
266
  case '.hpp':
260
267
  case '.hxx':
261
268
  case '.hh':
269
+ case '.cu':
270
+ case '.cuh':
262
271
  return Cpp;
263
272
  default:
264
273
  return null;
@@ -281,7 +290,7 @@ function getLanguageForFile(filePath) {
281
290
  function isLocalInclude(cleaned, suffixIndex) {
282
291
  const candidates = [cleaned];
283
292
  if (!/\.[a-zA-Z0-9]+$/.test(cleaned)) {
284
- for (const ext of ['.h', '.hpp', '.hxx', '.hh'])
293
+ for (const ext of HEADER_EXTENSIONS)
285
294
  candidates.push(cleaned + ext);
286
295
  }
287
296
  for (const c of candidates) {
@@ -386,7 +395,7 @@ export class IncludeExtractor {
386
395
  async extractProvidersGraph(db, repoPath) {
387
396
  try {
388
397
  const rows = await db(`MATCH (f:File)
389
- WHERE f.filePath =~ '.*\\\\.(h|hpp|hxx|hh)$'
398
+ WHERE f.filePath =~ '.*\\\\.(h|hpp|hxx|hh|cuh)$'
390
399
  RETURN f.filePath AS filePath, f.id AS fileId`);
391
400
  // gitnexus analyze stores absolute paths in the File.filePath column.
392
401
  // Provider contract IDs MUST be repo-relative — otherwise the consumer
@@ -1,5 +1,5 @@
1
1
  import { type RegistryEntry } from '../../storage/repo-manager.js';
2
- import type { GroupConfig, RepoHandle, RepoSnapshot, StoredContract, CrossLink } from './types.js';
2
+ import type { GroupConfig, RepoHandle, RepoSnapshot, StoredContract, CrossLink, GroupManifestLink } from './types.js';
3
3
  export interface SyncOptions {
4
4
  extractorOverride?: ((repo: RepoHandle) => Promise<StoredContract[]>) | (() => Promise<StoredContract[]>);
5
5
  resolveRepoHandle?: (registryName: string, groupPath: string) => Promise<RepoHandle | null>;
@@ -18,4 +18,30 @@ export interface SyncResult {
18
18
  repoSnapshots: Record<string, RepoSnapshot>;
19
19
  }
20
20
  export declare function stableRepoPoolId(entry: RegistryEntry, allEntries: RegistryEntry[]): string;
21
+ /** A batch of manifest links whose referenced in-group repos fit one resident window. */
22
+ export interface ManifestWindow {
23
+ links: GroupManifestLink[];
24
+ /** In-group repos (group paths) this window's links reference; size ≤ maxResident. */
25
+ repos: Set<string>;
26
+ }
27
+ /**
28
+ * Partition manifest links into windows so each window references at most
29
+ * `maxResident` distinct in-group repos. Manifest resolution then materializes
30
+ * only one window's repos at a time, bounding peak pool residency regardless of
31
+ * group size (PR #2191 review, Finding 3 — windowed deferred resolution).
32
+ *
33
+ * Each link references ≤2 in-group repos, so every link fits a window when
34
+ * `maxResident ≥ 2`. Links are pre-sorted by their referenced-repo key so links
35
+ * sharing a repo land in contiguous windows — combined with release-not-close
36
+ * pooling, a hub repo stays warm across the windows that reference it (its
37
+ * lease is released, not closed, so the next window's initLbug fast-paths it).
38
+ * Every link lands in EXACTLY one window (a true partition): downstream
39
+ * dedupeCrossLinks dedupes cross-links but not contracts, so a link in two
40
+ * windows would emit duplicate contracts nothing absorbs.
41
+ *
42
+ * Repos not in `knownRepos` (dangling / unresolved) add 0 to a window's repo
43
+ * budget — the link is still placed (so it yields synthetic-UID contracts), it
44
+ * just consumes no residency.
45
+ */
46
+ export declare function partitionManifestWindows(links: GroupManifestLink[], knownRepos: Set<string>, maxResident: number): ManifestWindow[];
21
47
  export declare function syncGroup(config: GroupConfig, opts?: SyncOptions): Promise<SyncResult>;
Binary file
@@ -49,6 +49,21 @@
49
49
  */
50
50
  import { createKnowledgeGraph } from '../graph/graph.js';
51
51
  const isGraphWide = (label) => label === 'Community' || label === 'Process';
52
+ /**
53
+ * Relationship types whose VALIDITY is a whole-program property, not a
54
+ * function of their endpoints' files (#2084 M4 U6). `TAINT_PATH` (cross-
55
+ * function taint) can be invalidated by a change to an INTERMEDIATE function
56
+ * on a third file, so the endpoint-writability rule below would skip a stale
57
+ * A→C edge. These are always extracted (and the orchestrator delete-alls them
58
+ * first, like Community/Process) so they rebuild from the fresh graph.
59
+ */
60
+ // `CALL_SUMMARY` (PDG FU-C) is intra-procedural (a callee's RETURN-VALUE ASCENT
61
+ // depends only on its OWN body), but the orchestrator delete-alls it on an
62
+ // incremental `--pdg` writeback to keep the emit path single — so it must be
63
+ // re-included from the FULL fresh graph (which the emit phase recomputes every
64
+ // run) or an unchanged function's summary would be lost. Cheap: one self-loop
65
+ // edge per return-flowing function.
66
+ const isGraphWideRelType = (type) => type === 'TAINT_PATH' || type === 'CALL_SUMMARY';
52
67
  /**
53
68
  * Build a Map<nodeId, filePath> for every File-bound node in the graph.
54
69
  * Graph-wide nodes (Community/Process) have no filePath and are filtered.
@@ -74,7 +89,9 @@ export const extractChangedSubgraph = (fullGraph, toWriteSet) => {
74
89
  }
75
90
  });
76
91
  fullGraph.forEachRelationship((r) => {
77
- if (writableNodeIds.has(r.sourceId) || writableNodeIds.has(r.targetId)) {
92
+ if (writableNodeIds.has(r.sourceId) ||
93
+ writableNodeIds.has(r.targetId) ||
94
+ isGraphWideRelType(r.type)) {
78
95
  sub.addRelationship(r);
79
96
  }
80
97
  });
@@ -0,0 +1,114 @@
1
+ /**
2
+ * CfgBuilder (issue #2081, M1) — the language-agnostic accumulator.
3
+ *
4
+ * A per-language `CfgVisitor` drives this: it creates blocks as it walks
5
+ * statements, wires edges (including back-edges and break/continue/return/throw
6
+ * targets resolved via {@link ControlFlowContext}), and calls {@link finish} to
7
+ * produce the serializable {@link FunctionCfg}. The builder owns the synthetic
8
+ * ENTRY (index 0) and EXIT blocks and de-duplicates identical edges so repeated
9
+ * `connect` calls (common when wiring a set of dangling exits) stay idempotent.
10
+ *
11
+ * It has no knowledge of any AST — it is exercised directly in unit tests with
12
+ * hand-built block sequences, which is how the classic CFG hazards are pinned
13
+ * before the tree-sitter visitor (U2) drives it.
14
+ */
15
+ import type { BasicBlockData, BindingEntry, CfgEdgeKind, FunctionCfg, StatementFacts } from './types.js';
16
+ /**
17
+ * Hard ceiling on CFG recursive-descent scope-entry depth (#2195). A language
18
+ * `CfgVisitor` wraps each nested block scope in {@link CfgBuilder.withNesting} (its
19
+ * `visitBody` / `visitSeq` choke points), so the live count tracks scope entries,
20
+ * not statement width. NOTE the count is ~2× LEXICAL nesting for block-bodied
21
+ * constructs (visitBody → visitSeq both enter), so the effective lexical ceiling
22
+ * is ~250 levels for block bodies (~500 for single-statement bodies / bare
23
+ * blocks). Real source nests ≤ ~50 deep, so this fires only on machine-generated
24
+ * / adversarial input. Both effective ceilings sit far below the engine's native
25
+ * stack limit (~1.2k+ nesting even on the raised worker `stackSizeMb`), so the
26
+ * bail is a DETERMINISTIC, language-independent {@link CfgNestingDepthError}
27
+ * rather than a nondeterministic `RangeError` thrown somewhere mid-walk.
28
+ */
29
+ export declare const MAX_CFG_NESTING_DEPTH = 500;
30
+ /**
31
+ * Thrown by the visitor nesting-depth guard ({@link CfgBuilder.enterNesting})
32
+ * when lexical nesting exceeds {@link MAX_CFG_NESTING_DEPTH}. `collectFunctionCfgs`
33
+ * catches it and counts the function under `skipped.tooDeeplyNested`, isolating
34
+ * the bail to one function instead of risking a worker-wide stack overflow.
35
+ */
36
+ export declare class CfgNestingDepthError extends Error {
37
+ readonly limit: number;
38
+ constructor(limit: number);
39
+ }
40
+ export declare class CfgBuilder {
41
+ private readonly filePath;
42
+ private readonly functionStartLine;
43
+ private readonly functionEndLine;
44
+ /** Start column of the owning function — disambiguates same-line functions
45
+ * in the BasicBlock ids (see {@link FunctionCfg.functionStartColumn}).
46
+ * Defaults to 0 for hand-built test CFGs that don't model columns. */
47
+ private readonly functionStartColumn;
48
+ private readonly blocks;
49
+ private readonly edges;
50
+ private readonly edgeKeys;
51
+ /** Live recursive-descent nesting depth — see {@link enterNesting}. */
52
+ private nesting;
53
+ readonly entryIndex: number;
54
+ readonly exitIndex: number;
55
+ constructor(filePath: string, functionStartLine: number, functionEndLine: number,
56
+ /** Start column of the owning function — disambiguates same-line functions
57
+ * in the BasicBlock ids (see {@link FunctionCfg.functionStartColumn}).
58
+ * Defaults to 0 for hand-built test CFGs that don't model columns. */
59
+ functionStartColumn?: number);
60
+ /** Create a block and return its index. */
61
+ newBlock(startLine: number, endLine: number, text: string, kind?: BasicBlockData['kind'], facts?: StatementFacts): number;
62
+ /** Add a single edge (idempotent on from+to+kind). */
63
+ edge(from: number, to: number, kind: CfgEdgeKind): void;
64
+ /** Wire a set of dangling exits to a single target block with one kind. */
65
+ connect(exits: readonly number[], to: number, kind?: CfgEdgeKind): void;
66
+ /** Extend a block's end line as more statements accrue to it. */
67
+ extendBlock(index: number, endLine: number, appendText?: string, facts?: StatementFacts): void;
68
+ /**
69
+ * Attach a facts-only statement record to a block WITHOUT touching its text
70
+ * or line span (#2082 M2 U1) — bench fingerprints and CFG snapshots include
71
+ * block text, so harvesting must never perturb it (ENTRY-block param defs
72
+ * are the canonical use; records that must precede a walked body get their
73
+ * own facts-only block instead, see the catch-param handling in visitTry).
74
+ */
75
+ attachFacts(index: number, facts: StatementFacts): void;
76
+ get blockCount(): number;
77
+ /**
78
+ * Run `fn` inside ONE nested block scope (#2195) — the single choke every
79
+ * visitor's `visitBody` / `visitSeq` funnels through. Enters on the way in and
80
+ * exits in a `finally`, so the live depth is balanced on every return AND every
81
+ * throw and the enter/exit can never drift out of pair (the reason this is one
82
+ * helper, not 24 hand-paired call sites). Throws {@link CfgNestingDepthError}
83
+ * when nesting exceeds {@link MAX_CFG_NESTING_DEPTH} — a proactive, deterministic
84
+ * bail before the native stack can overflow on a pathologically nested function.
85
+ *
86
+ * A block-bodied construct passes through BOTH visitBody and visitSeq, so it
87
+ * costs TWO scopes per lexical level: the effective structural ceiling is
88
+ * ~MAX_CFG_NESTING_DEPTH/2 (~250) lexical levels for block bodies (~500 for
89
+ * single-statement bodies / bare blocks, which hit only one of the two). Still
90
+ * an order of magnitude below the native limit and far above real code (≤ ~50).
91
+ */
92
+ withNesting<T>(fn: () => T): T;
93
+ /**
94
+ * Increment the nesting counter, throwing {@link CfgNestingDepthError} past the
95
+ * cap. Prefer {@link withNesting}, which pairs the exit in a `finally`; this is
96
+ * exposed for direct depth-accounting tests only.
97
+ */
98
+ enterNesting(): void;
99
+ /** Decrement the nesting counter — the partner of {@link enterNesting}. */
100
+ exitNesting(): void;
101
+ /** Produce the serializable CFG. Caller is responsible for having wired the
102
+ * function's dangling exits to {@link exitIndex} before calling.
103
+ *
104
+ * Pass `bindings` (the function's binding table, possibly empty) to emit
105
+ * statement facts (#2082 M2 U1) — every block then carries a `statements`
106
+ * array. Omit it (hand-built test CFGs, pre-M2 producers) and both fields
107
+ * are absent, which the reaching-defs solver reports as `no-facts`. */
108
+ finish(bindings?: readonly BindingEntry[]): FunctionCfg;
109
+ }
110
+ /**
111
+ * Block indices reachable from `entryIndex` by following edges. Backs the
112
+ * reachability property tests (R9) over hand-built and visitor-produced CFGs.
113
+ */
114
+ export declare const reachableBlocks: (cfg: FunctionCfg) => Set<number>;
@@ -0,0 +1,196 @@
1
+ /**
2
+ * Hard ceiling on CFG recursive-descent scope-entry depth (#2195). A language
3
+ * `CfgVisitor` wraps each nested block scope in {@link CfgBuilder.withNesting} (its
4
+ * `visitBody` / `visitSeq` choke points), so the live count tracks scope entries,
5
+ * not statement width. NOTE the count is ~2× LEXICAL nesting for block-bodied
6
+ * constructs (visitBody → visitSeq both enter), so the effective lexical ceiling
7
+ * is ~250 levels for block bodies (~500 for single-statement bodies / bare
8
+ * blocks). Real source nests ≤ ~50 deep, so this fires only on machine-generated
9
+ * / adversarial input. Both effective ceilings sit far below the engine's native
10
+ * stack limit (~1.2k+ nesting even on the raised worker `stackSizeMb`), so the
11
+ * bail is a DETERMINISTIC, language-independent {@link CfgNestingDepthError}
12
+ * rather than a nondeterministic `RangeError` thrown somewhere mid-walk.
13
+ */
14
+ export const MAX_CFG_NESTING_DEPTH = 500;
15
+ /**
16
+ * Thrown by the visitor nesting-depth guard ({@link CfgBuilder.enterNesting})
17
+ * when lexical nesting exceeds {@link MAX_CFG_NESTING_DEPTH}. `collectFunctionCfgs`
18
+ * catches it and counts the function under `skipped.tooDeeplyNested`, isolating
19
+ * the bail to one function instead of risking a worker-wide stack overflow.
20
+ */
21
+ export class CfgNestingDepthError extends Error {
22
+ limit;
23
+ constructor(limit) {
24
+ super(`CFG nesting depth exceeded ${limit}`);
25
+ this.limit = limit;
26
+ this.name = 'CfgNestingDepthError';
27
+ }
28
+ }
29
+ export class CfgBuilder {
30
+ filePath;
31
+ functionStartLine;
32
+ functionEndLine;
33
+ functionStartColumn;
34
+ blocks = [];
35
+ edges = [];
36
+ edgeKeys = new Set();
37
+ /** Live recursive-descent nesting depth — see {@link enterNesting}. */
38
+ nesting = 0;
39
+ entryIndex;
40
+ exitIndex;
41
+ constructor(filePath, functionStartLine, functionEndLine,
42
+ /** Start column of the owning function — disambiguates same-line functions
43
+ * in the BasicBlock ids (see {@link FunctionCfg.functionStartColumn}).
44
+ * Defaults to 0 for hand-built test CFGs that don't model columns. */
45
+ functionStartColumn = 0) {
46
+ this.filePath = filePath;
47
+ this.functionStartLine = functionStartLine;
48
+ this.functionEndLine = functionEndLine;
49
+ this.functionStartColumn = functionStartColumn;
50
+ this.entryIndex = this.newBlock(functionStartLine, functionStartLine, '', 'entry');
51
+ this.exitIndex = this.newBlock(functionEndLine, functionEndLine, '', 'exit');
52
+ }
53
+ /** Create a block and return its index. */
54
+ newBlock(startLine, endLine, text, kind = 'normal', facts) {
55
+ this.blocks.push({
56
+ startLine,
57
+ endLine,
58
+ textParts: text ? [text] : [],
59
+ kind,
60
+ statements: facts ? [facts] : [],
61
+ });
62
+ return this.blocks.length - 1;
63
+ }
64
+ /** Add a single edge (idempotent on from+to+kind). */
65
+ edge(from, to, kind) {
66
+ const key = `${from}->${to}:${kind}`;
67
+ if (this.edgeKeys.has(key))
68
+ return;
69
+ this.edgeKeys.add(key);
70
+ this.edges.push({ from, to, kind });
71
+ }
72
+ /** Wire a set of dangling exits to a single target block with one kind. */
73
+ connect(exits, to, kind = 'seq') {
74
+ for (const from of exits)
75
+ this.edge(from, to, kind);
76
+ }
77
+ /** Extend a block's end line as more statements accrue to it. */
78
+ extendBlock(index, endLine, appendText, facts) {
79
+ const b = this.blocks[index];
80
+ if (!b)
81
+ return;
82
+ if (endLine > b.endLine)
83
+ b.endLine = endLine;
84
+ if (appendText)
85
+ b.textParts.push(appendText);
86
+ if (facts)
87
+ b.statements.push(facts);
88
+ }
89
+ /**
90
+ * Attach a facts-only statement record to a block WITHOUT touching its text
91
+ * or line span (#2082 M2 U1) — bench fingerprints and CFG snapshots include
92
+ * block text, so harvesting must never perturb it (ENTRY-block param defs
93
+ * are the canonical use; records that must precede a walked body get their
94
+ * own facts-only block instead, see the catch-param handling in visitTry).
95
+ */
96
+ attachFacts(index, facts) {
97
+ const b = this.blocks[index];
98
+ if (!b)
99
+ return;
100
+ b.statements.push(facts);
101
+ }
102
+ get blockCount() {
103
+ return this.blocks.length;
104
+ }
105
+ /**
106
+ * Run `fn` inside ONE nested block scope (#2195) — the single choke every
107
+ * visitor's `visitBody` / `visitSeq` funnels through. Enters on the way in and
108
+ * exits in a `finally`, so the live depth is balanced on every return AND every
109
+ * throw and the enter/exit can never drift out of pair (the reason this is one
110
+ * helper, not 24 hand-paired call sites). Throws {@link CfgNestingDepthError}
111
+ * when nesting exceeds {@link MAX_CFG_NESTING_DEPTH} — a proactive, deterministic
112
+ * bail before the native stack can overflow on a pathologically nested function.
113
+ *
114
+ * A block-bodied construct passes through BOTH visitBody and visitSeq, so it
115
+ * costs TWO scopes per lexical level: the effective structural ceiling is
116
+ * ~MAX_CFG_NESTING_DEPTH/2 (~250) lexical levels for block bodies (~500 for
117
+ * single-statement bodies / bare blocks, which hit only one of the two). Still
118
+ * an order of magnitude below the native limit and far above real code (≤ ~50).
119
+ */
120
+ withNesting(fn) {
121
+ this.enterNesting();
122
+ try {
123
+ return fn();
124
+ }
125
+ finally {
126
+ this.exitNesting();
127
+ }
128
+ }
129
+ /**
130
+ * Increment the nesting counter, throwing {@link CfgNestingDepthError} past the
131
+ * cap. Prefer {@link withNesting}, which pairs the exit in a `finally`; this is
132
+ * exposed for direct depth-accounting tests only.
133
+ */
134
+ enterNesting() {
135
+ if (++this.nesting > MAX_CFG_NESTING_DEPTH)
136
+ throw new CfgNestingDepthError(MAX_CFG_NESTING_DEPTH);
137
+ }
138
+ /** Decrement the nesting counter — the partner of {@link enterNesting}. */
139
+ exitNesting() {
140
+ this.nesting--;
141
+ }
142
+ /** Produce the serializable CFG. Caller is responsible for having wired the
143
+ * function's dangling exits to {@link exitIndex} before calling.
144
+ *
145
+ * Pass `bindings` (the function's binding table, possibly empty) to emit
146
+ * statement facts (#2082 M2 U1) — every block then carries a `statements`
147
+ * array. Omit it (hand-built test CFGs, pre-M2 producers) and both fields
148
+ * are absent, which the reaching-defs solver reports as `no-facts`. */
149
+ finish(bindings) {
150
+ const withFacts = bindings !== undefined;
151
+ return {
152
+ filePath: this.filePath,
153
+ functionStartLine: this.functionStartLine,
154
+ functionEndLine: this.functionEndLine,
155
+ functionStartColumn: this.functionStartColumn,
156
+ entryIndex: this.entryIndex,
157
+ exitIndex: this.exitIndex,
158
+ blocks: this.blocks.map((b, index) => ({
159
+ index,
160
+ startLine: b.startLine,
161
+ endLine: b.endLine,
162
+ text: b.textParts.join('\n'),
163
+ kind: b.kind,
164
+ ...(withFacts ? { statements: b.statements } : {}),
165
+ })),
166
+ edges: [...this.edges],
167
+ ...(withFacts ? { bindings } : {}),
168
+ };
169
+ }
170
+ }
171
+ /**
172
+ * Block indices reachable from `entryIndex` by following edges. Backs the
173
+ * reachability property tests (R9) over hand-built and visitor-produced CFGs.
174
+ */
175
+ export const reachableBlocks = (cfg) => {
176
+ const adj = new Map();
177
+ for (const e of cfg.edges) {
178
+ const list = adj.get(e.from);
179
+ if (list)
180
+ list.push(e.to);
181
+ else
182
+ adj.set(e.from, [e.to]);
183
+ }
184
+ const seen = new Set([cfg.entryIndex]);
185
+ const stack = [cfg.entryIndex];
186
+ while (stack.length) {
187
+ const n = stack.pop();
188
+ for (const next of adj.get(n) ?? []) {
189
+ if (!seen.has(next)) {
190
+ seen.add(next);
191
+ stack.push(next);
192
+ }
193
+ }
194
+ }
195
+ return seen;
196
+ };
@@ -0,0 +1,51 @@
1
+ /**
2
+ * collectFunctionCfgs (issue #2081, M1).
3
+ *
4
+ * Walks a parsed file's tree-sitter tree and builds one {@link FunctionCfg} per
5
+ * CFG-bearing function via the language's {@link CfgVisitor}. Runs IN THE PARSE
6
+ * WORKER (where the AST lives — KTD1/KTD7); the result rides on
7
+ * `ParsedFile.cfgSideChannel` across the worker→main boundary.
8
+ *
9
+ * Nested functions are enumerated independently — each gets its own CFG, and
10
+ * appears as an opaque straight-line block in its enclosing function's CFG (the
11
+ * visitor does not descend into nested function bodies). `maxFunctionLines`
12
+ * bounds per-function cost: a function whose source span exceeds the cap is
13
+ * skipped (and counted) rather than walked, so a pathological mega-function
14
+ * cannot blow up worker time/memory. A cap of `0` means no limit.
15
+ */
16
+ import type { SyntaxNode } from '../utils/ast-helpers.js';
17
+ import type { CfgVisitor, FunctionCfg } from './types.js';
18
+ /**
19
+ * Default per-function source-line cap used by the worker when the `--pdg` run
20
+ * does not specify `pdgMaxFunctionLines`. A function longer than this (almost
21
+ * always minified/generated code) is skipped rather than walked — its CFG is
22
+ * both expensive and low-value. Overridable via `PipelineOptions.pdgMaxFunctionLines`.
23
+ */
24
+ export declare const DEFAULT_PDG_MAX_FUNCTION_LINES = 2000;
25
+ /**
26
+ * CFG-bearing functions skipped during the walk, bucketed by reason (#2195).
27
+ * Surfaced per-language in the parse telemetry (parsing-processor.ts) so a CFG
28
+ * coverage gap is observable, not silent. All-zero ⇒ nothing skipped.
29
+ */
30
+ export interface CfgSkipCounts {
31
+ /** Source span exceeded `maxFunctionLines` (minified / generated code). */
32
+ readonly tooManyLines: number;
33
+ /**
34
+ * Recursive-descent nesting hit {@link MAX_CFG_NESTING_DEPTH} — a proactive,
35
+ * deterministic bail (see {@link CfgNestingDepthError}) before a worker stack
36
+ * overflow.
37
+ */
38
+ readonly tooDeeplyNested: number;
39
+ /**
40
+ * `buildFunctionCfg` threw an unexpected error. Caught PER FUNCTION so one
41
+ * malformed function no longer drops the whole file's CFGs (the throw used to
42
+ * escape to the worker's language-group catch).
43
+ */
44
+ readonly buildError: number;
45
+ }
46
+ export interface CollectedCfgs {
47
+ readonly cfgs: readonly FunctionCfg[];
48
+ /** Per-reason skip counts (#2195). */
49
+ readonly skipped: CfgSkipCounts;
50
+ }
51
+ export declare function collectFunctionCfgs(root: SyntaxNode, visitor: CfgVisitor<SyntaxNode>, filePath: string, maxFunctionLines?: number, lineOffset?: number): CollectedCfgs;
@@ -0,0 +1,77 @@
1
+ import { CfgNestingDepthError } from './cfg-builder.js';
2
+ /**
3
+ * Default per-function source-line cap used by the worker when the `--pdg` run
4
+ * does not specify `pdgMaxFunctionLines`. A function longer than this (almost
5
+ * always minified/generated code) is skipped rather than walked — its CFG is
6
+ * both expensive and low-value. Overridable via `PipelineOptions.pdgMaxFunctionLines`.
7
+ */
8
+ export const DEFAULT_PDG_MAX_FUNCTION_LINES = 2000;
9
+ /**
10
+ * Convert a CFG built from an EXTRACTED sub-document's AST (script-relative
11
+ * tree-sitter rows) into the enclosing file's coordinates by adding `offset` to
12
+ * every source-line field. Needed for embedded scripts — a Vue SFC `<script>`
13
+ * block parses at row 0 but lives at `lineOffset` in the `.vue` file, and every
14
+ * other worker-emitted graph node is already file-relative; without this, the
15
+ * CFG's `functionStartLine` would never join its Function/Method graph node
16
+ * (inter-procedural taint silently resolves nothing) and BasicBlock source
17
+ * lines would point at the wrong `.vue` line. A 0 offset returns the input
18
+ * unchanged (the common case: `.ts`/`.js`/etc. parse at the file root), keeping
19
+ * non-embedded languages byte-identical. Synthetic bindings keep `declLine` 0.
20
+ */
21
+ function shiftCfgLines(cfg, offset) {
22
+ if (offset === 0)
23
+ return cfg;
24
+ return {
25
+ ...cfg,
26
+ functionStartLine: cfg.functionStartLine + offset,
27
+ functionEndLine: cfg.functionEndLine + offset,
28
+ blocks: cfg.blocks.map((b) => ({
29
+ ...b,
30
+ startLine: b.startLine + offset,
31
+ endLine: b.endLine + offset,
32
+ statements: b.statements?.map((s) => ({ ...s, line: s.line + offset })),
33
+ })),
34
+ bindings: cfg.bindings?.map((bd) => bd.declLine > 0 ? { ...bd, declLine: bd.declLine + offset } : bd),
35
+ };
36
+ }
37
+ export function collectFunctionCfgs(root, visitor, filePath, maxFunctionLines = 0, lineOffset = 0) {
38
+ const cfgs = [];
39
+ let tooManyLines = 0;
40
+ let tooDeeplyNested = 0;
41
+ let buildError = 0;
42
+ const stack = [root];
43
+ while (stack.length) {
44
+ const node = stack.pop();
45
+ if (visitor.isFunction(node)) {
46
+ const lines = node.endPosition.row - node.startPosition.row + 1;
47
+ if (maxFunctionLines > 0 && lines > maxFunctionLines) {
48
+ tooManyLines++;
49
+ }
50
+ else {
51
+ // Isolate the per-function build: a proactive deep-nesting bail
52
+ // (CfgNestingDepthError) or any other visitor throw is counted and
53
+ // skipped HERE, so it can't escape to the worker's language-group catch
54
+ // and silently drop every remaining function's CFG (#2195).
55
+ try {
56
+ const cfg = visitor.buildFunctionCfg(node, filePath);
57
+ if (cfg)
58
+ cfgs.push(shiftCfgLines(cfg, lineOffset));
59
+ }
60
+ catch (err) {
61
+ if (err instanceof CfgNestingDepthError)
62
+ tooDeeplyNested++;
63
+ else
64
+ buildError++;
65
+ }
66
+ }
67
+ }
68
+ // Descend regardless (a skipped mega-function may still contain small
69
+ // nested functions that are worth a CFG of their own).
70
+ for (let i = node.namedChildCount - 1; i >= 0; i--) {
71
+ const child = node.namedChild(i);
72
+ if (child)
73
+ stack.push(child);
74
+ }
75
+ }
76
+ return { cfgs, skipped: { tooManyLines, tooDeeplyNested, buildError } };
77
+ }
@@ -0,0 +1,58 @@
1
+ /**
2
+ * Control dependence (#2085 M5 U3) — Ferrante, Ottenstein & Warren §3.1.1
3
+ * semantics. A block `dependent` is control-dependent on a branch block
4
+ * `controller` when `controller` decides whether `dependent` executes: formally,
5
+ * there is a CFG edge `controller → B` such that `dependent` post-dominates `B`
6
+ * but does NOT strictly post-dominate `controller`.
7
+ *
8
+ * Construction — the reverse-CFG dominance-frontier formulation (Cytron,
9
+ * Ferrante, Rosen, Wegman & Zadeck 1991): control dependence IS the dominance
10
+ * frontier of the reverse CFG, so `A ∈ PDF(X)` (the post-dominance frontier)
11
+ * ⟺ `X` is control-dependent on `A`. The PDF is computed bottom-up over the
12
+ * post-dom tree (`PDF_local` from a node's CFG predecessors + `PDF_up` from its
13
+ * post-dom-tree children) in O(N + E + output) — each up-step is charged to a
14
+ * distinct emitted edge, NOT re-walked per CFG edge as the original §3.1.1
15
+ * up-walk did (which was Θ(N²) on a deep post-dom chain). The two formulations
16
+ * enumerate the IDENTICAL full `(controller, dependent, label)` set (verified
17
+ * byte-identical on 3203 CFGs + ~1M-case differential fuzz); LLVM, Joern and WALA
18
+ * use the reverse-DF form. (Only the rare TRUNCATED prefix — when a function
19
+ * exceeds `maxEdges` — differs from the old prefix: it is now a sorted
20
+ * deterministic prefix rather than CFG-edge-iteration order. Both are valid,
21
+ * deterministic subsets; the full untruncated output is unchanged.)
22
+ * The branch SENSE ('T' | 'F') of the controlling edge becomes the edge label
23
+ * (KTD4 / KTD3 — it rides the persisted relation's `reason` column).
24
+ *
25
+ * PURE AND DETERMINISTIC (mirrors post-dominators.ts / reaching-defs.ts): no
26
+ * graph, no logger, importable outside the worker; output is deduped per
27
+ * (controller, dependent, label) and sorted, so snapshot tests and
28
+ * content-derived edge ids are stable. The loop header legitimately appears as
29
+ * control-dependent on ITSELF (`controller === dependent`) — the loop predicate
30
+ * gates its own re-execution; this is standard PDG behavior, not a bug.
31
+ */
32
+ import { type PostDomTree } from './post-dominators.js';
33
+ import type { FunctionCfg } from './types.js';
34
+ export type CdgLabel = 'T' | 'F';
35
+ export interface ControlDepEdge {
36
+ /** The branch block whose outcome controls `dependentBlock`. */
37
+ readonly controllerBlock: number;
38
+ /** The block that executes only because `controllerBlock` took `label`. */
39
+ readonly dependentBlock: number;
40
+ /** Branch sense of the controlling CFG edge — see {@link branchSense}. */
41
+ readonly label: CdgLabel;
42
+ }
43
+ export interface ControlDepResult {
44
+ /** Deduped, sorted (controller, dependent, label) control-dependence edges. */
45
+ readonly edges: readonly ControlDepEdge[];
46
+ /**
47
+ * True when the `maxEdges` ceiling was reached; `edges` is then a
48
+ * deterministic prefix (CFG-edge iteration order, sorted), never a silent
49
+ * drop. Mirrors {@link computeReachingDefs}'s `truncated`.
50
+ */
51
+ readonly truncated: boolean;
52
+ }
53
+ /**
54
+ * Compute control-dependence edges for one function's CFG. `postDom` may be
55
+ * supplied to reuse an already-built tree; otherwise it is computed. See the
56
+ * module doc for the purity/determinism contract.
57
+ */
58
+ export declare function computeControlDependence(cfg: FunctionCfg, postDom?: PostDomTree, maxEdges?: number): ControlDepResult;