gitnexus 1.6.8-rc.9 → 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 (430) 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 +11 -0
  135. package/dist/core/ingestion/languages/c-cpp.js +6 -1
  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 +3 -0
  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 +23 -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/parse-worker.d.ts +13 -0
  238. package/dist/core/ingestion/workers/parse-worker.js +76 -17
  239. package/dist/core/ingestion/workers/worker-pool.d.ts +9 -40
  240. package/dist/core/ingestion/workers/worker-pool.js +15 -2
  241. package/dist/core/lbug/csv-generator.d.ts +51 -3
  242. package/dist/core/lbug/csv-generator.js +369 -255
  243. package/dist/core/lbug/lbug-adapter.d.ts +58 -18
  244. package/dist/core/lbug/lbug-adapter.js +346 -84
  245. package/dist/core/lbug/lbug-config.d.ts +19 -0
  246. package/dist/core/lbug/lbug-config.js +29 -0
  247. package/dist/core/lbug/pdg-emit-sink.d.ts +127 -0
  248. package/dist/core/lbug/pdg-emit-sink.js +358 -0
  249. package/dist/core/lbug/pool-adapter.d.ts +35 -0
  250. package/dist/core/lbug/pool-adapter.js +90 -1
  251. package/dist/core/lbug/rel-pair-routing.d.ts +54 -0
  252. package/dist/core/lbug/rel-pair-routing.js +140 -0
  253. package/dist/core/lbug/schema.d.ts +2 -2
  254. package/dist/core/lbug/schema.js +3 -0
  255. package/dist/core/logger.d.ts +0 -5
  256. package/dist/core/run-analyze.d.ts +96 -0
  257. package/dist/core/run-analyze.js +207 -3
  258. package/dist/core/tree-sitter/parser-loader.js +5 -4
  259. package/dist/core/tree-sitter/safe-parse.d.ts +0 -5
  260. package/dist/core/tree-sitter/vendored-grammars.d.ts +39 -0
  261. package/dist/core/tree-sitter/vendored-grammars.js +57 -0
  262. package/dist/core/wiki/generator.js +3 -1
  263. package/dist/core/wiki/graph-queries.d.ts +6 -0
  264. package/dist/core/wiki/graph-queries.js +9 -1
  265. package/dist/mcp/http-transport.d.ts +134 -0
  266. package/dist/mcp/http-transport.js +503 -0
  267. package/dist/mcp/local/local-backend.d.ts +110 -24
  268. package/dist/mcp/local/local-backend.js +1225 -19
  269. package/dist/mcp/local/pdg-impact.d.ts +384 -0
  270. package/dist/mcp/local/pdg-impact.js +1972 -0
  271. package/dist/mcp/resources.js +13 -1
  272. package/dist/mcp/tools.d.ts +12 -0
  273. package/dist/mcp/tools.js +214 -7
  274. package/dist/server/analyze-launch.d.ts +29 -0
  275. package/dist/server/analyze-launch.js +137 -0
  276. package/dist/server/analyze-upload.d.ts +33 -0
  277. package/dist/server/analyze-upload.js +123 -0
  278. package/dist/server/analyze-worker.d.ts +17 -1
  279. package/dist/server/api.d.ts +17 -0
  280. package/dist/server/api.js +132 -168
  281. package/dist/server/git-clone.d.ts +43 -2
  282. package/dist/server/git-clone.js +211 -16
  283. package/dist/server/mcp-http.d.ts +5 -6
  284. package/dist/server/mcp-http.js +9 -82
  285. package/dist/server/middleware.d.ts +40 -0
  286. package/dist/server/middleware.js +92 -0
  287. package/dist/server/private-ip.d.ts +1 -0
  288. package/dist/server/private-ip.js +15 -0
  289. package/dist/server/upload-ingest.d.ts +56 -0
  290. package/dist/server/upload-ingest.js +276 -0
  291. package/dist/server/upload-paths.d.ts +37 -0
  292. package/dist/server/upload-paths.js +57 -0
  293. package/dist/server/upload-sweep.d.ts +20 -0
  294. package/dist/server/upload-sweep.js +57 -0
  295. package/dist/storage/git.js +5 -8
  296. package/dist/storage/parse-cache.d.ts +22 -1
  297. package/dist/storage/parse-cache.js +41 -10
  298. package/dist/storage/repo-manager.d.ts +121 -10
  299. package/dist/storage/repo-manager.js +43 -5
  300. package/dist/types/pipeline.d.ts +9 -0
  301. package/hooks/antigravity/gitnexus-antigravity-hook.cjs +110 -10
  302. package/hooks/claude/gitnexus-hook.cjs +110 -13
  303. package/hooks/claude/hook-db-lock-probe.cjs +513 -26
  304. package/package.json +8 -2
  305. package/scripts/assert-publish-grammar-coverage.cjs +31 -0
  306. package/scripts/build-tree-sitter-grammars.cjs +16 -10
  307. package/scripts/cross-platform-tests.ts +1 -0
  308. package/skills/gitnexus-debugging.md +16 -4
  309. package/skills/gitnexus-exploring.md +3 -3
  310. package/skills/gitnexus-guide.md +33 -0
  311. package/skills/gitnexus-pdg-query.md +89 -0
  312. package/skills/gitnexus-refactoring.md +1 -1
  313. package/skills/gitnexus-taint-analysis.md +178 -0
  314. package/vendor/tree-sitter-c/package.json +1 -1
  315. package/vendor/tree-sitter-dart/package.json +1 -1
  316. package/vendor/tree-sitter-kotlin/package.json +1 -1
  317. package/vendor/tree-sitter-proto/package.json +1 -1
  318. package/vendor/tree-sitter-swift/package.json +1 -1
  319. package/web/assets/{agent-CKPMqImC.js → agent-D3Xd7zZE.js} +123 -123
  320. package/web/assets/architecture-7EHR7CIX-6QZW5X65-DxJw65fT.js +1 -0
  321. package/web/assets/architectureDiagram-UL44E2DR-ChH9xW-N.js +36 -0
  322. package/web/assets/{blockDiagram-7IZFK4PR-B4niSLvR.js → blockDiagram-7IZFK4PR-BkWhpzWB.js} +1 -1
  323. package/web/assets/{c4Diagram-Y2BXMSZH-DIzEXalR.js → c4Diagram-Y2BXMSZH-DtBvpzWD.js} +1 -1
  324. package/web/assets/{chunk-3SSMPTDK-BzGeeheI.js → chunk-3SSMPTDK-B4_etUhr.js} +2 -2
  325. package/web/assets/{chunk-5IMINLNL-CnTLsXIV.js → chunk-5IMINLNL-DOdTeQri.js} +1 -1
  326. package/web/assets/{chunk-5VCL7Z4A-w1BCx98Z.js → chunk-5VCL7Z4A-CQ-2dYWj.js} +1 -1
  327. package/web/assets/chunk-6764PJDD-DpIS7hxD.js +1 -0
  328. package/web/assets/{chunk-67TQ5CYL-CChC2cAv.js → chunk-67TQ5CYL-4sNPJU1q.js} +3 -3
  329. package/web/assets/{chunk-7W6UQGC5-CgFyfZ6k.js → chunk-7W6UQGC5-KyEG0HQg.js} +1 -1
  330. package/web/assets/{chunk-AZZRMDJM-5E9ARdDQ.js → chunk-AZZRMDJM-y-xJBuMz.js} +1 -1
  331. package/web/assets/{chunk-INKRHTLW-ELpfuk9h.js → chunk-INKRHTLW-Nu4ri9P-.js} +1 -1
  332. package/web/assets/{chunk-JQRUD6KW-Dcq_Qnyy.js → chunk-JQRUD6KW-Dbva2Z17.js} +1 -1
  333. package/web/assets/{chunk-KGFNY3KK-W-VR57xb.js → chunk-KGFNY3KK-JGMJvKCK.js} +1 -1
  334. package/web/assets/chunk-KGYTTC2M-CWC_c3H9.js +161 -0
  335. package/web/assets/{chunk-KNLZD3CH-BuZBOcso.js → chunk-KNLZD3CH-BGlP6X9R.js} +1 -1
  336. package/web/assets/{chunk-KRXBNO2N-DH2NPM7I.js → chunk-KRXBNO2N-BW5o0KUN.js} +1 -1
  337. package/web/assets/{chunk-LCXTWHL2-Dfmux4m1.js → chunk-LCXTWHL2-zoomRtWX.js} +1 -1
  338. package/web/assets/{chunk-LII3EMHJ-3X33tCpU.js → chunk-LII3EMHJ-D-jm-dLa.js} +1 -1
  339. package/web/assets/{chunk-QA3QBVWF-D5Ha3GgB.js → chunk-QA3QBVWF-BgRW3SXd.js} +1 -1
  340. package/web/assets/{chunk-RG4AUYOV-CAkzcoRj.js → chunk-RG4AUYOV-DD0B2N2B.js} +1 -1
  341. package/web/assets/{chunk-T2UQINTJ-kGYG7ppP.js → chunk-T2UQINTJ-DSBqkzH7.js} +1 -1
  342. package/web/assets/chunk-T5OCTHI4-DdZvN-9i.js +1 -0
  343. package/web/assets/{chunk-UY5QBCOK-Du-c56gs.js → chunk-UY5QBCOK-DyF0vyGd.js} +1 -1
  344. package/web/assets/{chunk-W44A43WB-lrCpuupA.js → chunk-W44A43WB-JqMLIpR0.js} +1 -1
  345. package/web/assets/{chunk-ZXARS5L4-CSZRiyOf.js → chunk-ZXARS5L4-CxN8oiwI.js} +1 -1
  346. package/web/assets/classDiagram-KGZ6W3CR-DJm9BgF-.js +1 -0
  347. package/web/assets/classDiagram-v2-72OJOZXJ-DJm9BgF-.js +1 -0
  348. package/web/assets/{context-builder-_HS0v2ma.js → context-builder-BHiFUA8O.js} +10 -2
  349. package/web/assets/{cose-bilkent-UX7MHV2Q-BHv2bbtl.js → cose-bilkent-UX7MHV2Q-D71wNYRJ.js} +1 -1
  350. package/web/assets/dagre-ND4H6XIP-BIkxmhcu.js +4 -0
  351. package/web/assets/diagram-3NCE3AQN-BTa6iH0T.js +43 -0
  352. package/web/assets/diagram-GF46GFSD-DZDV0vBj.js +24 -0
  353. package/web/assets/{diagram-HNR7UZ2L-fUWreZzx.js → diagram-HNR7UZ2L-DFCfd5LI.js} +2 -2
  354. package/web/assets/diagram-QXG6HAR7-BzM--Jj0.js +24 -0
  355. package/web/assets/diagram-WEQXMOUZ-DFFwz0k4.js +10 -0
  356. package/web/assets/{erDiagram-L5TCEMPS-QN2eEP1e.js → erDiagram-L5TCEMPS-CfHMJJqo.js} +1 -1
  357. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-BQm9QzEa.js +1 -0
  358. package/web/assets/{flowDiagram-H6V6AXG4-CXbXImlN.js → flowDiagram-H6V6AXG4-Be805QiJ.js} +3 -3
  359. package/web/assets/{ganttDiagram-JCBTUEKG-BHQssTz6.js → ganttDiagram-JCBTUEKG-D3iL2Aet.js} +1 -1
  360. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-Cr_Bm2Nb.js +1 -0
  361. package/web/assets/gitGraphDiagram-S2ZK5IYY-CPIDgxGm.js +106 -0
  362. package/web/assets/index-BvYev1UJ.js +635 -0
  363. package/web/assets/index-_lgn7hs5.css +2 -0
  364. package/web/assets/info-J43DQDTF-KCYPFFUO-Cs4p2oyk.js +1 -0
  365. package/web/assets/infoDiagram-3YFTVSEB-Y7BKSoke.js +2 -0
  366. package/web/assets/{ishikawaDiagram-BNXS4ZKH-6LKOvBfp.js → ishikawaDiagram-BNXS4ZKH-CT4SHFuI.js} +1 -1
  367. package/web/assets/{journeyDiagram-M6C3CM3L-DNPYCpvq.js → journeyDiagram-M6C3CM3L-CvArszLo.js} +1 -1
  368. package/web/assets/{kanban-definition-75IXJCU3-DgDi9oJT.js → kanban-definition-75IXJCU3-C6yDxr7N.js} +3 -3
  369. package/web/assets/{katex-K3KEBU37-CrVLz8l7.js → katex-K3KEBU37-CTc5BslQ.js} +1 -1
  370. package/web/assets/{mindmap-definition-2TDM6QVE-CwR5sBB-.js → mindmap-definition-2TDM6QVE-BOc2WEne.js} +1 -1
  371. package/web/assets/packet-YPE3B663-LP52Z2RK-CKCrztD2.js +1 -0
  372. package/web/assets/pie-LRSECV5Y-TCRJHUBD-BB7pHqoD.js +1 -0
  373. package/web/assets/{pieDiagram-CU6KROY3-By8g6f6B.js → pieDiagram-CU6KROY3-Cvc0f_Pd.js} +1 -1
  374. package/web/assets/{quadrantDiagram-VICAPDV7-bAm6Hi_5.js → quadrantDiagram-VICAPDV7-yXSZ2lLz.js} +1 -1
  375. package/web/assets/radar-GUYGQ44K-RDLRG3WG-DhoTOcuK.js +1 -0
  376. package/web/assets/{requirementDiagram-JXO7QTGE-7oDcJ1_J.js → requirementDiagram-JXO7QTGE-BRcZvHs4.js} +1 -1
  377. package/web/assets/{sankeyDiagram-URQDO5SZ-LFJz53u5.js → sankeyDiagram-URQDO5SZ-1qEjlFIB.js} +1 -1
  378. package/web/assets/{sequenceDiagram-VS2MUI6T-FySeKCUy.js → sequenceDiagram-VS2MUI6T-PcSCuvrB.js} +3 -3
  379. package/web/assets/stateDiagram-7D4R322I-D6qYSV1E.js +1 -0
  380. package/web/assets/stateDiagram-v2-36443NZ5-Bg-ImOSX.js +1 -0
  381. package/web/assets/{timeline-definition-O6YCAMPW-Ds2CnVZK.js → timeline-definition-O6YCAMPW-QWkh01xw.js} +1 -1
  382. package/web/assets/treeView-BLDUP644-QA4HXRO3-ODehyGKL.js +1 -0
  383. package/web/assets/treemap-LRROVOQU-LLAWBHMP-BfpgC-7o.js +1 -0
  384. package/web/assets/{vennDiagram-MWXL3ELB-DUIEwXWp.js → vennDiagram-MWXL3ELB-ak4DfwuM.js} +3 -3
  385. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-CNeL6VHE.js +1 -0
  386. package/web/assets/{wardleyDiagram-CUQ6CDDI-DEiFPQih.js → wardleyDiagram-CUQ6CDDI-CTzR4Loq.js} +1 -1
  387. package/web/assets/{xychartDiagram-N2JHSOCM-BUbayhST.js → xychartDiagram-N2JHSOCM-DA1BEaQz.js} +1 -1
  388. package/web/index.html +13 -15
  389. package/scripts/materialize-vendor-grammars.cjs +0 -97
  390. package/web/assets/architecture-7EHR7CIX-6QZW5X65-BETj2x4g.js +0 -1
  391. package/web/assets/architectureDiagram-UL44E2DR-D1EXI0zA.js +0 -36
  392. package/web/assets/chunk-2T2R6R2M-n6s9JZqv.js +0 -4
  393. package/web/assets/chunk-2UTLFMKG-CMBB1TMN.js +0 -1
  394. package/web/assets/chunk-4R4BOZG6-mKhL59ul.js +0 -159
  395. package/web/assets/chunk-6764PJDD-ChwMM2z4.js +0 -1
  396. package/web/assets/chunk-7J6CGLKN-DT-b53FT.js +0 -10
  397. package/web/assets/chunk-C62D2QBJ-CDAWj26E.js +0 -1
  398. package/web/assets/chunk-CEXFNPSA-D68Tk6ls.js +0 -1
  399. package/web/assets/chunk-CilyBKbf.js +0 -1
  400. package/web/assets/chunk-J5EP6P6S-DxWW0yvu.js +0 -1
  401. package/web/assets/chunk-KGYTTC2M-C6PHeuay.js +0 -1
  402. package/web/assets/chunk-RERM46MO-DQNbXtfw.js +0 -1
  403. package/web/assets/chunk-RKZBBQEN-BmTPLSyv.js +0 -1
  404. package/web/assets/chunk-RLI5ZMPA-DExu2DOK.js +0 -1
  405. package/web/assets/chunk-T5OCTHI4--9wWpVws.js +0 -1
  406. package/web/assets/chunk-UP6H54XL-DsKdC6jC.js +0 -1
  407. package/web/assets/chunk-UXSXWOXI-DR81EqLr.js +0 -1
  408. package/web/assets/classDiagram-KGZ6W3CR-Bv93af_b.js +0 -1
  409. package/web/assets/classDiagram-v2-72OJOZXJ-CLfEqHUa.js +0 -1
  410. package/web/assets/dagre-ND4H6XIP-DsIr9MOv.js +0 -4
  411. package/web/assets/diagram-3NCE3AQN-BqAtKUpW.js +0 -43
  412. package/web/assets/diagram-GF46GFSD-CaBG6n6o.js +0 -24
  413. package/web/assets/diagram-QXG6HAR7-CZ-O3rcV.js +0 -24
  414. package/web/assets/diagram-WEQXMOUZ-P4lSL4GH.js +0 -10
  415. package/web/assets/eventmodeling-FCH6USID-MREXMVOE-B3myHUst.js +0 -1
  416. package/web/assets/gitGraph-WXDBUCRP-R675I2BI-DF3rtf4A.js +0 -1
  417. package/web/assets/gitGraphDiagram-S2ZK5IYY-CCwVLT__.js +0 -106
  418. package/web/assets/index-BKWA-m7o.css +0 -2
  419. package/web/assets/index-CG6q8eTs.js +0 -626
  420. package/web/assets/info-J43DQDTF-KCYPFFUO-R4XV_akJ.js +0 -1
  421. package/web/assets/infoDiagram-3YFTVSEB-DmLICZx1.js +0 -2
  422. package/web/assets/packet-YPE3B663-LP52Z2RK-CgQPdNZa.js +0 -1
  423. package/web/assets/pie-LRSECV5Y-TCRJHUBD-BzWOwc_c.js +0 -1
  424. package/web/assets/radar-GUYGQ44K-RDLRG3WG-B7KG0FN7.js +0 -1
  425. package/web/assets/stateDiagram-7D4R322I-CB2nABwH.js +0 -1
  426. package/web/assets/stateDiagram-v2-36443NZ5-COBGd2RL.js +0 -1
  427. package/web/assets/treeView-BLDUP644-QA4HXRO3-CRSxEwLO.js +0 -1
  428. package/web/assets/treemap-LRROVOQU-LLAWBHMP-a0PfKoVn.js +0 -1
  429. package/web/assets/wardley-L42UT6IY-5TKZOOLJ-BKQ6e5mC.js +0 -1
  430. /package/web/assets/{chunk-AQ6EADP3-CCFje6lL.js → chunk-AQ6EADP3-CZhslHi-.js} +0 -0
@@ -26,6 +26,9 @@
26
26
  import type { PipelinePhase } from '../../pipeline-phases/types.js';
27
27
  import { SupportedLanguages } from '../../../../_shared/index.js';
28
28
  import type { ResolutionOutcome } from '../resolution-outcome.js';
29
+ import type { FunctionSummary } from '../../taint/summary-model.js';
30
+ import type { CallSummary } from '../../taint/call-summary-model.js';
31
+ import { type PdgEmitManifest } from '../../../lbug/pdg-emit-sink.js';
29
32
  export interface ScopeResolutionOutput {
30
33
  /** True when at least one language ran. */
31
34
  readonly ran: boolean;
@@ -43,5 +46,26 @@ export interface ScopeResolutionOutput {
43
46
  readonly importsEmitted: number;
44
47
  readonly referenceEdgesEmitted: number;
45
48
  }>;
49
+ /**
50
+ * Per-function taint summaries harvested in the pdg window (#2084 M4 U1),
51
+ * across all languages. Empty unless `--pdg` and a registered taint model.
52
+ * The `taintSummaries` phase composes these over the `CALLS` graph.
53
+ */
54
+ readonly functionSummaries: readonly FunctionSummary[];
55
+ /**
56
+ * Per-function RETURN-VALUE ASCENT summaries harvested in the pdg window
57
+ * (PDG FU-C, U-C2), across all languages. Empty unless `--pdg`. The
58
+ * `callSummaries` phase materialises one `CALL_SUMMARY` self-loop edge per
59
+ * entry once the resolved call graph is known.
60
+ */
61
+ readonly callSummaries: readonly CallSummary[];
62
+ /**
63
+ * Streamed PDG-emit COPY manifest (#2202). Present only when streaming was on
64
+ * (full rebuild + `--pdg` + enabled): the BasicBlock node CSV + per-pair PDG
65
+ * edge CSVs that were flushed to disk during the emit loop, for the persistence
66
+ * step to COPY alongside the structural CSVs. Absent ⇒ the PDG layer (if any)
67
+ * is in the in-memory graph and persists via the normal whole-graph emit.
68
+ */
69
+ readonly pdgEmitManifest?: PdgEmitManifest;
46
70
  }
47
71
  export declare const scopeResolutionPhase: PipelinePhase<ScopeResolutionOutput>;
@@ -33,6 +33,9 @@ import { SCOPE_RESOLVERS } from './registry.js';
33
33
  import { isDev, isSemanticModelValidatorEnabled } from '../../utils/env.js';
34
34
  import { logHeapProbe } from '../../utils/heap-probe.js';
35
35
  import { clearParsedFileStore, loadParsedFilesForPaths, forceGc, } from '../../../../storage/parsedfile-store.js';
36
+ import { buildFunctionNodeIndex } from '../../taint/summary-harvest-driver.js';
37
+ import { PdgEmitSink } from '../../../lbug/pdg-emit-sink.js';
38
+ import { resolveNativeSafeStorageDir } from '../../../lbug/lbug-config.js';
36
39
  import { logger } from '../../../logger.js';
37
40
  const NOOP_OUTPUT = Object.freeze({
38
41
  ran: false,
@@ -41,6 +44,8 @@ const NOOP_OUTPUT = Object.freeze({
41
44
  referenceEdgesEmitted: 0,
42
45
  resolutionOutcomes: [],
43
46
  perLanguage: new Map(),
47
+ functionSummaries: [],
48
+ callSummaries: [],
44
49
  });
45
50
  export const scopeResolutionPhase = {
46
51
  name: 'scopeResolution',
@@ -103,6 +108,12 @@ export const scopeResolutionPhase = {
103
108
  let totalRefs = 0;
104
109
  let anyRan = false;
105
110
  const resolutionOutcomes = [];
111
+ // M4 (#2084 U1): per-function taint summaries accumulated across every
112
+ // language pass; the cross-function fixpoint phase reads this output.
113
+ const functionSummaries = [];
114
+ // FU-C (U-C2): per-function RETURN-VALUE ASCENT summaries accumulated across
115
+ // every language pass; the `callSummaries` emit phase reads this output.
116
+ const callSummaries = [];
106
117
  const perLanguage = new Map();
107
118
  // Pre-count files and languages for progress reporting. This avoids
108
119
  // a frozen progress bar during long scope-resolution runs (#1741).
@@ -167,204 +178,273 @@ export const scopeResolutionPhase = {
167
178
  logHeapProbe('scope-setup-nodeLookup-start', `langs=${totalScopeLangs} files=${totalScopeFiles}`);
168
179
  const sharedNodeLookup = totalScopeFiles > 0 ? buildGraphNodeLookup(ctx.graph) : undefined;
169
180
  logHeapProbe('scope-setup-nodeLookup-end', `langs=${totalScopeLangs}`);
170
- for (const [lang, provider] of SCOPE_RESOLVERS) {
171
- // Standalone providers (COBOL, JCL) don't emit graph edges yet
172
- // through the scope-resolution path. This is the canonical guard:
173
- // runScopeResolution is never called for standalone providers, which
174
- // keeps cobolPhase as the sole IMPORTS edge producer. Keep this guard
175
- // in sync with any additional standalone providers added to
176
- // SCOPE_RESOLVERS.
177
- if (provider.languageProvider.parseStrategy === 'standalone')
178
- continue;
179
- const primaryLangFiles = filesByLang.get(lang) ?? [];
180
- if (primaryLangFiles.length === 0)
181
- continue;
182
- const primaryFilePaths = primaryLangFiles.map((f) => f.path);
183
- // Load per-language import-resolution config (tsconfig paths,
184
- // composer.json autoload, go.mod, ...). One I/O round trip per
185
- // workspace pass cached implicitly by the result handed to
186
- // every `resolveImportTarget` call below.
187
- const resolutionConfig = provider.loadResolutionConfig !== undefined
188
- ? await provider.loadResolutionConfig(ctx.repoPath)
189
- : undefined;
190
- // Some languages (e.g. Vue) expand their file universe beyond the
191
- // primary-language files via the `collectScopeContextPaths` hook.
192
- // The hook receives raw source contents of the primary files so it
193
- // can trace import closures without a second tree-sitter parse.
194
- //
195
- // To avoid reading primary files twice (once for the hook, once for
196
- // the resolution pass), we read them upfront and merge with the
197
- // extra context paths the hook may add.
198
- // Stream this language's pre-built ParsedFiles in from the disk store
199
- // FIRST (huge-repo path). Doing it before reading source lets us skip
200
- // loading content for files the store already covers — for a provider
201
- // with no content-consuming hook that source is pure dead weight once
202
- // extraction is served from the store (~1.5 GB on the kernel's C pass).
203
- // Merged into `preExtractedByPath`; the per-language release block below
204
- // evicts these again before the next language, so only one language's
205
- // ParsedFiles are resident at a time.
206
- const loadStoreFor = async (paths) => {
207
- if (!parsedFileStorePath)
208
- return;
209
- const fromDisk = await loadParsedFilesForPaths(parsedFileStorePath, paths);
210
- for (const [fp, pf] of fromDisk)
211
- preExtractedByPath.set(fp, pf);
212
- };
213
- // A provider that feeds source text into a post-extract hook
214
- // (populateWorkspaceOwners / populateNamespaceSiblings /
215
- // populateRangeBindings / emitPostResolutionEdges) needs content for ALL
216
- // its files; one without those hooks only needs content for files the
217
- // store does NOT cover (fresh-extract fallback). Keep this in sync with
218
- // the getFileContents() call-sites in run.ts.
219
- const providerNeedsAllContent = provider.populateWorkspaceOwners !== undefined ||
220
- provider.populateNamespaceSiblings !== undefined ||
221
- provider.populateRangeBindings !== undefined ||
222
- provider.emitPostResolutionEdges !== undefined;
223
- let scopeFilePaths;
224
- let contents;
225
- if (provider.collectScopeContextPaths !== undefined) {
226
- // Context-expanding providers (e.g. Vue) need every primary file's
227
- // source up front for the closure hook, so load it all.
228
- const entryFileContents = await readFileContents(ctx.repoPath, primaryFilePaths);
229
- scopeFilePaths = provider.collectScopeContextPaths({
230
- primaryFilePaths,
231
- preExtractedByPath,
232
- entryFileContents,
233
- allScannedPaths,
234
- resolutionConfig,
235
- });
236
- // Read only the extra context files (TS/JS etc.) not already loaded.
237
- const extraPaths = [...scopeFilePaths].filter((p) => !entryFileContents.has(p));
238
- const extraContents = await readFileContents(ctx.repoPath, extraPaths);
239
- contents = new Map([...entryFileContents, ...extraContents]);
240
- await loadStoreFor(scopeFilePaths);
181
+ // M4 (#2084 review P2-6): build the functionish-node index ONCE for the
182
+ // taint summary harvest, shared across every language pass (it is a whole-
183
+ // graph scan and language-agnostic). Only when pdg is on off ⇒ undefined,
184
+ // no scan, byte-identical.
185
+ const sharedFnNodeIndex = ctx.options?.pdg === true && totalScopeFiles > 0
186
+ ? buildFunctionNodeIndex(ctx.graph)
187
+ : undefined;
188
+ // Streaming/chunked PDG emit (#2202): when enabled (the caller has already
189
+ // gated this to full-rebuild + `--pdg`), route the BasicBlock + intra-file
190
+ // PDG-edge layer to CSV-on-disk through one sink shared across every
191
+ // language pass, so it never accumulates in `ctx.graph` (peak RSS O(chunk)).
192
+ // Needs the storage dir (the parse-cache store path, the same `.gitnexus`
193
+ // dir loadGraphToLbug COPYs from); if that is somehow absent we skip
194
+ // streaming and fall back to the in-memory whole-graph emit.
195
+ let pdgEmitSink;
196
+ if (ctx.options?.streamPdgEmit === true && totalScopeFiles > 0) {
197
+ if (parsedFileStorePath) {
198
+ pdgEmitSink = new PdgEmitSink(ctx.graph,
199
+ // Same ASCII-safe relocation the structural CSVs get (#2202 review #2):
200
+ // on Windows non-ASCII storage paths the COPY can't open files under
201
+ // the native path, so the dir is relocated to a hashed os.tmpdir().
202
+ resolveNativeSafeStorageDir(parsedFileStorePath, 'pdg-csv'), ctx.options?.pdgEmitChunkSize);
241
203
  }
242
204
  else {
243
- scopeFilePaths = new Set(primaryFilePaths);
244
- await loadStoreFor(scopeFilePaths);
245
- const pathsToRead = providerNeedsAllContent
246
- ? primaryFilePaths
247
- : primaryFilePaths.filter((p) => !preExtractedByPath.has(p));
248
- contents = await readFileContents(ctx.repoPath, pathsToRead);
205
+ logger.warn('[scope-resolution] streaming PDG emit requested but no storage path is ' +
206
+ 'available; falling back to in-memory whole-graph emit');
249
207
  }
250
- const filePaths = [...scopeFilePaths];
251
- const files = [];
252
- for (const fp of filePaths) {
253
- const content = contents.get(fp);
254
- if (content !== undefined) {
255
- files.push({ path: fp, content });
208
+ }
209
+ // Cross-pass per-file dedup set for the streaming sink (#2202): one set
210
+ // shared across every language pass so a file emitted in two passes (e.g. a
211
+ // `.ts` module pulled into the Vue context pass) streams its PDG layer once.
212
+ // Only created when streaming — the in-memory-graph path dedups via its Map.
213
+ const pdgEmittedFiles = pdgEmitSink !== undefined ? new Set() : undefined;
214
+ // Stream the PDG layer with guaranteed writer cleanup: a throw escaping the
215
+ // per-language loop (outside run.ts's per-file try/catch — e.g. from
216
+ // finalize/propagate/a provider hook) must still release the sink's file
217
+ // descriptors. finalize() runs on the success path; the finally closes the
218
+ // sink only when finalize did not (idempotent via the sink's `finalized`).
219
+ let pdgEmitManifest;
220
+ let pdgSinkSettled = false;
221
+ try {
222
+ for (const [lang, provider] of SCOPE_RESOLVERS) {
223
+ // Standalone providers (COBOL, JCL) don't emit graph edges yet
224
+ // through the scope-resolution path. This is the canonical guard:
225
+ // runScopeResolution is never called for standalone providers, which
226
+ // keeps cobolPhase as the sole IMPORTS edge producer. Keep this guard
227
+ // in sync with any additional standalone providers added to
228
+ // SCOPE_RESOLVERS.
229
+ if (provider.languageProvider.parseStrategy === 'standalone')
230
+ continue;
231
+ const primaryLangFiles = filesByLang.get(lang) ?? [];
232
+ if (primaryLangFiles.length === 0)
233
+ continue;
234
+ const primaryFilePaths = primaryLangFiles.map((f) => f.path);
235
+ // Load per-language import-resolution config (tsconfig paths,
236
+ // composer.json autoload, go.mod, ...). One I/O round trip per
237
+ // workspace pass — cached implicitly by the result handed to
238
+ // every `resolveImportTarget` call below.
239
+ const resolutionConfig = provider.loadResolutionConfig !== undefined
240
+ ? await provider.loadResolutionConfig(ctx.repoPath)
241
+ : undefined;
242
+ // Some languages (e.g. Vue) expand their file universe beyond the
243
+ // primary-language files via the `collectScopeContextPaths` hook.
244
+ // The hook receives raw source contents of the primary files so it
245
+ // can trace import closures without a second tree-sitter parse.
246
+ //
247
+ // To avoid reading primary files twice (once for the hook, once for
248
+ // the resolution pass), we read them upfront and merge with the
249
+ // extra context paths the hook may add.
250
+ // Stream this language's pre-built ParsedFiles in from the disk store
251
+ // FIRST (huge-repo path). Doing it before reading source lets us skip
252
+ // loading content for files the store already covers — for a provider
253
+ // with no content-consuming hook that source is pure dead weight once
254
+ // extraction is served from the store (~1.5 GB on the kernel's C pass).
255
+ // Merged into `preExtractedByPath`; the per-language release block below
256
+ // evicts these again before the next language, so only one language's
257
+ // ParsedFiles are resident at a time.
258
+ const loadStoreFor = async (paths) => {
259
+ if (!parsedFileStorePath)
260
+ return;
261
+ const fromDisk = await loadParsedFilesForPaths(parsedFileStorePath, paths);
262
+ for (const [fp, pf] of fromDisk)
263
+ preExtractedByPath.set(fp, pf);
264
+ };
265
+ // A provider that feeds source text into a post-extract hook
266
+ // (populateWorkspaceOwners / populateNamespaceSiblings /
267
+ // populateRangeBindings / emitPostResolutionEdges) needs content for ALL
268
+ // its files; one without those hooks only needs content for files the
269
+ // store does NOT cover (fresh-extract fallback). Keep this in sync with
270
+ // the getFileContents() call-sites in run.ts.
271
+ const providerNeedsAllContent = provider.populateWorkspaceOwners !== undefined ||
272
+ provider.populateNamespaceSiblings !== undefined ||
273
+ provider.populateRangeBindings !== undefined ||
274
+ provider.emitPostResolutionEdges !== undefined;
275
+ let scopeFilePaths;
276
+ let contents;
277
+ if (provider.collectScopeContextPaths !== undefined) {
278
+ // Context-expanding providers (e.g. Vue) need every primary file's
279
+ // source up front for the closure hook, so load it all.
280
+ const entryFileContents = await readFileContents(ctx.repoPath, primaryFilePaths);
281
+ scopeFilePaths = provider.collectScopeContextPaths({
282
+ primaryFilePaths,
283
+ preExtractedByPath,
284
+ entryFileContents,
285
+ allScannedPaths,
286
+ resolutionConfig,
287
+ });
288
+ // Read only the extra context files (TS/JS etc.) not already loaded.
289
+ const extraPaths = [...scopeFilePaths].filter((p) => !entryFileContents.has(p));
290
+ const extraContents = await readFileContents(ctx.repoPath, extraPaths);
291
+ contents = new Map([...entryFileContents, ...extraContents]);
292
+ await loadStoreFor(scopeFilePaths);
256
293
  }
257
- else if (preExtractedByPath.has(fp)) {
258
- // Store covers extraction for this file and we deliberately skipped
259
- // reading its source; the empty string is never consumed (the
260
- // extract loop uses the pre-extracted ParsedFile and this provider
261
- // has no content hook).
262
- files.push({ path: fp, content: '' });
294
+ else {
295
+ scopeFilePaths = new Set(primaryFilePaths);
296
+ await loadStoreFor(scopeFilePaths);
297
+ const pathsToRead = providerNeedsAllContent
298
+ ? primaryFilePaths
299
+ : primaryFilePaths.filter((p) => !preExtractedByPath.has(p));
300
+ contents = await readFileContents(ctx.repoPath, pathsToRead);
263
301
  }
264
- // else: uncovered AND unreadable → skip (unchanged from prior behavior).
265
- }
266
- const langFileCount = files.length;
267
- logHeapProbe('scope-lang-start', `lang=${lang} files=${langFileCount} contentsLoaded=${contents.size}`);
268
- const langLabel = lang.charAt(0).toUpperCase() + lang.slice(1);
269
- currentLangIdx++;
270
- const langTag = totalScopeLangs > 1 ? `${langLabel} [${currentLangIdx}/${totalScopeLangs}]` : langLabel;
271
- if (totalScopeFiles > 0) {
272
- const pct = SCOPE_PCT_START + Math.round((processedScopeFiles / totalScopeFiles) * SCOPE_PCT_RANGE);
273
- ctx.onProgress({
274
- phase: 'scopeResolution',
275
- percent: pct,
276
- message: 'Resolving types',
277
- detail: `${langTag}, ${langFileCount.toLocaleString()} files`,
278
- });
279
- }
280
- const stats = runScopeResolution({
281
- graph: ctx.graph,
282
- model,
283
- files,
284
- resolutionConfig,
285
- prebuiltNodeLookup: sharedNodeLookup,
286
- preExtractedParsedFiles: preExtractedByPath,
287
- scopeIndexStorePath: parsedFileStorePath,
288
- recordResolutionOutcome: (outcome) => {
289
- resolutionOutcomes.push(outcome);
290
- },
291
- onWarn: (msg) => {
292
- if (isSemanticModelValidatorEnabled()) {
293
- logger.warn(`[scope-resolution:${lang}] ${msg}`);
302
+ const filePaths = [...scopeFilePaths];
303
+ const files = [];
304
+ for (const fp of filePaths) {
305
+ const content = contents.get(fp);
306
+ if (content !== undefined) {
307
+ files.push({ path: fp, content });
294
308
  }
295
- },
296
- onProgress: totalScopeFiles > 0
297
- ? (subPhase, current, total) => {
298
- let langRatio;
299
- switch (subPhase) {
300
- case 'extracting':
301
- langRatio = total > 0 ? (current / total) * 0.5 : 0;
302
- break;
303
- case 'analyzing types':
304
- langRatio = 0.5;
305
- break;
306
- case 'resolving references':
307
- langRatio = 0.7;
308
- break;
309
- case 'linking symbols':
310
- langRatio = 0.85;
311
- break;
312
- default: {
313
- const _exhaustive = subPhase;
314
- langRatio = 0.85;
309
+ else if (preExtractedByPath.has(fp)) {
310
+ // Store covers extraction for this file and we deliberately skipped
311
+ // reading its source; the empty string is never consumed (the
312
+ // extract loop uses the pre-extracted ParsedFile and this provider
313
+ // has no content hook).
314
+ files.push({ path: fp, content: '' });
315
+ }
316
+ // else: uncovered AND unreadable → skip (unchanged from prior behavior).
317
+ }
318
+ const langFileCount = files.length;
319
+ logHeapProbe('scope-lang-start', `lang=${lang} files=${langFileCount} contentsLoaded=${contents.size}`);
320
+ const langLabel = lang.charAt(0).toUpperCase() + lang.slice(1);
321
+ currentLangIdx++;
322
+ const langTag = totalScopeLangs > 1 ? `${langLabel} [${currentLangIdx}/${totalScopeLangs}]` : langLabel;
323
+ if (totalScopeFiles > 0) {
324
+ const pct = SCOPE_PCT_START + Math.round((processedScopeFiles / totalScopeFiles) * SCOPE_PCT_RANGE);
325
+ ctx.onProgress({
326
+ phase: 'scopeResolution',
327
+ percent: pct,
328
+ message: 'Resolving types',
329
+ detail: `${langTag}, ${langFileCount.toLocaleString()} files`,
330
+ });
331
+ }
332
+ const stats = runScopeResolution({
333
+ graph: ctx.graph,
334
+ model,
335
+ files,
336
+ resolutionConfig,
337
+ prebuiltNodeLookup: sharedNodeLookup,
338
+ prebuiltFunctionNodeIndex: sharedFnNodeIndex,
339
+ preExtractedParsedFiles: preExtractedByPath,
340
+ scopeIndexStorePath: parsedFileStorePath,
341
+ // CFG/PDG emission (#2081 M1) — opt-in; off ⇒ byte-identical graph.
342
+ pdg: ctx.options?.pdg === true,
343
+ pdgMaxEdgesPerFunction: ctx.options?.pdgMaxEdgesPerFunction,
344
+ pdgMaxReachingDefEdgesPerFunction: ctx.options?.pdgMaxReachingDefEdgesPerFunction,
345
+ pdgMaxCdgEdgesPerFunction: ctx.options?.pdgMaxCdgEdgesPerFunction,
346
+ pdgMaxTaintFindingsPerFunction: ctx.options?.pdgMaxTaintFindingsPerFunction,
347
+ pdgMaxTaintHops: ctx.options?.pdgMaxTaintHops,
348
+ // Streaming PDG-emit sink (#2202) — undefined ⇒ emit to the in-memory graph.
349
+ pdgEmitSink,
350
+ // Cross-pass per-file dedup set (#2202) — undefined when not streaming.
351
+ pdgEmittedFiles,
352
+ recordResolutionOutcome: (outcome) => {
353
+ resolutionOutcomes.push(outcome);
354
+ },
355
+ onWarn: (msg) => {
356
+ if (isSemanticModelValidatorEnabled()) {
357
+ logger.warn(`[scope-resolution:${lang}] ${msg}`);
358
+ }
359
+ },
360
+ onProgress: totalScopeFiles > 0
361
+ ? (subPhase, current, total) => {
362
+ let langRatio;
363
+ switch (subPhase) {
364
+ case 'extracting':
365
+ langRatio = total > 0 ? (current / total) * 0.5 : 0;
366
+ break;
367
+ case 'analyzing types':
368
+ langRatio = 0.5;
369
+ break;
370
+ case 'resolving references':
371
+ langRatio = 0.7;
372
+ break;
373
+ case 'linking symbols':
374
+ langRatio = 0.85;
375
+ break;
376
+ default: {
377
+ const _exhaustive = subPhase;
378
+ langRatio = 0.85;
379
+ }
315
380
  }
381
+ const overallRatio = Math.min(1, (processedScopeFiles + langRatio * langFileCount) / totalScopeFiles);
382
+ const pct = SCOPE_PCT_START + Math.round(overallRatio * SCOPE_PCT_RANGE);
383
+ ctx.onProgress({
384
+ phase: 'scopeResolution',
385
+ percent: pct,
386
+ message: 'Resolving types',
387
+ detail: subPhase === 'extracting'
388
+ ? `${langTag} — extracting ${current.toLocaleString()}/${total.toLocaleString()} files`
389
+ : `${langTag} — ${subPhase}`,
390
+ });
316
391
  }
317
- const overallRatio = Math.min(1, (processedScopeFiles + langRatio * langFileCount) / totalScopeFiles);
318
- const pct = SCOPE_PCT_START + Math.round(overallRatio * SCOPE_PCT_RANGE);
319
- ctx.onProgress({
320
- phase: 'scopeResolution',
321
- percent: pct,
322
- message: 'Resolving types',
323
- detail: subPhase === 'extracting'
324
- ? `${langTag} extracting ${current.toLocaleString()}/${total.toLocaleString()} files`
325
- : `${langTag} ${subPhase}`,
326
- });
327
- }
328
- : undefined,
329
- }, provider);
330
- // Release file contents and pre-extracted entries after each language
331
- // to reduce memory pressure. For large codebases (16K+ PHP files),
332
- // holding all source code simultaneously with scope trees causes OOM.
333
- // See: https://github.com/abhigyanpatwari/GitNexus/issues/1741
334
- //
335
- // Use `filePaths` (not `primaryFilePaths`) so that any context files
336
- // added by `collectScopeContextPaths` (e.g. TS/JS files pulled in for
337
- // Vue cross-file resolution) are also evicted and not held until GC.
338
- files.length = 0;
339
- contents.clear();
340
- for (const fp of filePaths) {
341
- preExtractedByPath.delete(fp);
342
- }
343
- // This language's ParsedFiles are now unreachable (runScopeResolution has
344
- // returned and the Map entries are deleted). Force a GC HERE so a heavy
345
- // language's ~17-20GB set (e.g. C/C++ on the Linux kernel) is reclaimed
346
- // BEFORE the next language's store-load — instead of leaving V8 to collect
347
- // it lazily under the next pass's allocation pressure (which, at a cap >=
348
- // RAM, degrades into swap-thrash). Collects only dead objects: the live
349
- // cross-file index of the next pass is untouched. The pre/post probe
350
- // confirms whether old-space fragmentation defeats the reclaim.
351
- logHeapProbe('lang-release-pre-gc', `lang=${lang}`);
352
- forceGc();
353
- logHeapProbe('lang-release-post-gc', `lang=${lang}`);
354
- logHeapProbe('scope-lang-end', `lang=${lang} filesProcessed=${stats.filesProcessed}`);
355
- processedScopeFiles += langFileCount;
356
- anyRan = true;
357
- totalFiles += stats.filesProcessed;
358
- totalImports += stats.importsEmitted;
359
- totalRefs += stats.referenceEdgesEmitted;
360
- perLanguage.set(lang, {
361
- filesProcessed: stats.filesProcessed,
362
- importsEmitted: stats.importsEmitted,
363
- referenceEdgesEmitted: stats.referenceEdgesEmitted,
364
- });
365
- if (isDev) {
366
- logger.info(`[scope-resolution:${lang}] ${stats.filesProcessed} files → ${stats.importsEmitted} IMPORTS + ${stats.referenceEdgesEmitted} reference edges (${stats.resolve.unresolved} unresolved sites, ${stats.referenceSkipped} skipped)`);
392
+ : undefined,
393
+ }, provider);
394
+ // Release file contents and pre-extracted entries after each language
395
+ // to reduce memory pressure. For large codebases (16K+ PHP files),
396
+ // holding all source code simultaneously with scope trees causes OOM.
397
+ // See: https://github.com/abhigyanpatwari/GitNexus/issues/1741
398
+ //
399
+ // Use `filePaths` (not `primaryFilePaths`) so that any context files
400
+ // added by `collectScopeContextPaths` (e.g. TS/JS files pulled in for
401
+ // Vue cross-file resolution) are also evicted and not held until GC.
402
+ files.length = 0;
403
+ contents.clear();
404
+ for (const fp of filePaths) {
405
+ preExtractedByPath.delete(fp);
406
+ }
407
+ // This language's ParsedFiles are now unreachable (runScopeResolution has
408
+ // returned and the Map entries are deleted). Force a GC HERE so a heavy
409
+ // language's ~17-20GB set (e.g. C/C++ on the Linux kernel) is reclaimed
410
+ // BEFORE the next language's store-load instead of leaving V8 to collect
411
+ // it lazily under the next pass's allocation pressure (which, at a cap >=
412
+ // RAM, degrades into swap-thrash). Collects only dead objects: the live
413
+ // cross-file index of the next pass is untouched. The pre/post probe
414
+ // confirms whether old-space fragmentation defeats the reclaim.
415
+ logHeapProbe('lang-release-pre-gc', `lang=${lang}`);
416
+ forceGc();
417
+ logHeapProbe('lang-release-post-gc', `lang=${lang}`);
418
+ logHeapProbe('scope-lang-end', `lang=${lang} filesProcessed=${stats.filesProcessed}`);
419
+ processedScopeFiles += langFileCount;
420
+ anyRan = true;
421
+ functionSummaries.push(...stats.functionSummaries);
422
+ callSummaries.push(...stats.callSummaries);
423
+ totalFiles += stats.filesProcessed;
424
+ totalImports += stats.importsEmitted;
425
+ totalRefs += stats.referenceEdgesEmitted;
426
+ perLanguage.set(lang, {
427
+ filesProcessed: stats.filesProcessed,
428
+ importsEmitted: stats.importsEmitted,
429
+ referenceEdgesEmitted: stats.referenceEdgesEmitted,
430
+ });
431
+ if (isDev) {
432
+ logger.info(`[scope-resolution:${lang}] ${stats.filesProcessed} files → ${stats.importsEmitted} IMPORTS + ${stats.referenceEdgesEmitted} reference edges (${stats.resolve.unresolved} unresolved sites, ${stats.referenceSkipped} skipped)`);
433
+ }
367
434
  }
435
+ // Finalize the streaming PDG sink (#2202) once after the last language:
436
+ // flush + close its CSV writers and capture the COPY manifest. forceGc at
437
+ // the boundary reclaims transient write buffers (mirrors the per-language
438
+ // release below).
439
+ pdgEmitManifest = pdgEmitSink?.finalize();
440
+ pdgSinkSettled = true;
441
+ if (pdgEmitSink !== undefined)
442
+ forceGc();
443
+ }
444
+ finally {
445
+ // Release fds if a throw skipped finalize (idempotent with finalize()).
446
+ if (pdgEmitSink !== undefined && !pdgSinkSettled)
447
+ pdgEmitSink.close();
368
448
  }
369
449
  if (totalScopeFiles > 0 && anyRan) {
370
450
  ctx.onProgress({
@@ -386,8 +466,11 @@ export const scopeResolutionPhase = {
386
466
  /* best-effort cleanup */
387
467
  }
388
468
  }
469
+ // Even when no language ran, surface a finalized manifest (its CSVs are on
470
+ // disk) so loadGraphToLbug COPYs them rather than orphaning them — empty in
471
+ // the no-files case, harmless.
389
472
  if (!anyRan)
390
- return NOOP_OUTPUT;
473
+ return pdgEmitManifest ? { ...NOOP_OUTPUT, pdgEmitManifest } : NOOP_OUTPUT;
391
474
  return {
392
475
  ran: true,
393
476
  filesProcessed: totalFiles,
@@ -395,6 +478,9 @@ export const scopeResolutionPhase = {
395
478
  referenceEdgesEmitted: totalRefs,
396
479
  resolutionOutcomes,
397
480
  perLanguage,
481
+ functionSummaries,
482
+ callSummaries,
483
+ pdgEmitManifest,
398
484
  };
399
485
  },
400
486
  };
@@ -64,14 +64,39 @@ export function reconcileOwnership(parsedFiles, model) {
64
64
  for (const parsed of parsedFiles) {
65
65
  for (const def of parsed.localDefs) {
66
66
  const ownerId = def.ownerId;
67
- if (ownerId === undefined)
68
- continue;
69
67
  const simple = simpleQualifiedName(def);
70
68
  if (simple === undefined)
71
69
  continue;
72
70
  if (def.type === 'Method' || def.type === 'Function' || def.type === 'Constructor') {
71
+ if (ownerId === undefined) {
72
+ if (def.isDeleted !== true)
73
+ continue;
74
+ const existingDef = model.symbols
75
+ .lookupExactAll(def.filePath, simple)
76
+ .find((candidate) => callableSignatureMatches(candidate, def));
77
+ if (existingDef !== undefined) {
78
+ existingDef.isDeleted = true;
79
+ skippedAlreadyPresent++;
80
+ continue;
81
+ }
82
+ model.symbols.add(def.filePath, simple, def.nodeId, def.type, {
83
+ parameterCount: def.parameterCount,
84
+ requiredParameterCount: def.requiredParameterCount,
85
+ parameterTypes: def.parameterTypes,
86
+ parameterTypeClasses: def.parameterTypeClasses,
87
+ returnType: def.returnType,
88
+ qualifiedName: def.qualifiedName,
89
+ isDeleted: true,
90
+ });
91
+ continue;
92
+ }
73
93
  const existing = model.methods.lookupAllByOwner(ownerId, simple);
74
- if (existing.some((e) => e.nodeId === def.nodeId)) {
94
+ const existingDef = existing.find((candidate) => candidate.nodeId === def.nodeId ||
95
+ (def.isDeleted === true && callableSignatureMatches(candidate, def)));
96
+ if (existingDef !== undefined) {
97
+ if (def.isDeleted === true) {
98
+ existingDef.isDeleted = true;
99
+ }
75
100
  skippedAlreadyPresent++;
76
101
  continue;
77
102
  }
@@ -103,6 +128,21 @@ export function reconcileOwnership(parsedFiles, model) {
103
128
  }
104
129
  return { methodsRegistered, fieldsRegistered, nestedTypesRegistered, skippedAlreadyPresent };
105
130
  }
131
+ function callableSignatureMatches(left, right) {
132
+ if (left.filePath !== right.filePath)
133
+ return false;
134
+ if (left.parameterCount !== right.parameterCount)
135
+ return false;
136
+ if (left.requiredParameterCount !== right.requiredParameterCount)
137
+ return false;
138
+ const leftTypes = left.parameterTypes;
139
+ const rightTypes = right.parameterTypes;
140
+ if (leftTypes === undefined || rightTypes === undefined) {
141
+ return leftTypes === rightTypes;
142
+ }
143
+ return (leftTypes.length === rightTypes.length &&
144
+ leftTypes.every((parameterType, index) => parameterType === rightTypes[index]));
145
+ }
106
146
  /**
107
147
  * Debug-mode parity validator. Runs only when
108
148
  * `VALIDATE_SEMANTIC_MODEL !== '0'` AND `NODE_ENV !== 'production'`.