@kevinrabun/judges 3.105.0 → 3.106.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 (42) hide show
  1. package/CHANGELOG.md +13 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +63 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/finding-priority-rank.d.ts +2 -0
  6. package/dist/commands/finding-priority-rank.d.ts.map +1 -0
  7. package/dist/commands/finding-priority-rank.js +83 -0
  8. package/dist/commands/finding-priority-rank.js.map +1 -0
  9. package/dist/commands/finding-regression-detect.d.ts +2 -0
  10. package/dist/commands/finding-regression-detect.d.ts.map +1 -0
  11. package/dist/commands/finding-regression-detect.js +87 -0
  12. package/dist/commands/finding-regression-detect.js.map +1 -0
  13. package/dist/commands/finding-reopen-detect.d.ts +2 -0
  14. package/dist/commands/finding-reopen-detect.d.ts.map +1 -0
  15. package/dist/commands/finding-reopen-detect.js +78 -0
  16. package/dist/commands/finding-reopen-detect.js.map +1 -0
  17. package/dist/commands/review-dependency-review.d.ts +2 -0
  18. package/dist/commands/review-dependency-review.d.ts.map +1 -0
  19. package/dist/commands/review-dependency-review.js +105 -0
  20. package/dist/commands/review-dependency-review.js.map +1 -0
  21. package/dist/commands/review-knowledge-capture.d.ts +2 -0
  22. package/dist/commands/review-knowledge-capture.d.ts.map +1 -0
  23. package/dist/commands/review-knowledge-capture.js +95 -0
  24. package/dist/commands/review-knowledge-capture.js.map +1 -0
  25. package/dist/commands/review-merge-readiness.d.ts +2 -0
  26. package/dist/commands/review-merge-readiness.d.ts.map +1 -0
  27. package/dist/commands/review-merge-readiness.js +91 -0
  28. package/dist/commands/review-merge-readiness.js.map +1 -0
  29. package/dist/commands/review-onboarding-check.d.ts +2 -0
  30. package/dist/commands/review-onboarding-check.d.ts.map +1 -0
  31. package/dist/commands/review-onboarding-check.js +94 -0
  32. package/dist/commands/review-onboarding-check.js.map +1 -0
  33. package/dist/commands/review-quality-gate.d.ts +2 -0
  34. package/dist/commands/review-quality-gate.d.ts.map +1 -0
  35. package/dist/commands/review-quality-gate.js +87 -0
  36. package/dist/commands/review-quality-gate.js.map +1 -0
  37. package/dist/commands/review-security-posture.d.ts +2 -0
  38. package/dist/commands/review-security-posture.d.ts.map +1 -0
  39. package/dist/commands/review-security-posture.js +106 -0
  40. package/dist/commands/review-security-posture.js.map +1 -0
  41. package/package.json +1 -1
  42. package/server.json +2 -2
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-onboarding-check.d.ts","sourceRoot":"","sources":["../../src/commands/review-onboarding-check.ts"],"names":[],"mappings":"AAyEA,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAsC7D"}
@@ -0,0 +1,94 @@
1
+ import { readFileSync, existsSync } from "fs";
2
+ import { join } from "path";
3
+ function runChecks(cwd) {
4
+ const checks = [];
5
+ // Check for judgesrc config
6
+ const rcPath = join(cwd, ".judgesrc");
7
+ const rcJsonPath = join(cwd, ".judgesrc.json");
8
+ if (existsSync(rcPath) || existsSync(rcJsonPath)) {
9
+ checks.push({ item: "Config file", status: "OK", detail: "Found .judgesrc" });
10
+ }
11
+ else {
12
+ checks.push({ item: "Config file", status: "MISSING", detail: "Create .judgesrc or .judgesrc.json" });
13
+ }
14
+ // Check for .judges directory
15
+ const judgesDir = join(cwd, ".judges");
16
+ if (existsSync(judgesDir)) {
17
+ checks.push({ item: ".judges directory", status: "OK", detail: "Found .judges/" });
18
+ }
19
+ else {
20
+ checks.push({ item: ".judges directory", status: "MISSING", detail: "Create .judges/ for local data" });
21
+ }
22
+ // Check for baseline
23
+ const baselinePath = join(cwd, ".judges", "baseline.json");
24
+ if (existsSync(baselinePath)) {
25
+ checks.push({ item: "Baseline", status: "OK", detail: "Baseline configured" });
26
+ }
27
+ else {
28
+ checks.push({ item: "Baseline", status: "MISSING", detail: "Run judges baseline to set up" });
29
+ }
30
+ // Check for CI integration
31
+ const ghWorkflow = join(cwd, ".github", "workflows");
32
+ if (existsSync(ghWorkflow)) {
33
+ checks.push({ item: "CI workflows", status: "OK", detail: "GitHub Actions detected" });
34
+ }
35
+ else {
36
+ checks.push({ item: "CI workflows", status: "MISSING", detail: "Set up CI integration" });
37
+ }
38
+ // Check for last verdict
39
+ const verdictPath = join(cwd, ".judges", "last-verdict.json");
40
+ if (existsSync(verdictPath)) {
41
+ checks.push({ item: "Last verdict", status: "OK", detail: "Previous review found" });
42
+ }
43
+ else {
44
+ checks.push({ item: "Last verdict", status: "MISSING", detail: "Run a review first" });
45
+ }
46
+ // Check for .gitignore entry
47
+ const gitignorePath = join(cwd, ".gitignore");
48
+ if (existsSync(gitignorePath)) {
49
+ const content = readFileSync(gitignorePath, "utf-8");
50
+ if (content.includes(".judges")) {
51
+ checks.push({ item: ".gitignore", status: "OK", detail: ".judges/ is gitignored" });
52
+ }
53
+ else {
54
+ checks.push({ item: ".gitignore", status: "WARNING", detail: "Consider adding .judges/ to .gitignore" });
55
+ }
56
+ }
57
+ return checks;
58
+ }
59
+ export function runReviewOnboardingCheck(argv) {
60
+ if (argv.includes("--help") || argv.includes("-h")) {
61
+ console.log(`Usage: judges review-onboarding-check [options]
62
+
63
+ Check onboarding status for Judges integration.
64
+
65
+ Options:
66
+ --format <fmt> Output format: table (default) or json
67
+ -h, --help Show this help message`);
68
+ return;
69
+ }
70
+ const formatIdx = argv.indexOf("--format");
71
+ const format = formatIdx !== -1 && argv[formatIdx + 1] ? argv[formatIdx + 1] : "table";
72
+ const checks = runChecks(process.cwd());
73
+ if (format === "json") {
74
+ console.log(JSON.stringify(checks, null, 2));
75
+ return;
76
+ }
77
+ console.log("\n=== Onboarding Checklist ===\n");
78
+ let okCount = 0;
79
+ for (const c of checks) {
80
+ const icon = c.status === "OK" ? "OK" : c.status === "WARNING" ? "WARN" : "MISS";
81
+ console.log(` [${icon}] ${c.item}: ${c.detail}`);
82
+ if (c.status === "OK")
83
+ okCount++;
84
+ }
85
+ const pct = Math.round((okCount / checks.length) * 100);
86
+ console.log(`\nOnboarding progress: ${pct}% (${okCount}/${checks.length})`);
87
+ if (pct === 100) {
88
+ console.log("All checks passed — setup is complete!");
89
+ }
90
+ else {
91
+ console.log("Address the MISSING items to complete setup.");
92
+ }
93
+ }
94
+ //# sourceMappingURL=review-onboarding-check.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-onboarding-check.js","sourceRoot":"","sources":["../../src/commands/review-onboarding-check.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runReviewQualityGate(argv: string[]): void;
2
+ //# sourceMappingURL=review-quality-gate.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-quality-gate.d.ts","sourceRoot":"","sources":["../../src/commands/review-quality-gate.ts"],"names":[],"mappings":"AA2DA,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAgEzD"}
@@ -0,0 +1,87 @@
1
+ import { readFileSync, existsSync } from "fs";
2
+ import { join } from "path";
3
+ function evaluateGates(findings, score, gates) {
4
+ const criticalCount = findings.filter((f) => f.severity === "critical").length;
5
+ const highCount = findings.filter((f) => f.severity === "high").length;
6
+ const results = [];
7
+ for (const gate of gates) {
8
+ const details = [];
9
+ let passed = true;
10
+ if (criticalCount > gate.maxCritical) {
11
+ passed = false;
12
+ details.push(`Critical findings: ${criticalCount} (max ${gate.maxCritical})`);
13
+ }
14
+ if (highCount > gate.maxHigh) {
15
+ passed = false;
16
+ details.push(`High findings: ${highCount} (max ${gate.maxHigh})`);
17
+ }
18
+ if (score < gate.minScore) {
19
+ passed = false;
20
+ details.push(`Score: ${score} (min ${gate.minScore})`);
21
+ }
22
+ if (findings.length > gate.maxTotal) {
23
+ passed = false;
24
+ details.push(`Total findings: ${findings.length} (max ${gate.maxTotal})`);
25
+ }
26
+ if (passed) {
27
+ details.push("All checks passed");
28
+ }
29
+ results.push({ gate: gate.name, passed, details });
30
+ }
31
+ return results;
32
+ }
33
+ export function runReviewQualityGate(argv) {
34
+ if (argv.includes("--help") || argv.includes("-h")) {
35
+ console.log(`Usage: judges review-quality-gate [options]
36
+
37
+ Evaluate quality gates against review findings.
38
+
39
+ Options:
40
+ --report <path> Path to verdict JSON file
41
+ --gates <path> Path to quality gates config JSON
42
+ --format <fmt> Output format: table (default) or json
43
+ -h, --help Show this help message`);
44
+ return;
45
+ }
46
+ const formatIdx = argv.indexOf("--format");
47
+ const format = formatIdx !== -1 && argv[formatIdx + 1] ? argv[formatIdx + 1] : "table";
48
+ const reportIdx = argv.indexOf("--report");
49
+ const reportPath = reportIdx !== -1 && argv[reportIdx + 1]
50
+ ? join(process.cwd(), argv[reportIdx + 1])
51
+ : join(process.cwd(), ".judges", "last-verdict.json");
52
+ const gatesIdx = argv.indexOf("--gates");
53
+ const gatesPath = gatesIdx !== -1 && argv[gatesIdx + 1]
54
+ ? join(process.cwd(), argv[gatesIdx + 1])
55
+ : join(process.cwd(), ".judges", "quality-gates.json");
56
+ if (!existsSync(reportPath)) {
57
+ console.log(`No report found at: ${reportPath}`);
58
+ return;
59
+ }
60
+ const data = JSON.parse(readFileSync(reportPath, "utf-8"));
61
+ const findings = data.findings ?? [];
62
+ let gates;
63
+ if (existsSync(gatesPath)) {
64
+ const gateData = JSON.parse(readFileSync(gatesPath, "utf-8"));
65
+ gates = gateData.gates ?? [];
66
+ }
67
+ else {
68
+ gates = [{ name: "Default", maxCritical: 0, maxHigh: 2, minScore: 70, maxTotal: 20 }];
69
+ }
70
+ const results = evaluateGates(findings, data.overallScore, gates);
71
+ if (format === "json") {
72
+ console.log(JSON.stringify(results, null, 2));
73
+ return;
74
+ }
75
+ console.log("\n=== Quality Gate Results ===\n");
76
+ for (const r of results) {
77
+ const status = r.passed ? "PASSED" : "FAILED";
78
+ console.log(`[${status}] ${r.gate}`);
79
+ for (const d of r.details) {
80
+ console.log(` - ${d}`);
81
+ }
82
+ console.log();
83
+ }
84
+ const allPassed = results.every((r) => r.passed);
85
+ console.log(allPassed ? "All quality gates passed." : "Some quality gates failed.");
86
+ }
87
+ //# sourceMappingURL=review-quality-gate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-quality-gate.js","sourceRoot":"","sources":["../../src/commands/review-quality-gate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runReviewSecurityPosture(argv: string[]): void;
2
+ //# sourceMappingURL=review-security-posture.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-security-posture.d.ts","sourceRoot":"","sources":["../../src/commands/review-security-posture.ts"],"names":[],"mappings":"AAuFA,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAqD7D"}
@@ -0,0 +1,106 @@
1
+ import { readFileSync, existsSync } from "fs";
2
+ import { join } from "path";
3
+ const SECURITY_PREFIXES = ["SEC", "AUTH", "CRYPTO", "INJECT", "XSS", "SSRF", "IDOR", "CORS"];
4
+ function isSecurityFinding(f) {
5
+ const prefix = f.ruleId.split("-")[0].toUpperCase();
6
+ if (SECURITY_PREFIXES.includes(prefix))
7
+ return true;
8
+ const lower = `${f.title} ${f.description}`.toLowerCase();
9
+ return lower.includes("security") || lower.includes("vulnerab") || lower.includes("exploit");
10
+ }
11
+ function getDomain(f) {
12
+ const prefix = f.ruleId.split("-")[0].toUpperCase();
13
+ if (SECURITY_PREFIXES.includes(prefix))
14
+ return prefix;
15
+ return "GENERAL";
16
+ }
17
+ function analyzePosture(findings) {
18
+ const secFindings = findings.filter(isSecurityFinding);
19
+ const domainMap = new Map();
20
+ for (const f of secFindings) {
21
+ const domain = getDomain(f);
22
+ const list = domainMap.get(domain) ?? [];
23
+ list.push(f);
24
+ domainMap.set(domain, list);
25
+ }
26
+ const domains = [];
27
+ for (const [domain, dFindings] of domainMap) {
28
+ const critCount = dFindings.filter((f) => f.severity === "critical").length;
29
+ const highCount = dFindings.filter((f) => f.severity === "high").length;
30
+ const riskScore = critCount * 10 + highCount * 5 + dFindings.length;
31
+ domains.push({
32
+ domain,
33
+ findingCount: dFindings.length,
34
+ criticalCount: critCount,
35
+ highCount,
36
+ riskScore,
37
+ });
38
+ }
39
+ domains.sort((a, b) => b.riskScore - a.riskScore);
40
+ const topThreats = secFindings
41
+ .filter((f) => f.severity === "critical" || f.severity === "high")
42
+ .slice(0, 5)
43
+ .map((f) => ({ ruleId: f.ruleId, title: f.title, severity: f.severity }));
44
+ const totalRisk = domains.reduce((s, d) => s + d.riskScore, 0);
45
+ let overallRisk;
46
+ if (totalRisk === 0)
47
+ overallRisk = "Low";
48
+ else if (totalRisk <= 10)
49
+ overallRisk = "Moderate";
50
+ else if (totalRisk <= 30)
51
+ overallRisk = "High";
52
+ else
53
+ overallRisk = "Critical";
54
+ return {
55
+ overallRisk,
56
+ totalSecurityFindings: secFindings.length,
57
+ domains,
58
+ topThreats,
59
+ };
60
+ }
61
+ export function runReviewSecurityPosture(argv) {
62
+ if (argv.includes("--help") || argv.includes("-h")) {
63
+ console.log(`Usage: judges review-security-posture [options]
64
+
65
+ Assess security posture from review findings.
66
+
67
+ Options:
68
+ --report <path> Path to verdict JSON file
69
+ --format <fmt> Output format: table (default) or json
70
+ -h, --help Show this help message`);
71
+ return;
72
+ }
73
+ const formatIdx = argv.indexOf("--format");
74
+ const format = formatIdx !== -1 && argv[formatIdx + 1] ? argv[formatIdx + 1] : "table";
75
+ const reportIdx = argv.indexOf("--report");
76
+ const reportPath = reportIdx !== -1 && argv[reportIdx + 1]
77
+ ? join(process.cwd(), argv[reportIdx + 1])
78
+ : join(process.cwd(), ".judges", "last-verdict.json");
79
+ if (!existsSync(reportPath)) {
80
+ console.log(`No report found at: ${reportPath}`);
81
+ return;
82
+ }
83
+ const data = JSON.parse(readFileSync(reportPath, "utf-8"));
84
+ const findings = data.findings ?? [];
85
+ const summary = analyzePosture(findings);
86
+ if (format === "json") {
87
+ console.log(JSON.stringify(summary, null, 2));
88
+ return;
89
+ }
90
+ console.log(`\n=== Security Posture: ${summary.overallRisk} Risk ===\n`);
91
+ console.log(`Security findings: ${summary.totalSecurityFindings} of ${findings.length} total\n`);
92
+ if (summary.domains.length > 0) {
93
+ console.log("Domains:");
94
+ for (const d of summary.domains) {
95
+ console.log(` ${d.domain}: ${d.findingCount} findings (risk score: ${d.riskScore})`);
96
+ }
97
+ }
98
+ if (summary.topThreats.length > 0) {
99
+ console.log("\nTop Threats:");
100
+ for (const t of summary.topThreats) {
101
+ console.log(` [${t.severity.toUpperCase()}] ${t.ruleId}: ${t.title}`);
102
+ }
103
+ }
104
+ console.log();
105
+ }
106
+ //# sourceMappingURL=review-security-posture.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-security-posture.js","sourceRoot":"","sources":["../../src/commands/review-security-posture.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.105.0",
3
+ "version": "3.106.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.105.0",
10
+ "version": "3.106.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "@kevinrabun/judges",
15
- "version": "3.105.0",
15
+ "version": "3.106.0",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }