@oculum/scanner 1.0.9 → 1.0.11

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 (365) hide show
  1. package/dist/baseline/diff.d.ts +32 -0
  2. package/dist/baseline/diff.d.ts.map +1 -0
  3. package/dist/baseline/diff.js +119 -0
  4. package/dist/baseline/diff.js.map +1 -0
  5. package/dist/baseline/index.d.ts +9 -0
  6. package/dist/baseline/index.d.ts.map +1 -0
  7. package/dist/baseline/index.js +19 -0
  8. package/dist/baseline/index.js.map +1 -0
  9. package/dist/baseline/manager.d.ts +67 -0
  10. package/dist/baseline/manager.d.ts.map +1 -0
  11. package/dist/baseline/manager.js +180 -0
  12. package/dist/baseline/manager.js.map +1 -0
  13. package/dist/baseline/types.d.ts +91 -0
  14. package/dist/baseline/types.d.ts.map +1 -0
  15. package/dist/baseline/types.js +12 -0
  16. package/dist/baseline/types.js.map +1 -0
  17. package/dist/formatters/cli-terminal.d.ts +38 -0
  18. package/dist/formatters/cli-terminal.d.ts.map +1 -1
  19. package/dist/formatters/cli-terminal.js +365 -42
  20. package/dist/formatters/cli-terminal.js.map +1 -1
  21. package/dist/formatters/github-comment.d.ts +1 -1
  22. package/dist/formatters/github-comment.d.ts.map +1 -1
  23. package/dist/formatters/github-comment.js +75 -11
  24. package/dist/formatters/github-comment.js.map +1 -1
  25. package/dist/formatters/index.d.ts +1 -1
  26. package/dist/formatters/index.d.ts.map +1 -1
  27. package/dist/formatters/index.js +4 -1
  28. package/dist/formatters/index.js.map +1 -1
  29. package/dist/index.d.ts +7 -0
  30. package/dist/index.d.ts.map +1 -1
  31. package/dist/index.js +155 -16
  32. package/dist/index.js.map +1 -1
  33. package/dist/layer1/config-audit.d.ts.map +1 -1
  34. package/dist/layer1/config-audit.js +20 -3
  35. package/dist/layer1/config-audit.js.map +1 -1
  36. package/dist/layer1/config-mcp-audit.d.ts +20 -0
  37. package/dist/layer1/config-mcp-audit.d.ts.map +1 -0
  38. package/dist/layer1/config-mcp-audit.js +239 -0
  39. package/dist/layer1/config-mcp-audit.js.map +1 -0
  40. package/dist/layer1/index.d.ts +1 -0
  41. package/dist/layer1/index.d.ts.map +1 -1
  42. package/dist/layer1/index.js +9 -1
  43. package/dist/layer1/index.js.map +1 -1
  44. package/dist/layer2/ai-agent-tools.d.ts.map +1 -1
  45. package/dist/layer2/ai-agent-tools.js +303 -0
  46. package/dist/layer2/ai-agent-tools.js.map +1 -1
  47. package/dist/layer2/ai-endpoint-protection.d.ts.map +1 -1
  48. package/dist/layer2/ai-endpoint-protection.js +17 -3
  49. package/dist/layer2/ai-endpoint-protection.js.map +1 -1
  50. package/dist/layer2/ai-execution-sinks.d.ts.map +1 -1
  51. package/dist/layer2/ai-execution-sinks.js +462 -12
  52. package/dist/layer2/ai-execution-sinks.js.map +1 -1
  53. package/dist/layer2/ai-fingerprinting.d.ts.map +1 -1
  54. package/dist/layer2/ai-fingerprinting.js +3 -0
  55. package/dist/layer2/ai-fingerprinting.js.map +1 -1
  56. package/dist/layer2/ai-mcp-security.d.ts +17 -0
  57. package/dist/layer2/ai-mcp-security.d.ts.map +1 -0
  58. package/dist/layer2/ai-mcp-security.js +679 -0
  59. package/dist/layer2/ai-mcp-security.js.map +1 -0
  60. package/dist/layer2/ai-package-hallucination.d.ts +19 -0
  61. package/dist/layer2/ai-package-hallucination.d.ts.map +1 -0
  62. package/dist/layer2/ai-package-hallucination.js +696 -0
  63. package/dist/layer2/ai-package-hallucination.js.map +1 -0
  64. package/dist/layer2/ai-prompt-hygiene.d.ts.map +1 -1
  65. package/dist/layer2/ai-prompt-hygiene.js +495 -9
  66. package/dist/layer2/ai-prompt-hygiene.js.map +1 -1
  67. package/dist/layer2/ai-rag-safety.d.ts.map +1 -1
  68. package/dist/layer2/ai-rag-safety.js +372 -1
  69. package/dist/layer2/ai-rag-safety.js.map +1 -1
  70. package/dist/layer2/auth-antipatterns.d.ts.map +1 -1
  71. package/dist/layer2/auth-antipatterns.js +4 -0
  72. package/dist/layer2/auth-antipatterns.js.map +1 -1
  73. package/dist/layer2/byok-patterns.d.ts.map +1 -1
  74. package/dist/layer2/byok-patterns.js +3 -0
  75. package/dist/layer2/byok-patterns.js.map +1 -1
  76. package/dist/layer2/dangerous-functions/child-process.d.ts +16 -0
  77. package/dist/layer2/dangerous-functions/child-process.d.ts.map +1 -0
  78. package/dist/layer2/dangerous-functions/child-process.js +74 -0
  79. package/dist/layer2/dangerous-functions/child-process.js.map +1 -0
  80. package/dist/layer2/dangerous-functions/dom-xss.d.ts +29 -0
  81. package/dist/layer2/dangerous-functions/dom-xss.d.ts.map +1 -0
  82. package/dist/layer2/dangerous-functions/dom-xss.js +179 -0
  83. package/dist/layer2/dangerous-functions/dom-xss.js.map +1 -0
  84. package/dist/layer2/dangerous-functions/index.d.ts +13 -0
  85. package/dist/layer2/dangerous-functions/index.d.ts.map +1 -0
  86. package/dist/layer2/dangerous-functions/index.js +621 -0
  87. package/dist/layer2/dangerous-functions/index.js.map +1 -0
  88. package/dist/layer2/dangerous-functions/json-parse.d.ts +31 -0
  89. package/dist/layer2/dangerous-functions/json-parse.d.ts.map +1 -0
  90. package/dist/layer2/dangerous-functions/json-parse.js +319 -0
  91. package/dist/layer2/dangerous-functions/json-parse.js.map +1 -0
  92. package/dist/layer2/dangerous-functions/math-random.d.ts +61 -0
  93. package/dist/layer2/dangerous-functions/math-random.d.ts.map +1 -0
  94. package/dist/layer2/dangerous-functions/math-random.js +459 -0
  95. package/dist/layer2/dangerous-functions/math-random.js.map +1 -0
  96. package/dist/layer2/dangerous-functions/patterns.d.ts +21 -0
  97. package/dist/layer2/dangerous-functions/patterns.d.ts.map +1 -0
  98. package/dist/layer2/dangerous-functions/patterns.js +161 -0
  99. package/dist/layer2/dangerous-functions/patterns.js.map +1 -0
  100. package/dist/layer2/dangerous-functions/request-validation.d.ts +13 -0
  101. package/dist/layer2/dangerous-functions/request-validation.d.ts.map +1 -0
  102. package/dist/layer2/dangerous-functions/request-validation.js +119 -0
  103. package/dist/layer2/dangerous-functions/request-validation.js.map +1 -0
  104. package/dist/layer2/dangerous-functions/utils/control-flow.d.ts +23 -0
  105. package/dist/layer2/dangerous-functions/utils/control-flow.d.ts.map +1 -0
  106. package/dist/layer2/dangerous-functions/utils/control-flow.js +149 -0
  107. package/dist/layer2/dangerous-functions/utils/control-flow.js.map +1 -0
  108. package/dist/layer2/dangerous-functions/utils/helpers.d.ts +31 -0
  109. package/dist/layer2/dangerous-functions/utils/helpers.d.ts.map +1 -0
  110. package/dist/layer2/dangerous-functions/utils/helpers.js +124 -0
  111. package/dist/layer2/dangerous-functions/utils/helpers.js.map +1 -0
  112. package/dist/layer2/dangerous-functions/utils/index.d.ts +9 -0
  113. package/dist/layer2/dangerous-functions/utils/index.d.ts.map +1 -0
  114. package/dist/layer2/dangerous-functions/utils/index.js +23 -0
  115. package/dist/layer2/dangerous-functions/utils/index.js.map +1 -0
  116. package/dist/layer2/dangerous-functions/utils/schema-validation.d.ts +22 -0
  117. package/dist/layer2/dangerous-functions/utils/schema-validation.d.ts.map +1 -0
  118. package/dist/layer2/dangerous-functions/utils/schema-validation.js +89 -0
  119. package/dist/layer2/dangerous-functions/utils/schema-validation.js.map +1 -0
  120. package/dist/layer2/data-exposure.d.ts.map +1 -1
  121. package/dist/layer2/data-exposure.js +3 -0
  122. package/dist/layer2/data-exposure.js.map +1 -1
  123. package/dist/layer2/framework-checks.d.ts.map +1 -1
  124. package/dist/layer2/framework-checks.js +3 -0
  125. package/dist/layer2/framework-checks.js.map +1 -1
  126. package/dist/layer2/index.d.ts +3 -0
  127. package/dist/layer2/index.d.ts.map +1 -1
  128. package/dist/layer2/index.js +61 -2
  129. package/dist/layer2/index.js.map +1 -1
  130. package/dist/layer2/logic-gates.d.ts.map +1 -1
  131. package/dist/layer2/logic-gates.js +4 -0
  132. package/dist/layer2/logic-gates.js.map +1 -1
  133. package/dist/layer2/model-supply-chain.d.ts +20 -0
  134. package/dist/layer2/model-supply-chain.d.ts.map +1 -0
  135. package/dist/layer2/model-supply-chain.js +376 -0
  136. package/dist/layer2/model-supply-chain.js.map +1 -0
  137. package/dist/layer2/risky-imports.d.ts.map +1 -1
  138. package/dist/layer2/risky-imports.js +4 -0
  139. package/dist/layer2/risky-imports.js.map +1 -1
  140. package/dist/layer2/variables.d.ts.map +1 -1
  141. package/dist/layer2/variables.js +4 -0
  142. package/dist/layer2/variables.js.map +1 -1
  143. package/dist/layer3/anthropic/auto-dismiss.d.ts +24 -0
  144. package/dist/layer3/anthropic/auto-dismiss.d.ts.map +1 -0
  145. package/dist/layer3/anthropic/auto-dismiss.js +188 -0
  146. package/dist/layer3/anthropic/auto-dismiss.js.map +1 -0
  147. package/dist/layer3/anthropic/clients.d.ts +44 -0
  148. package/dist/layer3/anthropic/clients.d.ts.map +1 -0
  149. package/dist/layer3/anthropic/clients.js +81 -0
  150. package/dist/layer3/anthropic/clients.js.map +1 -0
  151. package/dist/layer3/anthropic/index.d.ts +41 -0
  152. package/dist/layer3/anthropic/index.d.ts.map +1 -0
  153. package/dist/layer3/anthropic/index.js +141 -0
  154. package/dist/layer3/anthropic/index.js.map +1 -0
  155. package/dist/layer3/anthropic/prompts/index.d.ts +8 -0
  156. package/dist/layer3/anthropic/prompts/index.d.ts.map +1 -0
  157. package/dist/layer3/anthropic/prompts/index.js +14 -0
  158. package/dist/layer3/anthropic/prompts/index.js.map +1 -0
  159. package/dist/layer3/anthropic/prompts/semantic-analysis.d.ts +15 -0
  160. package/dist/layer3/anthropic/prompts/semantic-analysis.d.ts.map +1 -0
  161. package/dist/layer3/anthropic/prompts/semantic-analysis.js +169 -0
  162. package/dist/layer3/anthropic/prompts/semantic-analysis.js.map +1 -0
  163. package/dist/layer3/anthropic/prompts/validation.d.ts +12 -0
  164. package/dist/layer3/anthropic/prompts/validation.d.ts.map +1 -0
  165. package/dist/layer3/anthropic/prompts/validation.js +421 -0
  166. package/dist/layer3/anthropic/prompts/validation.js.map +1 -0
  167. package/dist/layer3/anthropic/providers/anthropic.d.ts +21 -0
  168. package/dist/layer3/anthropic/providers/anthropic.d.ts.map +1 -0
  169. package/dist/layer3/anthropic/providers/anthropic.js +266 -0
  170. package/dist/layer3/anthropic/providers/anthropic.js.map +1 -0
  171. package/dist/layer3/anthropic/providers/index.d.ts +8 -0
  172. package/dist/layer3/anthropic/providers/index.d.ts.map +1 -0
  173. package/dist/layer3/anthropic/providers/index.js +15 -0
  174. package/dist/layer3/anthropic/providers/index.js.map +1 -0
  175. package/dist/layer3/anthropic/providers/openai.d.ts +18 -0
  176. package/dist/layer3/anthropic/providers/openai.d.ts.map +1 -0
  177. package/dist/layer3/anthropic/providers/openai.js +340 -0
  178. package/dist/layer3/anthropic/providers/openai.js.map +1 -0
  179. package/dist/layer3/anthropic/request-builder.d.ts +20 -0
  180. package/dist/layer3/anthropic/request-builder.d.ts.map +1 -0
  181. package/dist/layer3/anthropic/request-builder.js +134 -0
  182. package/dist/layer3/anthropic/request-builder.js.map +1 -0
  183. package/dist/layer3/anthropic/types.d.ts +88 -0
  184. package/dist/layer3/anthropic/types.d.ts.map +1 -0
  185. package/dist/layer3/anthropic/types.js +38 -0
  186. package/dist/layer3/anthropic/types.js.map +1 -0
  187. package/dist/layer3/anthropic/utils/index.d.ts +9 -0
  188. package/dist/layer3/anthropic/utils/index.d.ts.map +1 -0
  189. package/dist/layer3/anthropic/utils/index.js +24 -0
  190. package/dist/layer3/anthropic/utils/index.js.map +1 -0
  191. package/dist/layer3/anthropic/utils/path-helpers.d.ts +21 -0
  192. package/dist/layer3/anthropic/utils/path-helpers.d.ts.map +1 -0
  193. package/dist/layer3/anthropic/utils/path-helpers.js +69 -0
  194. package/dist/layer3/anthropic/utils/path-helpers.js.map +1 -0
  195. package/dist/layer3/anthropic/utils/response-parser.d.ts +40 -0
  196. package/dist/layer3/anthropic/utils/response-parser.d.ts.map +1 -0
  197. package/dist/layer3/anthropic/utils/response-parser.js +285 -0
  198. package/dist/layer3/anthropic/utils/response-parser.js.map +1 -0
  199. package/dist/layer3/anthropic/utils/retry.d.ts +15 -0
  200. package/dist/layer3/anthropic/utils/retry.d.ts.map +1 -0
  201. package/dist/layer3/anthropic/utils/retry.js +62 -0
  202. package/dist/layer3/anthropic/utils/retry.js.map +1 -0
  203. package/dist/layer3/index.d.ts +1 -0
  204. package/dist/layer3/index.d.ts.map +1 -1
  205. package/dist/layer3/index.js +16 -6
  206. package/dist/layer3/index.js.map +1 -1
  207. package/dist/layer3/osv-check.d.ts +75 -0
  208. package/dist/layer3/osv-check.d.ts.map +1 -0
  209. package/dist/layer3/osv-check.js +308 -0
  210. package/dist/layer3/osv-check.js.map +1 -0
  211. package/dist/rules/framework-fixes.d.ts +48 -0
  212. package/dist/rules/framework-fixes.d.ts.map +1 -0
  213. package/dist/rules/framework-fixes.js +439 -0
  214. package/dist/rules/framework-fixes.js.map +1 -0
  215. package/dist/rules/index.d.ts +8 -0
  216. package/dist/rules/index.d.ts.map +1 -0
  217. package/dist/rules/index.js +18 -0
  218. package/dist/rules/index.js.map +1 -0
  219. package/dist/rules/metadata.d.ts +43 -0
  220. package/dist/rules/metadata.d.ts.map +1 -0
  221. package/dist/rules/metadata.js +734 -0
  222. package/dist/rules/metadata.js.map +1 -0
  223. package/dist/suppression/config-loader.d.ts +74 -0
  224. package/dist/suppression/config-loader.d.ts.map +1 -0
  225. package/dist/suppression/config-loader.js +424 -0
  226. package/dist/suppression/config-loader.js.map +1 -0
  227. package/dist/suppression/hash.d.ts +48 -0
  228. package/dist/suppression/hash.d.ts.map +1 -0
  229. package/dist/suppression/hash.js +88 -0
  230. package/dist/suppression/hash.js.map +1 -0
  231. package/dist/suppression/index.d.ts +11 -0
  232. package/dist/suppression/index.d.ts.map +1 -0
  233. package/dist/suppression/index.js +39 -0
  234. package/dist/suppression/index.js.map +1 -0
  235. package/dist/suppression/inline-parser.d.ts +39 -0
  236. package/dist/suppression/inline-parser.d.ts.map +1 -0
  237. package/dist/suppression/inline-parser.js +218 -0
  238. package/dist/suppression/inline-parser.js.map +1 -0
  239. package/dist/suppression/manager.d.ts +94 -0
  240. package/dist/suppression/manager.d.ts.map +1 -0
  241. package/dist/suppression/manager.js +292 -0
  242. package/dist/suppression/manager.js.map +1 -0
  243. package/dist/suppression/types.d.ts +151 -0
  244. package/dist/suppression/types.d.ts.map +1 -0
  245. package/dist/suppression/types.js +28 -0
  246. package/dist/suppression/types.js.map +1 -0
  247. package/dist/tiers.d.ts +1 -1
  248. package/dist/tiers.d.ts.map +1 -1
  249. package/dist/tiers.js +27 -0
  250. package/dist/tiers.js.map +1 -1
  251. package/dist/types.d.ts +62 -1
  252. package/dist/types.d.ts.map +1 -1
  253. package/dist/types.js.map +1 -1
  254. package/dist/utils/context-helpers.d.ts +4 -0
  255. package/dist/utils/context-helpers.d.ts.map +1 -1
  256. package/dist/utils/context-helpers.js +13 -9
  257. package/dist/utils/context-helpers.js.map +1 -1
  258. package/package.json +4 -2
  259. package/src/__tests__/benchmark/fixtures/layer1/mcp-config-audit.json +31 -0
  260. package/src/__tests__/benchmark/fixtures/layer2/ai-execution-sinks.ts +1489 -82
  261. package/src/__tests__/benchmark/fixtures/layer2/ai-mcp-security.ts +495 -0
  262. package/src/__tests__/benchmark/fixtures/layer2/ai-package-hallucination.ts +255 -0
  263. package/src/__tests__/benchmark/fixtures/layer2/ai-prompt-hygiene.ts +300 -1
  264. package/src/__tests__/benchmark/fixtures/layer2/ai-rag-safety.ts +139 -0
  265. package/src/__tests__/benchmark/fixtures/layer2/byok-patterns.ts +7 -0
  266. package/src/__tests__/benchmark/fixtures/layer2/data-exposure.ts +63 -0
  267. package/src/__tests__/benchmark/fixtures/layer2/excessive-agency.ts +221 -0
  268. package/src/__tests__/benchmark/fixtures/layer2/index.ts +18 -0
  269. package/src/__tests__/benchmark/fixtures/layer2/model-supply-chain.ts +204 -0
  270. package/src/__tests__/benchmark/fixtures/layer2/phase1-enhancements.ts +157 -0
  271. package/src/__tests__/snapshots/__snapshots__/anthropic-validation-refactor.test.ts.snap +758 -0
  272. package/src/__tests__/snapshots/__snapshots__/dangerous-functions-refactor.test.ts.snap +503 -0
  273. package/src/__tests__/snapshots/anthropic-validation-refactor.test.ts +321 -0
  274. package/src/__tests__/snapshots/dangerous-functions-refactor.test.ts +439 -0
  275. package/src/baseline/__tests__/diff.test.ts +261 -0
  276. package/src/baseline/__tests__/manager.test.ts +225 -0
  277. package/src/baseline/diff.ts +135 -0
  278. package/src/baseline/index.ts +29 -0
  279. package/src/baseline/manager.ts +230 -0
  280. package/src/baseline/types.ts +97 -0
  281. package/src/formatters/cli-terminal.ts +444 -41
  282. package/src/formatters/github-comment.ts +79 -11
  283. package/src/formatters/index.ts +4 -0
  284. package/src/index.ts +197 -14
  285. package/src/layer1/config-audit.ts +24 -3
  286. package/src/layer1/config-mcp-audit.ts +276 -0
  287. package/src/layer1/index.ts +16 -6
  288. package/src/layer2/ai-agent-tools.ts +336 -0
  289. package/src/layer2/ai-endpoint-protection.ts +16 -3
  290. package/src/layer2/ai-execution-sinks.ts +516 -12
  291. package/src/layer2/ai-fingerprinting.ts +5 -1
  292. package/src/layer2/ai-mcp-security.ts +730 -0
  293. package/src/layer2/ai-package-hallucination.ts +791 -0
  294. package/src/layer2/ai-prompt-hygiene.ts +547 -9
  295. package/src/layer2/ai-rag-safety.ts +382 -3
  296. package/src/layer2/auth-antipatterns.ts +5 -0
  297. package/src/layer2/byok-patterns.ts +5 -1
  298. package/src/layer2/dangerous-functions/child-process.ts +98 -0
  299. package/src/layer2/dangerous-functions/dom-xss.ts +220 -0
  300. package/src/layer2/dangerous-functions/index.ts +949 -0
  301. package/src/layer2/dangerous-functions/json-parse.ts +385 -0
  302. package/src/layer2/dangerous-functions/math-random.ts +537 -0
  303. package/src/layer2/dangerous-functions/patterns.ts +174 -0
  304. package/src/layer2/dangerous-functions/request-validation.ts +145 -0
  305. package/src/layer2/dangerous-functions/utils/control-flow.ts +162 -0
  306. package/src/layer2/dangerous-functions/utils/helpers.ts +170 -0
  307. package/src/layer2/dangerous-functions/utils/index.ts +25 -0
  308. package/src/layer2/dangerous-functions/utils/schema-validation.ts +91 -0
  309. package/src/layer2/data-exposure.ts +5 -1
  310. package/src/layer2/framework-checks.ts +5 -0
  311. package/src/layer2/index.ts +63 -1
  312. package/src/layer2/logic-gates.ts +5 -0
  313. package/src/layer2/model-supply-chain.ts +456 -0
  314. package/src/layer2/risky-imports.ts +5 -0
  315. package/src/layer2/variables.ts +5 -0
  316. package/src/layer3/__tests__/osv-check.test.ts +384 -0
  317. package/src/layer3/anthropic/auto-dismiss.ts +212 -0
  318. package/src/layer3/anthropic/clients.ts +84 -0
  319. package/src/layer3/anthropic/index.ts +170 -0
  320. package/src/layer3/anthropic/prompts/index.ts +14 -0
  321. package/src/layer3/anthropic/prompts/semantic-analysis.ts +173 -0
  322. package/src/layer3/anthropic/prompts/validation.ts +419 -0
  323. package/src/layer3/anthropic/providers/anthropic.ts +310 -0
  324. package/src/layer3/anthropic/providers/index.ts +8 -0
  325. package/src/layer3/anthropic/providers/openai.ts +384 -0
  326. package/src/layer3/anthropic/request-builder.ts +150 -0
  327. package/src/layer3/anthropic/types.ts +148 -0
  328. package/src/layer3/anthropic/utils/index.ts +26 -0
  329. package/src/layer3/anthropic/utils/path-helpers.ts +68 -0
  330. package/src/layer3/anthropic/utils/response-parser.ts +322 -0
  331. package/src/layer3/anthropic/utils/retry.ts +75 -0
  332. package/src/layer3/index.ts +18 -5
  333. package/src/layer3/osv-check.ts +420 -0
  334. package/src/rules/__tests__/framework-fixes.test.ts +689 -0
  335. package/src/rules/__tests__/metadata.test.ts +218 -0
  336. package/src/rules/framework-fixes.ts +470 -0
  337. package/src/rules/index.ts +21 -0
  338. package/src/rules/metadata.ts +831 -0
  339. package/src/suppression/__tests__/config-loader.test.ts +382 -0
  340. package/src/suppression/__tests__/hash.test.ts +166 -0
  341. package/src/suppression/__tests__/inline-parser.test.ts +212 -0
  342. package/src/suppression/__tests__/manager.test.ts +415 -0
  343. package/src/suppression/config-loader.ts +462 -0
  344. package/src/suppression/hash.ts +95 -0
  345. package/src/suppression/index.ts +51 -0
  346. package/src/suppression/inline-parser.ts +273 -0
  347. package/src/suppression/manager.ts +379 -0
  348. package/src/suppression/types.ts +174 -0
  349. package/src/tiers.ts +36 -0
  350. package/src/types.ts +90 -0
  351. package/src/utils/context-helpers.ts +13 -9
  352. package/dist/layer2/dangerous-functions.d.ts +0 -7
  353. package/dist/layer2/dangerous-functions.d.ts.map +0 -1
  354. package/dist/layer2/dangerous-functions.js +0 -1701
  355. package/dist/layer2/dangerous-functions.js.map +0 -1
  356. package/dist/layer3/anthropic.d.ts +0 -87
  357. package/dist/layer3/anthropic.d.ts.map +0 -1
  358. package/dist/layer3/anthropic.js +0 -1948
  359. package/dist/layer3/anthropic.js.map +0 -1
  360. package/dist/layer3/openai.d.ts +0 -25
  361. package/dist/layer3/openai.d.ts.map +0 -1
  362. package/dist/layer3/openai.js +0 -238
  363. package/dist/layer3/openai.js.map +0 -1
  364. package/src/layer2/dangerous-functions.ts +0 -1940
  365. package/src/layer3/anthropic.ts +0 -2257
@@ -0,0 +1,88 @@
1
+ "use strict";
2
+ /**
3
+ * Finding Hash Computation
4
+ * Creates stable, reproducible hashes for identifying specific findings
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.normalizePathForHash = normalizePathForHash;
8
+ exports.normalizeContentForHash = normalizeContentForHash;
9
+ exports.computeFindingHash = computeFindingHash;
10
+ exports.computeHashFromComponents = computeHashFromComponents;
11
+ exports.isValidHash = isValidHash;
12
+ exports.formatHashForDisplay = formatHashForDisplay;
13
+ const crypto_1 = require("crypto");
14
+ /**
15
+ * Normalize a file path for hashing
16
+ * - Removes leading ./ or /
17
+ * - Converts backslashes to forward slashes
18
+ * - Lowercases (for case-insensitive matching)
19
+ */
20
+ function normalizePathForHash(filePath) {
21
+ return filePath
22
+ .replace(/^\.\//, '') // Remove leading ./
23
+ .replace(/^\//, '') // Remove leading /
24
+ .replace(/\\/g, '/') // Normalize backslashes
25
+ .toLowerCase();
26
+ }
27
+ /**
28
+ * Normalize line content for hashing
29
+ * - Trims whitespace
30
+ * - Collapses multiple whitespace to single space
31
+ * - Removes common noise (line numbers, etc.)
32
+ */
33
+ function normalizeContentForHash(content) {
34
+ return content
35
+ .trim()
36
+ .replace(/\s+/g, ' ') // Collapse whitespace
37
+ .replace(/^\d+:\s*/, ''); // Remove line number prefix if present
38
+ }
39
+ /**
40
+ * Compute a stable hash for a vulnerability finding
41
+ *
42
+ * Hash = SHA256(normalizedPath:normalizedContent:category).slice(0,16)
43
+ *
44
+ * This creates a 16-character hex hash that:
45
+ * - Stays stable across whitespace changes
46
+ * - Changes when the actual code changes
47
+ * - Changes when the finding category changes
48
+ * - Is unique enough for practical use
49
+ *
50
+ * @param finding - The vulnerability to hash
51
+ * @returns A 16-character hex hash string
52
+ */
53
+ function computeFindingHash(finding) {
54
+ const normalizedPath = normalizePathForHash(finding.filePath);
55
+ const normalizedContent = normalizeContentForHash(finding.lineContent);
56
+ const category = finding.category;
57
+ const input = `${normalizedPath}:${normalizedContent}:${category}`;
58
+ const hash = (0, crypto_1.createHash)('sha256').update(input).digest('hex');
59
+ // Return first 16 characters (64 bits of entropy - sufficient for uniqueness)
60
+ return hash.slice(0, 16);
61
+ }
62
+ /**
63
+ * Compute hash from raw components (for testing or manual construction)
64
+ */
65
+ function computeHashFromComponents(filePath, lineContent, category) {
66
+ const normalizedPath = normalizePathForHash(filePath);
67
+ const normalizedContent = normalizeContentForHash(lineContent);
68
+ const input = `${normalizedPath}:${normalizedContent}:${category}`;
69
+ const hash = (0, crypto_1.createHash)('sha256').update(input).digest('hex');
70
+ return hash.slice(0, 16);
71
+ }
72
+ /**
73
+ * Validate a hash format
74
+ * Must be 16 hexadecimal characters
75
+ */
76
+ function isValidHash(hash) {
77
+ return /^[0-9a-f]{16}$/i.test(hash);
78
+ }
79
+ /**
80
+ * Format a hash for display (with truncation indicator)
81
+ */
82
+ function formatHashForDisplay(hash) {
83
+ if (hash.length <= 16) {
84
+ return hash;
85
+ }
86
+ return `${hash.slice(0, 12)}...`;
87
+ }
88
+ //# sourceMappingURL=hash.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"hash.js","sourceRoot":"","sources":["../../src/suppression/hash.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AAWH,oDAMC;AAQD,0DAKC;AAgBD,gDAUC;AAKD,8DAYC;AAMD,kCAEC;AAKD,oDAKC;AAzFD,mCAAmC;AAGnC;;;;;GAKG;AACH,SAAgB,oBAAoB,CAAC,QAAgB;IACnD,OAAO,QAAQ;SACZ,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,oBAAoB;SACzC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,mBAAmB;SACtC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC,wBAAwB;SAC5C,WAAW,EAAE,CAAA;AAClB,CAAC;AAED;;;;;GAKG;AACH,SAAgB,uBAAuB,CAAC,OAAe;IACrD,OAAO,OAAO;SACX,IAAI,EAAE;SACN,OAAO,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC,sBAAsB;SAC3C,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC,CAAA,CAAC,uCAAuC;AACpE,CAAC;AAED;;;;;;;;;;;;;GAaG;AACH,SAAgB,kBAAkB,CAAC,OAAsB;IACvD,MAAM,cAAc,GAAG,oBAAoB,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAA;IAC7D,MAAM,iBAAiB,GAAG,uBAAuB,CAAC,OAAO,CAAC,WAAW,CAAC,CAAA;IACtE,MAAM,QAAQ,GAAG,OAAO,CAAC,QAAQ,CAAA;IAEjC,MAAM,KAAK,GAAG,GAAG,cAAc,IAAI,iBAAiB,IAAI,QAAQ,EAAE,CAAA;IAClE,MAAM,IAAI,GAAG,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAE7D,8EAA8E;IAC9E,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AAC1B,CAAC;AAED;;GAEG;AACH,SAAgB,yBAAyB,CACvC,QAAgB,EAChB,WAAmB,EACnB,QAAgB;IAEhB,MAAM,cAAc,GAAG,oBAAoB,CAAC,QAAQ,CAAC,CAAA;IACrD,MAAM,iBAAiB,GAAG,uBAAuB,CAAC,WAAW,CAAC,CAAA;IAE9D,MAAM,KAAK,GAAG,GAAG,cAAc,IAAI,iBAAiB,IAAI,QAAQ,EAAE,CAAA;IAClE,MAAM,IAAI,GAAG,IAAA,mBAAU,EAAC,QAAQ,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IAE7D,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,CAAA;AAC1B,CAAC;AAED;;;GAGG;AACH,SAAgB,WAAW,CAAC,IAAY;IACtC,OAAO,iBAAiB,CAAC,IAAI,CAAC,IAAI,CAAC,CAAA;AACrC,CAAC;AAED;;GAEG;AACH,SAAgB,oBAAoB,CAAC,IAAY;IAC/C,IAAI,IAAI,CAAC,MAAM,IAAI,EAAE,EAAE,CAAC;QACtB,OAAO,IAAI,CAAA;IACb,CAAC;IACD,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,KAAK,CAAA;AAClC,CAAC"}
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Suppression System
3
+ * Allows users to suppress findings via config files and inline comments
4
+ */
5
+ export { SuppressionManager, type SuppressionManagerOptions } from './manager';
6
+ export type { SuppressionConfig, RuleSuppression, FindingSuppression, InlineSuppression, SuppressionMatch, SuppressedVulnerability, SuppressionResult, } from './types';
7
+ export { SUPPRESSION_CONFIG_FILES, DEFAULT_SUPPRESSION_CONFIG } from './types';
8
+ export { computeFindingHash, computeHashFromComponents, normalizePathForHash, normalizeContentForHash, isValidHash, formatHashForDisplay, } from './hash';
9
+ export { loadSuppressionConfig, loadConfigFromPath, findConfigFile, writeSuppressionConfig, addFindingSuppression, removeFindingSuppression, addRuleSuppression, listSuppressions, isExpired, type ConfigLoadResult, } from './config-loader';
10
+ export { parseInlineSuppressions, isLineSuppressed, extractSuppressionReasons, generateSuppressionComment, } from './inline-parser';
11
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/suppression/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EAAE,kBAAkB,EAAE,KAAK,yBAAyB,EAAE,MAAM,WAAW,CAAA;AAG9E,YAAY,EACV,iBAAiB,EACjB,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,gBAAgB,EAChB,uBAAuB,EACvB,iBAAiB,GAClB,MAAM,SAAS,CAAA;AAChB,OAAO,EAAE,wBAAwB,EAAE,0BAA0B,EAAE,MAAM,SAAS,CAAA;AAG9E,OAAO,EACL,kBAAkB,EAClB,yBAAyB,EACzB,oBAAoB,EACpB,uBAAuB,EACvB,WAAW,EACX,oBAAoB,GACrB,MAAM,QAAQ,CAAA;AAGf,OAAO,EACL,qBAAqB,EACrB,kBAAkB,EAClB,cAAc,EACd,sBAAsB,EACtB,qBAAqB,EACrB,wBAAwB,EACxB,kBAAkB,EAClB,gBAAgB,EAChB,SAAS,EACT,KAAK,gBAAgB,GACtB,MAAM,iBAAiB,CAAA;AAGxB,OAAO,EACL,uBAAuB,EACvB,gBAAgB,EAChB,yBAAyB,EACzB,0BAA0B,GAC3B,MAAM,iBAAiB,CAAA"}
@@ -0,0 +1,39 @@
1
+ "use strict";
2
+ /**
3
+ * Suppression System
4
+ * Allows users to suppress findings via config files and inline comments
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.generateSuppressionComment = exports.extractSuppressionReasons = exports.isLineSuppressed = exports.parseInlineSuppressions = exports.isExpired = exports.listSuppressions = exports.addRuleSuppression = exports.removeFindingSuppression = exports.addFindingSuppression = exports.writeSuppressionConfig = exports.findConfigFile = exports.loadConfigFromPath = exports.loadSuppressionConfig = exports.formatHashForDisplay = exports.isValidHash = exports.normalizeContentForHash = exports.normalizePathForHash = exports.computeHashFromComponents = exports.computeFindingHash = exports.DEFAULT_SUPPRESSION_CONFIG = exports.SUPPRESSION_CONFIG_FILES = exports.SuppressionManager = void 0;
8
+ // Main exports
9
+ var manager_1 = require("./manager");
10
+ Object.defineProperty(exports, "SuppressionManager", { enumerable: true, get: function () { return manager_1.SuppressionManager; } });
11
+ var types_1 = require("./types");
12
+ Object.defineProperty(exports, "SUPPRESSION_CONFIG_FILES", { enumerable: true, get: function () { return types_1.SUPPRESSION_CONFIG_FILES; } });
13
+ Object.defineProperty(exports, "DEFAULT_SUPPRESSION_CONFIG", { enumerable: true, get: function () { return types_1.DEFAULT_SUPPRESSION_CONFIG; } });
14
+ // Hash utilities
15
+ var hash_1 = require("./hash");
16
+ Object.defineProperty(exports, "computeFindingHash", { enumerable: true, get: function () { return hash_1.computeFindingHash; } });
17
+ Object.defineProperty(exports, "computeHashFromComponents", { enumerable: true, get: function () { return hash_1.computeHashFromComponents; } });
18
+ Object.defineProperty(exports, "normalizePathForHash", { enumerable: true, get: function () { return hash_1.normalizePathForHash; } });
19
+ Object.defineProperty(exports, "normalizeContentForHash", { enumerable: true, get: function () { return hash_1.normalizeContentForHash; } });
20
+ Object.defineProperty(exports, "isValidHash", { enumerable: true, get: function () { return hash_1.isValidHash; } });
21
+ Object.defineProperty(exports, "formatHashForDisplay", { enumerable: true, get: function () { return hash_1.formatHashForDisplay; } });
22
+ // Config utilities
23
+ var config_loader_1 = require("./config-loader");
24
+ Object.defineProperty(exports, "loadSuppressionConfig", { enumerable: true, get: function () { return config_loader_1.loadSuppressionConfig; } });
25
+ Object.defineProperty(exports, "loadConfigFromPath", { enumerable: true, get: function () { return config_loader_1.loadConfigFromPath; } });
26
+ Object.defineProperty(exports, "findConfigFile", { enumerable: true, get: function () { return config_loader_1.findConfigFile; } });
27
+ Object.defineProperty(exports, "writeSuppressionConfig", { enumerable: true, get: function () { return config_loader_1.writeSuppressionConfig; } });
28
+ Object.defineProperty(exports, "addFindingSuppression", { enumerable: true, get: function () { return config_loader_1.addFindingSuppression; } });
29
+ Object.defineProperty(exports, "removeFindingSuppression", { enumerable: true, get: function () { return config_loader_1.removeFindingSuppression; } });
30
+ Object.defineProperty(exports, "addRuleSuppression", { enumerable: true, get: function () { return config_loader_1.addRuleSuppression; } });
31
+ Object.defineProperty(exports, "listSuppressions", { enumerable: true, get: function () { return config_loader_1.listSuppressions; } });
32
+ Object.defineProperty(exports, "isExpired", { enumerable: true, get: function () { return config_loader_1.isExpired; } });
33
+ // Inline comment utilities
34
+ var inline_parser_1 = require("./inline-parser");
35
+ Object.defineProperty(exports, "parseInlineSuppressions", { enumerable: true, get: function () { return inline_parser_1.parseInlineSuppressions; } });
36
+ Object.defineProperty(exports, "isLineSuppressed", { enumerable: true, get: function () { return inline_parser_1.isLineSuppressed; } });
37
+ Object.defineProperty(exports, "extractSuppressionReasons", { enumerable: true, get: function () { return inline_parser_1.extractSuppressionReasons; } });
38
+ Object.defineProperty(exports, "generateSuppressionComment", { enumerable: true, get: function () { return inline_parser_1.generateSuppressionComment; } });
39
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/suppression/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,eAAe;AACf,qCAA8E;AAArE,6GAAA,kBAAkB,OAAA;AAY3B,iCAA8E;AAArE,iHAAA,wBAAwB,OAAA;AAAE,mHAAA,0BAA0B,OAAA;AAE7D,iBAAiB;AACjB,+BAOe;AANb,0GAAA,kBAAkB,OAAA;AAClB,iHAAA,yBAAyB,OAAA;AACzB,4GAAA,oBAAoB,OAAA;AACpB,+GAAA,uBAAuB,OAAA;AACvB,mGAAA,WAAW,OAAA;AACX,4GAAA,oBAAoB,OAAA;AAGtB,mBAAmB;AACnB,iDAWwB;AAVtB,sHAAA,qBAAqB,OAAA;AACrB,mHAAA,kBAAkB,OAAA;AAClB,+GAAA,cAAc,OAAA;AACd,uHAAA,sBAAsB,OAAA;AACtB,sHAAA,qBAAqB,OAAA;AACrB,yHAAA,wBAAwB,OAAA;AACxB,mHAAA,kBAAkB,OAAA;AAClB,iHAAA,gBAAgB,OAAA;AAChB,0GAAA,SAAS,OAAA;AAIX,2BAA2B;AAC3B,iDAKwB;AAJtB,wHAAA,uBAAuB,OAAA;AACvB,iHAAA,gBAAgB,OAAA;AAChB,0HAAA,yBAAyB,OAAA;AACzB,2HAAA,0BAA0B,OAAA"}
@@ -0,0 +1,39 @@
1
+ /**
2
+ * Inline Suppression Comment Parser
3
+ * Parses oculum-ignore comments from source code
4
+ */
5
+ import type { InlineSuppression } from './types';
6
+ import type { VulnerabilityCategory } from '../types';
7
+ /**
8
+ * Parse all inline suppressions from file content
9
+ *
10
+ * Returns a map of line numbers to their effective suppressions.
11
+ * A line can be suppressed by:
12
+ * 1. A same-line comment (oculum-ignore)
13
+ * 2. A next-line comment on the previous line (oculum-ignore-next-line)
14
+ * 3. Being within a block suppression (oculum-ignore-block ... oculum-ignore-block-end)
15
+ */
16
+ export declare function parseInlineSuppressions(content: string): Map<number, InlineSuppression>;
17
+ /**
18
+ * Check if a specific line is suppressed
19
+ */
20
+ export declare function isLineSuppressed(suppressions: Map<number, InlineSuppression>, lineNumber: number, category?: VulnerabilityCategory): InlineSuppression | null;
21
+ /**
22
+ * Extract all unique suppression reasons from a file
23
+ * Useful for auditing suppressed findings
24
+ */
25
+ export declare function extractSuppressionReasons(content: string): Array<{
26
+ reason: string;
27
+ ruleId?: VulnerabilityCategory;
28
+ lineNumber: number;
29
+ type: InlineSuppression['type'];
30
+ }>;
31
+ /**
32
+ * Generate a suppression comment for a given line
33
+ */
34
+ export declare function generateSuppressionComment(reason: string, options?: {
35
+ type?: 'next-line' | 'same-line';
36
+ ruleId?: VulnerabilityCategory;
37
+ commentStyle?: '//' | '#' | '--';
38
+ }): string;
39
+ //# sourceMappingURL=inline-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline-parser.d.ts","sourceRoot":"","sources":["../../src/suppression/inline-parser.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AAChD,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAkHrD;;;;;;;;GAQG;AACH,wBAAgB,uBAAuB,CAAC,OAAO,EAAE,MAAM,GAAG,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,CA+DvF;AAED;;GAEG;AACH,wBAAgB,gBAAgB,CAC9B,YAAY,EAAE,GAAG,CAAC,MAAM,EAAE,iBAAiB,CAAC,EAC5C,UAAU,EAAE,MAAM,EAClB,QAAQ,CAAC,EAAE,qBAAqB,GAC/B,iBAAiB,GAAG,IAAI,CAa1B;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,MAAM,GAAG,KAAK,CAAC;IAChE,MAAM,EAAE,MAAM,CAAA;IACd,MAAM,CAAC,EAAE,qBAAqB,CAAA;IAC9B,UAAU,EAAE,MAAM,CAAA;IAClB,IAAI,EAAE,iBAAiB,CAAC,MAAM,CAAC,CAAA;CAChC,CAAC,CAyBD;AAED;;GAEG;AACH,wBAAgB,0BAA0B,CACxC,MAAM,EAAE,MAAM,EACd,OAAO,GAAE;IACP,IAAI,CAAC,EAAE,WAAW,GAAG,WAAW,CAAA;IAChC,MAAM,CAAC,EAAE,qBAAqB,CAAA;IAC9B,YAAY,CAAC,EAAE,IAAI,GAAG,GAAG,GAAG,IAAI,CAAA;CAC5B,GACL,MAAM,CAUR"}
@@ -0,0 +1,218 @@
1
+ "use strict";
2
+ /**
3
+ * Inline Suppression Comment Parser
4
+ * Parses oculum-ignore comments from source code
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.parseInlineSuppressions = parseInlineSuppressions;
8
+ exports.isLineSuppressed = isLineSuppressed;
9
+ exports.extractSuppressionReasons = extractSuppressionReasons;
10
+ exports.generateSuppressionComment = generateSuppressionComment;
11
+ /**
12
+ * Valid suppression comment patterns:
13
+ *
14
+ * Single-line suppressions:
15
+ * // oculum-ignore-next-line: reason here
16
+ * // oculum-ignore-next-line [rule-id]: reason here
17
+ * code // oculum-ignore: reason here
18
+ * code // oculum-ignore [rule-id]: reason here
19
+ *
20
+ * Block suppressions:
21
+ * /* oculum-ignore-block: reason here * /
22
+ * ... code ...
23
+ * /* oculum-ignore-block-end * /
24
+ *
25
+ * Also supports:
26
+ * # oculum-ignore-next-line: reason (Python, Ruby, YAML, etc.)
27
+ * -- oculum-ignore-next-line: reason (SQL)
28
+ */
29
+ // Regex patterns for parsing comments
30
+ const PATTERNS = {
31
+ // // oculum-ignore-next-line: reason
32
+ // // oculum-ignore-next-line [rule-id]: reason
33
+ nextLine: /(?:\/\/|#|--)\s*oculum-ignore-next-line(?:\s*\[([^\]]+)\])?\s*:\s*(.+)/i,
34
+ // code // oculum-ignore: reason
35
+ // code // oculum-ignore [rule-id]: reason
36
+ sameLine: /(?:\/\/|#|--)\s*oculum-ignore(?:\s*\[([^\]]+)\])?\s*:\s*(.+)/i,
37
+ // /* oculum-ignore-block: reason */
38
+ // /* oculum-ignore-block [rule-id]: reason */
39
+ blockStart: /\/\*\s*oculum-ignore-block(?:\s*\[([^\]]+)\])?\s*:\s*([^*]+)\*\//i,
40
+ // /* oculum-ignore-block-end */
41
+ blockEnd: /\/\*\s*oculum-ignore-block-end\s*\*\//i,
42
+ };
43
+ /**
44
+ * Parse a single line for suppression comments
45
+ */
46
+ function parseLineForSuppression(line, lineNumber) {
47
+ // Check for next-line suppression (must be the only thing on the line, aside from whitespace)
48
+ const trimmed = line.trim();
49
+ // Next-line pattern (comment at start of line)
50
+ if (trimmed.startsWith('//') ||
51
+ trimmed.startsWith('#') ||
52
+ trimmed.startsWith('--')) {
53
+ const nextLineMatch = trimmed.match(PATTERNS.nextLine);
54
+ if (nextLineMatch) {
55
+ return {
56
+ lineNumber,
57
+ type: 'next-line',
58
+ ruleId: nextLineMatch[1],
59
+ reason: nextLineMatch[2].trim(),
60
+ commentText: trimmed,
61
+ };
62
+ }
63
+ }
64
+ // Same-line pattern (comment at end of line with code before)
65
+ // Only check if there's actual code before the comment
66
+ const sameLineMatch = line.match(PATTERNS.sameLine);
67
+ if (sameLineMatch) {
68
+ // Find where the comment starts
69
+ const commentIndex = line.search(/(?:\/\/|#|--)\s*oculum-ignore/i);
70
+ const beforeComment = line.substring(0, commentIndex).trim();
71
+ // Only treat as same-line if there's code before the comment
72
+ // (not just whitespace or if it's at the start)
73
+ if (beforeComment.length > 0) {
74
+ return {
75
+ lineNumber,
76
+ type: 'same-line',
77
+ ruleId: sameLineMatch[1],
78
+ reason: sameLineMatch[2].trim(),
79
+ commentText: line.substring(commentIndex).trim(),
80
+ };
81
+ }
82
+ }
83
+ // Block start pattern
84
+ const blockStartMatch = line.match(PATTERNS.blockStart);
85
+ if (blockStartMatch) {
86
+ return {
87
+ lineNumber,
88
+ type: 'block-start',
89
+ ruleId: blockStartMatch[1],
90
+ reason: blockStartMatch[2].trim(),
91
+ commentText: blockStartMatch[0],
92
+ };
93
+ }
94
+ // Block end pattern
95
+ const blockEndMatch = line.match(PATTERNS.blockEnd);
96
+ if (blockEndMatch) {
97
+ return {
98
+ lineNumber,
99
+ type: 'block-end',
100
+ reason: '', // Block end has no reason
101
+ commentText: blockEndMatch[0],
102
+ };
103
+ }
104
+ return null;
105
+ }
106
+ /**
107
+ * Parse all inline suppressions from file content
108
+ *
109
+ * Returns a map of line numbers to their effective suppressions.
110
+ * A line can be suppressed by:
111
+ * 1. A same-line comment (oculum-ignore)
112
+ * 2. A next-line comment on the previous line (oculum-ignore-next-line)
113
+ * 3. Being within a block suppression (oculum-ignore-block ... oculum-ignore-block-end)
114
+ */
115
+ function parseInlineSuppressions(content) {
116
+ const lines = content.split('\n');
117
+ const suppressions = new Map();
118
+ // Track block suppression state
119
+ let currentBlock = null;
120
+ for (let i = 0; i < lines.length; i++) {
121
+ const lineNumber = i + 1; // 1-indexed
122
+ const line = lines[i];
123
+ const suppression = parseLineForSuppression(line, lineNumber);
124
+ if (suppression) {
125
+ switch (suppression.type) {
126
+ case 'next-line':
127
+ // Apply to the next line
128
+ if (i + 1 < lines.length) {
129
+ suppressions.set(lineNumber + 1, {
130
+ ...suppression,
131
+ lineNumber: lineNumber + 1,
132
+ });
133
+ }
134
+ break;
135
+ case 'same-line':
136
+ // Apply to this line
137
+ suppressions.set(lineNumber, suppression);
138
+ break;
139
+ case 'block-start':
140
+ // Start tracking block suppression
141
+ currentBlock = {
142
+ startLine: lineNumber,
143
+ reason: suppression.reason,
144
+ ruleId: suppression.ruleId,
145
+ };
146
+ break;
147
+ case 'block-end':
148
+ // End block suppression
149
+ currentBlock = null;
150
+ break;
151
+ }
152
+ }
153
+ // If we're in a block suppression, add suppression for this line
154
+ // (unless it's the block start/end line itself)
155
+ if (currentBlock && suppression?.type !== 'block-start' && suppression?.type !== 'block-end') {
156
+ // Don't override explicit same-line suppressions
157
+ if (!suppressions.has(lineNumber)) {
158
+ suppressions.set(lineNumber, {
159
+ lineNumber,
160
+ type: 'block-start', // Mark as from block
161
+ reason: currentBlock.reason,
162
+ ruleId: currentBlock.ruleId,
163
+ commentText: `Block suppression from line ${currentBlock.startLine}`,
164
+ });
165
+ }
166
+ }
167
+ }
168
+ return suppressions;
169
+ }
170
+ /**
171
+ * Check if a specific line is suppressed
172
+ */
173
+ function isLineSuppressed(suppressions, lineNumber, category) {
174
+ const suppression = suppressions.get(lineNumber);
175
+ if (!suppression) {
176
+ return null;
177
+ }
178
+ // If suppression specifies a rule and category doesn't match, not suppressed
179
+ if (suppression.ruleId && category && suppression.ruleId !== category) {
180
+ return null;
181
+ }
182
+ return suppression;
183
+ }
184
+ /**
185
+ * Extract all unique suppression reasons from a file
186
+ * Useful for auditing suppressed findings
187
+ */
188
+ function extractSuppressionReasons(content) {
189
+ const suppressions = parseInlineSuppressions(content);
190
+ const seen = new Set();
191
+ const results = [];
192
+ for (const [lineNumber, suppression] of suppressions) {
193
+ // Only include unique comment sources (not duplicates from block propagation)
194
+ const key = `${suppression.commentText}`;
195
+ if (!seen.has(key) && suppression.type !== 'block-end') {
196
+ seen.add(key);
197
+ results.push({
198
+ reason: suppression.reason,
199
+ ruleId: suppression.ruleId,
200
+ lineNumber,
201
+ type: suppression.type,
202
+ });
203
+ }
204
+ }
205
+ return results;
206
+ }
207
+ /**
208
+ * Generate a suppression comment for a given line
209
+ */
210
+ function generateSuppressionComment(reason, options = {}) {
211
+ const { type = 'next-line', ruleId, commentStyle = '//' } = options;
212
+ const ruleSpec = ruleId ? ` [${ruleId}]` : '';
213
+ if (type === 'next-line') {
214
+ return `${commentStyle} oculum-ignore-next-line${ruleSpec}: ${reason}`;
215
+ }
216
+ return `${commentStyle} oculum-ignore${ruleSpec}: ${reason}`;
217
+ }
218
+ //# sourceMappingURL=inline-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"inline-parser.js","sourceRoot":"","sources":["../../src/suppression/inline-parser.ts"],"names":[],"mappings":";AAAA;;;GAGG;;AA8HH,0DA+DC;AAKD,4CAiBC;AAMD,8DA8BC;AAKD,gEAiBC;AAxQD;;;;;;;;;;;;;;;;;GAiBG;AAEH,sCAAsC;AACtC,MAAM,QAAQ,GAAG;IACf,qCAAqC;IACrC,+CAA+C;IAC/C,QAAQ,EAAE,yEAAyE;IAEnF,gCAAgC;IAChC,0CAA0C;IAC1C,QAAQ,EAAE,+DAA+D;IAEzE,oCAAoC;IACpC,8CAA8C;IAC9C,UAAU,EAAE,mEAAmE;IAE/E,gCAAgC;IAChC,QAAQ,EAAE,wCAAwC;CACnD,CAAA;AAED;;GAEG;AACH,SAAS,uBAAuB,CAC9B,IAAY,EACZ,UAAkB;IAElB,8FAA8F;IAC9F,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,EAAE,CAAA;IAE3B,+CAA+C;IAC/C,IACE,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC;QACxB,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC;QACvB,OAAO,CAAC,UAAU,CAAC,IAAI,CAAC,EACxB,CAAC;QACD,MAAM,aAAa,GAAG,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;QACtD,IAAI,aAAa,EAAE,CAAC;YAClB,OAAO;gBACL,UAAU;gBACV,IAAI,EAAE,WAAW;gBACjB,MAAM,EAAE,aAAa,CAAC,CAAC,CAAsC;gBAC7D,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;gBAC/B,WAAW,EAAE,OAAO;aACrB,CAAA;QACH,CAAC;IACH,CAAC;IAED,8DAA8D;IAC9D,uDAAuD;IACvD,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;IACnD,IAAI,aAAa,EAAE,CAAC;QAClB,gCAAgC;QAChC,MAAM,YAAY,GAAG,IAAI,CAAC,MAAM,CAAC,gCAAgC,CAAC,CAAA;QAClE,MAAM,aAAa,GAAG,IAAI,CAAC,SAAS,CAAC,CAAC,EAAE,YAAY,CAAC,CAAC,IAAI,EAAE,CAAA;QAE5D,6DAA6D;QAC7D,gDAAgD;QAChD,IAAI,aAAa,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YAC7B,OAAO;gBACL,UAAU;gBACV,IAAI,EAAE,WAAW;gBACjB,MAAM,EAAE,aAAa,CAAC,CAAC,CAAsC;gBAC7D,MAAM,EAAE,aAAa,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;gBAC/B,WAAW,EAAE,IAAI,CAAC,SAAS,CAAC,YAAY,CAAC,CAAC,IAAI,EAAE;aACjD,CAAA;QACH,CAAC;IACH,CAAC;IAED,sBAAsB;IACtB,MAAM,eAAe,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,UAAU,CAAC,CAAA;IACvD,IAAI,eAAe,EAAE,CAAC;QACpB,OAAO;YACL,UAAU;YACV,IAAI,EAAE,aAAa;YACnB,MAAM,EAAE,eAAe,CAAC,CAAC,CAAsC;YAC/D,MAAM,EAAE,eAAe,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE;YACjC,WAAW,EAAE,eAAe,CAAC,CAAC,CAAC;SAChC,CAAA;IACH,CAAC;IAED,oBAAoB;IACpB,MAAM,aAAa,GAAG,IAAI,CAAC,KAAK,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAA;IACnD,IAAI,aAAa,EAAE,CAAC;QAClB,OAAO;YACL,UAAU;YACV,IAAI,EAAE,WAAW;YACjB,MAAM,EAAE,EAAE,EAAE,0BAA0B;YACtC,WAAW,EAAE,aAAa,CAAC,CAAC,CAAC;SAC9B,CAAA;IACH,CAAC;IAED,OAAO,IAAI,CAAA;AACb,CAAC;AAED;;;;;;;;GAQG;AACH,SAAgB,uBAAuB,CAAC,OAAe;IACrD,MAAM,KAAK,GAAG,OAAO,CAAC,KAAK,CAAC,IAAI,CAAC,CAAA;IACjC,MAAM,YAAY,GAAG,IAAI,GAAG,EAA6B,CAAA;IAEzD,gCAAgC;IAChC,IAAI,YAAY,GAAiF,IAAI,CAAA;IAErG,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACtC,MAAM,UAAU,GAAG,CAAC,GAAG,CAAC,CAAA,CAAC,YAAY;QACrC,MAAM,IAAI,GAAG,KAAK,CAAC,CAAC,CAAC,CAAA;QAErB,MAAM,WAAW,GAAG,uBAAuB,CAAC,IAAI,EAAE,UAAU,CAAC,CAAA;QAE7D,IAAI,WAAW,EAAE,CAAC;YAChB,QAAQ,WAAW,CAAC,IAAI,EAAE,CAAC;gBACzB,KAAK,WAAW;oBACd,yBAAyB;oBACzB,IAAI,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC;wBACzB,YAAY,CAAC,GAAG,CAAC,UAAU,GAAG,CAAC,EAAE;4BAC/B,GAAG,WAAW;4BACd,UAAU,EAAE,UAAU,GAAG,CAAC;yBAC3B,CAAC,CAAA;oBACJ,CAAC;oBACD,MAAK;gBAEP,KAAK,WAAW;oBACd,qBAAqB;oBACrB,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE,WAAW,CAAC,CAAA;oBACzC,MAAK;gBAEP,KAAK,aAAa;oBAChB,mCAAmC;oBACnC,YAAY,GAAG;wBACb,SAAS,EAAE,UAAU;wBACrB,MAAM,EAAE,WAAW,CAAC,MAAM;wBAC1B,MAAM,EAAE,WAAW,CAAC,MAAM;qBAC3B,CAAA;oBACD,MAAK;gBAEP,KAAK,WAAW;oBACd,wBAAwB;oBACxB,YAAY,GAAG,IAAI,CAAA;oBACnB,MAAK;YACT,CAAC;QACH,CAAC;QAED,iEAAiE;QACjE,gDAAgD;QAChD,IAAI,YAAY,IAAI,WAAW,EAAE,IAAI,KAAK,aAAa,IAAI,WAAW,EAAE,IAAI,KAAK,WAAW,EAAE,CAAC;YAC7F,iDAAiD;YACjD,IAAI,CAAC,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,EAAE,CAAC;gBAClC,YAAY,CAAC,GAAG,CAAC,UAAU,EAAE;oBAC3B,UAAU;oBACV,IAAI,EAAE,aAAa,EAAE,qBAAqB;oBAC1C,MAAM,EAAE,YAAY,CAAC,MAAM;oBAC3B,MAAM,EAAE,YAAY,CAAC,MAAM;oBAC3B,WAAW,EAAE,+BAA+B,YAAY,CAAC,SAAS,EAAE;iBACrE,CAAC,CAAA;YACJ,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,YAAY,CAAA;AACrB,CAAC;AAED;;GAEG;AACH,SAAgB,gBAAgB,CAC9B,YAA4C,EAC5C,UAAkB,EAClB,QAAgC;IAEhC,MAAM,WAAW,GAAG,YAAY,CAAC,GAAG,CAAC,UAAU,CAAC,CAAA;IAEhD,IAAI,CAAC,WAAW,EAAE,CAAC;QACjB,OAAO,IAAI,CAAA;IACb,CAAC;IAED,6EAA6E;IAC7E,IAAI,WAAW,CAAC,MAAM,IAAI,QAAQ,IAAI,WAAW,CAAC,MAAM,KAAK,QAAQ,EAAE,CAAC;QACtE,OAAO,IAAI,CAAA;IACb,CAAC;IAED,OAAO,WAAW,CAAA;AACpB,CAAC;AAED;;;GAGG;AACH,SAAgB,yBAAyB,CAAC,OAAe;IAMvD,MAAM,YAAY,GAAG,uBAAuB,CAAC,OAAO,CAAC,CAAA;IACrD,MAAM,IAAI,GAAG,IAAI,GAAG,EAAU,CAAA;IAC9B,MAAM,OAAO,GAKR,EAAE,CAAA;IAEP,KAAK,MAAM,CAAC,UAAU,EAAE,WAAW,CAAC,IAAI,YAAY,EAAE,CAAC;QACrD,8EAA8E;QAC9E,MAAM,GAAG,GAAG,GAAG,WAAW,CAAC,WAAW,EAAE,CAAA;QACxC,IAAI,CAAC,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,WAAW,CAAC,IAAI,KAAK,WAAW,EAAE,CAAC;YACvD,IAAI,CAAC,GAAG,CAAC,GAAG,CAAC,CAAA;YACb,OAAO,CAAC,IAAI,CAAC;gBACX,MAAM,EAAE,WAAW,CAAC,MAAM;gBAC1B,MAAM,EAAE,WAAW,CAAC,MAAM;gBAC1B,UAAU;gBACV,IAAI,EAAE,WAAW,CAAC,IAAI;aACvB,CAAC,CAAA;QACJ,CAAC;IACH,CAAC;IAED,OAAO,OAAO,CAAA;AAChB,CAAC;AAED;;GAEG;AACH,SAAgB,0BAA0B,CACxC,MAAc,EACd,UAII,EAAE;IAEN,MAAM,EAAE,IAAI,GAAG,WAAW,EAAE,MAAM,EAAE,YAAY,GAAG,IAAI,EAAE,GAAG,OAAO,CAAA;IAEnE,MAAM,QAAQ,GAAG,MAAM,CAAC,CAAC,CAAC,KAAK,MAAM,GAAG,CAAC,CAAC,CAAC,EAAE,CAAA;IAE7C,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;QACzB,OAAO,GAAG,YAAY,2BAA2B,QAAQ,KAAK,MAAM,EAAE,CAAA;IACxE,CAAC;IAED,OAAO,GAAG,YAAY,iBAAiB,QAAQ,KAAK,MAAM,EAAE,CAAA;AAC9D,CAAC"}
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Suppression Manager
3
+ * Central class for managing all suppression logic
4
+ */
5
+ import type { Vulnerability, ScanFile } from '../types';
6
+ import type { SuppressionConfig, SuppressionMatch, SuppressionResult, RuleSuppression, FindingSuppression } from './types';
7
+ /**
8
+ * Options for SuppressionManager
9
+ */
10
+ export interface SuppressionManagerOptions {
11
+ /** Path to the project root (for finding config files) */
12
+ projectPath: string;
13
+ /** Optional pre-loaded config (skips file loading) */
14
+ config?: SuppressionConfig;
15
+ /** Whether to include expired suppressions (for auditing) */
16
+ includeExpired?: boolean;
17
+ }
18
+ /**
19
+ * SuppressionManager handles all suppression logic
20
+ *
21
+ * Priority order for suppressions:
22
+ * 1. Inline comment suppressions (highest priority)
23
+ * 2. Config file finding suppressions (by hash)
24
+ * 3. Config file rule suppressions (by category)
25
+ */
26
+ export declare class SuppressionManager {
27
+ private config;
28
+ private configPath;
29
+ private configErrors;
30
+ private includeExpired;
31
+ private projectPath;
32
+ private inlineSuppressionCache;
33
+ constructor(options: SuppressionManagerOptions);
34
+ /**
35
+ * Get configuration errors (if any)
36
+ */
37
+ getConfigErrors(): string[];
38
+ /**
39
+ * Get the path to the config file (if found)
40
+ */
41
+ getConfigPath(): string | undefined;
42
+ /**
43
+ * Check if a file path should be ignored entirely
44
+ */
45
+ isPathIgnored(filePath: string): boolean;
46
+ /**
47
+ * Parse inline suppressions for a file
48
+ */
49
+ private getInlineSuppressions;
50
+ /**
51
+ * Check if a finding is suppressed
52
+ *
53
+ * Priority:
54
+ * 1. Inline comment (highest)
55
+ * 2. Config finding suppression (by hash)
56
+ * 3. Config rule suppression (by category)
57
+ */
58
+ isFindingSuppressed(finding: Vulnerability, fileContent?: string): SuppressionMatch;
59
+ /**
60
+ * Apply suppressions to a list of findings
61
+ */
62
+ applySuppressions(findings: Vulnerability[], files: ScanFile[]): SuppressionResult;
63
+ /**
64
+ * Get all suppressions from config
65
+ */
66
+ getAllSuppressions(): {
67
+ rules: RuleSuppression[];
68
+ findings: FindingSuppression[];
69
+ };
70
+ /**
71
+ * Get ignore patterns from config
72
+ */
73
+ getIgnorePatterns(): string[];
74
+ /**
75
+ * Check if suppression system is active (has any suppressions)
76
+ */
77
+ hasSuppressions(): boolean;
78
+ /**
79
+ * Get summary of suppression configuration
80
+ */
81
+ getSummary(): {
82
+ configPath: string | undefined;
83
+ ruleCount: number;
84
+ findingCount: number;
85
+ ignorePatternCount: number;
86
+ hasErrors: boolean;
87
+ };
88
+ /**
89
+ * Clear the inline suppression cache
90
+ * (useful if files have been modified)
91
+ */
92
+ clearCache(): void;
93
+ }
94
+ //# sourceMappingURL=manager.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/suppression/manager.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,KAAK,EAAE,aAAa,EAAE,QAAQ,EAAE,MAAM,UAAU,CAAA;AACvD,OAAO,KAAK,EACV,iBAAiB,EACjB,gBAAgB,EAChB,iBAAiB,EAGjB,eAAe,EACf,kBAAkB,EACnB,MAAM,SAAS,CAAA;AAKhB;;GAEG;AACH,MAAM,WAAW,yBAAyB;IACxC,0DAA0D;IAC1D,WAAW,EAAE,MAAM,CAAA;IACnB,sDAAsD;IACtD,MAAM,CAAC,EAAE,iBAAiB,CAAA;IAC1B,6DAA6D;IAC7D,cAAc,CAAC,EAAE,OAAO,CAAA;CACzB;AAED;;;;;;;GAOG;AACH,qBAAa,kBAAkB;IAC7B,OAAO,CAAC,MAAM,CAAmB;IACjC,OAAO,CAAC,UAAU,CAAoB;IACtC,OAAO,CAAC,YAAY,CAAU;IAC9B,OAAO,CAAC,cAAc,CAAS;IAC/B,OAAO,CAAC,WAAW,CAAQ;IAG3B,OAAO,CAAC,sBAAsB,CAAyD;gBAE3E,OAAO,EAAE,yBAAyB;IAgB9C;;OAEG;IACH,eAAe,IAAI,MAAM,EAAE;IAI3B;;OAEG;IACH,aAAa,IAAI,MAAM,GAAG,SAAS;IAInC;;OAEG;IACH,aAAa,CAAC,QAAQ,EAAE,MAAM,GAAG,OAAO;IAYxC;;OAEG;IACH,OAAO,CAAC,qBAAqB;IAgB7B;;;;;;;OAOG;IACH,mBAAmB,CACjB,OAAO,EAAE,aAAa,EACtB,WAAW,CAAC,EAAE,MAAM,GACnB,gBAAgB;IAmHnB;;OAEG;IACH,iBAAiB,CACf,QAAQ,EAAE,aAAa,EAAE,EACzB,KAAK,EAAE,QAAQ,EAAE,GAChB,iBAAiB;IA2EpB;;OAEG;IACH,kBAAkB,IAAI;QACpB,KAAK,EAAE,eAAe,EAAE,CAAA;QACxB,QAAQ,EAAE,kBAAkB,EAAE,CAAA;KAC/B;IAOD;;OAEG;IACH,iBAAiB,IAAI,MAAM,EAAE;IAI7B;;OAEG;IACH,eAAe,IAAI,OAAO;IAQ1B;;OAEG;IACH,UAAU,IAAI;QACZ,UAAU,EAAE,MAAM,GAAG,SAAS,CAAA;QAC9B,SAAS,EAAE,MAAM,CAAA;QACjB,YAAY,EAAE,MAAM,CAAA;QACpB,kBAAkB,EAAE,MAAM,CAAA;QAC1B,SAAS,EAAE,OAAO,CAAA;KACnB;IAUD;;;OAGG;IACH,UAAU,IAAI,IAAI;CAGnB"}