@kevinrabun/judges 3.72.0 → 3.73.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 (38) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +56 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/finding-false-positive.d.ts +5 -0
  6. package/dist/commands/finding-false-positive.d.ts.map +1 -0
  7. package/dist/commands/finding-false-positive.js +135 -0
  8. package/dist/commands/finding-false-positive.js.map +1 -0
  9. package/dist/commands/finding-link.d.ts +5 -0
  10. package/dist/commands/finding-link.d.ts.map +1 -0
  11. package/dist/commands/finding-link.js +129 -0
  12. package/dist/commands/finding-link.js.map +1 -0
  13. package/dist/commands/review-bulk-action.d.ts +5 -0
  14. package/dist/commands/review-bulk-action.d.ts.map +1 -0
  15. package/dist/commands/review-bulk-action.js +110 -0
  16. package/dist/commands/review-bulk-action.js.map +1 -0
  17. package/dist/commands/review-compare-version.d.ts +5 -0
  18. package/dist/commands/review-compare-version.d.ts.map +1 -0
  19. package/dist/commands/review-compare-version.js +109 -0
  20. package/dist/commands/review-compare-version.js.map +1 -0
  21. package/dist/commands/review-depth.d.ts +5 -0
  22. package/dist/commands/review-depth.d.ts.map +1 -0
  23. package/dist/commands/review-depth.js +143 -0
  24. package/dist/commands/review-depth.js.map +1 -0
  25. package/dist/commands/review-retry.d.ts +5 -0
  26. package/dist/commands/review-retry.d.ts.map +1 -0
  27. package/dist/commands/review-retry.js +92 -0
  28. package/dist/commands/review-retry.js.map +1 -0
  29. package/dist/commands/review-session.d.ts +5 -0
  30. package/dist/commands/review-session.d.ts.map +1 -0
  31. package/dist/commands/review-session.js +151 -0
  32. package/dist/commands/review-session.js.map +1 -0
  33. package/dist/commands/review-summary-email.d.ts +5 -0
  34. package/dist/commands/review-summary-email.d.ts.map +1 -0
  35. package/dist/commands/review-summary-email.js +103 -0
  36. package/dist/commands/review-summary-email.js.map +1 -0
  37. package/package.json +1 -1
  38. package/server.json +2 -2
@@ -0,0 +1,143 @@
1
+ /**
2
+ * Review-depth — Control review depth (shallow, normal, deep).
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
5
+ import { dirname } from "path";
6
+ // ─── Profiles ───────────────────────────────────────────────────────────────
7
+ const PROFILES = {
8
+ shallow: {
9
+ level: "shallow",
10
+ maxJudges: 5,
11
+ enableAST: false,
12
+ enableCrossFile: false,
13
+ description: "Quick scan — top security rules only",
14
+ },
15
+ normal: {
16
+ level: "normal",
17
+ maxJudges: 20,
18
+ enableAST: true,
19
+ enableCrossFile: false,
20
+ description: "Standard review — core judges with AST",
21
+ },
22
+ deep: {
23
+ level: "deep",
24
+ maxJudges: 45,
25
+ enableAST: true,
26
+ enableCrossFile: true,
27
+ description: "Full review — all judges, cross-file analysis",
28
+ },
29
+ };
30
+ // ─── Storage ────────────────────────────────────────────────────────────────
31
+ const DEPTH_FILE = ".judges/review-depth.json";
32
+ function loadConfig() {
33
+ if (!existsSync(DEPTH_FILE))
34
+ return { version: "1.0.0", currentLevel: "normal", perPath: {} };
35
+ try {
36
+ return JSON.parse(readFileSync(DEPTH_FILE, "utf-8"));
37
+ }
38
+ catch {
39
+ return { version: "1.0.0", currentLevel: "normal", perPath: {} };
40
+ }
41
+ }
42
+ function saveConfig(config) {
43
+ mkdirSync(dirname(DEPTH_FILE), { recursive: true });
44
+ writeFileSync(DEPTH_FILE, JSON.stringify(config, null, 2), "utf-8");
45
+ }
46
+ // ─── CLI ────────────────────────────────────────────────────────────────────
47
+ export function runReviewDepth(argv) {
48
+ if (argv.includes("--help") || argv.includes("-h")) {
49
+ console.log(`
50
+ judges review-depth — Control review depth
51
+
52
+ Usage:
53
+ judges review-depth Show current depth
54
+ judges review-depth set --level deep
55
+ judges review-depth set-path --path src/auth --level deep
56
+ judges review-depth profiles
57
+ judges review-depth reset
58
+
59
+ Subcommands:
60
+ (default) Show current depth setting
61
+ set Set global review depth
62
+ set-path Set depth for a specific path
63
+ profiles Show available depth profiles
64
+ reset Reset to default (normal)
65
+
66
+ Depth Levels:
67
+ shallow Quick scan — top security rules only
68
+ normal Standard review — core judges with AST
69
+ deep Full review — all judges, cross-file analysis
70
+
71
+ Options:
72
+ --level <level> Depth level: shallow, normal, deep
73
+ --path <path> File or directory path
74
+ --format json JSON output
75
+ --help, -h Show this help
76
+
77
+ Config stored in .judges/review-depth.json.
78
+ `);
79
+ return;
80
+ }
81
+ const subcommand = argv.find((a) => ["set", "set-path", "profiles", "reset"].includes(a));
82
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
83
+ const config = loadConfig();
84
+ if (subcommand === "set") {
85
+ const level = argv.find((_a, i) => argv[i - 1] === "--level");
86
+ if (!level || !PROFILES[level]) {
87
+ console.log("Invalid level. Use: shallow, normal, deep");
88
+ return;
89
+ }
90
+ config.currentLevel = level;
91
+ saveConfig(config);
92
+ console.log(`Review depth set to: ${level} — ${PROFILES[level].description}`);
93
+ return;
94
+ }
95
+ if (subcommand === "set-path") {
96
+ const path = argv.find((_a, i) => argv[i - 1] === "--path") || "";
97
+ const level = argv.find((_a, i) => argv[i - 1] === "--level");
98
+ if (!path || !level || !PROFILES[level]) {
99
+ console.log("Specify --path and --level (shallow, normal, deep).");
100
+ return;
101
+ }
102
+ config.perPath[path] = level;
103
+ saveConfig(config);
104
+ console.log(`Set ${path} → ${level}`);
105
+ return;
106
+ }
107
+ if (subcommand === "profiles") {
108
+ if (format === "json") {
109
+ console.log(JSON.stringify(PROFILES, null, 2));
110
+ return;
111
+ }
112
+ console.log("\nDepth Profiles:");
113
+ console.log("═".repeat(50));
114
+ for (const [, p] of Object.entries(PROFILES)) {
115
+ console.log(` ${p.level.padEnd(10)} ${p.description}`);
116
+ console.log(` judges=${p.maxJudges} AST=${p.enableAST} crossFile=${p.enableCrossFile}`);
117
+ }
118
+ console.log("═".repeat(50));
119
+ return;
120
+ }
121
+ if (subcommand === "reset") {
122
+ saveConfig({ version: "1.0.0", currentLevel: "normal", perPath: {} });
123
+ console.log("Review depth reset to normal.");
124
+ return;
125
+ }
126
+ // Default: show current
127
+ const profile = PROFILES[config.currentLevel];
128
+ if (format === "json") {
129
+ console.log(JSON.stringify({ current: config.currentLevel, profile, perPath: config.perPath }, null, 2));
130
+ return;
131
+ }
132
+ console.log(`\nCurrent Review Depth: ${config.currentLevel}`);
133
+ console.log(` ${profile.description}`);
134
+ console.log(` Max judges: ${profile.maxJudges} AST: ${profile.enableAST} Cross-file: ${profile.enableCrossFile}`);
135
+ const pathEntries = Object.entries(config.perPath);
136
+ if (pathEntries.length > 0) {
137
+ console.log("\nPath Overrides:");
138
+ for (const [p, l] of pathEntries) {
139
+ console.log(` ${p} → ${l}`);
140
+ }
141
+ }
142
+ }
143
+ //# sourceMappingURL=review-depth.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-depth.js","sourceRoot":"","sources":["../../src/commands/review-depth.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-retry — Retry failed or incomplete reviews.
3
+ */
4
+ export declare function runReviewRetry(argv: string[]): void;
5
+ //# sourceMappingURL=review-retry.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-retry.d.ts","sourceRoot":"","sources":["../../src/commands/review-retry.ts"],"names":[],"mappings":"AAAA;;GAEG;AAeH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAyFnD"}
@@ -0,0 +1,92 @@
1
+ /**
2
+ * Review-retry — Retry failed or incomplete reviews.
3
+ */
4
+ import { readFileSync, existsSync, readdirSync } from "fs";
5
+ // ─── CLI ────────────────────────────────────────────────────────────────────
6
+ export function runReviewRetry(argv) {
7
+ if (argv.includes("--help") || argv.includes("-h")) {
8
+ console.log(`
9
+ judges review-retry — Retry failed or incomplete reviews
10
+
11
+ Usage:
12
+ judges review-retry Show retry candidates
13
+ judges review-retry scan Scan for failed reviews
14
+ judges review-retry list List retry candidates
15
+ judges review-retry clear Clear retry state
16
+
17
+ Subcommands:
18
+ (default) Show retry candidates
19
+ scan Scan for reviews that need retry
20
+ list List candidates with details
21
+ clear Clear retry state
22
+
23
+ Options:
24
+ --threshold <n> Score threshold for retry (default: 5)
25
+ --dir <path> Override results directory
26
+ --format json JSON output
27
+ --help, -h Show this help
28
+
29
+ Detects reviews that scored below threshold or had errors.
30
+ `);
31
+ return;
32
+ }
33
+ const subcommand = argv.find((a) => ["scan", "list", "clear"].includes(a));
34
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
35
+ const threshold = parseFloat(argv.find((_a, i) => argv[i - 1] === "--threshold") || "5");
36
+ const dir = argv.find((_a, i) => argv[i - 1] === "--dir") || ".judges/results";
37
+ if (subcommand === "clear") {
38
+ console.log("Retry state cleared.");
39
+ return;
40
+ }
41
+ // Scan for candidates
42
+ const candidates = [];
43
+ if (existsSync(dir)) {
44
+ try {
45
+ const files = readdirSync(dir);
46
+ for (const f of files) {
47
+ if (!String(f).endsWith(".json"))
48
+ continue;
49
+ try {
50
+ const content = JSON.parse(readFileSync(`${dir}/${String(f)}`, "utf-8"));
51
+ const score = typeof content.overallScore === "number" ? content.overallScore : 0;
52
+ const status = score < threshold ? "below-threshold" : "ok";
53
+ if (status === "below-threshold") {
54
+ candidates.push({
55
+ file: String(f),
56
+ lastReview: content.timestamp || "unknown",
57
+ status,
58
+ score,
59
+ });
60
+ }
61
+ }
62
+ catch {
63
+ candidates.push({
64
+ file: String(f),
65
+ lastReview: "unknown",
66
+ status: "parse-error",
67
+ score: 0,
68
+ });
69
+ }
70
+ }
71
+ }
72
+ catch {
73
+ // Directory not readable
74
+ }
75
+ }
76
+ if (format === "json") {
77
+ console.log(JSON.stringify({ threshold, candidates }, null, 2));
78
+ return;
79
+ }
80
+ if (candidates.length === 0) {
81
+ console.log(`No retry candidates (threshold: ${threshold}).`);
82
+ return;
83
+ }
84
+ console.log(`\nRetry Candidates (score < ${threshold}):`);
85
+ console.log("─".repeat(60));
86
+ for (const c of candidates) {
87
+ console.log(` ${c.file} score=${c.score.toFixed(1)} status=${c.status}`);
88
+ }
89
+ console.log("─".repeat(60));
90
+ console.log(`\n${candidates.length} review(s) eligible for retry.`);
91
+ }
92
+ //# sourceMappingURL=review-retry.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-retry.js","sourceRoot":"","sources":["../../src/commands/review-retry.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-session — Group reviews into named sessions for project phases.
3
+ */
4
+ export declare function runReviewSession(argv: string[]): void;
5
+ //# sourceMappingURL=review-session.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-session.d.ts","sourceRoot":"","sources":["../../src/commands/review-session.ts"],"names":[],"mappings":"AAAA;;GAEG;AA8CH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAsIrD"}
@@ -0,0 +1,151 @@
1
+ /**
2
+ * Review-session — Group reviews into named sessions for project phases.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
5
+ import { dirname } from "path";
6
+ // ─── Storage ────────────────────────────────────────────────────────────────
7
+ const SESSION_FILE = ".judges/sessions.json";
8
+ function loadStore() {
9
+ if (!existsSync(SESSION_FILE))
10
+ return { version: "1.0.0", sessions: [] };
11
+ try {
12
+ return JSON.parse(readFileSync(SESSION_FILE, "utf-8"));
13
+ }
14
+ catch {
15
+ return { version: "1.0.0", sessions: [] };
16
+ }
17
+ }
18
+ function saveStore(store) {
19
+ mkdirSync(dirname(SESSION_FILE), { recursive: true });
20
+ writeFileSync(SESSION_FILE, JSON.stringify(store, null, 2), "utf-8");
21
+ }
22
+ function generateId() {
23
+ return `ses-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 6)}`;
24
+ }
25
+ // ─── CLI ────────────────────────────────────────────────────────────────────
26
+ export function runReviewSession(argv) {
27
+ if (argv.includes("--help") || argv.includes("-h")) {
28
+ console.log(`
29
+ judges review-session — Group reviews into named sessions
30
+
31
+ Usage:
32
+ judges review-session start --name "sprint-42"
33
+ judges review-session end
34
+ judges review-session log --reviews 5 --findings 12
35
+ judges review-session list
36
+ judges review-session show --id <id>
37
+ judges review-session clear
38
+
39
+ Subcommands:
40
+ start Start a new session
41
+ end End the active session
42
+ log Log review activity to active session
43
+ list List all sessions
44
+ show Show session details
45
+ clear Clear all sessions
46
+
47
+ Options:
48
+ --name <text> Session name
49
+ --id <id> Session ID
50
+ --reviews <n> Number of reviews to log
51
+ --findings <n> Number of findings to log
52
+ --format json JSON output
53
+ --help, -h Show this help
54
+
55
+ Sessions stored in .judges/sessions.json.
56
+ `);
57
+ return;
58
+ }
59
+ const subcommand = argv.find((a) => ["start", "end", "log", "list", "show", "clear"].includes(a));
60
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
61
+ const store = loadStore();
62
+ if (subcommand === "start") {
63
+ const name = argv.find((_a, i) => argv[i - 1] === "--name") || `session-${store.sessions.length + 1}`;
64
+ // Close any active session
65
+ for (const s of store.sessions) {
66
+ if (s.status === "active") {
67
+ s.status = "closed";
68
+ s.endedAt = new Date().toISOString();
69
+ }
70
+ }
71
+ const session = {
72
+ id: generateId(),
73
+ name,
74
+ startedAt: new Date().toISOString(),
75
+ endedAt: "",
76
+ reviewCount: 0,
77
+ findingCount: 0,
78
+ status: "active",
79
+ };
80
+ store.sessions.push(session);
81
+ saveStore(store);
82
+ console.log(`Session started: "${name}" (${session.id})`);
83
+ return;
84
+ }
85
+ if (subcommand === "end") {
86
+ const active = store.sessions.find((s) => s.status === "active");
87
+ if (!active) {
88
+ console.log("No active session.");
89
+ return;
90
+ }
91
+ active.status = "closed";
92
+ active.endedAt = new Date().toISOString();
93
+ saveStore(store);
94
+ console.log(`Session ended: "${active.name}" — ${active.reviewCount} reviews, ${active.findingCount} findings.`);
95
+ return;
96
+ }
97
+ if (subcommand === "log") {
98
+ const active = store.sessions.find((s) => s.status === "active");
99
+ if (!active) {
100
+ console.log("No active session. Start one with 'judges review-session start'.");
101
+ return;
102
+ }
103
+ const reviews = parseInt(argv.find((_a, i) => argv[i - 1] === "--reviews") || "1", 10);
104
+ const findings = parseInt(argv.find((_a, i) => argv[i - 1] === "--findings") || "0", 10);
105
+ active.reviewCount += reviews;
106
+ active.findingCount += findings;
107
+ saveStore(store);
108
+ console.log(`Logged to "${active.name}": +${reviews} reviews, +${findings} findings.`);
109
+ return;
110
+ }
111
+ if (subcommand === "show") {
112
+ const id = argv.find((_a, i) => argv[i - 1] === "--id") || "";
113
+ const session = store.sessions.find((s) => s.id === id);
114
+ if (!session) {
115
+ console.log(`Session ${id} not found.`);
116
+ return;
117
+ }
118
+ if (format === "json") {
119
+ console.log(JSON.stringify(session, null, 2));
120
+ return;
121
+ }
122
+ console.log(`\nSession: ${session.name} (${session.id})`);
123
+ console.log(` Status: ${session.status}`);
124
+ console.log(` Started: ${session.startedAt}`);
125
+ console.log(` Ended: ${session.endedAt || "(active)"}`);
126
+ console.log(` Reviews: ${session.reviewCount} Findings: ${session.findingCount}`);
127
+ return;
128
+ }
129
+ if (subcommand === "clear") {
130
+ saveStore({ version: "1.0.0", sessions: [] });
131
+ console.log("Sessions cleared.");
132
+ return;
133
+ }
134
+ // Default: list
135
+ if (store.sessions.length === 0) {
136
+ console.log("No sessions. Start one with 'judges review-session start'.");
137
+ return;
138
+ }
139
+ if (format === "json") {
140
+ console.log(JSON.stringify(store.sessions, null, 2));
141
+ return;
142
+ }
143
+ console.log("\nReview Sessions:");
144
+ console.log("─".repeat(60));
145
+ for (const s of store.sessions) {
146
+ const status = s.status === "active" ? "[ACTIVE]" : "[closed]";
147
+ console.log(` ${s.id} ${status} "${s.name}" reviews=${s.reviewCount} findings=${s.findingCount}`);
148
+ }
149
+ console.log("─".repeat(60));
150
+ }
151
+ //# sourceMappingURL=review-session.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-session.js","sourceRoot":"","sources":["../../src/commands/review-session.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-summary-email — Generate email-ready review summaries.
3
+ */
4
+ export declare function runReviewSummaryEmail(argv: string[]): void;
5
+ //# sourceMappingURL=review-summary-email.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-summary-email.d.ts","sourceRoot":"","sources":["../../src/commands/review-summary-email.ts"],"names":[],"mappings":"AAAA;;GAEG;AAMH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAiH1D"}
@@ -0,0 +1,103 @@
1
+ /**
2
+ * Review-summary-email — Generate email-ready review summaries.
3
+ */
4
+ import { readFileSync, existsSync } from "fs";
5
+ // ─── CLI ────────────────────────────────────────────────────────────────────
6
+ export function runReviewSummaryEmail(argv) {
7
+ if (argv.includes("--help") || argv.includes("-h")) {
8
+ console.log(`
9
+ judges review-summary-email — Generate email-ready review summaries
10
+
11
+ Usage:
12
+ judges review-summary-email --file results.json
13
+ judges review-summary-email --file results.json --to team@example.com
14
+ judges review-summary-email --file results.json --format json
15
+
16
+ Options:
17
+ --file <path> Path to review result JSON
18
+ --to <email> Recipient (included in subject line, not sent)
19
+ --subject <text> Custom subject line
20
+ --format json JSON output
21
+ --help, -h Show this help
22
+
23
+ Generates a formatted text suitable for copy-paste into email.
24
+ Does NOT send email — output is local only.
25
+ `);
26
+ return;
27
+ }
28
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
29
+ const filePath = argv.find((_a, i) => argv[i - 1] === "--file") || "";
30
+ const to = argv.find((_a, i) => argv[i - 1] === "--to") || "";
31
+ const customSubject = argv.find((_a, i) => argv[i - 1] === "--subject") || "";
32
+ if (!filePath) {
33
+ console.log("Specify --file <path> to a review result JSON.");
34
+ return;
35
+ }
36
+ if (!existsSync(filePath)) {
37
+ console.log(`File not found: ${filePath}`);
38
+ return;
39
+ }
40
+ let data;
41
+ try {
42
+ data = JSON.parse(readFileSync(filePath, "utf-8"));
43
+ }
44
+ catch {
45
+ console.log(`Failed to parse: ${filePath}`);
46
+ return;
47
+ }
48
+ const score = typeof data.overallScore === "number" ? data.overallScore : 0;
49
+ const verdict = typeof data.overallVerdict === "string" ? data.overallVerdict : "unknown";
50
+ const summary = typeof data.summary === "string" ? data.summary : "";
51
+ const criticalCount = typeof data.criticalCount === "number" ? data.criticalCount : 0;
52
+ const highCount = typeof data.highCount === "number" ? data.highCount : 0;
53
+ const findings = Array.isArray(data.findings) ? data.findings : [];
54
+ const timestamp = typeof data.timestamp === "string" ? data.timestamp : new Date().toISOString();
55
+ const subject = customSubject || `Code Review Report — Score ${score.toFixed(1)}/10 (${verdict})`;
56
+ if (format === "json") {
57
+ console.log(JSON.stringify({
58
+ to,
59
+ subject,
60
+ body: { score, verdict, summary, criticalCount, highCount, findingCount: findings.length, timestamp },
61
+ }, null, 2));
62
+ return;
63
+ }
64
+ // Generate email text
65
+ const lines = [];
66
+ lines.push("─".repeat(60));
67
+ if (to)
68
+ lines.push(`To: ${to}`);
69
+ lines.push(`Subject: ${subject}`);
70
+ lines.push(`Date: ${timestamp.slice(0, 10)}`);
71
+ lines.push("─".repeat(60));
72
+ lines.push("");
73
+ lines.push("CODE REVIEW SUMMARY");
74
+ lines.push("═".repeat(40));
75
+ lines.push(`Score: ${score.toFixed(1)} / 10`);
76
+ lines.push(`Verdict: ${verdict.toUpperCase()}`);
77
+ lines.push(`Findings: ${findings.length} total (${criticalCount} critical, ${highCount} high)`);
78
+ lines.push("");
79
+ if (summary) {
80
+ lines.push("Overview:");
81
+ lines.push(` ${summary}`);
82
+ lines.push("");
83
+ }
84
+ if (findings.length > 0) {
85
+ lines.push("Top Findings:");
86
+ const top = findings.slice(0, 5);
87
+ for (const f of top) {
88
+ const sev = typeof f === "object" && f && "severity" in f ? String(f.severity) : "?";
89
+ const title = typeof f === "object" && f && "title" in f ? String(f.title) : "untitled";
90
+ const rule = typeof f === "object" && f && "ruleId" in f ? String(f.ruleId) : "";
91
+ lines.push(` [${sev.toUpperCase()}] ${rule} — ${title}`);
92
+ }
93
+ if (findings.length > 5) {
94
+ lines.push(` ... and ${findings.length - 5} more findings`);
95
+ }
96
+ lines.push("");
97
+ }
98
+ lines.push("─".repeat(60));
99
+ lines.push("Generated by Judges Panel — https://github.com/KevinRabun/judges");
100
+ lines.push("─".repeat(60));
101
+ console.log(lines.join("\n"));
102
+ }
103
+ //# sourceMappingURL=review-summary-email.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-summary-email.js","sourceRoot":"","sources":["../../src/commands/review-summary-email.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAE9C,+EAA+E;AAE/E,MAAM,UAAU,qBAAqB,CAAC,IAAc;IAClD,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;CAiBf,CAAC,CAAC;QACC,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,UAAU,CAAC,IAAI,MAAM,CAAC;IAC1F,MAAM,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,QAAQ,CAAC,IAAI,EAAE,CAAC;IACtF,MAAM,EAAE,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC;IAC9E,MAAM,aAAa,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,WAAW,CAAC,IAAI,EAAE,CAAC;IAE9F,IAAI,CAAC,QAAQ,EAAE,CAAC;QACd,OAAO,CAAC,GAAG,CAAC,gDAAgD,CAAC,CAAC;QAC9D,OAAO;IACT,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC1B,OAAO,CAAC,GAAG,CAAC,mBAAmB,QAAQ,EAAE,CAAC,CAAC;QAC3C,OAAO;IACT,CAAC;IAED,IAAI,IAA6B,CAAC;IAClC,IAAI,CAAC;QACH,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,QAAQ,EAAE,OAAO,CAAC,CAA4B,CAAC;IAChF,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,CAAC,GAAG,CAAC,oBAAoB,QAAQ,EAAE,CAAC,CAAC;QAC5C,OAAO;IACT,CAAC;IAED,MAAM,KAAK,GAAG,OAAO,IAAI,CAAC,YAAY,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,CAAC;IAC5E,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,cAAc,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,cAAc,CAAC,CAAC,CAAC,SAAS,CAAC;IAC1F,MAAM,OAAO,GAAG,OAAO,IAAI,CAAC,OAAO,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAC,EAAE,CAAC;IACrE,MAAM,aAAa,GAAG,OAAO,IAAI,CAAC,aAAa,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,aAAa,CAAC,CAAC,CAAC,CAAC,CAAC;IACtF,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,CAAC,CAAC;IAC1E,MAAM,QAAQ,GAAG,KAAK,CAAC,OAAO,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,CAAC;IACnE,MAAM,SAAS,GAAG,OAAO,IAAI,CAAC,SAAS,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,SAAS,CAAC,CAAC,CAAC,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,CAAC;IAEjG,MAAM,OAAO,GAAG,aAAa,IAAI,8BAA8B,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,QAAQ,OAAO,GAAG,CAAC;IAElG,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CACT,IAAI,CAAC,SAAS,CACZ;YACE,EAAE;YACF,OAAO;YACP,IAAI,EAAE,EAAE,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,EAAE,SAAS,EAAE,YAAY,EAAE,QAAQ,CAAC,MAAM,EAAE,SAAS,EAAE;SACtG,EACD,IAAI,EACJ,CAAC,CACF,CACF,CAAC;QACF,OAAO;IACT,CAAC;IAED,sBAAsB;IACtB,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3B,IAAI,EAAE;QAAE,KAAK,CAAC,IAAI,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAChC,KAAK,CAAC,IAAI,CAAC,YAAY,OAAO,EAAE,CAAC,CAAC;IAClC,KAAK,CAAC,IAAI,CAAC,SAAS,SAAS,CAAC,KAAK,CAAC,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,CAAC;IAC9C,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACf,KAAK,CAAC,IAAI,CAAC,qBAAqB,CAAC,CAAC;IAClC,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,cAAc,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAClD,KAAK,CAAC,IAAI,CAAC,cAAc,OAAO,CAAC,WAAW,EAAE,EAAE,CAAC,CAAC;IAClD,KAAK,CAAC,IAAI,CAAC,cAAc,QAAQ,CAAC,MAAM,WAAW,aAAa,cAAc,SAAS,QAAQ,CAAC,CAAC;IACjG,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IAEf,IAAI,OAAO,EAAE,CAAC;QACZ,KAAK,CAAC,IAAI,CAAC,WAAW,CAAC,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,KAAK,OAAO,EAAE,CAAC,CAAC;QAC3B,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,KAAK,CAAC,IAAI,CAAC,eAAe,CAAC,CAAC;QAC5B,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACjC,KAAK,MAAM,CAAC,IAAI,GAAG,EAAE,CAAC;YACpB,MAAM,GAAG,GAAG,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,IAAI,UAAU,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAE,CAA6B,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC;YAClH,MAAM,KAAK,GACT,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,IAAI,OAAO,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAE,CAA6B,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,UAAU,CAAC;YACzG,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,QAAQ,IAAI,CAAC,IAAI,QAAQ,IAAI,CAAC,CAAC,CAAC,CAAC,MAAM,CAAE,CAA6B,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;YAC9G,KAAK,CAAC,IAAI,CAAC,MAAM,GAAG,CAAC,WAAW,EAAE,KAAK,IAAI,MAAM,KAAK,EAAE,CAAC,CAAC;QAC5D,CAAC;QACD,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,aAAa,QAAQ,CAAC,MAAM,GAAG,CAAC,gBAAgB,CAAC,CAAC;QAC/D,CAAC;QACD,KAAK,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACjB,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,kEAAkE,CAAC,CAAC;IAC/E,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,MAAM,CAAC,EAAE,CAAC,CAAC,CAAC;IAE3B,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AAChC,CAAC"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kevinrabun/judges",
3
- "version": "3.72.0",
3
+ "version": "3.73.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.72.0",
10
+ "version": "3.73.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "@kevinrabun/judges",
15
- "version": "3.72.0",
15
+ "version": "3.73.0",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }