@oculum/scanner 1.0.0

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 (281) hide show
  1. package/dist/formatters/cli-terminal.d.ts +27 -0
  2. package/dist/formatters/cli-terminal.d.ts.map +1 -0
  3. package/dist/formatters/cli-terminal.js +412 -0
  4. package/dist/formatters/cli-terminal.js.map +1 -0
  5. package/dist/formatters/github-comment.d.ts +41 -0
  6. package/dist/formatters/github-comment.d.ts.map +1 -0
  7. package/dist/formatters/github-comment.js +306 -0
  8. package/dist/formatters/github-comment.js.map +1 -0
  9. package/dist/formatters/grouping.d.ts +52 -0
  10. package/dist/formatters/grouping.d.ts.map +1 -0
  11. package/dist/formatters/grouping.js +152 -0
  12. package/dist/formatters/grouping.js.map +1 -0
  13. package/dist/formatters/index.d.ts +9 -0
  14. package/dist/formatters/index.d.ts.map +1 -0
  15. package/dist/formatters/index.js +35 -0
  16. package/dist/formatters/index.js.map +1 -0
  17. package/dist/formatters/vscode-diagnostic.d.ts +103 -0
  18. package/dist/formatters/vscode-diagnostic.d.ts.map +1 -0
  19. package/dist/formatters/vscode-diagnostic.js +151 -0
  20. package/dist/formatters/vscode-diagnostic.js.map +1 -0
  21. package/dist/index.d.ts +52 -0
  22. package/dist/index.d.ts.map +1 -0
  23. package/dist/index.js +648 -0
  24. package/dist/index.js.map +1 -0
  25. package/dist/layer1/comments.d.ts +8 -0
  26. package/dist/layer1/comments.d.ts.map +1 -0
  27. package/dist/layer1/comments.js +203 -0
  28. package/dist/layer1/comments.js.map +1 -0
  29. package/dist/layer1/config-audit.d.ts +8 -0
  30. package/dist/layer1/config-audit.d.ts.map +1 -0
  31. package/dist/layer1/config-audit.js +252 -0
  32. package/dist/layer1/config-audit.js.map +1 -0
  33. package/dist/layer1/entropy.d.ts +8 -0
  34. package/dist/layer1/entropy.d.ts.map +1 -0
  35. package/dist/layer1/entropy.js +500 -0
  36. package/dist/layer1/entropy.js.map +1 -0
  37. package/dist/layer1/file-flags.d.ts +7 -0
  38. package/dist/layer1/file-flags.d.ts.map +1 -0
  39. package/dist/layer1/file-flags.js +112 -0
  40. package/dist/layer1/file-flags.js.map +1 -0
  41. package/dist/layer1/index.d.ts +36 -0
  42. package/dist/layer1/index.d.ts.map +1 -0
  43. package/dist/layer1/index.js +132 -0
  44. package/dist/layer1/index.js.map +1 -0
  45. package/dist/layer1/patterns.d.ts +8 -0
  46. package/dist/layer1/patterns.d.ts.map +1 -0
  47. package/dist/layer1/patterns.js +482 -0
  48. package/dist/layer1/patterns.js.map +1 -0
  49. package/dist/layer1/urls.d.ts +8 -0
  50. package/dist/layer1/urls.d.ts.map +1 -0
  51. package/dist/layer1/urls.js +296 -0
  52. package/dist/layer1/urls.js.map +1 -0
  53. package/dist/layer1/weak-crypto.d.ts +7 -0
  54. package/dist/layer1/weak-crypto.d.ts.map +1 -0
  55. package/dist/layer1/weak-crypto.js +291 -0
  56. package/dist/layer1/weak-crypto.js.map +1 -0
  57. package/dist/layer2/ai-agent-tools.d.ts +19 -0
  58. package/dist/layer2/ai-agent-tools.d.ts.map +1 -0
  59. package/dist/layer2/ai-agent-tools.js +528 -0
  60. package/dist/layer2/ai-agent-tools.js.map +1 -0
  61. package/dist/layer2/ai-endpoint-protection.d.ts +36 -0
  62. package/dist/layer2/ai-endpoint-protection.d.ts.map +1 -0
  63. package/dist/layer2/ai-endpoint-protection.js +332 -0
  64. package/dist/layer2/ai-endpoint-protection.js.map +1 -0
  65. package/dist/layer2/ai-execution-sinks.d.ts +18 -0
  66. package/dist/layer2/ai-execution-sinks.d.ts.map +1 -0
  67. package/dist/layer2/ai-execution-sinks.js +496 -0
  68. package/dist/layer2/ai-execution-sinks.js.map +1 -0
  69. package/dist/layer2/ai-fingerprinting.d.ts +7 -0
  70. package/dist/layer2/ai-fingerprinting.d.ts.map +1 -0
  71. package/dist/layer2/ai-fingerprinting.js +654 -0
  72. package/dist/layer2/ai-fingerprinting.js.map +1 -0
  73. package/dist/layer2/ai-prompt-hygiene.d.ts +19 -0
  74. package/dist/layer2/ai-prompt-hygiene.d.ts.map +1 -0
  75. package/dist/layer2/ai-prompt-hygiene.js +356 -0
  76. package/dist/layer2/ai-prompt-hygiene.js.map +1 -0
  77. package/dist/layer2/ai-rag-safety.d.ts +21 -0
  78. package/dist/layer2/ai-rag-safety.d.ts.map +1 -0
  79. package/dist/layer2/ai-rag-safety.js +459 -0
  80. package/dist/layer2/ai-rag-safety.js.map +1 -0
  81. package/dist/layer2/ai-schema-validation.d.ts +25 -0
  82. package/dist/layer2/ai-schema-validation.d.ts.map +1 -0
  83. package/dist/layer2/ai-schema-validation.js +375 -0
  84. package/dist/layer2/ai-schema-validation.js.map +1 -0
  85. package/dist/layer2/auth-antipatterns.d.ts +20 -0
  86. package/dist/layer2/auth-antipatterns.d.ts.map +1 -0
  87. package/dist/layer2/auth-antipatterns.js +333 -0
  88. package/dist/layer2/auth-antipatterns.js.map +1 -0
  89. package/dist/layer2/byok-patterns.d.ts +12 -0
  90. package/dist/layer2/byok-patterns.d.ts.map +1 -0
  91. package/dist/layer2/byok-patterns.js +299 -0
  92. package/dist/layer2/byok-patterns.js.map +1 -0
  93. package/dist/layer2/dangerous-functions.d.ts +7 -0
  94. package/dist/layer2/dangerous-functions.d.ts.map +1 -0
  95. package/dist/layer2/dangerous-functions.js +1375 -0
  96. package/dist/layer2/dangerous-functions.js.map +1 -0
  97. package/dist/layer2/data-exposure.d.ts +16 -0
  98. package/dist/layer2/data-exposure.d.ts.map +1 -0
  99. package/dist/layer2/data-exposure.js +279 -0
  100. package/dist/layer2/data-exposure.js.map +1 -0
  101. package/dist/layer2/framework-checks.d.ts +7 -0
  102. package/dist/layer2/framework-checks.d.ts.map +1 -0
  103. package/dist/layer2/framework-checks.js +388 -0
  104. package/dist/layer2/framework-checks.js.map +1 -0
  105. package/dist/layer2/index.d.ts +58 -0
  106. package/dist/layer2/index.d.ts.map +1 -0
  107. package/dist/layer2/index.js +380 -0
  108. package/dist/layer2/index.js.map +1 -0
  109. package/dist/layer2/logic-gates.d.ts +7 -0
  110. package/dist/layer2/logic-gates.d.ts.map +1 -0
  111. package/dist/layer2/logic-gates.js +182 -0
  112. package/dist/layer2/logic-gates.js.map +1 -0
  113. package/dist/layer2/risky-imports.d.ts +7 -0
  114. package/dist/layer2/risky-imports.d.ts.map +1 -0
  115. package/dist/layer2/risky-imports.js +161 -0
  116. package/dist/layer2/risky-imports.js.map +1 -0
  117. package/dist/layer2/variables.d.ts +8 -0
  118. package/dist/layer2/variables.d.ts.map +1 -0
  119. package/dist/layer2/variables.js +152 -0
  120. package/dist/layer2/variables.js.map +1 -0
  121. package/dist/layer3/anthropic.d.ts +83 -0
  122. package/dist/layer3/anthropic.d.ts.map +1 -0
  123. package/dist/layer3/anthropic.js +1745 -0
  124. package/dist/layer3/anthropic.js.map +1 -0
  125. package/dist/layer3/index.d.ts +24 -0
  126. package/dist/layer3/index.d.ts.map +1 -0
  127. package/dist/layer3/index.js +119 -0
  128. package/dist/layer3/index.js.map +1 -0
  129. package/dist/layer3/openai.d.ts +25 -0
  130. package/dist/layer3/openai.d.ts.map +1 -0
  131. package/dist/layer3/openai.js +238 -0
  132. package/dist/layer3/openai.js.map +1 -0
  133. package/dist/layer3/package-check.d.ts +63 -0
  134. package/dist/layer3/package-check.d.ts.map +1 -0
  135. package/dist/layer3/package-check.js +508 -0
  136. package/dist/layer3/package-check.js.map +1 -0
  137. package/dist/modes/incremental.d.ts +66 -0
  138. package/dist/modes/incremental.d.ts.map +1 -0
  139. package/dist/modes/incremental.js +200 -0
  140. package/dist/modes/incremental.js.map +1 -0
  141. package/dist/tiers.d.ts +125 -0
  142. package/dist/tiers.d.ts.map +1 -0
  143. package/dist/tiers.js +234 -0
  144. package/dist/tiers.js.map +1 -0
  145. package/dist/types.d.ts +175 -0
  146. package/dist/types.d.ts.map +1 -0
  147. package/dist/types.js +50 -0
  148. package/dist/types.js.map +1 -0
  149. package/dist/utils/auth-helper-detector.d.ts +56 -0
  150. package/dist/utils/auth-helper-detector.d.ts.map +1 -0
  151. package/dist/utils/auth-helper-detector.js +360 -0
  152. package/dist/utils/auth-helper-detector.js.map +1 -0
  153. package/dist/utils/context-helpers.d.ts +96 -0
  154. package/dist/utils/context-helpers.d.ts.map +1 -0
  155. package/dist/utils/context-helpers.js +493 -0
  156. package/dist/utils/context-helpers.js.map +1 -0
  157. package/dist/utils/diff-detector.d.ts +53 -0
  158. package/dist/utils/diff-detector.d.ts.map +1 -0
  159. package/dist/utils/diff-detector.js +104 -0
  160. package/dist/utils/diff-detector.js.map +1 -0
  161. package/dist/utils/diff-parser.d.ts +80 -0
  162. package/dist/utils/diff-parser.d.ts.map +1 -0
  163. package/dist/utils/diff-parser.js +202 -0
  164. package/dist/utils/diff-parser.js.map +1 -0
  165. package/dist/utils/imported-auth-detector.d.ts +37 -0
  166. package/dist/utils/imported-auth-detector.d.ts.map +1 -0
  167. package/dist/utils/imported-auth-detector.js +251 -0
  168. package/dist/utils/imported-auth-detector.js.map +1 -0
  169. package/dist/utils/middleware-detector.d.ts +55 -0
  170. package/dist/utils/middleware-detector.d.ts.map +1 -0
  171. package/dist/utils/middleware-detector.js +260 -0
  172. package/dist/utils/middleware-detector.js.map +1 -0
  173. package/dist/utils/oauth-flow-detector.d.ts +41 -0
  174. package/dist/utils/oauth-flow-detector.d.ts.map +1 -0
  175. package/dist/utils/oauth-flow-detector.js +202 -0
  176. package/dist/utils/oauth-flow-detector.js.map +1 -0
  177. package/dist/utils/path-exclusions.d.ts +55 -0
  178. package/dist/utils/path-exclusions.d.ts.map +1 -0
  179. package/dist/utils/path-exclusions.js +222 -0
  180. package/dist/utils/path-exclusions.js.map +1 -0
  181. package/dist/utils/project-context-builder.d.ts +119 -0
  182. package/dist/utils/project-context-builder.d.ts.map +1 -0
  183. package/dist/utils/project-context-builder.js +534 -0
  184. package/dist/utils/project-context-builder.js.map +1 -0
  185. package/dist/utils/registry-clients.d.ts +93 -0
  186. package/dist/utils/registry-clients.d.ts.map +1 -0
  187. package/dist/utils/registry-clients.js +273 -0
  188. package/dist/utils/registry-clients.js.map +1 -0
  189. package/dist/utils/trpc-analyzer.d.ts +78 -0
  190. package/dist/utils/trpc-analyzer.d.ts.map +1 -0
  191. package/dist/utils/trpc-analyzer.js +297 -0
  192. package/dist/utils/trpc-analyzer.js.map +1 -0
  193. package/package.json +45 -0
  194. package/src/__tests__/benchmark/fixtures/false-positives.ts +227 -0
  195. package/src/__tests__/benchmark/fixtures/index.ts +68 -0
  196. package/src/__tests__/benchmark/fixtures/layer1/config-audit.ts +364 -0
  197. package/src/__tests__/benchmark/fixtures/layer1/hardcoded-secrets.ts +173 -0
  198. package/src/__tests__/benchmark/fixtures/layer1/high-entropy.ts +234 -0
  199. package/src/__tests__/benchmark/fixtures/layer1/index.ts +31 -0
  200. package/src/__tests__/benchmark/fixtures/layer1/sensitive-urls.ts +90 -0
  201. package/src/__tests__/benchmark/fixtures/layer1/weak-crypto.ts +197 -0
  202. package/src/__tests__/benchmark/fixtures/layer2/ai-agent-tools.ts +170 -0
  203. package/src/__tests__/benchmark/fixtures/layer2/ai-endpoint-protection.ts +418 -0
  204. package/src/__tests__/benchmark/fixtures/layer2/ai-execution-sinks.ts +189 -0
  205. package/src/__tests__/benchmark/fixtures/layer2/ai-fingerprinting.ts +316 -0
  206. package/src/__tests__/benchmark/fixtures/layer2/ai-prompt-hygiene.ts +178 -0
  207. package/src/__tests__/benchmark/fixtures/layer2/ai-rag-safety.ts +184 -0
  208. package/src/__tests__/benchmark/fixtures/layer2/ai-schema-validation.ts +434 -0
  209. package/src/__tests__/benchmark/fixtures/layer2/auth-antipatterns.ts +159 -0
  210. package/src/__tests__/benchmark/fixtures/layer2/byok-patterns.ts +112 -0
  211. package/src/__tests__/benchmark/fixtures/layer2/dangerous-functions.ts +246 -0
  212. package/src/__tests__/benchmark/fixtures/layer2/data-exposure.ts +168 -0
  213. package/src/__tests__/benchmark/fixtures/layer2/framework-checks.ts +346 -0
  214. package/src/__tests__/benchmark/fixtures/layer2/index.ts +67 -0
  215. package/src/__tests__/benchmark/fixtures/layer2/injection-vulnerabilities.ts +239 -0
  216. package/src/__tests__/benchmark/fixtures/layer2/logic-gates.ts +246 -0
  217. package/src/__tests__/benchmark/fixtures/layer2/risky-imports.ts +231 -0
  218. package/src/__tests__/benchmark/fixtures/layer2/variables.ts +167 -0
  219. package/src/__tests__/benchmark/index.ts +29 -0
  220. package/src/__tests__/benchmark/run-benchmark.ts +144 -0
  221. package/src/__tests__/benchmark/run-depth-validation.ts +206 -0
  222. package/src/__tests__/benchmark/run-real-world-test.ts +243 -0
  223. package/src/__tests__/benchmark/security-benchmark-script.ts +1737 -0
  224. package/src/__tests__/benchmark/tier-integration-script.ts +177 -0
  225. package/src/__tests__/benchmark/types.ts +144 -0
  226. package/src/__tests__/benchmark/utils/test-runner.ts +475 -0
  227. package/src/__tests__/regression/known-false-positives.test.ts +467 -0
  228. package/src/__tests__/snapshots/__snapshots__/scan-depth.test.ts.snap +178 -0
  229. package/src/__tests__/snapshots/scan-depth.test.ts +258 -0
  230. package/src/__tests__/validation/analyze-results.ts +542 -0
  231. package/src/__tests__/validation/extract-for-triage.ts +146 -0
  232. package/src/__tests__/validation/fp-deep-analysis.ts +327 -0
  233. package/src/__tests__/validation/run-validation.ts +364 -0
  234. package/src/__tests__/validation/triage-template.md +132 -0
  235. package/src/formatters/cli-terminal.ts +446 -0
  236. package/src/formatters/github-comment.ts +382 -0
  237. package/src/formatters/grouping.ts +190 -0
  238. package/src/formatters/index.ts +47 -0
  239. package/src/formatters/vscode-diagnostic.ts +243 -0
  240. package/src/index.ts +823 -0
  241. package/src/layer1/comments.ts +218 -0
  242. package/src/layer1/config-audit.ts +289 -0
  243. package/src/layer1/entropy.ts +583 -0
  244. package/src/layer1/file-flags.ts +127 -0
  245. package/src/layer1/index.ts +181 -0
  246. package/src/layer1/patterns.ts +516 -0
  247. package/src/layer1/urls.ts +334 -0
  248. package/src/layer1/weak-crypto.ts +328 -0
  249. package/src/layer2/ai-agent-tools.ts +601 -0
  250. package/src/layer2/ai-endpoint-protection.ts +387 -0
  251. package/src/layer2/ai-execution-sinks.ts +580 -0
  252. package/src/layer2/ai-fingerprinting.ts +758 -0
  253. package/src/layer2/ai-prompt-hygiene.ts +411 -0
  254. package/src/layer2/ai-rag-safety.ts +511 -0
  255. package/src/layer2/ai-schema-validation.ts +421 -0
  256. package/src/layer2/auth-antipatterns.ts +394 -0
  257. package/src/layer2/byok-patterns.ts +336 -0
  258. package/src/layer2/dangerous-functions.ts +1563 -0
  259. package/src/layer2/data-exposure.ts +315 -0
  260. package/src/layer2/framework-checks.ts +433 -0
  261. package/src/layer2/index.ts +473 -0
  262. package/src/layer2/logic-gates.ts +206 -0
  263. package/src/layer2/risky-imports.ts +186 -0
  264. package/src/layer2/variables.ts +166 -0
  265. package/src/layer3/anthropic.ts +2030 -0
  266. package/src/layer3/index.ts +130 -0
  267. package/src/layer3/package-check.ts +604 -0
  268. package/src/modes/incremental.ts +293 -0
  269. package/src/tiers.ts +318 -0
  270. package/src/types.ts +284 -0
  271. package/src/utils/auth-helper-detector.ts +443 -0
  272. package/src/utils/context-helpers.ts +535 -0
  273. package/src/utils/diff-detector.ts +135 -0
  274. package/src/utils/diff-parser.ts +272 -0
  275. package/src/utils/imported-auth-detector.ts +320 -0
  276. package/src/utils/middleware-detector.ts +333 -0
  277. package/src/utils/oauth-flow-detector.ts +246 -0
  278. package/src/utils/path-exclusions.ts +266 -0
  279. package/src/utils/project-context-builder.ts +707 -0
  280. package/src/utils/registry-clients.ts +351 -0
  281. package/src/utils/trpc-analyzer.ts +382 -0
@@ -0,0 +1,306 @@
1
+ "use strict";
2
+ /**
3
+ * GitHub Comment Formatter
4
+ * Formats scan results as markdown for GitHub PR comments
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.formatGitHubComment = formatGitHubComment;
8
+ exports.formatShortStatus = formatShortStatus;
9
+ exports.formatAnnotation = formatAnnotation;
10
+ const grouping_1 = require("./grouping");
11
+ /**
12
+ * Severity badges for GitHub markdown
13
+ */
14
+ const SEVERITY_BADGE = {
15
+ critical: '🔴 Critical',
16
+ high: '🟠 High',
17
+ medium: '🟡 Medium',
18
+ low: '🔵 Low',
19
+ info: '⚪ Info',
20
+ };
21
+ /**
22
+ * Category documentation URLs
23
+ */
24
+ const CATEGORY_DOCS = {
25
+ hardcoded_secret: 'https://oculum.dev/docs/rules/hardcoded-secrets',
26
+ ai_prompt_injection: 'https://oculum.dev/docs/rules/prompt-injection',
27
+ ai_unsafe_execution: 'https://oculum.dev/docs/rules/unsafe-execution',
28
+ ai_overpermissive_tool: 'https://oculum.dev/docs/rules/overpermissive-tools',
29
+ ai_rag_exfiltration: 'https://oculum.dev/docs/rules/rag-exfiltration',
30
+ ai_endpoint_unprotected: 'https://oculum.dev/docs/rules/unprotected-endpoints',
31
+ ai_schema_mismatch: 'https://oculum.dev/docs/rules/schema-validation',
32
+ sql_injection: 'https://oculum.dev/docs/rules/sql-injection',
33
+ xss: 'https://oculum.dev/docs/rules/xss',
34
+ missing_auth: 'https://oculum.dev/docs/rules/missing-auth',
35
+ data_exposure: 'https://oculum.dev/docs/rules/data-exposure',
36
+ };
37
+ /**
38
+ * Format a single finding as a markdown list item
39
+ */
40
+ function formatFinding(finding, options = {}) {
41
+ const { showFile = true, showDocs = true } = options;
42
+ const badge = SEVERITY_BADGE[finding.severity];
43
+ const location = showFile
44
+ ? `\`${finding.filePath}:${finding.lineNumber}\``
45
+ : `Line ${finding.lineNumber}`;
46
+ let md = `- ${badge} **${finding.title}**\n`;
47
+ md += ` - 📍 ${location}\n`;
48
+ md += ` - ${finding.description}\n`;
49
+ if (finding.suggestedFix) {
50
+ md += ` - 💡 **Fix:** ${finding.suggestedFix}\n`;
51
+ }
52
+ // Add documentation link if available
53
+ const docsUrl = CATEGORY_DOCS[finding.category];
54
+ if (showDocs && docsUrl) {
55
+ md += ` - 📚 [Learn more](${docsUrl})\n`;
56
+ }
57
+ return md;
58
+ }
59
+ /**
60
+ * Format a group of findings
61
+ */
62
+ function formatGroup(group, maxFindings = 5) {
63
+ const { themeIcon, themeName, findings, severityCounts } = group;
64
+ // Count summary
65
+ const counts = [];
66
+ if (severityCounts.critical > 0)
67
+ counts.push(`${severityCounts.critical} critical`);
68
+ if (severityCounts.high > 0)
69
+ counts.push(`${severityCounts.high} high`);
70
+ if (severityCounts.medium > 0)
71
+ counts.push(`${severityCounts.medium} medium`);
72
+ if (severityCounts.low > 0)
73
+ counts.push(`${severityCounts.low} low`);
74
+ if (severityCounts.info > 0)
75
+ counts.push(`${severityCounts.info} info`);
76
+ let md = `### ${themeIcon} ${themeName}\n`;
77
+ md += `> ${counts.join(', ')}\n\n`;
78
+ // Show top findings
79
+ const shown = findings.slice(0, maxFindings);
80
+ for (const finding of shown) {
81
+ md += formatFinding(finding) + '\n';
82
+ }
83
+ // Show truncation notice if needed
84
+ if (findings.length > maxFindings) {
85
+ md += `<details>\n<summary>+ ${findings.length - maxFindings} more ${themeName.toLowerCase()} issues</summary>\n\n`;
86
+ for (const finding of findings.slice(maxFindings)) {
87
+ md += formatFinding(finding) + '\n';
88
+ }
89
+ md += `</details>\n`;
90
+ }
91
+ return md;
92
+ }
93
+ /**
94
+ * Format scan result as GitHub PR comment
95
+ */
96
+ function formatGitHubComment(result, options = {}) {
97
+ const { maxFindingsPerGroup = 5, showAllFindings = false, includeFooter = true, scanDepth, previousScanCounts, } = options;
98
+ const { vulnerabilities, severityCounts, hasBlockingIssues } = result;
99
+ // Professional header with Oculum branding
100
+ let md = `<!-- oculum-security-scan -->\n`;
101
+ md += `<div align="center">\n\n`;
102
+ md += `# 🛡️ Oculum Security Scan\n\n`;
103
+ md += `</div>\n\n`;
104
+ // Status banner
105
+ if (hasBlockingIssues) {
106
+ const blocking = severityCounts.critical + severityCounts.high;
107
+ md += `> 🚨 **${blocking} blocking issue${blocking === 1 ? '' : 's'} found** — These must be addressed before merging.\n\n`;
108
+ }
109
+ else if (vulnerabilities.length > 0) {
110
+ md += `> ⚠️ **${vulnerabilities.length} issue${vulnerabilities.length === 1 ? '' : 's'} found** — Review recommended, but no blocking issues.\n\n`;
111
+ }
112
+ else {
113
+ md += `> ✅ **No security issues detected** — This PR looks good!\n\n`;
114
+ md += formatScanMetadata(result, scanDepth);
115
+ if (includeFooter) {
116
+ md += formatFooter();
117
+ }
118
+ return md;
119
+ }
120
+ // Comparison with previous scan if available
121
+ if (previousScanCounts) {
122
+ md += formatComparison(severityCounts, previousScanCounts);
123
+ }
124
+ // Summary section
125
+ md += `## 📊 Summary\n\n`;
126
+ md += formatSummaryTable(severityCounts);
127
+ md += '\n';
128
+ // Scan metadata
129
+ md += formatScanMetadata(result, scanDepth);
130
+ // Blocking issues section (critical + high)
131
+ const blockingIssues = (0, grouping_1.getBlockingIssues)(vulnerabilities);
132
+ if (blockingIssues.length > 0) {
133
+ md += `## 🚨 Blocking Issues\n\n`;
134
+ md += `> These issues must be fixed before merging.\n\n`;
135
+ for (const finding of blockingIssues.slice(0, 10)) {
136
+ md += formatFinding(finding) + '\n';
137
+ }
138
+ if (blockingIssues.length > 10) {
139
+ md += `<details>\n<summary>+ ${blockingIssues.length - 10} more blocking issues</summary>\n\n`;
140
+ for (const finding of blockingIssues.slice(10)) {
141
+ md += formatFinding(finding, { showDocs: false }) + '\n';
142
+ }
143
+ md += `</details>\n`;
144
+ }
145
+ md += '\n';
146
+ }
147
+ // All findings grouped by theme
148
+ const grouped = (0, grouping_1.groupByTheme)(vulnerabilities);
149
+ const limited = showAllFindings ? grouped : (0, grouping_1.limitPerGroup)(grouped, 10);
150
+ // Only show non-blocking findings in "All Findings" section
151
+ const hasNonBlockingFindings = vulnerabilities.some(v => v.severity !== 'critical' && v.severity !== 'high');
152
+ if (hasNonBlockingFindings) {
153
+ md += `## 📋 All Findings by Category\n\n`;
154
+ for (const group of limited) {
155
+ // Skip groups with only blocking issues (already shown above)
156
+ const nonBlockingInGroup = group.findings.filter(f => f.severity !== 'critical' && f.severity !== 'high');
157
+ if (nonBlockingInGroup.length === 0)
158
+ continue;
159
+ md += formatGroup(group, maxFindingsPerGroup) + '\n';
160
+ }
161
+ }
162
+ // Quick actions
163
+ md += formatQuickActions(hasBlockingIssues);
164
+ // Footer
165
+ if (includeFooter) {
166
+ md += formatFooter();
167
+ }
168
+ return md;
169
+ }
170
+ /**
171
+ * Format summary table
172
+ */
173
+ function formatSummaryTable(severityCounts) {
174
+ let md = `| Severity | Count | Status |\n`;
175
+ md += `|:---------|:-----:|:------:|\n`;
176
+ if (severityCounts.critical > 0) {
177
+ md += `| 🔴 **Critical** | ${severityCounts.critical} | ❌ Blocking |\n`;
178
+ }
179
+ if (severityCounts.high > 0) {
180
+ md += `| 🟠 **High** | ${severityCounts.high} | ❌ Blocking |\n`;
181
+ }
182
+ if (severityCounts.medium > 0) {
183
+ md += `| 🟡 Medium | ${severityCounts.medium} | ⚠️ Review |\n`;
184
+ }
185
+ if (severityCounts.low > 0) {
186
+ md += `| 🔵 Low | ${severityCounts.low} | ℹ️ Info |\n`;
187
+ }
188
+ if (severityCounts.info > 0) {
189
+ md += `| ⚪ Info | ${severityCounts.info} | ℹ️ Info |\n`;
190
+ }
191
+ return md;
192
+ }
193
+ /**
194
+ * Format comparison with previous scan
195
+ */
196
+ function formatComparison(current, previous) {
197
+ const currentTotal = Object.values(current).reduce((a, b) => a + b, 0);
198
+ const previousTotal = Object.values(previous).reduce((a, b) => a + b, 0);
199
+ const diff = currentTotal - previousTotal;
200
+ const currentBlocking = current.critical + current.high;
201
+ const previousBlocking = previous.critical + previous.high;
202
+ const blockingDiff = currentBlocking - previousBlocking;
203
+ let md = `### 📈 Changes from Previous Scan\n\n`;
204
+ if (diff === 0 && blockingDiff === 0) {
205
+ md += `No change in findings.\n\n`;
206
+ }
207
+ else {
208
+ const parts = [];
209
+ if (blockingDiff > 0) {
210
+ parts.push(`🔺 **${blockingDiff} new blocking issue${blockingDiff === 1 ? '' : 's'}**`);
211
+ }
212
+ else if (blockingDiff < 0) {
213
+ parts.push(`🔻 **${Math.abs(blockingDiff)} blocking issue${Math.abs(blockingDiff) === 1 ? '' : 's'} resolved**`);
214
+ }
215
+ if (diff > 0 && diff !== blockingDiff) {
216
+ parts.push(`${diff - blockingDiff} new non-blocking issue${diff - blockingDiff === 1 ? '' : 's'}`);
217
+ }
218
+ else if (diff < 0 && diff !== blockingDiff) {
219
+ parts.push(`${Math.abs(diff - blockingDiff)} non-blocking issue${Math.abs(diff - blockingDiff) === 1 ? '' : 's'} resolved`);
220
+ }
221
+ md += parts.join(' • ') + '\n\n';
222
+ }
223
+ return md;
224
+ }
225
+ /**
226
+ * Format scan metadata
227
+ */
228
+ function formatScanMetadata(result, scanDepth) {
229
+ let md = `<details>\n<summary>📋 Scan Details</summary>\n\n`;
230
+ md += `| Metric | Value |\n`;
231
+ md += `|--------|-------|\n`;
232
+ md += `| Files scanned | ${result.filesScanned} |\n`;
233
+ md += `| Files skipped | ${result.filesSkipped} |\n`;
234
+ md += `| Scan duration | ${(result.scanDuration / 1000).toFixed(1)}s |\n`;
235
+ if (scanDepth) {
236
+ const depthLabels = {
237
+ cheap: 'Fast (pattern matching)',
238
+ validated: 'Validated (AI-assisted)',
239
+ deep: 'Deep (full semantic)',
240
+ };
241
+ md += `| Scan depth | ${depthLabels[scanDepth] || scanDepth} |\n`;
242
+ }
243
+ md += `| Timestamp | ${result.timestamp} |\n`;
244
+ md += `\n</details>\n\n`;
245
+ return md;
246
+ }
247
+ /**
248
+ * Format quick actions section
249
+ */
250
+ function formatQuickActions(hasBlockingIssues) {
251
+ let md = `## 🎯 Quick Actions\n\n`;
252
+ if (hasBlockingIssues) {
253
+ md += `- [ ] Fix all blocking issues before merging\n`;
254
+ md += `- [ ] Review medium/low severity findings\n`;
255
+ }
256
+ else {
257
+ md += `- [ ] Review findings and address as needed\n`;
258
+ }
259
+ md += `- [ ] Mark false positives with \`// oculum-ignore\` comment\n`;
260
+ md += `- 📖 [View documentation](https://oculum.dev/docs)\n`;
261
+ md += `- 🐛 [Report false positive](https://github.com/oculum-security/oculum/issues/new?template=false-positive.md)\n\n`;
262
+ return md;
263
+ }
264
+ /**
265
+ * Format footer
266
+ */
267
+ function formatFooter() {
268
+ let md = `---\n\n`;
269
+ md += `<div align="center">\n\n`;
270
+ md += `🛡️ Powered by [Oculum Security Scanner](https://oculum.dev) • `;
271
+ md += `[Documentation](https://oculum.dev/docs) • `;
272
+ md += `[Get Pro](https://oculum.dev/pricing)\n\n`;
273
+ md += `</div>\n`;
274
+ return md;
275
+ }
276
+ /**
277
+ * Format scan result as a short status comment (for check run summary)
278
+ */
279
+ function formatShortStatus(result) {
280
+ const { severityCounts, hasBlockingIssues, filesScanned, scanDuration } = result;
281
+ if (hasBlockingIssues) {
282
+ const blocking = severityCounts.critical + severityCounts.high;
283
+ return `🚨 Found ${blocking} blocking security issue${blocking === 1 ? '' : 's'} (${severityCounts.critical} critical, ${severityCounts.high} high)`;
284
+ }
285
+ const total = Object.values(severityCounts).reduce((a, b) => a + b, 0);
286
+ if (total > 0) {
287
+ return `⚠️ Found ${total} issue${total === 1 ? '' : 's'} (${severityCounts.medium} medium, ${severityCounts.low} low, ${severityCounts.info} info)`;
288
+ }
289
+ return `✅ No security issues found (scanned ${filesScanned} files in ${(scanDuration / 1000).toFixed(1)}s)`;
290
+ }
291
+ /**
292
+ * Format as inline annotation for GitHub check run
293
+ */
294
+ function formatAnnotation(finding) {
295
+ const level = finding.severity === 'critical' || finding.severity === 'high' ? 'failure' :
296
+ finding.severity === 'medium' ? 'warning' : 'notice';
297
+ return {
298
+ path: finding.filePath,
299
+ start_line: finding.lineNumber,
300
+ end_line: finding.lineNumber,
301
+ annotation_level: level,
302
+ title: `${SEVERITY_BADGE[finding.severity]} ${finding.title}`,
303
+ message: finding.description + (finding.suggestedFix ? `\n\n💡 Fix: ${finding.suggestedFix}` : ''),
304
+ };
305
+ }
306
+ //# sourceMappingURL=github-comment.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"github-comment.js","sourceRoot":"","sources":["../../src/formatters/github-comment.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,52 @@
1
+ /**
2
+ * Finding Grouping Logic
3
+ * Groups and sorts vulnerabilities for workflow-friendly output
4
+ */
5
+ import type { Vulnerability, VulnerabilitySeverity, VulnerabilityCategory } from '../types';
6
+ /**
7
+ * Risk themes for grouping findings
8
+ */
9
+ export type RiskTheme = 'secrets' | 'injection' | 'auth' | 'ai' | 'config' | 'data' | 'other';
10
+ /**
11
+ * Map categories to risk themes
12
+ */
13
+ export declare function getRiskTheme(category: VulnerabilityCategory): RiskTheme;
14
+ /**
15
+ * Theme display names and icons
16
+ */
17
+ export declare const THEME_CONFIG: Record<RiskTheme, {
18
+ name: string;
19
+ icon: string;
20
+ priority: number;
21
+ }>;
22
+ /**
23
+ * Grouped findings by risk theme
24
+ */
25
+ export interface GroupedFindings {
26
+ theme: RiskTheme;
27
+ themeName: string;
28
+ themeIcon: string;
29
+ findings: Vulnerability[];
30
+ severityCounts: Record<VulnerabilitySeverity, number>;
31
+ }
32
+ /**
33
+ * Group vulnerabilities by risk theme
34
+ */
35
+ export declare function groupByTheme(vulnerabilities: Vulnerability[]): GroupedFindings[];
36
+ /**
37
+ * Limit findings per group to avoid overwhelming output
38
+ */
39
+ export declare function limitPerGroup(groups: GroupedFindings[], maxPerGroup?: number): GroupedFindings[];
40
+ /**
41
+ * Get findings sorted by severity across all groups
42
+ */
43
+ export declare function sortBySeverity(vulnerabilities: Vulnerability[]): Vulnerability[];
44
+ /**
45
+ * Filter to only blocking issues (critical/high)
46
+ */
47
+ export declare function getBlockingIssues(vulnerabilities: Vulnerability[]): Vulnerability[];
48
+ /**
49
+ * Filter to actionable issues (medium and above)
50
+ */
51
+ export declare function getActionableIssues(vulnerabilities: Vulnerability[]): Vulnerability[];
52
+ //# sourceMappingURL=grouping.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grouping.d.ts","sourceRoot":"","sources":["../../src/formatters/grouping.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAEH,OAAO,KAAK,EAAE,aAAa,EAAE,qBAAqB,EAAE,qBAAqB,EAAE,MAAM,UAAU,CAAA;AAE3F;;GAEG;AACH,MAAM,MAAM,SAAS,GACjB,SAAS,GACT,WAAW,GACX,MAAM,GACN,IAAI,GACJ,QAAQ,GACR,MAAM,GACN,OAAO,CAAA;AAEX;;GAEG;AACH,wBAAgB,YAAY,CAAC,QAAQ,EAAE,qBAAqB,GAAG,SAAS,CAqCvE;AAED;;GAEG;AACH,eAAO,MAAM,YAAY,EAAE,MAAM,CAAC,SAAS,EAAE;IAAE,IAAI,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,CAQ5F,CAAA;AAaD;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B,KAAK,EAAE,SAAS,CAAA;IAChB,SAAS,EAAE,MAAM,CAAA;IACjB,SAAS,EAAE,MAAM,CAAA;IACjB,QAAQ,EAAE,aAAa,EAAE,CAAA;IACzB,cAAc,EAAE,MAAM,CAAC,qBAAqB,EAAE,MAAM,CAAC,CAAA;CACtD;AAED;;GAEG;AACH,wBAAgB,YAAY,CAAC,eAAe,EAAE,aAAa,EAAE,GAAG,eAAe,EAAE,CAmDhF;AAED;;GAEG;AACH,wBAAgB,aAAa,CAAC,MAAM,EAAE,eAAe,EAAE,EAAE,WAAW,GAAE,MAAW,GAAG,eAAe,EAAE,CAKpG;AAED;;GAEG;AACH,wBAAgB,cAAc,CAAC,eAAe,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CAQhF;AAED;;GAEG;AACH,wBAAgB,iBAAiB,CAAC,eAAe,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CAEnF;AAED;;GAEG;AACH,wBAAgB,mBAAmB,CAAC,eAAe,EAAE,aAAa,EAAE,GAAG,aAAa,EAAE,CAIrF"}
@@ -0,0 +1,152 @@
1
+ "use strict";
2
+ /**
3
+ * Finding Grouping Logic
4
+ * Groups and sorts vulnerabilities for workflow-friendly output
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.THEME_CONFIG = void 0;
8
+ exports.getRiskTheme = getRiskTheme;
9
+ exports.groupByTheme = groupByTheme;
10
+ exports.limitPerGroup = limitPerGroup;
11
+ exports.sortBySeverity = sortBySeverity;
12
+ exports.getBlockingIssues = getBlockingIssues;
13
+ exports.getActionableIssues = getActionableIssues;
14
+ /**
15
+ * Map categories to risk themes
16
+ */
17
+ function getRiskTheme(category) {
18
+ switch (category) {
19
+ case 'hardcoded_secret':
20
+ case 'high_entropy_string':
21
+ case 'sensitive_url':
22
+ return 'secrets';
23
+ case 'sql_injection':
24
+ case 'xss':
25
+ case 'command_injection':
26
+ case 'dangerous_function':
27
+ return 'injection';
28
+ case 'missing_auth':
29
+ case 'security_bypass':
30
+ return 'auth';
31
+ case 'ai_pattern':
32
+ case 'ai_prompt_injection':
33
+ case 'ai_unsafe_execution':
34
+ case 'ai_overpermissive_tool':
35
+ return 'ai';
36
+ case 'insecure_config':
37
+ case 'cors_misconfiguration':
38
+ case 'root_container':
39
+ case 'dangerous_file':
40
+ case 'weak_crypto':
41
+ return 'config';
42
+ case 'data_exposure':
43
+ case 'sensitive_variable':
44
+ return 'data';
45
+ default:
46
+ return 'other';
47
+ }
48
+ }
49
+ /**
50
+ * Theme display names and icons
51
+ */
52
+ exports.THEME_CONFIG = {
53
+ secrets: { name: 'Secrets & Credentials', icon: '🔑', priority: 1 },
54
+ injection: { name: 'Injection Vulnerabilities', icon: '💉', priority: 2 },
55
+ auth: { name: 'Authentication Issues', icon: '🔒', priority: 3 },
56
+ ai: { name: 'AI Security', icon: '🤖', priority: 4 },
57
+ config: { name: 'Configuration Issues', icon: '⚙️', priority: 5 },
58
+ data: { name: 'Data Exposure', icon: '📊', priority: 6 },
59
+ other: { name: 'Other Issues', icon: '⚠️', priority: 7 },
60
+ };
61
+ /**
62
+ * Severity sort order (higher = more severe)
63
+ */
64
+ const SEVERITY_ORDER = {
65
+ critical: 5,
66
+ high: 4,
67
+ medium: 3,
68
+ low: 2,
69
+ info: 1,
70
+ };
71
+ /**
72
+ * Group vulnerabilities by risk theme
73
+ */
74
+ function groupByTheme(vulnerabilities) {
75
+ // Group by theme
76
+ const groups = new Map();
77
+ for (const vuln of vulnerabilities) {
78
+ const theme = getRiskTheme(vuln.category);
79
+ if (!groups.has(theme)) {
80
+ groups.set(theme, []);
81
+ }
82
+ groups.get(theme).push(vuln);
83
+ }
84
+ // Convert to array and sort
85
+ const result = [];
86
+ for (const [theme, findings] of groups) {
87
+ // Sort findings within group: severity desc, then confidence desc
88
+ findings.sort((a, b) => {
89
+ const severityDiff = SEVERITY_ORDER[b.severity] - SEVERITY_ORDER[a.severity];
90
+ if (severityDiff !== 0)
91
+ return severityDiff;
92
+ const confidenceOrder = { high: 3, medium: 2, low: 1 };
93
+ return confidenceOrder[b.confidence] - confidenceOrder[a.confidence];
94
+ });
95
+ // Count severities
96
+ const severityCounts = {
97
+ critical: 0,
98
+ high: 0,
99
+ medium: 0,
100
+ low: 0,
101
+ info: 0,
102
+ };
103
+ for (const f of findings) {
104
+ severityCounts[f.severity]++;
105
+ }
106
+ const config = exports.THEME_CONFIG[theme];
107
+ result.push({
108
+ theme,
109
+ themeName: config.name,
110
+ themeIcon: config.icon,
111
+ findings,
112
+ severityCounts,
113
+ });
114
+ }
115
+ // Sort groups by theme priority
116
+ result.sort((a, b) => exports.THEME_CONFIG[a.theme].priority - exports.THEME_CONFIG[b.theme].priority);
117
+ return result;
118
+ }
119
+ /**
120
+ * Limit findings per group to avoid overwhelming output
121
+ */
122
+ function limitPerGroup(groups, maxPerGroup = 10) {
123
+ return groups.map(group => ({
124
+ ...group,
125
+ findings: group.findings.slice(0, maxPerGroup),
126
+ }));
127
+ }
128
+ /**
129
+ * Get findings sorted by severity across all groups
130
+ */
131
+ function sortBySeverity(vulnerabilities) {
132
+ return [...vulnerabilities].sort((a, b) => {
133
+ const severityDiff = SEVERITY_ORDER[b.severity] - SEVERITY_ORDER[a.severity];
134
+ if (severityDiff !== 0)
135
+ return severityDiff;
136
+ const confidenceOrder = { high: 3, medium: 2, low: 1 };
137
+ return confidenceOrder[b.confidence] - confidenceOrder[a.confidence];
138
+ });
139
+ }
140
+ /**
141
+ * Filter to only blocking issues (critical/high)
142
+ */
143
+ function getBlockingIssues(vulnerabilities) {
144
+ return vulnerabilities.filter(v => v.severity === 'critical' || v.severity === 'high');
145
+ }
146
+ /**
147
+ * Filter to actionable issues (medium and above)
148
+ */
149
+ function getActionableIssues(vulnerabilities) {
150
+ return vulnerabilities.filter(v => v.severity === 'critical' || v.severity === 'high' || v.severity === 'medium');
151
+ }
152
+ //# sourceMappingURL=grouping.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"grouping.js","sourceRoot":"","sources":["../../src/formatters/grouping.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Output Formatters
3
+ * Export all formatting utilities for different workflows
4
+ */
5
+ export { groupByTheme, limitPerGroup, sortBySeverity, getBlockingIssues, getActionableIssues, getRiskTheme, THEME_CONFIG, type RiskTheme, type GroupedFindings, } from './grouping';
6
+ export { formatGitHubComment, formatShortStatus, formatAnnotation, type GitHubCommentOptions, } from './github-comment';
7
+ export { formatDiagnostic, formatDiagnosticsByFile, generateCodeAction, formatForProblemsPanel, DiagnosticSeverity, type Diagnostic, type DiagnosticsByFile, type CodeAction, type Position, type Range, } from './vscode-diagnostic';
8
+ export { formatTerminalOutput, formatSimpleList, formatJSON, formatSARIF, } from './cli-terminal';
9
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/formatters/index.ts"],"names":[],"mappings":"AAAA;;;GAGG;AAGH,OAAO,EACL,YAAY,EACZ,aAAa,EACb,cAAc,EACd,iBAAiB,EACjB,mBAAmB,EACnB,YAAY,EACZ,YAAY,EACZ,KAAK,SAAS,EACd,KAAK,eAAe,GACrB,MAAM,YAAY,CAAA;AAGnB,OAAO,EACL,mBAAmB,EACnB,iBAAiB,EACjB,gBAAgB,EAChB,KAAK,oBAAoB,GAC1B,MAAM,kBAAkB,CAAA;AAGzB,OAAO,EACL,gBAAgB,EAChB,uBAAuB,EACvB,kBAAkB,EAClB,sBAAsB,EACtB,kBAAkB,EAClB,KAAK,UAAU,EACf,KAAK,iBAAiB,EACtB,KAAK,UAAU,EACf,KAAK,QAAQ,EACb,KAAK,KAAK,GACX,MAAM,qBAAqB,CAAA;AAG5B,OAAO,EACL,oBAAoB,EACpB,gBAAgB,EAChB,UAAU,EACV,WAAW,GACZ,MAAM,gBAAgB,CAAA"}
@@ -0,0 +1,35 @@
1
+ "use strict";
2
+ /**
3
+ * Output Formatters
4
+ * Export all formatting utilities for different workflows
5
+ */
6
+ Object.defineProperty(exports, "__esModule", { value: true });
7
+ exports.formatSARIF = exports.formatJSON = exports.formatSimpleList = exports.formatTerminalOutput = exports.DiagnosticSeverity = exports.formatForProblemsPanel = exports.generateCodeAction = exports.formatDiagnosticsByFile = exports.formatDiagnostic = exports.formatAnnotation = exports.formatShortStatus = exports.formatGitHubComment = exports.THEME_CONFIG = exports.getRiskTheme = exports.getActionableIssues = exports.getBlockingIssues = exports.sortBySeverity = exports.limitPerGroup = exports.groupByTheme = void 0;
8
+ // Grouping utilities
9
+ var grouping_1 = require("./grouping");
10
+ Object.defineProperty(exports, "groupByTheme", { enumerable: true, get: function () { return grouping_1.groupByTheme; } });
11
+ Object.defineProperty(exports, "limitPerGroup", { enumerable: true, get: function () { return grouping_1.limitPerGroup; } });
12
+ Object.defineProperty(exports, "sortBySeverity", { enumerable: true, get: function () { return grouping_1.sortBySeverity; } });
13
+ Object.defineProperty(exports, "getBlockingIssues", { enumerable: true, get: function () { return grouping_1.getBlockingIssues; } });
14
+ Object.defineProperty(exports, "getActionableIssues", { enumerable: true, get: function () { return grouping_1.getActionableIssues; } });
15
+ Object.defineProperty(exports, "getRiskTheme", { enumerable: true, get: function () { return grouping_1.getRiskTheme; } });
16
+ Object.defineProperty(exports, "THEME_CONFIG", { enumerable: true, get: function () { return grouping_1.THEME_CONFIG; } });
17
+ // GitHub comment formatter
18
+ var github_comment_1 = require("./github-comment");
19
+ Object.defineProperty(exports, "formatGitHubComment", { enumerable: true, get: function () { return github_comment_1.formatGitHubComment; } });
20
+ Object.defineProperty(exports, "formatShortStatus", { enumerable: true, get: function () { return github_comment_1.formatShortStatus; } });
21
+ Object.defineProperty(exports, "formatAnnotation", { enumerable: true, get: function () { return github_comment_1.formatAnnotation; } });
22
+ // VS Code diagnostic formatter
23
+ var vscode_diagnostic_1 = require("./vscode-diagnostic");
24
+ Object.defineProperty(exports, "formatDiagnostic", { enumerable: true, get: function () { return vscode_diagnostic_1.formatDiagnostic; } });
25
+ Object.defineProperty(exports, "formatDiagnosticsByFile", { enumerable: true, get: function () { return vscode_diagnostic_1.formatDiagnosticsByFile; } });
26
+ Object.defineProperty(exports, "generateCodeAction", { enumerable: true, get: function () { return vscode_diagnostic_1.generateCodeAction; } });
27
+ Object.defineProperty(exports, "formatForProblemsPanel", { enumerable: true, get: function () { return vscode_diagnostic_1.formatForProblemsPanel; } });
28
+ Object.defineProperty(exports, "DiagnosticSeverity", { enumerable: true, get: function () { return vscode_diagnostic_1.DiagnosticSeverity; } });
29
+ // CLI terminal formatter
30
+ var cli_terminal_1 = require("./cli-terminal");
31
+ Object.defineProperty(exports, "formatTerminalOutput", { enumerable: true, get: function () { return cli_terminal_1.formatTerminalOutput; } });
32
+ Object.defineProperty(exports, "formatSimpleList", { enumerable: true, get: function () { return cli_terminal_1.formatSimpleList; } });
33
+ Object.defineProperty(exports, "formatJSON", { enumerable: true, get: function () { return cli_terminal_1.formatJSON; } });
34
+ Object.defineProperty(exports, "formatSARIF", { enumerable: true, get: function () { return cli_terminal_1.formatSARIF; } });
35
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/formatters/index.ts"],"names":[],"mappings":";AAAA;;;GAGG;;;AAEH,qBAAqB;AACrB,uCAUmB;AATjB,wGAAA,YAAY,OAAA;AACZ,yGAAA,aAAa,OAAA;AACb,0GAAA,cAAc,OAAA;AACd,6GAAA,iBAAiB,OAAA;AACjB,+GAAA,mBAAmB,OAAA;AACnB,wGAAA,YAAY,OAAA;AACZ,wGAAA,YAAY,OAAA;AAKd,2BAA2B;AAC3B,mDAKyB;AAJvB,qHAAA,mBAAmB,OAAA;AACnB,mHAAA,iBAAiB,OAAA;AACjB,kHAAA,gBAAgB,OAAA;AAIlB,+BAA+B;AAC/B,yDAW4B;AAV1B,qHAAA,gBAAgB,OAAA;AAChB,4HAAA,uBAAuB,OAAA;AACvB,uHAAA,kBAAkB,OAAA;AAClB,2HAAA,sBAAsB,OAAA;AACtB,uHAAA,kBAAkB,OAAA;AAQpB,yBAAyB;AACzB,+CAKuB;AAJrB,oHAAA,oBAAoB,OAAA;AACpB,gHAAA,gBAAgB,OAAA;AAChB,0GAAA,UAAU,OAAA;AACV,2GAAA,WAAW,OAAA"}