@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.
- package/dist/formatters/cli-terminal.d.ts +27 -0
- package/dist/formatters/cli-terminal.d.ts.map +1 -0
- package/dist/formatters/cli-terminal.js +412 -0
- package/dist/formatters/cli-terminal.js.map +1 -0
- package/dist/formatters/github-comment.d.ts +41 -0
- package/dist/formatters/github-comment.d.ts.map +1 -0
- package/dist/formatters/github-comment.js +306 -0
- package/dist/formatters/github-comment.js.map +1 -0
- package/dist/formatters/grouping.d.ts +52 -0
- package/dist/formatters/grouping.d.ts.map +1 -0
- package/dist/formatters/grouping.js +152 -0
- package/dist/formatters/grouping.js.map +1 -0
- package/dist/formatters/index.d.ts +9 -0
- package/dist/formatters/index.d.ts.map +1 -0
- package/dist/formatters/index.js +35 -0
- package/dist/formatters/index.js.map +1 -0
- package/dist/formatters/vscode-diagnostic.d.ts +103 -0
- package/dist/formatters/vscode-diagnostic.d.ts.map +1 -0
- package/dist/formatters/vscode-diagnostic.js +151 -0
- package/dist/formatters/vscode-diagnostic.js.map +1 -0
- package/dist/index.d.ts +52 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +648 -0
- package/dist/index.js.map +1 -0
- package/dist/layer1/comments.d.ts +8 -0
- package/dist/layer1/comments.d.ts.map +1 -0
- package/dist/layer1/comments.js +203 -0
- package/dist/layer1/comments.js.map +1 -0
- package/dist/layer1/config-audit.d.ts +8 -0
- package/dist/layer1/config-audit.d.ts.map +1 -0
- package/dist/layer1/config-audit.js +252 -0
- package/dist/layer1/config-audit.js.map +1 -0
- package/dist/layer1/entropy.d.ts +8 -0
- package/dist/layer1/entropy.d.ts.map +1 -0
- package/dist/layer1/entropy.js +500 -0
- package/dist/layer1/entropy.js.map +1 -0
- package/dist/layer1/file-flags.d.ts +7 -0
- package/dist/layer1/file-flags.d.ts.map +1 -0
- package/dist/layer1/file-flags.js +112 -0
- package/dist/layer1/file-flags.js.map +1 -0
- package/dist/layer1/index.d.ts +36 -0
- package/dist/layer1/index.d.ts.map +1 -0
- package/dist/layer1/index.js +132 -0
- package/dist/layer1/index.js.map +1 -0
- package/dist/layer1/patterns.d.ts +8 -0
- package/dist/layer1/patterns.d.ts.map +1 -0
- package/dist/layer1/patterns.js +482 -0
- package/dist/layer1/patterns.js.map +1 -0
- package/dist/layer1/urls.d.ts +8 -0
- package/dist/layer1/urls.d.ts.map +1 -0
- package/dist/layer1/urls.js +296 -0
- package/dist/layer1/urls.js.map +1 -0
- package/dist/layer1/weak-crypto.d.ts +7 -0
- package/dist/layer1/weak-crypto.d.ts.map +1 -0
- package/dist/layer1/weak-crypto.js +291 -0
- package/dist/layer1/weak-crypto.js.map +1 -0
- package/dist/layer2/ai-agent-tools.d.ts +19 -0
- package/dist/layer2/ai-agent-tools.d.ts.map +1 -0
- package/dist/layer2/ai-agent-tools.js +528 -0
- package/dist/layer2/ai-agent-tools.js.map +1 -0
- package/dist/layer2/ai-endpoint-protection.d.ts +36 -0
- package/dist/layer2/ai-endpoint-protection.d.ts.map +1 -0
- package/dist/layer2/ai-endpoint-protection.js +332 -0
- package/dist/layer2/ai-endpoint-protection.js.map +1 -0
- package/dist/layer2/ai-execution-sinks.d.ts +18 -0
- package/dist/layer2/ai-execution-sinks.d.ts.map +1 -0
- package/dist/layer2/ai-execution-sinks.js +496 -0
- package/dist/layer2/ai-execution-sinks.js.map +1 -0
- package/dist/layer2/ai-fingerprinting.d.ts +7 -0
- package/dist/layer2/ai-fingerprinting.d.ts.map +1 -0
- package/dist/layer2/ai-fingerprinting.js +654 -0
- package/dist/layer2/ai-fingerprinting.js.map +1 -0
- package/dist/layer2/ai-prompt-hygiene.d.ts +19 -0
- package/dist/layer2/ai-prompt-hygiene.d.ts.map +1 -0
- package/dist/layer2/ai-prompt-hygiene.js +356 -0
- package/dist/layer2/ai-prompt-hygiene.js.map +1 -0
- package/dist/layer2/ai-rag-safety.d.ts +21 -0
- package/dist/layer2/ai-rag-safety.d.ts.map +1 -0
- package/dist/layer2/ai-rag-safety.js +459 -0
- package/dist/layer2/ai-rag-safety.js.map +1 -0
- package/dist/layer2/ai-schema-validation.d.ts +25 -0
- package/dist/layer2/ai-schema-validation.d.ts.map +1 -0
- package/dist/layer2/ai-schema-validation.js +375 -0
- package/dist/layer2/ai-schema-validation.js.map +1 -0
- package/dist/layer2/auth-antipatterns.d.ts +20 -0
- package/dist/layer2/auth-antipatterns.d.ts.map +1 -0
- package/dist/layer2/auth-antipatterns.js +333 -0
- package/dist/layer2/auth-antipatterns.js.map +1 -0
- package/dist/layer2/byok-patterns.d.ts +12 -0
- package/dist/layer2/byok-patterns.d.ts.map +1 -0
- package/dist/layer2/byok-patterns.js +299 -0
- package/dist/layer2/byok-patterns.js.map +1 -0
- package/dist/layer2/dangerous-functions.d.ts +7 -0
- package/dist/layer2/dangerous-functions.d.ts.map +1 -0
- package/dist/layer2/dangerous-functions.js +1375 -0
- package/dist/layer2/dangerous-functions.js.map +1 -0
- package/dist/layer2/data-exposure.d.ts +16 -0
- package/dist/layer2/data-exposure.d.ts.map +1 -0
- package/dist/layer2/data-exposure.js +279 -0
- package/dist/layer2/data-exposure.js.map +1 -0
- package/dist/layer2/framework-checks.d.ts +7 -0
- package/dist/layer2/framework-checks.d.ts.map +1 -0
- package/dist/layer2/framework-checks.js +388 -0
- package/dist/layer2/framework-checks.js.map +1 -0
- package/dist/layer2/index.d.ts +58 -0
- package/dist/layer2/index.d.ts.map +1 -0
- package/dist/layer2/index.js +380 -0
- package/dist/layer2/index.js.map +1 -0
- package/dist/layer2/logic-gates.d.ts +7 -0
- package/dist/layer2/logic-gates.d.ts.map +1 -0
- package/dist/layer2/logic-gates.js +182 -0
- package/dist/layer2/logic-gates.js.map +1 -0
- package/dist/layer2/risky-imports.d.ts +7 -0
- package/dist/layer2/risky-imports.d.ts.map +1 -0
- package/dist/layer2/risky-imports.js +161 -0
- package/dist/layer2/risky-imports.js.map +1 -0
- package/dist/layer2/variables.d.ts +8 -0
- package/dist/layer2/variables.d.ts.map +1 -0
- package/dist/layer2/variables.js +152 -0
- package/dist/layer2/variables.js.map +1 -0
- package/dist/layer3/anthropic.d.ts +83 -0
- package/dist/layer3/anthropic.d.ts.map +1 -0
- package/dist/layer3/anthropic.js +1745 -0
- package/dist/layer3/anthropic.js.map +1 -0
- package/dist/layer3/index.d.ts +24 -0
- package/dist/layer3/index.d.ts.map +1 -0
- package/dist/layer3/index.js +119 -0
- package/dist/layer3/index.js.map +1 -0
- package/dist/layer3/openai.d.ts +25 -0
- package/dist/layer3/openai.d.ts.map +1 -0
- package/dist/layer3/openai.js +238 -0
- package/dist/layer3/openai.js.map +1 -0
- package/dist/layer3/package-check.d.ts +63 -0
- package/dist/layer3/package-check.d.ts.map +1 -0
- package/dist/layer3/package-check.js +508 -0
- package/dist/layer3/package-check.js.map +1 -0
- package/dist/modes/incremental.d.ts +66 -0
- package/dist/modes/incremental.d.ts.map +1 -0
- package/dist/modes/incremental.js +200 -0
- package/dist/modes/incremental.js.map +1 -0
- package/dist/tiers.d.ts +125 -0
- package/dist/tiers.d.ts.map +1 -0
- package/dist/tiers.js +234 -0
- package/dist/tiers.js.map +1 -0
- package/dist/types.d.ts +175 -0
- package/dist/types.d.ts.map +1 -0
- package/dist/types.js +50 -0
- package/dist/types.js.map +1 -0
- package/dist/utils/auth-helper-detector.d.ts +56 -0
- package/dist/utils/auth-helper-detector.d.ts.map +1 -0
- package/dist/utils/auth-helper-detector.js +360 -0
- package/dist/utils/auth-helper-detector.js.map +1 -0
- package/dist/utils/context-helpers.d.ts +96 -0
- package/dist/utils/context-helpers.d.ts.map +1 -0
- package/dist/utils/context-helpers.js +493 -0
- package/dist/utils/context-helpers.js.map +1 -0
- package/dist/utils/diff-detector.d.ts +53 -0
- package/dist/utils/diff-detector.d.ts.map +1 -0
- package/dist/utils/diff-detector.js +104 -0
- package/dist/utils/diff-detector.js.map +1 -0
- package/dist/utils/diff-parser.d.ts +80 -0
- package/dist/utils/diff-parser.d.ts.map +1 -0
- package/dist/utils/diff-parser.js +202 -0
- package/dist/utils/diff-parser.js.map +1 -0
- package/dist/utils/imported-auth-detector.d.ts +37 -0
- package/dist/utils/imported-auth-detector.d.ts.map +1 -0
- package/dist/utils/imported-auth-detector.js +251 -0
- package/dist/utils/imported-auth-detector.js.map +1 -0
- package/dist/utils/middleware-detector.d.ts +55 -0
- package/dist/utils/middleware-detector.d.ts.map +1 -0
- package/dist/utils/middleware-detector.js +260 -0
- package/dist/utils/middleware-detector.js.map +1 -0
- package/dist/utils/oauth-flow-detector.d.ts +41 -0
- package/dist/utils/oauth-flow-detector.d.ts.map +1 -0
- package/dist/utils/oauth-flow-detector.js +202 -0
- package/dist/utils/oauth-flow-detector.js.map +1 -0
- package/dist/utils/path-exclusions.d.ts +55 -0
- package/dist/utils/path-exclusions.d.ts.map +1 -0
- package/dist/utils/path-exclusions.js +222 -0
- package/dist/utils/path-exclusions.js.map +1 -0
- package/dist/utils/project-context-builder.d.ts +119 -0
- package/dist/utils/project-context-builder.d.ts.map +1 -0
- package/dist/utils/project-context-builder.js +534 -0
- package/dist/utils/project-context-builder.js.map +1 -0
- package/dist/utils/registry-clients.d.ts +93 -0
- package/dist/utils/registry-clients.d.ts.map +1 -0
- package/dist/utils/registry-clients.js +273 -0
- package/dist/utils/registry-clients.js.map +1 -0
- package/dist/utils/trpc-analyzer.d.ts +78 -0
- package/dist/utils/trpc-analyzer.d.ts.map +1 -0
- package/dist/utils/trpc-analyzer.js +297 -0
- package/dist/utils/trpc-analyzer.js.map +1 -0
- package/package.json +45 -0
- package/src/__tests__/benchmark/fixtures/false-positives.ts +227 -0
- package/src/__tests__/benchmark/fixtures/index.ts +68 -0
- package/src/__tests__/benchmark/fixtures/layer1/config-audit.ts +364 -0
- package/src/__tests__/benchmark/fixtures/layer1/hardcoded-secrets.ts +173 -0
- package/src/__tests__/benchmark/fixtures/layer1/high-entropy.ts +234 -0
- package/src/__tests__/benchmark/fixtures/layer1/index.ts +31 -0
- package/src/__tests__/benchmark/fixtures/layer1/sensitive-urls.ts +90 -0
- package/src/__tests__/benchmark/fixtures/layer1/weak-crypto.ts +197 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-agent-tools.ts +170 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-endpoint-protection.ts +418 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-execution-sinks.ts +189 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-fingerprinting.ts +316 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-prompt-hygiene.ts +178 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-rag-safety.ts +184 -0
- package/src/__tests__/benchmark/fixtures/layer2/ai-schema-validation.ts +434 -0
- package/src/__tests__/benchmark/fixtures/layer2/auth-antipatterns.ts +159 -0
- package/src/__tests__/benchmark/fixtures/layer2/byok-patterns.ts +112 -0
- package/src/__tests__/benchmark/fixtures/layer2/dangerous-functions.ts +246 -0
- package/src/__tests__/benchmark/fixtures/layer2/data-exposure.ts +168 -0
- package/src/__tests__/benchmark/fixtures/layer2/framework-checks.ts +346 -0
- package/src/__tests__/benchmark/fixtures/layer2/index.ts +67 -0
- package/src/__tests__/benchmark/fixtures/layer2/injection-vulnerabilities.ts +239 -0
- package/src/__tests__/benchmark/fixtures/layer2/logic-gates.ts +246 -0
- package/src/__tests__/benchmark/fixtures/layer2/risky-imports.ts +231 -0
- package/src/__tests__/benchmark/fixtures/layer2/variables.ts +167 -0
- package/src/__tests__/benchmark/index.ts +29 -0
- package/src/__tests__/benchmark/run-benchmark.ts +144 -0
- package/src/__tests__/benchmark/run-depth-validation.ts +206 -0
- package/src/__tests__/benchmark/run-real-world-test.ts +243 -0
- package/src/__tests__/benchmark/security-benchmark-script.ts +1737 -0
- package/src/__tests__/benchmark/tier-integration-script.ts +177 -0
- package/src/__tests__/benchmark/types.ts +144 -0
- package/src/__tests__/benchmark/utils/test-runner.ts +475 -0
- package/src/__tests__/regression/known-false-positives.test.ts +467 -0
- package/src/__tests__/snapshots/__snapshots__/scan-depth.test.ts.snap +178 -0
- package/src/__tests__/snapshots/scan-depth.test.ts +258 -0
- package/src/__tests__/validation/analyze-results.ts +542 -0
- package/src/__tests__/validation/extract-for-triage.ts +146 -0
- package/src/__tests__/validation/fp-deep-analysis.ts +327 -0
- package/src/__tests__/validation/run-validation.ts +364 -0
- package/src/__tests__/validation/triage-template.md +132 -0
- package/src/formatters/cli-terminal.ts +446 -0
- package/src/formatters/github-comment.ts +382 -0
- package/src/formatters/grouping.ts +190 -0
- package/src/formatters/index.ts +47 -0
- package/src/formatters/vscode-diagnostic.ts +243 -0
- package/src/index.ts +823 -0
- package/src/layer1/comments.ts +218 -0
- package/src/layer1/config-audit.ts +289 -0
- package/src/layer1/entropy.ts +583 -0
- package/src/layer1/file-flags.ts +127 -0
- package/src/layer1/index.ts +181 -0
- package/src/layer1/patterns.ts +516 -0
- package/src/layer1/urls.ts +334 -0
- package/src/layer1/weak-crypto.ts +328 -0
- package/src/layer2/ai-agent-tools.ts +601 -0
- package/src/layer2/ai-endpoint-protection.ts +387 -0
- package/src/layer2/ai-execution-sinks.ts +580 -0
- package/src/layer2/ai-fingerprinting.ts +758 -0
- package/src/layer2/ai-prompt-hygiene.ts +411 -0
- package/src/layer2/ai-rag-safety.ts +511 -0
- package/src/layer2/ai-schema-validation.ts +421 -0
- package/src/layer2/auth-antipatterns.ts +394 -0
- package/src/layer2/byok-patterns.ts +336 -0
- package/src/layer2/dangerous-functions.ts +1563 -0
- package/src/layer2/data-exposure.ts +315 -0
- package/src/layer2/framework-checks.ts +433 -0
- package/src/layer2/index.ts +473 -0
- package/src/layer2/logic-gates.ts +206 -0
- package/src/layer2/risky-imports.ts +186 -0
- package/src/layer2/variables.ts +166 -0
- package/src/layer3/anthropic.ts +2030 -0
- package/src/layer3/index.ts +130 -0
- package/src/layer3/package-check.ts +604 -0
- package/src/modes/incremental.ts +293 -0
- package/src/tiers.ts +318 -0
- package/src/types.ts +284 -0
- package/src/utils/auth-helper-detector.ts +443 -0
- package/src/utils/context-helpers.ts +535 -0
- package/src/utils/diff-detector.ts +135 -0
- package/src/utils/diff-parser.ts +272 -0
- package/src/utils/imported-auth-detector.ts +320 -0
- package/src/utils/middleware-detector.ts +333 -0
- package/src/utils/oauth-flow-detector.ts +246 -0
- package/src/utils/path-exclusions.ts +266 -0
- package/src/utils/project-context-builder.ts +707 -0
- package/src/utils/registry-clients.ts +351 -0
- package/src/utils/trpc-analyzer.ts +382 -0
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* VS Code Diagnostic Formatter
|
|
3
|
+
* Formats scan results as LSP diagnostic format for VS Code integration
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
import type { Vulnerability, VulnerabilitySeverity } from '../types'
|
|
7
|
+
|
|
8
|
+
/**
|
|
9
|
+
* LSP Diagnostic Severity
|
|
10
|
+
* https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnosticSeverity
|
|
11
|
+
*/
|
|
12
|
+
export enum DiagnosticSeverity {
|
|
13
|
+
Error = 1,
|
|
14
|
+
Warning = 2,
|
|
15
|
+
Information = 3,
|
|
16
|
+
Hint = 4,
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
/**
|
|
20
|
+
* LSP Position (0-indexed)
|
|
21
|
+
*/
|
|
22
|
+
export interface Position {
|
|
23
|
+
line: number
|
|
24
|
+
character: number
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
/**
|
|
28
|
+
* LSP Range
|
|
29
|
+
*/
|
|
30
|
+
export interface Range {
|
|
31
|
+
start: Position
|
|
32
|
+
end: Position
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* LSP Diagnostic
|
|
37
|
+
* https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#diagnostic
|
|
38
|
+
*/
|
|
39
|
+
export interface Diagnostic {
|
|
40
|
+
range: Range
|
|
41
|
+
severity: DiagnosticSeverity
|
|
42
|
+
code?: string | number
|
|
43
|
+
source: string
|
|
44
|
+
message: string
|
|
45
|
+
relatedInformation?: DiagnosticRelatedInformation[]
|
|
46
|
+
tags?: DiagnosticTag[]
|
|
47
|
+
data?: unknown
|
|
48
|
+
}
|
|
49
|
+
|
|
50
|
+
/**
|
|
51
|
+
* LSP Diagnostic Related Information
|
|
52
|
+
*/
|
|
53
|
+
export interface DiagnosticRelatedInformation {
|
|
54
|
+
location: {
|
|
55
|
+
uri: string
|
|
56
|
+
range: Range
|
|
57
|
+
}
|
|
58
|
+
message: string
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* LSP Diagnostic Tag
|
|
63
|
+
*/
|
|
64
|
+
export enum DiagnosticTag {
|
|
65
|
+
Unnecessary = 1,
|
|
66
|
+
Deprecated = 2,
|
|
67
|
+
}
|
|
68
|
+
|
|
69
|
+
/**
|
|
70
|
+
* Map vulnerability severity to LSP diagnostic severity
|
|
71
|
+
*/
|
|
72
|
+
function mapSeverity(severity: VulnerabilitySeverity): DiagnosticSeverity {
|
|
73
|
+
switch (severity) {
|
|
74
|
+
case 'critical':
|
|
75
|
+
case 'high':
|
|
76
|
+
return DiagnosticSeverity.Error
|
|
77
|
+
case 'medium':
|
|
78
|
+
return DiagnosticSeverity.Warning
|
|
79
|
+
case 'low':
|
|
80
|
+
return DiagnosticSeverity.Information
|
|
81
|
+
case 'info':
|
|
82
|
+
return DiagnosticSeverity.Hint
|
|
83
|
+
default:
|
|
84
|
+
return DiagnosticSeverity.Information
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* Create range for a finding (line-based, full line)
|
|
90
|
+
*/
|
|
91
|
+
function createRange(lineNumber: number, lineContent?: string): Range {
|
|
92
|
+
const line = lineNumber - 1 // LSP is 0-indexed
|
|
93
|
+
const endChar = lineContent ? lineContent.length : 1000
|
|
94
|
+
|
|
95
|
+
return {
|
|
96
|
+
start: { line, character: 0 },
|
|
97
|
+
end: { line, character: endChar },
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
/**
|
|
102
|
+
* Format vulnerability as LSP diagnostic
|
|
103
|
+
*/
|
|
104
|
+
export function formatDiagnostic(finding: Vulnerability, fileUri?: string): Diagnostic {
|
|
105
|
+
const severity = mapSeverity(finding.severity)
|
|
106
|
+
const severityLabel = finding.severity.toUpperCase()
|
|
107
|
+
|
|
108
|
+
// Build message with fix suggestion
|
|
109
|
+
let message = `[${severityLabel}] ${finding.title}\n\n${finding.description}`
|
|
110
|
+
if (finding.suggestedFix) {
|
|
111
|
+
message += `\n\n💡 Fix: ${finding.suggestedFix}`
|
|
112
|
+
}
|
|
113
|
+
|
|
114
|
+
const diagnostic: Diagnostic = {
|
|
115
|
+
range: createRange(finding.lineNumber, finding.lineContent),
|
|
116
|
+
severity,
|
|
117
|
+
code: finding.category,
|
|
118
|
+
source: 'oculum',
|
|
119
|
+
message,
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
// Add validation notes if available
|
|
123
|
+
if (finding.validationNotes) {
|
|
124
|
+
diagnostic.relatedInformation = [{
|
|
125
|
+
location: {
|
|
126
|
+
uri: fileUri || `file://${finding.filePath}`,
|
|
127
|
+
range: createRange(finding.lineNumber),
|
|
128
|
+
},
|
|
129
|
+
message: `AI Validation: ${finding.validationNotes}`,
|
|
130
|
+
}]
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
return diagnostic
|
|
134
|
+
}
|
|
135
|
+
|
|
136
|
+
/**
|
|
137
|
+
* Group diagnostics by file URI
|
|
138
|
+
*/
|
|
139
|
+
export interface DiagnosticsByFile {
|
|
140
|
+
uri: string
|
|
141
|
+
diagnostics: Diagnostic[]
|
|
142
|
+
}
|
|
143
|
+
|
|
144
|
+
/**
|
|
145
|
+
* Format vulnerabilities as diagnostics grouped by file
|
|
146
|
+
*/
|
|
147
|
+
export function formatDiagnosticsByFile(
|
|
148
|
+
vulnerabilities: Vulnerability[],
|
|
149
|
+
baseUri?: string
|
|
150
|
+
): DiagnosticsByFile[] {
|
|
151
|
+
const byFile = new Map<string, Diagnostic[]>()
|
|
152
|
+
|
|
153
|
+
for (const finding of vulnerabilities) {
|
|
154
|
+
const uri = baseUri
|
|
155
|
+
? `${baseUri}/${finding.filePath}`
|
|
156
|
+
: `file://${finding.filePath}`
|
|
157
|
+
|
|
158
|
+
if (!byFile.has(uri)) {
|
|
159
|
+
byFile.set(uri, [])
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
byFile.get(uri)!.push(formatDiagnostic(finding, uri))
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
// Sort diagnostics within each file by line number
|
|
166
|
+
const result: DiagnosticsByFile[] = []
|
|
167
|
+
for (const [uri, diagnostics] of byFile) {
|
|
168
|
+
diagnostics.sort((a, b) => a.range.start.line - b.range.start.line)
|
|
169
|
+
result.push({ uri, diagnostics })
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
// Sort files alphabetically
|
|
173
|
+
result.sort((a, b) => a.uri.localeCompare(b.uri))
|
|
174
|
+
|
|
175
|
+
return result
|
|
176
|
+
}
|
|
177
|
+
|
|
178
|
+
/**
|
|
179
|
+
* VS Code Code Action (quick fix) format
|
|
180
|
+
*/
|
|
181
|
+
export interface CodeAction {
|
|
182
|
+
title: string
|
|
183
|
+
kind: string
|
|
184
|
+
diagnostics: Diagnostic[]
|
|
185
|
+
edit?: {
|
|
186
|
+
changes: Record<string, TextEdit[]>
|
|
187
|
+
}
|
|
188
|
+
isPreferred?: boolean
|
|
189
|
+
}
|
|
190
|
+
|
|
191
|
+
/**
|
|
192
|
+
* Text Edit for Code Action
|
|
193
|
+
*/
|
|
194
|
+
export interface TextEdit {
|
|
195
|
+
range: Range
|
|
196
|
+
newText: string
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
/**
|
|
200
|
+
* Generate code action for a finding (if fix is available)
|
|
201
|
+
*/
|
|
202
|
+
export function generateCodeAction(
|
|
203
|
+
finding: Vulnerability,
|
|
204
|
+
fileUri: string
|
|
205
|
+
): CodeAction | null {
|
|
206
|
+
if (!finding.suggestedFix) return null
|
|
207
|
+
|
|
208
|
+
// For now, just provide a "learn more" action
|
|
209
|
+
// In the future, we could generate actual code fixes
|
|
210
|
+
return {
|
|
211
|
+
title: `💡 Fix: ${finding.suggestedFix.slice(0, 50)}${finding.suggestedFix.length > 50 ? '...' : ''}`,
|
|
212
|
+
kind: 'quickfix',
|
|
213
|
+
diagnostics: [formatDiagnostic(finding, fileUri)],
|
|
214
|
+
isPreferred: true,
|
|
215
|
+
}
|
|
216
|
+
}
|
|
217
|
+
|
|
218
|
+
/**
|
|
219
|
+
* Format for VS Code Problems panel (simplified text format)
|
|
220
|
+
*/
|
|
221
|
+
export function formatForProblemsPanel(vulnerabilities: Vulnerability[]): string {
|
|
222
|
+
const byFile = new Map<string, Vulnerability[]>()
|
|
223
|
+
|
|
224
|
+
for (const finding of vulnerabilities) {
|
|
225
|
+
if (!byFile.has(finding.filePath)) {
|
|
226
|
+
byFile.set(finding.filePath, [])
|
|
227
|
+
}
|
|
228
|
+
byFile.get(finding.filePath)!.push(finding)
|
|
229
|
+
}
|
|
230
|
+
|
|
231
|
+
let output = ''
|
|
232
|
+
|
|
233
|
+
for (const [filePath, findings] of byFile) {
|
|
234
|
+
output += `\n${filePath}\n`
|
|
235
|
+
for (const finding of findings) {
|
|
236
|
+
const icon = finding.severity === 'critical' || finding.severity === 'high' ? '❌' :
|
|
237
|
+
finding.severity === 'medium' ? '⚠️' : 'ℹ️'
|
|
238
|
+
output += ` ${icon} Line ${finding.lineNumber}: ${finding.title}\n`
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
|
|
242
|
+
return output.trim()
|
|
243
|
+
}
|