@oculum/scanner 1.0.11 → 1.0.13

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 (1178) hide show
  1. package/dist/ai-context/index.d.ts +6 -0
  2. package/dist/ai-context/index.d.ts.map +1 -0
  3. package/dist/ai-context/index.js +13 -0
  4. package/dist/ai-context/index.js.map +1 -0
  5. package/dist/ai-context/manager.d.ts +67 -0
  6. package/dist/ai-context/manager.d.ts.map +1 -0
  7. package/dist/ai-context/manager.js +104 -0
  8. package/dist/ai-context/manager.js.map +1 -0
  9. package/dist/category-filter.d.ts +125 -0
  10. package/dist/category-filter.d.ts.map +1 -0
  11. package/dist/category-filter.js +360 -0
  12. package/dist/category-filter.js.map +1 -0
  13. package/dist/detect/ai-code/agent-tools.d.ts +22 -0
  14. package/dist/detect/ai-code/agent-tools.d.ts.map +1 -0
  15. package/dist/detect/ai-code/agent-tools.js +1509 -0
  16. package/dist/detect/ai-code/agent-tools.js.map +1 -0
  17. package/dist/detect/ai-code/byok-patterns.d.ts +15 -0
  18. package/dist/detect/ai-code/byok-patterns.d.ts.map +1 -0
  19. package/dist/detect/ai-code/byok-patterns.js +313 -0
  20. package/dist/detect/ai-code/byok-patterns.js.map +1 -0
  21. package/dist/detect/ai-code/endpoint-protection.d.ts +38 -0
  22. package/dist/detect/ai-code/endpoint-protection.d.ts.map +1 -0
  23. package/dist/detect/ai-code/endpoint-protection.js +349 -0
  24. package/dist/detect/ai-code/endpoint-protection.js.map +1 -0
  25. package/dist/detect/ai-code/execution-sinks.d.ts +21 -0
  26. package/dist/detect/ai-code/execution-sinks.d.ts.map +1 -0
  27. package/dist/detect/ai-code/execution-sinks.js +1158 -0
  28. package/dist/detect/ai-code/execution-sinks.js.map +1 -0
  29. package/dist/detect/ai-code/fingerprinting.d.ts +10 -0
  30. package/dist/detect/ai-code/fingerprinting.d.ts.map +1 -0
  31. package/dist/detect/ai-code/fingerprinting.js +665 -0
  32. package/dist/detect/ai-code/fingerprinting.js.map +1 -0
  33. package/dist/detect/ai-code/index.d.ts +12 -0
  34. package/dist/detect/ai-code/index.d.ts.map +1 -0
  35. package/dist/detect/ai-code/index.js +26 -0
  36. package/dist/detect/ai-code/index.js.map +1 -0
  37. package/dist/detect/ai-code/mcp-security.d.ts +20 -0
  38. package/dist/detect/ai-code/mcp-security.d.ts.map +1 -0
  39. package/dist/detect/ai-code/mcp-security.js +880 -0
  40. package/dist/detect/ai-code/mcp-security.js.map +1 -0
  41. package/dist/detect/ai-code/model-supply-chain.d.ts +23 -0
  42. package/dist/detect/ai-code/model-supply-chain.d.ts.map +1 -0
  43. package/dist/detect/ai-code/model-supply-chain.js +447 -0
  44. package/dist/detect/ai-code/model-supply-chain.js.map +1 -0
  45. package/dist/detect/ai-code/package-hallucination.d.ts +22 -0
  46. package/dist/detect/ai-code/package-hallucination.d.ts.map +1 -0
  47. package/dist/detect/ai-code/package-hallucination.js +841 -0
  48. package/dist/detect/ai-code/package-hallucination.js.map +1 -0
  49. package/dist/detect/ai-code/prompt-hygiene.d.ts +22 -0
  50. package/dist/detect/ai-code/prompt-hygiene.d.ts.map +1 -0
  51. package/dist/detect/ai-code/prompt-hygiene.js +1177 -0
  52. package/dist/detect/ai-code/prompt-hygiene.js.map +1 -0
  53. package/dist/detect/ai-code/rag-safety.d.ts +24 -0
  54. package/dist/detect/ai-code/rag-safety.d.ts.map +1 -0
  55. package/dist/detect/ai-code/rag-safety.js +913 -0
  56. package/dist/detect/ai-code/rag-safety.js.map +1 -0
  57. package/dist/detect/ai-code/schema-validation.d.ts +28 -0
  58. package/dist/detect/ai-code/schema-validation.d.ts.map +1 -0
  59. package/dist/detect/ai-code/schema-validation.js +378 -0
  60. package/dist/detect/ai-code/schema-validation.js.map +1 -0
  61. package/dist/detect/config/agent-skill-injection.d.ts +27 -0
  62. package/dist/detect/config/agent-skill-injection.d.ts.map +1 -0
  63. package/dist/detect/config/agent-skill-injection.js +472 -0
  64. package/dist/detect/config/agent-skill-injection.js.map +1 -0
  65. package/dist/detect/config/comments.d.ts +11 -0
  66. package/dist/detect/config/comments.d.ts.map +1 -0
  67. package/dist/detect/config/comments.js +206 -0
  68. package/dist/detect/config/comments.js.map +1 -0
  69. package/dist/detect/config/file-flags.d.ts +10 -0
  70. package/dist/detect/config/file-flags.d.ts.map +1 -0
  71. package/dist/detect/config/file-flags.js +124 -0
  72. package/dist/detect/config/file-flags.js.map +1 -0
  73. package/dist/detect/config/index.d.ts +7 -0
  74. package/dist/detect/config/index.d.ts.map +1 -0
  75. package/dist/detect/config/index.js +17 -0
  76. package/dist/detect/config/index.js.map +1 -0
  77. package/dist/detect/config/osv-check.d.ts +75 -0
  78. package/dist/detect/config/osv-check.d.ts.map +1 -0
  79. package/dist/detect/config/osv-check.js +309 -0
  80. package/dist/detect/config/osv-check.js.map +1 -0
  81. package/dist/detect/config/package-check.d.ts +63 -0
  82. package/dist/detect/config/package-check.d.ts.map +1 -0
  83. package/dist/detect/config/package-check.js +509 -0
  84. package/dist/detect/config/package-check.js.map +1 -0
  85. package/dist/detect/config/urls.d.ts +11 -0
  86. package/dist/detect/config/urls.d.ts.map +1 -0
  87. package/dist/detect/config/urls.js +450 -0
  88. package/dist/detect/config/urls.js.map +1 -0
  89. package/dist/detect/index.d.ts +37 -0
  90. package/dist/detect/index.d.ts.map +1 -0
  91. package/dist/detect/index.js +77 -0
  92. package/dist/detect/index.js.map +1 -0
  93. package/dist/detect/secrets/config-audit.d.ts +11 -0
  94. package/dist/detect/secrets/config-audit.d.ts.map +1 -0
  95. package/dist/detect/secrets/config-audit.js +315 -0
  96. package/dist/detect/secrets/config-audit.js.map +1 -0
  97. package/dist/detect/secrets/config-mcp-audit.d.ts +23 -0
  98. package/dist/detect/secrets/config-mcp-audit.d.ts.map +1 -0
  99. package/dist/detect/secrets/config-mcp-audit.js +243 -0
  100. package/dist/detect/secrets/config-mcp-audit.js.map +1 -0
  101. package/dist/detect/secrets/entropy.d.ts +11 -0
  102. package/dist/detect/secrets/entropy.d.ts.map +1 -0
  103. package/dist/detect/secrets/entropy.js +751 -0
  104. package/dist/detect/secrets/entropy.js.map +1 -0
  105. package/dist/detect/secrets/index.d.ts +36 -0
  106. package/dist/detect/secrets/index.d.ts.map +1 -0
  107. package/dist/detect/secrets/index.js +174 -0
  108. package/dist/detect/secrets/index.js.map +1 -0
  109. package/dist/detect/secrets/patterns.d.ts +11 -0
  110. package/dist/detect/secrets/patterns.d.ts.map +1 -0
  111. package/dist/detect/secrets/patterns.js +518 -0
  112. package/dist/detect/secrets/patterns.js.map +1 -0
  113. package/dist/detect/secrets/weak-crypto.d.ts +10 -0
  114. package/dist/detect/secrets/weak-crypto.d.ts.map +1 -0
  115. package/dist/detect/secrets/weak-crypto.js +432 -0
  116. package/dist/detect/secrets/weak-crypto.js.map +1 -0
  117. package/dist/detect/structural/auth-patterns.d.ts +22 -0
  118. package/dist/detect/structural/auth-patterns.d.ts.map +1 -0
  119. package/dist/detect/structural/auth-patterns.js +533 -0
  120. package/dist/detect/structural/auth-patterns.js.map +1 -0
  121. package/dist/detect/structural/dangerous-functions/child-process.d.ts +16 -0
  122. package/dist/detect/structural/dangerous-functions/child-process.d.ts.map +1 -0
  123. package/dist/detect/structural/dangerous-functions/child-process.js +74 -0
  124. package/dist/detect/structural/dangerous-functions/child-process.js.map +1 -0
  125. package/dist/detect/structural/dangerous-functions/dom-xss.d.ts +34 -0
  126. package/dist/detect/structural/dangerous-functions/dom-xss.d.ts.map +1 -0
  127. package/dist/detect/structural/dangerous-functions/dom-xss.js +230 -0
  128. package/dist/detect/structural/dangerous-functions/dom-xss.js.map +1 -0
  129. package/dist/detect/structural/dangerous-functions/index.d.ts +16 -0
  130. package/dist/detect/structural/dangerous-functions/index.d.ts.map +1 -0
  131. package/dist/detect/structural/dangerous-functions/index.js +1193 -0
  132. package/dist/detect/structural/dangerous-functions/index.js.map +1 -0
  133. package/dist/detect/structural/dangerous-functions/json-parse.d.ts +31 -0
  134. package/dist/detect/structural/dangerous-functions/json-parse.d.ts.map +1 -0
  135. package/dist/detect/structural/dangerous-functions/json-parse.js +326 -0
  136. package/dist/detect/structural/dangerous-functions/json-parse.js.map +1 -0
  137. package/dist/detect/structural/dangerous-functions/math-random.d.ts +111 -0
  138. package/dist/detect/structural/dangerous-functions/math-random.d.ts.map +1 -0
  139. package/dist/detect/structural/dangerous-functions/math-random.js +684 -0
  140. package/dist/detect/structural/dangerous-functions/math-random.js.map +1 -0
  141. package/dist/detect/structural/dangerous-functions/patterns.d.ts +21 -0
  142. package/dist/detect/structural/dangerous-functions/patterns.d.ts.map +1 -0
  143. package/dist/detect/structural/dangerous-functions/patterns.js +163 -0
  144. package/dist/detect/structural/dangerous-functions/patterns.js.map +1 -0
  145. package/dist/detect/structural/dangerous-functions/request-validation.d.ts +13 -0
  146. package/dist/detect/structural/dangerous-functions/request-validation.d.ts.map +1 -0
  147. package/dist/detect/structural/dangerous-functions/request-validation.js +126 -0
  148. package/dist/detect/structural/dangerous-functions/request-validation.js.map +1 -0
  149. package/dist/detect/structural/dangerous-functions/utils/control-flow.d.ts +24 -0
  150. package/dist/detect/structural/dangerous-functions/utils/control-flow.d.ts.map +1 -0
  151. package/dist/detect/structural/dangerous-functions/utils/control-flow.js +70 -0
  152. package/dist/detect/structural/dangerous-functions/utils/control-flow.js.map +1 -0
  153. package/dist/detect/structural/dangerous-functions/utils/helpers.d.ts +31 -0
  154. package/dist/detect/structural/dangerous-functions/utils/helpers.d.ts.map +1 -0
  155. package/dist/detect/structural/dangerous-functions/utils/helpers.js +147 -0
  156. package/dist/detect/structural/dangerous-functions/utils/helpers.js.map +1 -0
  157. package/dist/detect/structural/dangerous-functions/utils/index.d.ts +9 -0
  158. package/dist/detect/structural/dangerous-functions/utils/index.d.ts.map +1 -0
  159. package/dist/detect/structural/dangerous-functions/utils/index.js +23 -0
  160. package/dist/detect/structural/dangerous-functions/utils/index.js.map +1 -0
  161. package/dist/detect/structural/dangerous-functions/utils/schema-validation.d.ts +22 -0
  162. package/dist/detect/structural/dangerous-functions/utils/schema-validation.d.ts.map +1 -0
  163. package/dist/detect/structural/dangerous-functions/utils/schema-validation.js +102 -0
  164. package/dist/detect/structural/dangerous-functions/utils/schema-validation.js.map +1 -0
  165. package/dist/detect/structural/data-exposure.d.ts +19 -0
  166. package/dist/detect/structural/data-exposure.d.ts.map +1 -0
  167. package/dist/detect/structural/data-exposure.js +262 -0
  168. package/dist/detect/structural/data-exposure.js.map +1 -0
  169. package/dist/detect/structural/framework-checks.d.ts +10 -0
  170. package/dist/detect/structural/framework-checks.d.ts.map +1 -0
  171. package/dist/detect/structural/framework-checks.js +389 -0
  172. package/dist/detect/structural/framework-checks.js.map +1 -0
  173. package/dist/detect/structural/index.d.ts +71 -0
  174. package/dist/detect/structural/index.d.ts.map +1 -0
  175. package/dist/detect/structural/index.js +510 -0
  176. package/dist/detect/structural/index.js.map +1 -0
  177. package/dist/detect/structural/log-injection.d.ts +18 -0
  178. package/dist/detect/structural/log-injection.d.ts.map +1 -0
  179. package/dist/detect/structural/log-injection.js +217 -0
  180. package/dist/detect/structural/log-injection.js.map +1 -0
  181. package/dist/detect/structural/logic-gates.d.ts +10 -0
  182. package/dist/detect/structural/logic-gates.d.ts.map +1 -0
  183. package/dist/detect/structural/logic-gates.js +227 -0
  184. package/dist/detect/structural/logic-gates.js.map +1 -0
  185. package/dist/detect/structural/risky-imports.d.ts +10 -0
  186. package/dist/detect/structural/risky-imports.d.ts.map +1 -0
  187. package/dist/detect/structural/risky-imports.js +168 -0
  188. package/dist/detect/structural/risky-imports.js.map +1 -0
  189. package/dist/detect/structural/security-headers.d.ts +18 -0
  190. package/dist/detect/structural/security-headers.d.ts.map +1 -0
  191. package/dist/detect/structural/security-headers.js +196 -0
  192. package/dist/detect/structural/security-headers.js.map +1 -0
  193. package/dist/detect/structural/ssrf-detection.d.ts +18 -0
  194. package/dist/detect/structural/ssrf-detection.d.ts.map +1 -0
  195. package/dist/detect/structural/ssrf-detection.js +263 -0
  196. package/dist/detect/structural/ssrf-detection.js.map +1 -0
  197. package/dist/detect/structural/variables.d.ts +11 -0
  198. package/dist/detect/structural/variables.d.ts.map +1 -0
  199. package/dist/detect/structural/variables.js +159 -0
  200. package/dist/detect/structural/variables.js.map +1 -0
  201. package/dist/detect/structural/xxe-detection.d.ts +18 -0
  202. package/dist/detect/structural/xxe-detection.d.ts.map +1 -0
  203. package/dist/detect/structural/xxe-detection.js +245 -0
  204. package/dist/detect/structural/xxe-detection.js.map +1 -0
  205. package/dist/filtering/context-adjustments.d.ts +23 -0
  206. package/dist/filtering/context-adjustments.d.ts.map +1 -0
  207. package/dist/filtering/context-adjustments.js +100 -0
  208. package/dist/filtering/context-adjustments.js.map +1 -0
  209. package/dist/filtering/index.d.ts +3 -0
  210. package/dist/filtering/index.d.ts.map +1 -0
  211. package/dist/filtering/index.js +8 -0
  212. package/dist/filtering/index.js.map +1 -0
  213. package/dist/filtering/pipeline.d.ts +48 -0
  214. package/dist/filtering/pipeline.d.ts.map +1 -0
  215. package/dist/filtering/pipeline.js +76 -0
  216. package/dist/filtering/pipeline.js.map +1 -0
  217. package/dist/formatters/ai-context.d.ts +23 -0
  218. package/dist/formatters/ai-context.d.ts.map +1 -0
  219. package/dist/formatters/ai-context.js +238 -0
  220. package/dist/formatters/ai-context.js.map +1 -0
  221. package/dist/formatters/github-comment.d.ts +1 -1
  222. package/dist/formatters/github-comment.d.ts.map +1 -1
  223. package/dist/formatters/github-comment.js +2 -2
  224. package/dist/formatters/github-comment.js.map +1 -1
  225. package/dist/formatters/ide/claude-code.d.ts +17 -0
  226. package/dist/formatters/ide/claude-code.d.ts.map +1 -0
  227. package/dist/formatters/ide/claude-code.js +94 -0
  228. package/dist/formatters/ide/claude-code.js.map +1 -0
  229. package/dist/formatters/ide/cursor.d.ts +13 -0
  230. package/dist/formatters/ide/cursor.d.ts.map +1 -0
  231. package/dist/formatters/ide/cursor.js +125 -0
  232. package/dist/formatters/ide/cursor.js.map +1 -0
  233. package/dist/formatters/ide/index.d.ts +62 -0
  234. package/dist/formatters/ide/index.d.ts.map +1 -0
  235. package/dist/formatters/ide/index.js +184 -0
  236. package/dist/formatters/ide/index.js.map +1 -0
  237. package/dist/formatters/ide/windsurf.d.ts +13 -0
  238. package/dist/formatters/ide/windsurf.d.ts.map +1 -0
  239. package/dist/formatters/ide/windsurf.js +117 -0
  240. package/dist/formatters/ide/windsurf.js.map +1 -0
  241. package/dist/formatters/index.d.ts +2 -0
  242. package/dist/formatters/index.d.ts.map +1 -1
  243. package/dist/formatters/index.js +17 -1
  244. package/dist/formatters/index.js.map +1 -1
  245. package/dist/index.d.ts +17 -60
  246. package/dist/index.d.ts.map +1 -1
  247. package/dist/index.js +67 -824
  248. package/dist/index.js.map +1 -1
  249. package/dist/layer1/comments.d.ts +4 -1
  250. package/dist/layer1/comments.d.ts.map +1 -1
  251. package/dist/layer1/comments.js +1 -1
  252. package/dist/layer1/comments.js.map +1 -1
  253. package/dist/layer1/config-audit.d.ts +4 -1
  254. package/dist/layer1/config-audit.d.ts.map +1 -1
  255. package/dist/layer1/config-audit.js +45 -11
  256. package/dist/layer1/config-audit.js.map +1 -1
  257. package/dist/layer1/config-mcp-audit.d.ts +4 -1
  258. package/dist/layer1/config-mcp-audit.d.ts.map +1 -1
  259. package/dist/layer1/config-mcp-audit.js +2 -2
  260. package/dist/layer1/config-mcp-audit.js.map +1 -1
  261. package/dist/layer1/entropy.d.ts +4 -1
  262. package/dist/layer1/entropy.d.ts.map +1 -1
  263. package/dist/layer1/entropy.js +212 -1
  264. package/dist/layer1/entropy.js.map +1 -1
  265. package/dist/layer1/file-flags.d.ts +4 -1
  266. package/dist/layer1/file-flags.d.ts.map +1 -1
  267. package/dist/layer1/file-flags.js +12 -5
  268. package/dist/layer1/file-flags.js.map +1 -1
  269. package/dist/layer1/index.d.ts.map +1 -1
  270. package/dist/layer1/index.js +14 -19
  271. package/dist/layer1/index.js.map +1 -1
  272. package/dist/layer1/patterns.d.ts +4 -1
  273. package/dist/layer1/patterns.d.ts.map +1 -1
  274. package/dist/layer1/patterns.js +34 -4
  275. package/dist/layer1/patterns.js.map +1 -1
  276. package/dist/layer1/urls.d.ts +4 -1
  277. package/dist/layer1/urls.d.ts.map +1 -1
  278. package/dist/layer1/urls.js +162 -14
  279. package/dist/layer1/urls.js.map +1 -1
  280. package/dist/layer1/weak-crypto.d.ts +4 -1
  281. package/dist/layer1/weak-crypto.d.ts.map +1 -1
  282. package/dist/layer1/weak-crypto.js +144 -7
  283. package/dist/layer1/weak-crypto.js.map +1 -1
  284. package/dist/layer2/ai-agent-tools.d.ts +4 -1
  285. package/dist/layer2/ai-agent-tools.d.ts.map +1 -1
  286. package/dist/layer2/ai-agent-tools.js +661 -2
  287. package/dist/layer2/ai-agent-tools.js.map +1 -1
  288. package/dist/layer2/ai-endpoint-protection.d.ts +2 -0
  289. package/dist/layer2/ai-endpoint-protection.d.ts.map +1 -1
  290. package/dist/layer2/ai-endpoint-protection.js +1 -1
  291. package/dist/layer2/ai-endpoint-protection.js.map +1 -1
  292. package/dist/layer2/ai-execution-sinks.d.ts +4 -1
  293. package/dist/layer2/ai-execution-sinks.d.ts.map +1 -1
  294. package/dist/layer2/ai-execution-sinks.js +252 -43
  295. package/dist/layer2/ai-execution-sinks.js.map +1 -1
  296. package/dist/layer2/ai-fingerprinting.d.ts +4 -1
  297. package/dist/layer2/ai-fingerprinting.d.ts.map +1 -1
  298. package/dist/layer2/ai-fingerprinting.js +25 -32
  299. package/dist/layer2/ai-fingerprinting.js.map +1 -1
  300. package/dist/layer2/ai-mcp-security.d.ts +4 -1
  301. package/dist/layer2/ai-mcp-security.d.ts.map +1 -1
  302. package/dist/layer2/ai-mcp-security.js +200 -2
  303. package/dist/layer2/ai-mcp-security.js.map +1 -1
  304. package/dist/layer2/ai-package-hallucination.d.ts +4 -1
  305. package/dist/layer2/ai-package-hallucination.d.ts.map +1 -1
  306. package/dist/layer2/ai-package-hallucination.js +136 -4
  307. package/dist/layer2/ai-package-hallucination.js.map +1 -1
  308. package/dist/layer2/ai-prompt-hygiene.d.ts +4 -1
  309. package/dist/layer2/ai-prompt-hygiene.d.ts.map +1 -1
  310. package/dist/layer2/ai-prompt-hygiene.js +342 -28
  311. package/dist/layer2/ai-prompt-hygiene.js.map +1 -1
  312. package/dist/layer2/ai-rag-safety.d.ts +4 -1
  313. package/dist/layer2/ai-rag-safety.d.ts.map +1 -1
  314. package/dist/layer2/ai-rag-safety.js +82 -2
  315. package/dist/layer2/ai-rag-safety.js.map +1 -1
  316. package/dist/layer2/ai-schema-validation.d.ts +4 -1
  317. package/dist/layer2/ai-schema-validation.d.ts.map +1 -1
  318. package/dist/layer2/ai-schema-validation.js +2 -2
  319. package/dist/layer2/ai-schema-validation.js.map +1 -1
  320. package/dist/layer2/auth-antipatterns.d.ts +2 -0
  321. package/dist/layer2/auth-antipatterns.d.ts.map +1 -1
  322. package/dist/layer2/auth-antipatterns.js +205 -20
  323. package/dist/layer2/auth-antipatterns.js.map +1 -1
  324. package/dist/layer2/byok-patterns.d.ts +4 -1
  325. package/dist/layer2/byok-patterns.d.ts.map +1 -1
  326. package/dist/layer2/byok-patterns.js +2 -2
  327. package/dist/layer2/byok-patterns.js.map +1 -1
  328. package/dist/layer2/dangerous-functions/dom-xss.d.ts +9 -4
  329. package/dist/layer2/dangerous-functions/dom-xss.d.ts.map +1 -1
  330. package/dist/layer2/dangerous-functions/dom-xss.js +73 -22
  331. package/dist/layer2/dangerous-functions/dom-xss.js.map +1 -1
  332. package/dist/layer2/dangerous-functions/index.d.ts +4 -1
  333. package/dist/layer2/dangerous-functions/index.d.ts.map +1 -1
  334. package/dist/layer2/dangerous-functions/index.js +551 -20
  335. package/dist/layer2/dangerous-functions/index.js.map +1 -1
  336. package/dist/layer2/dangerous-functions/math-random.d.ts +54 -4
  337. package/dist/layer2/dangerous-functions/math-random.d.ts.map +1 -1
  338. package/dist/layer2/dangerous-functions/math-random.js +241 -16
  339. package/dist/layer2/dangerous-functions/math-random.js.map +1 -1
  340. package/dist/layer2/dangerous-functions/patterns.d.ts.map +1 -1
  341. package/dist/layer2/dangerous-functions/patterns.js +3 -1
  342. package/dist/layer2/dangerous-functions/patterns.js.map +1 -1
  343. package/dist/layer2/dangerous-functions/utils/control-flow.d.ts +3 -2
  344. package/dist/layer2/dangerous-functions/utils/control-flow.d.ts.map +1 -1
  345. package/dist/layer2/dangerous-functions/utils/control-flow.js +41 -120
  346. package/dist/layer2/dangerous-functions/utils/control-flow.js.map +1 -1
  347. package/dist/layer2/dangerous-functions/utils/helpers.d.ts.map +1 -1
  348. package/dist/layer2/dangerous-functions/utils/helpers.js +26 -3
  349. package/dist/layer2/dangerous-functions/utils/helpers.js.map +1 -1
  350. package/dist/layer2/dangerous-functions/utils/schema-validation.d.ts.map +1 -1
  351. package/dist/layer2/dangerous-functions/utils/schema-validation.js +14 -1
  352. package/dist/layer2/dangerous-functions/utils/schema-validation.js.map +1 -1
  353. package/dist/layer2/data-exposure.d.ts +4 -1
  354. package/dist/layer2/data-exposure.d.ts.map +1 -1
  355. package/dist/layer2/data-exposure.js +11 -38
  356. package/dist/layer2/data-exposure.js.map +1 -1
  357. package/dist/layer2/framework-checks.d.ts +4 -1
  358. package/dist/layer2/framework-checks.d.ts.map +1 -1
  359. package/dist/layer2/framework-checks.js +3 -10
  360. package/dist/layer2/framework-checks.js.map +1 -1
  361. package/dist/layer2/index.d.ts +13 -1
  362. package/dist/layer2/index.d.ts.map +1 -1
  363. package/dist/layer2/index.js +107 -52
  364. package/dist/layer2/index.js.map +1 -1
  365. package/dist/layer2/log-injection.d.ts +18 -0
  366. package/dist/layer2/log-injection.d.ts.map +1 -0
  367. package/dist/layer2/log-injection.js +214 -0
  368. package/dist/layer2/log-injection.js.map +1 -0
  369. package/dist/layer2/logic-gates.d.ts +4 -1
  370. package/dist/layer2/logic-gates.d.ts.map +1 -1
  371. package/dist/layer2/logic-gates.js +54 -20
  372. package/dist/layer2/logic-gates.js.map +1 -1
  373. package/dist/layer2/model-supply-chain.d.ts +4 -1
  374. package/dist/layer2/model-supply-chain.d.ts.map +1 -1
  375. package/dist/layer2/model-supply-chain.js +72 -4
  376. package/dist/layer2/model-supply-chain.js.map +1 -1
  377. package/dist/layer2/risky-imports.d.ts +4 -1
  378. package/dist/layer2/risky-imports.d.ts.map +1 -1
  379. package/dist/layer2/risky-imports.js +2 -2
  380. package/dist/layer2/risky-imports.js.map +1 -1
  381. package/dist/layer2/security-headers.d.ts +18 -0
  382. package/dist/layer2/security-headers.d.ts.map +1 -0
  383. package/dist/layer2/security-headers.js +187 -0
  384. package/dist/layer2/security-headers.js.map +1 -0
  385. package/dist/layer2/ssrf-detection.d.ts +18 -0
  386. package/dist/layer2/ssrf-detection.d.ts.map +1 -0
  387. package/dist/layer2/ssrf-detection.js +252 -0
  388. package/dist/layer2/ssrf-detection.js.map +1 -0
  389. package/dist/layer2/variables.d.ts +4 -1
  390. package/dist/layer2/variables.d.ts.map +1 -1
  391. package/dist/layer2/variables.js +2 -2
  392. package/dist/layer2/variables.js.map +1 -1
  393. package/dist/layer2/xxe-detection.d.ts +18 -0
  394. package/dist/layer2/xxe-detection.d.ts.map +1 -0
  395. package/dist/layer2/xxe-detection.js +242 -0
  396. package/dist/layer2/xxe-detection.js.map +1 -0
  397. package/dist/layer3/anthropic/auto-dismiss.d.ts.map +1 -1
  398. package/dist/layer3/anthropic/auto-dismiss.js +11 -0
  399. package/dist/layer3/anthropic/auto-dismiss.js.map +1 -1
  400. package/dist/layer3/anthropic/prompts/index.d.ts +1 -1
  401. package/dist/layer3/anthropic/prompts/index.d.ts.map +1 -1
  402. package/dist/layer3/anthropic/prompts/index.js +3 -1
  403. package/dist/layer3/anthropic/prompts/index.js.map +1 -1
  404. package/dist/layer3/anthropic/prompts/modules/ai-patterns.d.ts +19 -0
  405. package/dist/layer3/anthropic/prompts/modules/ai-patterns.d.ts.map +1 -0
  406. package/dist/layer3/anthropic/prompts/modules/ai-patterns.js +156 -0
  407. package/dist/layer3/anthropic/prompts/modules/ai-patterns.js.map +1 -0
  408. package/dist/layer3/anthropic/prompts/modules/auth-access.d.ts +9 -0
  409. package/dist/layer3/anthropic/prompts/modules/auth-access.d.ts.map +1 -0
  410. package/dist/layer3/anthropic/prompts/modules/auth-access.js +25 -0
  411. package/dist/layer3/anthropic/prompts/modules/auth-access.js.map +1 -0
  412. package/dist/layer3/anthropic/prompts/modules/common.d.ts +11 -0
  413. package/dist/layer3/anthropic/prompts/modules/common.d.ts.map +1 -0
  414. package/dist/layer3/anthropic/prompts/modules/common.js +152 -0
  415. package/dist/layer3/anthropic/prompts/modules/common.js.map +1 -0
  416. package/dist/layer3/anthropic/prompts/modules/index.d.ts +54 -0
  417. package/dist/layer3/anthropic/prompts/modules/index.d.ts.map +1 -0
  418. package/dist/layer3/anthropic/prompts/modules/index.js +185 -0
  419. package/dist/layer3/anthropic/prompts/modules/index.js.map +1 -0
  420. package/dist/layer3/anthropic/prompts/modules/owasp-classic.d.ts +8 -0
  421. package/dist/layer3/anthropic/prompts/modules/owasp-classic.d.ts.map +1 -0
  422. package/dist/layer3/anthropic/prompts/modules/owasp-classic.js +84 -0
  423. package/dist/layer3/anthropic/prompts/modules/owasp-classic.js.map +1 -0
  424. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.d.ts +8 -0
  425. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.d.ts.map +1 -0
  426. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.js +68 -0
  427. package/dist/layer3/anthropic/prompts/modules/secrets-crypto.js.map +1 -0
  428. package/dist/layer3/anthropic/prompts/modules/xss-prompt.d.ts +8 -0
  429. package/dist/layer3/anthropic/prompts/modules/xss-prompt.d.ts.map +1 -0
  430. package/dist/layer3/anthropic/prompts/modules/xss-prompt.js +22 -0
  431. package/dist/layer3/anthropic/prompts/modules/xss-prompt.js.map +1 -0
  432. package/dist/layer3/anthropic/prompts/validation.d.ts +9 -3
  433. package/dist/layer3/anthropic/prompts/validation.d.ts.map +1 -1
  434. package/dist/layer3/anthropic/prompts/validation.js +14 -410
  435. package/dist/layer3/anthropic/prompts/validation.js.map +1 -1
  436. package/dist/layer3/anthropic/providers/anthropic.d.ts.map +1 -1
  437. package/dist/layer3/anthropic/providers/anthropic.js +6 -3
  438. package/dist/layer3/anthropic/providers/anthropic.js.map +1 -1
  439. package/dist/layer3/anthropic/providers/openai.d.ts.map +1 -1
  440. package/dist/layer3/anthropic/providers/openai.js +6 -3
  441. package/dist/layer3/anthropic/providers/openai.js.map +1 -1
  442. package/dist/layer3/anthropic/request-builder.d.ts +11 -4
  443. package/dist/layer3/anthropic/request-builder.d.ts.map +1 -1
  444. package/dist/layer3/anthropic/request-builder.js +32 -16
  445. package/dist/layer3/anthropic/request-builder.js.map +1 -1
  446. package/dist/layer3/anthropic/utils/context-extractor.d.ts +55 -0
  447. package/dist/layer3/anthropic/utils/context-extractor.d.ts.map +1 -0
  448. package/dist/layer3/anthropic/utils/context-extractor.js +161 -0
  449. package/dist/layer3/anthropic/utils/context-extractor.js.map +1 -0
  450. package/dist/layer3/anthropic/utils/index.d.ts +2 -0
  451. package/dist/layer3/anthropic/utils/index.d.ts.map +1 -1
  452. package/dist/layer3/anthropic/utils/index.js +4 -1
  453. package/dist/layer3/anthropic/utils/index.js.map +1 -1
  454. package/dist/model/auth-helper-detector.d.ts +56 -0
  455. package/dist/model/auth-helper-detector.d.ts.map +1 -0
  456. package/dist/model/auth-helper-detector.js +360 -0
  457. package/dist/model/auth-helper-detector.js.map +1 -0
  458. package/dist/model/cross-file-taint.d.ts +40 -0
  459. package/dist/model/cross-file-taint.d.ts.map +1 -0
  460. package/dist/model/cross-file-taint.js +290 -0
  461. package/dist/model/cross-file-taint.js.map +1 -0
  462. package/dist/model/framework-models/django.d.ts +9 -0
  463. package/dist/model/framework-models/django.d.ts.map +1 -0
  464. package/dist/model/framework-models/django.js +82 -0
  465. package/dist/model/framework-models/django.js.map +1 -0
  466. package/dist/model/framework-models/express.d.ts +9 -0
  467. package/dist/model/framework-models/express.d.ts.map +1 -0
  468. package/dist/model/framework-models/express.js +52 -0
  469. package/dist/model/framework-models/express.js.map +1 -0
  470. package/dist/model/framework-models/index.d.ts +20 -0
  471. package/dist/model/framework-models/index.d.ts.map +1 -0
  472. package/dist/model/framework-models/index.js +102 -0
  473. package/dist/model/framework-models/index.js.map +1 -0
  474. package/dist/model/framework-models/nextjs.d.ts +9 -0
  475. package/dist/model/framework-models/nextjs.d.ts.map +1 -0
  476. package/dist/model/framework-models/nextjs.js +71 -0
  477. package/dist/model/framework-models/nextjs.js.map +1 -0
  478. package/dist/model/framework-models/prisma.d.ts +10 -0
  479. package/dist/model/framework-models/prisma.d.ts.map +1 -0
  480. package/dist/model/framework-models/prisma.js +54 -0
  481. package/dist/model/framework-models/prisma.js.map +1 -0
  482. package/dist/model/framework-models/react.d.ts +9 -0
  483. package/dist/model/framework-models/react.d.ts.map +1 -0
  484. package/dist/model/framework-models/react.js +67 -0
  485. package/dist/model/framework-models/react.js.map +1 -0
  486. package/dist/model/framework-models/sequelize.d.ts +9 -0
  487. package/dist/model/framework-models/sequelize.d.ts.map +1 -0
  488. package/dist/model/framework-models/sequelize.js +62 -0
  489. package/dist/model/framework-models/sequelize.js.map +1 -0
  490. package/dist/model/framework-models/types.d.ts +43 -0
  491. package/dist/model/framework-models/types.d.ts.map +1 -0
  492. package/dist/model/framework-models/types.js +10 -0
  493. package/dist/model/framework-models/types.js.map +1 -0
  494. package/dist/model/function-classifier.d.ts +32 -0
  495. package/dist/model/function-classifier.d.ts.map +1 -0
  496. package/dist/model/function-classifier.js +143 -0
  497. package/dist/model/function-classifier.js.map +1 -0
  498. package/dist/model/import-resolver.d.ts +45 -0
  499. package/dist/model/import-resolver.d.ts.map +1 -0
  500. package/dist/model/import-resolver.js +410 -0
  501. package/dist/model/import-resolver.js.map +1 -0
  502. package/dist/model/imported-auth-detector.d.ts +38 -0
  503. package/dist/model/imported-auth-detector.d.ts.map +1 -0
  504. package/dist/model/imported-auth-detector.js +199 -0
  505. package/dist/model/imported-auth-detector.js.map +1 -0
  506. package/dist/model/index.d.ts +63 -0
  507. package/dist/model/index.d.ts.map +1 -0
  508. package/dist/model/index.js +272 -0
  509. package/dist/model/index.js.map +1 -0
  510. package/dist/model/middleware-detector.d.ts +55 -0
  511. package/dist/model/middleware-detector.d.ts.map +1 -0
  512. package/dist/model/middleware-detector.js +382 -0
  513. package/dist/model/middleware-detector.js.map +1 -0
  514. package/dist/model/module-graph.d.ts +46 -0
  515. package/dist/model/module-graph.d.ts.map +1 -0
  516. package/dist/model/module-graph.js +187 -0
  517. package/dist/model/module-graph.js.map +1 -0
  518. package/dist/model/oauth-flow-detector.d.ts +41 -0
  519. package/dist/model/oauth-flow-detector.d.ts.map +1 -0
  520. package/dist/model/oauth-flow-detector.js +202 -0
  521. package/dist/model/oauth-flow-detector.js.map +1 -0
  522. package/dist/model/project-context.d.ts +119 -0
  523. package/dist/model/project-context.d.ts.map +1 -0
  524. package/dist/model/project-context.js +534 -0
  525. package/dist/model/project-context.js.map +1 -0
  526. package/dist/model/route-auth-resolver.d.ts +27 -0
  527. package/dist/model/route-auth-resolver.d.ts.map +1 -0
  528. package/dist/model/route-auth-resolver.js +182 -0
  529. package/dist/model/route-auth-resolver.js.map +1 -0
  530. package/dist/model/route-discovery/express.d.ts +25 -0
  531. package/dist/model/route-discovery/express.d.ts.map +1 -0
  532. package/dist/model/route-discovery/express.js +225 -0
  533. package/dist/model/route-discovery/express.js.map +1 -0
  534. package/dist/model/route-discovery/index.d.ts +21 -0
  535. package/dist/model/route-discovery/index.d.ts.map +1 -0
  536. package/dist/model/route-discovery/index.js +67 -0
  537. package/dist/model/route-discovery/index.js.map +1 -0
  538. package/dist/model/route-discovery/nextjs.d.ts +16 -0
  539. package/dist/model/route-discovery/nextjs.d.ts.map +1 -0
  540. package/dist/model/route-discovery/nextjs.js +179 -0
  541. package/dist/model/route-discovery/nextjs.js.map +1 -0
  542. package/dist/model/route-discovery/python.d.ts +16 -0
  543. package/dist/model/route-discovery/python.d.ts.map +1 -0
  544. package/dist/model/route-discovery/python.js +181 -0
  545. package/dist/model/route-discovery/python.js.map +1 -0
  546. package/dist/model/route-discovery/types.d.ts +36 -0
  547. package/dist/model/route-discovery/types.d.ts.map +1 -0
  548. package/dist/model/route-discovery/types.js +16 -0
  549. package/dist/model/route-discovery/types.js.map +1 -0
  550. package/dist/model/route-discovery/utils.d.ts +18 -0
  551. package/dist/model/route-discovery/utils.d.ts.map +1 -0
  552. package/dist/model/route-discovery/utils.js +55 -0
  553. package/dist/model/route-discovery/utils.js.map +1 -0
  554. package/dist/model/route-hierarchy.d.ts +50 -0
  555. package/dist/model/route-hierarchy.d.ts.map +1 -0
  556. package/dist/model/route-hierarchy.js +226 -0
  557. package/dist/model/route-hierarchy.js.map +1 -0
  558. package/dist/model/sanitiser-detection.d.ts +27 -0
  559. package/dist/model/sanitiser-detection.d.ts.map +1 -0
  560. package/dist/model/sanitiser-detection.js +224 -0
  561. package/dist/model/sanitiser-detection.js.map +1 -0
  562. package/dist/model/sink-matcher.d.ts +17 -0
  563. package/dist/model/sink-matcher.d.ts.map +1 -0
  564. package/dist/model/sink-matcher.js +141 -0
  565. package/dist/model/sink-matcher.js.map +1 -0
  566. package/dist/model/sink-patterns.d.ts +19 -0
  567. package/dist/model/sink-patterns.d.ts.map +1 -0
  568. package/dist/model/sink-patterns.js +88 -0
  569. package/dist/model/sink-patterns.js.map +1 -0
  570. package/dist/model/source-discovery.d.ts +15 -0
  571. package/dist/model/source-discovery.d.ts.map +1 -0
  572. package/dist/model/source-discovery.js +170 -0
  573. package/dist/model/source-discovery.js.map +1 -0
  574. package/dist/model/taint-tracker.d.ts +21 -0
  575. package/dist/model/taint-tracker.d.ts.map +1 -0
  576. package/dist/model/taint-tracker.js +281 -0
  577. package/dist/model/taint-tracker.js.map +1 -0
  578. package/dist/model/taint-types.d.ts +74 -0
  579. package/dist/model/taint-types.d.ts.map +1 -0
  580. package/dist/model/taint-types.js +9 -0
  581. package/dist/model/taint-types.js.map +1 -0
  582. package/dist/model/trpc-analyzer.d.ts +78 -0
  583. package/dist/model/trpc-analyzer.d.ts.map +1 -0
  584. package/dist/model/trpc-analyzer.js +297 -0
  585. package/dist/model/trpc-analyzer.js.map +1 -0
  586. package/dist/modes/incremental.js +1 -1
  587. package/dist/parse/file-classifier.d.ts +228 -0
  588. package/dist/parse/file-classifier.d.ts.map +1 -0
  589. package/dist/parse/file-classifier.js +933 -0
  590. package/dist/parse/file-classifier.js.map +1 -0
  591. package/dist/parse/path-exclusions.d.ts +55 -0
  592. package/dist/parse/path-exclusions.d.ts.map +1 -0
  593. package/dist/parse/path-exclusions.js +224 -0
  594. package/dist/parse/path-exclusions.js.map +1 -0
  595. package/dist/pipeline/config.d.ts +39 -0
  596. package/dist/pipeline/config.d.ts.map +1 -0
  597. package/dist/pipeline/config.js +46 -0
  598. package/dist/pipeline/config.js.map +1 -0
  599. package/dist/pipeline/index.d.ts +34 -0
  600. package/dist/pipeline/index.d.ts.map +1 -0
  601. package/dist/pipeline/index.js +377 -0
  602. package/dist/pipeline/index.js.map +1 -0
  603. package/dist/pipeline/modes/incremental.d.ts +66 -0
  604. package/dist/pipeline/modes/incremental.d.ts.map +1 -0
  605. package/dist/pipeline/modes/incremental.js +200 -0
  606. package/dist/pipeline/modes/incremental.js.map +1 -0
  607. package/dist/postprocess/aggregation.d.ts +14 -0
  608. package/dist/postprocess/aggregation.d.ts.map +1 -0
  609. package/dist/postprocess/aggregation.js +63 -0
  610. package/dist/postprocess/aggregation.js.map +1 -0
  611. package/dist/postprocess/contradictions.d.ts +18 -0
  612. package/dist/postprocess/contradictions.d.ts.map +1 -0
  613. package/dist/postprocess/contradictions.js +99 -0
  614. package/dist/postprocess/contradictions.js.map +1 -0
  615. package/dist/postprocess/dedup.d.ts +13 -0
  616. package/dist/postprocess/dedup.d.ts.map +1 -0
  617. package/dist/postprocess/dedup.js +58 -0
  618. package/dist/postprocess/dedup.js.map +1 -0
  619. package/dist/postprocess/filtering/context-adjustments.d.ts +23 -0
  620. package/dist/postprocess/filtering/context-adjustments.d.ts.map +1 -0
  621. package/dist/postprocess/filtering/context-adjustments.js +100 -0
  622. package/dist/postprocess/filtering/context-adjustments.js.map +1 -0
  623. package/dist/postprocess/filtering/index.d.ts +3 -0
  624. package/dist/postprocess/filtering/index.d.ts.map +1 -0
  625. package/dist/postprocess/filtering/index.js +8 -0
  626. package/dist/postprocess/filtering/index.js.map +1 -0
  627. package/dist/postprocess/filtering/pipeline.d.ts +48 -0
  628. package/dist/postprocess/filtering/pipeline.d.ts.map +1 -0
  629. package/dist/postprocess/filtering/pipeline.js +76 -0
  630. package/dist/postprocess/filtering/pipeline.js.map +1 -0
  631. package/dist/postprocess/index.d.ts +41 -0
  632. package/dist/postprocess/index.d.ts.map +1 -0
  633. package/dist/postprocess/index.js +85 -0
  634. package/dist/postprocess/index.js.map +1 -0
  635. package/dist/postprocess/suppression/config-loader.d.ts +74 -0
  636. package/dist/postprocess/suppression/config-loader.d.ts.map +1 -0
  637. package/dist/postprocess/suppression/config-loader.js +424 -0
  638. package/dist/postprocess/suppression/config-loader.js.map +1 -0
  639. package/dist/postprocess/suppression/hash.d.ts +48 -0
  640. package/dist/postprocess/suppression/hash.d.ts.map +1 -0
  641. package/dist/postprocess/suppression/hash.js +88 -0
  642. package/dist/postprocess/suppression/hash.js.map +1 -0
  643. package/dist/postprocess/suppression/index.d.ts +11 -0
  644. package/dist/postprocess/suppression/index.d.ts.map +1 -0
  645. package/dist/postprocess/suppression/index.js +39 -0
  646. package/dist/postprocess/suppression/index.js.map +1 -0
  647. package/dist/postprocess/suppression/inline-parser.d.ts +39 -0
  648. package/dist/postprocess/suppression/inline-parser.d.ts.map +1 -0
  649. package/dist/postprocess/suppression/inline-parser.js +218 -0
  650. package/dist/postprocess/suppression/inline-parser.js.map +1 -0
  651. package/dist/postprocess/suppression/manager.d.ts +94 -0
  652. package/dist/postprocess/suppression/manager.d.ts.map +1 -0
  653. package/dist/postprocess/suppression/manager.js +292 -0
  654. package/dist/postprocess/suppression/manager.js.map +1 -0
  655. package/dist/postprocess/suppression/types.d.ts +151 -0
  656. package/dist/postprocess/suppression/types.d.ts.map +1 -0
  657. package/dist/postprocess/suppression/types.js +28 -0
  658. package/dist/postprocess/suppression/types.js.map +1 -0
  659. package/dist/postprocess/validation-cap.d.ts +17 -0
  660. package/dist/postprocess/validation-cap.d.ts.map +1 -0
  661. package/dist/postprocess/validation-cap.js +64 -0
  662. package/dist/postprocess/validation-cap.js.map +1 -0
  663. package/dist/report/build-result.d.ts +33 -0
  664. package/dist/report/build-result.d.ts.map +1 -0
  665. package/dist/report/build-result.js +59 -0
  666. package/dist/report/build-result.js.map +1 -0
  667. package/dist/report/enrichment.d.ts +19 -0
  668. package/dist/report/enrichment.d.ts.map +1 -0
  669. package/dist/report/enrichment.js +44 -0
  670. package/dist/report/enrichment.js.map +1 -0
  671. package/dist/report/formatters/ai-context.d.ts +23 -0
  672. package/dist/report/formatters/ai-context.d.ts.map +1 -0
  673. package/dist/report/formatters/ai-context.js +238 -0
  674. package/dist/report/formatters/ai-context.js.map +1 -0
  675. package/dist/report/formatters/cli-terminal.d.ts +65 -0
  676. package/dist/report/formatters/cli-terminal.d.ts.map +1 -0
  677. package/dist/report/formatters/cli-terminal.js +735 -0
  678. package/dist/report/formatters/cli-terminal.js.map +1 -0
  679. package/dist/report/formatters/github-comment.d.ts +41 -0
  680. package/dist/report/formatters/github-comment.d.ts.map +1 -0
  681. package/dist/report/formatters/github-comment.js +370 -0
  682. package/dist/report/formatters/github-comment.js.map +1 -0
  683. package/dist/report/formatters/grouping.d.ts +52 -0
  684. package/dist/report/formatters/grouping.d.ts.map +1 -0
  685. package/dist/report/formatters/grouping.js +152 -0
  686. package/dist/report/formatters/grouping.js.map +1 -0
  687. package/dist/report/formatters/ide/claude-code.d.ts +17 -0
  688. package/dist/report/formatters/ide/claude-code.d.ts.map +1 -0
  689. package/dist/report/formatters/ide/claude-code.js +94 -0
  690. package/dist/report/formatters/ide/claude-code.js.map +1 -0
  691. package/dist/report/formatters/ide/cursor.d.ts +13 -0
  692. package/dist/report/formatters/ide/cursor.d.ts.map +1 -0
  693. package/dist/report/formatters/ide/cursor.js +125 -0
  694. package/dist/report/formatters/ide/cursor.js.map +1 -0
  695. package/dist/report/formatters/ide/index.d.ts +62 -0
  696. package/dist/report/formatters/ide/index.d.ts.map +1 -0
  697. package/dist/report/formatters/ide/index.js +184 -0
  698. package/dist/report/formatters/ide/index.js.map +1 -0
  699. package/dist/report/formatters/ide/windsurf.d.ts +13 -0
  700. package/dist/report/formatters/ide/windsurf.d.ts.map +1 -0
  701. package/dist/report/formatters/ide/windsurf.js +117 -0
  702. package/dist/report/formatters/ide/windsurf.js.map +1 -0
  703. package/dist/report/formatters/index.d.ts +11 -0
  704. package/dist/report/formatters/index.d.ts.map +1 -0
  705. package/dist/report/formatters/index.js +54 -0
  706. package/dist/report/formatters/index.js.map +1 -0
  707. package/dist/report/formatters/vscode-diagnostic.d.ts +103 -0
  708. package/dist/report/formatters/vscode-diagnostic.d.ts.map +1 -0
  709. package/dist/report/formatters/vscode-diagnostic.js +151 -0
  710. package/dist/report/formatters/vscode-diagnostic.js.map +1 -0
  711. package/dist/report/summary.d.ts +27 -0
  712. package/dist/report/summary.d.ts.map +1 -0
  713. package/dist/report/summary.js +57 -0
  714. package/dist/report/summary.js.map +1 -0
  715. package/dist/rules/metadata.d.ts.map +1 -1
  716. package/dist/rules/metadata.js +66 -0
  717. package/dist/rules/metadata.js.map +1 -1
  718. package/dist/score/adjustments.d.ts +22 -0
  719. package/dist/score/adjustments.d.ts.map +1 -0
  720. package/dist/score/adjustments.js +373 -0
  721. package/dist/score/adjustments.js.map +1 -0
  722. package/dist/score/auto-dismiss.d.ts +28 -0
  723. package/dist/score/auto-dismiss.d.ts.map +1 -0
  724. package/dist/score/auto-dismiss.js +200 -0
  725. package/dist/score/auto-dismiss.js.map +1 -0
  726. package/dist/score/confidence.d.ts +19 -0
  727. package/dist/score/confidence.d.ts.map +1 -0
  728. package/dist/score/confidence.js +52 -0
  729. package/dist/score/confidence.js.map +1 -0
  730. package/dist/score/index.d.ts +61 -0
  731. package/dist/score/index.d.ts.map +1 -0
  732. package/dist/score/index.js +250 -0
  733. package/dist/score/index.js.map +1 -0
  734. package/dist/score/types.d.ts +160 -0
  735. package/dist/score/types.d.ts.map +1 -0
  736. package/dist/score/types.js +14 -0
  737. package/dist/score/types.js.map +1 -0
  738. package/dist/shared/ai-context/index.d.ts +6 -0
  739. package/dist/shared/ai-context/index.d.ts.map +1 -0
  740. package/dist/shared/ai-context/index.js +13 -0
  741. package/dist/shared/ai-context/index.js.map +1 -0
  742. package/dist/shared/ai-context/manager.d.ts +67 -0
  743. package/dist/shared/ai-context/manager.d.ts.map +1 -0
  744. package/dist/shared/ai-context/manager.js +104 -0
  745. package/dist/shared/ai-context/manager.js.map +1 -0
  746. package/dist/shared/baseline/diff.d.ts +32 -0
  747. package/dist/shared/baseline/diff.d.ts.map +1 -0
  748. package/dist/shared/baseline/diff.js +119 -0
  749. package/dist/shared/baseline/diff.js.map +1 -0
  750. package/dist/shared/baseline/index.d.ts +9 -0
  751. package/dist/shared/baseline/index.d.ts.map +1 -0
  752. package/dist/shared/baseline/index.js +19 -0
  753. package/dist/shared/baseline/index.js.map +1 -0
  754. package/dist/shared/baseline/manager.d.ts +67 -0
  755. package/dist/shared/baseline/manager.d.ts.map +1 -0
  756. package/dist/shared/baseline/manager.js +180 -0
  757. package/dist/shared/baseline/manager.js.map +1 -0
  758. package/dist/shared/baseline/types.d.ts +91 -0
  759. package/dist/shared/baseline/types.d.ts.map +1 -0
  760. package/dist/shared/baseline/types.js +12 -0
  761. package/dist/shared/baseline/types.js.map +1 -0
  762. package/dist/shared/category-filter.d.ts +125 -0
  763. package/dist/shared/category-filter.d.ts.map +1 -0
  764. package/dist/shared/category-filter.js +360 -0
  765. package/dist/shared/category-filter.js.map +1 -0
  766. package/dist/shared/code-analysis.d.ts +39 -0
  767. package/dist/shared/code-analysis.d.ts.map +1 -0
  768. package/dist/shared/code-analysis.js +159 -0
  769. package/dist/shared/code-analysis.js.map +1 -0
  770. package/dist/shared/comment-analyzer.d.ts +38 -0
  771. package/dist/shared/comment-analyzer.d.ts.map +1 -0
  772. package/dist/shared/comment-analyzer.js +218 -0
  773. package/dist/shared/comment-analyzer.js.map +1 -0
  774. package/dist/shared/diff-detector.d.ts +53 -0
  775. package/dist/shared/diff-detector.d.ts.map +1 -0
  776. package/dist/shared/diff-detector.js +104 -0
  777. package/dist/shared/diff-detector.js.map +1 -0
  778. package/dist/shared/diff-parser.d.ts +80 -0
  779. package/dist/shared/diff-parser.d.ts.map +1 -0
  780. package/dist/shared/diff-parser.js +202 -0
  781. package/dist/shared/diff-parser.js.map +1 -0
  782. package/dist/shared/environment-context.d.ts +76 -0
  783. package/dist/shared/environment-context.d.ts.map +1 -0
  784. package/dist/shared/environment-context.js +271 -0
  785. package/dist/shared/environment-context.js.map +1 -0
  786. package/dist/shared/intent-detector.d.ts +66 -0
  787. package/dist/shared/intent-detector.d.ts.map +1 -0
  788. package/dist/shared/intent-detector.js +282 -0
  789. package/dist/shared/intent-detector.js.map +1 -0
  790. package/dist/shared/parsed-file.d.ts +51 -0
  791. package/dist/shared/parsed-file.d.ts.map +1 -0
  792. package/dist/shared/parsed-file.js +95 -0
  793. package/dist/shared/parsed-file.js.map +1 -0
  794. package/dist/shared/registry-clients.d.ts +93 -0
  795. package/dist/shared/registry-clients.d.ts.map +1 -0
  796. package/dist/shared/registry-clients.js +273 -0
  797. package/dist/shared/registry-clients.js.map +1 -0
  798. package/dist/shared/rules/framework-fixes.d.ts +48 -0
  799. package/dist/shared/rules/framework-fixes.d.ts.map +1 -0
  800. package/dist/shared/rules/framework-fixes.js +439 -0
  801. package/dist/shared/rules/framework-fixes.js.map +1 -0
  802. package/dist/shared/rules/index.d.ts +8 -0
  803. package/dist/shared/rules/index.d.ts.map +1 -0
  804. package/dist/shared/rules/index.js +18 -0
  805. package/dist/shared/rules/index.js.map +1 -0
  806. package/dist/shared/rules/metadata.d.ts +43 -0
  807. package/dist/shared/rules/metadata.d.ts.map +1 -0
  808. package/dist/shared/rules/metadata.js +819 -0
  809. package/dist/shared/rules/metadata.js.map +1 -0
  810. package/dist/shared/schema-semantics.d.ts +45 -0
  811. package/dist/shared/schema-semantics.d.ts.map +1 -0
  812. package/dist/shared/schema-semantics.js +193 -0
  813. package/dist/shared/schema-semantics.js.map +1 -0
  814. package/dist/shared/types.d.ts +337 -0
  815. package/dist/shared/types.d.ts.map +1 -0
  816. package/dist/shared/types.js +126 -0
  817. package/dist/shared/types.js.map +1 -0
  818. package/dist/tiers.d.ts +4 -4
  819. package/dist/tiers.d.ts.map +1 -1
  820. package/dist/tiers.js +17 -7
  821. package/dist/tiers.js.map +1 -1
  822. package/dist/types.d.ts +79 -9
  823. package/dist/types.d.ts.map +1 -1
  824. package/dist/types.js +34 -0
  825. package/dist/types.js.map +1 -1
  826. package/dist/utils/code-analysis.d.ts +39 -0
  827. package/dist/utils/code-analysis.d.ts.map +1 -0
  828. package/dist/utils/code-analysis.js +159 -0
  829. package/dist/utils/code-analysis.js.map +1 -0
  830. package/dist/utils/comment-analyzer.d.ts +38 -0
  831. package/dist/utils/comment-analyzer.d.ts.map +1 -0
  832. package/dist/utils/comment-analyzer.js +218 -0
  833. package/dist/utils/comment-analyzer.js.map +1 -0
  834. package/dist/utils/context-helpers.d.ts +108 -1
  835. package/dist/utils/context-helpers.d.ts.map +1 -1
  836. package/dist/utils/context-helpers.js +351 -2
  837. package/dist/utils/context-helpers.js.map +1 -1
  838. package/dist/utils/environment-context.d.ts +76 -0
  839. package/dist/utils/environment-context.d.ts.map +1 -0
  840. package/dist/utils/environment-context.js +271 -0
  841. package/dist/utils/environment-context.js.map +1 -0
  842. package/dist/utils/intent-detector.d.ts +66 -0
  843. package/dist/utils/intent-detector.d.ts.map +1 -0
  844. package/dist/utils/intent-detector.js +282 -0
  845. package/dist/utils/intent-detector.js.map +1 -0
  846. package/dist/utils/parsed-file.d.ts +51 -0
  847. package/dist/utils/parsed-file.d.ts.map +1 -0
  848. package/dist/utils/parsed-file.js +95 -0
  849. package/dist/utils/parsed-file.js.map +1 -0
  850. package/dist/utils/route-hierarchy.d.ts +50 -0
  851. package/dist/utils/route-hierarchy.d.ts.map +1 -0
  852. package/dist/utils/route-hierarchy.js +226 -0
  853. package/dist/utils/route-hierarchy.js.map +1 -0
  854. package/dist/utils/schema-semantics.d.ts +45 -0
  855. package/dist/utils/schema-semantics.d.ts.map +1 -0
  856. package/dist/utils/schema-semantics.js +193 -0
  857. package/dist/utils/schema-semantics.js.map +1 -0
  858. package/dist/validate/clients.d.ts +44 -0
  859. package/dist/validate/clients.d.ts.map +1 -0
  860. package/dist/validate/clients.js +81 -0
  861. package/dist/validate/clients.js.map +1 -0
  862. package/dist/validate/index.d.ts +41 -0
  863. package/dist/validate/index.d.ts.map +1 -0
  864. package/dist/validate/index.js +141 -0
  865. package/dist/validate/index.js.map +1 -0
  866. package/dist/validate/prompts/index.d.ts +8 -0
  867. package/dist/validate/prompts/index.d.ts.map +1 -0
  868. package/dist/validate/prompts/index.js +16 -0
  869. package/dist/validate/prompts/index.js.map +1 -0
  870. package/dist/validate/prompts/modules/ai-patterns.d.ts +19 -0
  871. package/dist/validate/prompts/modules/ai-patterns.d.ts.map +1 -0
  872. package/dist/validate/prompts/modules/ai-patterns.js +156 -0
  873. package/dist/validate/prompts/modules/ai-patterns.js.map +1 -0
  874. package/dist/validate/prompts/modules/auth-access.d.ts +9 -0
  875. package/dist/validate/prompts/modules/auth-access.d.ts.map +1 -0
  876. package/dist/validate/prompts/modules/auth-access.js +25 -0
  877. package/dist/validate/prompts/modules/auth-access.js.map +1 -0
  878. package/dist/validate/prompts/modules/common.d.ts +11 -0
  879. package/dist/validate/prompts/modules/common.d.ts.map +1 -0
  880. package/dist/validate/prompts/modules/common.js +186 -0
  881. package/dist/validate/prompts/modules/common.js.map +1 -0
  882. package/dist/validate/prompts/modules/index.d.ts +54 -0
  883. package/dist/validate/prompts/modules/index.d.ts.map +1 -0
  884. package/dist/validate/prompts/modules/index.js +186 -0
  885. package/dist/validate/prompts/modules/index.js.map +1 -0
  886. package/dist/validate/prompts/modules/owasp-classic.d.ts +8 -0
  887. package/dist/validate/prompts/modules/owasp-classic.d.ts.map +1 -0
  888. package/dist/validate/prompts/modules/owasp-classic.js +84 -0
  889. package/dist/validate/prompts/modules/owasp-classic.js.map +1 -0
  890. package/dist/validate/prompts/modules/secrets-crypto.d.ts +8 -0
  891. package/dist/validate/prompts/modules/secrets-crypto.d.ts.map +1 -0
  892. package/dist/validate/prompts/modules/secrets-crypto.js +68 -0
  893. package/dist/validate/prompts/modules/secrets-crypto.js.map +1 -0
  894. package/dist/validate/prompts/modules/xss-prompt.d.ts +8 -0
  895. package/dist/validate/prompts/modules/xss-prompt.d.ts.map +1 -0
  896. package/dist/validate/prompts/modules/xss-prompt.js +22 -0
  897. package/dist/validate/prompts/modules/xss-prompt.js.map +1 -0
  898. package/dist/validate/prompts/semantic-analysis.d.ts +15 -0
  899. package/dist/validate/prompts/semantic-analysis.d.ts.map +1 -0
  900. package/dist/validate/prompts/semantic-analysis.js +169 -0
  901. package/dist/validate/prompts/semantic-analysis.js.map +1 -0
  902. package/dist/validate/prompts/validation.d.ts +18 -0
  903. package/dist/validate/prompts/validation.d.ts.map +1 -0
  904. package/dist/validate/prompts/validation.js +25 -0
  905. package/dist/validate/prompts/validation.js.map +1 -0
  906. package/dist/validate/providers/anthropic.d.ts +17 -0
  907. package/dist/validate/providers/anthropic.d.ts.map +1 -0
  908. package/dist/validate/providers/anthropic.js +260 -0
  909. package/dist/validate/providers/anthropic.js.map +1 -0
  910. package/dist/validate/providers/index.d.ts +8 -0
  911. package/dist/validate/providers/index.d.ts.map +1 -0
  912. package/dist/validate/providers/index.js +13 -0
  913. package/dist/validate/providers/index.js.map +1 -0
  914. package/dist/validate/providers/openai.d.ts +14 -0
  915. package/dist/validate/providers/openai.d.ts.map +1 -0
  916. package/dist/validate/providers/openai.js +336 -0
  917. package/dist/validate/providers/openai.js.map +1 -0
  918. package/dist/validate/request-builder.d.ts +61 -0
  919. package/dist/validate/request-builder.d.ts.map +1 -0
  920. package/dist/validate/request-builder.js +346 -0
  921. package/dist/validate/request-builder.js.map +1 -0
  922. package/dist/validate/types.d.ts +88 -0
  923. package/dist/validate/types.d.ts.map +1 -0
  924. package/dist/validate/types.js +38 -0
  925. package/dist/validate/types.js.map +1 -0
  926. package/dist/validate/utils/context-extractor.d.ts +55 -0
  927. package/dist/validate/utils/context-extractor.d.ts.map +1 -0
  928. package/dist/validate/utils/context-extractor.js +161 -0
  929. package/dist/validate/utils/context-extractor.js.map +1 -0
  930. package/dist/validate/utils/index.d.ts +11 -0
  931. package/dist/validate/utils/index.d.ts.map +1 -0
  932. package/dist/validate/utils/index.js +27 -0
  933. package/dist/validate/utils/index.js.map +1 -0
  934. package/dist/validate/utils/path-helpers.d.ts +21 -0
  935. package/dist/validate/utils/path-helpers.d.ts.map +1 -0
  936. package/dist/validate/utils/path-helpers.js +69 -0
  937. package/dist/validate/utils/path-helpers.js.map +1 -0
  938. package/dist/validate/utils/response-parser.d.ts +40 -0
  939. package/dist/validate/utils/response-parser.d.ts.map +1 -0
  940. package/dist/validate/utils/response-parser.js +286 -0
  941. package/dist/validate/utils/response-parser.js.map +1 -0
  942. package/dist/validate/utils/retry.d.ts +15 -0
  943. package/dist/validate/utils/retry.d.ts.map +1 -0
  944. package/dist/validate/utils/retry.js +62 -0
  945. package/dist/validate/utils/retry.js.map +1 -0
  946. package/package.json +8 -7
  947. package/src/__tests__/benchmark/fixtures/layer1/agent-skill-injection.ts +204 -0
  948. package/src/__tests__/benchmark/fixtures/layer1/index.ts +3 -0
  949. package/src/__tests__/benchmark/fixtures/layer2/index.ts +27 -0
  950. package/src/__tests__/benchmark/fixtures/layer2/log-injection.ts +147 -0
  951. package/src/__tests__/benchmark/fixtures/layer2/phase5-excessive-agency.ts +580 -0
  952. package/src/__tests__/benchmark/fixtures/layer2/security-headers.ts +197 -0
  953. package/src/__tests__/benchmark/fixtures/layer2/sprint6-ai-enhancements.ts +515 -0
  954. package/src/__tests__/benchmark/fixtures/layer2/ssrf-detection.ts +210 -0
  955. package/src/__tests__/benchmark/fixtures/layer2/xxe-detection.ts +195 -0
  956. package/src/__tests__/benchmark/run-depth-validation.ts +12 -12
  957. package/src/__tests__/benchmark/run-real-world-test.ts +4 -4
  958. package/src/__tests__/benchmark/types.ts +1 -1
  959. package/src/__tests__/benchmark/utils/test-runner.ts +3 -3
  960. package/src/__tests__/category-filter.test.ts +478 -0
  961. package/src/__tests__/context-engine/cross-file-taint.test.ts +284 -0
  962. package/src/__tests__/context-engine/framework-models.test.ts +457 -0
  963. package/src/__tests__/context-engine/function-classifier.test.ts +146 -0
  964. package/src/__tests__/context-engine/import-resolver.test.ts +328 -0
  965. package/src/__tests__/context-engine/integration.test.ts +320 -0
  966. package/src/__tests__/context-engine/module-graph.test.ts +159 -0
  967. package/src/__tests__/context-engine/route-discovery/auth-resolver.test.ts +353 -0
  968. package/src/__tests__/context-engine/route-discovery/express.test.ts +150 -0
  969. package/src/__tests__/context-engine/route-discovery/nextjs.test.ts +138 -0
  970. package/src/__tests__/context-engine/route-discovery/python.test.ts +95 -0
  971. package/src/__tests__/context-engine/sanitiser-detection.test.ts +187 -0
  972. package/src/__tests__/context-engine/sink-matcher.test.ts +251 -0
  973. package/src/__tests__/context-engine/source-discovery.test.ts +186 -0
  974. package/src/__tests__/context-engine/taint-tracker.test.ts +182 -0
  975. package/src/__tests__/regression/agent-skill-benign.test.ts +174 -0
  976. package/src/__tests__/regression/known-false-positives.test.ts +801 -3
  977. package/src/__tests__/score/adjustments.test.ts +385 -0
  978. package/src/__tests__/score/confidence.test.ts +283 -0
  979. package/src/__tests__/score/framework-scoring.test.ts +275 -0
  980. package/src/__tests__/score/route-scoring.test.ts +156 -0
  981. package/src/__tests__/score/scoring-integration.test.ts +165 -0
  982. package/src/__tests__/score/taint-adjustments.test.ts +244 -0
  983. package/src/__tests__/snapshots/__snapshots__/anthropic-validation-refactor.test.ts.snap +50 -58
  984. package/src/__tests__/snapshots/__snapshots__/dangerous-functions-refactor.test.ts.snap +52 -0
  985. package/src/__tests__/snapshots/__snapshots__/scan-depth.test.ts.snap +3 -12
  986. package/src/__tests__/snapshots/anthropic-validation-refactor.test.ts +3 -3
  987. package/src/__tests__/snapshots/dangerous-functions-refactor.test.ts +1 -1
  988. package/src/__tests__/snapshots/scan-depth.test.ts +3 -3
  989. package/src/__tests__/validate/route-annotations.test.ts +138 -0
  990. package/src/__tests__/validation/analyze-results.ts +1 -1
  991. package/src/__tests__/validation/extract-for-triage.ts +1 -1
  992. package/src/__tests__/validation/fp-deep-analysis.ts +1 -1
  993. package/src/__tests__/validation/run-validation.ts +7 -7
  994. package/src/{layer2/ai-agent-tools.ts → detect/ai-code/agent-tools.ts} +729 -4
  995. package/src/{layer2 → detect/ai-code}/byok-patterns.ts +20 -6
  996. package/src/{layer2/ai-endpoint-protection.ts → detect/ai-code/endpoint-protection.ts} +10 -4
  997. package/src/{layer2/ai-execution-sinks.ts → detect/ai-code/execution-sinks.ts} +272 -46
  998. package/src/{layer2/ai-fingerprinting.ts → detect/ai-code/fingerprinting.ts} +46 -34
  999. package/src/detect/ai-code/index.ts +11 -0
  1000. package/src/{layer2/ai-mcp-security.ts → detect/ai-code/mcp-security.ts} +212 -5
  1001. package/src/{layer2 → detect/ai-code}/model-supply-chain.ts +85 -6
  1002. package/src/{layer2/ai-package-hallucination.ts → detect/ai-code/package-hallucination.ts} +170 -6
  1003. package/src/{layer2/ai-prompt-hygiene.ts → detect/ai-code/prompt-hygiene.ts} +393 -28
  1004. package/src/{layer2/ai-rag-safety.ts → detect/ai-code/rag-safety.ts} +91 -4
  1005. package/src/{layer2/ai-schema-validation.ts → detect/ai-code/schema-validation.ts} +10 -4
  1006. package/src/detect/config/agent-skill-injection.ts +551 -0
  1007. package/src/{layer1 → detect/config}/comments.ts +8 -2
  1008. package/src/{layer1 → detect/config}/file-flags.ts +23 -6
  1009. package/src/detect/config/index.ts +6 -0
  1010. package/src/{layer3 → detect/config}/osv-check.ts +3 -2
  1011. package/src/{layer3 → detect/config}/package-check.ts +3 -2
  1012. package/src/{layer1 → detect/config}/urls.ts +196 -15
  1013. package/src/detect/index.ts +131 -0
  1014. package/src/{layer1 → detect/secrets}/config-audit.ts +56 -12
  1015. package/src/{layer1 → detect/secrets}/config-mcp-audit.ts +11 -4
  1016. package/src/{layer1 → detect/secrets}/entropy.ts +256 -11
  1017. package/src/{layer1 → detect/secrets}/index.ts +43 -46
  1018. package/src/{layer1 → detect/secrets}/patterns.ts +51 -6
  1019. package/src/{layer1 → detect/secrets}/weak-crypto.ts +174 -17
  1020. package/src/{layer2/auth-antipatterns.ts → detect/structural/auth-patterns.ts} +249 -27
  1021. package/src/{layer2 → detect/structural}/dangerous-functions/dom-xss.ts +94 -22
  1022. package/src/{layer2 → detect/structural}/dangerous-functions/index.ts +672 -65
  1023. package/src/{layer2 → detect/structural}/dangerous-functions/json-parse.ts +10 -2
  1024. package/src/{layer2 → detect/structural}/dangerous-functions/math-random.ts +269 -17
  1025. package/src/{layer2 → detect/structural}/dangerous-functions/patterns.ts +4 -2
  1026. package/src/{layer2 → detect/structural}/dangerous-functions/request-validation.ts +10 -2
  1027. package/src/detect/structural/dangerous-functions/utils/control-flow.ts +35 -0
  1028. package/src/{layer2 → detect/structural}/dangerous-functions/utils/schema-validation.ts +16 -1
  1029. package/src/{layer2 → detect/structural}/data-exposure.ts +23 -40
  1030. package/src/{layer2 → detect/structural}/framework-checks.ts +13 -12
  1031. package/src/{layer2 → detect/structural}/index.ts +144 -122
  1032. package/src/detect/structural/log-injection.ts +254 -0
  1033. package/src/{layer2 → detect/structural}/logic-gates.ts +69 -24
  1034. package/src/{layer2 → detect/structural}/risky-imports.ts +10 -4
  1035. package/src/detect/structural/security-headers.ts +231 -0
  1036. package/src/detect/structural/ssrf-detection.ts +300 -0
  1037. package/src/{layer2 → detect/structural}/variables.ts +10 -4
  1038. package/src/detect/structural/xxe-detection.ts +295 -0
  1039. package/src/index.ts +64 -1038
  1040. package/src/{utils → model}/auth-helper-detector.ts +1 -1
  1041. package/src/model/cross-file-taint.ts +374 -0
  1042. package/src/model/framework-models/django.ts +82 -0
  1043. package/src/model/framework-models/express.ts +54 -0
  1044. package/src/model/framework-models/index.ts +116 -0
  1045. package/src/model/framework-models/nextjs.ts +69 -0
  1046. package/src/model/framework-models/prisma.ts +57 -0
  1047. package/src/model/framework-models/react.ts +63 -0
  1048. package/src/model/framework-models/sequelize.ts +63 -0
  1049. package/src/model/framework-models/types.ts +46 -0
  1050. package/src/model/function-classifier.ts +184 -0
  1051. package/src/model/import-resolver.ts +453 -0
  1052. package/src/{utils → model}/imported-auth-detector.ts +21 -85
  1053. package/src/model/index.ts +353 -0
  1054. package/src/{utils → model}/middleware-detector.ts +156 -17
  1055. package/src/model/module-graph.ts +254 -0
  1056. package/src/{utils → model}/oauth-flow-detector.ts +1 -1
  1057. package/src/{utils/project-context-builder.ts → model/project-context.ts} +1 -1
  1058. package/src/model/route-auth-resolver.ts +216 -0
  1059. package/src/model/route-discovery/express.ts +251 -0
  1060. package/src/model/route-discovery/index.ts +83 -0
  1061. package/src/model/route-discovery/nextjs.ts +216 -0
  1062. package/src/model/route-discovery/python.ts +214 -0
  1063. package/src/model/route-discovery/types.ts +48 -0
  1064. package/src/model/route-discovery/utils.ts +54 -0
  1065. package/src/model/route-hierarchy.ts +250 -0
  1066. package/src/model/sanitiser-detection.ts +268 -0
  1067. package/src/model/sink-matcher.ts +178 -0
  1068. package/src/model/sink-patterns.ts +109 -0
  1069. package/src/model/source-discovery.ts +209 -0
  1070. package/src/model/taint-tracker.ts +333 -0
  1071. package/src/model/taint-types.ts +149 -0
  1072. package/src/{utils → model}/trpc-analyzer.ts +1 -1
  1073. package/src/{utils/context-helpers.ts → parse/file-classifier.ts} +462 -2
  1074. package/src/{utils → parse}/path-exclusions.ts +1 -1
  1075. package/src/pipeline/config.ts +81 -0
  1076. package/src/pipeline/index.ts +437 -0
  1077. package/src/{modes → pipeline/modes}/incremental.ts +6 -6
  1078. package/src/postprocess/aggregation.ts +74 -0
  1079. package/src/postprocess/contradictions.ts +128 -0
  1080. package/src/postprocess/dedup.ts +62 -0
  1081. package/src/postprocess/filtering/__tests__/pipeline.test.ts +134 -0
  1082. package/src/postprocess/filtering/context-adjustments.ts +111 -0
  1083. package/src/postprocess/filtering/index.ts +10 -0
  1084. package/src/postprocess/filtering/pipeline.ts +130 -0
  1085. package/src/postprocess/index.ts +118 -0
  1086. package/src/{suppression → postprocess/suppression}/config-loader.ts +1 -1
  1087. package/src/{suppression → postprocess/suppression}/hash.ts +1 -1
  1088. package/src/{suppression → postprocess/suppression}/inline-parser.ts +1 -1
  1089. package/src/{suppression → postprocess/suppression}/manager.ts +1 -1
  1090. package/src/{suppression → postprocess/suppression}/types.ts +2 -2
  1091. package/src/postprocess/validation-cap.ts +66 -0
  1092. package/src/report/build-result.ts +94 -0
  1093. package/src/report/enrichment.ts +52 -0
  1094. package/src/report/formatters/__tests__/ai-context.test.ts +254 -0
  1095. package/src/report/formatters/ai-context.ts +302 -0
  1096. package/src/{formatters → report/formatters}/cli-terminal.ts +11 -11
  1097. package/src/{formatters → report/formatters}/github-comment.ts +4 -4
  1098. package/src/{formatters → report/formatters}/grouping.ts +8 -8
  1099. package/src/report/formatters/ide/__tests__/ide.test.ts +319 -0
  1100. package/src/report/formatters/ide/claude-code.ts +110 -0
  1101. package/src/report/formatters/ide/cursor.ts +147 -0
  1102. package/src/report/formatters/ide/index.ts +216 -0
  1103. package/src/report/formatters/ide/windsurf.ts +135 -0
  1104. package/src/{formatters → report/formatters}/index.ts +24 -0
  1105. package/src/{formatters → report/formatters}/vscode-diagnostic.ts +1 -1
  1106. package/src/report/summary.ts +70 -0
  1107. package/src/score/adjustments.ts +387 -0
  1108. package/src/{layer3/anthropic → score}/auto-dismiss.ts +26 -14
  1109. package/src/score/confidence.ts +66 -0
  1110. package/src/score/index.ts +316 -0
  1111. package/src/score/types.ts +187 -0
  1112. package/src/shared/__tests__/code-analysis.test.ts +165 -0
  1113. package/src/shared/__tests__/parsed-file.test.ts +124 -0
  1114. package/src/shared/ai-context/__tests__/manager.test.ts +193 -0
  1115. package/src/shared/ai-context/index.ts +15 -0
  1116. package/src/shared/ai-context/manager.ts +145 -0
  1117. package/src/{baseline → shared/baseline}/__tests__/diff.test.ts +2 -2
  1118. package/src/{baseline → shared/baseline}/__tests__/manager.test.ts +2 -2
  1119. package/src/{baseline → shared/baseline}/diff.ts +1 -1
  1120. package/src/{baseline → shared/baseline}/manager.ts +1 -1
  1121. package/src/shared/category-filter.ts +400 -0
  1122. package/src/{layer2/dangerous-functions/utils/control-flow.ts → shared/code-analysis.ts} +56 -39
  1123. package/src/shared/comment-analyzer.ts +249 -0
  1124. package/src/shared/environment-context.ts +304 -0
  1125. package/src/shared/intent-detector.ts +318 -0
  1126. package/src/shared/parsed-file.ts +103 -0
  1127. package/src/{rules → shared/rules}/__tests__/metadata.test.ts +7 -0
  1128. package/src/{rules → shared/rules}/framework-fixes.ts +1 -1
  1129. package/src/{rules → shared/rules}/metadata.ts +94 -0
  1130. package/src/shared/schema-semantics.ts +233 -0
  1131. package/src/{types.ts → shared/types.ts} +142 -11
  1132. package/src/tiers.ts +27 -10
  1133. package/src/validate/__tests__/context-extractor.test.ts +191 -0
  1134. package/src/validate/__tests__/prompt-assembly.test.ts +233 -0
  1135. package/src/validate/__tests__/request-builder.test.ts +347 -0
  1136. package/src/{layer3/anthropic → validate}/index.ts +8 -7
  1137. package/src/{layer3/anthropic → validate}/prompts/index.ts +2 -0
  1138. package/src/validate/prompts/modules/ai-patterns.ts +153 -0
  1139. package/src/validate/prompts/modules/auth-access.ts +22 -0
  1140. package/src/validate/prompts/modules/common.ts +183 -0
  1141. package/src/validate/prompts/modules/index.ts +204 -0
  1142. package/src/validate/prompts/modules/owasp-classic.ts +81 -0
  1143. package/src/validate/prompts/modules/secrets-crypto.ts +65 -0
  1144. package/src/validate/prompts/modules/xss-prompt.ts +19 -0
  1145. package/src/validate/prompts/validation.ts +20 -0
  1146. package/src/{layer3/anthropic → validate}/providers/anthropic.ts +28 -27
  1147. package/src/validate/providers/index.ts +8 -0
  1148. package/src/{layer3/anthropic → validate}/providers/openai.ts +30 -25
  1149. package/src/validate/request-builder.ts +448 -0
  1150. package/src/{layer3/anthropic → validate}/types.ts +1 -1
  1151. package/src/validate/utils/context-extractor.ts +220 -0
  1152. package/src/{layer3/anthropic → validate}/utils/index.ts +10 -0
  1153. package/src/{layer3/anthropic → validate}/utils/response-parser.ts +2 -1
  1154. package/src/layer3/anthropic/prompts/validation.ts +0 -419
  1155. package/src/layer3/anthropic/providers/index.ts +0 -8
  1156. package/src/layer3/anthropic/request-builder.ts +0 -150
  1157. package/src/layer3/index.ts +0 -168
  1158. /package/src/{layer3 → detect/config}/__tests__/osv-check.test.ts +0 -0
  1159. /package/src/{layer2 → detect/structural}/__tests__/math-random-enhanced.test.ts +0 -0
  1160. /package/src/{layer2 → detect/structural}/dangerous-functions/child-process.ts +0 -0
  1161. /package/src/{layer2 → detect/structural}/dangerous-functions/utils/helpers.ts +0 -0
  1162. /package/src/{layer2 → detect/structural}/dangerous-functions/utils/index.ts +0 -0
  1163. /package/src/{suppression → postprocess/suppression}/__tests__/config-loader.test.ts +0 -0
  1164. /package/src/{suppression → postprocess/suppression}/__tests__/hash.test.ts +0 -0
  1165. /package/src/{suppression → postprocess/suppression}/__tests__/inline-parser.test.ts +0 -0
  1166. /package/src/{suppression → postprocess/suppression}/__tests__/manager.test.ts +0 -0
  1167. /package/src/{suppression → postprocess/suppression}/index.ts +0 -0
  1168. /package/src/{baseline → shared/baseline}/index.ts +0 -0
  1169. /package/src/{baseline → shared/baseline}/types.ts +0 -0
  1170. /package/src/{utils → shared}/diff-detector.ts +0 -0
  1171. /package/src/{utils → shared}/diff-parser.ts +0 -0
  1172. /package/src/{utils → shared}/registry-clients.ts +0 -0
  1173. /package/src/{rules → shared/rules}/__tests__/framework-fixes.test.ts +0 -0
  1174. /package/src/{rules → shared/rules}/index.ts +0 -0
  1175. /package/src/{layer3/anthropic → validate}/clients.ts +0 -0
  1176. /package/src/{layer3/anthropic → validate}/prompts/semantic-analysis.ts +0 -0
  1177. /package/src/{layer3/anthropic → validate}/utils/path-helpers.ts +0 -0
  1178. /package/src/{layer3/anthropic → validate}/utils/retry.ts +0 -0
package/src/index.ts CHANGED
@@ -1,1047 +1,47 @@
1
1
  /**
2
- * Scanner Orchestrator
3
- * Coordinates all three scanning layers and produces final results
4
- */
5
-
6
- import type {
7
- ScanFile,
8
- ScanResult,
9
- Vulnerability,
10
- SeverityCounts,
11
- CategoryCounts,
12
- VulnerabilityCategory,
13
- ScanMode,
14
- ScanModeConfig,
15
- ScanDepth,
16
- CancellationToken,
17
- SuppressedVulnerabilitySummary,
18
- } from './types'
19
- import { SCANNABLE_EXTENSIONS, SPECIAL_FILES, MAX_FILE_SIZE, SCAN_MODE_DEFAULTS } from './types'
20
- import { runLayer1Scan } from './layer1'
21
- import { runLayer2Scan } from './layer2'
22
- import { runLayer3Scan } from './layer3'
23
- import { validateFindingsWithAI, applyAutoDismissRules, type ValidationStats } from './layer3/anthropic'
24
- import { aggregateLocalhostFindings } from './layer1/urls'
25
- import { detectGlobalAuthMiddleware, type MiddlewareAuthConfig, getRoutePathFromFile, isRouteProtectedByMiddleware } from './utils/middleware-detector'
26
- import { detectAuthHelpers } from './utils/auth-helper-detector'
27
- import { buildFileAuthImports } from './utils/imported-auth-detector'
28
- // Tier system imports for filtering by scan depth
29
- import {
30
- type DetectorTier,
31
- type TierStats,
32
- getTierForCategory,
33
- isTierVisibleAtDepth,
34
- shouldValidateWithAI,
35
- computeTierStats,
36
- formatTierStats,
37
- } from './tiers'
38
- // Suppression system
39
- import { SuppressionManager } from './suppression'
40
- // Rule metadata for actionable output (PRO-82)
41
- import { getRuleMetadata } from './rules'
42
- // Framework-aware fix suggestions (PRO-83)
43
- import { getFrameworkFix } from './rules/framework-fixes'
44
- // Project context for framework detection
45
- import { buildProjectContext, type ProjectContext } from './utils/project-context-builder'
46
-
47
- // Maximum candidates per file to send to AI validation (cost control)
48
- const MAX_VALIDATION_CANDIDATES_PER_FILE = 10
49
-
50
- /**
51
- * Classify vulnerabilities into tier groups for filtering
52
- */
53
- interface TierClassification {
54
- /** Tier A (core): High-precision, always visible */
55
- core: Vulnerability[]
56
- /** Tier B (ai_assisted): Context-heavy, needs AI validation */
57
- ai_assisted: Vulnerability[]
58
- /** Tier C (experimental): Hidden from users, internal use only */
59
- experimental: Vulnerability[]
60
- }
61
-
62
- /**
63
- * Classify vulnerabilities by their detector tier
64
- */
65
- function classifyByTier(vulnerabilities: Vulnerability[]): TierClassification {
66
- const result: TierClassification = {
67
- core: [],
68
- ai_assisted: [],
69
- experimental: [],
70
- }
71
-
72
- for (const vuln of vulnerabilities) {
73
- const tier = getTierForCategory(vuln.category, vuln.layer)
74
- result[tier].push(vuln)
75
- }
76
-
77
- return result
78
- }
79
-
80
- /**
81
- * Filter vulnerabilities based on scan depth and tier
82
- *
83
- * - cheap: Only Tier A (core) findings are surfaced
84
- * - validated: Tier A visible, Tier B goes through AI validation
85
- * - deep: Same as validated, plus Layer 3 semantic analysis
86
- *
87
- * Tier C (experimental) is NEVER surfaced to users, regardless of depth.
88
- */
89
- function filterByTierAndDepth(
90
- vulnerabilities: Vulnerability[],
91
- depth: ScanDepth
92
- ): {
93
- /** Findings to surface directly (no AI validation needed) */
94
- toSurface: Vulnerability[]
95
- /** Findings to send through AI validation */
96
- toValidate: Vulnerability[]
97
- /** Findings hidden from users (Tier C) */
98
- hidden: Vulnerability[]
99
- /** Tier stats for logging */
100
- tierStats: TierStats
101
- } {
102
- const classified = classifyByTier(vulnerabilities)
103
- const tierStats = computeTierStats(
104
- vulnerabilities.map(v => ({ category: v.category, layer: v.layer }))
105
- )
106
-
107
- switch (depth) {
108
- case 'cheap':
109
- // Only Tier A is visible, no AI validation
110
- return {
111
- toSurface: classified.core,
112
- toValidate: [],
113
- hidden: [...classified.ai_assisted, ...classified.experimental],
114
- tierStats,
115
- }
116
-
117
- case 'validated':
118
- case 'deep':
119
- // Tier A always surfaces, Tier B goes to AI validation
120
- // For findings that already require AI validation, only include Tier A/B
121
- const coreRequiringValidation = classified.core.filter(v =>
122
- v.requiresAIValidation ||
123
- v.category === 'high_entropy_string' ||
124
- v.category === 'hardcoded_secret' ||
125
- (v.category === 'sensitive_url' && v.severity !== 'info')
126
- )
127
- const coreNotRequiringValidation = classified.core.filter(v =>
128
- !coreRequiringValidation.includes(v)
129
- )
130
-
131
- return {
132
- toSurface: coreNotRequiringValidation,
133
- toValidate: [...coreRequiringValidation, ...classified.ai_assisted],
134
- hidden: classified.experimental,
135
- tierStats,
136
- }
137
- }
138
- }
139
-
140
- export interface ScanOptions {
141
- /** Enable AI-powered validation and analysis */
142
- enableAI?: boolean
143
- /** Maximum files to scan */
144
- maxFiles?: number
145
- /** Branch being scanned */
146
- branch?: string
147
- /** Scan mode configuration (full vs incremental) */
148
- scanMode?: ScanMode | ScanModeConfig
149
- /** Scan depth (cheap/validated/deep) - controls AI usage */
150
- scanDepth?: ScanDepth
151
- /** Suppress console.log output (for interactive CLI mode) */
152
- quiet?: boolean
153
- /** Cancellation token for aborting scans gracefully */
154
- cancellationToken?: CancellationToken
155
- /** Project path for loading suppression config (defaults to cwd) */
156
- projectPath?: string
157
- /** Include suppressed findings in output (for --show-suppressed) */
158
- showSuppressed?: boolean
159
- }
160
-
161
- export interface ScanProgress {
162
- status: 'fetching' | 'layer1' | 'layer2' | 'layer3' | 'validating' | 'complete' | 'failed'
163
- message: string
164
- filesProcessed: number
165
- totalFiles: number
166
- vulnerabilitiesFound: number
167
- }
168
-
169
- export type ProgressCallback = (progress: ScanProgress) => void
170
-
171
- /**
172
- * Resolve scan mode configuration from options
173
- *
174
- * Handles both scan mode (full/incremental) and depth (cheap/validated/deep).
175
- * Depth controls AI usage:
176
- * - cheap: skip AI validation + skip Layer 3
177
- * - validated: run AI validation, skip Layer 3
178
- * - deep: run AI validation + Layer 3
179
- */
180
- function resolveScanModeConfig(options: ScanOptions): ScanModeConfig {
181
- const scanModeOption = options.scanMode
182
-
183
- // Determine base mode
184
- const mode: ScanMode = !scanModeOption ? 'full'
185
- : typeof scanModeOption === 'string' ? scanModeOption
186
- : scanModeOption.mode
187
-
188
- const defaults = SCAN_MODE_DEFAULTS[mode]
189
-
190
- // Build config from defaults + explicit overrides
191
- let config: ScanModeConfig = {
192
- ...defaults,
193
- mode,
194
- ...(typeof scanModeOption === 'object' ? scanModeOption : {}),
195
- }
196
-
197
- // Apply depth mode (default: 'cheap')
198
- const depth = options.scanDepth ?? 'cheap'
199
- config.scanDepth = depth
200
-
201
- // Map depth to skipAIValidation/skipLayer3 unless explicitly overridden
202
- const hasExplicitSkipAI = typeof scanModeOption === 'object' && scanModeOption.skipAIValidation !== undefined
203
- const hasExplicitSkipL3 = typeof scanModeOption === 'object' && scanModeOption.skipLayer3 !== undefined
204
-
205
- if (!hasExplicitSkipAI) {
206
- config.skipAIValidation = depth === 'cheap'
207
- }
208
- if (!hasExplicitSkipL3) {
209
- config.skipLayer3 = depth !== 'deep'
210
- }
211
-
212
- return config
213
- }
214
-
215
- /**
216
- * Run a complete security scan on the provided files
217
- *
218
- * Supports two scan modes:
219
- * - full: Complete scan with AI validation on all files (initial onboarding, deep audits)
220
- * - incremental: Focused scan on changed files only (CI/CD, fast feedback)
221
- */
222
- export async function runScan(
223
- files: ScanFile[],
224
- repoInfo: { name: string; url: string; branch: string },
225
- options: ScanOptions = {},
226
- onProgress?: ProgressCallback
227
- ): Promise<ScanResult> {
228
- const startTime = Date.now()
229
- const allVulnerabilities: Vulnerability[] = []
230
-
231
- // Resolve scan mode configuration
232
- const scanModeConfig = resolveScanModeConfig(options)
233
- const isIncremental = scanModeConfig.mode === 'incremental'
234
- const depth = scanModeConfig.scanDepth || 'cheap'
235
- const quiet = options.quiet ?? false
236
- const cancellationToken = options.cancellationToken
237
-
238
- // Conditional logging helper - suppresses output in quiet mode (interactive CLI)
239
- const log = (message: string) => {
240
- if (!quiet) {
241
- console.log(message)
242
- }
243
- }
244
-
245
- // Helper to check cancellation and throw if cancelled
246
- const checkCancelled = () => {
247
- if (cancellationToken?.cancelled) {
248
- throw new Error(`Scan cancelled: ${cancellationToken.reason || 'user requested'}`)
249
- }
250
- }
251
-
252
- log(`[Scanner] repo=${repoInfo.name} mode=${scanModeConfig.mode} depth=${depth} files=${files.length}`)
253
- if (isIncremental && scanModeConfig.changedFiles) {
254
- log(`[Scanner] repo=${repoInfo.name} incremental_files=${scanModeConfig.changedFiles.length}`)
255
- }
256
-
257
- // Report progress helper
258
- const reportProgress = (
259
- status: ScanProgress['status'],
260
- message: string,
261
- vulnerabilitiesFound: number = allVulnerabilities.length
262
- ) => {
263
- if (onProgress) {
264
- onProgress({
265
- status,
266
- message,
267
- filesProcessed: files.length,
268
- totalFiles: files.length,
269
- vulnerabilitiesFound,
270
- })
271
- }
272
- }
273
-
274
- // For incremental scans, filter to only changed files for AI-heavy operations
275
- // but still run static analysis on all files for context
276
- const filesForAI = isIncremental && scanModeConfig.changedFiles
277
- ? files.filter(f => scanModeConfig.changedFiles!.some(cf => f.path.endsWith(cf) || f.path.includes(cf)))
278
- : files
279
-
280
- // Declare variables that need to be accessible in catch block
281
- let middlewareConfig: MiddlewareAuthConfig | undefined
282
- let capturedValidationStats: ValidationStats | undefined
283
-
284
- try {
285
- checkCancelled()
286
-
287
- // Detect global auth middleware before scanning (always on all files for context)
288
- middlewareConfig = detectGlobalAuthMiddleware(files)
289
- if (middlewareConfig.hasAuthMiddleware) {
290
- log(`[Scanner] repo=${repoInfo.name} auth_middleware=${middlewareConfig.authType || 'unknown'} file=${middlewareConfig.middlewareFile}`)
291
- }
292
-
293
- // Build imported auth registry for cross-file middleware detection
294
- const fileAuthImports = buildFileAuthImports(files)
295
- const filesWithImportedAuth = Array.from(fileAuthImports.values()).filter(f => f.usesImportedAuth).length
296
- if (filesWithImportedAuth > 0) {
297
- log(`[Scanner] repo=${repoInfo.name} files_with_imported_auth=${filesWithImportedAuth}`)
298
- }
299
-
300
- checkCancelled()
301
-
302
- // Phase timing tracking
303
- const phaseTiming: { layer1?: number; layer2?: number; aiValidation?: number; layer3?: number } = {}
304
-
305
- // Layer 1: Surface Scan
306
- const layer1Start = Date.now()
307
- reportProgress('layer1', 'Running surface scan (patterns, entropy, config)...')
308
- let layer1Result = await runLayer1Scan(files, onProgress, cancellationToken)
309
-
310
- // Aggregate repeated localhost findings
311
- const layer1RawCount = layer1Result.vulnerabilities.length
312
- layer1Result = {
313
- ...layer1Result,
314
- vulnerabilities: aggregateLocalhostFindings(layer1Result.vulnerabilities)
315
- }
316
- phaseTiming.layer1 = Date.now() - layer1Start
317
- log(`[Layer1] repo=${repoInfo.name} findings_raw=${layer1RawCount} findings_deduped=${layer1Result.vulnerabilities.length} duration=${phaseTiming.layer1}ms`)
318
-
319
- checkCancelled()
320
-
321
- // Layer 2: Structural Scan
322
- const layer2Start = Date.now()
323
- reportProgress('layer2', 'Running structural scan (variables, logic gates)...', layer1Result.vulnerabilities.length)
324
- const layer2Result = await runLayer2Scan(files, { middlewareConfig, fileAuthImports }, onProgress, cancellationToken)
325
-
326
- // Format heuristic breakdown for logging
327
- const heuristicBreakdown = Object.entries(layer2Result.stats.raw)
328
- .filter(([, count]) => count > 0)
329
- .map(([name, count]) => `${name}:${count}`)
330
- .join(',')
331
- phaseTiming.layer2 = Date.now() - layer2Start
332
- log(`[Layer2] repo=${repoInfo.name} findings_raw=${Object.values(layer2Result.stats.raw).reduce((a, b) => a + b, 0)} findings_deduped=${layer2Result.vulnerabilities.length} duration=${phaseTiming.layer2}ms heuristic_breakdown={${heuristicBreakdown}}`)
333
-
334
- // Combine Layer 1 and Layer 2 findings
335
- const layer12Findings = [...layer1Result.vulnerabilities, ...layer2Result.vulnerabilities]
336
-
337
- // Aggregate noisy findings BEFORE tier filtering to reduce noise
338
- const beforeAggregationCount = layer12Findings.length
339
- const aggregatedFindings = aggregateNoisyFindings(layer12Findings)
340
- const aggregatedCount = beforeAggregationCount - aggregatedFindings.length
341
-
342
- // Build project context for framework-aware fixes (PRO-83)
343
- // This detects frameworks (Next.js, Express), ORMs (Prisma, Drizzle), and frontend libs (React, Vue)
344
- const projectContext = buildProjectContext(files)
345
-
346
- // Enrich findings with metadata from rule registry (PRO-82)
347
- // PRO-83: Uses projectContext for framework-specific fix suggestions
348
- // This provides default impact, evidence, fixSteps, references for all findings
349
- // AI validation can override these later with context-aware content
350
- const enrichedFindings = enrichWithMetadata(aggregatedFindings, projectContext)
351
-
352
- // Apply tier-based filtering based on scan depth
353
- // This is the key integration point for the detector tier system
354
- const tierFiltered = filterByTierAndDepth(enrichedFindings, depth)
355
-
356
- // Log tier breakdown
357
- log(`[Scanner] repo=${repoInfo.name} tier_breakdown=${formatTierStats(tierFiltered.tierStats)}`)
358
- log(`[Scanner] repo=${repoInfo.name} depth=${depth} tier_routing: surface=${tierFiltered.toSurface.length} validate=${tierFiltered.toValidate.length} hidden=${tierFiltered.hidden.length}`)
359
-
360
- // For cheap scans: Tier A surfaces directly, Tier B/C are hidden
361
- // For validated/deep: Tier A surfaces, Tier B goes through AI validation, Tier C hidden
362
-
363
- // Some Tier A findings still need AI validation (entropy, secrets, AI-specific)
364
- const additionalValidation = tierFiltered.toSurface.filter(v =>
365
- v.requiresAIValidation ||
366
- v.category === 'ai_prompt_injection' || // Story B1: Prompt hygiene
367
- v.category === 'ai_unsafe_execution' || // Story B2: LLM output execution
368
- v.category === 'ai_overpermissive_tool' // Story B4: Agent tool permissions
369
- )
370
-
371
- // Surface findings that don't need validation (excluding those that do)
372
- const noValidationNeededRaw = tierFiltered.toSurface.filter(v => !additionalValidation.includes(v))
373
-
374
- // Apply auto-dismiss rules to direct-surface findings (mode='surface')
375
- // Uses 'surface' mode to exclude cost-saving rules like 'info_severity_core_only'
376
- // This ensures test/scanner/example files are dismissed, but info-severity findings still surface
377
- const { toValidate: noValidationNeeded, dismissed: surfaceDismissed } = applyAutoDismissRules(noValidationNeededRaw, 'surface')
378
-
379
- // Combine tier-filtered validation candidates with additional ones
380
- const requiresValidation = [...tierFiltered.toValidate, ...additionalValidation]
381
-
382
- // Apply smart auto-dismiss rules BEFORE AI validation (saves API costs)
383
- const { toValidate: afterAutoDismiss, dismissed: autoDismissed } = applyAutoDismissRules(requiresValidation)
384
-
385
- // Combine all dismissed findings for logging
386
- const allDismissed = [...surfaceDismissed, ...autoDismissed]
387
-
388
- // Track auto-dismiss by severity and category for logging
389
- const autoDismissBySeverity: Record<string, number> = { info: 0, low: 0, medium: 0, high: 0, critical: 0 }
390
- const autoDismissByCategory: Record<string, number> = {}
391
- for (const d of allDismissed) {
392
- autoDismissBySeverity[d.finding.severity] = (autoDismissBySeverity[d.finding.severity] || 0) + 1
393
- autoDismissByCategory[d.finding.category] = (autoDismissByCategory[d.finding.category] || 0) + 1
394
- }
395
- if (allDismissed.length > 0) {
396
- const categoryBreakdown = Object.entries(autoDismissByCategory)
397
- .sort(([, a], [, b]) => b - a)
398
- .map(([cat, count]) => `${cat}:${count}`)
399
- .join(',')
400
- log(`[AutoDismiss] repo=${repoInfo.name} total=${allDismissed.length} (surface=${surfaceDismissed.length} validation=${autoDismissed.length}) by_severity={info:${autoDismissBySeverity.info},low:${autoDismissBySeverity.low},medium:${autoDismissBySeverity.medium},high:${autoDismissBySeverity.high}} by_category={${categoryBreakdown}}`)
401
- }
402
-
403
- // Apply per-file cap to validation candidates (cost control)
404
- // Use scan mode config for max files
405
- const maxValidationFiles = scanModeConfig.maxAIValidationFiles || MAX_VALIDATION_CANDIDATES_PER_FILE
406
- const cappedValidation = capValidationCandidatesPerFile(afterAutoDismiss, maxValidationFiles)
407
-
408
- checkCancelled()
409
-
410
- // AI Validation of selected findings (if AI is enabled and not skipped by scan mode)
411
- let validatedFindings = cappedValidation
412
- let capturedValidationStats: ValidationStats | undefined = undefined
413
- const shouldValidate = options.enableAI !== false && !scanModeConfig.skipAIValidation && cappedValidation.length > 0
414
-
415
- if (shouldValidate) {
416
- checkCancelled()
417
- const aiValidationStart = Date.now()
418
- reportProgress('validating', 'AI validating findings (entropy, secrets, AI patterns)...', cappedValidation.length)
419
-
420
- // For incremental scans, only validate findings in changed files
421
- const findingsToValidate = isIncremental && scanModeConfig.changedFiles
422
- ? cappedValidation.filter(v => scanModeConfig.changedFiles!.some(cf => v.filePath.endsWith(cf) || v.filePath.includes(cf)))
423
- : cappedValidation
424
-
425
- if (findingsToValidate.length > 0) {
426
- const validationResult = await validateFindingsWithAI(
427
- findingsToValidate,
428
- filesForAI,
429
- undefined, // projectContext (uses default)
430
- onProgress ? (progress) => {
431
- // Convert AI validation progress to ScanProgress format
432
- onProgress({
433
- status: 'validating',
434
- message: progress.status,
435
- filesProcessed: progress.filesProcessed,
436
- totalFiles: progress.totalFiles,
437
- vulnerabilitiesFound: allVulnerabilities.length,
438
- })
439
- } : undefined
440
- )
441
- validatedFindings = validationResult.vulnerabilities
442
- const { stats: validationStats } = validationResult
443
- capturedValidationStats = validationStats // Capture for return
444
- phaseTiming.aiValidation = Date.now() - aiValidationStart
445
-
446
- log(`[AI Validation] repo=${repoInfo.name} depth=${depth} duration=${phaseTiming.aiValidation}ms candidates=${findingsToValidate.length} capped_from=${requiresValidation.length} auto_dismissed=${autoDismissed.length} kept=${validationStats.confirmedFindings} rejected=${validationStats.dismissedFindings} downgraded=${validationStats.downgradedFindings}`)
447
- log(`[AI Validation] cost_estimate: input_tokens=${validationStats.estimatedInputTokens} output_tokens=${validationStats.estimatedOutputTokens} cost=$${validationStats.estimatedCost.toFixed(4)} api_calls=${validationStats.apiCalls}`)
448
-
449
- // Add back findings that weren't validated (not in changed files)
450
- // Mark them as skipped rather than failed validation
451
- const notValidated = cappedValidation.filter(v => !findingsToValidate.includes(v)).map(v => ({
452
- ...v,
453
- validatedByAI: false,
454
- validationStatus: 'not_validated' as const,
455
- validationNotes: 'Skipped validation (not in changed files for incremental scan)',
456
- }))
457
- validatedFindings.push(...notValidated)
458
- }
459
- } else if (scanModeConfig.skipAIValidation) {
460
- log(`[AI Validation] repo=${repoInfo.name} depth=${depth} skipped=true reason=scan_mode_config findings_requiring_validation=${cappedValidation.length}`)
461
- // In cheap mode, don't surface findings that require AI validation
462
- // These are low-confidence without validation and would be noise
463
- // Only surface high-confidence findings that don't need validation
464
- validatedFindings = []
465
- }
466
-
467
- // Combine validated and non-validated findings
468
- allVulnerabilities.push(...validatedFindings, ...noValidationNeeded)
469
-
470
- // Layer 3: AI Semantic Analysis (new findings)
471
- // Skip for incremental scans by default (configurable)
472
- const shouldRunLayer3 = options.enableAI !== false && !scanModeConfig.skipLayer3
473
-
474
- if (shouldRunLayer3) {
475
- checkCancelled()
476
- const layer3Start = Date.now()
477
- reportProgress('layer3', 'Running AI semantic analysis...', allVulnerabilities.length)
478
-
479
- // For incremental scans, only analyze changed files
480
- const filesToAnalyze = isIncremental ? filesForAI : files
481
- const maxLayer3Files = scanModeConfig.maxLayer3Files || 10
482
-
483
- // Detect auth helpers for Layer 3 context
484
- const authHelperContext = detectAuthHelpers(files)
485
-
486
- const layer3Result = await runLayer3Scan(filesToAnalyze, {
487
- enableAI: options.enableAI,
488
- maxFiles: maxLayer3Files,
489
- projectContext: {
490
- middlewareConfig: middlewareConfig.hasAuthMiddleware ? {
491
- hasAuthMiddleware: true,
492
- authType: middlewareConfig.authType,
493
- protectedPaths: middlewareConfig.protectedPaths,
494
- } : undefined,
495
- authHelpers: authHelperContext.hasThrowingHelpers ? {
496
- hasThrowingHelpers: true,
497
- summary: authHelperContext.summary,
498
- } : undefined,
499
- },
500
- cancellationToken,
501
- })
502
- phaseTiming.layer3 = Date.now() - layer3Start
503
- allVulnerabilities.push(...layer3Result.vulnerabilities)
504
- log(`[Layer3] repo=${repoInfo.name} depth=${depth} duration=${phaseTiming.layer3}ms files_analyzed=${layer3Result.aiAnalyzed} findings=${layer3Result.vulnerabilities.length}`)
505
- } else if (scanModeConfig.skipLayer3) {
506
- log(`[Layer3] repo=${repoInfo.name} depth=${depth} skipped=true reason=scan_mode_config`)
507
- }
508
-
509
- // Log phase timing summary
510
- const phaseTimingStr = Object.entries(phaseTiming)
511
- .filter(([, ms]) => ms !== undefined)
512
- .map(([phase, ms]) => `${phase}=${ms}ms`)
513
- .join(' ')
514
- if (phaseTimingStr) {
515
- log(`[Scanner] repo=${repoInfo.name} phase_timing: ${phaseTimingStr}`)
516
- }
517
-
518
- // Deduplicate vulnerabilities
519
- const uniqueVulnerabilities = deduplicateVulnerabilities(allVulnerabilities)
520
-
521
- // Resolve contradictions (e.g., middleware-protected INFO vs missing-auth CRITICAL on same route)
522
- const resolvedVulnerabilities = resolveContradictions(uniqueVulnerabilities, middlewareConfig)
523
-
524
- // Apply suppressions (inline comments + config file)
525
- const projectPath = options.projectPath || process.cwd()
526
- const suppressionManager = new SuppressionManager({ projectPath })
527
- const suppressionResult = suppressionManager.applySuppressions(resolvedVulnerabilities, files)
528
-
529
- // Log suppression stats if any were suppressed
530
- if (suppressionResult.suppressed.length > 0 || suppressionResult.expiredSuppressions > 0) {
531
- log(`[Suppression] repo=${repoInfo.name} suppressed=${suppressionResult.suppressed.length} (inline=${suppressionResult.stats.inlineSuppressed} config_finding=${suppressionResult.stats.configFindingSuppressed} config_rule=${suppressionResult.stats.configRuleSuppressed}) expired=${suppressionResult.expiredSuppressions}`)
532
- }
533
-
534
- // Use the filtered findings (after suppression)
535
- const afterSuppression = suppressionResult.findings
536
-
537
- // Sort by severity
538
- const sortedVulnerabilities = sortBySeverity(afterSuppression)
539
-
540
- // Compute issue-mix counts (based on unsuppressed findings)
541
- const severityCounts = computeSeverityCounts(sortedVulnerabilities)
542
- const categoryCounts = computeCategoryCounts(sortedVulnerabilities)
543
- const hasBlockingIssues = severityCounts.critical > 0 || severityCounts.high > 0
544
-
545
- // Build suppressed vulnerabilities summary (for --show-suppressed)
546
- const suppressedVulnerabilities: SuppressedVulnerabilitySummary[] | undefined = options.showSuppressed
547
- ? suppressionResult.suppressed.map(s => ({
548
- hash: s.suppression.hash,
549
- filePath: s.vulnerability.filePath,
550
- lineNumber: s.vulnerability.lineNumber,
551
- category: s.vulnerability.category,
552
- severity: s.vulnerability.severity,
553
- title: s.vulnerability.title,
554
- suppressionType: s.suppression.type,
555
- suppressionReason: s.suppression.reason,
556
- expires: s.suppression.expires,
557
- }))
558
- : undefined
559
-
560
- reportProgress('complete', 'Scan complete!', sortedVulnerabilities.length)
561
-
562
- return {
563
- repoName: repoInfo.name,
564
- repoUrl: repoInfo.url,
565
- branch: repoInfo.branch,
566
- filesScanned: files.length,
567
- filesSkipped: 0, // TODO: track skipped files
568
- vulnerabilities: sortedVulnerabilities,
569
- severityCounts,
570
- categoryCounts,
571
- hasBlockingIssues,
572
- scanDuration: Date.now() - startTime,
573
- timestamp: new Date().toISOString(),
574
- validationStats: capturedValidationStats,
575
- suppressionStats: suppressionResult.suppressed.length > 0 || suppressionResult.expiredSuppressions > 0
576
- ? suppressionResult.stats
577
- : undefined,
578
- suppressedVulnerabilities,
579
- }
580
- } catch (error) {
581
- if (cancellationToken?.cancelled) {
582
- // Return partial results on cancellation
583
- reportProgress('failed', 'Scan cancelled')
584
-
585
- // Compute partial results
586
- const uniqueVulnerabilities = deduplicateVulnerabilities(allVulnerabilities)
587
- const resolvedVulnerabilities = resolveContradictions(uniqueVulnerabilities, middlewareConfig)
588
- const sortedVulnerabilities = sortBySeverity(resolvedVulnerabilities)
589
- const severityCounts = computeSeverityCounts(sortedVulnerabilities)
590
- const categoryCounts = computeCategoryCounts(sortedVulnerabilities)
591
-
592
- return {
593
- repoName: repoInfo.name,
594
- repoUrl: repoInfo.url,
595
- branch: repoInfo.branch,
596
- filesScanned: files.length,
597
- filesSkipped: 0,
598
- vulnerabilities: sortedVulnerabilities,
599
- severityCounts,
600
- categoryCounts,
601
- hasBlockingIssues: false, // Don't block on partial results
602
- scanDuration: Date.now() - startTime,
603
- timestamp: new Date().toISOString(),
604
- validationStats: capturedValidationStats,
605
- cancelled: true,
606
- cancelReason: cancellationToken.reason,
607
- }
608
- }
609
-
610
- reportProgress('failed', `Scan failed: ${error}`)
611
- throw error
612
- }
613
- }
614
-
615
- /**
616
- * Enrich findings with metadata from the rule registry (PRO-82)
617
- * Sets default impact, evidence, fixSteps, and references from registry
618
- *
619
- * PRO-83: When projectContext is provided, uses framework-aware fix suggestions
620
- * that are tailored to the user's detected tech stack (e.g., Prisma-specific
621
- * SQL injection fixes instead of generic advice).
2
+ * Scanner Public API
622
3
  *
623
- * These can be overridden later by AI-generated content
624
- */
625
- function enrichWithMetadata(
626
- findings: Vulnerability[],
627
- projectContext?: ProjectContext
628
- ): Vulnerability[] {
629
- return findings.map(f => {
630
- const metadata = getRuleMetadata(f.category)
631
- if (!metadata) return f
632
-
633
- // PRO-83: Check for framework-specific fix suggestions
634
- let fixSteps = metadata.fixSteps
635
- if (projectContext) {
636
- const frameworkFix = getFrameworkFix(
637
- f.category,
638
- projectContext.frameworks,
639
- projectContext.dataAccess
640
- )
641
- if (frameworkFix) {
642
- fixSteps = frameworkFix.fixSteps
643
- // Optionally append code example to description if available
644
- // This makes the fix more actionable
645
- }
646
- }
647
-
648
- return {
649
- ...f,
650
- // Set defaults from registry (AI can override later)
651
- impact: f.impact || metadata.whyItMatters,
652
- evidence: f.evidence || metadata.evidence,
653
- fixSteps: f.fixSteps || fixSteps,
654
- references: f.references || metadata.references,
655
- }
656
- })
657
- }
658
-
659
- /**
660
- * Aggregate noisy findings in the same file to reduce clutter
661
- * Groups repeated findings with same filePath + category + title
662
- * Especially useful for AI pattern spam
663
- */
664
- function aggregateNoisyFindings(vulnerabilities: Vulnerability[]): Vulnerability[] {
665
- // Group findings by file + category + title
666
- const groups = new Map<string, Vulnerability[]>()
667
-
668
- for (const vuln of vulnerabilities) {
669
- // Create grouping key: same file, category, and base title (without line-specific info)
670
- const baseTitle = vuln.title.replace(/\s*\(\d+ instances?\)/, '').trim()
671
- const key = `${vuln.filePath}|${vuln.category}|${baseTitle}`
672
-
673
- const existing = groups.get(key) || []
674
- existing.push(vuln)
675
- groups.set(key, existing)
676
- }
677
-
678
- const result: Vulnerability[] = []
679
-
680
- for (const [key, group] of groups) {
681
- // If only 1-2 findings, keep them as-is
682
- if (group.length <= 2) {
683
- result.push(...group)
684
- continue
685
- }
686
-
687
- // For 3+ similar findings in same file, aggregate into one
688
- const first = group[0]
689
- const lineNumbers = group.map(v => v.lineNumber).sort((a, b) => a - b)
690
- const uniqueLines = [...new Set(lineNumbers)]
691
-
692
- // Format line numbers nicely (show first few, then "...")
693
- const lineDisplay = uniqueLines.length > 5
694
- ? `${uniqueLines.slice(0, 5).join(', ')}... (${uniqueLines.length} total)`
695
- : uniqueLines.join(', ')
696
-
697
- // Keep highest severity from the group
698
- const highestSeverity = group.reduce((max, v) =>
699
- severityRank(v.severity) > severityRank(max.severity) ? v : max
700
- , group[0]).severity
701
-
702
- // Create aggregated finding
703
- const aggregated: Vulnerability = {
704
- id: `${first.id}-aggregated`,
705
- filePath: first.filePath,
706
- lineNumber: uniqueLines[0], // First occurrence
707
- lineContent: `${group.length} instances across this file`,
708
- severity: highestSeverity,
709
- category: first.category,
710
- title: `${first.title.replace(/\s*\(\d+ instances?\)/, '')} (${group.length} instances)`,
711
- description: `${first.description}\n\nFound ${group.length} occurrences at lines: ${lineDisplay}`,
712
- suggestedFix: first.suggestedFix,
713
- confidence: first.confidence,
714
- layer: first.layer,
715
- requiresAIValidation: first.requiresAIValidation,
716
- }
717
-
718
- result.push(aggregated)
719
- }
720
-
721
- return result
722
- }
723
-
724
- /**
725
- * Cap validation candidates per file to control AI costs
726
- * Prioritizes by:
727
- * 1. Tier (ai_assisted findings need AI most, so they get priority)
728
- * 2. Severity (critical > high > medium > low > info)
729
- * 3. Category importance (secrets/URLs/auth before cosmetic patterns)
730
- */
731
- function capValidationCandidatesPerFile(
732
- vulnerabilities: Vulnerability[],
733
- maxPerFile: number = MAX_VALIDATION_CANDIDATES_PER_FILE
734
- ): Vulnerability[] {
735
- // Group by file
736
- const byFile = new Map<string, Vulnerability[]>()
737
- for (const vuln of vulnerabilities) {
738
- const existing = byFile.get(vuln.filePath) || []
739
- existing.push(vuln)
740
- byFile.set(vuln.filePath, existing)
741
- }
742
-
743
- const result: Vulnerability[] = []
744
-
745
- for (const [filePath, fileVulns] of byFile) {
746
- // Sort by priority: tier first (ai_assisted needs AI most), then severity, then category
747
- const sorted = [...fileVulns].sort((a, b) => {
748
- // Tier comparison: ai_assisted (needs AI) > core (high precision) > experimental (hidden anyway)
749
- const tierPriority = (v: Vulnerability): number => {
750
- const tier = getTierForCategory(v.category, v.layer)
751
- if (tier === 'ai_assisted') return 10 // Highest priority - these NEED AI validation
752
- if (tier === 'core') return 5 // High precision, but AI can still help
753
- return 1 // Experimental - shouldn't even be here
754
- }
755
- const tierDiff = tierPriority(b) - tierPriority(a)
756
- if (tierDiff !== 0) return tierDiff
757
-
758
- // Severity comparison (higher severity = higher priority)
759
- const severityDiff = severityRank(b.severity) - severityRank(a.severity)
760
- if (severityDiff !== 0) return severityDiff
761
-
762
- // Category importance (secrets/URLs/auth before AI patterns)
763
- const categoryPriority = (v: Vulnerability): number => {
764
- if (v.category === 'hardcoded_secret') return 10
765
- if (v.category === 'high_entropy_string') return 9
766
- if (v.category === 'sensitive_url') return 8
767
- if (v.category === 'missing_auth') return 7
768
- if (v.category === 'ai_pattern') return 3
769
- return 5
770
- }
771
- return categoryPriority(b) - categoryPriority(a)
772
- })
773
-
774
- // Take top N per file
775
- const capped = sorted.slice(0, maxPerFile)
776
- result.push(...capped)
777
-
778
- // Note: Capping log removed to support quiet mode - this is debug info only
779
- }
780
-
781
- return result
782
- }
783
-
784
- /**
785
- * Remove duplicate vulnerabilities (same file, line, category)
786
- * Also handles cross-layer URL duplicates (sensitive_url + ai_pattern)
787
- */
788
- function deduplicateVulnerabilities(vulnerabilities: Vulnerability[]): Vulnerability[] {
789
- const seen = new Map<string, Vulnerability>()
790
- const urlDedupMap = new Map<string, Vulnerability>()
791
-
792
- for (const vuln of vulnerabilities) {
793
- // Special handling for URL duplicates across layers
794
- // (e.g., Layer 1 detects as sensitive_url, Layer 2 detects as ai_pattern)
795
- if ((vuln.category === 'sensitive_url' || vuln.category === 'ai_pattern') &&
796
- /url|localhost|127\.0\.0\.1|http/i.test(vuln.lineContent)) {
797
-
798
- // Create compound key that ignores category differences for URLs
799
- const urlKey = `${vuln.filePath}:${vuln.lineNumber}:url_finding`
800
- const existing = urlDedupMap.get(urlKey)
801
-
802
- if (!existing) {
803
- urlDedupMap.set(urlKey, vuln)
804
- } else {
805
- // Keep Layer 1 (more specific) over Layer 2 AI pattern
806
- // Or keep higher severity
807
- if (vuln.layer < existing.layer ||
808
- severityRank(vuln.severity) > severityRank(existing.severity)) {
809
- urlDedupMap.set(urlKey, vuln)
810
- }
811
- }
812
- continue
813
- }
814
-
815
- // Standard deduplication for non-URL findings
816
- const key = `${vuln.filePath}:${vuln.lineNumber}:${vuln.category}`
817
- const existing = seen.get(key)
818
-
819
- // Keep the higher severity or higher confidence finding
820
- if (!existing) {
821
- seen.set(key, vuln)
822
- } else if (severityRank(vuln.severity) > severityRank(existing.severity)) {
823
- seen.set(key, vuln)
824
- } else if (
825
- severityRank(vuln.severity) === severityRank(existing.severity) &&
826
- confidenceRank(vuln.confidence) > confidenceRank(existing.confidence)
827
- ) {
828
- seen.set(key, vuln)
829
- }
830
- }
831
-
832
- // Combine URL and non-URL findings
833
- return [...Array.from(seen.values()), ...Array.from(urlDedupMap.values())]
834
- }
835
-
836
- /**
837
- * Resolve contradictions in findings
838
- *
839
- * Key contradiction types:
840
- * 1. Same route has both "protected by middleware" (info) AND "missing auth" (high/critical)
841
- * → Keep only the info-level "protected by middleware" finding
842
- * 2. Same file has BYOK "transient use" (info) AND "key stored insecurely" (high)
843
- * → Keep only the most accurate one based on context
844
- * 3. Same line has conflicting severities from different layers
845
- * → Prefer the lower severity if one explicitly notes protection
846
- */
847
- function resolveContradictions(
848
- vulnerabilities: Vulnerability[],
849
- middlewareConfig?: MiddlewareAuthConfig
850
- ): Vulnerability[] {
851
- // Group findings by file path for contradiction analysis
852
- const byFile = new Map<string, Vulnerability[]>()
853
- for (const vuln of vulnerabilities) {
854
- const existing = byFile.get(vuln.filePath) || []
855
- existing.push(vuln)
856
- byFile.set(vuln.filePath, existing)
857
- }
858
-
859
- const result: Vulnerability[] = []
860
-
861
- for (const [filePath, fileVulns] of byFile) {
862
- // Check for auth contradictions in this file
863
- const authFindings = fileVulns.filter(v => v.category === 'missing_auth')
864
- const otherFindings = fileVulns.filter(v => v.category !== 'missing_auth')
865
-
866
- // Identify protected routes (middleware or auth helper)
867
- const protectedInfos = authFindings.filter(v =>
868
- v.severity === 'info' &&
869
- (v.validationNotes === 'MIDDLEWARE_PROTECTED' ||
870
- v.validationNotes === 'AUTH_HELPER_PROTECTED' ||
871
- v.title.includes('protected by middleware') ||
872
- v.title.includes('uses auth helper'))
873
- )
874
-
875
- // NEW: Check if this file's route is protected by middleware (even without explicit info finding)
876
- // This catches Layer 3 findings that don't have the Layer 2 protection info
877
- const routePath = getRoutePathFromFile(filePath)
878
- const isAPIRouteProtected = routePath && middlewareConfig?.hasAuthMiddleware
879
- ? isRouteProtectedByMiddleware(routePath, middlewareConfig).isProtected
880
- : false
881
-
882
- // Also check if file is a client component calling protected API routes
883
- // Client components (components/, app/ without route.ts) calling /api/** are safe
884
- const isClientCallingProtectedAPI =
885
- middlewareConfig?.hasAuthMiddleware &&
886
- (filePath.includes('/components/') ||
887
- (filePath.includes('/app/') && !filePath.includes('route.ts')))
888
-
889
- // If we have protected route info findings OR the route is protected by middleware
890
- if (protectedInfos.length > 0 || isAPIRouteProtected || isClientCallingProtectedAPI) {
891
- // Keep the protected info findings
892
- result.push(...protectedInfos)
893
-
894
- // For other auth findings on same file, either drop or downgrade to info
895
- const otherAuthFindings = authFindings.filter(v => !protectedInfos.includes(v))
896
-
897
- for (const vuln of otherAuthFindings) {
898
- // If it's high/critical missing auth on a protected route, drop it entirely
899
- // (the middleware/helper protection supersedes)
900
- if (vuln.severity === 'critical' || vuln.severity === 'high') {
901
- const reason = isAPIRouteProtected
902
- ? 'API route protected by middleware'
903
- : isClientCallingProtectedAPI
904
- ? 'client component calling protected API'
905
- : 'route is protected'
906
- // Note: Contradiction log removed to support quiet mode - this is debug info only
907
- continue // Skip this finding
908
- }
909
-
910
- // Keep lower severity auth findings as-is
911
- result.push(vuln)
912
- }
913
- } else {
914
- // No protection detected - keep all auth findings as-is
915
- result.push(...authFindings)
916
- }
917
-
918
- // Handle BYOK contradictions
919
- const byokFindings = otherFindings.filter(v =>
920
- v.category === 'ai_pattern' && v.title.toLowerCase().includes('byok')
921
- )
922
- const nonByokFindings = otherFindings.filter(v =>
923
- !(v.category === 'ai_pattern' && v.title.toLowerCase().includes('byok'))
924
- )
925
-
926
- if (byokFindings.length > 0) {
927
- // Check if we have both transient (low) and storage (high) BYOK findings
928
- const transientByok = byokFindings.filter(v =>
929
- v.severity === 'low' || v.severity === 'info'
930
- )
931
- const storageByok = byokFindings.filter(v =>
932
- v.severity === 'high' || v.severity === 'medium'
933
- )
934
-
935
- if (transientByok.length > 0 && storageByok.length > 0) {
936
- // If we detected transient usage, prefer the lower severity
937
- // The higher severity ones may be false positives
938
- result.push(...transientByok)
939
- // Mark high-severity BYOK for review
940
- for (const vuln of storageByok) {
941
- result.push({
942
- ...vuln,
943
- severity: 'low',
944
- validationNotes: `${vuln.validationNotes || ''} (downgraded: transient BYOK usage detected in same file)`.trim(),
945
- })
946
- }
947
- } else {
948
- // Keep all BYOK findings as-is
949
- result.push(...byokFindings)
950
- }
951
- }
952
-
953
- // Add non-BYOK other findings
954
- result.push(...nonByokFindings)
955
- }
956
-
957
- return result
958
- }
959
-
960
- /**
961
- * Sort vulnerabilities by severity (critical first)
4
+ * Re-exports from stage modules. All prior exports preserved.
962
5
  */
963
- function sortBySeverity(vulnerabilities: Vulnerability[]): Vulnerability[] {
964
- return [...vulnerabilities].sort((a, b) => {
965
- const severityDiff = severityRank(b.severity) - severityRank(a.severity)
966
- if (severityDiff !== 0) return severityDiff
967
-
968
- // Secondary sort by confidence
969
- return confidenceRank(b.confidence) - confidenceRank(a.confidence)
970
- })
971
- }
972
6
 
973
- function severityRank(severity: string): number {
974
- const ranks: Record<string, number> = {
975
- critical: 5,
976
- high: 4,
977
- medium: 3,
978
- low: 2,
979
- info: 1,
980
- }
981
- return ranks[severity] || 0
982
- }
7
+ // ============================================================================
8
+ // Core Scanner API
9
+ // ============================================================================
983
10
 
984
- function confidenceRank(confidence: string): number {
985
- const ranks: Record<string, number> = {
986
- high: 3,
987
- medium: 2,
988
- low: 1,
989
- }
990
- return ranks[confidence] || 0
991
- }
11
+ // Pipeline orchestrator main entry point
12
+ export { runScan, type ScanOptions } from './pipeline'
992
13
 
993
- /**
994
- * Compute severity counts from vulnerabilities
995
- */
996
- function computeSeverityCounts(vulnerabilities: Vulnerability[]): SeverityCounts {
997
- const counts: SeverityCounts = { critical: 0, high: 0, medium: 0, low: 0, info: 0 }
998
-
999
- for (const vuln of vulnerabilities) {
1000
- if (vuln.severity in counts) {
1001
- counts[vuln.severity]++
1002
- }
1003
- }
14
+ // Summary utilities (public API for backfilling legacy scans etc.)
15
+ export { computeIssueMixFromVulnerabilities } from './report/summary'
1004
16
 
1005
- return counts
1006
- }
1007
-
1008
- /**
1009
- * Compute category counts from vulnerabilities
1010
- */
1011
- function computeCategoryCounts(vulnerabilities: Vulnerability[]): CategoryCounts {
1012
- const counts: CategoryCounts = {}
1013
-
1014
- for (const vuln of vulnerabilities) {
1015
- const category = vuln.category as VulnerabilityCategory
1016
- counts[category] = (counts[category] || 0) + 1
1017
- }
1018
-
1019
- return counts
1020
- }
17
+ // ============================================================================
18
+ // Re-export types and utilities
19
+ // ============================================================================
1021
20
 
1022
- /**
1023
- * Helper to compute counts from vulnerabilities (for backfilling legacy scans)
1024
- */
1025
- export function computeIssueMixFromVulnerabilities(vulnerabilities: Vulnerability[]): {
1026
- severityCounts: SeverityCounts
1027
- categoryCounts: CategoryCounts
1028
- hasBlockingIssues: boolean
1029
- } {
1030
- const severityCounts = computeSeverityCounts(vulnerabilities)
1031
- const categoryCounts = computeCategoryCounts(vulnerabilities)
1032
- const hasBlockingIssues = severityCounts.critical > 0 || severityCounts.high > 0
1033
-
1034
- return { severityCounts, categoryCounts, hasBlockingIssues }
1035
- }
21
+ export * from './shared/types'
22
+ export { runLayer1Scan } from './detect/secrets'
23
+ export { runLayer2Scan } from './detect/structural'
24
+ export { buildProjectContext, type ProjectContext } from './model/project-context'
25
+ export { validateFindingsWithAI, type ValidationStats, type AIValidationResult } from './validate'
26
+ export { createCancellationToken } from './shared/types'
1036
27
 
1037
- // Re-export types and utilities
1038
- export * from './types'
1039
- export { runLayer1Scan } from './layer1'
1040
- export { runLayer2Scan } from './layer2'
1041
- export { runLayer3Scan } from './layer3'
1042
- export { buildProjectContext, type ProjectContext } from './utils/project-context-builder'
1043
- export { validateFindingsWithAI, type ValidationStats, type AIValidationResult } from './layer3/anthropic'
1044
- export { createCancellationToken } from './types'
28
+ // Confidence scoring exports (Phase 2B)
29
+ export {
30
+ scoreFindings,
31
+ buildAdjustmentContext,
32
+ buildConfidenceLog,
33
+ DEPTH_CONFIGS,
34
+ type ScoredFinding,
35
+ type ConfidenceComputation,
36
+ type ConfidenceAdjustment,
37
+ type ConfidenceLog,
38
+ type AdjustmentRule,
39
+ type AdjustmentContext,
40
+ type DepthConfig,
41
+ } from './score'
42
+
43
+ // Context Engine types
44
+ export type { ContextEngineResult } from './model/taint-types'
1045
45
 
1046
46
  // Suppression system exports
1047
47
  export {
@@ -1060,7 +60,7 @@ export {
1060
60
  type RuleSuppression,
1061
61
  type SuppressionResult,
1062
62
  type SuppressedVulnerability,
1063
- } from './suppression'
63
+ } from './postprocess/suppression'
1064
64
 
1065
65
  // Baseline system exports
1066
66
  export {
@@ -1078,7 +78,7 @@ export {
1078
78
  type LoadBaselineResult,
1079
79
  type SaveBaselineResult,
1080
80
  type ClearBaselineResult,
1081
- } from './baseline'
81
+ } from './shared/baseline'
1082
82
 
1083
83
  // Rule metadata exports (PRO-82)
1084
84
  export {
@@ -1087,4 +87,30 @@ export {
1087
87
  getAllCategories,
1088
88
  hasMetadata,
1089
89
  type RuleMetadata,
1090
- } from './rules'
90
+ } from './shared/rules'
91
+
92
+ // AI Context exports
93
+ export {
94
+ AIContextManager,
95
+ AI_CONTEXT_FILE,
96
+ AI_CONTEXT_PATH,
97
+ type AIContextManagerOptions,
98
+ type SaveContextResult,
99
+ type LoadContextResult,
100
+ type ClearContextResult,
101
+ } from './shared/ai-context'
102
+
103
+ // Category filter exports (Phase 2: Category-Based Filtering)
104
+ export {
105
+ CATEGORY_GROUPS,
106
+ ALL_CATEGORIES,
107
+ normalizeCategory,
108
+ expandCategoryPattern,
109
+ matchesAnyCategory,
110
+ shouldFailOnCategories,
111
+ getMatchingCategories,
112
+ parseCategoryList,
113
+ validateCategories,
114
+ getAvailableCategoryGroups,
115
+ getCategoryGroupCounts,
116
+ } from './shared/category-filter'