@kevinrabun/judges 3.110.0 → 3.111.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-auto-priority.d.ts +2 -0
  6. package/dist/commands/finding-auto-priority.d.ts.map +1 -0
  7. package/dist/commands/finding-auto-priority.js +101 -0
  8. package/dist/commands/finding-auto-priority.js.map +1 -0
  9. package/dist/commands/finding-cluster-summary.d.ts +2 -0
  10. package/dist/commands/finding-cluster-summary.d.ts.map +1 -0
  11. package/dist/commands/finding-cluster-summary.js +86 -0
  12. package/dist/commands/finding-cluster-summary.js.map +1 -0
  13. package/dist/commands/finding-context-link.d.ts +2 -0
  14. package/dist/commands/finding-context-link.d.ts.map +1 -0
  15. package/dist/commands/finding-context-link.js +95 -0
  16. package/dist/commands/finding-context-link.js.map +1 -0
  17. package/dist/commands/finding-dependency-impact.d.ts +2 -0
  18. package/dist/commands/finding-dependency-impact.d.ts.map +1 -0
  19. package/dist/commands/finding-dependency-impact.js +98 -0
  20. package/dist/commands/finding-dependency-impact.js.map +1 -0
  21. package/dist/commands/finding-resolution-workflow.d.ts +2 -0
  22. package/dist/commands/finding-resolution-workflow.d.ts.map +1 -0
  23. package/dist/commands/finding-resolution-workflow.js +92 -0
  24. package/dist/commands/finding-resolution-workflow.js.map +1 -0
  25. package/dist/commands/review-mentor-suggest.d.ts +2 -0
  26. package/dist/commands/review-mentor-suggest.d.ts.map +1 -0
  27. package/dist/commands/review-mentor-suggest.js +113 -0
  28. package/dist/commands/review-mentor-suggest.js.map +1 -0
  29. package/dist/commands/review-quality-baseline.d.ts +2 -0
  30. package/dist/commands/review-quality-baseline.d.ts.map +1 -0
  31. package/dist/commands/review-quality-baseline.js +135 -0
  32. package/dist/commands/review-quality-baseline.js.map +1 -0
  33. package/dist/commands/review-retrospective.d.ts +2 -0
  34. package/dist/commands/review-retrospective.d.ts.map +1 -0
  35. package/dist/commands/review-retrospective.js +119 -0
  36. package/dist/commands/review-retrospective.js.map +1 -0
  37. package/dist/commands/review-team-velocity.d.ts +2 -0
  38. package/dist/commands/review-team-velocity.d.ts.map +1 -0
  39. package/dist/commands/review-team-velocity.js +104 -0
  40. package/dist/commands/review-team-velocity.js.map +1 -0
  41. package/package.json +1 -1
  42. package/server.json +2 -2
@@ -0,0 +1,113 @@
1
+ import { readFileSync, existsSync, readdirSync } from "fs";
2
+ import { join } from "path";
3
+ function extractDomain(ruleId) {
4
+ const parts = ruleId.split("/");
5
+ return parts.length > 1 ? parts[0] : "general";
6
+ }
7
+ function buildProfiles(historyDir) {
8
+ if (!existsSync(historyDir))
9
+ return [];
10
+ const files = readdirSync(historyDir);
11
+ const jsonFiles = files.filter((f) => String(f).endsWith(".json"));
12
+ const domainScores = {};
13
+ for (const file of jsonFiles) {
14
+ const raw = readFileSync(join(historyDir, String(file)), "utf-8");
15
+ let verdict;
16
+ try {
17
+ verdict = JSON.parse(raw);
18
+ }
19
+ catch {
20
+ continue;
21
+ }
22
+ const reviewer = String(file)
23
+ .replace(/\.json$/, "")
24
+ .replace(/[-_]\d+$/, "");
25
+ if (!domainScores[reviewer])
26
+ domainScores[reviewer] = {};
27
+ const domainCounts = {};
28
+ for (const f of verdict.findings ?? []) {
29
+ const domain = extractDomain(f.ruleId);
30
+ domainCounts[domain] = (domainCounts[domain] ?? 0) + 1;
31
+ }
32
+ for (const domain of Object.keys(domainCounts)) {
33
+ if (!domainScores[reviewer][domain]) {
34
+ domainScores[reviewer][domain] = { total: 0, findings: 0 };
35
+ }
36
+ domainScores[reviewer][domain].total += 1;
37
+ domainScores[reviewer][domain].findings += domainCounts[domain];
38
+ }
39
+ }
40
+ const profiles = [];
41
+ for (const [reviewer, domains] of Object.entries(domainScores)) {
42
+ const strengths = [];
43
+ const weaknesses = [];
44
+ for (const [domain, stats] of Object.entries(domains)) {
45
+ const avgFindings = stats.findings / stats.total;
46
+ if (avgFindings <= 1) {
47
+ strengths.push(domain);
48
+ }
49
+ else if (avgFindings >= 3) {
50
+ weaknesses.push(domain);
51
+ }
52
+ }
53
+ profiles.push({ reviewer, strengths, weaknesses });
54
+ }
55
+ return profiles;
56
+ }
57
+ function suggestPairings(profiles) {
58
+ const pairings = [];
59
+ for (const mentee of profiles) {
60
+ for (const weakness of mentee.weaknesses) {
61
+ const mentor = profiles.find((p) => p.reviewer !== mentee.reviewer && p.strengths.includes(weakness));
62
+ if (mentor) {
63
+ pairings.push({
64
+ mentee: mentee.reviewer,
65
+ mentor: mentor.reviewer,
66
+ domain: weakness,
67
+ reason: `${mentor.reviewer} shows strength in "${weakness}" where ${mentee.reviewer} has frequent findings`,
68
+ });
69
+ }
70
+ }
71
+ }
72
+ return pairings;
73
+ }
74
+ export function runReviewMentorSuggest(argv) {
75
+ if (argv.includes("--help") || argv.includes("-h")) {
76
+ console.log(`Usage: judges review-mentor-suggest [options]
77
+
78
+ Suggest mentor pairings based on expertise gaps in review history.
79
+
80
+ Options:
81
+ --history <dir> Directory with verdict JSON files (default: .judges/history)
82
+ --format <fmt> Output format: table (default) or json
83
+ -h, --help Show this help message`);
84
+ return;
85
+ }
86
+ const formatIdx = argv.indexOf("--format");
87
+ const format = formatIdx !== -1 && argv[formatIdx + 1] ? argv[formatIdx + 1] : "table";
88
+ const histIdx = argv.indexOf("--history");
89
+ const historyDir = histIdx !== -1 && argv[histIdx + 1]
90
+ ? join(process.cwd(), argv[histIdx + 1])
91
+ : join(process.cwd(), ".judges", "history");
92
+ const profiles = buildProfiles(historyDir);
93
+ if (profiles.length === 0) {
94
+ console.log("No reviewer profiles found. Run some reviews first.");
95
+ return;
96
+ }
97
+ const pairings = suggestPairings(profiles);
98
+ if (format === "json") {
99
+ console.log(JSON.stringify({ profiles, pairings }, null, 2));
100
+ return;
101
+ }
102
+ console.log(`\n=== Mentor Suggestions (${pairings.length} pairings) ===\n`);
103
+ if (pairings.length === 0) {
104
+ console.log("No clear mentor pairings identified — team expertise is well-distributed.");
105
+ return;
106
+ }
107
+ for (const p of pairings) {
108
+ console.log(` ${p.mentee} <-- ${p.mentor} (domain: ${p.domain})`);
109
+ console.log(` ${p.reason}`);
110
+ console.log();
111
+ }
112
+ }
113
+ //# sourceMappingURL=review-mentor-suggest.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-mentor-suggest.js","sourceRoot":"","sources":["../../src/commands/review-mentor-suggest.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runReviewQualityBaseline(argv: string[]): void;
2
+ //# sourceMappingURL=review-quality-baseline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-quality-baseline.d.ts","sourceRoot":"","sources":["../../src/commands/review-quality-baseline.ts"],"names":[],"mappings":"AAoHA,wBAAgB,wBAAwB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAkE7D"}
@@ -0,0 +1,135 @@
1
+ import { readFileSync, existsSync, readdirSync } from "fs";
2
+ import { join } from "path";
3
+ function computeBaseline(historyDir) {
4
+ if (!existsSync(historyDir))
5
+ return undefined;
6
+ const files = readdirSync(historyDir)
7
+ .filter((f) => typeof f === "string" && f.endsWith(".json"))
8
+ .sort();
9
+ if (files.length === 0)
10
+ return undefined;
11
+ const scores = [];
12
+ const findingCounts = [];
13
+ const criticalCounts = [];
14
+ const highCounts = [];
15
+ let passes = 0;
16
+ for (const file of files) {
17
+ try {
18
+ const data = JSON.parse(readFileSync(join(historyDir, file), "utf-8"));
19
+ scores.push(data.overallScore ?? 0);
20
+ findingCounts.push((data.findings ?? []).length);
21
+ criticalCounts.push(data.criticalCount ?? 0);
22
+ highCounts.push(data.highCount ?? 0);
23
+ if (data.overallVerdict === "pass")
24
+ passes++;
25
+ }
26
+ catch {
27
+ // Skip
28
+ }
29
+ }
30
+ if (scores.length === 0)
31
+ return undefined;
32
+ const avg = (arr) => Math.round(arr.reduce((a, b) => a + b, 0) / arr.length);
33
+ return {
34
+ avgScore: avg(scores),
35
+ avgFindings: avg(findingCounts),
36
+ avgCritical: avg(criticalCounts),
37
+ avgHigh: avg(highCounts),
38
+ passRate: Math.round((passes / scores.length) * 100),
39
+ };
40
+ }
41
+ function compareToBaseline(baseline, current) {
42
+ const comparisons = [];
43
+ const curScore = current.overallScore ?? 0;
44
+ const curFindings = (current.findings ?? []).length;
45
+ const curCritical = current.criticalCount ?? 0;
46
+ const curHigh = current.highCount ?? 0;
47
+ function status(delta, higherIsBetter) {
48
+ if (delta === 0)
49
+ return "On baseline";
50
+ if (higherIsBetter)
51
+ return delta > 0 ? "Above baseline" : "Below baseline";
52
+ return delta < 0 ? "Better than baseline" : "Worse than baseline";
53
+ }
54
+ comparisons.push({
55
+ metric: "Score",
56
+ baseline: baseline.avgScore,
57
+ current: curScore,
58
+ delta: curScore - baseline.avgScore,
59
+ status: status(curScore - baseline.avgScore, true),
60
+ });
61
+ comparisons.push({
62
+ metric: "Findings",
63
+ baseline: baseline.avgFindings,
64
+ current: curFindings,
65
+ delta: curFindings - baseline.avgFindings,
66
+ status: status(curFindings - baseline.avgFindings, false),
67
+ });
68
+ comparisons.push({
69
+ metric: "Critical",
70
+ baseline: baseline.avgCritical,
71
+ current: curCritical,
72
+ delta: curCritical - baseline.avgCritical,
73
+ status: status(curCritical - baseline.avgCritical, false),
74
+ });
75
+ comparisons.push({
76
+ metric: "High",
77
+ baseline: baseline.avgHigh,
78
+ current: curHigh,
79
+ delta: curHigh - baseline.avgHigh,
80
+ status: status(curHigh - baseline.avgHigh, false),
81
+ });
82
+ return comparisons;
83
+ }
84
+ export function runReviewQualityBaseline(argv) {
85
+ if (argv.includes("--help") || argv.includes("-h")) {
86
+ console.log(`Usage: judges review-quality-baseline [options]
87
+
88
+ Compare current review against quality baseline.
89
+
90
+ Options:
91
+ --report <path> Path to current verdict JSON
92
+ --history <path> Path to review history directory
93
+ --format <fmt> Output format: table (default) or json
94
+ -h, --help Show this help message`);
95
+ return;
96
+ }
97
+ const formatIdx = argv.indexOf("--format");
98
+ const format = formatIdx !== -1 && argv[formatIdx + 1] ? argv[formatIdx + 1] : "table";
99
+ const reportIdx = argv.indexOf("--report");
100
+ const reportPath = reportIdx !== -1 && argv[reportIdx + 1]
101
+ ? join(process.cwd(), argv[reportIdx + 1])
102
+ : join(process.cwd(), ".judges", "last-verdict.json");
103
+ const histIdx = argv.indexOf("--history");
104
+ const historyDir = histIdx !== -1 && argv[histIdx + 1]
105
+ ? join(process.cwd(), argv[histIdx + 1])
106
+ : join(process.cwd(), ".judges", "history");
107
+ const baseline = computeBaseline(historyDir);
108
+ if (baseline === undefined) {
109
+ console.log("No review history to compute baseline. Run more reviews first.");
110
+ return;
111
+ }
112
+ if (!existsSync(reportPath)) {
113
+ console.log(`No report found at: ${reportPath}`);
114
+ return;
115
+ }
116
+ const current = JSON.parse(readFileSync(reportPath, "utf-8"));
117
+ const comparisons = compareToBaseline(baseline, current);
118
+ if (format === "json") {
119
+ console.log(JSON.stringify({ baseline, comparisons }, null, 2));
120
+ return;
121
+ }
122
+ console.log(`\n=== Quality Baseline Comparison ===\n`);
123
+ console.log(" " + "Metric".padEnd(12) + "Baseline".padEnd(12) + "Current".padEnd(12) + "Delta".padEnd(10) + "Status");
124
+ console.log(" " + "-".repeat(55));
125
+ for (const c of comparisons) {
126
+ const deltaStr = c.delta >= 0 ? `+${c.delta}` : String(c.delta);
127
+ console.log(" " +
128
+ c.metric.padEnd(12) +
129
+ String(c.baseline).padEnd(12) +
130
+ String(c.current).padEnd(12) +
131
+ deltaStr.padEnd(10) +
132
+ c.status);
133
+ }
134
+ }
135
+ //# sourceMappingURL=review-quality-baseline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-quality-baseline.js","sourceRoot":"","sources":["../../src/commands/review-quality-baseline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runReviewRetrospective(argv: string[]): void;
2
+ //# sourceMappingURL=review-retrospective.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-retrospective.d.ts","sourceRoot":"","sources":["../../src/commands/review-retrospective.ts"],"names":[],"mappings":"AA0GA,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA2C3D"}
@@ -0,0 +1,119 @@
1
+ import { readFileSync, existsSync, readdirSync } from "fs";
2
+ import { join } from "path";
3
+ function generateRetro(historyDir) {
4
+ const empty = {
5
+ period: "No data",
6
+ reviewCount: 0,
7
+ sections: [],
8
+ };
9
+ if (!existsSync(historyDir))
10
+ return empty;
11
+ const files = readdirSync(historyDir)
12
+ .filter((f) => typeof f === "string" && f.endsWith(".json"))
13
+ .sort();
14
+ if (files.length === 0)
15
+ return empty;
16
+ const verdicts = [];
17
+ for (const file of files) {
18
+ try {
19
+ verdicts.push(JSON.parse(readFileSync(join(historyDir, file), "utf-8")));
20
+ }
21
+ catch {
22
+ // Skip
23
+ }
24
+ }
25
+ if (verdicts.length === 0)
26
+ return empty;
27
+ const scores = verdicts.map((v) => v.overallScore ?? 0);
28
+ const avgScore = Math.round(scores.reduce((a, b) => a + b, 0) / scores.length);
29
+ const passes = verdicts.filter((v) => v.overallVerdict === "pass").length;
30
+ const passRate = Math.round((passes / verdicts.length) * 100);
31
+ // Score trend
32
+ const mid = Math.floor(scores.length / 2) || 1;
33
+ const firstAvg = scores.slice(0, mid).reduce((a, b) => a + b, 0) / mid;
34
+ const secondAvg = scores.slice(mid).reduce((a, b) => a + b, 0) / (scores.length - mid);
35
+ const improving = secondAvg >= firstAvg;
36
+ // Most common rules
37
+ const ruleFreq = new Map();
38
+ for (const v of verdicts) {
39
+ for (const f of v.findings ?? []) {
40
+ ruleFreq.set(f.ruleId, (ruleFreq.get(f.ruleId) ?? 0) + 1);
41
+ }
42
+ }
43
+ const topRules = [...ruleFreq.entries()].sort((a, b) => b[1] - a[1]).slice(0, 5);
44
+ // Build sections
45
+ const wentWell = [];
46
+ const needsImprovement = [];
47
+ const actionItems = [];
48
+ if (passRate >= 80)
49
+ wentWell.push(`High pass rate: ${passRate}%`);
50
+ else
51
+ needsImprovement.push(`Pass rate below threshold: ${passRate}%`);
52
+ if (improving)
53
+ wentWell.push(`Scores trending upward (${Math.round(firstAvg)} → ${Math.round(secondAvg)})`);
54
+ else
55
+ needsImprovement.push(`Scores trending downward (${Math.round(firstAvg)} → ${Math.round(secondAvg)})`);
56
+ if (avgScore >= 70)
57
+ wentWell.push(`Good average score: ${avgScore}/100`);
58
+ else
59
+ needsImprovement.push(`Average score needs work: ${avgScore}/100`);
60
+ if (topRules.length > 0) {
61
+ needsImprovement.push(`Most recurring rules: ${topRules.map(([r, c]) => `${r} (${c}x)`).join(", ")}`);
62
+ actionItems.push(`Address top recurring rule: ${topRules[0][0]}`);
63
+ }
64
+ if (!improving)
65
+ actionItems.push("Investigate declining score trend");
66
+ if (passRate < 80)
67
+ actionItems.push("Focus on reducing critical/high findings to improve pass rate");
68
+ actionItems.push("Review and update severity thresholds if too noisy");
69
+ const sections = [
70
+ { category: "What Went Well", items: wentWell },
71
+ { category: "Needs Improvement", items: needsImprovement },
72
+ { category: "Action Items", items: actionItems },
73
+ ];
74
+ const firstDate = verdicts[0].timestamp ?? "unknown";
75
+ const lastDate = verdicts[verdicts.length - 1].timestamp ?? "unknown";
76
+ return {
77
+ period: `${firstDate.slice(0, 10)} to ${lastDate.slice(0, 10)}`,
78
+ reviewCount: verdicts.length,
79
+ sections,
80
+ };
81
+ }
82
+ export function runReviewRetrospective(argv) {
83
+ if (argv.includes("--help") || argv.includes("-h")) {
84
+ console.log(`Usage: judges review-retrospective [options]
85
+
86
+ Generate review retrospective summary.
87
+
88
+ Options:
89
+ --history <path> Path to review history directory
90
+ --format <fmt> Output format: table (default) or json
91
+ -h, --help Show this help message`);
92
+ return;
93
+ }
94
+ const formatIdx = argv.indexOf("--format");
95
+ const format = formatIdx !== -1 && argv[formatIdx + 1] ? argv[formatIdx + 1] : "table";
96
+ const histIdx = argv.indexOf("--history");
97
+ const historyDir = histIdx !== -1 && argv[histIdx + 1]
98
+ ? join(process.cwd(), argv[histIdx + 1])
99
+ : join(process.cwd(), ".judges", "history");
100
+ const retro = generateRetro(historyDir);
101
+ if (format === "json") {
102
+ console.log(JSON.stringify(retro, null, 2));
103
+ return;
104
+ }
105
+ console.log(`\n=== Review Retrospective ===`);
106
+ console.log(` Period: ${retro.period}`);
107
+ console.log(` Reviews: ${retro.reviewCount}\n`);
108
+ for (const section of retro.sections) {
109
+ console.log(` ${section.category}:`);
110
+ if (section.items.length === 0) {
111
+ console.log(" (none)");
112
+ }
113
+ for (const item of section.items) {
114
+ console.log(` • ${item}`);
115
+ }
116
+ console.log();
117
+ }
118
+ }
119
+ //# sourceMappingURL=review-retrospective.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-retrospective.js","sourceRoot":"","sources":["../../src/commands/review-retrospective.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export declare function runReviewTeamVelocity(argv: string[]): void;
2
+ //# sourceMappingURL=review-team-velocity.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-team-velocity.d.ts","sourceRoot":"","sources":["../../src/commands/review-team-velocity.ts"],"names":[],"mappings":"AA2FA,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAsD1D"}
@@ -0,0 +1,104 @@
1
+ import { readFileSync, existsSync, readdirSync } from "fs";
2
+ import { join } from "path";
3
+ function computeVelocity(historyDir) {
4
+ const empty = {
5
+ totalReviews: 0,
6
+ periods: [],
7
+ avgReviewsPerPeriod: 0,
8
+ acceleration: "unknown",
9
+ };
10
+ if (!existsSync(historyDir))
11
+ return empty;
12
+ const files = readdirSync(historyDir)
13
+ .filter((f) => typeof f === "string" && f.endsWith(".json"))
14
+ .sort();
15
+ if (files.length === 0)
16
+ return empty;
17
+ // Group by month from timestamps
18
+ const monthMap = new Map();
19
+ for (const file of files) {
20
+ try {
21
+ const data = JSON.parse(readFileSync(join(historyDir, file), "utf-8"));
22
+ const ts = data.timestamp ?? file.replace(".json", "");
23
+ const month = ts.slice(0, 7) || "unknown";
24
+ const entry = monthMap.get(month) ?? { reviews: 0, findings: 0, scores: [], passes: 0 };
25
+ entry.reviews++;
26
+ entry.findings += (data.findings ?? []).length;
27
+ entry.scores.push(data.overallScore ?? 0);
28
+ if (data.overallVerdict === "pass")
29
+ entry.passes++;
30
+ monthMap.set(month, entry);
31
+ }
32
+ catch {
33
+ // Skip
34
+ }
35
+ }
36
+ const periods = [];
37
+ for (const [month, data] of monthMap) {
38
+ const avgScore = data.scores.length > 0 ? Math.round(data.scores.reduce((a, b) => a + b, 0) / data.scores.length) : 0;
39
+ periods.push({
40
+ period: month,
41
+ reviews: data.reviews,
42
+ findings: data.findings,
43
+ avgScore,
44
+ passRate: data.reviews > 0 ? Math.round((data.passes / data.reviews) * 100) : 0,
45
+ });
46
+ }
47
+ periods.sort((a, b) => a.period.localeCompare(b.period));
48
+ const totalReviews = periods.reduce((s, p) => s + p.reviews, 0);
49
+ const avgPerPeriod = periods.length > 0 ? Math.round(totalReviews / periods.length) : 0;
50
+ let acceleration = "stable";
51
+ if (periods.length >= 2) {
52
+ const firstHalf = periods.slice(0, Math.floor(periods.length / 2));
53
+ const secondHalf = periods.slice(Math.floor(periods.length / 2));
54
+ const firstAvg = firstHalf.reduce((s, p) => s + p.reviews, 0) / firstHalf.length;
55
+ const secondAvg = secondHalf.reduce((s, p) => s + p.reviews, 0) / secondHalf.length;
56
+ if (secondAvg > firstAvg * 1.1)
57
+ acceleration = "accelerating";
58
+ else if (secondAvg < firstAvg * 0.9)
59
+ acceleration = "decelerating";
60
+ }
61
+ return { totalReviews, periods, avgReviewsPerPeriod: avgPerPeriod, acceleration };
62
+ }
63
+ export function runReviewTeamVelocity(argv) {
64
+ if (argv.includes("--help") || argv.includes("-h")) {
65
+ console.log(`Usage: judges review-team-velocity [options]
66
+
67
+ Track team review velocity metrics.
68
+
69
+ Options:
70
+ --history <path> Path to review history directory
71
+ --format <fmt> Output format: table (default) or json
72
+ -h, --help Show this help message`);
73
+ return;
74
+ }
75
+ const formatIdx = argv.indexOf("--format");
76
+ const format = formatIdx !== -1 && argv[formatIdx + 1] ? argv[formatIdx + 1] : "table";
77
+ const histIdx = argv.indexOf("--history");
78
+ const historyDir = histIdx !== -1 && argv[histIdx + 1]
79
+ ? join(process.cwd(), argv[histIdx + 1])
80
+ : join(process.cwd(), ".judges", "history");
81
+ const report = computeVelocity(historyDir);
82
+ if (format === "json") {
83
+ console.log(JSON.stringify(report, null, 2));
84
+ return;
85
+ }
86
+ console.log(`\n=== Team Velocity (${report.totalReviews} reviews, ${report.acceleration}) ===\n`);
87
+ if (report.periods.length === 0) {
88
+ console.log("No review history found.");
89
+ return;
90
+ }
91
+ console.log(" " + "Period".padEnd(12) + "Reviews".padEnd(10) + "Findings".padEnd(10) + "Avg Score".padEnd(12) + "Pass Rate");
92
+ console.log(" " + "-".repeat(55));
93
+ for (const p of report.periods) {
94
+ console.log(" " +
95
+ p.period.padEnd(12) +
96
+ String(p.reviews).padEnd(10) +
97
+ String(p.findings).padEnd(10) +
98
+ String(p.avgScore).padEnd(12) +
99
+ `${p.passRate}%`);
100
+ }
101
+ console.log(`\n Avg Reviews/Period: ${report.avgReviewsPerPeriod}`);
102
+ console.log(` Trend: ${report.acceleration}`);
103
+ }
104
+ //# sourceMappingURL=review-team-velocity.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-team-velocity.js","sourceRoot":"","sources":["../../src/commands/review-team-velocity.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.110.0",
3
+ "version": "3.111.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.110.0",
10
+ "version": "3.111.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "@kevinrabun/judges",
15
- "version": "3.110.0",
15
+ "version": "3.111.0",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }