@quantracode/vibecheck 0.0.1 → 0.0.2
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/README.md +6 -6
- package/dist/index.d.ts +0 -2
- package/dist/index.js +7902 -8
- package/package.json +13 -7
- package/dist/__tests__/cli.test.d.ts +0 -2
- package/dist/__tests__/cli.test.d.ts.map +0 -1
- package/dist/__tests__/cli.test.js +0 -243
- package/dist/__tests__/fixtures/safe-app/app/api/users/route.js +0 -36
- package/dist/__tests__/fixtures/vulnerable-app/app/api/users/route.js +0 -28
- package/dist/__tests__/fixtures/vulnerable-app/lib/config.d.ts +0 -4
- package/dist/__tests__/fixtures/vulnerable-app/lib/config.d.ts.map +0 -1
- package/dist/__tests__/fixtures/vulnerable-app/lib/config.js +0 -6
- package/dist/__tests__/scanners/env-config.test.d.ts +0 -2
- package/dist/__tests__/scanners/env-config.test.d.ts.map +0 -1
- package/dist/__tests__/scanners/env-config.test.js +0 -142
- package/dist/__tests__/scanners/nextjs-middleware.test.d.ts +0 -2
- package/dist/__tests__/scanners/nextjs-middleware.test.d.ts.map +0 -1
- package/dist/__tests__/scanners/nextjs-middleware.test.js +0 -193
- package/dist/__tests__/scanners/scanner-packs.test.d.ts +0 -2
- package/dist/__tests__/scanners/scanner-packs.test.d.ts.map +0 -1
- package/dist/__tests__/scanners/scanner-packs.test.js +0 -126
- package/dist/__tests__/scanners/unused-security-imports.test.d.ts +0 -2
- package/dist/__tests__/scanners/unused-security-imports.test.d.ts.map +0 -1
- package/dist/__tests__/scanners/unused-security-imports.test.js +0 -145
- package/dist/commands/demo-artifact.d.ts +0 -7
- package/dist/commands/demo-artifact.d.ts.map +0 -1
- package/dist/commands/demo-artifact.js +0 -322
- package/dist/commands/evaluate.d.ts +0 -30
- package/dist/commands/evaluate.d.ts.map +0 -1
- package/dist/commands/evaluate.js +0 -258
- package/dist/commands/explain.d.ts +0 -12
- package/dist/commands/explain.d.ts.map +0 -1
- package/dist/commands/explain.js +0 -214
- package/dist/commands/index.d.ts +0 -7
- package/dist/commands/index.d.ts.map +0 -1
- package/dist/commands/index.js +0 -6
- package/dist/commands/intent.d.ts +0 -21
- package/dist/commands/intent.d.ts.map +0 -1
- package/dist/commands/intent.js +0 -192
- package/dist/commands/scan.d.ts +0 -44
- package/dist/commands/scan.d.ts.map +0 -1
- package/dist/commands/scan.js +0 -497
- package/dist/commands/waivers.d.ts +0 -30
- package/dist/commands/waivers.d.ts.map +0 -1
- package/dist/commands/waivers.js +0 -249
- package/dist/index.d.ts.map +0 -1
- package/dist/phase3/index.d.ts +0 -11
- package/dist/phase3/index.d.ts.map +0 -1
- package/dist/phase3/index.js +0 -12
- package/dist/phase3/intent-miner.d.ts +0 -32
- package/dist/phase3/intent-miner.d.ts.map +0 -1
- package/dist/phase3/intent-miner.js +0 -323
- package/dist/phase3/proof-trace-builder.d.ts +0 -42
- package/dist/phase3/proof-trace-builder.d.ts.map +0 -1
- package/dist/phase3/proof-trace-builder.js +0 -441
- package/dist/phase3/scanners/auth-by-ui-server-gap.d.ts +0 -15
- package/dist/phase3/scanners/auth-by-ui-server-gap.d.ts.map +0 -1
- package/dist/phase3/scanners/auth-by-ui-server-gap.js +0 -237
- package/dist/phase3/scanners/comment-claim-unproven.d.ts +0 -14
- package/dist/phase3/scanners/comment-claim-unproven.d.ts.map +0 -1
- package/dist/phase3/scanners/comment-claim-unproven.js +0 -161
- package/dist/phase3/scanners/index.d.ts +0 -31
- package/dist/phase3/scanners/index.d.ts.map +0 -1
- package/dist/phase3/scanners/index.js +0 -40
- package/dist/phase3/scanners/middleware-assumed-not-matching.d.ts +0 -14
- package/dist/phase3/scanners/middleware-assumed-not-matching.d.ts.map +0 -1
- package/dist/phase3/scanners/middleware-assumed-not-matching.js +0 -172
- package/dist/phase3/scanners/validation-claimed-missing.d.ts +0 -15
- package/dist/phase3/scanners/validation-claimed-missing.d.ts.map +0 -1
- package/dist/phase3/scanners/validation-claimed-missing.js +0 -204
- package/dist/scanners/abuse/compute-abuse.d.ts +0 -20
- package/dist/scanners/abuse/compute-abuse.d.ts.map +0 -1
- package/dist/scanners/abuse/compute-abuse.js +0 -509
- package/dist/scanners/abuse/index.d.ts +0 -12
- package/dist/scanners/abuse/index.d.ts.map +0 -1
- package/dist/scanners/abuse/index.js +0 -15
- package/dist/scanners/auth/index.d.ts +0 -5
- package/dist/scanners/auth/index.d.ts.map +0 -1
- package/dist/scanners/auth/index.js +0 -10
- package/dist/scanners/auth/middleware-gap.d.ts +0 -22
- package/dist/scanners/auth/middleware-gap.d.ts.map +0 -1
- package/dist/scanners/auth/middleware-gap.js +0 -203
- package/dist/scanners/auth/unprotected-api-route.d.ts +0 -12
- package/dist/scanners/auth/unprotected-api-route.d.ts.map +0 -1
- package/dist/scanners/auth/unprotected-api-route.js +0 -126
- package/dist/scanners/config/index.d.ts +0 -5
- package/dist/scanners/config/index.d.ts.map +0 -1
- package/dist/scanners/config/index.js +0 -10
- package/dist/scanners/config/insecure-defaults.d.ts +0 -12
- package/dist/scanners/config/insecure-defaults.d.ts.map +0 -1
- package/dist/scanners/config/insecure-defaults.js +0 -77
- package/dist/scanners/config/undocumented-env.d.ts +0 -24
- package/dist/scanners/config/undocumented-env.d.ts.map +0 -1
- package/dist/scanners/config/undocumented-env.js +0 -159
- package/dist/scanners/crypto/index.d.ts +0 -6
- package/dist/scanners/crypto/index.d.ts.map +0 -1
- package/dist/scanners/crypto/index.js +0 -11
- package/dist/scanners/crypto/jwt-decode-unverified.d.ts +0 -14
- package/dist/scanners/crypto/jwt-decode-unverified.d.ts.map +0 -1
- package/dist/scanners/crypto/jwt-decode-unverified.js +0 -87
- package/dist/scanners/crypto/math-random-tokens.d.ts +0 -13
- package/dist/scanners/crypto/math-random-tokens.d.ts.map +0 -1
- package/dist/scanners/crypto/math-random-tokens.js +0 -80
- package/dist/scanners/crypto/weak-hashing.d.ts +0 -11
- package/dist/scanners/crypto/weak-hashing.d.ts.map +0 -1
- package/dist/scanners/crypto/weak-hashing.js +0 -95
- package/dist/scanners/env-config.d.ts +0 -24
- package/dist/scanners/env-config.d.ts.map +0 -1
- package/dist/scanners/env-config.js +0 -164
- package/dist/scanners/hallucinations/index.d.ts +0 -4
- package/dist/scanners/hallucinations/index.d.ts.map +0 -1
- package/dist/scanners/hallucinations/index.js +0 -8
- package/dist/scanners/hallucinations/unused-security-imports.d.ts +0 -36
- package/dist/scanners/hallucinations/unused-security-imports.d.ts.map +0 -1
- package/dist/scanners/hallucinations/unused-security-imports.js +0 -309
- package/dist/scanners/helpers/ast-helpers.d.ts +0 -6
- package/dist/scanners/helpers/ast-helpers.d.ts.map +0 -1
- package/dist/scanners/helpers/ast-helpers.js +0 -945
- package/dist/scanners/helpers/context-builder.d.ts +0 -17
- package/dist/scanners/helpers/context-builder.d.ts.map +0 -1
- package/dist/scanners/helpers/context-builder.js +0 -148
- package/dist/scanners/helpers/index.d.ts +0 -3
- package/dist/scanners/helpers/index.d.ts.map +0 -1
- package/dist/scanners/helpers/index.js +0 -2
- package/dist/scanners/index.d.ts +0 -30
- package/dist/scanners/index.d.ts.map +0 -1
- package/dist/scanners/index.js +0 -102
- package/dist/scanners/middleware/index.d.ts +0 -4
- package/dist/scanners/middleware/index.d.ts.map +0 -1
- package/dist/scanners/middleware/index.js +0 -7
- package/dist/scanners/middleware/missing-rate-limit.d.ts +0 -13
- package/dist/scanners/middleware/missing-rate-limit.d.ts.map +0 -1
- package/dist/scanners/middleware/missing-rate-limit.js +0 -140
- package/dist/scanners/network/cors-misconfiguration.d.ts +0 -14
- package/dist/scanners/network/cors-misconfiguration.d.ts.map +0 -1
- package/dist/scanners/network/cors-misconfiguration.js +0 -89
- package/dist/scanners/network/index.d.ts +0 -7
- package/dist/scanners/network/index.d.ts.map +0 -1
- package/dist/scanners/network/index.js +0 -18
- package/dist/scanners/network/missing-timeout.d.ts +0 -15
- package/dist/scanners/network/missing-timeout.d.ts.map +0 -1
- package/dist/scanners/network/missing-timeout.js +0 -93
- package/dist/scanners/network/open-redirect.d.ts +0 -15
- package/dist/scanners/network/open-redirect.d.ts.map +0 -1
- package/dist/scanners/network/open-redirect.js +0 -88
- package/dist/scanners/network/ssrf-prone-fetch.d.ts +0 -12
- package/dist/scanners/network/ssrf-prone-fetch.d.ts.map +0 -1
- package/dist/scanners/network/ssrf-prone-fetch.js +0 -90
- package/dist/scanners/nextjs-middleware.d.ts +0 -26
- package/dist/scanners/nextjs-middleware.d.ts.map +0 -1
- package/dist/scanners/nextjs-middleware.js +0 -246
- package/dist/scanners/privacy/debug-flags.d.ts +0 -13
- package/dist/scanners/privacy/debug-flags.d.ts.map +0 -1
- package/dist/scanners/privacy/debug-flags.js +0 -124
- package/dist/scanners/privacy/index.d.ts +0 -6
- package/dist/scanners/privacy/index.d.ts.map +0 -1
- package/dist/scanners/privacy/index.js +0 -11
- package/dist/scanners/privacy/over-broad-response.d.ts +0 -15
- package/dist/scanners/privacy/over-broad-response.d.ts.map +0 -1
- package/dist/scanners/privacy/over-broad-response.js +0 -109
- package/dist/scanners/privacy/sensitive-logging.d.ts +0 -11
- package/dist/scanners/privacy/sensitive-logging.d.ts.map +0 -1
- package/dist/scanners/privacy/sensitive-logging.js +0 -78
- package/dist/scanners/types.d.ts +0 -456
- package/dist/scanners/types.d.ts.map +0 -1
- package/dist/scanners/types.js +0 -16
- package/dist/scanners/unused-security-imports.d.ts +0 -34
- package/dist/scanners/unused-security-imports.d.ts.map +0 -1
- package/dist/scanners/unused-security-imports.js +0 -206
- package/dist/scanners/uploads/index.d.ts +0 -5
- package/dist/scanners/uploads/index.d.ts.map +0 -1
- package/dist/scanners/uploads/index.js +0 -9
- package/dist/scanners/uploads/missing-constraints.d.ts +0 -15
- package/dist/scanners/uploads/missing-constraints.d.ts.map +0 -1
- package/dist/scanners/uploads/missing-constraints.js +0 -109
- package/dist/scanners/uploads/public-path.d.ts +0 -11
- package/dist/scanners/uploads/public-path.d.ts.map +0 -1
- package/dist/scanners/uploads/public-path.js +0 -87
- package/dist/scanners/validation/client-side-only.d.ts +0 -14
- package/dist/scanners/validation/client-side-only.d.ts.map +0 -1
- package/dist/scanners/validation/client-side-only.js +0 -140
- package/dist/scanners/validation/ignored-validation.d.ts +0 -12
- package/dist/scanners/validation/ignored-validation.d.ts.map +0 -1
- package/dist/scanners/validation/ignored-validation.js +0 -119
- package/dist/scanners/validation/index.d.ts +0 -5
- package/dist/scanners/validation/index.d.ts.map +0 -1
- package/dist/scanners/validation/index.js +0 -9
- package/dist/utils/exclude-patterns.d.ts +0 -35
- package/dist/utils/exclude-patterns.d.ts.map +0 -1
- package/dist/utils/exclude-patterns.js +0 -78
- package/dist/utils/file-utils.d.ts +0 -37
- package/dist/utils/file-utils.d.ts.map +0 -1
- package/dist/utils/file-utils.js +0 -77
- package/dist/utils/fingerprint.d.ts +0 -25
- package/dist/utils/fingerprint.d.ts.map +0 -1
- package/dist/utils/fingerprint.js +0 -28
- package/dist/utils/git-info.d.ts +0 -14
- package/dist/utils/git-info.d.ts.map +0 -1
- package/dist/utils/git-info.js +0 -55
- package/dist/utils/index.d.ts +0 -4
- package/dist/utils/index.d.ts.map +0 -1
- package/dist/utils/index.js +0 -3
- package/dist/utils/progress.d.ts +0 -42
- package/dist/utils/progress.d.ts.map +0 -1
- package/dist/utils/progress.js +0 -165
- package/dist/utils/sarif-formatter.d.ts +0 -92
- package/dist/utils/sarif-formatter.d.ts.map +0 -1
- package/dist/utils/sarif-formatter.js +0 -172
package/dist/utils/progress.js
DELETED
|
@@ -1,165 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Terminal progress display - clean, minimal design
|
|
3
|
-
*/
|
|
4
|
-
import path from "node:path";
|
|
5
|
-
const ANSI = {
|
|
6
|
-
reset: "\x1b[0m",
|
|
7
|
-
bold: "\x1b[1m",
|
|
8
|
-
dim: "\x1b[2m",
|
|
9
|
-
red: "\x1b[31m",
|
|
10
|
-
green: "\x1b[32m",
|
|
11
|
-
yellow: "\x1b[33m",
|
|
12
|
-
cyan: "\x1b[36m",
|
|
13
|
-
clearLine: "\x1b[2K",
|
|
14
|
-
};
|
|
15
|
-
// Progress bar characters
|
|
16
|
-
const BAR_FILLED = "█";
|
|
17
|
-
const BAR_EMPTY = "░";
|
|
18
|
-
function createProgressBar(current, total, width = 20) {
|
|
19
|
-
const percent = total > 0 ? Math.min(current / total, 1) : 0;
|
|
20
|
-
const filled = Math.min(Math.round(percent * width), width);
|
|
21
|
-
const empty = Math.max(width - filled, 0);
|
|
22
|
-
return (`${ANSI.cyan}${BAR_FILLED.repeat(filled)}${ANSI.reset}` +
|
|
23
|
-
`${ANSI.dim}${BAR_EMPTY.repeat(empty)}${ANSI.reset}`);
|
|
24
|
-
}
|
|
25
|
-
function truncateEnd(str, maxLen) {
|
|
26
|
-
if (str.length <= maxLen)
|
|
27
|
-
return str.padEnd(maxLen);
|
|
28
|
-
return str.slice(0, maxLen - 2) + "..";
|
|
29
|
-
}
|
|
30
|
-
export class ScanProgress {
|
|
31
|
-
packs;
|
|
32
|
-
results = new Map();
|
|
33
|
-
startTime = 0;
|
|
34
|
-
currentPack = -1;
|
|
35
|
-
totalFiles = 0;
|
|
36
|
-
currentFile = "";
|
|
37
|
-
filesProcessed = 0;
|
|
38
|
-
constructor(packs, totalFiles = 0) {
|
|
39
|
-
this.packs = packs;
|
|
40
|
-
this.totalFiles = totalFiles;
|
|
41
|
-
}
|
|
42
|
-
start() {
|
|
43
|
-
this.startTime = Date.now();
|
|
44
|
-
const width = 88;
|
|
45
|
-
const filesStr = `${this.totalFiles} files`;
|
|
46
|
-
const packsStr = `${this.packs.length} packs`;
|
|
47
|
-
const padding = width - 14 - filesStr.length - packsStr.length;
|
|
48
|
-
console.log("");
|
|
49
|
-
console.log(`${ANSI.cyan} ${"─".repeat(width)}${ANSI.reset}`);
|
|
50
|
-
console.log(`${ANSI.cyan} ${ANSI.reset} ${ANSI.bold}SCANNING${ANSI.reset} ${ANSI.dim}${filesStr}${ANSI.reset}${" ".repeat(Math.max(padding, 2))}${ANSI.dim}${packsStr}${ANSI.reset}`);
|
|
51
|
-
console.log(`${ANSI.cyan} ${"─".repeat(width)}${ANSI.reset}`);
|
|
52
|
-
console.log("");
|
|
53
|
-
}
|
|
54
|
-
startPack(packIndex) {
|
|
55
|
-
this.currentPack = packIndex;
|
|
56
|
-
this.results.set(packIndex, { findingsCount: 0, scannersRun: 0 });
|
|
57
|
-
this.renderPackProgress();
|
|
58
|
-
}
|
|
59
|
-
startScanner(packIndex, _scannerIndex) {
|
|
60
|
-
this.renderPackProgress();
|
|
61
|
-
}
|
|
62
|
-
/** Called when a file is processed */
|
|
63
|
-
onFileProgress(file, processed, _total) {
|
|
64
|
-
this.currentFile = file;
|
|
65
|
-
this.filesProcessed = processed;
|
|
66
|
-
this.renderPackProgress();
|
|
67
|
-
}
|
|
68
|
-
completeScanner(packIndex, findingsFound) {
|
|
69
|
-
const result = this.results.get(packIndex);
|
|
70
|
-
if (result) {
|
|
71
|
-
result.findingsCount += findingsFound;
|
|
72
|
-
result.scannersRun++;
|
|
73
|
-
}
|
|
74
|
-
this.renderPackProgress();
|
|
75
|
-
}
|
|
76
|
-
renderPackProgress() {
|
|
77
|
-
const pack = this.packs[this.currentPack];
|
|
78
|
-
const result = this.results.get(this.currentPack);
|
|
79
|
-
// Pack number on the left
|
|
80
|
-
const packNum = `[${String(this.currentPack + 1).padStart(2)}/${this.packs.length}]`;
|
|
81
|
-
// Calculate progress based on files processed
|
|
82
|
-
const filePercent = this.totalFiles > 0
|
|
83
|
-
? Math.min(Math.round((this.filesProcessed / this.totalFiles) * 100), 100)
|
|
84
|
-
: 0;
|
|
85
|
-
// Progress bar
|
|
86
|
-
const progressBar = createProgressBar(this.filesProcessed, this.totalFiles, 20);
|
|
87
|
-
// Current file or status
|
|
88
|
-
const fileName = this.currentFile ? path.basename(this.currentFile) : "";
|
|
89
|
-
const truncatedFile = truncateEnd(fileName, 28);
|
|
90
|
-
const statusText = `${ANSI.dim}${truncatedFile}${ANSI.reset} ${ANSI.cyan}${String(filePercent).padStart(3)}%${ANSI.reset}`;
|
|
91
|
-
// Pack name (fixed width)
|
|
92
|
-
const packName = truncateEnd(pack.name, 32);
|
|
93
|
-
// Clear line and write progress
|
|
94
|
-
process.stdout.write(`\r${ANSI.clearLine}`);
|
|
95
|
-
process.stdout.write(` ${ANSI.cyan}●${ANSI.reset} ${ANSI.dim}${packNum}${ANSI.reset} ${packName} ${progressBar} ${statusText}`);
|
|
96
|
-
}
|
|
97
|
-
completePack(packIndex) {
|
|
98
|
-
const result = this.results.get(packIndex);
|
|
99
|
-
const findings = result?.findingsCount ?? 0;
|
|
100
|
-
const pack = this.packs[packIndex];
|
|
101
|
-
// Pack number on the left
|
|
102
|
-
const packNum = `[${String(packIndex + 1).padStart(2)}/${this.packs.length}]`;
|
|
103
|
-
// Show full progress bar on completion
|
|
104
|
-
const progressBar = createProgressBar(1, 1, 20);
|
|
105
|
-
// Pack name (fixed width)
|
|
106
|
-
const packName = truncateEnd(pack.name, 32);
|
|
107
|
-
// Status text
|
|
108
|
-
const statusIcon = findings > 0 ? `${ANSI.yellow}●${ANSI.reset}` : `${ANSI.green}●${ANSI.reset}`;
|
|
109
|
-
const statusText = findings > 0
|
|
110
|
-
? `${ANSI.yellow}${String(findings).padStart(3)} found${ANSI.reset}`
|
|
111
|
-
: `${ANSI.green} clean${ANSI.reset}`;
|
|
112
|
-
// Clear line and write final result
|
|
113
|
-
process.stdout.write(`\r${ANSI.clearLine}`);
|
|
114
|
-
console.log(` ${statusIcon} ${ANSI.dim}${packNum}${ANSI.reset} ${packName} ${progressBar} ${statusText}`);
|
|
115
|
-
}
|
|
116
|
-
stop() {
|
|
117
|
-
const elapsed = ((Date.now() - this.startTime) / 1000).toFixed(1);
|
|
118
|
-
const totalFindings = Array.from(this.results.values()).reduce((sum, r) => sum + r.findingsCount, 0);
|
|
119
|
-
const width = 88;
|
|
120
|
-
const statusIcon = totalFindings > 0 ? `${ANSI.yellow}!${ANSI.reset}` : `${ANSI.green}✓${ANSI.reset}`;
|
|
121
|
-
const findingsText = totalFindings > 0
|
|
122
|
-
? `${ANSI.yellow}${ANSI.bold}${totalFindings} finding${totalFindings > 1 ? "s" : ""}${ANSI.reset}`
|
|
123
|
-
: `${ANSI.green}${ANSI.bold}No findings${ANSI.reset}`;
|
|
124
|
-
const timeStr = `${elapsed}s`;
|
|
125
|
-
const mainContent = ` ${statusIcon} COMPLETE ${findingsText}`;
|
|
126
|
-
// Account for ANSI codes in length calculation
|
|
127
|
-
const visibleLen = totalFindings > 0
|
|
128
|
-
? 14 + totalFindings.toString().length + (totalFindings > 1 ? 8 : 7)
|
|
129
|
-
: 23;
|
|
130
|
-
const padding = width - visibleLen - timeStr.length - 2;
|
|
131
|
-
console.log("");
|
|
132
|
-
console.log(`${ANSI.cyan} ${"─".repeat(width)}${ANSI.reset}`);
|
|
133
|
-
console.log(`${ANSI.cyan} ${ANSI.reset}${mainContent}${" ".repeat(Math.max(padding, 2))}${ANSI.dim}${timeStr}${ANSI.reset}`);
|
|
134
|
-
console.log(`${ANSI.cyan} ${"─".repeat(width)}${ANSI.reset}`);
|
|
135
|
-
}
|
|
136
|
-
}
|
|
137
|
-
/**
|
|
138
|
-
* Simple spinner for single operations
|
|
139
|
-
*/
|
|
140
|
-
export class Spinner {
|
|
141
|
-
message;
|
|
142
|
-
startTime = 0;
|
|
143
|
-
constructor(message) {
|
|
144
|
-
this.message = message;
|
|
145
|
-
}
|
|
146
|
-
start() {
|
|
147
|
-
this.startTime = Date.now();
|
|
148
|
-
process.stdout.write(` ${ANSI.cyan}●${ANSI.reset} ${this.message}...`);
|
|
149
|
-
}
|
|
150
|
-
update(message) {
|
|
151
|
-
this.message = message;
|
|
152
|
-
}
|
|
153
|
-
succeed(message) {
|
|
154
|
-
const elapsed = ((Date.now() - this.startTime) / 1000).toFixed(1);
|
|
155
|
-
process.stdout.write(`\r${ANSI.clearLine}`);
|
|
156
|
-
console.log(` ${ANSI.green}●${ANSI.reset} ${message || this.message} ${ANSI.dim}(${elapsed}s)${ANSI.reset}`);
|
|
157
|
-
}
|
|
158
|
-
fail(message) {
|
|
159
|
-
process.stdout.write(`\r${ANSI.clearLine}`);
|
|
160
|
-
console.log(` ${ANSI.red}●${ANSI.reset} ${message || this.message}`);
|
|
161
|
-
}
|
|
162
|
-
stop() {
|
|
163
|
-
process.stdout.write(`\r${ANSI.clearLine}`);
|
|
164
|
-
}
|
|
165
|
-
}
|
|
@@ -1,92 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SARIF (Static Analysis Results Interchange Format) output formatter
|
|
3
|
-
*
|
|
4
|
-
* Converts VibeCheck findings to SARIF 2.1.0 format for integration
|
|
5
|
-
* with GitHub Code Scanning and other SARIF-compatible tools.
|
|
6
|
-
*/
|
|
7
|
-
import type { ScanArtifact } from "@vibecheck/schema";
|
|
8
|
-
/**
|
|
9
|
-
* SARIF 2.1.0 schema types
|
|
10
|
-
*/
|
|
11
|
-
interface SarifLog {
|
|
12
|
-
$schema: string;
|
|
13
|
-
version: string;
|
|
14
|
-
runs: SarifRun[];
|
|
15
|
-
}
|
|
16
|
-
interface SarifRun {
|
|
17
|
-
tool: SarifTool;
|
|
18
|
-
results: SarifResult[];
|
|
19
|
-
invocations?: SarifInvocation[];
|
|
20
|
-
}
|
|
21
|
-
interface SarifTool {
|
|
22
|
-
driver: SarifDriver;
|
|
23
|
-
}
|
|
24
|
-
interface SarifDriver {
|
|
25
|
-
name: string;
|
|
26
|
-
version: string;
|
|
27
|
-
informationUri?: string;
|
|
28
|
-
rules: SarifRule[];
|
|
29
|
-
}
|
|
30
|
-
interface SarifRule {
|
|
31
|
-
id: string;
|
|
32
|
-
name: string;
|
|
33
|
-
shortDescription: SarifMessage;
|
|
34
|
-
fullDescription?: SarifMessage;
|
|
35
|
-
defaultConfiguration: {
|
|
36
|
-
level: SarifLevel;
|
|
37
|
-
};
|
|
38
|
-
help?: SarifMessage;
|
|
39
|
-
properties?: {
|
|
40
|
-
tags?: string[];
|
|
41
|
-
security_severity?: string;
|
|
42
|
-
};
|
|
43
|
-
}
|
|
44
|
-
interface SarifResult {
|
|
45
|
-
ruleId: string;
|
|
46
|
-
ruleIndex: number;
|
|
47
|
-
level: SarifLevel;
|
|
48
|
-
message: SarifMessage;
|
|
49
|
-
locations: SarifLocation[];
|
|
50
|
-
fingerprints?: Record<string, string>;
|
|
51
|
-
properties?: {
|
|
52
|
-
confidence?: number;
|
|
53
|
-
category?: string;
|
|
54
|
-
};
|
|
55
|
-
}
|
|
56
|
-
interface SarifLocation {
|
|
57
|
-
physicalLocation: SarifPhysicalLocation;
|
|
58
|
-
}
|
|
59
|
-
interface SarifPhysicalLocation {
|
|
60
|
-
artifactLocation: SarifArtifactLocation;
|
|
61
|
-
region?: SarifRegion;
|
|
62
|
-
}
|
|
63
|
-
interface SarifArtifactLocation {
|
|
64
|
-
uri: string;
|
|
65
|
-
uriBaseId?: string;
|
|
66
|
-
}
|
|
67
|
-
interface SarifRegion {
|
|
68
|
-
startLine: number;
|
|
69
|
-
endLine?: number;
|
|
70
|
-
snippet?: {
|
|
71
|
-
text: string;
|
|
72
|
-
};
|
|
73
|
-
}
|
|
74
|
-
interface SarifMessage {
|
|
75
|
-
text: string;
|
|
76
|
-
}
|
|
77
|
-
interface SarifInvocation {
|
|
78
|
-
executionSuccessful: boolean;
|
|
79
|
-
startTimeUtc?: string;
|
|
80
|
-
endTimeUtc?: string;
|
|
81
|
-
}
|
|
82
|
-
type SarifLevel = "none" | "note" | "warning" | "error";
|
|
83
|
-
/**
|
|
84
|
-
* Convert VibeCheck scan artifact to SARIF format
|
|
85
|
-
*/
|
|
86
|
-
export declare function toSarif(artifact: ScanArtifact): SarifLog;
|
|
87
|
-
/**
|
|
88
|
-
* Convert SARIF log to JSON string
|
|
89
|
-
*/
|
|
90
|
-
export declare function sarifToJson(sarif: SarifLog, pretty?: boolean): string;
|
|
91
|
-
export {};
|
|
92
|
-
//# sourceMappingURL=sarif-formatter.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"sarif-formatter.d.ts","sourceRoot":"","sources":["../../src/utils/sarif-formatter.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAW,YAAY,EAAY,MAAM,mBAAmB,CAAC;AAGzE;;GAEG;AACH,UAAU,QAAQ;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,OAAO,EAAE,MAAM,CAAC;IAChB,IAAI,EAAE,QAAQ,EAAE,CAAC;CAClB;AAED,UAAU,QAAQ;IAChB,IAAI,EAAE,SAAS,CAAC;IAChB,OAAO,EAAE,WAAW,EAAE,CAAC;IACvB,WAAW,CAAC,EAAE,eAAe,EAAE,CAAC;CACjC;AAED,UAAU,SAAS;IACjB,MAAM,EAAE,WAAW,CAAC;CACrB;AAED,UAAU,WAAW;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,OAAO,EAAE,MAAM,CAAC;IAChB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,KAAK,EAAE,SAAS,EAAE,CAAC;CACpB;AAED,UAAU,SAAS;IACjB,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB,EAAE,YAAY,CAAC;IAC/B,eAAe,CAAC,EAAE,YAAY,CAAC;IAC/B,oBAAoB,EAAE;QACpB,KAAK,EAAE,UAAU,CAAC;KACnB,CAAC;IACF,IAAI,CAAC,EAAE,YAAY,CAAC;IACpB,UAAU,CAAC,EAAE;QACX,IAAI,CAAC,EAAE,MAAM,EAAE,CAAC;QAChB,iBAAiB,CAAC,EAAE,MAAM,CAAC;KAC5B,CAAC;CACH;AAED,UAAU,WAAW;IACnB,MAAM,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,KAAK,EAAE,UAAU,CAAC;IAClB,OAAO,EAAE,YAAY,CAAC;IACtB,SAAS,EAAE,aAAa,EAAE,CAAC;IAC3B,YAAY,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,UAAU,CAAC,EAAE;QACX,UAAU,CAAC,EAAE,MAAM,CAAC;QACpB,QAAQ,CAAC,EAAE,MAAM,CAAC;KACnB,CAAC;CACH;AAED,UAAU,aAAa;IACrB,gBAAgB,EAAE,qBAAqB,CAAC;CACzC;AAED,UAAU,qBAAqB;IAC7B,gBAAgB,EAAE,qBAAqB,CAAC;IACxC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,UAAU,qBAAqB;IAC7B,GAAG,EAAE,MAAM,CAAC;IACZ,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAED,UAAU,WAAW;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,OAAO,CAAC,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;KACd,CAAC;CACH;AAED,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;CACd;AAED,UAAU,eAAe;IACvB,mBAAmB,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;CACrB;AAED,KAAK,UAAU,GAAG,MAAM,GAAG,MAAM,GAAG,SAAS,GAAG,OAAO,CAAC;AA2IxD;;GAEG;AACH,wBAAgB,OAAO,CAAC,QAAQ,EAAE,YAAY,GAAG,QAAQ,CAmCxD;AAED;;GAEG;AACH,wBAAgB,WAAW,CAAC,KAAK,EAAE,QAAQ,EAAE,MAAM,UAAO,GAAG,MAAM,CAElE"}
|
|
@@ -1,172 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* SARIF (Static Analysis Results Interchange Format) output formatter
|
|
3
|
-
*
|
|
4
|
-
* Converts VibeCheck findings to SARIF 2.1.0 format for integration
|
|
5
|
-
* with GitHub Code Scanning and other SARIF-compatible tools.
|
|
6
|
-
*/
|
|
7
|
-
/**
|
|
8
|
-
* Map VibeCheck severity to SARIF level
|
|
9
|
-
*/
|
|
10
|
-
function severityToSarifLevel(severity) {
|
|
11
|
-
switch (severity) {
|
|
12
|
-
case "critical":
|
|
13
|
-
case "high":
|
|
14
|
-
return "error";
|
|
15
|
-
case "medium":
|
|
16
|
-
return "warning";
|
|
17
|
-
case "low":
|
|
18
|
-
case "info":
|
|
19
|
-
return "note";
|
|
20
|
-
default:
|
|
21
|
-
return "note";
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
/**
|
|
25
|
-
* Map VibeCheck severity to GitHub security severity score (0-10)
|
|
26
|
-
*/
|
|
27
|
-
function severityToSecurityScore(severity) {
|
|
28
|
-
switch (severity) {
|
|
29
|
-
case "critical":
|
|
30
|
-
return "9.0";
|
|
31
|
-
case "high":
|
|
32
|
-
return "7.5";
|
|
33
|
-
case "medium":
|
|
34
|
-
return "5.0";
|
|
35
|
-
case "low":
|
|
36
|
-
return "3.0";
|
|
37
|
-
case "info":
|
|
38
|
-
return "0.0";
|
|
39
|
-
default:
|
|
40
|
-
return "0.0";
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
/**
|
|
44
|
-
* Generate SARIF rule definitions from findings
|
|
45
|
-
*/
|
|
46
|
-
function generateRules(findings) {
|
|
47
|
-
const ruleMap = new Map();
|
|
48
|
-
// Get unique rules from findings
|
|
49
|
-
for (const finding of findings) {
|
|
50
|
-
if (!ruleMap.has(finding.ruleId)) {
|
|
51
|
-
ruleMap.set(finding.ruleId, finding);
|
|
52
|
-
}
|
|
53
|
-
}
|
|
54
|
-
return Array.from(ruleMap.entries()).map(([ruleId, finding]) => ({
|
|
55
|
-
id: ruleId,
|
|
56
|
-
name: ruleId.replace(/-/g, " "),
|
|
57
|
-
shortDescription: {
|
|
58
|
-
text: finding.title,
|
|
59
|
-
},
|
|
60
|
-
fullDescription: {
|
|
61
|
-
text: finding.description,
|
|
62
|
-
},
|
|
63
|
-
defaultConfiguration: {
|
|
64
|
-
level: severityToSarifLevel(finding.severity),
|
|
65
|
-
},
|
|
66
|
-
help: finding.remediation?.recommendedFix
|
|
67
|
-
? {
|
|
68
|
-
text: finding.remediation.recommendedFix,
|
|
69
|
-
}
|
|
70
|
-
: undefined,
|
|
71
|
-
properties: {
|
|
72
|
-
tags: [finding.category, "security"],
|
|
73
|
-
security_severity: severityToSecurityScore(finding.severity),
|
|
74
|
-
},
|
|
75
|
-
}));
|
|
76
|
-
}
|
|
77
|
-
/**
|
|
78
|
-
* Normalize file path for SARIF URI (use forward slashes)
|
|
79
|
-
*/
|
|
80
|
-
function normalizeUri(filePath) {
|
|
81
|
-
return filePath.replace(/\\/g, "/");
|
|
82
|
-
}
|
|
83
|
-
/**
|
|
84
|
-
* Convert a finding to SARIF result
|
|
85
|
-
*/
|
|
86
|
-
function findingToResult(finding, ruleIndex) {
|
|
87
|
-
const locations = finding.evidence.map((evidence) => ({
|
|
88
|
-
physicalLocation: {
|
|
89
|
-
artifactLocation: {
|
|
90
|
-
uri: normalizeUri(evidence.file),
|
|
91
|
-
uriBaseId: "%SRCROOT%",
|
|
92
|
-
},
|
|
93
|
-
region: {
|
|
94
|
-
startLine: evidence.startLine,
|
|
95
|
-
endLine: evidence.endLine,
|
|
96
|
-
snippet: evidence.snippet
|
|
97
|
-
? {
|
|
98
|
-
text: evidence.snippet,
|
|
99
|
-
}
|
|
100
|
-
: undefined,
|
|
101
|
-
},
|
|
102
|
-
},
|
|
103
|
-
}));
|
|
104
|
-
// If no evidence with file locations, use a default location
|
|
105
|
-
if (locations.length === 0) {
|
|
106
|
-
locations.push({
|
|
107
|
-
physicalLocation: {
|
|
108
|
-
artifactLocation: {
|
|
109
|
-
uri: "unknown",
|
|
110
|
-
uriBaseId: "%SRCROOT%",
|
|
111
|
-
},
|
|
112
|
-
},
|
|
113
|
-
});
|
|
114
|
-
}
|
|
115
|
-
return {
|
|
116
|
-
ruleId: finding.ruleId,
|
|
117
|
-
ruleIndex,
|
|
118
|
-
level: severityToSarifLevel(finding.severity),
|
|
119
|
-
message: {
|
|
120
|
-
text: `${finding.title}\n\n${finding.description}`,
|
|
121
|
-
},
|
|
122
|
-
locations,
|
|
123
|
-
fingerprints: {
|
|
124
|
-
vibecheck_v1: finding.fingerprint,
|
|
125
|
-
},
|
|
126
|
-
properties: {
|
|
127
|
-
confidence: finding.confidence,
|
|
128
|
-
category: finding.category,
|
|
129
|
-
},
|
|
130
|
-
};
|
|
131
|
-
}
|
|
132
|
-
/**
|
|
133
|
-
* Convert VibeCheck scan artifact to SARIF format
|
|
134
|
-
*/
|
|
135
|
-
export function toSarif(artifact) {
|
|
136
|
-
const rules = generateRules(artifact.findings);
|
|
137
|
-
const ruleIndexMap = new Map(rules.map((r, i) => [r.id, i]));
|
|
138
|
-
const results = artifact.findings.map((finding) => {
|
|
139
|
-
const ruleIndex = ruleIndexMap.get(finding.ruleId) ?? 0;
|
|
140
|
-
return findingToResult(finding, ruleIndex);
|
|
141
|
-
});
|
|
142
|
-
const sarifLog = {
|
|
143
|
-
$schema: "https://raw.githubusercontent.com/oasis-tcs/sarif-spec/master/Schemata/sarif-schema-2.1.0.json",
|
|
144
|
-
version: "2.1.0",
|
|
145
|
-
runs: [
|
|
146
|
-
{
|
|
147
|
-
tool: {
|
|
148
|
-
driver: {
|
|
149
|
-
name: artifact.tool.name,
|
|
150
|
-
version: artifact.tool.version,
|
|
151
|
-
informationUri: "https://github.com/anthropics/vibecheck",
|
|
152
|
-
rules,
|
|
153
|
-
},
|
|
154
|
-
},
|
|
155
|
-
results,
|
|
156
|
-
invocations: [
|
|
157
|
-
{
|
|
158
|
-
executionSuccessful: true,
|
|
159
|
-
startTimeUtc: artifact.generatedAt,
|
|
160
|
-
},
|
|
161
|
-
],
|
|
162
|
-
},
|
|
163
|
-
],
|
|
164
|
-
};
|
|
165
|
-
return sarifLog;
|
|
166
|
-
}
|
|
167
|
-
/**
|
|
168
|
-
* Convert SARIF log to JSON string
|
|
169
|
-
*/
|
|
170
|
-
export function sarifToJson(sarif, pretty = true) {
|
|
171
|
-
return JSON.stringify(sarif, null, pretty ? 2 : 0);
|
|
172
|
-
}
|