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
@@ -0,0 +1,195 @@
1
+ /**
2
+ * Shared call-site taint substrate for the C-family CFG harvesters (#2195 U6,
3
+ * plan R7 / KTD2) — the language-agnostic mechanism the C/C++, C#, Java and Go
4
+ * harvesters layer their grammar-specific call/member walks on top of.
5
+ *
6
+ * This file is PURE MECHANISM: it contains no tree-sitter node-type or field
7
+ * literals (each harvester supplies those when it drives `openCallSite` /
8
+ * `addMemberRead` / `setFrameArg`), so it names no language and carries nothing
9
+ * the grammar-literal CI gate needs to validate. It is the C-family analogue of
10
+ * the `FactAccumulator` site machinery in
11
+ * {@link import('./typescript-harvest.js')} — extracted into one place because
12
+ * the four C-family harvesters already share an identical def/use accumulator,
13
+ * and the site layer is identical across them too (only the per-grammar node
14
+ * shapes differ, and those live in each harvester's `walkValue`/`visitCall`).
15
+ *
16
+ * Produces the same {@link SiteRecord} shape the (future, deferred) shared
17
+ * taint matcher consumes uniformly across all languages: callee path, receiver,
18
+ * per-argument occurrence entries (with sanitizer-interposition via-tags),
19
+ * result defs, spread/template markers, and member reads. INERT BY DESIGN — no
20
+ * C-family source/sink/sanitizer model is registered today (`getSourceSinkConfig`
21
+ * returns undefined for every C-family language), so a harvest with no model
22
+ * produces ZERO TAINTED edges; this only emits the substrate the deferred model
23
+ * work will match against.
24
+ *
25
+ * Sites are emitted on {@link StatementFacts.sites} only when non-empty, exactly
26
+ * like the TS harvester — flag-off runs never harvest, and most fact-bearing
27
+ * statements carry no calls.
28
+ *
29
+ * NOTE: nothing serialized here may carry a field named `nodeId` — the durable
30
+ * parsedfile-store reviver dedups objects keyed on that field name.
31
+ */
32
+ import type { SyntaxNode } from '../../utils/ast-helpers.js';
33
+ import type { StatementFacts } from '../types.js';
34
+ /**
35
+ * Minimal ordered, deduplicating def/use collector for one statement record,
36
+ * with NO call-site machinery (#2195 U7). The Kotlin / Python / Ruby / Rust /
37
+ * Dart / Swift harvesters each carried a BYTE-IDENTICAL copy of this class:
38
+ * those units harvest NO call sites (the taint substrate is a later step), so a
39
+ * site-free accumulator keeps their emitted facts free of any `sites` key
40
+ * (matching the Python harvester) and byte-identical to one another. This is the
41
+ * no-site sibling of {@link CallSiteFactAccumulator}; `finish` omits `sites`
42
+ * entirely. `useCount` is live (Ruby's emit guard is `defCount() ||
43
+ * useCount()`).
44
+ */
45
+ export declare class DefUseAccumulator {
46
+ private readonly line;
47
+ private readonly defs;
48
+ private readonly uses;
49
+ private readonly mayDefs;
50
+ private readonly defSeen;
51
+ private readonly useSeen;
52
+ private readonly mayDefSeen;
53
+ constructor(line: number);
54
+ addDef(idx: number): void;
55
+ /** A def that may not execute (conditional context) — gen without kill. */
56
+ addMayDef(idx: number): void;
57
+ addUse(idx: number): void;
58
+ defCount(): number;
59
+ useCount(): number;
60
+ finish(): StatementFacts;
61
+ }
62
+ /**
63
+ * Defensive per-statement cap on harvested taint `sites` (#2195 U11). A real
64
+ * statement carries a handful of call / member-read sites; this only bounds a
65
+ * pathological or machine-generated statement (e.g. hundreds of nested calls)
66
+ * from producing an unbounded site list. Mirrors the PDG edge/fact caps' style
67
+ * (a generous-but-finite limit, checked before each push). Overflow is silent
68
+ * but observable via {@link CallSiteFactAccumulator.sitesTruncated}; the first
69
+ * `DEFAULT_PDG_MAX_SITES_PER_STATEMENT` sites are kept fully intact (callee,
70
+ * args, parent), the over-cap tail is dropped.
71
+ */
72
+ export declare const DEFAULT_PDG_MAX_SITES_PER_STATEMENT = 512;
73
+ /**
74
+ * Ordered, deduplicating def/use collector for one statement record, PLUS the
75
+ * call-site harvest machinery (#2195 U6). A drop-in superset of the simple
76
+ * def/use accumulator the C-family harvesters used before the substrate landed
77
+ * — `addDef`/`addMayDef`/`addUse`/`defCount`/`useCount`/`finish` are unchanged,
78
+ * so harvesters that never open a site emit byte-identical facts (no `sites`
79
+ * key, since `finish` omits it when empty).
80
+ */
81
+ export declare class CallSiteFactAccumulator {
82
+ private readonly line;
83
+ private readonly defs;
84
+ private readonly uses;
85
+ private readonly mayDefs;
86
+ private readonly defSeen;
87
+ private readonly useSeen;
88
+ private readonly mayDefSeen;
89
+ /** Taint sites recorded for this statement. */
90
+ private readonly sites;
91
+ /** Composite (object|property|parent) keys of recorded member-read sites — O(1) dedup. */
92
+ private readonly memberReadKeys;
93
+ /** Stack of open call/new sites — the occurrence fan-out targets. */
94
+ private readonly frames;
95
+ /** Set once the per-statement site cap is hit; over-cap sites are dropped. */
96
+ private _sitesTruncated;
97
+ constructor(line: number);
98
+ /** True iff this statement hit {@link DEFAULT_PDG_MAX_SITES_PER_STATEMENT}. */
99
+ get sitesTruncated(): boolean;
100
+ addDef(idx: number): void;
101
+ /** A def that may not execute (conditional context) — gen without kill. */
102
+ addMayDef(idx: number): void;
103
+ addUse(idx: number): void;
104
+ /**
105
+ * Statement-level use that is NOT a value occurrence in any open site
106
+ * argument — bare callee names only (see each harvester's `visitCall`).
107
+ */
108
+ addUseWithoutOccurrence(idx: number): void;
109
+ defCount(): number;
110
+ useCount(): number;
111
+ /** `[defs.length, mayDefs.length]` marker for {@link defsSince}. */
112
+ defSnapshot(): readonly [number, number];
113
+ /** Binding indices def'd (must- OR may-) since the snapshot was taken. */
114
+ defsSince(snap: readonly [number, number]): number[];
115
+ /**
116
+ * Open a call/new site; parent = innermost enclosing argument position.
117
+ * Returns the new site index, or -1 when the per-statement site cap is hit
118
+ * (the caller threads -1 through `pushFrame`/`setSite*`, all of which no-op on
119
+ * a sentinel index — see {@link DEFAULT_PDG_MAX_SITES_PER_STATEMENT}).
120
+ *
121
+ * `at` is the call/new node's anchor position `[line (1-based), col (0-based)]`
122
+ * — the SAME position the CALLS-edge resolution keys on (see
123
+ * {@link SiteRecord.at} for the KTD7 alignment); the harvester passes its
124
+ * `visitCall`/`visitNew` node's `startPosition` so the downstream resolved-id
125
+ * join lands by exact position.
126
+ */
127
+ openCallSite(kind: 'call' | 'new', at?: readonly [number, number]): number;
128
+ pushFrame(siteIdx: number): void;
129
+ popFrame(): void;
130
+ /** Set the argument position the top frame is currently walking. */
131
+ setFrameArg(argIdx: number): void;
132
+ /**
133
+ * Run `fn` with all open arg frames temporarily detached (argIdx = -1), so
134
+ * identifier reads inside still record USES but do NOT fan occurrences into
135
+ * the enclosing sink-argument position (e.g. the non-value operands of a
136
+ * comma expression — only the final operand's value flows).
137
+ */
138
+ suppressOccurrences(fn: () => void): void;
139
+ setSiteCallee(siteIdx: number, callee: string): void;
140
+ setSiteReceiver(siteIdx: number, receiver: number): void;
141
+ setSiteResultDefs(siteIdx: number, resultDefs: readonly number[]): void;
142
+ setSiteSpread(siteIdx: number, firstSpreadArg: number): void;
143
+ /**
144
+ * Record a value-position member read. Exact duplicates within the statement
145
+ * (same object/property/parent position) dedup; reads at DIFFERENT argument
146
+ * positions stay distinct (`exec(req.body, req.body)` is two occurrences).
147
+ */
148
+ addMemberRead(object: number, property: string): void;
149
+ private innermostArgPosition;
150
+ /**
151
+ * Fan a binding occurrence out to every arg-active open frame, via-tagged
152
+ * with the site of the IMMEDIATELY nested frame when one exists:
153
+ * `exec(escape(x))` puts a plain `x` in escape's arg 0 and `[x, escapeIdx]`
154
+ * in exec's arg 0 — the sanitizer-interposition substrate.
155
+ */
156
+ private recordOccurrence;
157
+ private pushArgEntry;
158
+ finish(): StatementFacts;
159
+ }
160
+ /**
161
+ * Per-grammar hooks the shared {@link finalizeChain} terminal needs but cannot
162
+ * name itself (it carries no tree-sitter literals — see the file header). Each
163
+ * harvester supplies the two callbacks bound to its own `this`.
164
+ */
165
+ export interface ChainTerminalHooks {
166
+ /** Resolve a binding-target node to its function-table binding index. */
167
+ resolve(node: SyntaxNode): number;
168
+ /**
169
+ * Walk a NON-identifier chain root for its uses + nested sites (the terminal's
170
+ * `else` branch — `self.x.f()`, `foo().bar`, a tuple index, etc.).
171
+ */
172
+ walkRoot(node: SyntaxNode): void;
173
+ }
174
+ /**
175
+ * Shared `walkChain` TERMINAL (#2227 follow-up, plan KTD5/U8) — the byte-identical
176
+ * post-unwind block the Go / Kotlin / Swift / Rust / Python harvesters all ran
177
+ * after walking their grammar-specific access chain (`selector_expression` /
178
+ * `navigation_expression` / `field_expression` / `attribute`) into an
179
+ * `accesses: string[]` list and a resolved root node `cur`.
180
+ *
181
+ * It records the chain-root identifier as a use, emits at most ONE member-read
182
+ * site — the INNERMOST access — when the root is an identifier (suppressed by
183
+ * `skipFinalRead` when that access IS the callee, carried by the dotted path
184
+ * instead), and builds the dotted path `[root, ...accesses].join('.')`. The only
185
+ * per-grammar bit is the root identifier node type, supplied via `isRootIdType`
186
+ * (`'identifier'` for Go/Rust/Python, `'simple_identifier'` for Kotlin/Swift);
187
+ * the `resolve` / `walkRoot` callbacks bind the harvester's own methods. The
188
+ * `addUse` / `addMemberRead` machinery is on the accumulator itself, so it is
189
+ * called directly (no callback). Behavior is identical to the inlined terminals
190
+ * this replaces — the per-language harvest tests are the characterization lock.
191
+ */
192
+ export declare function finalizeChain(acc: CallSiteFactAccumulator, cur: SyntaxNode, accesses: readonly string[], skipFinalRead: boolean, isRootIdType: (type: string) => boolean, hooks: ChainTerminalHooks): {
193
+ path?: string;
194
+ rootIdx?: number;
195
+ };
@@ -0,0 +1,350 @@
1
+ /**
2
+ * Minimal ordered, deduplicating def/use collector for one statement record,
3
+ * with NO call-site machinery (#2195 U7). The Kotlin / Python / Ruby / Rust /
4
+ * Dart / Swift harvesters each carried a BYTE-IDENTICAL copy of this class:
5
+ * those units harvest NO call sites (the taint substrate is a later step), so a
6
+ * site-free accumulator keeps their emitted facts free of any `sites` key
7
+ * (matching the Python harvester) and byte-identical to one another. This is the
8
+ * no-site sibling of {@link CallSiteFactAccumulator}; `finish` omits `sites`
9
+ * entirely. `useCount` is live (Ruby's emit guard is `defCount() ||
10
+ * useCount()`).
11
+ */
12
+ export class DefUseAccumulator {
13
+ line;
14
+ defs = [];
15
+ uses = [];
16
+ mayDefs = [];
17
+ defSeen = new Set();
18
+ useSeen = new Set();
19
+ mayDefSeen = new Set();
20
+ constructor(line) {
21
+ this.line = line;
22
+ }
23
+ addDef(idx) {
24
+ if (this.defSeen.has(idx))
25
+ return;
26
+ this.defSeen.add(idx);
27
+ this.defs.push(idx);
28
+ }
29
+ /** A def that may not execute (conditional context) — gen without kill. */
30
+ addMayDef(idx) {
31
+ if (this.mayDefSeen.has(idx))
32
+ return;
33
+ this.mayDefSeen.add(idx);
34
+ this.mayDefs.push(idx);
35
+ }
36
+ addUse(idx) {
37
+ if (this.useSeen.has(idx))
38
+ return;
39
+ this.useSeen.add(idx);
40
+ this.uses.push(idx);
41
+ }
42
+ defCount() {
43
+ return this.defs.length + this.mayDefs.length;
44
+ }
45
+ useCount() {
46
+ return this.uses.length;
47
+ }
48
+ finish() {
49
+ return {
50
+ line: this.line,
51
+ defs: this.defs,
52
+ uses: this.uses,
53
+ // Stay absent when empty — keeps the serialized side-channel payload lean.
54
+ ...(this.mayDefs.length > 0 ? { mayDefs: this.mayDefs } : {}),
55
+ };
56
+ }
57
+ }
58
+ /**
59
+ * Defensive per-statement cap on harvested taint `sites` (#2195 U11). A real
60
+ * statement carries a handful of call / member-read sites; this only bounds a
61
+ * pathological or machine-generated statement (e.g. hundreds of nested calls)
62
+ * from producing an unbounded site list. Mirrors the PDG edge/fact caps' style
63
+ * (a generous-but-finite limit, checked before each push). Overflow is silent
64
+ * but observable via {@link CallSiteFactAccumulator.sitesTruncated}; the first
65
+ * `DEFAULT_PDG_MAX_SITES_PER_STATEMENT` sites are kept fully intact (callee,
66
+ * args, parent), the over-cap tail is dropped.
67
+ */
68
+ export const DEFAULT_PDG_MAX_SITES_PER_STATEMENT = 512;
69
+ /**
70
+ * Ordered, deduplicating def/use collector for one statement record, PLUS the
71
+ * call-site harvest machinery (#2195 U6). A drop-in superset of the simple
72
+ * def/use accumulator the C-family harvesters used before the substrate landed
73
+ * — `addDef`/`addMayDef`/`addUse`/`defCount`/`useCount`/`finish` are unchanged,
74
+ * so harvesters that never open a site emit byte-identical facts (no `sites`
75
+ * key, since `finish` omits it when empty).
76
+ */
77
+ export class CallSiteFactAccumulator {
78
+ line;
79
+ defs = [];
80
+ uses = [];
81
+ mayDefs = [];
82
+ defSeen = new Set();
83
+ useSeen = new Set();
84
+ mayDefSeen = new Set();
85
+ /** Taint sites recorded for this statement. */
86
+ sites = [];
87
+ /** Composite (object|property|parent) keys of recorded member-read sites — O(1) dedup. */
88
+ memberReadKeys = new Set();
89
+ /** Stack of open call/new sites — the occurrence fan-out targets. */
90
+ frames = [];
91
+ /** Set once the per-statement site cap is hit; over-cap sites are dropped. */
92
+ _sitesTruncated = false;
93
+ constructor(line) {
94
+ this.line = line;
95
+ }
96
+ /** True iff this statement hit {@link DEFAULT_PDG_MAX_SITES_PER_STATEMENT}. */
97
+ get sitesTruncated() {
98
+ return this._sitesTruncated;
99
+ }
100
+ addDef(idx) {
101
+ if (this.defSeen.has(idx))
102
+ return;
103
+ this.defSeen.add(idx);
104
+ this.defs.push(idx);
105
+ }
106
+ /** A def that may not execute (conditional context) — gen without kill. */
107
+ addMayDef(idx) {
108
+ if (this.mayDefSeen.has(idx))
109
+ return;
110
+ this.mayDefSeen.add(idx);
111
+ this.mayDefs.push(idx);
112
+ }
113
+ addUse(idx) {
114
+ // Occurrence fan-out happens BEFORE the statement-level dedup: `exec(x, x)`
115
+ // records x at BOTH arg positions even though `uses` lists it once.
116
+ this.recordOccurrence(idx);
117
+ this.addUseWithoutOccurrence(idx);
118
+ }
119
+ /**
120
+ * Statement-level use that is NOT a value occurrence in any open site
121
+ * argument — bare callee names only (see each harvester's `visitCall`).
122
+ */
123
+ addUseWithoutOccurrence(idx) {
124
+ if (this.useSeen.has(idx))
125
+ return;
126
+ this.useSeen.add(idx);
127
+ this.uses.push(idx);
128
+ }
129
+ defCount() {
130
+ return this.defs.length + this.mayDefs.length;
131
+ }
132
+ useCount() {
133
+ return this.uses.length;
134
+ }
135
+ // ── site machinery (#2195 U6, mirrors the TS harvester) ──────────────────
136
+ /** `[defs.length, mayDefs.length]` marker for {@link defsSince}. */
137
+ defSnapshot() {
138
+ return [this.defs.length, this.mayDefs.length];
139
+ }
140
+ /** Binding indices def'd (must- OR may-) since the snapshot was taken. */
141
+ defsSince(snap) {
142
+ return [...this.defs.slice(snap[0]), ...this.mayDefs.slice(snap[1])];
143
+ }
144
+ /**
145
+ * Open a call/new site; parent = innermost enclosing argument position.
146
+ * Returns the new site index, or -1 when the per-statement site cap is hit
147
+ * (the caller threads -1 through `pushFrame`/`setSite*`, all of which no-op on
148
+ * a sentinel index — see {@link DEFAULT_PDG_MAX_SITES_PER_STATEMENT}).
149
+ *
150
+ * `at` is the call/new node's anchor position `[line (1-based), col (0-based)]`
151
+ * — the SAME position the CALLS-edge resolution keys on (see
152
+ * {@link SiteRecord.at} for the KTD7 alignment); the harvester passes its
153
+ * `visitCall`/`visitNew` node's `startPosition` so the downstream resolved-id
154
+ * join lands by exact position.
155
+ */
156
+ openCallSite(kind, at) {
157
+ if (this.sites.length >= DEFAULT_PDG_MAX_SITES_PER_STATEMENT) {
158
+ this._sitesTruncated = true;
159
+ return -1;
160
+ }
161
+ const site = { kind };
162
+ const parent = this.innermostArgPosition();
163
+ if (parent)
164
+ site.parent = parent;
165
+ if (at)
166
+ site.at = [at[0], at[1]];
167
+ this.sites.push(site);
168
+ return this.sites.length - 1;
169
+ }
170
+ pushFrame(siteIdx) {
171
+ this.frames.push({ siteIdx, argIdx: -1 });
172
+ }
173
+ popFrame() {
174
+ this.frames.pop();
175
+ }
176
+ /** Set the argument position the top frame is currently walking. */
177
+ setFrameArg(argIdx) {
178
+ const top = this.frames[this.frames.length - 1];
179
+ if (top)
180
+ top.argIdx = argIdx;
181
+ }
182
+ /**
183
+ * Run `fn` with all open arg frames temporarily detached (argIdx = -1), so
184
+ * identifier reads inside still record USES but do NOT fan occurrences into
185
+ * the enclosing sink-argument position (e.g. the non-value operands of a
186
+ * comma expression — only the final operand's value flows).
187
+ */
188
+ suppressOccurrences(fn) {
189
+ const saved = this.frames.map((f) => f.argIdx);
190
+ for (const f of this.frames)
191
+ f.argIdx = -1;
192
+ try {
193
+ fn();
194
+ }
195
+ finally {
196
+ this.frames.forEach((f, i) => {
197
+ f.argIdx = saved[i];
198
+ });
199
+ }
200
+ }
201
+ setSiteCallee(siteIdx, callee) {
202
+ const site = this.sites[siteIdx];
203
+ if (site)
204
+ site.callee = callee;
205
+ }
206
+ setSiteReceiver(siteIdx, receiver) {
207
+ const site = this.sites[siteIdx];
208
+ if (site)
209
+ site.receiver = receiver;
210
+ }
211
+ setSiteResultDefs(siteIdx, resultDefs) {
212
+ const site = this.sites[siteIdx];
213
+ if (site)
214
+ site.resultDefs = [...resultDefs];
215
+ }
216
+ setSiteSpread(siteIdx, firstSpreadArg) {
217
+ const site = this.sites[siteIdx];
218
+ if (site && site.spread === undefined)
219
+ site.spread = firstSpreadArg;
220
+ }
221
+ /**
222
+ * Record a value-position member read. Exact duplicates within the statement
223
+ * (same object/property/parent position) dedup; reads at DIFFERENT argument
224
+ * positions stay distinct (`exec(req.body, req.body)` is two occurrences).
225
+ */
226
+ addMemberRead(object, property) {
227
+ const parent = this.innermostArgPosition();
228
+ const dedupKey = `${object}|${property}|${parent ? `${parent[0]}:${parent[1]}` : 'top'}`;
229
+ if (this.memberReadKeys.has(dedupKey))
230
+ return;
231
+ if (this.sites.length >= DEFAULT_PDG_MAX_SITES_PER_STATEMENT) {
232
+ this._sitesTruncated = true;
233
+ return;
234
+ }
235
+ this.memberReadKeys.add(dedupKey);
236
+ const site = { kind: 'member-read' };
237
+ if (parent)
238
+ site.parent = parent;
239
+ site.object = object;
240
+ site.property = property;
241
+ this.sites.push(site);
242
+ }
243
+ innermostArgPosition() {
244
+ for (let i = this.frames.length - 1; i >= 0; i--) {
245
+ const f = this.frames[i];
246
+ if (f.argIdx >= 0)
247
+ return [f.siteIdx, f.argIdx];
248
+ }
249
+ return undefined;
250
+ }
251
+ /**
252
+ * Fan a binding occurrence out to every arg-active open frame, via-tagged
253
+ * with the site of the IMMEDIATELY nested frame when one exists:
254
+ * `exec(escape(x))` puts a plain `x` in escape's arg 0 and `[x, escapeIdx]`
255
+ * in exec's arg 0 — the sanitizer-interposition substrate.
256
+ */
257
+ recordOccurrence(idx) {
258
+ for (let i = this.frames.length - 1; i >= 0; i--) {
259
+ const f = this.frames[i];
260
+ if (f.argIdx < 0)
261
+ continue;
262
+ // A nested frame whose site was cap-dropped (siteIdx -1) is not a real via.
263
+ const next = i + 1 < this.frames.length ? this.frames[i + 1].siteIdx : undefined;
264
+ const via = next !== undefined && next >= 0 ? next : undefined;
265
+ this.pushArgEntry(f.siteIdx, f.argIdx, idx, via);
266
+ }
267
+ }
268
+ pushArgEntry(siteIdx, argIdx, bindingIdx, via) {
269
+ const site = this.sites[siteIdx];
270
+ if (!site)
271
+ return; // cap-dropped frame (siteIdx -1) — no target to fan into
272
+ const args = (site.args ??= []);
273
+ while (args.length <= argIdx)
274
+ args.push([]);
275
+ const list = args[argIdx];
276
+ // Dedup exact (binding, via) pairs per position — `f(x + x)` is one entry;
277
+ // `f(x + g(x))` keeps the plain AND the via-tagged entry (distinct paths).
278
+ for (const e of list) {
279
+ const match = typeof e === 'number'
280
+ ? via === undefined && e === bindingIdx
281
+ : via !== undefined && e[0] === bindingIdx && e[1] === via;
282
+ if (match)
283
+ return;
284
+ }
285
+ list.push(via === undefined ? bindingIdx : [bindingIdx, via]);
286
+ }
287
+ finish() {
288
+ return {
289
+ line: this.line,
290
+ defs: this.defs,
291
+ uses: this.uses,
292
+ // Optional fields stay absent when empty — keeps the serialized
293
+ // side-channel payload lean (most statements have no may-defs / sites).
294
+ ...(this.mayDefs.length > 0 ? { mayDefs: this.mayDefs } : {}),
295
+ ...(this.sites.length > 0 ? { sites: this.sites.map(finalizeSite) } : {}),
296
+ };
297
+ }
298
+ }
299
+ /** Trim trailing empty arg positions; drop `args` entirely when all-empty. */
300
+ const finalizeSite = (site) => {
301
+ const args = site.args;
302
+ if (args !== undefined) {
303
+ let end = args.length;
304
+ while (end > 0 && args[end - 1].length === 0)
305
+ end--;
306
+ if (end === 0)
307
+ delete site.args;
308
+ else if (end < args.length)
309
+ site.args = args.slice(0, end);
310
+ }
311
+ return site;
312
+ };
313
+ /**
314
+ * Shared `walkChain` TERMINAL (#2227 follow-up, plan KTD5/U8) — the byte-identical
315
+ * post-unwind block the Go / Kotlin / Swift / Rust / Python harvesters all ran
316
+ * after walking their grammar-specific access chain (`selector_expression` /
317
+ * `navigation_expression` / `field_expression` / `attribute`) into an
318
+ * `accesses: string[]` list and a resolved root node `cur`.
319
+ *
320
+ * It records the chain-root identifier as a use, emits at most ONE member-read
321
+ * site — the INNERMOST access — when the root is an identifier (suppressed by
322
+ * `skipFinalRead` when that access IS the callee, carried by the dotted path
323
+ * instead), and builds the dotted path `[root, ...accesses].join('.')`. The only
324
+ * per-grammar bit is the root identifier node type, supplied via `isRootIdType`
325
+ * (`'identifier'` for Go/Rust/Python, `'simple_identifier'` for Kotlin/Swift);
326
+ * the `resolve` / `walkRoot` callbacks bind the harvester's own methods. The
327
+ * `addUse` / `addMemberRead` machinery is on the accumulator itself, so it is
328
+ * called directly (no callback). Behavior is identical to the inlined terminals
329
+ * this replaces — the per-language harvest tests are the characterization lock.
330
+ */
331
+ export function finalizeChain(acc, cur, accesses, skipFinalRead, isRootIdType, hooks) {
332
+ let rootIdx;
333
+ let rootSegment;
334
+ if (isRootIdType(cur.type) && cur.text !== '_') {
335
+ rootIdx = hooks.resolve(cur);
336
+ acc.addUse(rootIdx);
337
+ rootSegment = cur.text;
338
+ }
339
+ else {
340
+ hooks.walkRoot(cur);
341
+ }
342
+ const innermost = accesses[0];
343
+ if (rootIdx !== undefined && innermost && !(skipFinalRead && accesses.length === 1)) {
344
+ acc.addMemberRead(rootIdx, innermost);
345
+ }
346
+ const path = rootSegment !== undefined && accesses.every((a) => a !== '')
347
+ ? [rootSegment, ...accesses].join('.')
348
+ : undefined;
349
+ return { path, rootIdx };
350
+ }
@@ -0,0 +1,124 @@
1
+ /**
2
+ * C# def/use harvester (#2195 U3, plan KTD2) — the C# analogue of
3
+ * {@link import('./typescript-harvest.js').TsHarvester} and the closely-related
4
+ * {@link import('./c-cpp-harvest.js').CCppHarvester}.
5
+ *
6
+ * Runs in the parse worker next to the C# CFG visitor, extracting per-statement
7
+ * variable definition/use facts that ride the side channel for the reaching-defs
8
+ * / CDG solvers. Output is the per-function binding table ({@link BindingEntry}[])
9
+ * plus {@link StatementFacts} the visitor attaches to blocks as it walks.
10
+ *
11
+ * TWO-PHASE, ORDER-INDEPENDENT (load-bearing — mirrors the TS / C-C++ harvesters):
12
+ * the CFG walk is NOT source-order (`visitFor` builds the init block after the
13
+ * body, `visitDoWhile` the condition before the body), so resolving names against
14
+ * a scope stack populated *during* the walk would mis-resolve. Phase 1 pre-scans
15
+ * the whole function subtree once into a completed lexical scope tree; phase 2
16
+ * resolves defs/uses against that finished tree from any walk order.
17
+ *
18
+ * v1 def-semantics scope:
19
+ * - `local_declaration_statement` → `variable_declaration` → `variable_declarator`
20
+ * (an INITIALIZED local is a def; a bare `int x;` with no initializer writes
21
+ * nothing at runtime — not a def, like the TS bare-`var` rule).
22
+ * - `assignment_expression` (plain + compound `+=` etc.), `postfix_unary_expression`
23
+ * / `prefix_unary_expression` (`x++` / `--x`) — define and (for compound /
24
+ * update) also use the lvalue.
25
+ * - parameters (`parameter` → `name` field), the `foreach` loop variable
26
+ * (`foreach_statement` field `left`), pattern bindings (`declaration_pattern`
27
+ * `name`, e.g. `o is string s` / `case int n:`), and catch-clause names
28
+ * (`catch_declaration` `name`).
29
+ * EXCLUDED, deliberately (TypeScript-CFA precedent): member / element / pointer
30
+ * writes (`obj.F = …`, `a[i] = …`) are NOT scalar defs — their identifiers are
31
+ * uses only. Nested-function (lambda / local-function / anonymous-method) bodies
32
+ * are opaque in BOTH directions (writes to and reads of captured outer variables
33
+ * are invisible).
34
+ *
35
+ * MAY-DEFS: a def inside a conditionally-evaluated subexpression — the right
36
+ * operand of `&&` / `||` / `??` (`a ?? (a = load())`), a ternary arm, or a switch
37
+ * arm/case test — is a may-def (gen without kill), so the not-taken path's prior
38
+ * def is not falsely killed.
39
+ *
40
+ * Identifiers with no in-function declaration (fields, properties, statics,
41
+ * namespaced names) resolve to a SYNTHETIC module-level binding (`name@module`),
42
+ * applied identically by def and use harvesting.
43
+ *
44
+ * NOTE: nothing serialized here may carry a field named `nodeId` — the durable
45
+ * parsedfile-store reviver dedups objects keyed on that field name.
46
+ */
47
+ import type { SyntaxNode } from '../../utils/ast-helpers.js';
48
+ import type { StatementFacts } from '../types.js';
49
+ import { ScopeTreeHarvester, type Scope } from './scope-tree-harvest.js';
50
+ export declare class CsharpHarvester extends ScopeTreeHarvester {
51
+ constructor(fnNode: SyntaxNode);
52
+ /** The function/lambda body node (a `block` or an expression for `=> expr`). */
53
+ private bodyOf;
54
+ private declareParams;
55
+ protected prescan(node: SyntaxNode, scope: Scope): void;
56
+ /** Declare every `variable_declarator` name in a `variable_declaration`. */
57
+ private declareVariableDeclaration;
58
+ /** Declare a `foreach` target — an identifier or a `tuple_pattern`. */
59
+ private declareForeachTarget;
60
+ /** Def/use facts for one statement (or construct-header expression) node. */
61
+ facts(node: SyntaxNode): StatementFacts;
62
+ /** Facts for an expression whose WHOLE evaluation is conditional (case tests). */
63
+ factsConditional(node: SyntaxNode): StatementFacts;
64
+ /**
65
+ * Def-ONLY facts for a value-position binding carrier (`var x = k switch {…}`,
66
+ * #2207): just the declared name(s)' def, attached to the continuation block the
67
+ * switch arms rejoin. The discriminant + arm-value USES are already harvested
68
+ * onto the branch's own blocks ({@link facts} on each arm), so this must NOT
69
+ * re-walk the initializer — only each `variable_declarator`'s name is a def here.
70
+ */
71
+ bindingDefFacts(stmt: SyntaxNode): StatementFacts | undefined;
72
+ /** Facts for a `foreach (decl in right)` head: decl binds, right is used. */
73
+ forEachHeadFacts(stmt: SyntaxNode): StatementFacts;
74
+ /** ENTRY-block facts for the function's parameters (defs only). */
75
+ paramFacts(): StatementFacts | undefined;
76
+ /** Def fact for a `catch (T e)` declaration — prepend to the handler entry block. */
77
+ catchParamFacts(catchClause: SyntaxNode): StatementFacts | undefined;
78
+ /** Strip parenthesized wrappers around an lvalue (`(x) = 1`). */
79
+ private unwrapLvalue;
80
+ /** Def a `foreach` target (identifier or tuple) in a header fact accumulator. */
81
+ private defForeachTarget;
82
+ /** Value-position walk: collect uses; route def positions to the lvalue handler. */
83
+ private walkValue;
84
+ /**
85
+ * When `value`'s root (after stripping parens) is an invocation/creation
86
+ * node, remember that its site should carry `resultDefs: defs` — consumed by
87
+ * {@link visitCall} once the value walk reaches the node.
88
+ */
89
+ private registerResultDefs;
90
+ /**
91
+ * Explicit invocation / object-creation handler: records a call site (callee
92
+ * path, receiver, per-arg occurrence entries, result defs) while reproducing
93
+ * EXACTLY the uses the old default descent recorded. C# wraps each argument in
94
+ * an `argument` node; `new Foo(...)` reads the `type` field as the callee.
95
+ */
96
+ private visitCall;
97
+ /**
98
+ * The value expression inside an `argument` node. A named argument
99
+ * (`name: x`) carries the label on the `name` field and the value as a
100
+ * sibling; a positional argument is just the value. Returns the last named
101
+ * child that is not the `name`-field label (and skips `ref`/`out`/`in`
102
+ * modifier keywords, which are anonymous tokens, not named children).
103
+ */
104
+ private argumentValue;
105
+ /**
106
+ * Member chain walk shared by value position and callee position. Records the
107
+ * chain-root identifier as a use (identical to the old default descent), plus
108
+ * at most ONE member-read site — the INNERMOST access — when the root is an
109
+ * identifier; `skipFinalRead` suppresses it when that access is the callee.
110
+ */
111
+ private walkChain;
112
+ /**
113
+ * The initializer value of a `variable_declarator` — the named child after
114
+ * `name`. NOTE: deliberately duplicated in `csharp.ts` (the visitor is a
115
+ * standalone class with no shared base — repo convention). The two copies must
116
+ * stay in sync; there is no C#-specific shared module to host it, and the only
117
+ * module both files share is the generic `utils/ast-helpers` (types only).
118
+ */
119
+ private declaratorInit;
120
+ /** Whether a unary expression is `++`/`--` (the only writing unary ops). */
121
+ private isIncDec;
122
+ /** Def each identifier in a `(a, b) = …` tuple deconstruction target. */
123
+ private defTupleTargets;
124
+ }