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