@kevinrabun/judges 3.102.0 → 3.103.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-annotation-export.d.ts +2 -0
  6. package/dist/commands/finding-annotation-export.d.ts.map +1 -0
  7. package/dist/commands/finding-annotation-export.js +98 -0
  8. package/dist/commands/finding-annotation-export.js.map +1 -0
  9. package/dist/commands/finding-dedup-smart.d.ts +2 -0
  10. package/dist/commands/finding-dedup-smart.d.ts.map +1 -0
  11. package/dist/commands/finding-dedup-smart.js +110 -0
  12. package/dist/commands/finding-dedup-smart.js.map +1 -0
  13. package/dist/commands/finding-merge-strategy.d.ts +2 -0
  14. package/dist/commands/finding-merge-strategy.d.ts.map +1 -0
  15. package/dist/commands/finding-merge-strategy.js +85 -0
  16. package/dist/commands/finding-merge-strategy.js.map +1 -0
  17. package/dist/commands/finding-trend-alert.d.ts +2 -0
  18. package/dist/commands/finding-trend-alert.d.ts.map +1 -0
  19. package/dist/commands/finding-trend-alert.js +127 -0
  20. package/dist/commands/finding-trend-alert.js.map +1 -0
  21. package/dist/commands/review-ai-feedback-loop.d.ts +2 -0
  22. package/dist/commands/review-ai-feedback-loop.d.ts.map +1 -0
  23. package/dist/commands/review-ai-feedback-loop.js +117 -0
  24. package/dist/commands/review-ai-feedback-loop.js.map +1 -0
  25. package/dist/commands/review-ci-insight.d.ts +2 -0
  26. package/dist/commands/review-ci-insight.d.ts.map +1 -0
  27. package/dist/commands/review-ci-insight.js +101 -0
  28. package/dist/commands/review-ci-insight.js.map +1 -0
  29. package/dist/commands/review-confidence-explain.d.ts +2 -0
  30. package/dist/commands/review-confidence-explain.d.ts.map +1 -0
  31. package/dist/commands/review-confidence-explain.js +100 -0
  32. package/dist/commands/review-confidence-explain.js.map +1 -0
  33. package/dist/commands/review-scope-suggest.d.ts +2 -0
  34. package/dist/commands/review-scope-suggest.d.ts.map +1 -0
  35. package/dist/commands/review-scope-suggest.js +113 -0
  36. package/dist/commands/review-scope-suggest.js.map +1 -0
  37. package/dist/commands/review-workload-balance.d.ts +2 -0
  38. package/dist/commands/review-workload-balance.d.ts.map +1 -0
  39. package/dist/commands/review-workload-balance.js +87 -0
  40. package/dist/commands/review-workload-balance.js.map +1 -0
  41. package/package.json +1 -1
  42. package/server.json +2 -2
@@ -0,0 +1,101 @@
1
+ import { readFileSync, existsSync, readdirSync } from "fs";
2
+ import { join } from "path";
3
+ function analyzeCiData(verdicts) {
4
+ const insights = [];
5
+ if (verdicts.length === 0)
6
+ return insights;
7
+ const totalFindings = verdicts.reduce((sum, v) => sum + (v.findings?.length ?? 0), 0);
8
+ const avgFindings = totalFindings / verdicts.length;
9
+ const criticalTotal = verdicts.reduce((sum, v) => sum + (v.criticalCount ?? 0), 0);
10
+ const highTotal = verdicts.reduce((sum, v) => sum + (v.highCount ?? 0), 0);
11
+ const passRate = verdicts.filter((v) => v.overallVerdict === "pass").length / verdicts.length;
12
+ const scores = verdicts.map((v) => v.overallScore ?? 0);
13
+ const avgScore = scores.reduce((a, b) => a + b, 0) / scores.length;
14
+ const recentHalf = verdicts.slice(Math.floor(verdicts.length / 2));
15
+ const olderHalf = verdicts.slice(0, Math.floor(verdicts.length / 2));
16
+ const recentAvg = recentHalf.length > 0 ? recentHalf.reduce((s, v) => s + (v.overallScore ?? 0), 0) / recentHalf.length : 0;
17
+ const olderAvg = olderHalf.length > 0 ? olderHalf.reduce((s, v) => s + (v.overallScore ?? 0), 0) / olderHalf.length : 0;
18
+ const scoreTrend = recentAvg > olderAvg ? "improving" : recentAvg < olderAvg ? "declining" : "stable";
19
+ insights.push({
20
+ metric: "Average Findings per Review",
21
+ value: avgFindings.toFixed(1),
22
+ trend: avgFindings > 5 ? "high" : "normal",
23
+ recommendation: avgFindings > 5
24
+ ? "High finding density may slow CI — consider pre-commit hooks"
25
+ : "Finding density is manageable",
26
+ });
27
+ insights.push({
28
+ metric: "Review Pass Rate",
29
+ value: `${(passRate * 100).toFixed(1)}%`,
30
+ trend: passRate < 0.7 ? "concerning" : "healthy",
31
+ recommendation: passRate < 0.7 ? "Low pass rate — review coding guidelines or adjust thresholds" : "Pass rate is healthy",
32
+ });
33
+ insights.push({
34
+ metric: "Critical + High Findings",
35
+ value: `${criticalTotal + highTotal} total`,
36
+ trend: criticalTotal > 0 ? "attention" : "good",
37
+ recommendation: criticalTotal > 0 ? "Critical findings should block deployment" : "No critical findings — pipeline can proceed",
38
+ });
39
+ insights.push({
40
+ metric: "Quality Score Trend",
41
+ value: `${avgScore.toFixed(1)} avg`,
42
+ trend: scoreTrend,
43
+ recommendation: scoreTrend === "declining" ? "Quality declining — investigate recent changes" : "Quality trend is positive",
44
+ });
45
+ insights.push({
46
+ metric: "Reviews Analyzed",
47
+ value: `${verdicts.length}`,
48
+ trend: verdicts.length < 5 ? "limited data" : "sufficient",
49
+ recommendation: verdicts.length < 5 ? "Need more review runs for reliable insights" : "Sufficient data for trend analysis",
50
+ });
51
+ return insights;
52
+ }
53
+ export function runReviewCiInsight(argv) {
54
+ if (argv.includes("--help") || argv.includes("-h")) {
55
+ console.log(`Usage: judges review-ci-insight [options]
56
+
57
+ CI pipeline performance insights from review data.
58
+
59
+ Options:
60
+ --dir <path> Directory with verdict JSON files
61
+ --format <fmt> Output format: table (default) or json
62
+ -h, --help Show this help message`);
63
+ return;
64
+ }
65
+ const formatIdx = argv.indexOf("--format");
66
+ const format = formatIdx !== -1 && argv[formatIdx + 1] ? argv[formatIdx + 1] : "table";
67
+ const dirIdx = argv.indexOf("--dir");
68
+ const dirPath = dirIdx !== -1 && argv[dirIdx + 1]
69
+ ? join(process.cwd(), argv[dirIdx + 1])
70
+ : join(process.cwd(), ".judges", "history");
71
+ const verdicts = [];
72
+ if (existsSync(dirPath)) {
73
+ const files = readdirSync(dirPath).filter((f) => f.endsWith(".json")).sort();
74
+ for (const file of files) {
75
+ const content = JSON.parse(readFileSync(join(dirPath, file), "utf-8"));
76
+ verdicts.push(content);
77
+ }
78
+ }
79
+ const lastVerdict = join(process.cwd(), ".judges", "last-verdict.json");
80
+ if (existsSync(lastVerdict)) {
81
+ const data = JSON.parse(readFileSync(lastVerdict, "utf-8"));
82
+ verdicts.push(data);
83
+ }
84
+ if (verdicts.length === 0) {
85
+ console.log("No verdict data found. Run reviews first or provide --dir.");
86
+ return;
87
+ }
88
+ const insights = analyzeCiData(verdicts);
89
+ if (format === "json") {
90
+ console.log(JSON.stringify(insights, null, 2));
91
+ return;
92
+ }
93
+ console.log("\n=== CI Pipeline Insights ===\n");
94
+ console.log(`Data points: ${verdicts.length} review(s)\n`);
95
+ for (const insight of insights) {
96
+ console.log(`${insight.metric}: ${insight.value} [${insight.trend}]`);
97
+ console.log(` → ${insight.recommendation}`);
98
+ console.log();
99
+ }
100
+ }
101
+ //# sourceMappingURL=review-ci-insight.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-ci-insight.js","sourceRoot":"","sources":["../../src/commands/review-ci-insight.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runReviewConfidenceExplain(argv: string[]): void;
2
+ //# sourceMappingURL=review-confidence-explain.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-confidence-explain.d.ts","sourceRoot":"","sources":["../../src/commands/review-confidence-explain.ts"],"names":[],"mappings":"AAoEA,wBAAgB,0BAA0B,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA8D/D"}
@@ -0,0 +1,100 @@
1
+ import { readFileSync, existsSync } from "fs";
2
+ import { join } from "path";
3
+ function explainConfidence(findings) {
4
+ const explanations = [];
5
+ for (const f of findings) {
6
+ const factors = [];
7
+ const conf = f.confidence ?? 0.5;
8
+ if (conf >= 0.9) {
9
+ factors.push("High pattern match confidence");
10
+ factors.push("Strong structural evidence");
11
+ }
12
+ else if (conf >= 0.7) {
13
+ factors.push("Moderate pattern match");
14
+ factors.push("Partial structural evidence");
15
+ }
16
+ else {
17
+ factors.push("Low pattern match — heuristic-based");
18
+ factors.push("Limited structural evidence");
19
+ }
20
+ if (f.evidenceBasis !== undefined && f.evidenceBasis !== null) {
21
+ factors.push(`Evidence basis: ${f.evidenceBasis}`);
22
+ }
23
+ if (f.isAbsenceBased === true) {
24
+ factors.push("Absence-based detection (missing safeguard)");
25
+ }
26
+ if (f.lineNumbers !== undefined && f.lineNumbers.length > 0) {
27
+ factors.push(`Pinpointed to ${f.lineNumbers.length} line(s)`);
28
+ }
29
+ if (f.patch !== undefined && f.patch !== null) {
30
+ factors.push("Auto-fix patch available");
31
+ }
32
+ const tier = f.confidenceTier ?? (conf >= 0.9 ? "high" : conf >= 0.7 ? "medium" : "low");
33
+ explanations.push({
34
+ finding: f.ruleId,
35
+ confidence: conf,
36
+ tier,
37
+ factors,
38
+ evidenceBasis: f.evidenceBasis ?? "pattern-match",
39
+ recommendation: conf < 0.7 ? "Manual verification recommended" : "Confidence level supports automated action",
40
+ });
41
+ }
42
+ return explanations;
43
+ }
44
+ export function runReviewConfidenceExplain(argv) {
45
+ if (argv.includes("--help") || argv.includes("-h")) {
46
+ console.log(`Usage: judges review-confidence-explain [options]
47
+
48
+ Explain verdict confidence levels and contributing factors.
49
+
50
+ Options:
51
+ --report <path> Path to a tribunal verdict JSON file
52
+ --format <fmt> Output format: table (default) or json
53
+ -h, --help Show this help message`);
54
+ return;
55
+ }
56
+ const formatIdx = argv.indexOf("--format");
57
+ const format = formatIdx !== -1 && argv[formatIdx + 1] ? argv[formatIdx + 1] : "table";
58
+ const reportIdx = argv.indexOf("--report");
59
+ const reportPath = reportIdx !== -1 && argv[reportIdx + 1] ? argv[reportIdx + 1] : null;
60
+ let findings = [];
61
+ if (reportPath !== null) {
62
+ const resolved = join(process.cwd(), reportPath);
63
+ if (!existsSync(resolved)) {
64
+ console.error(`Report not found: ${resolved}`);
65
+ process.exitCode = 1;
66
+ return;
67
+ }
68
+ const data = JSON.parse(readFileSync(resolved, "utf-8"));
69
+ findings = data.findings ?? [];
70
+ }
71
+ else {
72
+ const defaultPath = join(process.cwd(), ".judges", "last-verdict.json");
73
+ if (existsSync(defaultPath)) {
74
+ const data = JSON.parse(readFileSync(defaultPath, "utf-8"));
75
+ findings = data.findings ?? [];
76
+ }
77
+ }
78
+ if (findings.length === 0) {
79
+ console.log("No findings to explain. Provide --report or run a review first.");
80
+ return;
81
+ }
82
+ const explanations = explainConfidence(findings);
83
+ if (format === "json") {
84
+ console.log(JSON.stringify(explanations, null, 2));
85
+ return;
86
+ }
87
+ console.log("\n=== Confidence Explanations ===\n");
88
+ for (const ex of explanations) {
89
+ console.log(`Finding: ${ex.finding}`);
90
+ console.log(` Confidence: ${(ex.confidence * 100).toFixed(0)}% (${ex.tier})`);
91
+ console.log(` Evidence: ${ex.evidenceBasis}`);
92
+ console.log(` Factors:`);
93
+ for (const factor of ex.factors) {
94
+ console.log(` - ${factor}`);
95
+ }
96
+ console.log(` ${ex.recommendation}`);
97
+ console.log();
98
+ }
99
+ }
100
+ //# sourceMappingURL=review-confidence-explain.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-confidence-explain.js","sourceRoot":"","sources":["../../src/commands/review-confidence-explain.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runReviewScopeSuggest(argv: string[]): void;
2
+ //# sourceMappingURL=review-scope-suggest.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-scope-suggest.d.ts","sourceRoot":"","sources":["../../src/commands/review-scope-suggest.ts"],"names":[],"mappings":"AAiEA,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA0E1D"}
@@ -0,0 +1,113 @@
1
+ import { readFileSync, existsSync, readdirSync } from "fs";
2
+ import { join } from "path";
3
+ function suggestScope(files, historicalFindings) {
4
+ const suggestions = [];
5
+ const findingsByTitle = new Map();
6
+ for (const f of historicalFindings) {
7
+ const key = f.title.toLowerCase();
8
+ for (const file of files) {
9
+ if (key.includes(file.toLowerCase()) || file.toLowerCase().includes(key.split(" ")[0])) {
10
+ findingsByTitle.set(file, (findingsByTitle.get(file) ?? 0) + 1);
11
+ }
12
+ }
13
+ }
14
+ for (const file of files) {
15
+ const density = findingsByTitle.get(file) ?? 0;
16
+ const ext = file.split(".").pop() ?? "";
17
+ const securityExts = ["ts", "js", "py", "java", "go", "rs", "cs"];
18
+ const configExts = ["yml", "yaml", "json", "toml", "env"];
19
+ let priority;
20
+ let reason;
21
+ if (density > 3) {
22
+ priority = "critical";
23
+ reason = `High historical finding density (${density})`;
24
+ }
25
+ else if (securityExts.includes(ext)) {
26
+ priority = "high";
27
+ reason = "Source code — security-relevant";
28
+ }
29
+ else if (configExts.includes(ext)) {
30
+ priority = "medium";
31
+ reason = "Configuration file — check for secrets/misconfig";
32
+ }
33
+ else {
34
+ priority = "low";
35
+ reason = "Low-risk file type";
36
+ }
37
+ suggestions.push({ file, priority, reason, findingDensity: density });
38
+ }
39
+ suggestions.sort((a, b) => {
40
+ const order = { critical: 0, high: 1, medium: 2, low: 3 };
41
+ return (order[a.priority] ?? 4) - (order[b.priority] ?? 4);
42
+ });
43
+ return suggestions;
44
+ }
45
+ export function runReviewScopeSuggest(argv) {
46
+ if (argv.includes("--help") || argv.includes("-h")) {
47
+ console.log(`Usage: judges review-scope-suggest [options]
48
+
49
+ Suggest optimal review scope for a set of changed files.
50
+
51
+ Options:
52
+ --files <path> File listing changed files (one per line)
53
+ --history <path> Path to historical verdict JSON for density analysis
54
+ --format <fmt> Output format: table (default) or json
55
+ -h, --help Show this help message`);
56
+ return;
57
+ }
58
+ const formatIdx = argv.indexOf("--format");
59
+ const format = formatIdx !== -1 && argv[formatIdx + 1] ? argv[formatIdx + 1] : "table";
60
+ const filesIdx = argv.indexOf("--files");
61
+ const filesPath = filesIdx !== -1 && argv[filesIdx + 1] ? join(process.cwd(), argv[filesIdx + 1]) : null;
62
+ let changedFiles = [];
63
+ if (filesPath !== null && existsSync(filesPath)) {
64
+ changedFiles = readFileSync(filesPath, "utf-8")
65
+ .split("\n")
66
+ .map((l) => l.trim())
67
+ .filter((l) => l.length > 0);
68
+ }
69
+ else {
70
+ const gitDir = join(process.cwd(), ".git");
71
+ if (existsSync(gitDir)) {
72
+ const reportsDir = join(process.cwd(), ".judges", "reports");
73
+ if (existsSync(reportsDir)) {
74
+ changedFiles = readdirSync(reportsDir).filter((f) => f.endsWith(".json"));
75
+ }
76
+ }
77
+ }
78
+ if (changedFiles.length === 0) {
79
+ console.log("No changed files found. Provide --files or ensure .judges/reports/ exists.");
80
+ return;
81
+ }
82
+ let historicalFindings = [];
83
+ const historyIdx = argv.indexOf("--history");
84
+ if (historyIdx !== -1 && argv[historyIdx + 1]) {
85
+ const histPath = join(process.cwd(), argv[historyIdx + 1]);
86
+ if (existsSync(histPath)) {
87
+ const data = JSON.parse(readFileSync(histPath, "utf-8"));
88
+ historicalFindings = data.findings ?? [];
89
+ }
90
+ }
91
+ else {
92
+ const defaultHist = join(process.cwd(), ".judges", "last-verdict.json");
93
+ if (existsSync(defaultHist)) {
94
+ const data = JSON.parse(readFileSync(defaultHist, "utf-8"));
95
+ historicalFindings = data.findings ?? [];
96
+ }
97
+ }
98
+ const suggestions = suggestScope(changedFiles, historicalFindings);
99
+ if (format === "json") {
100
+ console.log(JSON.stringify(suggestions, null, 2));
101
+ return;
102
+ }
103
+ console.log("\n=== Review Scope Suggestions ===\n");
104
+ console.log(`Files analyzed: ${changedFiles.length}\n`);
105
+ for (const s of suggestions) {
106
+ console.log(`[${s.priority.toUpperCase()}] ${s.file}`);
107
+ console.log(` Reason: ${s.reason}`);
108
+ if (s.findingDensity > 0) {
109
+ console.log(` Historical findings: ${s.findingDensity}`);
110
+ }
111
+ }
112
+ }
113
+ //# sourceMappingURL=review-scope-suggest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-scope-suggest.js","sourceRoot":"","sources":["../../src/commands/review-scope-suggest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runReviewWorkloadBalance(argv: string[]): void;
2
+ //# sourceMappingURL=review-workload-balance.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-workload-balance.d.ts","sourceRoot":"","sources":["../../src/commands/review-workload-balance.ts"],"names":[],"mappings":"AA8DA,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAmE7D"}
@@ -0,0 +1,87 @@
1
+ import { readFileSync, existsSync } from "fs";
2
+ import { join } from "path";
3
+ function computeWorkload(config) {
4
+ const loads = [];
5
+ for (const reviewer of config.reviewers) {
6
+ const assigned = reviewer.assignedReviews ?? 0;
7
+ const findings = reviewer.findingsHandled ?? 0;
8
+ const capacity = reviewer.capacity ?? 10;
9
+ const loadScore = capacity > 0 ? assigned / capacity : 1;
10
+ let recommendation;
11
+ if (loadScore > 0.9) {
12
+ recommendation = "Overloaded — reassign pending reviews";
13
+ }
14
+ else if (loadScore > 0.7) {
15
+ recommendation = "Heavy load — limit new assignments";
16
+ }
17
+ else if (loadScore < 0.3) {
18
+ recommendation = "Available — can take more reviews";
19
+ }
20
+ else {
21
+ recommendation = "Balanced";
22
+ }
23
+ loads.push({
24
+ reviewer: reviewer.name,
25
+ assignedReviews: assigned,
26
+ findingsHandled: findings,
27
+ lastActive: reviewer.lastActive ?? "unknown",
28
+ loadScore,
29
+ recommendation,
30
+ });
31
+ }
32
+ loads.sort((a, b) => a.loadScore - b.loadScore);
33
+ return loads;
34
+ }
35
+ export function runReviewWorkloadBalance(argv) {
36
+ if (argv.includes("--help") || argv.includes("-h")) {
37
+ console.log(`Usage: judges review-workload-balance [options]
38
+
39
+ Analyze and balance reviewer workload across team members.
40
+
41
+ Options:
42
+ --config <path> Path to team config JSON file
43
+ --format <fmt> Output format: table (default) or json
44
+ -h, --help Show this help message`);
45
+ return;
46
+ }
47
+ const formatIdx = argv.indexOf("--format");
48
+ const format = formatIdx !== -1 && argv[formatIdx + 1] ? argv[formatIdx + 1] : "table";
49
+ const configIdx = argv.indexOf("--config");
50
+ const configPath = configIdx !== -1 && argv[configIdx + 1]
51
+ ? join(process.cwd(), argv[configIdx + 1])
52
+ : join(process.cwd(), ".judges", "team-workload.json");
53
+ if (!existsSync(configPath)) {
54
+ console.log(`No team config found at: ${configPath}`);
55
+ console.log("Create .judges/team-workload.json with reviewer data.");
56
+ console.log("\nExample:");
57
+ console.log(JSON.stringify({
58
+ reviewers: [
59
+ { name: "alice", assignedReviews: 5, findingsHandled: 23, capacity: 10, lastActive: "2026-03-14" },
60
+ { name: "bob", assignedReviews: 2, findingsHandled: 8, capacity: 8, lastActive: "2026-03-13" },
61
+ ],
62
+ }, null, 2));
63
+ return;
64
+ }
65
+ const config = JSON.parse(readFileSync(configPath, "utf-8"));
66
+ if (!config.reviewers || config.reviewers.length === 0) {
67
+ console.log("No reviewers defined in config.");
68
+ return;
69
+ }
70
+ const loads = computeWorkload(config);
71
+ if (format === "json") {
72
+ console.log(JSON.stringify(loads, null, 2));
73
+ return;
74
+ }
75
+ console.log("\n=== Review Workload Balance ===\n");
76
+ console.log(`Team size: ${loads.length}\n`);
77
+ for (const load of loads) {
78
+ const bar = "█".repeat(Math.round(load.loadScore * 10)) + "░".repeat(10 - Math.round(load.loadScore * 10));
79
+ console.log(`${load.reviewer}`);
80
+ console.log(` Load: [${bar}] ${(load.loadScore * 100).toFixed(0)}%`);
81
+ console.log(` Reviews: ${load.assignedReviews} | Findings: ${load.findingsHandled}`);
82
+ console.log(` Last active: ${load.lastActive}`);
83
+ console.log(` → ${load.recommendation}`);
84
+ console.log();
85
+ }
86
+ }
87
+ //# sourceMappingURL=review-workload-balance.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-workload-balance.js","sourceRoot":"","sources":["../../src/commands/review-workload-balance.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.102.0",
3
+ "version": "3.103.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.102.0",
10
+ "version": "3.103.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "@kevinrabun/judges",
15
- "version": "3.102.0",
15
+ "version": "3.103.0",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }