@oculum/scanner 1.0.14 → 1.0.15

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 (1323) hide show
  1. package/dist/detect/ai-code/index.d.ts +6 -11
  2. package/dist/detect/ai-code/index.d.ts.map +1 -1
  3. package/dist/detect/ai-code/index.js +6 -24
  4. package/dist/detect/ai-code/index.js.map +1 -1
  5. package/dist/detect/ast-rules/agent-tools-ast.d.ts +14 -0
  6. package/dist/detect/ast-rules/agent-tools-ast.d.ts.map +1 -0
  7. package/dist/detect/ast-rules/agent-tools-ast.js +809 -0
  8. package/dist/detect/ast-rules/agent-tools-ast.js.map +1 -0
  9. package/dist/detect/ast-rules/ai-fingerprinting-ast.d.ts +14 -0
  10. package/dist/detect/ast-rules/ai-fingerprinting-ast.d.ts.map +1 -0
  11. package/dist/detect/ast-rules/ai-fingerprinting-ast.js +344 -0
  12. package/dist/detect/ast-rules/ai-fingerprinting-ast.js.map +1 -0
  13. package/dist/detect/ast-rules/auth-patterns-ast.d.ts +14 -0
  14. package/dist/detect/ast-rules/auth-patterns-ast.d.ts.map +1 -0
  15. package/dist/detect/ast-rules/auth-patterns-ast.js +280 -0
  16. package/dist/detect/ast-rules/auth-patterns-ast.js.map +1 -0
  17. package/dist/detect/ast-rules/byok-ast.d.ts +13 -0
  18. package/dist/detect/ast-rules/byok-ast.d.ts.map +1 -0
  19. package/dist/detect/ast-rules/byok-ast.js +180 -0
  20. package/dist/detect/ast-rules/byok-ast.js.map +1 -0
  21. package/dist/detect/ast-rules/child-process-ast.d.ts +13 -0
  22. package/dist/detect/ast-rules/child-process-ast.d.ts.map +1 -0
  23. package/dist/detect/ast-rules/child-process-ast.js +252 -0
  24. package/dist/detect/ast-rules/child-process-ast.js.map +1 -0
  25. package/dist/detect/ast-rules/dangerous-eval-ast.d.ts +13 -0
  26. package/dist/detect/ast-rules/dangerous-eval-ast.d.ts.map +1 -0
  27. package/dist/detect/ast-rules/dangerous-eval-ast.js +218 -0
  28. package/dist/detect/ast-rules/dangerous-eval-ast.js.map +1 -0
  29. package/dist/detect/ast-rules/data-exposure-ast.d.ts +13 -0
  30. package/dist/detect/ast-rules/data-exposure-ast.d.ts.map +1 -0
  31. package/dist/detect/ast-rules/data-exposure-ast.js +158 -0
  32. package/dist/detect/ast-rules/data-exposure-ast.js.map +1 -0
  33. package/dist/detect/ast-rules/dom-xss-ast.d.ts +14 -0
  34. package/dist/detect/ast-rules/dom-xss-ast.d.ts.map +1 -0
  35. package/dist/detect/ast-rules/dom-xss-ast.js +217 -0
  36. package/dist/detect/ast-rules/dom-xss-ast.js.map +1 -0
  37. package/dist/detect/ast-rules/endpoint-protection-ast.d.ts +13 -0
  38. package/dist/detect/ast-rules/endpoint-protection-ast.d.ts.map +1 -0
  39. package/dist/detect/ast-rules/endpoint-protection-ast.js +228 -0
  40. package/dist/detect/ast-rules/endpoint-protection-ast.js.map +1 -0
  41. package/dist/detect/ast-rules/entropy-ast.d.ts +17 -0
  42. package/dist/detect/ast-rules/entropy-ast.d.ts.map +1 -0
  43. package/dist/detect/ast-rules/entropy-ast.js +265 -0
  44. package/dist/detect/ast-rules/entropy-ast.js.map +1 -0
  45. package/dist/detect/ast-rules/flask-debug-ast.d.ts +10 -0
  46. package/dist/detect/ast-rules/flask-debug-ast.d.ts.map +1 -0
  47. package/dist/detect/ast-rules/flask-debug-ast.js +125 -0
  48. package/dist/detect/ast-rules/flask-debug-ast.js.map +1 -0
  49. package/dist/detect/ast-rules/framework-checks-ast.d.ts +13 -0
  50. package/dist/detect/ast-rules/framework-checks-ast.d.ts.map +1 -0
  51. package/dist/detect/ast-rules/framework-checks-ast.js +185 -0
  52. package/dist/detect/ast-rules/framework-checks-ast.js.map +1 -0
  53. package/dist/detect/ast-rules/helpers/call-analysis.d.ts +62 -0
  54. package/dist/detect/ast-rules/helpers/call-analysis.d.ts.map +1 -0
  55. package/dist/detect/ast-rules/helpers/call-analysis.js +217 -0
  56. package/dist/detect/ast-rules/helpers/call-analysis.js.map +1 -0
  57. package/dist/detect/ast-rules/helpers/context-detection.d.ts +33 -0
  58. package/dist/detect/ast-rules/helpers/context-detection.d.ts.map +1 -0
  59. package/dist/detect/ast-rules/helpers/context-detection.js +256 -0
  60. package/dist/detect/ast-rules/helpers/context-detection.js.map +1 -0
  61. package/dist/detect/ast-rules/helpers/control-flow.d.ts +40 -0
  62. package/dist/detect/ast-rules/helpers/control-flow.d.ts.map +1 -0
  63. package/dist/detect/ast-rules/helpers/control-flow.js +174 -0
  64. package/dist/detect/ast-rules/helpers/control-flow.js.map +1 -0
  65. package/dist/detect/ast-rules/helpers/import-analysis.d.ts +43 -0
  66. package/dist/detect/ast-rules/helpers/import-analysis.d.ts.map +1 -0
  67. package/dist/detect/ast-rules/helpers/import-analysis.js +149 -0
  68. package/dist/detect/ast-rules/helpers/import-analysis.js.map +1 -0
  69. package/dist/detect/ast-rules/helpers/index.d.ts +16 -0
  70. package/dist/detect/ast-rules/helpers/index.d.ts.map +1 -0
  71. package/dist/detect/ast-rules/helpers/index.js +112 -0
  72. package/dist/detect/ast-rules/helpers/index.js.map +1 -0
  73. package/dist/detect/ast-rules/helpers/python-helpers.d.ts +215 -0
  74. package/dist/detect/ast-rules/helpers/python-helpers.d.ts.map +1 -0
  75. package/dist/detect/ast-rules/helpers/python-helpers.js +935 -0
  76. package/dist/detect/ast-rules/helpers/python-helpers.js.map +1 -0
  77. package/dist/detect/ast-rules/helpers/scope-analysis.d.ts +50 -0
  78. package/dist/detect/ast-rules/helpers/scope-analysis.d.ts.map +1 -0
  79. package/dist/detect/ast-rules/helpers/scope-analysis.js +194 -0
  80. package/dist/detect/ast-rules/helpers/scope-analysis.js.map +1 -0
  81. package/dist/detect/ast-rules/helpers/string-analysis.d.ts +57 -0
  82. package/dist/detect/ast-rules/helpers/string-analysis.d.ts.map +1 -0
  83. package/dist/detect/ast-rules/helpers/string-analysis.js +184 -0
  84. package/dist/detect/ast-rules/helpers/string-analysis.js.map +1 -0
  85. package/dist/detect/ast-rules/helpers/type-extraction.d.ts +44 -0
  86. package/dist/detect/ast-rules/helpers/type-extraction.d.ts.map +1 -0
  87. package/dist/detect/ast-rules/helpers/type-extraction.js +125 -0
  88. package/dist/detect/ast-rules/helpers/type-extraction.js.map +1 -0
  89. package/dist/detect/ast-rules/helpers/user-input.d.ts +35 -0
  90. package/dist/detect/ast-rules/helpers/user-input.d.ts.map +1 -0
  91. package/dist/detect/ast-rules/helpers/user-input.js +243 -0
  92. package/dist/detect/ast-rules/helpers/user-input.js.map +1 -0
  93. package/dist/detect/ast-rules/index.d.ts +112 -0
  94. package/dist/detect/ast-rules/index.d.ts.map +1 -0
  95. package/dist/detect/ast-rules/index.js +232 -0
  96. package/dist/detect/ast-rules/index.js.map +1 -0
  97. package/dist/detect/ast-rules/json-parse-ast.d.ts +13 -0
  98. package/dist/detect/ast-rules/json-parse-ast.d.ts.map +1 -0
  99. package/dist/detect/ast-rules/json-parse-ast.js +143 -0
  100. package/dist/detect/ast-rules/json-parse-ast.js.map +1 -0
  101. package/dist/detect/ast-rules/log-injection-ast.d.ts +14 -0
  102. package/dist/detect/ast-rules/log-injection-ast.d.ts.map +1 -0
  103. package/dist/detect/ast-rules/log-injection-ast.js +235 -0
  104. package/dist/detect/ast-rules/log-injection-ast.js.map +1 -0
  105. package/dist/detect/ast-rules/logic-gates-ast.d.ts +14 -0
  106. package/dist/detect/ast-rules/logic-gates-ast.d.ts.map +1 -0
  107. package/dist/detect/ast-rules/logic-gates-ast.js +312 -0
  108. package/dist/detect/ast-rules/logic-gates-ast.js.map +1 -0
  109. package/dist/detect/ast-rules/mcp-security-ast.d.ts +14 -0
  110. package/dist/detect/ast-rules/mcp-security-ast.d.ts.map +1 -0
  111. package/dist/detect/ast-rules/mcp-security-ast.js +755 -0
  112. package/dist/detect/ast-rules/mcp-security-ast.js.map +1 -0
  113. package/dist/detect/ast-rules/model-supply-chain-ast.d.ts +13 -0
  114. package/dist/detect/ast-rules/model-supply-chain-ast.d.ts.map +1 -0
  115. package/dist/detect/ast-rules/model-supply-chain-ast.js +188 -0
  116. package/dist/detect/ast-rules/model-supply-chain-ast.js.map +1 -0
  117. package/dist/detect/ast-rules/package-hallucination-ast.d.ts +13 -0
  118. package/dist/detect/ast-rules/package-hallucination-ast.d.ts.map +1 -0
  119. package/dist/detect/ast-rules/package-hallucination-ast.js +607 -0
  120. package/dist/detect/ast-rules/package-hallucination-ast.js.map +1 -0
  121. package/dist/detect/ast-rules/prompt-hygiene-ast.d.ts +15 -0
  122. package/dist/detect/ast-rules/prompt-hygiene-ast.d.ts.map +1 -0
  123. package/dist/detect/ast-rules/prompt-hygiene-ast.js +332 -0
  124. package/dist/detect/ast-rules/prompt-hygiene-ast.js.map +1 -0
  125. package/dist/detect/ast-rules/rag-safety-ast.d.ts +18 -0
  126. package/dist/detect/ast-rules/rag-safety-ast.d.ts.map +1 -0
  127. package/dist/detect/ast-rules/rag-safety-ast.js +640 -0
  128. package/dist/detect/ast-rules/rag-safety-ast.js.map +1 -0
  129. package/dist/detect/ast-rules/request-validation-ast.d.ts +13 -0
  130. package/dist/detect/ast-rules/request-validation-ast.d.ts.map +1 -0
  131. package/dist/detect/ast-rules/request-validation-ast.js +116 -0
  132. package/dist/detect/ast-rules/request-validation-ast.js.map +1 -0
  133. package/dist/detect/ast-rules/risky-imports-ast.d.ts +14 -0
  134. package/dist/detect/ast-rules/risky-imports-ast.d.ts.map +1 -0
  135. package/dist/detect/ast-rules/risky-imports-ast.js +114 -0
  136. package/dist/detect/ast-rules/risky-imports-ast.js.map +1 -0
  137. package/dist/detect/ast-rules/schema-validation-ast.d.ts +14 -0
  138. package/dist/detect/ast-rules/schema-validation-ast.d.ts.map +1 -0
  139. package/dist/detect/ast-rules/schema-validation-ast.js +233 -0
  140. package/dist/detect/ast-rules/schema-validation-ast.js.map +1 -0
  141. package/dist/detect/ast-rules/secret-patterns-ast.d.ts +17 -0
  142. package/dist/detect/ast-rules/secret-patterns-ast.d.ts.map +1 -0
  143. package/dist/detect/ast-rules/secret-patterns-ast.js +199 -0
  144. package/dist/detect/ast-rules/secret-patterns-ast.js.map +1 -0
  145. package/dist/detect/ast-rules/security-headers-ast.d.ts +14 -0
  146. package/dist/detect/ast-rules/security-headers-ast.d.ts.map +1 -0
  147. package/dist/detect/ast-rules/security-headers-ast.js +187 -0
  148. package/dist/detect/ast-rules/security-headers-ast.js.map +1 -0
  149. package/dist/detect/ast-rules/sql-injection-ast.d.ts +17 -0
  150. package/dist/detect/ast-rules/sql-injection-ast.d.ts.map +1 -0
  151. package/dist/detect/ast-rules/sql-injection-ast.js +497 -0
  152. package/dist/detect/ast-rules/sql-injection-ast.js.map +1 -0
  153. package/dist/detect/ast-rules/ssrf-ast.d.ts +14 -0
  154. package/dist/detect/ast-rules/ssrf-ast.d.ts.map +1 -0
  155. package/dist/detect/ast-rules/ssrf-ast.js +573 -0
  156. package/dist/detect/ast-rules/ssrf-ast.js.map +1 -0
  157. package/dist/detect/ast-rules/taint-fix-templates.d.ts +18 -0
  158. package/dist/detect/ast-rules/taint-fix-templates.d.ts.map +1 -0
  159. package/dist/detect/ast-rules/taint-fix-templates.js +92 -0
  160. package/dist/detect/ast-rules/taint-fix-templates.js.map +1 -0
  161. package/dist/detect/ast-rules/taint-flow-ast.d.ts +24 -0
  162. package/dist/detect/ast-rules/taint-flow-ast.d.ts.map +1 -0
  163. package/dist/detect/ast-rules/taint-flow-ast.js +340 -0
  164. package/dist/detect/ast-rules/taint-flow-ast.js.map +1 -0
  165. package/dist/detect/ast-rules/variables-ast.d.ts +24 -0
  166. package/dist/detect/ast-rules/variables-ast.d.ts.map +1 -0
  167. package/dist/detect/ast-rules/variables-ast.js +362 -0
  168. package/dist/detect/ast-rules/variables-ast.js.map +1 -0
  169. package/dist/detect/ast-rules/weak-crypto-ast.d.ts +15 -0
  170. package/dist/detect/ast-rules/weak-crypto-ast.d.ts.map +1 -0
  171. package/dist/detect/ast-rules/weak-crypto-ast.js +406 -0
  172. package/dist/detect/ast-rules/weak-crypto-ast.js.map +1 -0
  173. package/dist/detect/ast-rules/xxe-ast.d.ts +13 -0
  174. package/dist/detect/ast-rules/xxe-ast.d.ts.map +1 -0
  175. package/dist/detect/ast-rules/xxe-ast.js +157 -0
  176. package/dist/detect/ast-rules/xxe-ast.js.map +1 -0
  177. package/dist/detect/config/agent-skill-injection.d.ts.map +1 -1
  178. package/dist/detect/config/agent-skill-injection.js +2 -24
  179. package/dist/detect/config/agent-skill-injection.js.map +1 -1
  180. package/dist/detect/config/index.d.ts +1 -0
  181. package/dist/detect/config/index.d.ts.map +1 -1
  182. package/dist/detect/config/index.js +3 -1
  183. package/dist/detect/config/index.js.map +1 -1
  184. package/dist/detect/config/osv-check.d.ts.map +1 -1
  185. package/dist/detect/config/osv-check.js +6 -1
  186. package/dist/detect/config/osv-check.js.map +1 -1
  187. package/dist/detect/config/package-check.d.ts.map +1 -1
  188. package/dist/detect/config/package-check.js +6 -1
  189. package/dist/detect/config/package-check.js.map +1 -1
  190. package/dist/detect/config/rules-file-backdoor.d.ts +36 -0
  191. package/dist/detect/config/rules-file-backdoor.d.ts.map +1 -0
  192. package/dist/detect/config/rules-file-backdoor.js +379 -0
  193. package/dist/detect/config/rules-file-backdoor.js.map +1 -0
  194. package/dist/detect/index.d.ts +43 -6
  195. package/dist/detect/index.d.ts.map +1 -1
  196. package/dist/detect/index.js +70 -7
  197. package/dist/detect/index.js.map +1 -1
  198. package/dist/detect/secrets/config-audit.d.ts.map +1 -1
  199. package/dist/detect/secrets/config-audit.js +36 -3
  200. package/dist/detect/secrets/config-audit.js.map +1 -1
  201. package/dist/detect/secrets/entropy.d.ts.map +1 -1
  202. package/dist/detect/secrets/entropy.js +180 -0
  203. package/dist/detect/secrets/entropy.js.map +1 -1
  204. package/dist/detect/secrets/index.d.ts +0 -2
  205. package/dist/detect/secrets/index.d.ts.map +1 -1
  206. package/dist/detect/secrets/index.js +7 -17
  207. package/dist/detect/secrets/index.js.map +1 -1
  208. package/dist/detect/structural/index.d.ts +15 -28
  209. package/dist/detect/structural/index.d.ts.map +1 -1
  210. package/dist/detect/structural/index.js +20 -497
  211. package/dist/detect/structural/index.js.map +1 -1
  212. package/dist/index.d.ts +3 -0
  213. package/dist/index.d.ts.map +1 -1
  214. package/dist/index.js +9 -1
  215. package/dist/index.js.map +1 -1
  216. package/dist/model/auth-helper-detector.d.ts.map +1 -1
  217. package/dist/model/auth-helper-detector.js +2 -7
  218. package/dist/model/auth-helper-detector.js.map +1 -1
  219. package/dist/model/import-resolver.d.ts.map +1 -1
  220. package/dist/model/import-resolver.js +94 -0
  221. package/dist/model/import-resolver.js.map +1 -1
  222. package/dist/model/imported-auth-detector.js +8 -8
  223. package/dist/model/imported-auth-detector.js.map +1 -1
  224. package/dist/model/index.d.ts +8 -0
  225. package/dist/model/index.d.ts.map +1 -1
  226. package/dist/model/index.js +198 -73
  227. package/dist/model/index.js.map +1 -1
  228. package/dist/model/module-graph.d.ts.map +1 -1
  229. package/dist/model/module-graph.js +22 -9
  230. package/dist/model/module-graph.js.map +1 -1
  231. package/dist/model/project-context.d.ts +1 -1
  232. package/dist/model/project-context.d.ts.map +1 -1
  233. package/dist/model/project-context.js +34 -0
  234. package/dist/model/project-context.js.map +1 -1
  235. package/dist/model/route-auth-resolver.d.ts.map +1 -1
  236. package/dist/model/route-auth-resolver.js +17 -2
  237. package/dist/model/route-auth-resolver.js.map +1 -1
  238. package/dist/model/route-discovery/index.js +1 -1
  239. package/dist/model/route-discovery/index.js.map +1 -1
  240. package/dist/model/route-discovery/nextjs.js +1 -1
  241. package/dist/model/route-discovery/nextjs.js.map +1 -1
  242. package/dist/model/route-discovery/python.d.ts +6 -3
  243. package/dist/model/route-discovery/python.d.ts.map +1 -1
  244. package/dist/model/route-discovery/python.js +132 -9
  245. package/dist/model/route-discovery/python.js.map +1 -1
  246. package/dist/model/route-discovery/types.d.ts +1 -1
  247. package/dist/model/route-discovery/types.d.ts.map +1 -1
  248. package/dist/model/route-discovery/utils.d.ts +8 -0
  249. package/dist/model/route-discovery/utils.d.ts.map +1 -1
  250. package/dist/model/route-discovery/utils.js +70 -0
  251. package/dist/model/route-discovery/utils.js.map +1 -1
  252. package/dist/model/taint-types.d.ts +0 -4
  253. package/dist/model/taint-types.d.ts.map +1 -1
  254. package/dist/parse/ast.d.ts +58 -0
  255. package/dist/parse/ast.d.ts.map +1 -0
  256. package/dist/parse/ast.js +230 -0
  257. package/dist/parse/ast.js.map +1 -0
  258. package/dist/parse/call-graph.d.ts +41 -0
  259. package/dist/parse/call-graph.d.ts.map +1 -0
  260. package/dist/parse/call-graph.js +386 -0
  261. package/dist/parse/call-graph.js.map +1 -0
  262. package/dist/parse/file-classifier.d.ts +11 -0
  263. package/dist/parse/file-classifier.d.ts.map +1 -1
  264. package/dist/parse/file-classifier.js +63 -15
  265. package/dist/parse/file-classifier.js.map +1 -1
  266. package/dist/parse/node-index.d.ts +32 -0
  267. package/dist/parse/node-index.d.ts.map +1 -0
  268. package/dist/parse/node-index.js +103 -0
  269. package/dist/parse/node-index.js.map +1 -0
  270. package/dist/parse/type-extractor.d.ts +50 -0
  271. package/dist/parse/type-extractor.d.ts.map +1 -0
  272. package/dist/parse/type-extractor.js +243 -0
  273. package/dist/parse/type-extractor.js.map +1 -0
  274. package/dist/pipeline/config.d.ts +7 -1
  275. package/dist/pipeline/config.d.ts.map +1 -1
  276. package/dist/pipeline/config.js.map +1 -1
  277. package/dist/pipeline/index.d.ts +3 -3
  278. package/dist/pipeline/index.d.ts.map +1 -1
  279. package/dist/pipeline/index.js +192 -64
  280. package/dist/pipeline/index.js.map +1 -1
  281. package/dist/pipeline/modes/incremental.d.ts.map +1 -1
  282. package/dist/pipeline/modes/incremental.js +2 -7
  283. package/dist/pipeline/modes/incremental.js.map +1 -1
  284. package/dist/postprocess/dedup.d.ts +5 -2
  285. package/dist/postprocess/dedup.d.ts.map +1 -1
  286. package/dist/postprocess/dedup.js +47 -16
  287. package/dist/postprocess/dedup.js.map +1 -1
  288. package/dist/report/build-result.d.ts +9 -4
  289. package/dist/report/build-result.d.ts.map +1 -1
  290. package/dist/report/build-result.js +15 -4
  291. package/dist/report/build-result.js.map +1 -1
  292. package/dist/report/formatters/cli-terminal.d.ts +1 -1
  293. package/dist/report/formatters/cli-terminal.d.ts.map +1 -1
  294. package/dist/report/formatters/cli-terminal.js +434 -231
  295. package/dist/report/formatters/cli-terminal.js.map +1 -1
  296. package/dist/report/sanitize.d.ts +10 -0
  297. package/dist/report/sanitize.d.ts.map +1 -0
  298. package/dist/report/sanitize.js +19 -0
  299. package/dist/report/sanitize.js.map +1 -0
  300. package/dist/score/adjustments.d.ts +20 -2
  301. package/dist/score/adjustments.d.ts.map +1 -1
  302. package/dist/score/adjustments.js +108 -37
  303. package/dist/score/adjustments.js.map +1 -1
  304. package/dist/score/confidence.d.ts +6 -0
  305. package/dist/score/confidence.d.ts.map +1 -1
  306. package/dist/score/confidence.js +10 -4
  307. package/dist/score/confidence.js.map +1 -1
  308. package/dist/score/evidence.d.ts +25 -0
  309. package/dist/score/evidence.d.ts.map +1 -0
  310. package/dist/score/evidence.js +51 -0
  311. package/dist/score/evidence.js.map +1 -0
  312. package/dist/score/index.d.ts +3 -1
  313. package/dist/score/index.d.ts.map +1 -1
  314. package/dist/score/index.js +25 -50
  315. package/dist/score/index.js.map +1 -1
  316. package/dist/score/types.d.ts +5 -1
  317. package/dist/score/types.d.ts.map +1 -1
  318. package/dist/shared/category-filter.d.ts.map +1 -1
  319. package/dist/shared/category-filter.js +12 -0
  320. package/dist/shared/category-filter.js.map +1 -1
  321. package/dist/shared/regex-utils.d.ts +3 -0
  322. package/dist/shared/regex-utils.d.ts.map +1 -0
  323. package/dist/shared/regex-utils.js +8 -0
  324. package/dist/shared/regex-utils.js.map +1 -0
  325. package/dist/shared/registry-clients.d.ts +7 -0
  326. package/dist/shared/registry-clients.d.ts.map +1 -1
  327. package/dist/shared/registry-clients.js +94 -17
  328. package/dist/shared/registry-clients.js.map +1 -1
  329. package/dist/shared/rules/metadata.d.ts.map +1 -1
  330. package/dist/shared/rules/metadata.js +17 -0
  331. package/dist/shared/rules/metadata.js.map +1 -1
  332. package/dist/shared/types.d.ts +59 -15
  333. package/dist/shared/types.d.ts.map +1 -1
  334. package/dist/shared/types.js +38 -21
  335. package/dist/shared/types.js.map +1 -1
  336. package/dist/taint/async-flow.d.ts +44 -0
  337. package/dist/taint/async-flow.d.ts.map +1 -0
  338. package/dist/taint/async-flow.js +271 -0
  339. package/dist/taint/async-flow.js.map +1 -0
  340. package/dist/taint/cfg-builder.d.ts +35 -0
  341. package/dist/taint/cfg-builder.d.ts.map +1 -0
  342. package/dist/taint/cfg-builder.js +980 -0
  343. package/dist/taint/cfg-builder.js.map +1 -0
  344. package/dist/taint/cfg-types.d.ts +76 -0
  345. package/dist/taint/cfg-types.d.ts.map +1 -0
  346. package/dist/taint/cfg-types.js +13 -0
  347. package/dist/taint/cfg-types.js.map +1 -0
  348. package/dist/taint/constant-propagation.d.ts +34 -0
  349. package/dist/taint/constant-propagation.d.ts.map +1 -0
  350. package/dist/taint/constant-propagation.js +164 -0
  351. package/dist/taint/constant-propagation.js.map +1 -0
  352. package/dist/taint/cross-file-analyzer.d.ts +27 -0
  353. package/dist/taint/cross-file-analyzer.d.ts.map +1 -0
  354. package/dist/taint/cross-file-analyzer.js +99 -0
  355. package/dist/taint/cross-file-analyzer.js.map +1 -0
  356. package/dist/taint/cross-file-index.d.ts +59 -0
  357. package/dist/taint/cross-file-index.d.ts.map +1 -0
  358. package/dist/taint/cross-file-index.js +183 -0
  359. package/dist/taint/cross-file-index.js.map +1 -0
  360. package/dist/taint/def-use.d.ts +27 -0
  361. package/dist/taint/def-use.d.ts.map +1 -0
  362. package/dist/taint/def-use.js +519 -0
  363. package/dist/taint/def-use.js.map +1 -0
  364. package/dist/taint/file-analysis-cache.d.ts +47 -0
  365. package/dist/taint/file-analysis-cache.d.ts.map +1 -0
  366. package/dist/taint/file-analysis-cache.js +107 -0
  367. package/dist/taint/file-analysis-cache.js.map +1 -0
  368. package/dist/taint/framework-models.d.ts +77 -0
  369. package/dist/taint/framework-models.d.ts.map +1 -0
  370. package/dist/taint/framework-models.js +258 -0
  371. package/dist/taint/framework-models.js.map +1 -0
  372. package/dist/taint/helpers.d.ts +31 -0
  373. package/dist/taint/helpers.d.ts.map +1 -0
  374. package/dist/taint/helpers.js +130 -0
  375. package/dist/taint/helpers.js.map +1 -0
  376. package/dist/taint/index.d.ts +28 -0
  377. package/dist/taint/index.d.ts.map +1 -0
  378. package/dist/taint/index.js +77 -0
  379. package/dist/taint/index.js.map +1 -0
  380. package/dist/taint/llm-registry.d.ts +47 -0
  381. package/dist/taint/llm-registry.d.ts.map +1 -0
  382. package/dist/taint/llm-registry.js +152 -0
  383. package/dist/taint/llm-registry.js.map +1 -0
  384. package/dist/taint/llm-risk-scoring.d.ts +54 -0
  385. package/dist/taint/llm-risk-scoring.d.ts.map +1 -0
  386. package/dist/taint/llm-risk-scoring.js +376 -0
  387. package/dist/taint/llm-risk-scoring.js.map +1 -0
  388. package/dist/taint/propagation-types.d.ts +104 -0
  389. package/dist/taint/propagation-types.d.ts.map +1 -0
  390. package/dist/taint/propagation-types.js +98 -0
  391. package/dist/taint/propagation-types.js.map +1 -0
  392. package/dist/taint/propagation.d.ts +111 -0
  393. package/dist/taint/propagation.d.ts.map +1 -0
  394. package/dist/taint/propagation.js +1576 -0
  395. package/dist/taint/propagation.js.map +1 -0
  396. package/dist/taint/sanitizer-registry.d.ts +26 -0
  397. package/dist/taint/sanitizer-registry.d.ts.map +1 -0
  398. package/dist/taint/sanitizer-registry.js +422 -0
  399. package/dist/taint/sanitizer-registry.js.map +1 -0
  400. package/dist/taint/sink-classifier.d.ts +27 -0
  401. package/dist/taint/sink-classifier.d.ts.map +1 -0
  402. package/dist/taint/sink-classifier.js +1166 -0
  403. package/dist/taint/sink-classifier.js.map +1 -0
  404. package/dist/taint/source-classifier.d.ts +29 -0
  405. package/dist/taint/source-classifier.d.ts.map +1 -0
  406. package/dist/taint/source-classifier.js +814 -0
  407. package/dist/taint/source-classifier.js.map +1 -0
  408. package/dist/taint/taint-analyzer.d.ts +33 -0
  409. package/dist/taint/taint-analyzer.d.ts.map +1 -0
  410. package/dist/taint/taint-analyzer.js +88 -0
  411. package/dist/taint/taint-analyzer.js.map +1 -0
  412. package/dist/taint/taint-summary.d.ts +37 -0
  413. package/dist/taint/taint-summary.d.ts.map +1 -0
  414. package/dist/taint/taint-summary.js +293 -0
  415. package/dist/taint/taint-summary.js.map +1 -0
  416. package/dist/taint/types.d.ts +47 -0
  417. package/dist/taint/types.d.ts.map +1 -0
  418. package/dist/taint/types.js +19 -0
  419. package/dist/taint/types.js.map +1 -0
  420. package/dist/validate/clients.d.ts +2 -1
  421. package/dist/validate/clients.d.ts.map +1 -1
  422. package/dist/validate/clients.js +3 -2
  423. package/dist/validate/clients.js.map +1 -1
  424. package/dist/validate/index.d.ts +5 -6
  425. package/dist/validate/index.d.ts.map +1 -1
  426. package/dist/validate/index.js +22 -21
  427. package/dist/validate/index.js.map +1 -1
  428. package/dist/validate/prompts/modules/ai-patterns.d.ts +1 -1
  429. package/dist/validate/prompts/modules/ai-patterns.d.ts.map +1 -1
  430. package/dist/validate/prompts/modules/ai-patterns.js +16 -0
  431. package/dist/validate/prompts/modules/ai-patterns.js.map +1 -1
  432. package/dist/validate/prompts/modules/common.d.ts +1 -1
  433. package/dist/validate/prompts/modules/common.d.ts.map +1 -1
  434. package/dist/validate/prompts/modules/common.js +12 -3
  435. package/dist/validate/prompts/modules/common.js.map +1 -1
  436. package/dist/validate/providers/anthropic.d.ts +4 -4
  437. package/dist/validate/providers/anthropic.d.ts.map +1 -1
  438. package/dist/validate/providers/anthropic.js +85 -58
  439. package/dist/validate/providers/anthropic.js.map +1 -1
  440. package/dist/validate/providers/openai.d.ts +4 -4
  441. package/dist/validate/providers/openai.d.ts.map +1 -1
  442. package/dist/validate/providers/openai.js +149 -99
  443. package/dist/validate/providers/openai.js.map +1 -1
  444. package/dist/validate/request-builder.d.ts +2 -8
  445. package/dist/validate/request-builder.d.ts.map +1 -1
  446. package/dist/validate/request-builder.js +4 -34
  447. package/dist/validate/request-builder.js.map +1 -1
  448. package/dist/validate/types.d.ts +9 -0
  449. package/dist/validate/types.d.ts.map +1 -1
  450. package/dist/validate/types.js.map +1 -1
  451. package/dist/validate/utils/path-helpers.js +2 -2
  452. package/dist/validate/utils/path-helpers.js.map +1 -1
  453. package/dist/validate/utils/response-parser.d.ts +10 -0
  454. package/dist/validate/utils/response-parser.d.ts.map +1 -1
  455. package/dist/validate/utils/response-parser.js +21 -2
  456. package/dist/validate/utils/response-parser.js.map +1 -1
  457. package/dist/validate/utils/retry.d.ts.map +1 -1
  458. package/dist/validate/utils/retry.js +19 -4
  459. package/dist/validate/utils/retry.js.map +1 -1
  460. package/package.json +7 -4
  461. package/src/__tests__/benchmark/fixtures/layer2/ai-execution-sinks.ts +1 -1
  462. package/src/__tests__/benchmark/planted-benchmark.test.ts +337 -0
  463. package/src/__tests__/benchmark/utils/test-runner.ts +38 -4
  464. package/src/__tests__/category-filter.test.ts +5 -1
  465. package/src/__tests__/context-engine/route-discovery/python.test.ts +726 -0
  466. package/src/__tests__/detect/ast-rules.test.ts +1043 -0
  467. package/src/__tests__/detect/offline-mode.test.ts +147 -0
  468. package/src/__tests__/detect/python-ast-rules.test.ts +569 -0
  469. package/src/__tests__/detect/python-helpers.test.ts +536 -0
  470. package/src/__tests__/detect/python-sast-rules.test.ts +453 -0
  471. package/src/__tests__/detect/rules-file-backdoor-decoders.test.ts +151 -0
  472. package/src/__tests__/detect/rules-file-backdoor.test.ts +284 -0
  473. package/src/__tests__/detect/taint-fix-templates.test.ts +150 -0
  474. package/src/__tests__/detect/taint-path-serialization.test.ts +170 -0
  475. package/src/__tests__/parse/call-graph.test.ts +300 -0
  476. package/src/__tests__/parse/python-parser.test.ts +274 -0
  477. package/src/__tests__/regression/known-false-positives.test.ts +491 -9
  478. package/src/__tests__/regression/rules-file-backdoor.test.ts +137 -0
  479. package/src/__tests__/score/adjustments.test.ts +34 -16
  480. package/src/__tests__/score/confidence.test.ts +84 -57
  481. package/src/__tests__/score/evidence-scoring.test.ts +249 -0
  482. package/src/__tests__/score/evidence.test.ts +144 -0
  483. package/src/__tests__/score/scoring-integration.test.ts +56 -34
  484. package/src/__tests__/score/taint-adjustments.test.ts +14 -228
  485. package/src/__tests__/snapshots/__snapshots__/scan-depth.test.ts.snap +65 -59
  486. package/src/__tests__/snapshots/scan-depth.test.ts +39 -7
  487. package/src/__tests__/taint/async-flow.test.ts +247 -0
  488. package/src/__tests__/taint/cfg-builder.test.ts +835 -0
  489. package/src/__tests__/taint/constant-propagation.test.ts +302 -0
  490. package/src/__tests__/taint/cross-file-index.test.ts +683 -0
  491. package/src/__tests__/taint/cross-file-integration.test.ts +275 -0
  492. package/src/__tests__/taint/cross-file-propagation.test.ts +910 -0
  493. package/src/__tests__/taint/def-use.test.ts +132 -0
  494. package/src/__tests__/taint/field-sensitive-sinks.test.ts +179 -0
  495. package/src/__tests__/taint/field-sensitivity.test.ts +342 -0
  496. package/src/__tests__/taint/file-analysis-cache.test.ts +290 -0
  497. package/src/__tests__/taint/framework-models.test.ts +227 -0
  498. package/src/__tests__/taint/llm-flow-graph.test.ts +850 -0
  499. package/src/__tests__/taint/llm-risk-scoring.test.ts +439 -0
  500. package/src/__tests__/taint/performance-parity.test.ts +315 -0
  501. package/src/__tests__/taint/propagation.test.ts +621 -0
  502. package/src/__tests__/taint/python-cross-file.test.ts +494 -0
  503. package/src/__tests__/taint/python-taint.test.ts +1344 -0
  504. package/src/__tests__/taint/sanitizer-registry.test.ts +304 -0
  505. package/src/__tests__/taint/sanitizer-regression.test.ts +111 -0
  506. package/src/__tests__/taint/sink-classifier.test.ts +537 -0
  507. package/src/__tests__/taint/source-classifier.test.ts +367 -0
  508. package/src/__tests__/taint/taint-pipeline.test.ts +418 -0
  509. package/src/__tests__/taint/taint-smoke.test.ts +400 -0
  510. package/src/__tests__/taint/taint-summary.test.ts +472 -0
  511. package/src/detect/ai-code/index.ts +6 -11
  512. package/src/detect/ast-rules/agent-tools-ast.ts +861 -0
  513. package/src/detect/ast-rules/ai-fingerprinting-ast.ts +451 -0
  514. package/src/detect/ast-rules/auth-patterns-ast.ts +304 -0
  515. package/src/detect/ast-rules/byok-ast.ts +195 -0
  516. package/src/detect/ast-rules/child-process-ast.ts +276 -0
  517. package/src/detect/ast-rules/dangerous-eval-ast.ts +227 -0
  518. package/src/detect/ast-rules/data-exposure-ast.ts +162 -0
  519. package/src/detect/ast-rules/dom-xss-ast.ts +260 -0
  520. package/src/detect/ast-rules/endpoint-protection-ast.ts +231 -0
  521. package/src/detect/ast-rules/entropy-ast.ts +268 -0
  522. package/src/detect/ast-rules/flask-debug-ast.ts +148 -0
  523. package/src/detect/ast-rules/framework-checks-ast.ts +200 -0
  524. package/src/detect/ast-rules/helpers/call-analysis.ts +256 -0
  525. package/src/detect/ast-rules/helpers/context-detection.ts +277 -0
  526. package/src/detect/ast-rules/helpers/control-flow.ts +179 -0
  527. package/src/detect/ast-rules/helpers/import-analysis.ts +185 -0
  528. package/src/detect/ast-rules/helpers/index.ts +133 -0
  529. package/src/detect/ast-rules/helpers/python-helpers.ts +1054 -0
  530. package/src/detect/ast-rules/helpers/scope-analysis.ts +224 -0
  531. package/src/detect/ast-rules/helpers/string-analysis.ts +215 -0
  532. package/src/detect/ast-rules/helpers/type-extraction.ts +138 -0
  533. package/src/detect/ast-rules/helpers/user-input.ts +256 -0
  534. package/src/detect/ast-rules/index.ts +311 -0
  535. package/src/detect/ast-rules/json-parse-ast.ts +162 -0
  536. package/src/detect/ast-rules/log-injection-ast.ts +243 -0
  537. package/src/detect/ast-rules/logic-gates-ast.ts +343 -0
  538. package/src/detect/ast-rules/mcp-security-ast.ts +808 -0
  539. package/src/detect/ast-rules/model-supply-chain-ast.ts +202 -0
  540. package/src/detect/ast-rules/package-hallucination-ast.ts +664 -0
  541. package/src/detect/ast-rules/prompt-hygiene-ast.ts +329 -0
  542. package/src/detect/ast-rules/rag-safety-ast.ts +689 -0
  543. package/src/detect/ast-rules/request-validation-ast.ts +122 -0
  544. package/src/detect/ast-rules/risky-imports-ast.ts +133 -0
  545. package/src/detect/ast-rules/schema-validation-ast.ts +244 -0
  546. package/src/detect/ast-rules/secret-patterns-ast.ts +223 -0
  547. package/src/detect/ast-rules/security-headers-ast.ts +206 -0
  548. package/src/detect/ast-rules/sql-injection-ast.ts +614 -0
  549. package/src/detect/ast-rules/ssrf-ast.ts +601 -0
  550. package/src/detect/ast-rules/taint-fix-templates.ts +108 -0
  551. package/src/detect/ast-rules/taint-flow-ast.ts +416 -0
  552. package/src/detect/ast-rules/variables-ast.ts +446 -0
  553. package/src/detect/ast-rules/weak-crypto-ast.ts +441 -0
  554. package/src/detect/ast-rules/xxe-ast.ts +184 -0
  555. package/src/detect/config/agent-skill-injection.ts +2 -24
  556. package/src/detect/config/index.ts +1 -0
  557. package/src/detect/config/osv-check.ts +6 -1
  558. package/src/detect/config/package-check.ts +6 -1
  559. package/src/detect/config/rules-file-backdoor.ts +438 -0
  560. package/src/detect/index.ts +146 -52
  561. package/src/detect/secrets/config-audit.ts +37 -3
  562. package/src/detect/secrets/entropy.ts +195 -0
  563. package/src/detect/secrets/index.ts +7 -16
  564. package/src/detect/structural/index.ts +23 -566
  565. package/src/index.ts +7 -0
  566. package/src/model/auth-helper-detector.ts +1 -7
  567. package/src/model/import-resolver.ts +104 -0
  568. package/src/model/imported-auth-detector.ts +1 -1
  569. package/src/model/index.ts +240 -80
  570. package/src/model/module-graph.ts +17 -5
  571. package/src/model/project-context.ts +28 -1
  572. package/src/model/route-auth-resolver.ts +18 -3
  573. package/src/model/route-discovery/index.ts +1 -1
  574. package/src/model/route-discovery/nextjs.ts +1 -1
  575. package/src/model/route-discovery/python.ts +156 -9
  576. package/src/model/route-discovery/types.ts +1 -1
  577. package/src/model/route-discovery/utils.ts +73 -0
  578. package/src/model/taint-types.ts +1 -6
  579. package/src/parse/ast.ts +271 -0
  580. package/src/parse/call-graph.ts +419 -0
  581. package/src/parse/file-classifier.ts +69 -15
  582. package/src/parse/node-index.ts +118 -0
  583. package/src/parse/type-extractor.ts +293 -0
  584. package/src/pipeline/config.ts +7 -0
  585. package/src/pipeline/index.ts +464 -199
  586. package/src/pipeline/modes/incremental.ts +1 -7
  587. package/src/postprocess/dedup.ts +48 -17
  588. package/src/report/build-result.ts +57 -29
  589. package/src/report/formatters/cli-terminal.ts +731 -415
  590. package/src/report/sanitize.ts +27 -0
  591. package/src/score/adjustments.ts +113 -40
  592. package/src/score/confidence.ts +10 -5
  593. package/src/score/evidence.ts +55 -0
  594. package/src/score/index.ts +27 -55
  595. package/src/score/types.ts +4 -0
  596. package/src/shared/category-filter.ts +12 -0
  597. package/src/shared/regex-utils.ts +4 -0
  598. package/src/shared/registry-clients.ts +106 -18
  599. package/src/shared/rules/__tests__/metadata.test.ts +5 -1
  600. package/src/shared/rules/metadata.ts +19 -0
  601. package/src/shared/types.ts +372 -253
  602. package/src/taint/async-flow.ts +301 -0
  603. package/src/taint/cfg-builder.ts +1127 -0
  604. package/src/taint/cfg-types.ts +110 -0
  605. package/src/taint/constant-propagation.ts +170 -0
  606. package/src/taint/cross-file-analyzer.ts +118 -0
  607. package/src/taint/cross-file-index.ts +275 -0
  608. package/src/taint/def-use.ts +556 -0
  609. package/src/taint/file-analysis-cache.ts +145 -0
  610. package/src/taint/framework-models.ts +313 -0
  611. package/src/taint/helpers.ts +138 -0
  612. package/src/taint/index.ts +71 -0
  613. package/src/taint/llm-registry.ts +174 -0
  614. package/src/taint/llm-risk-scoring.ts +412 -0
  615. package/src/taint/propagation-types.ts +188 -0
  616. package/src/taint/propagation.ts +1750 -0
  617. package/src/taint/sanitizer-registry.ts +490 -0
  618. package/src/taint/sink-classifier.ts +1402 -0
  619. package/src/taint/source-classifier.ts +859 -0
  620. package/src/taint/taint-analyzer.ts +112 -0
  621. package/src/taint/taint-summary.ts +341 -0
  622. package/src/taint/types.ts +86 -0
  623. package/src/validate/clients.ts +3 -2
  624. package/src/validate/index.ts +89 -53
  625. package/src/validate/prompts/modules/ai-patterns.ts +16 -0
  626. package/src/validate/prompts/modules/common.ts +12 -3
  627. package/src/validate/providers/anthropic.ts +254 -148
  628. package/src/validate/providers/openai.ts +363 -218
  629. package/src/validate/request-builder.ts +2 -45
  630. package/src/validate/types.ts +9 -0
  631. package/src/validate/utils/path-helpers.ts +2 -2
  632. package/src/validate/utils/response-parser.ts +32 -3
  633. package/src/validate/utils/retry.ts +19 -4
  634. package/dist/ai-context/index.d.ts +0 -6
  635. package/dist/ai-context/index.d.ts.map +0 -1
  636. package/dist/ai-context/index.js +0 -13
  637. package/dist/ai-context/index.js.map +0 -1
  638. package/dist/ai-context/manager.d.ts +0 -67
  639. package/dist/ai-context/manager.d.ts.map +0 -1
  640. package/dist/ai-context/manager.js +0 -104
  641. package/dist/ai-context/manager.js.map +0 -1
  642. package/dist/baseline/diff.d.ts +0 -32
  643. package/dist/baseline/diff.d.ts.map +0 -1
  644. package/dist/baseline/diff.js +0 -119
  645. package/dist/baseline/diff.js.map +0 -1
  646. package/dist/baseline/index.d.ts +0 -9
  647. package/dist/baseline/index.d.ts.map +0 -1
  648. package/dist/baseline/index.js +0 -19
  649. package/dist/baseline/index.js.map +0 -1
  650. package/dist/baseline/manager.d.ts +0 -67
  651. package/dist/baseline/manager.d.ts.map +0 -1
  652. package/dist/baseline/manager.js +0 -180
  653. package/dist/baseline/manager.js.map +0 -1
  654. package/dist/baseline/types.d.ts +0 -91
  655. package/dist/baseline/types.d.ts.map +0 -1
  656. package/dist/baseline/types.js +0 -12
  657. package/dist/baseline/types.js.map +0 -1
  658. package/dist/category-filter.d.ts +0 -125
  659. package/dist/category-filter.d.ts.map +0 -1
  660. package/dist/category-filter.js +0 -360
  661. package/dist/category-filter.js.map +0 -1
  662. package/dist/detect/ai-code/agent-tools.d.ts +0 -22
  663. package/dist/detect/ai-code/agent-tools.d.ts.map +0 -1
  664. package/dist/detect/ai-code/agent-tools.js +0 -1509
  665. package/dist/detect/ai-code/agent-tools.js.map +0 -1
  666. package/dist/detect/ai-code/byok-patterns.d.ts +0 -15
  667. package/dist/detect/ai-code/byok-patterns.d.ts.map +0 -1
  668. package/dist/detect/ai-code/byok-patterns.js +0 -313
  669. package/dist/detect/ai-code/byok-patterns.js.map +0 -1
  670. package/dist/detect/ai-code/endpoint-protection.d.ts +0 -38
  671. package/dist/detect/ai-code/endpoint-protection.d.ts.map +0 -1
  672. package/dist/detect/ai-code/endpoint-protection.js +0 -349
  673. package/dist/detect/ai-code/endpoint-protection.js.map +0 -1
  674. package/dist/detect/ai-code/execution-sinks.d.ts +0 -21
  675. package/dist/detect/ai-code/execution-sinks.d.ts.map +0 -1
  676. package/dist/detect/ai-code/execution-sinks.js +0 -1158
  677. package/dist/detect/ai-code/execution-sinks.js.map +0 -1
  678. package/dist/detect/ai-code/fingerprinting.d.ts +0 -10
  679. package/dist/detect/ai-code/fingerprinting.d.ts.map +0 -1
  680. package/dist/detect/ai-code/fingerprinting.js +0 -665
  681. package/dist/detect/ai-code/fingerprinting.js.map +0 -1
  682. package/dist/detect/ai-code/mcp-security.d.ts +0 -20
  683. package/dist/detect/ai-code/mcp-security.d.ts.map +0 -1
  684. package/dist/detect/ai-code/mcp-security.js +0 -880
  685. package/dist/detect/ai-code/mcp-security.js.map +0 -1
  686. package/dist/detect/ai-code/model-supply-chain.d.ts +0 -23
  687. package/dist/detect/ai-code/model-supply-chain.d.ts.map +0 -1
  688. package/dist/detect/ai-code/model-supply-chain.js +0 -447
  689. package/dist/detect/ai-code/model-supply-chain.js.map +0 -1
  690. package/dist/detect/ai-code/package-hallucination.d.ts +0 -22
  691. package/dist/detect/ai-code/package-hallucination.d.ts.map +0 -1
  692. package/dist/detect/ai-code/package-hallucination.js +0 -841
  693. package/dist/detect/ai-code/package-hallucination.js.map +0 -1
  694. package/dist/detect/ai-code/prompt-hygiene.d.ts +0 -22
  695. package/dist/detect/ai-code/prompt-hygiene.d.ts.map +0 -1
  696. package/dist/detect/ai-code/prompt-hygiene.js +0 -1177
  697. package/dist/detect/ai-code/prompt-hygiene.js.map +0 -1
  698. package/dist/detect/ai-code/rag-safety.d.ts +0 -24
  699. package/dist/detect/ai-code/rag-safety.d.ts.map +0 -1
  700. package/dist/detect/ai-code/rag-safety.js +0 -913
  701. package/dist/detect/ai-code/rag-safety.js.map +0 -1
  702. package/dist/detect/ai-code/schema-validation.d.ts +0 -28
  703. package/dist/detect/ai-code/schema-validation.d.ts.map +0 -1
  704. package/dist/detect/ai-code/schema-validation.js +0 -378
  705. package/dist/detect/ai-code/schema-validation.js.map +0 -1
  706. package/dist/detect/secrets/patterns.d.ts +0 -11
  707. package/dist/detect/secrets/patterns.d.ts.map +0 -1
  708. package/dist/detect/secrets/patterns.js +0 -518
  709. package/dist/detect/secrets/patterns.js.map +0 -1
  710. package/dist/detect/secrets/weak-crypto.d.ts +0 -10
  711. package/dist/detect/secrets/weak-crypto.d.ts.map +0 -1
  712. package/dist/detect/secrets/weak-crypto.js +0 -432
  713. package/dist/detect/secrets/weak-crypto.js.map +0 -1
  714. package/dist/detect/structural/auth-patterns.d.ts +0 -22
  715. package/dist/detect/structural/auth-patterns.d.ts.map +0 -1
  716. package/dist/detect/structural/auth-patterns.js +0 -533
  717. package/dist/detect/structural/auth-patterns.js.map +0 -1
  718. package/dist/detect/structural/dangerous-functions/child-process.d.ts +0 -16
  719. package/dist/detect/structural/dangerous-functions/child-process.d.ts.map +0 -1
  720. package/dist/detect/structural/dangerous-functions/child-process.js +0 -74
  721. package/dist/detect/structural/dangerous-functions/child-process.js.map +0 -1
  722. package/dist/detect/structural/dangerous-functions/dom-xss.d.ts +0 -34
  723. package/dist/detect/structural/dangerous-functions/dom-xss.d.ts.map +0 -1
  724. package/dist/detect/structural/dangerous-functions/dom-xss.js +0 -230
  725. package/dist/detect/structural/dangerous-functions/dom-xss.js.map +0 -1
  726. package/dist/detect/structural/dangerous-functions/index.d.ts +0 -16
  727. package/dist/detect/structural/dangerous-functions/index.d.ts.map +0 -1
  728. package/dist/detect/structural/dangerous-functions/index.js +0 -1193
  729. package/dist/detect/structural/dangerous-functions/index.js.map +0 -1
  730. package/dist/detect/structural/dangerous-functions/json-parse.d.ts +0 -31
  731. package/dist/detect/structural/dangerous-functions/json-parse.d.ts.map +0 -1
  732. package/dist/detect/structural/dangerous-functions/json-parse.js +0 -326
  733. package/dist/detect/structural/dangerous-functions/json-parse.js.map +0 -1
  734. package/dist/detect/structural/dangerous-functions/math-random.d.ts +0 -111
  735. package/dist/detect/structural/dangerous-functions/math-random.d.ts.map +0 -1
  736. package/dist/detect/structural/dangerous-functions/math-random.js +0 -684
  737. package/dist/detect/structural/dangerous-functions/math-random.js.map +0 -1
  738. package/dist/detect/structural/dangerous-functions/patterns.d.ts +0 -21
  739. package/dist/detect/structural/dangerous-functions/patterns.d.ts.map +0 -1
  740. package/dist/detect/structural/dangerous-functions/patterns.js +0 -163
  741. package/dist/detect/structural/dangerous-functions/patterns.js.map +0 -1
  742. package/dist/detect/structural/dangerous-functions/request-validation.d.ts +0 -13
  743. package/dist/detect/structural/dangerous-functions/request-validation.d.ts.map +0 -1
  744. package/dist/detect/structural/dangerous-functions/request-validation.js +0 -126
  745. package/dist/detect/structural/dangerous-functions/request-validation.js.map +0 -1
  746. package/dist/detect/structural/dangerous-functions/utils/control-flow.d.ts +0 -24
  747. package/dist/detect/structural/dangerous-functions/utils/control-flow.d.ts.map +0 -1
  748. package/dist/detect/structural/dangerous-functions/utils/control-flow.js +0 -70
  749. package/dist/detect/structural/dangerous-functions/utils/control-flow.js.map +0 -1
  750. package/dist/detect/structural/dangerous-functions/utils/helpers.d.ts +0 -31
  751. package/dist/detect/structural/dangerous-functions/utils/helpers.d.ts.map +0 -1
  752. package/dist/detect/structural/dangerous-functions/utils/helpers.js +0 -147
  753. package/dist/detect/structural/dangerous-functions/utils/helpers.js.map +0 -1
  754. package/dist/detect/structural/dangerous-functions/utils/index.d.ts +0 -9
  755. package/dist/detect/structural/dangerous-functions/utils/index.d.ts.map +0 -1
  756. package/dist/detect/structural/dangerous-functions/utils/index.js +0 -23
  757. package/dist/detect/structural/dangerous-functions/utils/index.js.map +0 -1
  758. package/dist/detect/structural/dangerous-functions/utils/schema-validation.d.ts +0 -22
  759. package/dist/detect/structural/dangerous-functions/utils/schema-validation.d.ts.map +0 -1
  760. package/dist/detect/structural/dangerous-functions/utils/schema-validation.js +0 -102
  761. package/dist/detect/structural/dangerous-functions/utils/schema-validation.js.map +0 -1
  762. package/dist/detect/structural/data-exposure.d.ts +0 -19
  763. package/dist/detect/structural/data-exposure.d.ts.map +0 -1
  764. package/dist/detect/structural/data-exposure.js +0 -262
  765. package/dist/detect/structural/data-exposure.js.map +0 -1
  766. package/dist/detect/structural/framework-checks.d.ts +0 -10
  767. package/dist/detect/structural/framework-checks.d.ts.map +0 -1
  768. package/dist/detect/structural/framework-checks.js +0 -389
  769. package/dist/detect/structural/framework-checks.js.map +0 -1
  770. package/dist/detect/structural/log-injection.d.ts +0 -18
  771. package/dist/detect/structural/log-injection.d.ts.map +0 -1
  772. package/dist/detect/structural/log-injection.js +0 -217
  773. package/dist/detect/structural/log-injection.js.map +0 -1
  774. package/dist/detect/structural/logic-gates.d.ts +0 -10
  775. package/dist/detect/structural/logic-gates.d.ts.map +0 -1
  776. package/dist/detect/structural/logic-gates.js +0 -227
  777. package/dist/detect/structural/logic-gates.js.map +0 -1
  778. package/dist/detect/structural/risky-imports.d.ts +0 -10
  779. package/dist/detect/structural/risky-imports.d.ts.map +0 -1
  780. package/dist/detect/structural/risky-imports.js +0 -168
  781. package/dist/detect/structural/risky-imports.js.map +0 -1
  782. package/dist/detect/structural/security-headers.d.ts +0 -18
  783. package/dist/detect/structural/security-headers.d.ts.map +0 -1
  784. package/dist/detect/structural/security-headers.js +0 -196
  785. package/dist/detect/structural/security-headers.js.map +0 -1
  786. package/dist/detect/structural/ssrf-detection.d.ts +0 -18
  787. package/dist/detect/structural/ssrf-detection.d.ts.map +0 -1
  788. package/dist/detect/structural/ssrf-detection.js +0 -263
  789. package/dist/detect/structural/ssrf-detection.js.map +0 -1
  790. package/dist/detect/structural/variables.d.ts +0 -11
  791. package/dist/detect/structural/variables.d.ts.map +0 -1
  792. package/dist/detect/structural/variables.js +0 -159
  793. package/dist/detect/structural/variables.js.map +0 -1
  794. package/dist/detect/structural/xxe-detection.d.ts +0 -18
  795. package/dist/detect/structural/xxe-detection.d.ts.map +0 -1
  796. package/dist/detect/structural/xxe-detection.js +0 -245
  797. package/dist/detect/structural/xxe-detection.js.map +0 -1
  798. package/dist/filtering/context-adjustments.d.ts +0 -23
  799. package/dist/filtering/context-adjustments.d.ts.map +0 -1
  800. package/dist/filtering/context-adjustments.js +0 -100
  801. package/dist/filtering/context-adjustments.js.map +0 -1
  802. package/dist/filtering/index.d.ts +0 -3
  803. package/dist/filtering/index.d.ts.map +0 -1
  804. package/dist/filtering/index.js +0 -8
  805. package/dist/filtering/index.js.map +0 -1
  806. package/dist/filtering/pipeline.d.ts +0 -48
  807. package/dist/filtering/pipeline.d.ts.map +0 -1
  808. package/dist/filtering/pipeline.js +0 -76
  809. package/dist/filtering/pipeline.js.map +0 -1
  810. package/dist/formatters/ai-context.d.ts +0 -23
  811. package/dist/formatters/ai-context.d.ts.map +0 -1
  812. package/dist/formatters/ai-context.js +0 -238
  813. package/dist/formatters/ai-context.js.map +0 -1
  814. package/dist/formatters/cli-terminal.d.ts +0 -65
  815. package/dist/formatters/cli-terminal.d.ts.map +0 -1
  816. package/dist/formatters/cli-terminal.js +0 -735
  817. package/dist/formatters/cli-terminal.js.map +0 -1
  818. package/dist/formatters/github-comment.d.ts +0 -41
  819. package/dist/formatters/github-comment.d.ts.map +0 -1
  820. package/dist/formatters/github-comment.js +0 -370
  821. package/dist/formatters/github-comment.js.map +0 -1
  822. package/dist/formatters/grouping.d.ts +0 -52
  823. package/dist/formatters/grouping.d.ts.map +0 -1
  824. package/dist/formatters/grouping.js +0 -152
  825. package/dist/formatters/grouping.js.map +0 -1
  826. package/dist/formatters/ide/claude-code.d.ts +0 -17
  827. package/dist/formatters/ide/claude-code.d.ts.map +0 -1
  828. package/dist/formatters/ide/claude-code.js +0 -94
  829. package/dist/formatters/ide/claude-code.js.map +0 -1
  830. package/dist/formatters/ide/cursor.d.ts +0 -13
  831. package/dist/formatters/ide/cursor.d.ts.map +0 -1
  832. package/dist/formatters/ide/cursor.js +0 -125
  833. package/dist/formatters/ide/cursor.js.map +0 -1
  834. package/dist/formatters/ide/index.d.ts +0 -62
  835. package/dist/formatters/ide/index.d.ts.map +0 -1
  836. package/dist/formatters/ide/index.js +0 -184
  837. package/dist/formatters/ide/index.js.map +0 -1
  838. package/dist/formatters/ide/windsurf.d.ts +0 -13
  839. package/dist/formatters/ide/windsurf.d.ts.map +0 -1
  840. package/dist/formatters/ide/windsurf.js +0 -117
  841. package/dist/formatters/ide/windsurf.js.map +0 -1
  842. package/dist/formatters/index.d.ts +0 -11
  843. package/dist/formatters/index.d.ts.map +0 -1
  844. package/dist/formatters/index.js +0 -54
  845. package/dist/formatters/index.js.map +0 -1
  846. package/dist/formatters/vscode-diagnostic.d.ts +0 -103
  847. package/dist/formatters/vscode-diagnostic.d.ts.map +0 -1
  848. package/dist/formatters/vscode-diagnostic.js +0 -151
  849. package/dist/formatters/vscode-diagnostic.js.map +0 -1
  850. package/dist/layer1/comments.d.ts +0 -11
  851. package/dist/layer1/comments.d.ts.map +0 -1
  852. package/dist/layer1/comments.js +0 -203
  853. package/dist/layer1/comments.js.map +0 -1
  854. package/dist/layer1/config-audit.d.ts +0 -11
  855. package/dist/layer1/config-audit.d.ts.map +0 -1
  856. package/dist/layer1/config-audit.js +0 -311
  857. package/dist/layer1/config-audit.js.map +0 -1
  858. package/dist/layer1/config-mcp-audit.d.ts +0 -23
  859. package/dist/layer1/config-mcp-audit.d.ts.map +0 -1
  860. package/dist/layer1/config-mcp-audit.js +0 -239
  861. package/dist/layer1/config-mcp-audit.js.map +0 -1
  862. package/dist/layer1/entropy.d.ts +0 -11
  863. package/dist/layer1/entropy.d.ts.map +0 -1
  864. package/dist/layer1/entropy.js +0 -741
  865. package/dist/layer1/entropy.js.map +0 -1
  866. package/dist/layer1/file-flags.d.ts +0 -10
  867. package/dist/layer1/file-flags.d.ts.map +0 -1
  868. package/dist/layer1/file-flags.js +0 -119
  869. package/dist/layer1/file-flags.js.map +0 -1
  870. package/dist/layer1/index.d.ts +0 -38
  871. package/dist/layer1/index.d.ts.map +0 -1
  872. package/dist/layer1/index.js +0 -170
  873. package/dist/layer1/index.js.map +0 -1
  874. package/dist/layer1/patterns.d.ts +0 -11
  875. package/dist/layer1/patterns.d.ts.map +0 -1
  876. package/dist/layer1/patterns.js +0 -512
  877. package/dist/layer1/patterns.js.map +0 -1
  878. package/dist/layer1/urls.d.ts +0 -11
  879. package/dist/layer1/urls.d.ts.map +0 -1
  880. package/dist/layer1/urls.js +0 -444
  881. package/dist/layer1/urls.js.map +0 -1
  882. package/dist/layer1/weak-crypto.d.ts +0 -10
  883. package/dist/layer1/weak-crypto.d.ts.map +0 -1
  884. package/dist/layer1/weak-crypto.js +0 -428
  885. package/dist/layer1/weak-crypto.js.map +0 -1
  886. package/dist/layer2/ai-agent-tools.d.ts +0 -22
  887. package/dist/layer2/ai-agent-tools.d.ts.map +0 -1
  888. package/dist/layer2/ai-agent-tools.js +0 -1490
  889. package/dist/layer2/ai-agent-tools.js.map +0 -1
  890. package/dist/layer2/ai-endpoint-protection.d.ts +0 -38
  891. package/dist/layer2/ai-endpoint-protection.d.ts.map +0 -1
  892. package/dist/layer2/ai-endpoint-protection.js +0 -346
  893. package/dist/layer2/ai-endpoint-protection.js.map +0 -1
  894. package/dist/layer2/ai-execution-sinks.d.ts +0 -21
  895. package/dist/layer2/ai-execution-sinks.d.ts.map +0 -1
  896. package/dist/layer2/ai-execution-sinks.js +0 -1155
  897. package/dist/layer2/ai-execution-sinks.js.map +0 -1
  898. package/dist/layer2/ai-fingerprinting.d.ts +0 -10
  899. package/dist/layer2/ai-fingerprinting.d.ts.map +0 -1
  900. package/dist/layer2/ai-fingerprinting.js +0 -650
  901. package/dist/layer2/ai-fingerprinting.js.map +0 -1
  902. package/dist/layer2/ai-mcp-security.d.ts +0 -20
  903. package/dist/layer2/ai-mcp-security.d.ts.map +0 -1
  904. package/dist/layer2/ai-mcp-security.js +0 -877
  905. package/dist/layer2/ai-mcp-security.js.map +0 -1
  906. package/dist/layer2/ai-package-hallucination.d.ts +0 -22
  907. package/dist/layer2/ai-package-hallucination.d.ts.map +0 -1
  908. package/dist/layer2/ai-package-hallucination.js +0 -828
  909. package/dist/layer2/ai-package-hallucination.js.map +0 -1
  910. package/dist/layer2/ai-prompt-hygiene.d.ts +0 -22
  911. package/dist/layer2/ai-prompt-hygiene.d.ts.map +0 -1
  912. package/dist/layer2/ai-prompt-hygiene.js +0 -1156
  913. package/dist/layer2/ai-prompt-hygiene.js.map +0 -1
  914. package/dist/layer2/ai-rag-safety.d.ts +0 -24
  915. package/dist/layer2/ai-rag-safety.d.ts.map +0 -1
  916. package/dist/layer2/ai-rag-safety.js +0 -910
  917. package/dist/layer2/ai-rag-safety.js.map +0 -1
  918. package/dist/layer2/ai-schema-validation.d.ts +0 -28
  919. package/dist/layer2/ai-schema-validation.d.ts.map +0 -1
  920. package/dist/layer2/ai-schema-validation.js +0 -375
  921. package/dist/layer2/ai-schema-validation.js.map +0 -1
  922. package/dist/layer2/auth-antipatterns.d.ts +0 -22
  923. package/dist/layer2/auth-antipatterns.d.ts.map +0 -1
  924. package/dist/layer2/auth-antipatterns.js +0 -522
  925. package/dist/layer2/auth-antipatterns.js.map +0 -1
  926. package/dist/layer2/byok-patterns.d.ts +0 -15
  927. package/dist/layer2/byok-patterns.d.ts.map +0 -1
  928. package/dist/layer2/byok-patterns.js +0 -302
  929. package/dist/layer2/byok-patterns.js.map +0 -1
  930. package/dist/layer2/dangerous-functions/child-process.d.ts +0 -16
  931. package/dist/layer2/dangerous-functions/child-process.d.ts.map +0 -1
  932. package/dist/layer2/dangerous-functions/child-process.js +0 -74
  933. package/dist/layer2/dangerous-functions/child-process.js.map +0 -1
  934. package/dist/layer2/dangerous-functions/dom-xss.d.ts +0 -34
  935. package/dist/layer2/dangerous-functions/dom-xss.d.ts.map +0 -1
  936. package/dist/layer2/dangerous-functions/dom-xss.js +0 -230
  937. package/dist/layer2/dangerous-functions/dom-xss.js.map +0 -1
  938. package/dist/layer2/dangerous-functions/index.d.ts +0 -16
  939. package/dist/layer2/dangerous-functions/index.d.ts.map +0 -1
  940. package/dist/layer2/dangerous-functions/index.js +0 -1152
  941. package/dist/layer2/dangerous-functions/index.js.map +0 -1
  942. package/dist/layer2/dangerous-functions/json-parse.d.ts +0 -31
  943. package/dist/layer2/dangerous-functions/json-parse.d.ts.map +0 -1
  944. package/dist/layer2/dangerous-functions/json-parse.js +0 -319
  945. package/dist/layer2/dangerous-functions/json-parse.js.map +0 -1
  946. package/dist/layer2/dangerous-functions/math-random.d.ts +0 -111
  947. package/dist/layer2/dangerous-functions/math-random.d.ts.map +0 -1
  948. package/dist/layer2/dangerous-functions/math-random.js +0 -684
  949. package/dist/layer2/dangerous-functions/math-random.js.map +0 -1
  950. package/dist/layer2/dangerous-functions/patterns.d.ts +0 -21
  951. package/dist/layer2/dangerous-functions/patterns.d.ts.map +0 -1
  952. package/dist/layer2/dangerous-functions/patterns.js +0 -163
  953. package/dist/layer2/dangerous-functions/patterns.js.map +0 -1
  954. package/dist/layer2/dangerous-functions/request-validation.d.ts +0 -13
  955. package/dist/layer2/dangerous-functions/request-validation.d.ts.map +0 -1
  956. package/dist/layer2/dangerous-functions/request-validation.js +0 -119
  957. package/dist/layer2/dangerous-functions/request-validation.js.map +0 -1
  958. package/dist/layer2/dangerous-functions/utils/control-flow.d.ts +0 -24
  959. package/dist/layer2/dangerous-functions/utils/control-flow.d.ts.map +0 -1
  960. package/dist/layer2/dangerous-functions/utils/control-flow.js +0 -70
  961. package/dist/layer2/dangerous-functions/utils/control-flow.js.map +0 -1
  962. package/dist/layer2/dangerous-functions/utils/helpers.d.ts +0 -31
  963. package/dist/layer2/dangerous-functions/utils/helpers.d.ts.map +0 -1
  964. package/dist/layer2/dangerous-functions/utils/helpers.js +0 -147
  965. package/dist/layer2/dangerous-functions/utils/helpers.js.map +0 -1
  966. package/dist/layer2/dangerous-functions/utils/index.d.ts +0 -9
  967. package/dist/layer2/dangerous-functions/utils/index.d.ts.map +0 -1
  968. package/dist/layer2/dangerous-functions/utils/index.js +0 -23
  969. package/dist/layer2/dangerous-functions/utils/index.js.map +0 -1
  970. package/dist/layer2/dangerous-functions/utils/schema-validation.d.ts +0 -22
  971. package/dist/layer2/dangerous-functions/utils/schema-validation.d.ts.map +0 -1
  972. package/dist/layer2/dangerous-functions/utils/schema-validation.js +0 -102
  973. package/dist/layer2/dangerous-functions/utils/schema-validation.js.map +0 -1
  974. package/dist/layer2/data-exposure.d.ts +0 -19
  975. package/dist/layer2/data-exposure.d.ts.map +0 -1
  976. package/dist/layer2/data-exposure.js +0 -255
  977. package/dist/layer2/data-exposure.js.map +0 -1
  978. package/dist/layer2/framework-checks.d.ts +0 -10
  979. package/dist/layer2/framework-checks.d.ts.map +0 -1
  980. package/dist/layer2/framework-checks.js +0 -384
  981. package/dist/layer2/framework-checks.js.map +0 -1
  982. package/dist/layer2/index.d.ts +0 -74
  983. package/dist/layer2/index.d.ts.map +0 -1
  984. package/dist/layer2/index.js +0 -544
  985. package/dist/layer2/index.js.map +0 -1
  986. package/dist/layer2/log-injection.d.ts +0 -18
  987. package/dist/layer2/log-injection.d.ts.map +0 -1
  988. package/dist/layer2/log-injection.js +0 -214
  989. package/dist/layer2/log-injection.js.map +0 -1
  990. package/dist/layer2/logic-gates.d.ts +0 -10
  991. package/dist/layer2/logic-gates.d.ts.map +0 -1
  992. package/dist/layer2/logic-gates.js +0 -220
  993. package/dist/layer2/logic-gates.js.map +0 -1
  994. package/dist/layer2/model-supply-chain.d.ts +0 -23
  995. package/dist/layer2/model-supply-chain.d.ts.map +0 -1
  996. package/dist/layer2/model-supply-chain.js +0 -444
  997. package/dist/layer2/model-supply-chain.js.map +0 -1
  998. package/dist/layer2/risky-imports.d.ts +0 -10
  999. package/dist/layer2/risky-imports.d.ts.map +0 -1
  1000. package/dist/layer2/risky-imports.js +0 -165
  1001. package/dist/layer2/risky-imports.js.map +0 -1
  1002. package/dist/layer2/security-headers.d.ts +0 -18
  1003. package/dist/layer2/security-headers.d.ts.map +0 -1
  1004. package/dist/layer2/security-headers.js +0 -187
  1005. package/dist/layer2/security-headers.js.map +0 -1
  1006. package/dist/layer2/ssrf-detection.d.ts +0 -18
  1007. package/dist/layer2/ssrf-detection.d.ts.map +0 -1
  1008. package/dist/layer2/ssrf-detection.js +0 -252
  1009. package/dist/layer2/ssrf-detection.js.map +0 -1
  1010. package/dist/layer2/variables.d.ts +0 -11
  1011. package/dist/layer2/variables.d.ts.map +0 -1
  1012. package/dist/layer2/variables.js +0 -156
  1013. package/dist/layer2/variables.js.map +0 -1
  1014. package/dist/layer2/xxe-detection.d.ts +0 -18
  1015. package/dist/layer2/xxe-detection.d.ts.map +0 -1
  1016. package/dist/layer2/xxe-detection.js +0 -242
  1017. package/dist/layer2/xxe-detection.js.map +0 -1
  1018. package/dist/layer3/anthropic/auto-dismiss.d.ts +0 -24
  1019. package/dist/layer3/anthropic/auto-dismiss.d.ts.map +0 -1
  1020. package/dist/layer3/anthropic/auto-dismiss.js +0 -199
  1021. package/dist/layer3/anthropic/auto-dismiss.js.map +0 -1
  1022. package/dist/layer3/anthropic/clients.d.ts +0 -44
  1023. package/dist/layer3/anthropic/clients.d.ts.map +0 -1
  1024. package/dist/layer3/anthropic/clients.js +0 -81
  1025. package/dist/layer3/anthropic/clients.js.map +0 -1
  1026. package/dist/layer3/anthropic/index.d.ts +0 -41
  1027. package/dist/layer3/anthropic/index.d.ts.map +0 -1
  1028. package/dist/layer3/anthropic/index.js +0 -141
  1029. package/dist/layer3/anthropic/index.js.map +0 -1
  1030. package/dist/layer3/anthropic/prompts/index.d.ts +0 -8
  1031. package/dist/layer3/anthropic/prompts/index.d.ts.map +0 -1
  1032. package/dist/layer3/anthropic/prompts/index.js +0 -16
  1033. package/dist/layer3/anthropic/prompts/index.js.map +0 -1
  1034. package/dist/layer3/anthropic/prompts/modules/ai-patterns.d.ts +0 -19
  1035. package/dist/layer3/anthropic/prompts/modules/ai-patterns.d.ts.map +0 -1
  1036. package/dist/layer3/anthropic/prompts/modules/ai-patterns.js +0 -156
  1037. package/dist/layer3/anthropic/prompts/modules/ai-patterns.js.map +0 -1
  1038. package/dist/layer3/anthropic/prompts/modules/auth-access.d.ts +0 -9
  1039. package/dist/layer3/anthropic/prompts/modules/auth-access.d.ts.map +0 -1
  1040. package/dist/layer3/anthropic/prompts/modules/auth-access.js +0 -25
  1041. package/dist/layer3/anthropic/prompts/modules/auth-access.js.map +0 -1
  1042. package/dist/layer3/anthropic/prompts/modules/common.d.ts +0 -11
  1043. package/dist/layer3/anthropic/prompts/modules/common.d.ts.map +0 -1
  1044. package/dist/layer3/anthropic/prompts/modules/common.js +0 -152
  1045. package/dist/layer3/anthropic/prompts/modules/common.js.map +0 -1
  1046. package/dist/layer3/anthropic/prompts/modules/index.d.ts +0 -54
  1047. package/dist/layer3/anthropic/prompts/modules/index.d.ts.map +0 -1
  1048. package/dist/layer3/anthropic/prompts/modules/index.js +0 -185
  1049. package/dist/layer3/anthropic/prompts/modules/index.js.map +0 -1
  1050. package/dist/layer3/anthropic/prompts/modules/owasp-classic.d.ts +0 -8
  1051. package/dist/layer3/anthropic/prompts/modules/owasp-classic.d.ts.map +0 -1
  1052. package/dist/layer3/anthropic/prompts/modules/owasp-classic.js +0 -84
  1053. package/dist/layer3/anthropic/prompts/modules/owasp-classic.js.map +0 -1
  1054. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.d.ts +0 -8
  1055. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.d.ts.map +0 -1
  1056. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.js +0 -68
  1057. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.js.map +0 -1
  1058. package/dist/layer3/anthropic/prompts/modules/xss-prompt.d.ts +0 -8
  1059. package/dist/layer3/anthropic/prompts/modules/xss-prompt.d.ts.map +0 -1
  1060. package/dist/layer3/anthropic/prompts/modules/xss-prompt.js +0 -22
  1061. package/dist/layer3/anthropic/prompts/modules/xss-prompt.js.map +0 -1
  1062. package/dist/layer3/anthropic/prompts/semantic-analysis.d.ts +0 -15
  1063. package/dist/layer3/anthropic/prompts/semantic-analysis.d.ts.map +0 -1
  1064. package/dist/layer3/anthropic/prompts/semantic-analysis.js +0 -169
  1065. package/dist/layer3/anthropic/prompts/semantic-analysis.js.map +0 -1
  1066. package/dist/layer3/anthropic/prompts/validation.d.ts +0 -18
  1067. package/dist/layer3/anthropic/prompts/validation.d.ts.map +0 -1
  1068. package/dist/layer3/anthropic/prompts/validation.js +0 -25
  1069. package/dist/layer3/anthropic/prompts/validation.js.map +0 -1
  1070. package/dist/layer3/anthropic/providers/anthropic.d.ts +0 -21
  1071. package/dist/layer3/anthropic/providers/anthropic.d.ts.map +0 -1
  1072. package/dist/layer3/anthropic/providers/anthropic.js +0 -269
  1073. package/dist/layer3/anthropic/providers/anthropic.js.map +0 -1
  1074. package/dist/layer3/anthropic/providers/index.d.ts +0 -8
  1075. package/dist/layer3/anthropic/providers/index.d.ts.map +0 -1
  1076. package/dist/layer3/anthropic/providers/index.js +0 -15
  1077. package/dist/layer3/anthropic/providers/index.js.map +0 -1
  1078. package/dist/layer3/anthropic/providers/openai.d.ts +0 -18
  1079. package/dist/layer3/anthropic/providers/openai.d.ts.map +0 -1
  1080. package/dist/layer3/anthropic/providers/openai.js +0 -343
  1081. package/dist/layer3/anthropic/providers/openai.js.map +0 -1
  1082. package/dist/layer3/anthropic/request-builder.d.ts +0 -27
  1083. package/dist/layer3/anthropic/request-builder.d.ts.map +0 -1
  1084. package/dist/layer3/anthropic/request-builder.js +0 -150
  1085. package/dist/layer3/anthropic/request-builder.js.map +0 -1
  1086. package/dist/layer3/anthropic/types.d.ts +0 -88
  1087. package/dist/layer3/anthropic/types.d.ts.map +0 -1
  1088. package/dist/layer3/anthropic/types.js +0 -38
  1089. package/dist/layer3/anthropic/types.js.map +0 -1
  1090. package/dist/layer3/anthropic/utils/context-extractor.d.ts +0 -55
  1091. package/dist/layer3/anthropic/utils/context-extractor.d.ts.map +0 -1
  1092. package/dist/layer3/anthropic/utils/context-extractor.js +0 -161
  1093. package/dist/layer3/anthropic/utils/context-extractor.js.map +0 -1
  1094. package/dist/layer3/anthropic/utils/index.d.ts +0 -11
  1095. package/dist/layer3/anthropic/utils/index.d.ts.map +0 -1
  1096. package/dist/layer3/anthropic/utils/index.js +0 -27
  1097. package/dist/layer3/anthropic/utils/index.js.map +0 -1
  1098. package/dist/layer3/anthropic/utils/path-helpers.d.ts +0 -21
  1099. package/dist/layer3/anthropic/utils/path-helpers.d.ts.map +0 -1
  1100. package/dist/layer3/anthropic/utils/path-helpers.js +0 -69
  1101. package/dist/layer3/anthropic/utils/path-helpers.js.map +0 -1
  1102. package/dist/layer3/anthropic/utils/response-parser.d.ts +0 -40
  1103. package/dist/layer3/anthropic/utils/response-parser.d.ts.map +0 -1
  1104. package/dist/layer3/anthropic/utils/response-parser.js +0 -285
  1105. package/dist/layer3/anthropic/utils/response-parser.js.map +0 -1
  1106. package/dist/layer3/anthropic/utils/retry.d.ts +0 -15
  1107. package/dist/layer3/anthropic/utils/retry.d.ts.map +0 -1
  1108. package/dist/layer3/anthropic/utils/retry.js +0 -62
  1109. package/dist/layer3/anthropic/utils/retry.js.map +0 -1
  1110. package/dist/layer3/index.d.ts +0 -27
  1111. package/dist/layer3/index.d.ts.map +0 -1
  1112. package/dist/layer3/index.js +0 -150
  1113. package/dist/layer3/index.js.map +0 -1
  1114. package/dist/layer3/osv-check.d.ts +0 -75
  1115. package/dist/layer3/osv-check.d.ts.map +0 -1
  1116. package/dist/layer3/osv-check.js +0 -308
  1117. package/dist/layer3/osv-check.js.map +0 -1
  1118. package/dist/layer3/package-check.d.ts +0 -63
  1119. package/dist/layer3/package-check.d.ts.map +0 -1
  1120. package/dist/layer3/package-check.js +0 -508
  1121. package/dist/layer3/package-check.js.map +0 -1
  1122. package/dist/model/cross-file-taint.d.ts +0 -40
  1123. package/dist/model/cross-file-taint.d.ts.map +0 -1
  1124. package/dist/model/cross-file-taint.js +0 -290
  1125. package/dist/model/cross-file-taint.js.map +0 -1
  1126. package/dist/model/function-classifier.d.ts +0 -32
  1127. package/dist/model/function-classifier.d.ts.map +0 -1
  1128. package/dist/model/function-classifier.js +0 -143
  1129. package/dist/model/function-classifier.js.map +0 -1
  1130. package/dist/model/sanitiser-detection.d.ts +0 -27
  1131. package/dist/model/sanitiser-detection.d.ts.map +0 -1
  1132. package/dist/model/sanitiser-detection.js +0 -224
  1133. package/dist/model/sanitiser-detection.js.map +0 -1
  1134. package/dist/model/sink-matcher.d.ts +0 -17
  1135. package/dist/model/sink-matcher.d.ts.map +0 -1
  1136. package/dist/model/sink-matcher.js +0 -141
  1137. package/dist/model/sink-matcher.js.map +0 -1
  1138. package/dist/model/sink-patterns.d.ts +0 -19
  1139. package/dist/model/sink-patterns.d.ts.map +0 -1
  1140. package/dist/model/sink-patterns.js +0 -88
  1141. package/dist/model/sink-patterns.js.map +0 -1
  1142. package/dist/model/source-discovery.d.ts +0 -15
  1143. package/dist/model/source-discovery.d.ts.map +0 -1
  1144. package/dist/model/source-discovery.js +0 -170
  1145. package/dist/model/source-discovery.js.map +0 -1
  1146. package/dist/model/taint-tracker.d.ts +0 -21
  1147. package/dist/model/taint-tracker.d.ts.map +0 -1
  1148. package/dist/model/taint-tracker.js +0 -281
  1149. package/dist/model/taint-tracker.js.map +0 -1
  1150. package/dist/modes/incremental.d.ts +0 -66
  1151. package/dist/modes/incremental.d.ts.map +0 -1
  1152. package/dist/modes/incremental.js +0 -200
  1153. package/dist/modes/incremental.js.map +0 -1
  1154. package/dist/rules/framework-fixes.d.ts +0 -48
  1155. package/dist/rules/framework-fixes.d.ts.map +0 -1
  1156. package/dist/rules/framework-fixes.js +0 -439
  1157. package/dist/rules/framework-fixes.js.map +0 -1
  1158. package/dist/rules/index.d.ts +0 -8
  1159. package/dist/rules/index.d.ts.map +0 -1
  1160. package/dist/rules/index.js +0 -18
  1161. package/dist/rules/index.js.map +0 -1
  1162. package/dist/rules/metadata.d.ts +0 -43
  1163. package/dist/rules/metadata.d.ts.map +0 -1
  1164. package/dist/rules/metadata.js +0 -800
  1165. package/dist/rules/metadata.js.map +0 -1
  1166. package/dist/score/auto-dismiss.d.ts +0 -28
  1167. package/dist/score/auto-dismiss.d.ts.map +0 -1
  1168. package/dist/score/auto-dismiss.js +0 -200
  1169. package/dist/score/auto-dismiss.js.map +0 -1
  1170. package/dist/suppression/config-loader.d.ts +0 -74
  1171. package/dist/suppression/config-loader.d.ts.map +0 -1
  1172. package/dist/suppression/config-loader.js +0 -424
  1173. package/dist/suppression/config-loader.js.map +0 -1
  1174. package/dist/suppression/hash.d.ts +0 -48
  1175. package/dist/suppression/hash.d.ts.map +0 -1
  1176. package/dist/suppression/hash.js +0 -88
  1177. package/dist/suppression/hash.js.map +0 -1
  1178. package/dist/suppression/index.d.ts +0 -11
  1179. package/dist/suppression/index.d.ts.map +0 -1
  1180. package/dist/suppression/index.js +0 -39
  1181. package/dist/suppression/index.js.map +0 -1
  1182. package/dist/suppression/inline-parser.d.ts +0 -39
  1183. package/dist/suppression/inline-parser.d.ts.map +0 -1
  1184. package/dist/suppression/inline-parser.js +0 -218
  1185. package/dist/suppression/inline-parser.js.map +0 -1
  1186. package/dist/suppression/manager.d.ts +0 -94
  1187. package/dist/suppression/manager.d.ts.map +0 -1
  1188. package/dist/suppression/manager.js +0 -292
  1189. package/dist/suppression/manager.js.map +0 -1
  1190. package/dist/suppression/types.d.ts +0 -151
  1191. package/dist/suppression/types.d.ts.map +0 -1
  1192. package/dist/suppression/types.js +0 -28
  1193. package/dist/suppression/types.js.map +0 -1
  1194. package/dist/types.d.ts +0 -331
  1195. package/dist/types.d.ts.map +0 -1
  1196. package/dist/types.js +0 -124
  1197. package/dist/types.js.map +0 -1
  1198. package/dist/utils/auth-helper-detector.d.ts +0 -56
  1199. package/dist/utils/auth-helper-detector.d.ts.map +0 -1
  1200. package/dist/utils/auth-helper-detector.js +0 -360
  1201. package/dist/utils/auth-helper-detector.js.map +0 -1
  1202. package/dist/utils/code-analysis.d.ts +0 -39
  1203. package/dist/utils/code-analysis.d.ts.map +0 -1
  1204. package/dist/utils/code-analysis.js +0 -159
  1205. package/dist/utils/code-analysis.js.map +0 -1
  1206. package/dist/utils/comment-analyzer.d.ts +0 -38
  1207. package/dist/utils/comment-analyzer.d.ts.map +0 -1
  1208. package/dist/utils/comment-analyzer.js +0 -218
  1209. package/dist/utils/comment-analyzer.js.map +0 -1
  1210. package/dist/utils/context-helpers.d.ts +0 -219
  1211. package/dist/utils/context-helpers.d.ts.map +0 -1
  1212. package/dist/utils/context-helpers.js +0 -886
  1213. package/dist/utils/context-helpers.js.map +0 -1
  1214. package/dist/utils/diff-detector.d.ts +0 -53
  1215. package/dist/utils/diff-detector.d.ts.map +0 -1
  1216. package/dist/utils/diff-detector.js +0 -104
  1217. package/dist/utils/diff-detector.js.map +0 -1
  1218. package/dist/utils/diff-parser.d.ts +0 -80
  1219. package/dist/utils/diff-parser.d.ts.map +0 -1
  1220. package/dist/utils/diff-parser.js +0 -202
  1221. package/dist/utils/diff-parser.js.map +0 -1
  1222. package/dist/utils/environment-context.d.ts +0 -76
  1223. package/dist/utils/environment-context.d.ts.map +0 -1
  1224. package/dist/utils/environment-context.js +0 -271
  1225. package/dist/utils/environment-context.js.map +0 -1
  1226. package/dist/utils/imported-auth-detector.d.ts +0 -37
  1227. package/dist/utils/imported-auth-detector.d.ts.map +0 -1
  1228. package/dist/utils/imported-auth-detector.js +0 -251
  1229. package/dist/utils/imported-auth-detector.js.map +0 -1
  1230. package/dist/utils/intent-detector.d.ts +0 -66
  1231. package/dist/utils/intent-detector.d.ts.map +0 -1
  1232. package/dist/utils/intent-detector.js +0 -282
  1233. package/dist/utils/intent-detector.js.map +0 -1
  1234. package/dist/utils/middleware-detector.d.ts +0 -55
  1235. package/dist/utils/middleware-detector.d.ts.map +0 -1
  1236. package/dist/utils/middleware-detector.js +0 -260
  1237. package/dist/utils/middleware-detector.js.map +0 -1
  1238. package/dist/utils/oauth-flow-detector.d.ts +0 -41
  1239. package/dist/utils/oauth-flow-detector.d.ts.map +0 -1
  1240. package/dist/utils/oauth-flow-detector.js +0 -202
  1241. package/dist/utils/oauth-flow-detector.js.map +0 -1
  1242. package/dist/utils/parsed-file.d.ts +0 -51
  1243. package/dist/utils/parsed-file.d.ts.map +0 -1
  1244. package/dist/utils/parsed-file.js +0 -95
  1245. package/dist/utils/parsed-file.js.map +0 -1
  1246. package/dist/utils/path-exclusions.d.ts +0 -55
  1247. package/dist/utils/path-exclusions.d.ts.map +0 -1
  1248. package/dist/utils/path-exclusions.js +0 -224
  1249. package/dist/utils/path-exclusions.js.map +0 -1
  1250. package/dist/utils/project-context-builder.d.ts +0 -119
  1251. package/dist/utils/project-context-builder.d.ts.map +0 -1
  1252. package/dist/utils/project-context-builder.js +0 -534
  1253. package/dist/utils/project-context-builder.js.map +0 -1
  1254. package/dist/utils/registry-clients.d.ts +0 -93
  1255. package/dist/utils/registry-clients.d.ts.map +0 -1
  1256. package/dist/utils/registry-clients.js +0 -273
  1257. package/dist/utils/registry-clients.js.map +0 -1
  1258. package/dist/utils/route-hierarchy.d.ts +0 -50
  1259. package/dist/utils/route-hierarchy.d.ts.map +0 -1
  1260. package/dist/utils/route-hierarchy.js +0 -226
  1261. package/dist/utils/route-hierarchy.js.map +0 -1
  1262. package/dist/utils/schema-semantics.d.ts +0 -45
  1263. package/dist/utils/schema-semantics.d.ts.map +0 -1
  1264. package/dist/utils/schema-semantics.js +0 -193
  1265. package/dist/utils/schema-semantics.js.map +0 -1
  1266. package/dist/utils/trpc-analyzer.d.ts +0 -78
  1267. package/dist/utils/trpc-analyzer.d.ts.map +0 -1
  1268. package/dist/utils/trpc-analyzer.js +0 -297
  1269. package/dist/utils/trpc-analyzer.js.map +0 -1
  1270. package/src/__tests__/context-engine/cross-file-taint.test.ts +0 -284
  1271. package/src/__tests__/context-engine/function-classifier.test.ts +0 -146
  1272. package/src/__tests__/context-engine/integration.test.ts +0 -320
  1273. package/src/__tests__/context-engine/sanitiser-detection.test.ts +0 -187
  1274. package/src/__tests__/context-engine/sink-matcher.test.ts +0 -251
  1275. package/src/__tests__/context-engine/source-discovery.test.ts +0 -186
  1276. package/src/__tests__/context-engine/taint-tracker.test.ts +0 -182
  1277. package/src/__tests__/snapshots/__snapshots__/anthropic-validation-refactor.test.ts.snap +0 -750
  1278. package/src/__tests__/snapshots/__snapshots__/dangerous-functions-refactor.test.ts.snap +0 -555
  1279. package/src/__tests__/snapshots/anthropic-validation-refactor.test.ts +0 -321
  1280. package/src/__tests__/snapshots/dangerous-functions-refactor.test.ts +0 -439
  1281. package/src/detect/ai-code/agent-tools.ts +0 -1662
  1282. package/src/detect/ai-code/byok-patterns.ts +0 -354
  1283. package/src/detect/ai-code/endpoint-protection.ts +0 -406
  1284. package/src/detect/ai-code/execution-sinks.ts +0 -1310
  1285. package/src/detect/ai-code/fingerprinting.ts +0 -774
  1286. package/src/detect/ai-code/mcp-security.ts +0 -937
  1287. package/src/detect/ai-code/model-supply-chain.ts +0 -535
  1288. package/src/detect/ai-code/package-hallucination.ts +0 -955
  1289. package/src/detect/ai-code/prompt-hygiene.ts +0 -1314
  1290. package/src/detect/ai-code/rag-safety.ts +0 -977
  1291. package/src/detect/ai-code/schema-validation.ts +0 -427
  1292. package/src/detect/secrets/patterns.ts +0 -561
  1293. package/src/detect/secrets/weak-crypto.ts +0 -485
  1294. package/src/detect/structural/__tests__/math-random-enhanced.test.ts +0 -405
  1295. package/src/detect/structural/auth-patterns.ts +0 -621
  1296. package/src/detect/structural/dangerous-functions/child-process.ts +0 -98
  1297. package/src/detect/structural/dangerous-functions/dom-xss.ts +0 -292
  1298. package/src/detect/structural/dangerous-functions/index.ts +0 -1556
  1299. package/src/detect/structural/dangerous-functions/json-parse.ts +0 -393
  1300. package/src/detect/structural/dangerous-functions/math-random.ts +0 -789
  1301. package/src/detect/structural/dangerous-functions/patterns.ts +0 -176
  1302. package/src/detect/structural/dangerous-functions/request-validation.ts +0 -153
  1303. package/src/detect/structural/dangerous-functions/utils/control-flow.ts +0 -35
  1304. package/src/detect/structural/dangerous-functions/utils/helpers.ts +0 -170
  1305. package/src/detect/structural/dangerous-functions/utils/index.ts +0 -25
  1306. package/src/detect/structural/dangerous-functions/utils/schema-validation.ts +0 -106
  1307. package/src/detect/structural/data-exposure.ts +0 -302
  1308. package/src/detect/structural/framework-checks.ts +0 -439
  1309. package/src/detect/structural/log-injection.ts +0 -254
  1310. package/src/detect/structural/logic-gates.ts +0 -256
  1311. package/src/detect/structural/risky-imports.ts +0 -197
  1312. package/src/detect/structural/security-headers.ts +0 -231
  1313. package/src/detect/structural/ssrf-detection.ts +0 -300
  1314. package/src/detect/structural/variables.ts +0 -177
  1315. package/src/detect/structural/xxe-detection.ts +0 -295
  1316. package/src/model/cross-file-taint.ts +0 -374
  1317. package/src/model/function-classifier.ts +0 -184
  1318. package/src/model/sanitiser-detection.ts +0 -268
  1319. package/src/model/sink-matcher.ts +0 -178
  1320. package/src/model/sink-patterns.ts +0 -109
  1321. package/src/model/source-discovery.ts +0 -209
  1322. package/src/model/taint-tracker.ts +0 -333
  1323. package/src/score/auto-dismiss.ts +0 -224
@@ -0,0 +1,1127 @@
1
+ /**
2
+ * Control Flow Graph Builder
3
+ *
4
+ * Builds an intra-procedural CFG for each function in a parsed AST.
5
+ * Uses the "pending-exits" pattern: each processStatement() call receives
6
+ * a list of nodes needing an outgoing edge and returns a new list of exits.
7
+ *
8
+ * Statement-level granularity. Expression-level flow (sub-expressions, short-circuit)
9
+ * is handled by the taint propagator within each CFGNode.
10
+ */
11
+
12
+ import type Parser from 'tree-sitter'
13
+ import { walkAST, type ParsedAST } from '../parse/ast'
14
+ import { computeDefUse } from './def-use'
15
+ import type {
16
+ CFG,
17
+ CFGNode,
18
+ CFGNodeKind,
19
+ CFGEdge,
20
+ CFGEdgeKind,
21
+ PendingExit,
22
+ LoopFrame,
23
+ SwitchFrame,
24
+ TryFrame,
25
+ } from './cfg-types'
26
+
27
+ // ============================================================================
28
+ // Public API
29
+ // ============================================================================
30
+
31
+ /**
32
+ * Build a CFG for a single function AST node.
33
+ * The function node should be one of: function_declaration, arrow_function,
34
+ * function_expression, method_definition, generator_function_declaration.
35
+ */
36
+ export function buildCFG(fnNode: Parser.SyntaxNode, fnName: string): CFG {
37
+ const builder = new CFGBuilder(fnNode, fnName)
38
+ return builder.build()
39
+ }
40
+
41
+ /**
42
+ * Build CFGs for all functions in a file. Returns a map keyed by function name,
43
+ * using the same naming conventions as call-graph.ts:
44
+ * - function_declaration → name
45
+ * - method_definition → ClassName.methodName
46
+ * - arrow/function_expression in variable_declarator → variable name
47
+ * - module-level code → '<module>'
48
+ */
49
+ export function buildFileCFGs(ast: ParsedAST): Map<string, CFG> {
50
+ const root = ast.tree.rootNode
51
+ const cfgs = new Map<string, CFG>()
52
+
53
+ const fnTypes = [
54
+ 'function_declaration',
55
+ 'generator_function_declaration',
56
+ 'method_definition',
57
+ 'arrow_function',
58
+ 'function_expression',
59
+ 'function_definition', // Python
60
+ ]
61
+
62
+ walkAST(root, (node) => {
63
+ // Python: decorated_definition wraps the function_definition
64
+ if (node.type === 'decorated_definition') {
65
+ const def = node.namedChildren.find(c => fnTypes.includes(c.type))
66
+ if (def) {
67
+ const name = getFunctionName(def)
68
+ if (name) {
69
+ cfgs.set(name, buildCFG(def, name))
70
+ }
71
+ }
72
+ return true // skip children — we already processed the inner definition
73
+ }
74
+
75
+ if (!fnTypes.includes(node.type)) return false
76
+
77
+ const name = getFunctionName(node)
78
+ if (name) {
79
+ cfgs.set(name, buildCFG(node, name))
80
+ }
81
+ return false
82
+ })
83
+
84
+ // Module-level code: gather top-level statements NOT inside a function/class
85
+ const moduleStatements = getModuleLevelStatements(root)
86
+ if (moduleStatements.length > 0) {
87
+ const builder = new CFGBuilder(root, '<module>')
88
+ cfgs.set('<module>', builder.buildFromStatements(moduleStatements))
89
+ }
90
+
91
+ return cfgs
92
+ }
93
+
94
+ // ============================================================================
95
+ // Query Helpers
96
+ // ============================================================================
97
+
98
+ /** Get all successor node ids from a given node. */
99
+ export function getSuccessors(cfg: CFG, nodeId: number): number[] {
100
+ const edges = cfg.edges.get(nodeId)
101
+ if (!edges) return []
102
+ return edges.map(e => e.to)
103
+ }
104
+
105
+ /** Get all predecessor node ids for a given node. */
106
+ export function getPredecessors(cfg: CFG, nodeId: number): number[] {
107
+ const edges = cfg.reverseEdges.get(nodeId)
108
+ if (!edges) return []
109
+ return edges.map(e => e.from)
110
+ }
111
+
112
+ /** Check if there's a path from `fromId` to `toId` in the CFG using BFS. */
113
+ export function isReachable(cfg: CFG, fromId: number, toId: number): boolean {
114
+ if (fromId === toId) return true
115
+ const visited = new Set<number>()
116
+ const queue = [fromId]
117
+ visited.add(fromId)
118
+
119
+ while (queue.length > 0) {
120
+ const current = queue.shift()!
121
+ const edges = cfg.edges.get(current)
122
+ if (!edges) continue
123
+ for (const edge of edges) {
124
+ if (edge.to === toId) return true
125
+ if (!visited.has(edge.to)) {
126
+ visited.add(edge.to)
127
+ queue.push(edge.to)
128
+ }
129
+ }
130
+ }
131
+ return false
132
+ }
133
+
134
+ // ============================================================================
135
+ // CFG Builder Class
136
+ // ============================================================================
137
+
138
+ class CFGBuilder {
139
+ private nextId = 2 // 0=entry, 1=exit
140
+ private nodes = new Map<number, CFGNode>()
141
+ private edges = new Map<number, CFGEdge[]>()
142
+ private reverseEdges = new Map<number, CFGEdge[]>()
143
+
144
+ private loopStack: LoopFrame[] = []
145
+ private switchStack: SwitchFrame[] = []
146
+ private tryStack: TryFrame[] = []
147
+ private _pendingLabel?: string
148
+
149
+ constructor(
150
+ private fnNode: Parser.SyntaxNode,
151
+ private fnName: string,
152
+ ) {}
153
+
154
+ build(): CFG {
155
+ const entry = this.createNode('entry', null, -1, 'ENTRY')
156
+ const exit = this.createNode('exit', null, -1, 'EXIT')
157
+
158
+ const body = this.getFunctionBody()
159
+ if (!body || body.namedChildren.length === 0) {
160
+ this.addEdge(entry.id, exit.id, 'normal')
161
+ } else {
162
+ let pending: PendingExit[] = [{ nodeId: entry.id, edgeKind: 'normal' }]
163
+ const statements = this.getStatements(body)
164
+
165
+ for (const stmt of statements) {
166
+ if (pending.length === 0) break
167
+ pending = this.processStatement(stmt, pending)
168
+ }
169
+
170
+ this.connectToNode(pending, exit.id)
171
+ }
172
+
173
+ return this.finalize()
174
+ }
175
+
176
+ /** Build a CFG from an explicit list of statements (for module-level code). */
177
+ buildFromStatements(statements: Parser.SyntaxNode[]): CFG {
178
+ const entry = this.createNode('entry', null, -1, 'ENTRY')
179
+ const exit = this.createNode('exit', null, -1, 'EXIT')
180
+
181
+ if (statements.length === 0) {
182
+ this.addEdge(entry.id, exit.id, 'normal')
183
+ } else {
184
+ let pending: PendingExit[] = [{ nodeId: entry.id, edgeKind: 'normal' }]
185
+
186
+ for (const stmt of statements) {
187
+ if (pending.length === 0) break
188
+ pending = this.processStatement(stmt, pending)
189
+ }
190
+
191
+ this.connectToNode(pending, exit.id)
192
+ }
193
+
194
+ return this.finalize()
195
+ }
196
+
197
+ private finalize(): CFG {
198
+ return {
199
+ nodes: this.nodes,
200
+ edges: this.edges,
201
+ reverseEdges: this.reverseEdges,
202
+ entryId: 0,
203
+ exitId: 1,
204
+ functionNode: this.fnNode,
205
+ functionName: this.fnName,
206
+ }
207
+ }
208
+
209
+ // ==========================================================================
210
+ // Statement Processing (returns new pending exits)
211
+ // ==========================================================================
212
+
213
+ private processStatement(node: Parser.SyntaxNode, entries: PendingExit[]): PendingExit[] {
214
+ switch (node.type) {
215
+ case 'if_statement':
216
+ case 'elif_clause': // Python: elif has same fields (condition/consequence) as if_statement
217
+ return this.processIf(node, entries)
218
+ case 'while_statement':
219
+ return this.processWhile(node, entries)
220
+ case 'for_statement':
221
+ // Python for_statement uses left/right fields (like for-in), not initializer/condition/increment
222
+ if (node.childForFieldName('left') && node.childForFieldName('right')) {
223
+ return this.processForIn(node, entries)
224
+ }
225
+ return this.processFor(node, entries)
226
+ case 'for_in_statement':
227
+ return this.processForIn(node, entries)
228
+ case 'do_statement':
229
+ return this.processDoWhile(node, entries)
230
+ case 'try_statement':
231
+ return this.processTry(node, entries)
232
+ case 'switch_statement':
233
+ return this.processSwitch(node, entries)
234
+ case 'return_statement':
235
+ return this.processReturn(node, entries)
236
+ case 'throw_statement':
237
+ case 'raise_statement':
238
+ return this.processThrow(node, entries)
239
+ case 'break_statement':
240
+ return this.processBreak(node, entries)
241
+ case 'continue_statement':
242
+ return this.processContinue(node, entries)
243
+ case 'labeled_statement':
244
+ return this.processLabeled(node, entries)
245
+ case 'statement_block':
246
+ case 'block':
247
+ return this.processBlock(node, entries)
248
+ case 'empty_statement':
249
+ case 'pass_statement':
250
+ return entries
251
+ case 'with_statement':
252
+ return this.processWith(node, entries)
253
+ default:
254
+ return this.processPlainStatement(node, entries)
255
+ }
256
+ }
257
+
258
+ // --------------------------------------------------------------------------
259
+ // Plain statement
260
+ // --------------------------------------------------------------------------
261
+
262
+ private processPlainStatement(node: Parser.SyntaxNode, entries: PendingExit[]): PendingExit[] {
263
+ const cfgNode = this.createStatementNode(node)
264
+ this.connectToNode(entries, cfgNode.id)
265
+ return [{ nodeId: cfgNode.id, edgeKind: 'normal' }]
266
+ }
267
+
268
+ // --------------------------------------------------------------------------
269
+ // Block
270
+ // --------------------------------------------------------------------------
271
+
272
+ private processBlock(node: Parser.SyntaxNode, entries: PendingExit[]): PendingExit[] {
273
+ let pending = entries
274
+ for (const stmt of node.namedChildren) {
275
+ if (pending.length === 0) break
276
+ pending = this.processStatement(stmt, pending)
277
+ }
278
+ return pending
279
+ }
280
+
281
+ // --------------------------------------------------------------------------
282
+ // If / else
283
+ // --------------------------------------------------------------------------
284
+
285
+ private processIf(node: Parser.SyntaxNode, entries: PendingExit[]): PendingExit[] {
286
+ const condition = node.childForFieldName('condition')
287
+ const consequence = node.childForFieldName('consequence')
288
+ const alternative = node.childForFieldName('alternative')
289
+
290
+ const condNode = this.createConditionNode(condition ?? node)
291
+ this.connectToNode(entries, condNode.id)
292
+
293
+ const allExits: PendingExit[] = []
294
+
295
+ // True branch
296
+ if (consequence) {
297
+ const trueExits = this.processStatement(consequence, [{ nodeId: condNode.id, edgeKind: 'true' }])
298
+ allExits.push(...trueExits)
299
+ } else {
300
+ allExits.push({ nodeId: condNode.id, edgeKind: 'true' })
301
+ }
302
+
303
+ // False branch
304
+ if (alternative) {
305
+ const altBody = alternative.type === 'else_clause'
306
+ ? (alternative.namedChildren.find(c => c.type === 'block') ?? alternative.namedChildren[0] ?? alternative)
307
+ : alternative
308
+ const falseExits = this.processStatement(altBody, [{ nodeId: condNode.id, edgeKind: 'false' }])
309
+ allExits.push(...falseExits)
310
+ } else {
311
+ allExits.push({ nodeId: condNode.id, edgeKind: 'false' })
312
+ }
313
+
314
+ // Python if/elif/else: when alternative is elif_clause, the else_clause is a
315
+ // separate sibling child (not reachable via childForFieldName('alternative')).
316
+ // We need to find and process it from the last elif's false exit.
317
+ if (alternative?.type === 'elif_clause') {
318
+ const elseClause = node.namedChildren.find(c => c.type === 'else_clause')
319
+ if (elseClause) {
320
+ // The else body is reachable when all elif conditions are false.
321
+ // Since elif_clause is processed recursively via processIf, the last elif's
322
+ // false exit is already in allExits. We need to replace the "no alternative"
323
+ // false exit from the deepest elif with the else body.
324
+ // However, since elif recursion already added its false exit to our allExits
325
+ // via processStatement, we process the else body from the elif chain's exits.
326
+ // For simplicity and correctness, we find the else body and note that the
327
+ // elif's false exits already flow into it via processIf recursion — but only
328
+ // if the elif_clause itself has no alternative. The deepest elif will have
329
+ // added a condNode false exit. We need to intercept that.
330
+ //
331
+ // Simpler approach: the else_clause attaches to the LAST condition's false exit.
332
+ // Since we recursed into elif_clause, its false exits are already in allExits.
333
+ // We replace the last condition's false exit with the else body exits.
334
+ const elseBody = elseClause.namedChildren.find(c => c.type === 'block')
335
+ ?? elseClause.namedChildren[0]
336
+ if (elseBody) {
337
+ // Find exits that came from condition false edges (from deepest elif)
338
+ // These are the exits where the condition was false and no else was found
339
+ const condFalseExits = allExits.filter(e => e.edgeKind === 'false')
340
+ if (condFalseExits.length > 0) {
341
+ // Remove the condition false exits from allExits
342
+ for (const cfe of condFalseExits) {
343
+ const idx = allExits.indexOf(cfe)
344
+ if (idx >= 0) allExits.splice(idx, 1)
345
+ }
346
+ // Process else body with those exits as entries
347
+ const elseExits = this.processStatement(elseBody, condFalseExits)
348
+ allExits.push(...elseExits)
349
+ }
350
+ }
351
+ }
352
+ }
353
+
354
+ return allExits
355
+ }
356
+
357
+ // --------------------------------------------------------------------------
358
+ // While
359
+ // --------------------------------------------------------------------------
360
+
361
+ private processWhile(node: Parser.SyntaxNode, entries: PendingExit[]): PendingExit[] {
362
+ const condition = node.childForFieldName('condition')
363
+ const body = node.childForFieldName('body')
364
+
365
+ const condNode = this.createConditionNode(condition ?? node)
366
+ this.connectToNode(entries, condNode.id)
367
+
368
+ const frame: LoopFrame = {
369
+ continueTarget: condNode.id,
370
+ label: this.consumeLabel(),
371
+ breakExits: [],
372
+ }
373
+ this.loopStack.push(frame)
374
+
375
+ const bodyExits = body
376
+ ? this.processStatement(body, [{ nodeId: condNode.id, edgeKind: 'true' }])
377
+ : [{ nodeId: condNode.id, edgeKind: 'true' as CFGEdgeKind }]
378
+
379
+ // Back-edge
380
+ this.connectToNode(bodyExits, condNode.id)
381
+
382
+ this.loopStack.pop()
383
+
384
+ return [
385
+ { nodeId: condNode.id, edgeKind: 'false' },
386
+ ...frame.breakExits,
387
+ ]
388
+ }
389
+
390
+ // --------------------------------------------------------------------------
391
+ // For
392
+ // --------------------------------------------------------------------------
393
+
394
+ private processFor(node: Parser.SyntaxNode, entries: PendingExit[]): PendingExit[] {
395
+ const init = node.childForFieldName('initializer')
396
+ const condition = node.childForFieldName('condition')
397
+ const increment = node.childForFieldName('increment')
398
+ const body = node.childForFieldName('body')
399
+
400
+ // Init
401
+ let pending = entries
402
+ if (init) {
403
+ const initNode = this.createStatementNode(init)
404
+ this.connectToNode(pending, initNode.id)
405
+ pending = [{ nodeId: initNode.id, edgeKind: 'normal' }]
406
+ }
407
+
408
+ // Condition
409
+ let condNode: CFGNode | null = null
410
+ if (condition) {
411
+ condNode = this.createConditionNode(condition)
412
+ this.connectToNode(pending, condNode.id)
413
+ }
414
+
415
+ // Update node (for continue targeting)
416
+ let updateNode: CFGNode | null = null
417
+ if (increment) {
418
+ updateNode = this.createStatementNode(increment)
419
+ }
420
+
421
+ // Continue target: update → condition → init (fallback)
422
+ const continueTarget = updateNode?.id ?? condNode?.id ?? pending[0]?.nodeId ?? 0
423
+ const frame: LoopFrame = {
424
+ continueTarget,
425
+ label: this.consumeLabel(),
426
+ breakExits: [],
427
+ }
428
+ this.loopStack.push(frame)
429
+
430
+ // Body entries
431
+ const bodyEntries: PendingExit[] = condNode
432
+ ? [{ nodeId: condNode.id, edgeKind: 'true' }]
433
+ : pending // for(;;) — no condition, enter body from init/entry
434
+
435
+ const bodyExits = body
436
+ ? this.processStatement(body, bodyEntries)
437
+ : bodyEntries
438
+
439
+ // Back-edge: body → update → condition
440
+ if (updateNode) {
441
+ this.connectToNode(bodyExits, updateNode.id)
442
+ if (condNode) {
443
+ this.addEdge(updateNode.id, condNode.id, 'normal')
444
+ } else {
445
+ // No condition — update loops directly to body entry
446
+ // For for(;; i++), connect update back to first body node
447
+ if (bodyEntries.length > 0) {
448
+ // The body was entered from `pending`. After update, re-enter the same way.
449
+ // For simplicity, loop update → itself (the first body statement will be reached)
450
+ for (const be of bodyEntries) {
451
+ this.addEdge(updateNode.id, be.nodeId, 'normal')
452
+ }
453
+ }
454
+ }
455
+ } else if (condNode) {
456
+ this.connectToNode(bodyExits, condNode.id)
457
+ } else {
458
+ // for(;;) — no condition, no update, body loops back
459
+ for (const be of bodyEntries) {
460
+ this.connectToNode(bodyExits, be.nodeId)
461
+ }
462
+ }
463
+
464
+ this.loopStack.pop()
465
+
466
+ const exits: PendingExit[] = [...frame.breakExits]
467
+ if (condNode) {
468
+ exits.push({ nodeId: condNode.id, edgeKind: 'false' })
469
+ }
470
+ return exits
471
+ }
472
+
473
+ // --------------------------------------------------------------------------
474
+ // For-in / For-of
475
+ // --------------------------------------------------------------------------
476
+
477
+ private processForIn(node: Parser.SyntaxNode, entries: PendingExit[]): PendingExit[] {
478
+ const left = node.childForFieldName('left')
479
+ const right = node.childForFieldName('right')
480
+ const body = node.childForFieldName('body')
481
+
482
+ const headerNode = this.createNode(
483
+ 'condition', node, node.startPosition.row + 1,
484
+ `for-${node.text.includes(' of ') ? 'of' : 'in'}`,
485
+ )
486
+
487
+ // Left side is always a def (identifier or destructuring pattern).
488
+ // tree-sitter strips the `const/let/var` keyword from the left field.
489
+ if (left) {
490
+ extractPatternDefs(left, headerNode.defs)
491
+ }
492
+ if (right) {
493
+ const { uses } = computeDefUse(right)
494
+ for (const u of uses) headerNode.uses.add(u)
495
+ }
496
+
497
+ this.connectToNode(entries, headerNode.id)
498
+
499
+ const frame: LoopFrame = {
500
+ continueTarget: headerNode.id,
501
+ label: this.consumeLabel(),
502
+ breakExits: [],
503
+ }
504
+ this.loopStack.push(frame)
505
+
506
+ const bodyExits = body
507
+ ? this.processStatement(body, [{ nodeId: headerNode.id, edgeKind: 'true' }])
508
+ : [{ nodeId: headerNode.id, edgeKind: 'true' as CFGEdgeKind }]
509
+
510
+ this.connectToNode(bodyExits, headerNode.id)
511
+
512
+ this.loopStack.pop()
513
+
514
+ return [
515
+ { nodeId: headerNode.id, edgeKind: 'false' },
516
+ ...frame.breakExits,
517
+ ]
518
+ }
519
+
520
+ // --------------------------------------------------------------------------
521
+ // Do-while
522
+ // --------------------------------------------------------------------------
523
+
524
+ private processDoWhile(node: Parser.SyntaxNode, entries: PendingExit[]): PendingExit[] {
525
+ const body = node.childForFieldName('body')
526
+ const condition = node.childForFieldName('condition')
527
+
528
+ // We need a merge point for the body entry (initial entry + back-edge from condition).
529
+ // Create a synthetic merge node.
530
+ const mergeNode = this.createNode('statement', null, node.startPosition.row + 1, 'do-merge')
531
+ this.connectToNode(entries, mergeNode.id)
532
+
533
+ const condNode = this.createConditionNode(condition ?? node)
534
+
535
+ const frame: LoopFrame = {
536
+ continueTarget: condNode.id,
537
+ label: this.consumeLabel(),
538
+ breakExits: [],
539
+ }
540
+ this.loopStack.push(frame)
541
+
542
+ const bodyExits = body
543
+ ? this.processStatement(body, [{ nodeId: mergeNode.id, edgeKind: 'normal' }])
544
+ : [{ nodeId: mergeNode.id, edgeKind: 'normal' as CFGEdgeKind }]
545
+
546
+ this.connectToNode(bodyExits, condNode.id)
547
+
548
+ // true → back to merge (re-enter body)
549
+ this.addEdge(condNode.id, mergeNode.id, 'true')
550
+
551
+ this.loopStack.pop()
552
+
553
+ return [
554
+ { nodeId: condNode.id, edgeKind: 'false' },
555
+ ...frame.breakExits,
556
+ ]
557
+ }
558
+
559
+ // --------------------------------------------------------------------------
560
+ // Try / catch / finally
561
+ // --------------------------------------------------------------------------
562
+
563
+ private processTry(node: Parser.SyntaxNode, entries: PendingExit[]): PendingExit[] {
564
+ const tryBody = node.childForFieldName('body')
565
+ const handler = node.childForFieldName('handler')
566
+ // JS: 'finalizer' field. Python: finally_clause is a named child (no field name).
567
+ const finalizer = node.childForFieldName('finalizer')
568
+ ?? node.namedChildren.find(c => c.type === 'finally_clause')?.namedChildren.find(c => c.type === 'block')
569
+
570
+ // Python: except_clause children instead of handler field
571
+ const exceptClauses = node.namedChildren.filter(
572
+ c => c.type === 'except_clause' || c.type === 'except_group_clause'
573
+ )
574
+
575
+ const tryEntry = this.createNode('statement', node, node.startPosition.row + 1, 'try-entry')
576
+ this.connectToNode(entries, tryEntry.id)
577
+
578
+ let catchEntryNode: CFGNode | null = null
579
+
580
+ if (handler) {
581
+ // JS: catch_clause
582
+ const param = handler.childForFieldName('parameter')
583
+ catchEntryNode = this.createNode('statement', handler, handler.startPosition.row + 1, 'catch-entry')
584
+ if (param) {
585
+ if (param.type === 'identifier') {
586
+ catchEntryNode.defs.add(param.text)
587
+ } else {
588
+ const { defs } = computeDefUse(param)
589
+ for (const d of defs) catchEntryNode.defs.add(d)
590
+ }
591
+ }
592
+
593
+ this.addEdge(tryEntry.id, catchEntryNode.id, 'exception')
594
+ this.tryStack.push({ catchEntry: catchEntryNode.id })
595
+ } else if (exceptClauses.length > 0) {
596
+ // Python: use first except clause as catch entry
597
+ const firstExcept = exceptClauses[0]
598
+ catchEntryNode = this.createNode('statement', firstExcept, firstExcept.startPosition.row + 1, 'except-entry')
599
+
600
+ // Extract the exception variable from as_pattern (e.g., except ValueError as e)
601
+ const asPattern = firstExcept.descendantsOfType('as_pattern')[0]
602
+ if (asPattern) {
603
+ const target = asPattern.namedChildren.find(c => c.type === 'as_pattern_target')
604
+ const ident = target?.namedChildren.find(c => c.type === 'identifier')
605
+ if (ident) catchEntryNode.defs.add(ident.text)
606
+ }
607
+
608
+ this.addEdge(tryEntry.id, catchEntryNode.id, 'exception')
609
+ this.tryStack.push({ catchEntry: catchEntryNode.id })
610
+ }
611
+
612
+ const tryExits = tryBody
613
+ ? this.processStatement(tryBody, [{ nodeId: tryEntry.id, edgeKind: 'normal' }])
614
+ : [{ nodeId: tryEntry.id, edgeKind: 'normal' as CFGEdgeKind }]
615
+
616
+ if (handler || exceptClauses.length > 0) {
617
+ this.tryStack.pop()
618
+ }
619
+
620
+ let catchExits: PendingExit[] = []
621
+ if (handler && catchEntryNode) {
622
+ // JS: catch_clause body
623
+ const catchBody = handler.childForFieldName('body')
624
+ catchExits = catchBody
625
+ ? this.processStatement(catchBody, [{ nodeId: catchEntryNode.id, edgeKind: 'normal' }])
626
+ : [{ nodeId: catchEntryNode.id, edgeKind: 'normal' as CFGEdgeKind }]
627
+ } else if (exceptClauses.length > 0 && catchEntryNode) {
628
+ // Python: walk except clause bodies
629
+ let pending: PendingExit[] = [{ nodeId: catchEntryNode.id, edgeKind: 'normal' }]
630
+ for (const ec of exceptClauses) {
631
+ const exceptBody = ec.namedChildren.find(c => c.type === 'block')
632
+ if (exceptBody) {
633
+ pending = this.processStatement(exceptBody, pending)
634
+ }
635
+ }
636
+ catchExits = pending
637
+ }
638
+
639
+ // Python: else clause (runs if no exception raised)
640
+ const elseClause = node.childForFieldName('alternative')
641
+ ?? node.namedChildren.find(c => c.type === 'else_clause')
642
+ if (elseClause) {
643
+ const elseBody = elseClause.type === 'else_clause'
644
+ ? (elseClause.namedChildren.find(c => c.type === 'block') ?? elseClause.namedChildren[0])
645
+ : elseClause
646
+ if (elseBody) {
647
+ const elseExits = this.processStatement(elseBody, tryExits)
648
+ // try exits are replaced by else exits
649
+ if (finalizer) {
650
+ const allBeforeFinally = [...elseExits, ...catchExits]
651
+ return this.processStatement(finalizer, allBeforeFinally)
652
+ }
653
+ return [...elseExits, ...catchExits]
654
+ }
655
+ }
656
+
657
+ if (finalizer) {
658
+ const allBeforeFinally = [...tryExits, ...catchExits]
659
+ return this.processStatement(finalizer, allBeforeFinally)
660
+ }
661
+
662
+ return [...tryExits, ...catchExits]
663
+ }
664
+
665
+ // --------------------------------------------------------------------------
666
+ // Switch
667
+ // --------------------------------------------------------------------------
668
+
669
+ private processSwitch(node: Parser.SyntaxNode, entries: PendingExit[]): PendingExit[] {
670
+ const discriminant = node.childForFieldName('value')
671
+ const body = node.childForFieldName('body')
672
+
673
+ const switchNode = this.createConditionNode(discriminant ?? node)
674
+ this.connectToNode(entries, switchNode.id)
675
+
676
+ const frame: SwitchFrame = { label: this.consumeLabel(), breakExits: [] }
677
+ this.switchStack.push(frame)
678
+
679
+ const cases = body
680
+ ? body.namedChildren.filter(c => c.type === 'switch_case' || c.type === 'switch_default')
681
+ : []
682
+
683
+ let hasDefault = false
684
+ let prevCaseExits: PendingExit[] = []
685
+
686
+ for (const caseNode of cases) {
687
+ const isDefault = caseNode.type === 'switch_default'
688
+ if (isDefault) hasDefault = true
689
+
690
+ const caseEntries: PendingExit[] = [
691
+ { nodeId: switchNode.id, edgeKind: isDefault ? 'normal' : 'true' },
692
+ ]
693
+
694
+ // Fallthrough from previous case
695
+ if (prevCaseExits.length > 0) {
696
+ for (const e of prevCaseExits) {
697
+ caseEntries.push({ nodeId: e.nodeId, edgeKind: 'fallthrough' })
698
+ }
699
+ }
700
+
701
+ // Case body: skip the case value expression nodes
702
+ const caseStatements = getCaseBodyStatements(caseNode)
703
+
704
+ let caseExits = caseEntries
705
+ for (const stmt of caseStatements) {
706
+ if (caseExits.length === 0) break
707
+ caseExits = this.processStatement(stmt, caseExits)
708
+ }
709
+
710
+ prevCaseExits = caseExits
711
+ }
712
+
713
+ this.switchStack.pop()
714
+
715
+ const exits = [...frame.breakExits, ...prevCaseExits]
716
+ if (!hasDefault) {
717
+ exits.push({ nodeId: switchNode.id, edgeKind: 'false' })
718
+ }
719
+
720
+ return exits
721
+ }
722
+
723
+ // --------------------------------------------------------------------------
724
+ // Return
725
+ // --------------------------------------------------------------------------
726
+
727
+ private processReturn(node: Parser.SyntaxNode, entries: PendingExit[]): PendingExit[] {
728
+ const cfgNode = this.createStatementNode(node)
729
+ this.connectToNode(entries, cfgNode.id)
730
+ this.addEdge(cfgNode.id, 1, 'return')
731
+ return []
732
+ }
733
+
734
+ // --------------------------------------------------------------------------
735
+ // Throw
736
+ // --------------------------------------------------------------------------
737
+
738
+ private processThrow(node: Parser.SyntaxNode, entries: PendingExit[]): PendingExit[] {
739
+ const cfgNode = this.createStatementNode(node)
740
+ this.connectToNode(entries, cfgNode.id)
741
+
742
+ if (this.tryStack.length > 0) {
743
+ const frame = this.tryStack[this.tryStack.length - 1]
744
+ this.addEdge(cfgNode.id, frame.catchEntry, 'throw')
745
+ } else {
746
+ this.addEdge(cfgNode.id, 1, 'throw')
747
+ }
748
+
749
+ return []
750
+ }
751
+
752
+ // --------------------------------------------------------------------------
753
+ // Break
754
+ // --------------------------------------------------------------------------
755
+
756
+ private processBreak(node: Parser.SyntaxNode, entries: PendingExit[]): PendingExit[] {
757
+ const cfgNode = this.createStatementNode(node)
758
+ this.connectToNode(entries, cfgNode.id)
759
+
760
+ const label = node.childForFieldName('label')?.text
761
+
762
+ if (label) {
763
+ for (let i = this.loopStack.length - 1; i >= 0; i--) {
764
+ if (this.loopStack[i].label === label) {
765
+ this.loopStack[i].breakExits.push({ nodeId: cfgNode.id, edgeKind: 'break' })
766
+ return []
767
+ }
768
+ }
769
+ for (let i = this.switchStack.length - 1; i >= 0; i--) {
770
+ if (this.switchStack[i].label === label) {
771
+ this.switchStack[i].breakExits.push({ nodeId: cfgNode.id, edgeKind: 'break' })
772
+ return []
773
+ }
774
+ }
775
+ }
776
+
777
+ // Unlabeled: target innermost loop or switch
778
+ const target = this.getInnermostBreakTarget(node)
779
+ if (target) {
780
+ target.breakExits.push({ nodeId: cfgNode.id, edgeKind: 'break' })
781
+ }
782
+
783
+ return []
784
+ }
785
+
786
+ // --------------------------------------------------------------------------
787
+ // Continue
788
+ // --------------------------------------------------------------------------
789
+
790
+ private processContinue(node: Parser.SyntaxNode, entries: PendingExit[]): PendingExit[] {
791
+ const cfgNode = this.createStatementNode(node)
792
+ this.connectToNode(entries, cfgNode.id)
793
+
794
+ const label = node.childForFieldName('label')?.text
795
+
796
+ if (label) {
797
+ for (let i = this.loopStack.length - 1; i >= 0; i--) {
798
+ if (this.loopStack[i].label === label) {
799
+ this.addEdge(cfgNode.id, this.loopStack[i].continueTarget, 'continue')
800
+ return []
801
+ }
802
+ }
803
+ }
804
+
805
+ if (this.loopStack.length > 0) {
806
+ const frame = this.loopStack[this.loopStack.length - 1]
807
+ this.addEdge(cfgNode.id, frame.continueTarget, 'continue')
808
+ }
809
+
810
+ return []
811
+ }
812
+
813
+ // --------------------------------------------------------------------------
814
+ // Labeled statement
815
+ // --------------------------------------------------------------------------
816
+
817
+ private processLabeled(node: Parser.SyntaxNode, entries: PendingExit[]): PendingExit[] {
818
+ const label = node.childForFieldName('label')?.text
819
+ const body = node.namedChildren.find(c => c !== node.childForFieldName('label'))
820
+
821
+ if (!body) return entries
822
+
823
+ // Set label BEFORE processing — loop/switch processors will consume it
824
+ if (label) {
825
+ this._pendingLabel = label
826
+ }
827
+
828
+ return this.processStatement(body, entries)
829
+ }
830
+
831
+ // --------------------------------------------------------------------------
832
+ // With statement (Python)
833
+ // --------------------------------------------------------------------------
834
+
835
+ private processWith(node: Parser.SyntaxNode, entries: PendingExit[]): PendingExit[] {
836
+ const cfgNode = this.createStatementNode(node)
837
+ this.connectToNode(entries, cfgNode.id)
838
+
839
+ const body = node.childForFieldName('body')
840
+ if (body) {
841
+ return this.processStatement(body, [{ nodeId: cfgNode.id, edgeKind: 'normal' }])
842
+ }
843
+ return [{ nodeId: cfgNode.id, edgeKind: 'normal' }]
844
+ }
845
+
846
+ private consumeLabel(): string | undefined {
847
+ const label = this._pendingLabel
848
+ this._pendingLabel = undefined
849
+ return label
850
+ }
851
+
852
+ // ==========================================================================
853
+ // Node Creation
854
+ // ==========================================================================
855
+
856
+ private createNode(
857
+ kind: CFGNodeKind,
858
+ astNode: Parser.SyntaxNode | null,
859
+ line: number,
860
+ label: string,
861
+ ): CFGNode {
862
+ const id = kind === 'entry' ? 0 : kind === 'exit' ? 1 : this.nextId++
863
+ const node: CFGNode = {
864
+ id,
865
+ kind,
866
+ astNode,
867
+ defs: new Set(),
868
+ uses: new Set(),
869
+ line,
870
+ label,
871
+ }
872
+ this.nodes.set(id, node)
873
+ return node
874
+ }
875
+
876
+ private createStatementNode(astNode: Parser.SyntaxNode): CFGNode {
877
+ const { defs, uses } = computeDefUse(astNode)
878
+ const node = this.createNode(
879
+ 'statement',
880
+ astNode,
881
+ astNode.startPosition.row + 1,
882
+ truncate(astNode.text, 40),
883
+ )
884
+ node.defs = defs
885
+ node.uses = uses
886
+ return node
887
+ }
888
+
889
+ private createConditionNode(astNode: Parser.SyntaxNode): CFGNode {
890
+ const { defs, uses } = computeDefUse(astNode)
891
+ const node = this.createNode(
892
+ 'condition',
893
+ astNode,
894
+ astNode.startPosition.row + 1,
895
+ `cond: ${truncate(astNode.text, 30)}`,
896
+ )
897
+ node.defs = defs
898
+ node.uses = uses
899
+ return node
900
+ }
901
+
902
+ // ==========================================================================
903
+ // Edge Helpers
904
+ // ==========================================================================
905
+
906
+ private addEdge(from: number, to: number, kind: CFGEdgeKind): void {
907
+ const edge: CFGEdge = { from, to, kind }
908
+
909
+ if (!this.edges.has(from)) this.edges.set(from, [])
910
+ this.edges.get(from)!.push(edge)
911
+
912
+ if (!this.reverseEdges.has(to)) this.reverseEdges.set(to, [])
913
+ this.reverseEdges.get(to)!.push(edge)
914
+ }
915
+
916
+ private connectToNode(exits: PendingExit[], targetId: number): void {
917
+ for (const exit of exits) {
918
+ this.addEdge(exit.nodeId, targetId, exit.edgeKind)
919
+ }
920
+ }
921
+
922
+ // ==========================================================================
923
+ // Utility Helpers
924
+ // ==========================================================================
925
+
926
+ private getFunctionBody(): Parser.SyntaxNode | null {
927
+ if (this.fnNode.type === 'program' || this.fnNode.type === 'module') return null // module-level uses buildFromStatements
928
+ return this.fnNode.childForFieldName('body')
929
+ }
930
+
931
+ private getStatements(body: Parser.SyntaxNode): Parser.SyntaxNode[] {
932
+ if (body.type === 'statement_block' || body.type === 'block') {
933
+ return body.namedChildren
934
+ }
935
+ return [body]
936
+ }
937
+
938
+ /** Determine the innermost break-target (loop or switch) by walking up the AST. */
939
+ private getInnermostBreakTarget(breakNode: Parser.SyntaxNode): LoopFrame | SwitchFrame | null {
940
+ const loopTypes = new Set([
941
+ 'while_statement', 'for_statement', 'for_in_statement', 'do_statement',
942
+ ])
943
+ // Python for_statement is already in the set — its name matches
944
+
945
+ let current = breakNode.parent
946
+ while (current) {
947
+ if (current.type === 'switch_statement' && this.switchStack.length > 0) {
948
+ return this.switchStack[this.switchStack.length - 1]
949
+ }
950
+ if (loopTypes.has(current.type) && this.loopStack.length > 0) {
951
+ return this.loopStack[this.loopStack.length - 1]
952
+ }
953
+ current = current.parent
954
+ }
955
+
956
+ // Fallback
957
+ if (this.switchStack.length > 0) return this.switchStack[this.switchStack.length - 1]
958
+ if (this.loopStack.length > 0) return this.loopStack[this.loopStack.length - 1]
959
+ return null
960
+ }
961
+ }
962
+
963
+ // ============================================================================
964
+ // Function Name Resolution (matches call-graph conventions)
965
+ // ============================================================================
966
+
967
+ function getFunctionName(node: Parser.SyntaxNode): string | null {
968
+ switch (node.type) {
969
+ case 'function_declaration':
970
+ case 'generator_function_declaration':
971
+ return node.childForFieldName('name')?.text ?? null
972
+
973
+ case 'method_definition': {
974
+ const methodName = node.childForFieldName('name')?.text
975
+ if (!methodName) return null
976
+ const className = getEnclosingClassName(node)
977
+ return className ? `${className}.${methodName}` : methodName
978
+ }
979
+
980
+ case 'function_definition': {
981
+ const name = node.childForFieldName('name')?.text
982
+ if (!name) return null
983
+ const className = getEnclosingClassName(node)
984
+ return className ? `${className}.${name}` : name
985
+ }
986
+
987
+ case 'arrow_function':
988
+ case 'function_expression': {
989
+ const parent = node.parent
990
+ if (parent?.type === 'variable_declarator') {
991
+ const nameNode = parent.childForFieldName('name')
992
+ if (nameNode?.type === 'identifier') return nameNode.text
993
+ }
994
+ if (parent?.type === 'assignment_expression') {
995
+ const left = parent.childForFieldName('left')
996
+ if (left?.type === 'identifier') return left.text
997
+ }
998
+ return null
999
+ }
1000
+
1001
+ default:
1002
+ return null
1003
+ }
1004
+ }
1005
+
1006
+ function getEnclosingClassName(node: Parser.SyntaxNode): string | null {
1007
+ let current = node.parent
1008
+ while (current) {
1009
+ if (current.type === 'class_declaration' || current.type === 'class' || current.type === 'class_definition') {
1010
+ return current.childForFieldName('name')?.text ?? null
1011
+ }
1012
+ // Python: decorated_definition wraps the class, check its definition child
1013
+ if (current.type === 'decorated_definition') {
1014
+ const def = current.childForFieldName('definition')
1015
+ if (def?.type === 'class_definition') {
1016
+ return def.childForFieldName('name')?.text ?? null
1017
+ }
1018
+ }
1019
+ current = current.parent
1020
+ }
1021
+ return null
1022
+ }
1023
+
1024
+ function getModuleLevelStatements(root: Parser.SyntaxNode): Parser.SyntaxNode[] {
1025
+ const fnTypes = new Set([
1026
+ 'function_declaration', 'generator_function_declaration', 'class_declaration',
1027
+ 'function_definition', 'class_definition', 'decorated_definition', // Python
1028
+ ])
1029
+
1030
+ return root.namedChildren.filter(child => {
1031
+ if (fnTypes.has(child.type)) return false
1032
+ if (child.type === 'import_statement') return false
1033
+ if (child.type === 'import_from_statement') return false // Python
1034
+ if (child.type === 'export_statement') {
1035
+ const decl = child.namedChildren[0]
1036
+ if (decl && fnTypes.has(decl.type)) return false
1037
+ }
1038
+ return true
1039
+ })
1040
+ }
1041
+
1042
+ /** Get the body statements from a switch case, skipping the case value expression. */
1043
+ function getCaseBodyStatements(caseNode: Parser.SyntaxNode): Parser.SyntaxNode[] {
1044
+ // switch_case children: value expression(s) + ":" + body statements
1045
+ // switch_default children: ":" + body statements
1046
+ // The "value" field contains the case expression, everything else is body
1047
+ if (caseNode.type === 'switch_default') {
1048
+ return caseNode.namedChildren
1049
+ }
1050
+
1051
+ // For switch_case, the first named child is the value, rest are body
1052
+ const value = caseNode.childForFieldName('value')
1053
+ return caseNode.namedChildren.filter(c => c !== value)
1054
+ }
1055
+
1056
+ // ============================================================================
1057
+ // Pattern Def Extraction (for for-of/for-in left side)
1058
+ // ============================================================================
1059
+
1060
+ /** Extract defined variable names from a pattern (identifier, array/object destructuring). */
1061
+ function extractPatternDefs(node: Parser.SyntaxNode, defs: Set<string>): void {
1062
+ switch (node.type) {
1063
+ case 'identifier':
1064
+ defs.add(node.text)
1065
+ return
1066
+ case 'array_pattern':
1067
+ for (const child of node.namedChildren) {
1068
+ extractPatternDefs(child, defs)
1069
+ }
1070
+ return
1071
+ case 'object_pattern':
1072
+ for (const prop of node.namedChildren) {
1073
+ if (prop.type === 'shorthand_property_identifier_pattern') {
1074
+ defs.add(prop.text)
1075
+ } else if (prop.type === 'pair_pattern') {
1076
+ const value = prop.childForFieldName('value')
1077
+ if (value) extractPatternDefs(value, defs)
1078
+ } else if (prop.type === 'rest_pattern' && prop.namedChildren[0]) {
1079
+ extractPatternDefs(prop.namedChildren[0], defs)
1080
+ }
1081
+ }
1082
+ return
1083
+ case 'rest_pattern':
1084
+ if (node.namedChildren[0]) extractPatternDefs(node.namedChildren[0], defs)
1085
+ return
1086
+ case 'assignment_pattern': {
1087
+ const left = node.childForFieldName('left')
1088
+ if (left) extractPatternDefs(left, defs)
1089
+ return
1090
+ }
1091
+ // Python tuple/list unpacking: for a, b in items / for [a, b] in items
1092
+ case 'pattern_list':
1093
+ case 'tuple_pattern':
1094
+ case 'list_pattern':
1095
+ case 'expression_list':
1096
+ case 'tuple':
1097
+ for (const child of node.namedChildren) {
1098
+ extractPatternDefs(child, defs)
1099
+ }
1100
+ return
1101
+ // Python: let/const declarations wrapping for-of
1102
+ case 'lexical_declaration':
1103
+ case 'variable_declaration':
1104
+ for (const child of node.namedChildren) {
1105
+ if (child.type === 'variable_declarator') {
1106
+ const nameNode = child.childForFieldName('name')
1107
+ if (nameNode) extractPatternDefs(nameNode, defs)
1108
+ }
1109
+ }
1110
+ return
1111
+ case 'list_splat_pattern':
1112
+ if (node.namedChildren[0]) extractPatternDefs(node.namedChildren[0], defs)
1113
+ return
1114
+ default:
1115
+ return
1116
+ }
1117
+ }
1118
+
1119
+ // ============================================================================
1120
+ // Utilities
1121
+ // ============================================================================
1122
+
1123
+ function truncate(text: string, maxLen: number): string {
1124
+ const oneLine = text.replace(/\n/g, ' ').replace(/\s+/g, ' ').trim()
1125
+ if (oneLine.length <= maxLen) return oneLine
1126
+ return oneLine.slice(0, maxLen - 3) + '...'
1127
+ }