@kevinrabun/judges 3.48.0 → 3.50.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 (70) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +112 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/api-audit.d.ts +9 -0
  6. package/dist/commands/api-audit.d.ts.map +1 -0
  7. package/dist/commands/api-audit.js +360 -0
  8. package/dist/commands/api-audit.js.map +1 -0
  9. package/dist/commands/compliance-map.d.ts +9 -0
  10. package/dist/commands/compliance-map.d.ts.map +1 -0
  11. package/dist/commands/compliance-map.js +375 -0
  12. package/dist/commands/compliance-map.js.map +1 -0
  13. package/dist/commands/exec-report.d.ts +9 -0
  14. package/dist/commands/exec-report.d.ts.map +1 -0
  15. package/dist/commands/exec-report.js +272 -0
  16. package/dist/commands/exec-report.js.map +1 -0
  17. package/dist/commands/guided-tour.d.ts +9 -0
  18. package/dist/commands/guided-tour.d.ts.map +1 -0
  19. package/dist/commands/guided-tour.js +288 -0
  20. package/dist/commands/guided-tour.js.map +1 -0
  21. package/dist/commands/iac-lint.d.ts +8 -0
  22. package/dist/commands/iac-lint.d.ts.map +1 -0
  23. package/dist/commands/iac-lint.js +313 -0
  24. package/dist/commands/iac-lint.js.map +1 -0
  25. package/dist/commands/incident-response.d.ts +8 -0
  26. package/dist/commands/incident-response.d.ts.map +1 -0
  27. package/dist/commands/incident-response.js +255 -0
  28. package/dist/commands/incident-response.js.map +1 -0
  29. package/dist/commands/learning-path.d.ts +9 -0
  30. package/dist/commands/learning-path.d.ts.map +1 -0
  31. package/dist/commands/learning-path.js +326 -0
  32. package/dist/commands/learning-path.js.map +1 -0
  33. package/dist/commands/license-scan.d.ts +9 -0
  34. package/dist/commands/license-scan.d.ts.map +1 -0
  35. package/dist/commands/license-scan.js +180 -0
  36. package/dist/commands/license-scan.js.map +1 -0
  37. package/dist/commands/org-policy.d.ts +8 -0
  38. package/dist/commands/org-policy.d.ts.map +1 -0
  39. package/dist/commands/org-policy.js +208 -0
  40. package/dist/commands/org-policy.js.map +1 -0
  41. package/dist/commands/perf-compare.d.ts +9 -0
  42. package/dist/commands/perf-compare.d.ts.map +1 -0
  43. package/dist/commands/perf-compare.js +246 -0
  44. package/dist/commands/perf-compare.js.map +1 -0
  45. package/dist/commands/pii-scan.d.ts +8 -0
  46. package/dist/commands/pii-scan.d.ts.map +1 -0
  47. package/dist/commands/pii-scan.js +300 -0
  48. package/dist/commands/pii-scan.js.map +1 -0
  49. package/dist/commands/predict.d.ts +8 -0
  50. package/dist/commands/predict.d.ts.map +1 -0
  51. package/dist/commands/predict.js +219 -0
  52. package/dist/commands/predict.js.map +1 -0
  53. package/dist/commands/risk-heatmap.d.ts +8 -0
  54. package/dist/commands/risk-heatmap.d.ts.map +1 -0
  55. package/dist/commands/risk-heatmap.js +224 -0
  56. package/dist/commands/risk-heatmap.js.map +1 -0
  57. package/dist/commands/sbom-export.d.ts +8 -0
  58. package/dist/commands/sbom-export.d.ts.map +1 -0
  59. package/dist/commands/sbom-export.js +162 -0
  60. package/dist/commands/sbom-export.js.map +1 -0
  61. package/dist/commands/secret-scan.d.ts +8 -0
  62. package/dist/commands/secret-scan.d.ts.map +1 -0
  63. package/dist/commands/secret-scan.js +245 -0
  64. package/dist/commands/secret-scan.js.map +1 -0
  65. package/dist/commands/test-correlate.d.ts +8 -0
  66. package/dist/commands/test-correlate.d.ts.map +1 -0
  67. package/dist/commands/test-correlate.js +222 -0
  68. package/dist/commands/test-correlate.js.map +1 -0
  69. package/package.json +1 -1
  70. package/server.json +2 -2
@@ -0,0 +1,245 @@
1
+ /**
2
+ * Secret scan — entropy-based and regex-based secret detection
3
+ * in source files. Optimized for CI gates and pre-commit hooks.
4
+ *
5
+ * All analysis local — no external services.
6
+ */
7
+ import { existsSync, readFileSync, readdirSync, mkdirSync, writeFileSync } from "fs";
8
+ import { join, extname } from "path";
9
+ // ─── Patterns ───────────────────────────────────────────────────────────────
10
+ const SECRET_PATTERNS = [
11
+ { id: "aws-access-key", name: "AWS Access Key", regex: /AKIA[0-9A-Z]{16}/, severity: "critical" },
12
+ {
13
+ id: "aws-secret-key",
14
+ name: "AWS Secret Key",
15
+ regex: /(?:aws_secret_access_key|AWS_SECRET_ACCESS_KEY)\s*[=:]\s*['"]?([A-Za-z0-9/+=]{40})/,
16
+ severity: "critical",
17
+ },
18
+ {
19
+ id: "github-token",
20
+ name: "GitHub Token",
21
+ regex: /ghp_[A-Za-z0-9]{36}|github_pat_[A-Za-z0-9_]{82}/,
22
+ severity: "critical",
23
+ },
24
+ { id: "github-oauth", name: "GitHub OAuth", regex: /gho_[A-Za-z0-9]{36}/, severity: "critical" },
25
+ {
26
+ id: "generic-api-key",
27
+ name: "Generic API Key",
28
+ regex: /(?:api[_-]?key|apikey)\s*[=:]\s*['"]([A-Za-z0-9_-]{20,})['"]/,
29
+ severity: "high",
30
+ },
31
+ {
32
+ id: "generic-secret",
33
+ name: "Generic Secret",
34
+ regex: /(?:secret|password|passwd|pwd)\s*[=:]\s*['"]([^'"]{8,})['"]/,
35
+ severity: "high",
36
+ },
37
+ {
38
+ id: "private-key",
39
+ name: "Private Key",
40
+ regex: /-----BEGIN (?:RSA |EC |DSA )?PRIVATE KEY-----/,
41
+ severity: "critical",
42
+ },
43
+ {
44
+ id: "gcp-service-account",
45
+ name: "GCP Service Account",
46
+ regex: /"type"\s*:\s*"service_account"/,
47
+ severity: "critical",
48
+ },
49
+ { id: "stripe-key", name: "Stripe API Key", regex: /sk_live_[A-Za-z0-9]{24,}/, severity: "critical" },
50
+ { id: "stripe-test", name: "Stripe Test Key", regex: /sk_test_[A-Za-z0-9]{24,}/, severity: "medium" },
51
+ {
52
+ id: "slack-webhook",
53
+ name: "Slack Webhook",
54
+ regex: /hooks\.slack\.com\/services\/T[A-Z0-9]+\/B[A-Z0-9]+\/[A-Za-z0-9]+/,
55
+ severity: "high",
56
+ },
57
+ { id: "slack-token", name: "Slack Token", regex: /xox[bprs]-[A-Za-z0-9-]+/, severity: "high" },
58
+ { id: "npm-token", name: "NPM Token", regex: /npm_[A-Za-z0-9]{36}/, severity: "critical" },
59
+ {
60
+ id: "sendgrid-key",
61
+ name: "SendGrid API Key",
62
+ regex: /SG\.[A-Za-z0-9_-]{22}\.[A-Za-z0-9_-]{43}/,
63
+ severity: "critical",
64
+ },
65
+ {
66
+ id: "jwt-token",
67
+ name: "JWT Token",
68
+ regex: /eyJ[A-Za-z0-9_-]{10,}\.eyJ[A-Za-z0-9_-]{10,}\.[A-Za-z0-9_-]{10,}/,
69
+ severity: "high",
70
+ },
71
+ {
72
+ id: "connection-string",
73
+ name: "Database Connection String",
74
+ regex: /(?:mongodb|postgres|mysql|redis):\/\/[^:]+:[^@]+@[^\s'"]+/,
75
+ severity: "critical",
76
+ },
77
+ ];
78
+ // ─── Scanner ────────────────────────────────────────────────────────────────
79
+ const SKIP_EXTENSIONS = new Set([
80
+ ".png",
81
+ ".jpg",
82
+ ".jpeg",
83
+ ".gif",
84
+ ".ico",
85
+ ".svg",
86
+ ".woff",
87
+ ".woff2",
88
+ ".ttf",
89
+ ".eot",
90
+ ".zip",
91
+ ".tar",
92
+ ".gz",
93
+ ]);
94
+ const SKIP_DIRS = new Set(["node_modules", ".git", "dist", "build", "coverage", ".next"]);
95
+ function collectFiles(dir, maxFiles) {
96
+ const result = [];
97
+ function walk(d) {
98
+ if (result.length >= maxFiles)
99
+ return;
100
+ let entries;
101
+ try {
102
+ entries = readdirSync(d);
103
+ }
104
+ catch {
105
+ return;
106
+ }
107
+ for (const name of entries) {
108
+ if (result.length >= maxFiles)
109
+ return;
110
+ if (SKIP_DIRS.has(name))
111
+ continue;
112
+ const full = join(d, name);
113
+ if (SKIP_EXTENSIONS.has(extname(name)))
114
+ continue;
115
+ try {
116
+ const sub = readdirSync(full);
117
+ void sub;
118
+ walk(full);
119
+ }
120
+ catch {
121
+ result.push(full);
122
+ }
123
+ }
124
+ }
125
+ walk(dir);
126
+ return result;
127
+ }
128
+ function maskSecret(value) {
129
+ if (value.length <= 8)
130
+ return "****";
131
+ return value.substring(0, 4) + "****" + value.substring(value.length - 4);
132
+ }
133
+ function scanFile(filePath) {
134
+ let content;
135
+ try {
136
+ content = readFileSync(filePath, "utf-8");
137
+ }
138
+ catch {
139
+ return [];
140
+ }
141
+ // Skip binary-looking files
142
+ if (content.includes("\0"))
143
+ return [];
144
+ const lines = content.split("\n");
145
+ const findings = [];
146
+ for (let i = 0; i < lines.length; i++) {
147
+ const line = lines[i];
148
+ // Skip comments that are likely documentation
149
+ if (/^\s*(?:\/\/|#|\/\*|\*)\s*(?:example|sample|placeholder|todo|fixme)/i.test(line))
150
+ continue;
151
+ for (const pattern of SECRET_PATTERNS) {
152
+ const match = pattern.regex.exec(line);
153
+ if (match) {
154
+ findings.push({
155
+ file: filePath,
156
+ line: i + 1,
157
+ patternId: pattern.id,
158
+ patternName: pattern.name,
159
+ severity: pattern.severity,
160
+ snippet: line.trim().substring(0, 80),
161
+ masked: maskSecret(match[0]),
162
+ });
163
+ }
164
+ }
165
+ }
166
+ return findings;
167
+ }
168
+ // ─── CLI ────────────────────────────────────────────────────────────────────
169
+ const STORE = ".judges-secret-scan";
170
+ export function runSecretScan(argv) {
171
+ if (argv.includes("--help") || argv.includes("-h")) {
172
+ console.log(`
173
+ judges secret-scan — Detect secrets and credentials in source code
174
+
175
+ Usage:
176
+ judges secret-scan [dir]
177
+ judges secret-scan src/ --severity critical
178
+ judges secret-scan --patterns
179
+ judges secret-scan --save
180
+
181
+ Options:
182
+ --severity <level> Filter by severity (critical, high, medium)
183
+ --patterns List all secret detection patterns
184
+ --save Save report to ${STORE}/
185
+ --format json JSON output
186
+ --help, -h Show this help
187
+ `);
188
+ return;
189
+ }
190
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
191
+ // List patterns
192
+ if (argv.includes("--patterns")) {
193
+ if (format === "json") {
194
+ console.log(JSON.stringify(SECRET_PATTERNS.map(({ regex: _r, ...rest }) => rest), null, 2));
195
+ }
196
+ else {
197
+ console.log(`\n Secret Patterns (${SECRET_PATTERNS.length})\n ──────────────────────────`);
198
+ for (const p of SECRET_PATTERNS) {
199
+ console.log(` [${p.severity.toUpperCase().padEnd(8)}] ${p.id.padEnd(25)} ${p.name}`);
200
+ }
201
+ console.log("");
202
+ }
203
+ return;
204
+ }
205
+ const scanDir = argv.find((a) => !a.startsWith("--") && !argv[argv.indexOf(a) - 1]?.startsWith("--")) || ".";
206
+ const sevFilter = argv.find((_a, i) => argv[i - 1] === "--severity");
207
+ const files = collectFiles(scanDir, 1000);
208
+ let findings = [];
209
+ for (const file of files)
210
+ findings.push(...scanFile(file));
211
+ if (sevFilter)
212
+ findings = findings.filter((f) => f.severity === sevFilter);
213
+ const report = { findings, scannedFiles: files.length, timestamp: new Date().toISOString() };
214
+ if (argv.includes("--save")) {
215
+ if (!existsSync(STORE))
216
+ mkdirSync(STORE, { recursive: true });
217
+ writeFileSync(join(STORE, "secret-report.json"), JSON.stringify(report, null, 2));
218
+ console.log(` Report saved to ${STORE}/secret-report.json`);
219
+ }
220
+ if (format === "json") {
221
+ console.log(JSON.stringify(report, null, 2));
222
+ }
223
+ else {
224
+ console.log(`\n Secret Scan — ${report.scannedFiles} files scanned`);
225
+ console.log(` Found: ${findings.length} potential secrets\n ──────────────────────────`);
226
+ if (findings.length === 0) {
227
+ console.log(` ✅ No secrets detected\n`);
228
+ return;
229
+ }
230
+ for (const sev of ["critical", "high", "medium"]) {
231
+ const items = findings.filter((f) => f.severity === sev);
232
+ if (items.length === 0)
233
+ continue;
234
+ console.log(`\n ${sev.toUpperCase()} (${items.length})`);
235
+ for (const f of items.slice(0, 10)) {
236
+ console.log(` ${f.file}:${f.line} — ${f.patternName}`);
237
+ console.log(` ${f.masked}`);
238
+ }
239
+ if (items.length > 10)
240
+ console.log(` ... and ${items.length - 10} more`);
241
+ }
242
+ console.log("");
243
+ }
244
+ }
245
+ //# sourceMappingURL=secret-scan.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"secret-scan.js","sourceRoot":"","sources":["../../src/commands/secret-scan.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Test correlate — ingests test coverage data and cross-references
3
+ * with security findings to prioritize high-risk untested areas.
4
+ *
5
+ * All data from local coverage files.
6
+ */
7
+ export declare function runTestCorrelate(argv: string[]): void;
8
+ //# sourceMappingURL=test-correlate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-correlate.d.ts","sourceRoot":"","sources":["../../src/commands/test-correlate.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAsLH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA6ErD"}
@@ -0,0 +1,222 @@
1
+ /**
2
+ * Test correlate — ingests test coverage data and cross-references
3
+ * with security findings to prioritize high-risk untested areas.
4
+ *
5
+ * All data from local coverage files.
6
+ */
7
+ import { existsSync, readFileSync, mkdirSync, writeFileSync } from "fs";
8
+ import { join } from "path";
9
+ // ─── Coverage parsers ───────────────────────────────────────────────────────
10
+ function parseLcov(content) {
11
+ const entries = [];
12
+ let currentFile = "";
13
+ let linesFound = 0;
14
+ let linesHit = 0;
15
+ for (const line of content.split("\n")) {
16
+ if (line.startsWith("SF:")) {
17
+ currentFile = line.substring(3).trim();
18
+ linesFound = 0;
19
+ linesHit = 0;
20
+ }
21
+ else if (line.startsWith("LF:")) {
22
+ linesFound = parseInt(line.substring(3), 10);
23
+ }
24
+ else if (line.startsWith("LH:")) {
25
+ linesHit = parseInt(line.substring(3), 10);
26
+ }
27
+ else if (line === "end_of_record" && currentFile) {
28
+ entries.push({
29
+ file: currentFile,
30
+ lines: {
31
+ covered: linesHit,
32
+ total: linesFound,
33
+ percentage: linesFound > 0 ? Math.round((linesHit / linesFound) * 100) : 0,
34
+ },
35
+ });
36
+ currentFile = "";
37
+ }
38
+ }
39
+ return entries;
40
+ }
41
+ function parseIstanbul(content) {
42
+ try {
43
+ const data = JSON.parse(content);
44
+ const entries = [];
45
+ for (const [file, info] of Object.entries(data)) {
46
+ const cov = info;
47
+ if (cov.s) {
48
+ const stmts = Object.values(cov.s);
49
+ const total = stmts.length;
50
+ const covered = stmts.filter((v) => v > 0).length;
51
+ entries.push({
52
+ file,
53
+ lines: { covered, total, percentage: total > 0 ? Math.round((covered / total) * 100) : 0 },
54
+ });
55
+ }
56
+ }
57
+ return entries;
58
+ }
59
+ catch {
60
+ return [];
61
+ }
62
+ }
63
+ function loadCoverage() {
64
+ const lcovPaths = ["coverage/lcov.info", "lcov.info"];
65
+ for (const p of lcovPaths) {
66
+ if (existsSync(p))
67
+ return parseLcov(readFileSync(p, "utf-8"));
68
+ }
69
+ const istanbulPaths = ["coverage/coverage-final.json", ".nyc_output/coverage-final.json"];
70
+ for (const p of istanbulPaths) {
71
+ if (existsSync(p))
72
+ return parseIstanbul(readFileSync(p, "utf-8"));
73
+ }
74
+ // Cobertura XML — simplified check
75
+ if (existsSync("coverage/cobertura-coverage.xml") || existsSync("coverage.xml")) {
76
+ const p = existsSync("coverage/cobertura-coverage.xml") ? "coverage/cobertura-coverage.xml" : "coverage.xml";
77
+ const content = readFileSync(p, "utf-8");
78
+ const entries = [];
79
+ const fileRegex = /filename="([^"]+)"/g;
80
+ const rateRegex = /line-rate="([\d.]+)"/g;
81
+ let fileMatch;
82
+ let rateMatch;
83
+ while ((fileMatch = fileRegex.exec(content)) && (rateMatch = rateRegex.exec(content))) {
84
+ entries.push({
85
+ file: fileMatch[1],
86
+ lines: { covered: 0, total: 0, percentage: Math.round(parseFloat(rateMatch[1]) * 100) },
87
+ });
88
+ }
89
+ return entries;
90
+ }
91
+ return [];
92
+ }
93
+ function loadFindings() {
94
+ const paths = [".judges-findings.json", "judges-report.json"];
95
+ for (const p of paths) {
96
+ if (!existsSync(p))
97
+ continue;
98
+ try {
99
+ const data = JSON.parse(readFileSync(p, "utf-8"));
100
+ if (Array.isArray(data))
101
+ return data;
102
+ if (data.findings)
103
+ return data.findings;
104
+ }
105
+ catch {
106
+ /* skip */
107
+ }
108
+ }
109
+ return [];
110
+ }
111
+ // ─── Correlation ────────────────────────────────────────────────────────────
112
+ function correlate(coverage, findings) {
113
+ const coverageMap = new Map();
114
+ for (const c of coverage)
115
+ coverageMap.set(c.file, c);
116
+ const findingsByFile = new Map();
117
+ for (const f of findings) {
118
+ const key = f.file || "unknown";
119
+ if (!findingsByFile.has(key))
120
+ findingsByFile.set(key, []);
121
+ findingsByFile.get(key).push(f);
122
+ }
123
+ const correlations = [];
124
+ for (const [file, fileFindings] of findingsByFile) {
125
+ const cov = coverageMap.get(file);
126
+ const covPct = cov ? cov.lines.percentage : 0;
127
+ const sevWeights = { critical: 10, high: 7, medium: 4, low: 1 };
128
+ const riskScore = fileFindings.reduce((s, f) => s + (sevWeights[f.severity] || 2), 0);
129
+ const combinedRisk = riskScore * (1 + (100 - covPct) / 100);
130
+ let riskCategory = "low";
131
+ if (combinedRisk > 30)
132
+ riskCategory = "critical";
133
+ else if (combinedRisk > 15)
134
+ riskCategory = "high";
135
+ else if (combinedRisk > 7)
136
+ riskCategory = "medium";
137
+ correlations.push({
138
+ file,
139
+ coveragePercent: covPct,
140
+ findingCount: fileFindings.length,
141
+ riskCategory,
142
+ findings: fileFindings,
143
+ });
144
+ }
145
+ return correlations.sort((a, b) => {
146
+ const order = { critical: 0, high: 1, medium: 2, low: 3 };
147
+ return (order[a.riskCategory] || 4) - (order[b.riskCategory] || 4);
148
+ });
149
+ }
150
+ // ─── CLI ────────────────────────────────────────────────────────────────────
151
+ const STORE = ".judges-test-correlate";
152
+ export function runTestCorrelate(argv) {
153
+ if (argv.includes("--help") || argv.includes("-h")) {
154
+ console.log(`
155
+ judges test-correlate — Cross-reference test coverage with findings
156
+
157
+ Usage:
158
+ judges test-correlate
159
+ judges test-correlate --risk critical,high
160
+ judges test-correlate --save
161
+
162
+ Options:
163
+ --risk <levels> Filter by risk category (comma-separated)
164
+ --save Save report to ${STORE}/
165
+ --format json JSON output
166
+ --help, -h Show this help
167
+
168
+ Supports: lcov.info, coverage-final.json (Istanbul), cobertura XML
169
+ `);
170
+ return;
171
+ }
172
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
173
+ const coverage = loadCoverage();
174
+ const findings = loadFindings();
175
+ if (coverage.length === 0) {
176
+ console.log(" No coverage data found. Run tests with coverage first.");
177
+ console.log(" Supported formats: lcov.info, coverage-final.json, cobertura XML");
178
+ return;
179
+ }
180
+ let correlations = correlate(coverage, findings);
181
+ const riskFilter = argv.find((_a, i) => argv[i - 1] === "--risk");
182
+ if (riskFilter) {
183
+ const allowed = riskFilter.split(",");
184
+ correlations = correlations.filter((c) => allowed.includes(c.riskCategory));
185
+ }
186
+ const avgCov = coverage.length > 0 ? Math.round(coverage.reduce((s, c) => s + c.lines.percentage, 0) / coverage.length) : 0;
187
+ const report = {
188
+ correlations,
189
+ totalFiles: coverage.length,
190
+ untestedFilesWithFindings: correlations.filter((c) => c.coveragePercent === 0).length,
191
+ avgCoverage: avgCov,
192
+ timestamp: new Date().toISOString(),
193
+ };
194
+ if (argv.includes("--save")) {
195
+ if (!existsSync(STORE))
196
+ mkdirSync(STORE, { recursive: true });
197
+ writeFileSync(join(STORE, "correlation-report.json"), JSON.stringify(report, null, 2));
198
+ console.log(` Saved to ${STORE}/correlation-report.json`);
199
+ }
200
+ if (format === "json") {
201
+ console.log(JSON.stringify(report, null, 2));
202
+ }
203
+ else {
204
+ console.log(`\n Test-Finding Correlation`);
205
+ console.log(` Files: ${report.totalFiles} Avg Coverage: ${report.avgCoverage}%`);
206
+ console.log(` Untested files with findings: ${report.untestedFilesWithFindings}`);
207
+ console.log(` ──────────────────────────`);
208
+ if (correlations.length === 0) {
209
+ console.log(` ✅ No finding-coverage correlations\n`);
210
+ return;
211
+ }
212
+ for (const c of correlations.slice(0, 20)) {
213
+ const covBar = c.coveragePercent > 0 ? `${c.coveragePercent}%` : "0% ⚠️";
214
+ console.log(` [${c.riskCategory.toUpperCase().padEnd(8)}] ${c.file}`);
215
+ console.log(` Coverage: ${covBar} Findings: ${c.findingCount}`);
216
+ }
217
+ if (correlations.length > 20)
218
+ console.log(` ... and ${correlations.length - 20} more`);
219
+ console.log("");
220
+ }
221
+ }
222
+ //# sourceMappingURL=test-correlate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-correlate.js","sourceRoot":"","sources":["../../src/commands/test-correlate.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kevinrabun/judges",
3
- "version": "3.48.0",
3
+ "version": "3.50.0",
4
4
  "description": "45 specialized judges that evaluate AI-generated code for security, cost, and quality.",
5
5
  "mcpName": "io.github.KevinRabun/judges",
6
6
  "type": "module",
package/server.json CHANGED
@@ -7,12 +7,12 @@
7
7
  "url": "https://github.com/kevinrabun/judges",
8
8
  "source": "github"
9
9
  },
10
- "version": "3.48.0",
10
+ "version": "3.50.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "@kevinrabun/judges",
15
- "version": "3.48.0",
15
+ "version": "3.50.0",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }