@kevinrabun/judges 3.69.0 → 3.70.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 +11 -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-impact.d.ts +5 -0
  6. package/dist/commands/finding-impact.d.ts.map +1 -0
  7. package/dist/commands/finding-impact.js +136 -0
  8. package/dist/commands/finding-impact.js.map +1 -0
  9. package/dist/commands/review-archive.d.ts +5 -0
  10. package/dist/commands/review-archive.d.ts.map +1 -0
  11. package/dist/commands/review-archive.js +136 -0
  12. package/dist/commands/review-archive.js.map +1 -0
  13. package/dist/commands/review-ci-status.d.ts +5 -0
  14. package/dist/commands/review-ci-status.d.ts.map +1 -0
  15. package/dist/commands/review-ci-status.js +201 -0
  16. package/dist/commands/review-ci-status.js.map +1 -0
  17. package/dist/commands/review-custom-prompt.d.ts +5 -0
  18. package/dist/commands/review-custom-prompt.d.ts.map +1 -0
  19. package/dist/commands/review-custom-prompt.js +171 -0
  20. package/dist/commands/review-custom-prompt.js.map +1 -0
  21. package/dist/commands/review-diff-context.d.ts +5 -0
  22. package/dist/commands/review-diff-context.d.ts.map +1 -0
  23. package/dist/commands/review-diff-context.js +159 -0
  24. package/dist/commands/review-diff-context.js.map +1 -0
  25. package/dist/commands/review-tag.d.ts +5 -0
  26. package/dist/commands/review-tag.d.ts.map +1 -0
  27. package/dist/commands/review-tag.js +137 -0
  28. package/dist/commands/review-tag.js.map +1 -0
  29. package/dist/commands/review-team-summary.d.ts +5 -0
  30. package/dist/commands/review-team-summary.d.ts.map +1 -0
  31. package/dist/commands/review-team-summary.js +156 -0
  32. package/dist/commands/review-team-summary.js.map +1 -0
  33. package/dist/commands/review-whitelist.d.ts +5 -0
  34. package/dist/commands/review-whitelist.d.ts.map +1 -0
  35. package/dist/commands/review-whitelist.js +159 -0
  36. package/dist/commands/review-whitelist.js.map +1 -0
  37. package/package.json +1 -1
  38. package/server.json +2 -2
@@ -0,0 +1,156 @@
1
+ /**
2
+ * Review-team-summary — Aggregate team review metrics.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
5
+ import { join, dirname } from "path";
6
+ // ─── Storage ────────────────────────────────────────────────────────────────
7
+ const STORE_FILE = join(".judges", "team-reviews.json");
8
+ function loadStore() {
9
+ if (!existsSync(STORE_FILE))
10
+ return { version: "1.0.0", entries: [] };
11
+ try {
12
+ return JSON.parse(readFileSync(STORE_FILE, "utf-8"));
13
+ }
14
+ catch {
15
+ return { version: "1.0.0", entries: [] };
16
+ }
17
+ }
18
+ function saveStore(store) {
19
+ mkdirSync(dirname(STORE_FILE), { recursive: true });
20
+ writeFileSync(STORE_FILE, JSON.stringify(store, null, 2), "utf-8");
21
+ }
22
+ // ─── CLI ────────────────────────────────────────────────────────────────────
23
+ export function runReviewTeamSummary(argv) {
24
+ if (argv.includes("--help") || argv.includes("-h")) {
25
+ console.log(`
26
+ judges review-team-summary — Aggregate team review metrics
27
+
28
+ Usage:
29
+ judges review-team-summary Show team summary
30
+ judges review-team-summary add --reviewer alice --score 8.5 --findings 3
31
+ judges review-team-summary list List all entries
32
+ judges review-team-summary clear Clear all data
33
+
34
+ Subcommands:
35
+ (default) Show aggregated team summary
36
+ add Add a review entry
37
+ list List raw entries
38
+ clear Clear all team data
39
+
40
+ Options:
41
+ --reviewer <name> Reviewer name
42
+ --score <n> Review score
43
+ --findings <n> Number of findings
44
+ --tags <t1,t2> Comma-separated tags
45
+ --days <n> Recent activity window (default: 30)
46
+ --format json JSON output
47
+ --help, -h Show this help
48
+
49
+ Data stored locally in .judges/team-reviews.json.
50
+ Note: Judges does not store or process user data — all team data
51
+ is local and managed by the user.
52
+ `);
53
+ return;
54
+ }
55
+ const subcommand = argv.find((a) => ["add", "list", "clear"].includes(a));
56
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
57
+ const store = loadStore();
58
+ if (subcommand === "add") {
59
+ const reviewer = argv.find((_a, i) => argv[i - 1] === "--reviewer") || "";
60
+ const score = parseFloat(argv.find((_a, i) => argv[i - 1] === "--score") || "0");
61
+ const findingCount = parseInt(argv.find((_a, i) => argv[i - 1] === "--findings") || "0", 10);
62
+ const tagsArg = argv.find((_a, i) => argv[i - 1] === "--tags") || "";
63
+ const tags = tagsArg
64
+ ? tagsArg
65
+ .split(",")
66
+ .map((t) => t.trim())
67
+ .filter(Boolean)
68
+ : [];
69
+ if (!reviewer) {
70
+ console.error("Error: --reviewer is required.");
71
+ process.exitCode = 1;
72
+ return;
73
+ }
74
+ store.entries.push({ reviewer, score, findingCount, date: new Date().toISOString(), tags });
75
+ saveStore(store);
76
+ console.log(`Added review entry for "${reviewer}" (score=${score}, findings=${findingCount}).`);
77
+ return;
78
+ }
79
+ if (subcommand === "list") {
80
+ if (store.entries.length === 0) {
81
+ console.log("No team review entries.");
82
+ return;
83
+ }
84
+ if (format === "json") {
85
+ console.log(JSON.stringify(store.entries, null, 2));
86
+ return;
87
+ }
88
+ console.log("\nTeam Review Entries:");
89
+ console.log("─".repeat(70));
90
+ for (const e of store.entries) {
91
+ console.log(` ${e.date.slice(0, 10)} ${e.reviewer.padEnd(15)} score=${e.score.toFixed(1)} findings=${e.findingCount}`);
92
+ }
93
+ console.log("─".repeat(70));
94
+ return;
95
+ }
96
+ if (subcommand === "clear") {
97
+ saveStore({ version: "1.0.0", entries: [] });
98
+ console.log("Team review data cleared.");
99
+ return;
100
+ }
101
+ // Default: show summary
102
+ if (store.entries.length === 0) {
103
+ console.log("No team review data. Use 'judges review-team-summary add' to add entries.");
104
+ return;
105
+ }
106
+ const days = parseInt(argv.find((_a, i) => argv[i - 1] === "--days") || "30", 10);
107
+ const cutoff = new Date(Date.now() - days * 86400000).toISOString();
108
+ // Aggregate by reviewer
109
+ const byReviewer = new Map();
110
+ for (const e of store.entries) {
111
+ const list = byReviewer.get(e.reviewer) || [];
112
+ list.push(e);
113
+ byReviewer.set(e.reviewer, list);
114
+ }
115
+ const members = [];
116
+ for (const [reviewer, entries] of byReviewer) {
117
+ const avgScore = entries.reduce((s, e) => s + e.score, 0) / entries.length;
118
+ const totalFindings = entries.reduce((s, e) => s + e.findingCount, 0);
119
+ const lastActive = entries.sort((a, b) => b.date.localeCompare(a.date))[0].date;
120
+ members.push({ reviewer, reviewCount: entries.length, avgScore, totalFindings, lastActive });
121
+ }
122
+ members.sort((a, b) => b.avgScore - a.avgScore);
123
+ const totalReviews = store.entries.length;
124
+ const avgScore = store.entries.reduce((s, e) => s + e.score, 0) / totalReviews;
125
+ const recentActivity = store.entries.filter((e) => e.date >= cutoff).length;
126
+ const topPerformer = members.length > 0 ? members[0].reviewer : "N/A";
127
+ const report = {
128
+ timestamp: new Date().toISOString(),
129
+ teamSize: members.length,
130
+ totalReviews,
131
+ avgScore,
132
+ members,
133
+ topPerformer,
134
+ recentActivity,
135
+ };
136
+ if (format === "json") {
137
+ console.log(JSON.stringify(report, null, 2));
138
+ return;
139
+ }
140
+ console.log("\nTeam Review Summary:");
141
+ console.log("═".repeat(70));
142
+ console.log(` Team size: ${members.length} Total reviews: ${totalReviews} Avg score: ${avgScore.toFixed(1)}`);
143
+ console.log(` Recent activity (${days}d): ${recentActivity} review(s) Top: ${topPerformer}`);
144
+ console.log("═".repeat(70));
145
+ console.log("\n Members:");
146
+ console.log(" " + "─".repeat(68));
147
+ console.log(` ${"Reviewer".padEnd(18)} ${"Reviews".padEnd(10)} ${"Avg Score".padEnd(12)} ${"Findings".padEnd(10)} Last Active`);
148
+ console.log(" " + "─".repeat(68));
149
+ for (const m of members) {
150
+ console.log(` ${m.reviewer.padEnd(18)} ${String(m.reviewCount).padEnd(10)} ${m.avgScore.toFixed(1).padEnd(12)} ${String(m.totalFindings).padEnd(10)} ${m.lastActive.slice(0, 10)}`);
151
+ }
152
+ console.log(" " + "─".repeat(68));
153
+ console.log(`\n Report saved to ${STORE_FILE}`);
154
+ writeFileSync(join(".judges", "team-summary.json"), JSON.stringify(report, null, 2), "utf-8");
155
+ }
156
+ //# sourceMappingURL=review-team-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-team-summary.js","sourceRoot":"","sources":["../../src/commands/review-team-summary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-whitelist — Allow-list safe patterns that should not be flagged.
3
+ */
4
+ export declare function runReviewWhitelist(argv: string[]): void;
5
+ //# sourceMappingURL=review-whitelist.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-whitelist.d.ts","sourceRoot":"","sources":["../../src/commands/review-whitelist.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6CH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA0IvD"}
@@ -0,0 +1,159 @@
1
+ /**
2
+ * Review-whitelist — Allow-list safe patterns that should not be flagged.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
5
+ import { join, dirname } from "path";
6
+ // ─── Storage ────────────────────────────────────────────────────────────────
7
+ const WHITELIST_FILE = join(".judges", "whitelist.json");
8
+ function loadWhitelist() {
9
+ if (!existsSync(WHITELIST_FILE))
10
+ return { version: "1.0.0", entries: [] };
11
+ try {
12
+ return JSON.parse(readFileSync(WHITELIST_FILE, "utf-8"));
13
+ }
14
+ catch {
15
+ return { version: "1.0.0", entries: [] };
16
+ }
17
+ }
18
+ function saveWhitelist(store) {
19
+ mkdirSync(dirname(WHITELIST_FILE), { recursive: true });
20
+ writeFileSync(WHITELIST_FILE, JSON.stringify(store, null, 2), "utf-8");
21
+ }
22
+ function generateId() {
23
+ return `wl-${Date.now().toString(36)}`;
24
+ }
25
+ // ─── CLI ────────────────────────────────────────────────────────────────────
26
+ export function runReviewWhitelist(argv) {
27
+ if (argv.includes("--help") || argv.includes("-h")) {
28
+ console.log(`
29
+ judges review-whitelist — Allow-list safe patterns
30
+
31
+ Usage:
32
+ judges review-whitelist add --rule sql-injection --pattern "SELECT.*FROM config" --reason "Read-only config table"
33
+ judges review-whitelist list
34
+ judges review-whitelist remove --id wl-abc123
35
+ judges review-whitelist check --rule sql-injection --code "SELECT name FROM config"
36
+ judges review-whitelist clear
37
+
38
+ Subcommands:
39
+ add Add a whitelist entry
40
+ list List all whitelist entries
41
+ remove Remove a whitelist entry
42
+ check Check if code matches a whitelist pattern
43
+ clear Clear all whitelist data
44
+
45
+ Options:
46
+ --rule <ruleId> Rule ID to whitelist
47
+ --pattern <regex> Regex pattern to match safe code
48
+ --reason <text> Reason for whitelisting
49
+ --by <name> Who added the entry
50
+ --id <id> Whitelist entry ID
51
+ --code <text> Code snippet to check
52
+ --format json JSON output
53
+ --help, -h Show this help
54
+
55
+ Whitelist data stored in .judges/whitelist.json.
56
+ `);
57
+ return;
58
+ }
59
+ const subcommand = argv.find((a) => ["add", "list", "remove", "check", "clear"].includes(a)) || "list";
60
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
61
+ const store = loadWhitelist();
62
+ if (subcommand === "add") {
63
+ const ruleId = argv.find((_a, i) => argv[i - 1] === "--rule") || "";
64
+ const pattern = argv.find((_a, i) => argv[i - 1] === "--pattern") || "";
65
+ const reason = argv.find((_a, i) => argv[i - 1] === "--reason") || "";
66
+ const addedBy = argv.find((_a, i) => argv[i - 1] === "--by") || "unknown";
67
+ if (!ruleId || !pattern) {
68
+ console.error("Error: --rule and --pattern are required.");
69
+ process.exitCode = 1;
70
+ return;
71
+ }
72
+ // Validate the regex pattern
73
+ try {
74
+ new RegExp(pattern);
75
+ }
76
+ catch {
77
+ console.error("Error: --pattern is not a valid regex.");
78
+ process.exitCode = 1;
79
+ return;
80
+ }
81
+ const id = generateId();
82
+ store.entries.push({ id, ruleId, pattern, reason, addedAt: new Date().toISOString(), addedBy });
83
+ saveWhitelist(store);
84
+ console.log(`Added whitelist entry ${id}: rule="${ruleId}" pattern="${pattern}"`);
85
+ return;
86
+ }
87
+ if (subcommand === "remove") {
88
+ const id = argv.find((_a, i) => argv[i - 1] === "--id");
89
+ if (!id) {
90
+ console.error("Error: --id is required.");
91
+ process.exitCode = 1;
92
+ return;
93
+ }
94
+ const before = store.entries.length;
95
+ store.entries = store.entries.filter((e) => e.id !== id);
96
+ if (store.entries.length === before) {
97
+ console.error(`Error: Entry "${id}" not found.`);
98
+ process.exitCode = 1;
99
+ return;
100
+ }
101
+ saveWhitelist(store);
102
+ console.log(`Removed whitelist entry ${id}.`);
103
+ return;
104
+ }
105
+ if (subcommand === "check") {
106
+ const ruleId = argv.find((_a, i) => argv[i - 1] === "--rule") || "";
107
+ const code = argv.find((_a, i) => argv[i - 1] === "--code") || "";
108
+ if (!ruleId || !code) {
109
+ console.error("Error: --rule and --code are required.");
110
+ process.exitCode = 1;
111
+ return;
112
+ }
113
+ const matches = store.entries.filter((e) => {
114
+ if (e.ruleId !== ruleId && e.ruleId !== "*")
115
+ return false;
116
+ try {
117
+ return new RegExp(e.pattern).test(code);
118
+ }
119
+ catch {
120
+ return false;
121
+ }
122
+ });
123
+ if (matches.length > 0) {
124
+ console.log(`✓ Code is whitelisted by ${matches.length} entry/entries:`);
125
+ for (const m of matches) {
126
+ console.log(` ${m.id}: ${m.reason || "(no reason)"}`);
127
+ }
128
+ }
129
+ else {
130
+ console.log("✗ Code is NOT whitelisted for this rule.");
131
+ }
132
+ return;
133
+ }
134
+ if (subcommand === "clear") {
135
+ saveWhitelist({ version: "1.0.0", entries: [] });
136
+ console.log("Whitelist data cleared.");
137
+ return;
138
+ }
139
+ // list
140
+ if (store.entries.length === 0) {
141
+ console.log("No whitelist entries. Use 'judges review-whitelist add' to start.");
142
+ return;
143
+ }
144
+ if (format === "json") {
145
+ console.log(JSON.stringify(store.entries, null, 2));
146
+ return;
147
+ }
148
+ console.log("\nWhitelist Entries:");
149
+ console.log("─".repeat(70));
150
+ for (const e of store.entries) {
151
+ console.log(` ${e.id} rule=${e.ruleId} added=${e.addedAt.slice(0, 10)}`);
152
+ console.log(` Pattern: ${e.pattern}`);
153
+ if (e.reason)
154
+ console.log(` Reason: ${e.reason}`);
155
+ }
156
+ console.log("─".repeat(70));
157
+ console.log(` Total: ${store.entries.length} entry/entries`);
158
+ }
159
+ //# sourceMappingURL=review-whitelist.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-whitelist.js","sourceRoot":"","sources":["../../src/commands/review-whitelist.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.69.0",
3
+ "version": "3.70.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.69.0",
10
+ "version": "3.70.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "@kevinrabun/judges",
15
- "version": "3.69.0",
15
+ "version": "3.70.0",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }