@vibecheckai/cli 3.4.0 → 3.5.1
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/bin/registry.js +154 -338
- package/bin/runners/context/generators/mcp.js +13 -15
- package/bin/runners/context/proof-context.js +1 -248
- package/bin/runners/lib/analysis-core.js +180 -198
- package/bin/runners/lib/analyzers.js +223 -1669
- package/bin/runners/lib/cli-output.js +210 -242
- package/bin/runners/lib/detectors-v2.js +785 -547
- package/bin/runners/lib/entitlements-v2.js +458 -96
- package/bin/runners/lib/error-handler.js +9 -16
- package/bin/runners/lib/global-flags.js +0 -37
- package/bin/runners/lib/route-truth.js +322 -1167
- package/bin/runners/lib/scan-output.js +469 -448
- package/bin/runners/lib/ship-output.js +27 -280
- package/bin/runners/lib/terminal-ui.js +733 -231
- package/bin/runners/lib/truth.js +321 -1004
- package/bin/runners/lib/unified-output.js +158 -162
- package/bin/runners/lib/upsell.js +204 -104
- package/bin/runners/runAllowlist.js +324 -0
- package/bin/runners/runAuth.js +95 -324
- package/bin/runners/runCheckpoint.js +21 -39
- package/bin/runners/runContext.js +24 -136
- package/bin/runners/runDoctor.js +67 -115
- package/bin/runners/runEvidencePack.js +219 -0
- package/bin/runners/runFix.js +5 -6
- package/bin/runners/runGuard.js +118 -212
- package/bin/runners/runInit.js +2 -14
- package/bin/runners/runInstall.js +281 -0
- package/bin/runners/runLabs.js +341 -0
- package/bin/runners/runMcp.js +52 -130
- package/bin/runners/runPolish.js +20 -43
- package/bin/runners/runProve.js +3 -13
- package/bin/runners/runReality.js +0 -14
- package/bin/runners/runReport.js +2 -3
- package/bin/runners/runScan.js +44 -511
- package/bin/runners/runShip.js +14 -28
- package/bin/runners/runValidate.js +2 -19
- package/bin/runners/runWatch.js +54 -118
- package/bin/vibecheck.js +41 -148
- package/mcp-server/ARCHITECTURE.md +339 -0
- package/mcp-server/__tests__/cache.test.ts +313 -0
- package/mcp-server/__tests__/executor.test.ts +239 -0
- package/mcp-server/__tests__/fixtures/exclusion-test/.cache/webpack/cache.pack +1 -0
- package/mcp-server/__tests__/fixtures/exclusion-test/.next/server/chunk.js +3 -0
- package/mcp-server/__tests__/fixtures/exclusion-test/.turbo/cache.json +3 -0
- package/mcp-server/__tests__/fixtures/exclusion-test/.venv/lib/env.py +3 -0
- package/mcp-server/__tests__/fixtures/exclusion-test/dist/bundle.js +3 -0
- package/mcp-server/__tests__/fixtures/exclusion-test/package.json +5 -0
- package/mcp-server/__tests__/fixtures/exclusion-test/src/app.ts +5 -0
- package/mcp-server/__tests__/fixtures/exclusion-test/venv/lib/config.py +4 -0
- package/mcp-server/__tests__/ids.test.ts +345 -0
- package/mcp-server/__tests__/integration/tools.test.ts +410 -0
- package/mcp-server/__tests__/registry.test.ts +365 -0
- package/mcp-server/__tests__/sandbox.test.ts +323 -0
- package/mcp-server/__tests__/schemas.test.ts +372 -0
- package/mcp-server/benchmarks/run-benchmarks.ts +304 -0
- package/mcp-server/examples/doctor.request.json +14 -0
- package/mcp-server/examples/doctor.response.json +53 -0
- package/mcp-server/examples/error.response.json +15 -0
- package/mcp-server/examples/scan.request.json +14 -0
- package/mcp-server/examples/scan.response.json +108 -0
- package/mcp-server/handlers/tool-handler.ts +671 -0
- package/mcp-server/index-v3.ts +293 -0
- package/mcp-server/index.js +1072 -1573
- package/mcp-server/index.old.js +4137 -0
- package/mcp-server/lib/cache.ts +341 -0
- package/mcp-server/lib/errors.ts +346 -0
- package/mcp-server/lib/executor.ts +792 -0
- package/mcp-server/lib/ids.ts +238 -0
- package/mcp-server/lib/logger.ts +368 -0
- package/mcp-server/lib/metrics.ts +365 -0
- package/mcp-server/lib/sandbox.ts +337 -0
- package/mcp-server/lib/validator.ts +229 -0
- package/mcp-server/package-lock.json +165 -0
- package/mcp-server/package.json +32 -7
- package/mcp-server/premium-tools.js +2 -2
- package/mcp-server/registry/tools.json +476 -0
- package/mcp-server/schemas/error-envelope.schema.json +125 -0
- package/mcp-server/schemas/finding.schema.json +167 -0
- package/mcp-server/schemas/report-artifact.schema.json +88 -0
- package/mcp-server/schemas/run-request.schema.json +75 -0
- package/mcp-server/schemas/verdict.schema.json +168 -0
- package/mcp-server/tier-auth.d.ts +71 -0
- package/mcp-server/tier-auth.js +371 -183
- package/mcp-server/truth-context.js +90 -131
- package/mcp-server/truth-firewall-tools.js +1000 -1611
- package/mcp-server/tsconfig.json +34 -0
- package/mcp-server/vibecheck-tools.js +2 -2
- package/mcp-server/vitest.config.ts +16 -0
- package/package.json +3 -4
- package/bin/runners/lib/agent-firewall/ai/false-positive-analyzer.js +0 -474
- package/bin/runners/lib/agent-firewall/change-packet/builder.js +0 -488
- package/bin/runners/lib/agent-firewall/change-packet/schema.json +0 -228
- package/bin/runners/lib/agent-firewall/change-packet/store.js +0 -200
- package/bin/runners/lib/agent-firewall/claims/claim-types.js +0 -21
- package/bin/runners/lib/agent-firewall/claims/extractor.js +0 -303
- package/bin/runners/lib/agent-firewall/claims/patterns.js +0 -24
- package/bin/runners/lib/agent-firewall/critic/index.js +0 -151
- package/bin/runners/lib/agent-firewall/critic/judge.js +0 -432
- package/bin/runners/lib/agent-firewall/critic/prompts.js +0 -305
- package/bin/runners/lib/agent-firewall/evidence/auth-evidence.js +0 -88
- package/bin/runners/lib/agent-firewall/evidence/contract-evidence.js +0 -75
- package/bin/runners/lib/agent-firewall/evidence/env-evidence.js +0 -127
- package/bin/runners/lib/agent-firewall/evidence/resolver.js +0 -102
- package/bin/runners/lib/agent-firewall/evidence/route-evidence.js +0 -213
- package/bin/runners/lib/agent-firewall/evidence/side-effect-evidence.js +0 -145
- package/bin/runners/lib/agent-firewall/fs-hook/daemon.js +0 -19
- package/bin/runners/lib/agent-firewall/fs-hook/installer.js +0 -87
- package/bin/runners/lib/agent-firewall/fs-hook/watcher.js +0 -184
- package/bin/runners/lib/agent-firewall/git-hook/pre-commit.js +0 -163
- package/bin/runners/lib/agent-firewall/ide-extension/cursor.js +0 -107
- package/bin/runners/lib/agent-firewall/ide-extension/vscode.js +0 -68
- package/bin/runners/lib/agent-firewall/ide-extension/windsurf.js +0 -66
- package/bin/runners/lib/agent-firewall/interceptor/base.js +0 -304
- package/bin/runners/lib/agent-firewall/interceptor/cursor.js +0 -35
- package/bin/runners/lib/agent-firewall/interceptor/vscode.js +0 -35
- package/bin/runners/lib/agent-firewall/interceptor/windsurf.js +0 -34
- package/bin/runners/lib/agent-firewall/lawbook/distributor.js +0 -465
- package/bin/runners/lib/agent-firewall/lawbook/evaluator.js +0 -604
- package/bin/runners/lib/agent-firewall/lawbook/index.js +0 -304
- package/bin/runners/lib/agent-firewall/lawbook/registry.js +0 -514
- package/bin/runners/lib/agent-firewall/lawbook/schema.js +0 -420
- package/bin/runners/lib/agent-firewall/logger.js +0 -141
- package/bin/runners/lib/agent-firewall/policy/default-policy.json +0 -90
- package/bin/runners/lib/agent-firewall/policy/engine.js +0 -103
- package/bin/runners/lib/agent-firewall/policy/loader.js +0 -451
- package/bin/runners/lib/agent-firewall/policy/rules/auth-drift.js +0 -50
- package/bin/runners/lib/agent-firewall/policy/rules/contract-drift.js +0 -50
- package/bin/runners/lib/agent-firewall/policy/rules/fake-success.js +0 -86
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-env.js +0 -162
- package/bin/runners/lib/agent-firewall/policy/rules/ghost-route.js +0 -189
- package/bin/runners/lib/agent-firewall/policy/rules/scope.js +0 -93
- package/bin/runners/lib/agent-firewall/policy/rules/unsafe-side-effect.js +0 -57
- package/bin/runners/lib/agent-firewall/policy/schema.json +0 -183
- package/bin/runners/lib/agent-firewall/policy/verdict.js +0 -54
- package/bin/runners/lib/agent-firewall/proposal/extractor.js +0 -394
- package/bin/runners/lib/agent-firewall/proposal/index.js +0 -212
- package/bin/runners/lib/agent-firewall/proposal/schema.js +0 -251
- package/bin/runners/lib/agent-firewall/proposal/validator.js +0 -386
- package/bin/runners/lib/agent-firewall/reality/index.js +0 -332
- package/bin/runners/lib/agent-firewall/reality/state.js +0 -625
- package/bin/runners/lib/agent-firewall/reality/watcher.js +0 -322
- package/bin/runners/lib/agent-firewall/risk/index.js +0 -173
- package/bin/runners/lib/agent-firewall/risk/scorer.js +0 -328
- package/bin/runners/lib/agent-firewall/risk/thresholds.js +0 -321
- package/bin/runners/lib/agent-firewall/risk/vectors.js +0 -421
- package/bin/runners/lib/agent-firewall/simulator/diff-simulator.js +0 -472
- package/bin/runners/lib/agent-firewall/simulator/import-resolver.js +0 -346
- package/bin/runners/lib/agent-firewall/simulator/index.js +0 -181
- package/bin/runners/lib/agent-firewall/simulator/route-validator.js +0 -380
- package/bin/runners/lib/agent-firewall/time-machine/incident-correlator.js +0 -661
- package/bin/runners/lib/agent-firewall/time-machine/index.js +0 -267
- package/bin/runners/lib/agent-firewall/time-machine/replay-engine.js +0 -436
- package/bin/runners/lib/agent-firewall/time-machine/state-reconstructor.js +0 -490
- package/bin/runners/lib/agent-firewall/time-machine/timeline-builder.js +0 -530
- package/bin/runners/lib/agent-firewall/truthpack/index.js +0 -67
- package/bin/runners/lib/agent-firewall/truthpack/loader.js +0 -137
- package/bin/runners/lib/agent-firewall/unblock/planner.js +0 -337
- package/bin/runners/lib/agent-firewall/utils/ignore-checker.js +0 -118
- package/bin/runners/lib/api-client.js +0 -269
- package/bin/runners/lib/authority-badge.js +0 -425
- package/bin/runners/lib/engines/accessibility-engine.js +0 -190
- package/bin/runners/lib/engines/api-consistency-engine.js +0 -162
- package/bin/runners/lib/engines/ast-cache.js +0 -99
- package/bin/runners/lib/engines/code-quality-engine.js +0 -255
- package/bin/runners/lib/engines/console-logs-engine.js +0 -115
- package/bin/runners/lib/engines/cross-file-analysis-engine.js +0 -268
- package/bin/runners/lib/engines/dead-code-engine.js +0 -198
- package/bin/runners/lib/engines/deprecated-api-engine.js +0 -226
- package/bin/runners/lib/engines/empty-catch-engine.js +0 -150
- package/bin/runners/lib/engines/file-filter.js +0 -131
- package/bin/runners/lib/engines/hardcoded-secrets-engine.js +0 -251
- package/bin/runners/lib/engines/mock-data-engine.js +0 -272
- package/bin/runners/lib/engines/parallel-processor.js +0 -71
- package/bin/runners/lib/engines/performance-issues-engine.js +0 -265
- package/bin/runners/lib/engines/security-vulnerabilities-engine.js +0 -243
- package/bin/runners/lib/engines/todo-fixme-engine.js +0 -115
- package/bin/runners/lib/engines/type-aware-engine.js +0 -152
- package/bin/runners/lib/engines/unsafe-regex-engine.js +0 -225
- package/bin/runners/lib/engines/vibecheck-engines/README.md +0 -53
- package/bin/runners/lib/engines/vibecheck-engines/index.js +0 -15
- package/bin/runners/lib/engines/vibecheck-engines/lib/ast-cache.js +0 -164
- package/bin/runners/lib/engines/vibecheck-engines/lib/code-quality-engine.js +0 -291
- package/bin/runners/lib/engines/vibecheck-engines/lib/console-logs-engine.js +0 -83
- package/bin/runners/lib/engines/vibecheck-engines/lib/dead-code-engine.js +0 -198
- package/bin/runners/lib/engines/vibecheck-engines/lib/deprecated-api-engine.js +0 -275
- package/bin/runners/lib/engines/vibecheck-engines/lib/empty-catch-engine.js +0 -167
- package/bin/runners/lib/engines/vibecheck-engines/lib/file-filter.js +0 -217
- package/bin/runners/lib/engines/vibecheck-engines/lib/hardcoded-secrets-engine.js +0 -139
- package/bin/runners/lib/engines/vibecheck-engines/lib/mock-data-engine.js +0 -140
- package/bin/runners/lib/engines/vibecheck-engines/lib/parallel-processor.js +0 -164
- package/bin/runners/lib/engines/vibecheck-engines/lib/performance-issues-engine.js +0 -234
- package/bin/runners/lib/engines/vibecheck-engines/lib/type-aware-engine.js +0 -217
- package/bin/runners/lib/engines/vibecheck-engines/lib/unsafe-regex-engine.js +0 -78
- package/bin/runners/lib/engines/vibecheck-engines/package.json +0 -13
- package/bin/runners/lib/exit-codes.js +0 -275
- package/bin/runners/lib/fingerprint.js +0 -377
- package/bin/runners/lib/help-formatter.js +0 -413
- package/bin/runners/lib/logger.js +0 -38
- package/bin/runners/lib/ship-output-enterprise.js +0 -239
- package/bin/runners/lib/unified-cli-output.js +0 -604
- package/bin/runners/runAgent.d.ts +0 -5
- package/bin/runners/runAgent.js +0 -161
- package/bin/runners/runApprove.js +0 -1200
- package/bin/runners/runClassify.js +0 -859
- package/bin/runners/runContext.d.ts +0 -4
- package/bin/runners/runFirewall.d.ts +0 -5
- package/bin/runners/runFirewall.js +0 -134
- package/bin/runners/runFirewallHook.d.ts +0 -5
- package/bin/runners/runFirewallHook.js +0 -56
- package/bin/runners/runPolish.d.ts +0 -4
- package/bin/runners/runProof.zip +0 -0
- package/bin/runners/runTruth.d.ts +0 -5
- package/bin/runners/runTruth.js +0 -101
- package/mcp-server/HARDENING_SUMMARY.md +0 -299
- package/mcp-server/agent-firewall-interceptor.js +0 -500
- package/mcp-server/authority-tools.js +0 -569
- package/mcp-server/conductor/conflict-resolver.js +0 -588
- package/mcp-server/conductor/execution-planner.js +0 -544
- package/mcp-server/conductor/index.js +0 -377
- package/mcp-server/conductor/lock-manager.js +0 -615
- package/mcp-server/conductor/request-queue.js +0 -550
- package/mcp-server/conductor/session-manager.js +0 -500
- package/mcp-server/conductor/tools.js +0 -510
- package/mcp-server/lib/api-client.cjs +0 -13
- package/mcp-server/lib/logger.cjs +0 -30
- package/mcp-server/logger.js +0 -173
- package/mcp-server/tools-v3.js +0 -706
- package/mcp-server/vibecheck-mcp-server-3.2.0.tgz +0 -0
|
@@ -1,269 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* API Client for Vibecheck Dashboard Integration
|
|
3
|
-
*
|
|
4
|
-
* Handles communication with the web dashboard API for:
|
|
5
|
-
* - Creating scan records
|
|
6
|
-
* - Updating scan progress
|
|
7
|
-
* - Submitting scan results
|
|
8
|
-
* - Broadcasting real-time updates
|
|
9
|
-
*/
|
|
10
|
-
|
|
11
|
-
"use strict";
|
|
12
|
-
|
|
13
|
-
const https = require("https");
|
|
14
|
-
const http = require("http");
|
|
15
|
-
const { logger } = require("./logger");
|
|
16
|
-
|
|
17
|
-
// Configuration
|
|
18
|
-
const API_BASE_URL = process.env.VIBECHECK_API_URL || "https://api.vibecheckai.dev";
|
|
19
|
-
const API_TIMEOUT = 30000; // 30 seconds
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Make HTTP request to API
|
|
23
|
-
*/
|
|
24
|
-
async function makeRequest(path, options = {}) {
|
|
25
|
-
const url = new URL(path, API_BASE_URL);
|
|
26
|
-
const isHttps = url.protocol === "https:";
|
|
27
|
-
const client = isHttps ? https : http;
|
|
28
|
-
|
|
29
|
-
const defaultOptions = {
|
|
30
|
-
method: "POST",
|
|
31
|
-
headers: {
|
|
32
|
-
"Content-Type": "application/json",
|
|
33
|
-
"User-Agent": "vibecheck-cli/3.3.0",
|
|
34
|
-
},
|
|
35
|
-
timeout: API_TIMEOUT,
|
|
36
|
-
};
|
|
37
|
-
|
|
38
|
-
const requestOptions = {
|
|
39
|
-
...defaultOptions,
|
|
40
|
-
...options,
|
|
41
|
-
hostname: url.hostname,
|
|
42
|
-
port: url.port || (isHttps ? 443 : 80),
|
|
43
|
-
path: url.pathname + url.search,
|
|
44
|
-
};
|
|
45
|
-
|
|
46
|
-
// Add Authorization header if API key is available
|
|
47
|
-
const apiKey = process.env.VIBECHECK_API_KEY || getApiKey();
|
|
48
|
-
if (apiKey) {
|
|
49
|
-
requestOptions.headers.Authorization = `Bearer ${apiKey}`;
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
return new Promise((resolve, reject) => {
|
|
53
|
-
const req = client.request(requestOptions, (res) => {
|
|
54
|
-
let data = "";
|
|
55
|
-
|
|
56
|
-
res.on("data", (chunk) => {
|
|
57
|
-
data += chunk;
|
|
58
|
-
});
|
|
59
|
-
|
|
60
|
-
res.on("end", () => {
|
|
61
|
-
try {
|
|
62
|
-
const jsonData = data ? JSON.parse(data) : {};
|
|
63
|
-
resolve({
|
|
64
|
-
ok: res.statusCode >= 200 && res.statusCode < 300,
|
|
65
|
-
status: res.statusCode,
|
|
66
|
-
data: jsonData,
|
|
67
|
-
});
|
|
68
|
-
} catch (err) {
|
|
69
|
-
resolve({
|
|
70
|
-
ok: false,
|
|
71
|
-
status: res.statusCode,
|
|
72
|
-
data: { error: "Invalid JSON response" },
|
|
73
|
-
});
|
|
74
|
-
}
|
|
75
|
-
});
|
|
76
|
-
});
|
|
77
|
-
|
|
78
|
-
req.on("error", (err) => {
|
|
79
|
-
logger.debug(`API request failed: ${err.message}`);
|
|
80
|
-
resolve({
|
|
81
|
-
ok: false,
|
|
82
|
-
error: err.message,
|
|
83
|
-
data: { error: err.message },
|
|
84
|
-
});
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
req.on("timeout", () => {
|
|
88
|
-
req.destroy();
|
|
89
|
-
resolve({
|
|
90
|
-
ok: false,
|
|
91
|
-
error: "Request timeout",
|
|
92
|
-
data: { error: "Request timeout" },
|
|
93
|
-
});
|
|
94
|
-
});
|
|
95
|
-
|
|
96
|
-
if (options.body) {
|
|
97
|
-
req.write(JSON.stringify(options.body));
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
req.end();
|
|
101
|
-
});
|
|
102
|
-
}
|
|
103
|
-
|
|
104
|
-
/**
|
|
105
|
-
* Get API key from environment or config
|
|
106
|
-
*/
|
|
107
|
-
function getApiKey() {
|
|
108
|
-
// Try various environment variables
|
|
109
|
-
const envVars = [
|
|
110
|
-
"VIBECHECK_API_KEY",
|
|
111
|
-
"VIBECHECK_TOKEN",
|
|
112
|
-
"API_KEY",
|
|
113
|
-
"TOKEN",
|
|
114
|
-
];
|
|
115
|
-
|
|
116
|
-
for (const envVar of envVars) {
|
|
117
|
-
if (process.env[envVar]) {
|
|
118
|
-
return process.env[envVar];
|
|
119
|
-
}
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
// Try to read from config file
|
|
123
|
-
try {
|
|
124
|
-
const fs = require("fs");
|
|
125
|
-
const path = require("path");
|
|
126
|
-
const os = require("os");
|
|
127
|
-
|
|
128
|
-
const configPaths = [
|
|
129
|
-
path.join(os.homedir(), ".vibecheck", "config.json"),
|
|
130
|
-
path.join(process.cwd(), ".vibecheckrc.json"),
|
|
131
|
-
path.join(process.cwd(), "vibecheck.config.json"),
|
|
132
|
-
];
|
|
133
|
-
|
|
134
|
-
for (const configPath of configPaths) {
|
|
135
|
-
if (fs.existsSync(configPath)) {
|
|
136
|
-
const config = JSON.parse(fs.readFileSync(configPath, "utf8"));
|
|
137
|
-
if (config.apiKey || config.token) {
|
|
138
|
-
return config.apiKey || config.token;
|
|
139
|
-
}
|
|
140
|
-
}
|
|
141
|
-
}
|
|
142
|
-
} catch (err) {
|
|
143
|
-
// Ignore config file errors
|
|
144
|
-
}
|
|
145
|
-
|
|
146
|
-
return null;
|
|
147
|
-
}
|
|
148
|
-
|
|
149
|
-
/**
|
|
150
|
-
* Create a new scan record
|
|
151
|
-
*/
|
|
152
|
-
async function createScan(options) {
|
|
153
|
-
const {
|
|
154
|
-
repositoryId,
|
|
155
|
-
repositoryUrl,
|
|
156
|
-
localPath,
|
|
157
|
-
branch = "main",
|
|
158
|
-
enableLLM = false,
|
|
159
|
-
} = options;
|
|
160
|
-
|
|
161
|
-
const response = await makeRequest("/api/scans", {
|
|
162
|
-
body: {
|
|
163
|
-
repositoryId,
|
|
164
|
-
repositoryUrl,
|
|
165
|
-
localPath,
|
|
166
|
-
branch,
|
|
167
|
-
enableLLM,
|
|
168
|
-
},
|
|
169
|
-
});
|
|
170
|
-
|
|
171
|
-
if (!response.ok) {
|
|
172
|
-
throw new Error(`Failed to create scan: ${response.data?.error || response.error}`);
|
|
173
|
-
}
|
|
174
|
-
|
|
175
|
-
return response.data.data;
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
/**
|
|
179
|
-
* Update scan progress
|
|
180
|
-
*/
|
|
181
|
-
async function updateScanProgress(scanId, progress, status = null) {
|
|
182
|
-
const response = await makeRequest(`/api/scans/${scanId}/progress`, {
|
|
183
|
-
body: {
|
|
184
|
-
progress,
|
|
185
|
-
status,
|
|
186
|
-
},
|
|
187
|
-
});
|
|
188
|
-
|
|
189
|
-
if (!response.ok) {
|
|
190
|
-
logger.debug(`Failed to update scan progress: ${response.data?.error || response.error}`);
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
return response.data;
|
|
194
|
-
}
|
|
195
|
-
|
|
196
|
-
/**
|
|
197
|
-
* Submit scan results
|
|
198
|
-
*/
|
|
199
|
-
async function submitScanResults(scanId, results) {
|
|
200
|
-
const {
|
|
201
|
-
verdict,
|
|
202
|
-
score,
|
|
203
|
-
findings,
|
|
204
|
-
filesScanned,
|
|
205
|
-
linesScanned,
|
|
206
|
-
durationMs,
|
|
207
|
-
metadata = {},
|
|
208
|
-
} = results;
|
|
209
|
-
|
|
210
|
-
const response = await makeRequest(`/api/scans/${scanId}/complete`, {
|
|
211
|
-
body: {
|
|
212
|
-
verdict,
|
|
213
|
-
score,
|
|
214
|
-
findings,
|
|
215
|
-
filesScanned,
|
|
216
|
-
linesScanned,
|
|
217
|
-
durationMs,
|
|
218
|
-
metadata,
|
|
219
|
-
},
|
|
220
|
-
});
|
|
221
|
-
|
|
222
|
-
if (!response.ok) {
|
|
223
|
-
throw new Error(`Failed to submit scan results: ${response.data?.error || response.error}`);
|
|
224
|
-
}
|
|
225
|
-
|
|
226
|
-
return response.data;
|
|
227
|
-
}
|
|
228
|
-
|
|
229
|
-
/**
|
|
230
|
-
* Report scan error
|
|
231
|
-
*/
|
|
232
|
-
async function reportScanError(scanId, error) {
|
|
233
|
-
const response = await makeRequest(`/api/scans/${scanId}/error`, {
|
|
234
|
-
body: {
|
|
235
|
-
error: error.message || String(error),
|
|
236
|
-
stack: error.stack,
|
|
237
|
-
},
|
|
238
|
-
});
|
|
239
|
-
|
|
240
|
-
if (!response.ok) {
|
|
241
|
-
logger.debug(`Failed to report scan error: ${response.data?.error || response.error}`);
|
|
242
|
-
}
|
|
243
|
-
|
|
244
|
-
return response.data;
|
|
245
|
-
}
|
|
246
|
-
|
|
247
|
-
/**
|
|
248
|
-
* Check if API is available
|
|
249
|
-
*/
|
|
250
|
-
async function isApiAvailable() {
|
|
251
|
-
try {
|
|
252
|
-
const response = await makeRequest("/api/health", {
|
|
253
|
-
method: "GET",
|
|
254
|
-
timeout: 5000,
|
|
255
|
-
});
|
|
256
|
-
return response.ok;
|
|
257
|
-
} catch (err) {
|
|
258
|
-
return false;
|
|
259
|
-
}
|
|
260
|
-
}
|
|
261
|
-
|
|
262
|
-
module.exports = {
|
|
263
|
-
createScan,
|
|
264
|
-
updateScanProgress,
|
|
265
|
-
submitScanResults,
|
|
266
|
-
reportScanError,
|
|
267
|
-
isApiAvailable,
|
|
268
|
-
getApiKey,
|
|
269
|
-
};
|
|
@@ -1,425 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Authority Badge Generator
|
|
3
|
-
*
|
|
4
|
-
* Generates SVG badges for PROCEED verdicts from the Authority System.
|
|
5
|
-
* Part of the PRO tier - requires verified verdicts.
|
|
6
|
-
*
|
|
7
|
-
* Badge Types:
|
|
8
|
-
* - authority-approved: Standard approval badge
|
|
9
|
-
* - safe-consolidation: Safe Consolidation authority badge
|
|
10
|
-
* - inventory: Inventory analysis badge
|
|
11
|
-
*
|
|
12
|
-
* Output formats:
|
|
13
|
-
* - SVG (default, scalable)
|
|
14
|
-
* - Markdown (for README embedding)
|
|
15
|
-
* - HTML (for web embedding)
|
|
16
|
-
*/
|
|
17
|
-
|
|
18
|
-
const path = require("path");
|
|
19
|
-
const fs = require("fs");
|
|
20
|
-
|
|
21
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
22
|
-
// COLOR PALETTE
|
|
23
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
24
|
-
|
|
25
|
-
const BADGE_COLORS = {
|
|
26
|
-
PROCEED: {
|
|
27
|
-
background: '#22C55E',
|
|
28
|
-
text: '#FFFFFF',
|
|
29
|
-
},
|
|
30
|
-
DEFER: {
|
|
31
|
-
background: '#F59E0B',
|
|
32
|
-
text: '#000000',
|
|
33
|
-
},
|
|
34
|
-
STOP: {
|
|
35
|
-
background: '#EF4444',
|
|
36
|
-
text: '#FFFFFF',
|
|
37
|
-
},
|
|
38
|
-
neutral: {
|
|
39
|
-
background: '#555555',
|
|
40
|
-
text: '#FFFFFF',
|
|
41
|
-
},
|
|
42
|
-
};
|
|
43
|
-
|
|
44
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
45
|
-
// SVG TEMPLATES
|
|
46
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
47
|
-
|
|
48
|
-
/**
|
|
49
|
-
* Generate an SVG badge
|
|
50
|
-
*/
|
|
51
|
-
function generateSVGBadge(options) {
|
|
52
|
-
const {
|
|
53
|
-
label = 'Authority Approved',
|
|
54
|
-
message,
|
|
55
|
-
color,
|
|
56
|
-
textColor = '#FFFFFF',
|
|
57
|
-
logo = null,
|
|
58
|
-
style = 'flat',
|
|
59
|
-
} = options;
|
|
60
|
-
|
|
61
|
-
// Calculate widths based on text length
|
|
62
|
-
const labelWidth = Math.max(label.length * 7 + 10, 80);
|
|
63
|
-
const messageWidth = Math.max(message.length * 7 + 10, 50);
|
|
64
|
-
const totalWidth = labelWidth + messageWidth;
|
|
65
|
-
|
|
66
|
-
if (style === 'flat-square') {
|
|
67
|
-
return generateFlatSquareBadge({ label, message, color, textColor, labelWidth, messageWidth, totalWidth, logo });
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
return generateFlatBadge({ label, message, color, textColor, labelWidth, messageWidth, totalWidth, logo });
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
function generateFlatBadge(opts) {
|
|
74
|
-
const { label, message, color, textColor, labelWidth, messageWidth, totalWidth, logo } = opts;
|
|
75
|
-
|
|
76
|
-
let logoSvg = '';
|
|
77
|
-
let logoOffset = 0;
|
|
78
|
-
|
|
79
|
-
if (logo === 'vibecheck') {
|
|
80
|
-
logoOffset = 16;
|
|
81
|
-
logoSvg = `
|
|
82
|
-
<g transform="translate(5, 3)">
|
|
83
|
-
<path fill="${textColor}" d="M7 1l7 12H0L7 1zm0 3l-4 7h8L7 4z"/>
|
|
84
|
-
</g>`;
|
|
85
|
-
}
|
|
86
|
-
|
|
87
|
-
return `<svg xmlns="http://www.w3.org/2000/svg" width="${totalWidth + logoOffset}" height="20" role="img" aria-label="${label}: ${message}">
|
|
88
|
-
<title>${label}: ${message}</title>
|
|
89
|
-
<linearGradient id="s" x2="0" y2="100%">
|
|
90
|
-
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
91
|
-
<stop offset="1" stop-opacity=".1"/>
|
|
92
|
-
</linearGradient>
|
|
93
|
-
<clipPath id="r">
|
|
94
|
-
<rect width="${totalWidth + logoOffset}" height="20" rx="3" fill="#fff"/>
|
|
95
|
-
</clipPath>
|
|
96
|
-
<g clip-path="url(#r)">
|
|
97
|
-
<rect width="${labelWidth + logoOffset}" height="20" fill="#555"/>
|
|
98
|
-
<rect x="${labelWidth + logoOffset}" width="${messageWidth}" height="20" fill="${color}"/>
|
|
99
|
-
<rect width="${totalWidth + logoOffset}" height="20" fill="url(#s)"/>
|
|
100
|
-
</g>
|
|
101
|
-
${logoSvg}
|
|
102
|
-
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="11">
|
|
103
|
-
<text aria-hidden="true" x="${(labelWidth + logoOffset) / 2 + logoOffset/2}" y="15" fill="#010101" fill-opacity=".3">${label}</text>
|
|
104
|
-
<text x="${(labelWidth + logoOffset) / 2 + logoOffset/2}" y="14" fill="#fff">${label}</text>
|
|
105
|
-
<text aria-hidden="true" x="${labelWidth + logoOffset + messageWidth / 2}" y="15" fill="#010101" fill-opacity=".3">${message}</text>
|
|
106
|
-
<text x="${labelWidth + logoOffset + messageWidth / 2}" y="14" fill="${textColor}">${message}</text>
|
|
107
|
-
</g>
|
|
108
|
-
</svg>`;
|
|
109
|
-
}
|
|
110
|
-
|
|
111
|
-
function generateFlatSquareBadge(opts) {
|
|
112
|
-
const { label, message, color, textColor, labelWidth, messageWidth, totalWidth, logo } = opts;
|
|
113
|
-
|
|
114
|
-
let logoSvg = '';
|
|
115
|
-
let logoOffset = 0;
|
|
116
|
-
|
|
117
|
-
if (logo === 'vibecheck') {
|
|
118
|
-
logoOffset = 16;
|
|
119
|
-
logoSvg = `
|
|
120
|
-
<g transform="translate(5, 3)">
|
|
121
|
-
<path fill="${textColor}" d="M7 1l7 12H0L7 1zm0 3l-4 7h8L7 4z"/>
|
|
122
|
-
</g>`;
|
|
123
|
-
}
|
|
124
|
-
|
|
125
|
-
return `<svg xmlns="http://www.w3.org/2000/svg" width="${totalWidth + logoOffset}" height="20" role="img" aria-label="${label}: ${message}">
|
|
126
|
-
<title>${label}: ${message}</title>
|
|
127
|
-
<g shape-rendering="crispEdges">
|
|
128
|
-
<rect width="${labelWidth + logoOffset}" height="20" fill="#555"/>
|
|
129
|
-
<rect x="${labelWidth + logoOffset}" width="${messageWidth}" height="20" fill="${color}"/>
|
|
130
|
-
</g>
|
|
131
|
-
${logoSvg}
|
|
132
|
-
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="11">
|
|
133
|
-
<text x="${(labelWidth + logoOffset) / 2 + logoOffset/2}" y="14" fill="#fff">${label}</text>
|
|
134
|
-
<text x="${labelWidth + logoOffset + messageWidth / 2}" y="14" fill="${textColor}">${message}</text>
|
|
135
|
-
</g>
|
|
136
|
-
</svg>`;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
140
|
-
// BADGE GENERATORS
|
|
141
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
142
|
-
|
|
143
|
-
/**
|
|
144
|
-
* Generate an authority verdict badge
|
|
145
|
-
*/
|
|
146
|
-
function generateVerdictBadge(verdict, options = {}) {
|
|
147
|
-
const {
|
|
148
|
-
style = 'flat',
|
|
149
|
-
logo = 'vibecheck',
|
|
150
|
-
includeConfidence = true,
|
|
151
|
-
} = options;
|
|
152
|
-
|
|
153
|
-
const action = verdict.action || 'UNKNOWN';
|
|
154
|
-
const confidence = verdict.confidence || 0;
|
|
155
|
-
const authorityId = verdict.authority || 'authority';
|
|
156
|
-
|
|
157
|
-
const colors = BADGE_COLORS[action] || BADGE_COLORS.neutral;
|
|
158
|
-
|
|
159
|
-
let message = action;
|
|
160
|
-
if (includeConfidence && action !== 'STOP') {
|
|
161
|
-
message = `${action} ${Math.round(confidence * 100)}%`;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
return generateSVGBadge({
|
|
165
|
-
label: `Authority: ${authorityId}`,
|
|
166
|
-
message,
|
|
167
|
-
color: colors.background,
|
|
168
|
-
textColor: colors.text,
|
|
169
|
-
logo,
|
|
170
|
-
style,
|
|
171
|
-
});
|
|
172
|
-
}
|
|
173
|
-
|
|
174
|
-
/**
|
|
175
|
-
* Generate a simple "Authority Approved" badge
|
|
176
|
-
*/
|
|
177
|
-
function generateApprovedBadge(options = {}) {
|
|
178
|
-
const {
|
|
179
|
-
authority = 'vibecheck',
|
|
180
|
-
confidence = 100,
|
|
181
|
-
version = '1.0',
|
|
182
|
-
style = 'flat',
|
|
183
|
-
} = options;
|
|
184
|
-
|
|
185
|
-
return generateSVGBadge({
|
|
186
|
-
label: 'Authority Approved',
|
|
187
|
-
message: `${authority} v${version}`,
|
|
188
|
-
color: BADGE_COLORS.PROCEED.background,
|
|
189
|
-
textColor: BADGE_COLORS.PROCEED.text,
|
|
190
|
-
logo: 'vibecheck',
|
|
191
|
-
style,
|
|
192
|
-
});
|
|
193
|
-
}
|
|
194
|
-
|
|
195
|
-
/**
|
|
196
|
-
* Generate a Safe Consolidation badge
|
|
197
|
-
*/
|
|
198
|
-
function generateSafeConsolidationBadge(verdict, options = {}) {
|
|
199
|
-
const {
|
|
200
|
-
style = 'flat',
|
|
201
|
-
} = options;
|
|
202
|
-
|
|
203
|
-
const action = verdict.action || 'PROCEED';
|
|
204
|
-
const confidence = verdict.confidence || 0.95;
|
|
205
|
-
const colors = BADGE_COLORS[action] || BADGE_COLORS.PROCEED;
|
|
206
|
-
|
|
207
|
-
return generateSVGBadge({
|
|
208
|
-
label: 'Safe Consolidation',
|
|
209
|
-
message: `${action} ${Math.round(confidence * 100)}%`,
|
|
210
|
-
color: colors.background,
|
|
211
|
-
textColor: colors.text,
|
|
212
|
-
logo: 'vibecheck',
|
|
213
|
-
style,
|
|
214
|
-
});
|
|
215
|
-
}
|
|
216
|
-
|
|
217
|
-
/**
|
|
218
|
-
* Generate a CI status badge
|
|
219
|
-
*/
|
|
220
|
-
function generateCIBadge(verdict, options = {}) {
|
|
221
|
-
const {
|
|
222
|
-
style = 'flat',
|
|
223
|
-
ciName = 'CI',
|
|
224
|
-
} = options;
|
|
225
|
-
|
|
226
|
-
const action = verdict.action || 'UNKNOWN';
|
|
227
|
-
const exitCode = verdict.exitCode ?? (action === 'PROCEED' ? 0 : action === 'DEFER' ? 1 : 2);
|
|
228
|
-
|
|
229
|
-
let status, color;
|
|
230
|
-
if (exitCode === 0) {
|
|
231
|
-
status = 'passing';
|
|
232
|
-
color = BADGE_COLORS.PROCEED.background;
|
|
233
|
-
} else if (exitCode === 1) {
|
|
234
|
-
status = 'review';
|
|
235
|
-
color = BADGE_COLORS.DEFER.background;
|
|
236
|
-
} else {
|
|
237
|
-
status = 'failing';
|
|
238
|
-
color = BADGE_COLORS.STOP.background;
|
|
239
|
-
}
|
|
240
|
-
|
|
241
|
-
return generateSVGBadge({
|
|
242
|
-
label: ciName,
|
|
243
|
-
message: status,
|
|
244
|
-
color,
|
|
245
|
-
textColor: '#FFFFFF',
|
|
246
|
-
style,
|
|
247
|
-
});
|
|
248
|
-
}
|
|
249
|
-
|
|
250
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
251
|
-
// OUTPUT FORMATTERS
|
|
252
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
253
|
-
|
|
254
|
-
/**
|
|
255
|
-
* Format badge for markdown embedding
|
|
256
|
-
*/
|
|
257
|
-
function formatBadgeMarkdown(badge, options = {}) {
|
|
258
|
-
const {
|
|
259
|
-
altText = 'Authority Approved by VibeCheck',
|
|
260
|
-
link = 'https://vibecheckai.dev',
|
|
261
|
-
} = options;
|
|
262
|
-
|
|
263
|
-
// Encode SVG for data URI
|
|
264
|
-
const encoded = encodeURIComponent(badge)
|
|
265
|
-
.replace(/'/g, '%27')
|
|
266
|
-
.replace(/"/g, '%22');
|
|
267
|
-
|
|
268
|
-
const dataUri = `data:image/svg+xml,${encoded}`;
|
|
269
|
-
|
|
270
|
-
if (link) {
|
|
271
|
-
return `[](${link})`;
|
|
272
|
-
}
|
|
273
|
-
|
|
274
|
-
return ``;
|
|
275
|
-
}
|
|
276
|
-
|
|
277
|
-
/**
|
|
278
|
-
* Format badge for HTML embedding
|
|
279
|
-
*/
|
|
280
|
-
function formatBadgeHTML(badge, options = {}) {
|
|
281
|
-
const {
|
|
282
|
-
altText = 'Authority Approved by VibeCheck',
|
|
283
|
-
link = 'https://vibecheckai.dev',
|
|
284
|
-
className = 'vibecheck-badge',
|
|
285
|
-
} = options;
|
|
286
|
-
|
|
287
|
-
// Encode SVG for data URI
|
|
288
|
-
const encoded = encodeURIComponent(badge)
|
|
289
|
-
.replace(/'/g, '%27')
|
|
290
|
-
.replace(/"/g, '%22');
|
|
291
|
-
|
|
292
|
-
const dataUri = `data:image/svg+xml,${encoded}`;
|
|
293
|
-
|
|
294
|
-
const img = `<img src="${dataUri}" alt="${altText}" class="${className}">`;
|
|
295
|
-
|
|
296
|
-
if (link) {
|
|
297
|
-
return `<a href="${link}" target="_blank" rel="noopener noreferrer">${img}</a>`;
|
|
298
|
-
}
|
|
299
|
-
|
|
300
|
-
return img;
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
304
|
-
// FILE OUTPUT
|
|
305
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
306
|
-
|
|
307
|
-
/**
|
|
308
|
-
* Save badge to file
|
|
309
|
-
*/
|
|
310
|
-
async function saveBadge(badge, filePath, format = 'svg') {
|
|
311
|
-
const dir = path.dirname(filePath);
|
|
312
|
-
|
|
313
|
-
// Ensure directory exists
|
|
314
|
-
if (!fs.existsSync(dir)) {
|
|
315
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
316
|
-
}
|
|
317
|
-
|
|
318
|
-
let content = badge;
|
|
319
|
-
let ext = '.svg';
|
|
320
|
-
|
|
321
|
-
if (format === 'markdown' || format === 'md') {
|
|
322
|
-
content = formatBadgeMarkdown(badge);
|
|
323
|
-
ext = '.md';
|
|
324
|
-
} else if (format === 'html') {
|
|
325
|
-
content = formatBadgeHTML(badge);
|
|
326
|
-
ext = '.html';
|
|
327
|
-
}
|
|
328
|
-
|
|
329
|
-
// Ensure file has correct extension
|
|
330
|
-
let finalPath = filePath;
|
|
331
|
-
if (!filePath.endsWith(ext) && format !== 'svg') {
|
|
332
|
-
finalPath = filePath.replace(/\.[^.]+$/, ext);
|
|
333
|
-
}
|
|
334
|
-
|
|
335
|
-
await fs.promises.writeFile(finalPath, content);
|
|
336
|
-
|
|
337
|
-
return finalPath;
|
|
338
|
-
}
|
|
339
|
-
|
|
340
|
-
/**
|
|
341
|
-
* Generate and save all badge variants
|
|
342
|
-
*/
|
|
343
|
-
async function generateAllBadges(verdict, outputDir, options = {}) {
|
|
344
|
-
const {
|
|
345
|
-
prefix = verdict.authority || 'authority',
|
|
346
|
-
} = options;
|
|
347
|
-
|
|
348
|
-
const badges = {};
|
|
349
|
-
|
|
350
|
-
// Main verdict badge
|
|
351
|
-
const verdictBadge = generateVerdictBadge(verdict, options);
|
|
352
|
-
badges.verdict = await saveBadge(
|
|
353
|
-
verdictBadge,
|
|
354
|
-
path.join(outputDir, `${prefix}-badge.svg`)
|
|
355
|
-
);
|
|
356
|
-
|
|
357
|
-
// If PROCEED, also generate approved badge
|
|
358
|
-
if (verdict.action === 'PROCEED') {
|
|
359
|
-
const approvedBadge = generateApprovedBadge({
|
|
360
|
-
authority: verdict.authority,
|
|
361
|
-
confidence: verdict.confidence,
|
|
362
|
-
version: verdict.version,
|
|
363
|
-
});
|
|
364
|
-
badges.approved = await saveBadge(
|
|
365
|
-
approvedBadge,
|
|
366
|
-
path.join(outputDir, `${prefix}-approved-badge.svg`)
|
|
367
|
-
);
|
|
368
|
-
|
|
369
|
-
// CI badge
|
|
370
|
-
const ciBadge = generateCIBadge(verdict);
|
|
371
|
-
badges.ci = await saveBadge(
|
|
372
|
-
ciBadge,
|
|
373
|
-
path.join(outputDir, `${prefix}-ci-badge.svg`)
|
|
374
|
-
);
|
|
375
|
-
}
|
|
376
|
-
|
|
377
|
-
// Generate markdown snippet
|
|
378
|
-
const mdContent = `# ${verdict.authority || 'Authority'} Badge
|
|
379
|
-
|
|
380
|
-
${formatBadgeMarkdown(verdictBadge, { altText: \`\${verdict.authority} - \${verdict.action}\` })}
|
|
381
|
-
|
|
382
|
-
## Embed Code
|
|
383
|
-
|
|
384
|
-
### Markdown
|
|
385
|
-
\`\`\`markdown
|
|
386
|
-
${formatBadgeMarkdown(verdictBadge, { altText: \`\${verdict.authority} - \${verdict.action}\` })}
|
|
387
|
-
\`\`\`
|
|
388
|
-
|
|
389
|
-
### HTML
|
|
390
|
-
\`\`\`html
|
|
391
|
-
${formatBadgeHTML(verdictBadge, { altText: \`\${verdict.authority} - \${verdict.action}\` })}
|
|
392
|
-
\`\`\`
|
|
393
|
-
|
|
394
|
-
---
|
|
395
|
-
Generated: ${new Date().toISOString()}
|
|
396
|
-
`;
|
|
397
|
-
|
|
398
|
-
badges.readme = await saveBadge(mdContent, path.join(outputDir, `${prefix}-BADGE.md`), 'md');
|
|
399
|
-
|
|
400
|
-
return badges;
|
|
401
|
-
}
|
|
402
|
-
|
|
403
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
404
|
-
// EXPORTS
|
|
405
|
-
// ═══════════════════════════════════════════════════════════════════════════════
|
|
406
|
-
|
|
407
|
-
module.exports = {
|
|
408
|
-
// Badge generators
|
|
409
|
-
generateSVGBadge,
|
|
410
|
-
generateVerdictBadge,
|
|
411
|
-
generateApprovedBadge,
|
|
412
|
-
generateSafeConsolidationBadge,
|
|
413
|
-
generateCIBadge,
|
|
414
|
-
|
|
415
|
-
// Formatters
|
|
416
|
-
formatBadgeMarkdown,
|
|
417
|
-
formatBadgeHTML,
|
|
418
|
-
|
|
419
|
-
// File operations
|
|
420
|
-
saveBadge,
|
|
421
|
-
generateAllBadges,
|
|
422
|
-
|
|
423
|
-
// Constants
|
|
424
|
-
BADGE_COLORS,
|
|
425
|
-
};
|