@kevinrabun/judges 3.73.0 → 3.74.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-confidence-filter.d.ts +5 -0
  6. package/dist/commands/finding-confidence-filter.d.ts.map +1 -0
  7. package/dist/commands/finding-confidence-filter.js +78 -0
  8. package/dist/commands/finding-confidence-filter.js.map +1 -0
  9. package/dist/commands/finding-export-csv.d.ts +5 -0
  10. package/dist/commands/finding-export-csv.d.ts.map +1 -0
  11. package/dist/commands/finding-export-csv.js +79 -0
  12. package/dist/commands/finding-export-csv.js.map +1 -0
  13. package/dist/commands/finding-resolution.d.ts +5 -0
  14. package/dist/commands/finding-resolution.d.ts.map +1 -0
  15. package/dist/commands/finding-resolution.js +143 -0
  16. package/dist/commands/finding-resolution.js.map +1 -0
  17. package/dist/commands/review-note.d.ts +5 -0
  18. package/dist/commands/review-note.d.ts.map +1 -0
  19. package/dist/commands/review-note.js +105 -0
  20. package/dist/commands/review-note.js.map +1 -0
  21. package/dist/commands/review-owner.d.ts +5 -0
  22. package/dist/commands/review-owner.d.ts.map +1 -0
  23. package/dist/commands/review-owner.js +130 -0
  24. package/dist/commands/review-owner.js.map +1 -0
  25. package/dist/commands/review-skip-rule.d.ts +5 -0
  26. package/dist/commands/review-skip-rule.d.ts.map +1 -0
  27. package/dist/commands/review-skip-rule.js +106 -0
  28. package/dist/commands/review-skip-rule.js.map +1 -0
  29. package/dist/commands/review-snapshot-diff.d.ts +5 -0
  30. package/dist/commands/review-snapshot-diff.d.ts.map +1 -0
  31. package/dist/commands/review-snapshot-diff.js +101 -0
  32. package/dist/commands/review-snapshot-diff.js.map +1 -0
  33. package/dist/commands/review-timeline.d.ts +5 -0
  34. package/dist/commands/review-timeline.d.ts.map +1 -0
  35. package/dist/commands/review-timeline.js +77 -0
  36. package/dist/commands/review-timeline.js.map +1 -0
  37. package/package.json +1 -1
  38. package/server.json +2 -2
@@ -0,0 +1,106 @@
1
+ /**
2
+ * Review-skip-rule — Quick skip/disable specific rules for a session.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
5
+ import { dirname } from "path";
6
+ // ─── Storage ────────────────────────────────────────────────────────────────
7
+ const SKIP_FILE = ".judges/skip-rules.json";
8
+ function loadStore() {
9
+ if (!existsSync(SKIP_FILE))
10
+ return { version: "1.0.0", skippedRules: [] };
11
+ try {
12
+ return JSON.parse(readFileSync(SKIP_FILE, "utf-8"));
13
+ }
14
+ catch {
15
+ return { version: "1.0.0", skippedRules: [] };
16
+ }
17
+ }
18
+ function saveStore(store) {
19
+ mkdirSync(dirname(SKIP_FILE), { recursive: true });
20
+ writeFileSync(SKIP_FILE, JSON.stringify(store, null, 2), "utf-8");
21
+ }
22
+ // ─── CLI ────────────────────────────────────────────────────────────────────
23
+ export function runReviewSkipRule(argv) {
24
+ if (argv.includes("--help") || argv.includes("-h")) {
25
+ console.log(`
26
+ judges review-skip-rule — Quick skip/disable specific rules
27
+
28
+ Usage:
29
+ judges review-skip-rule add --rule SEC-001
30
+ judges review-skip-rule add --rules SEC-001,SEC-002,PERF-003
31
+ judges review-skip-rule list
32
+ judges review-skip-rule remove --rule SEC-001
33
+ judges review-skip-rule clear
34
+
35
+ Subcommands:
36
+ add Skip one or more rules
37
+ list List skipped rules
38
+ remove Re-enable a rule
39
+ clear Clear all skips
40
+
41
+ Options:
42
+ --rule <id> Single rule ID
43
+ --rules <ids> Comma-separated rule IDs
44
+ --format json JSON output
45
+ --help, -h Show this help
46
+
47
+ Skipped rules stored in .judges/skip-rules.json.
48
+ `);
49
+ return;
50
+ }
51
+ const subcommand = argv.find((a) => ["add", "list", "remove", "clear"].includes(a));
52
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
53
+ const store = loadStore();
54
+ if (subcommand === "add") {
55
+ const single = argv.find((_a, i) => argv[i - 1] === "--rule") || "";
56
+ const multi = argv.find((_a, i) => argv[i - 1] === "--rules") || "";
57
+ const rules = [
58
+ ...(single ? [single] : []),
59
+ ...multi
60
+ .split(",")
61
+ .map((r) => r.trim())
62
+ .filter(Boolean),
63
+ ];
64
+ if (rules.length === 0) {
65
+ console.log("Specify --rule or --rules.");
66
+ return;
67
+ }
68
+ let added = 0;
69
+ for (const r of rules) {
70
+ if (!store.skippedRules.includes(r)) {
71
+ store.skippedRules.push(r);
72
+ added++;
73
+ }
74
+ }
75
+ saveStore(store);
76
+ console.log(`Skipped ${added} rule(s). Total skipped: ${store.skippedRules.length}`);
77
+ return;
78
+ }
79
+ if (subcommand === "remove") {
80
+ const rule = argv.find((_a, i) => argv[i - 1] === "--rule") || "";
81
+ const before = store.skippedRules.length;
82
+ store.skippedRules = store.skippedRules.filter((r) => r !== rule);
83
+ saveStore(store);
84
+ console.log(before > store.skippedRules.length ? `Re-enabled ${rule}.` : `${rule} was not skipped.`);
85
+ return;
86
+ }
87
+ if (subcommand === "clear") {
88
+ saveStore({ version: "1.0.0", skippedRules: [] });
89
+ console.log("All rule skips cleared.");
90
+ return;
91
+ }
92
+ // Default: list
93
+ if (store.skippedRules.length === 0) {
94
+ console.log("No rules skipped.");
95
+ return;
96
+ }
97
+ if (format === "json") {
98
+ console.log(JSON.stringify(store.skippedRules, null, 2));
99
+ return;
100
+ }
101
+ console.log(`\nSkipped Rules (${store.skippedRules.length}):`);
102
+ for (const r of store.skippedRules) {
103
+ console.log(` - ${r}`);
104
+ }
105
+ }
106
+ //# sourceMappingURL=review-skip-rule.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-skip-rule.js","sourceRoot":"","sources":["../../src/commands/review-skip-rule.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-snapshot-diff — Diff between review snapshots.
3
+ */
4
+ export declare function runReviewSnapshotDiff(argv: string[]): void;
5
+ //# sourceMappingURL=review-snapshot-diff.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-snapshot-diff.d.ts","sourceRoot":"","sources":["../../src/commands/review-snapshot-diff.ts"],"names":[],"mappings":"AAAA;;GAEG;AAkCH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA0F1D"}
@@ -0,0 +1,101 @@
1
+ /**
2
+ * Review-snapshot-diff — Diff between review snapshots.
3
+ */
4
+ import { readFileSync, existsSync } from "fs";
5
+ // ─── Helpers ────────────────────────────────────────────────────────────────
6
+ function loadSnapshot(filePath) {
7
+ if (!existsSync(filePath))
8
+ return null;
9
+ try {
10
+ const data = JSON.parse(readFileSync(filePath, "utf-8"));
11
+ const findings = Array.isArray(data.findings) ? data.findings : [];
12
+ const ruleIds = findings.map((f) => f.ruleId || "").filter(Boolean);
13
+ return {
14
+ score: typeof data.overallScore === "number" ? data.overallScore : 0,
15
+ findingCount: findings.length,
16
+ ruleIds,
17
+ timestamp: typeof data.timestamp === "string" ? data.timestamp : "unknown",
18
+ };
19
+ }
20
+ catch {
21
+ return null;
22
+ }
23
+ }
24
+ // ─── CLI ────────────────────────────────────────────────────────────────────
25
+ export function runReviewSnapshotDiff(argv) {
26
+ if (argv.includes("--help") || argv.includes("-h")) {
27
+ console.log(`
28
+ judges review-snapshot-diff — Diff between review snapshots
29
+
30
+ Usage:
31
+ judges review-snapshot-diff --a snapshot1.json --b snapshot2.json
32
+
33
+ Options:
34
+ --a <path> First snapshot (earlier)
35
+ --b <path> Second snapshot (later)
36
+ --format json JSON output
37
+ --help, -h Show this help
38
+
39
+ Compares two review snapshot files and shows what changed.
40
+ `);
41
+ return;
42
+ }
43
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
44
+ const pathA = argv.find((_a, i) => argv[i - 1] === "--a") || "";
45
+ const pathB = argv.find((_a, i) => argv[i - 1] === "--b") || "";
46
+ if (!pathA || !pathB) {
47
+ console.log("Specify --a and --b snapshot file paths.");
48
+ return;
49
+ }
50
+ const snapA = loadSnapshot(pathA);
51
+ const snapB = loadSnapshot(pathB);
52
+ if (!snapA) {
53
+ console.log(`Cannot load: ${pathA}`);
54
+ return;
55
+ }
56
+ if (!snapB) {
57
+ console.log(`Cannot load: ${pathB}`);
58
+ return;
59
+ }
60
+ const setA = new Set(snapA.ruleIds);
61
+ const setB = new Set(snapB.ruleIds);
62
+ const added = snapB.ruleIds.filter((r) => !setA.has(r));
63
+ const removed = snapA.ruleIds.filter((r) => !setB.has(r));
64
+ const scoreDelta = snapB.score - snapA.score;
65
+ if (format === "json") {
66
+ console.log(JSON.stringify({
67
+ scoreA: snapA.score,
68
+ scoreB: snapB.score,
69
+ scoreDelta,
70
+ findingsA: snapA.findingCount,
71
+ findingsB: snapB.findingCount,
72
+ addedRules: added,
73
+ removedRules: removed,
74
+ }, null, 2));
75
+ return;
76
+ }
77
+ const arrow = scoreDelta > 0 ? "↗" : scoreDelta < 0 ? "↘" : "→";
78
+ console.log("\nSnapshot Diff:");
79
+ console.log("═".repeat(55));
80
+ console.log(` A: ${pathA} (${snapA.timestamp.slice(0, 10)})`);
81
+ console.log(` B: ${pathB} (${snapB.timestamp.slice(0, 10)})`);
82
+ console.log("");
83
+ console.log(` Score: ${snapA.score.toFixed(1)} → ${snapB.score.toFixed(1)} (${scoreDelta > 0 ? "+" : ""}${scoreDelta.toFixed(1)} ${arrow})`);
84
+ console.log(` Findings: ${snapA.findingCount} → ${snapB.findingCount}`);
85
+ if (added.length > 0) {
86
+ console.log(`\n New rules in B (${added.length}):`);
87
+ for (const r of added.slice(0, 10))
88
+ console.log(` + ${r}`);
89
+ if (added.length > 10)
90
+ console.log(` ... and ${added.length - 10} more`);
91
+ }
92
+ if (removed.length > 0) {
93
+ console.log(`\n Resolved in B (${removed.length}):`);
94
+ for (const r of removed.slice(0, 10))
95
+ console.log(` - ${r}`);
96
+ if (removed.length > 10)
97
+ console.log(` ... and ${removed.length - 10} more`);
98
+ }
99
+ console.log("═".repeat(55));
100
+ }
101
+ //# sourceMappingURL=review-snapshot-diff.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-snapshot-diff.js","sourceRoot":"","sources":["../../src/commands/review-snapshot-diff.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-timeline — Show review activity timeline.
3
+ */
4
+ export declare function runReviewTimeline(argv: string[]): void;
5
+ //# sourceMappingURL=review-timeline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-timeline.d.ts","sourceRoot":"","sources":["../../src/commands/review-timeline.ts"],"names":[],"mappings":"AAAA;;GAEG;AAeH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA4EtD"}
@@ -0,0 +1,77 @@
1
+ /**
2
+ * Review-timeline — Show review activity timeline.
3
+ */
4
+ import { readFileSync, existsSync, readdirSync } from "fs";
5
+ // ─── CLI ────────────────────────────────────────────────────────────────────
6
+ export function runReviewTimeline(argv) {
7
+ if (argv.includes("--help") || argv.includes("-h")) {
8
+ console.log(`
9
+ judges review-timeline — Show review activity timeline
10
+
11
+ Usage:
12
+ judges review-timeline
13
+ judges review-timeline --dir .judges/results
14
+ judges review-timeline --last 10
15
+
16
+ Options:
17
+ --dir <path> Results directory (default: .judges/results)
18
+ --last <n> Show last N entries
19
+ --format json JSON output
20
+ --help, -h Show this help
21
+
22
+ Scans review result files and displays a chronological timeline.
23
+ `);
24
+ return;
25
+ }
26
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
27
+ const dir = argv.find((_a, i) => argv[i - 1] === "--dir") || ".judges/results";
28
+ const last = parseInt(argv.find((_a, i) => argv[i - 1] === "--last") || "0", 10);
29
+ if (!existsSync(dir)) {
30
+ console.log(`Results directory not found: ${dir}`);
31
+ return;
32
+ }
33
+ const entries = [];
34
+ try {
35
+ const files = readdirSync(dir);
36
+ for (const f of files) {
37
+ if (!String(f).endsWith(".json"))
38
+ continue;
39
+ try {
40
+ const content = JSON.parse(readFileSync(`${dir}/${String(f)}`, "utf-8"));
41
+ entries.push({
42
+ date: typeof content.timestamp === "string" ? content.timestamp : "unknown",
43
+ file: String(f),
44
+ score: typeof content.overallScore === "number" ? content.overallScore : 0,
45
+ findings: Array.isArray(content.findings) ? content.findings.length : 0,
46
+ });
47
+ }
48
+ catch {
49
+ // Skip unparseable
50
+ }
51
+ }
52
+ }
53
+ catch {
54
+ console.log(`Cannot read: ${dir}`);
55
+ return;
56
+ }
57
+ // Sort by date
58
+ entries.sort((a, b) => a.date.localeCompare(b.date));
59
+ const display = last > 0 ? entries.slice(-last) : entries;
60
+ if (display.length === 0) {
61
+ console.log("No review entries found.");
62
+ return;
63
+ }
64
+ if (format === "json") {
65
+ console.log(JSON.stringify(display, null, 2));
66
+ return;
67
+ }
68
+ console.log("\nReview Timeline:");
69
+ console.log("═".repeat(65));
70
+ for (const e of display) {
71
+ const bar = "█".repeat(Math.round(e.score));
72
+ console.log(` ${e.date.slice(0, 16)} ${bar.padEnd(10)} ${e.score.toFixed(1)} findings=${e.findings} ${e.file}`);
73
+ }
74
+ console.log("═".repeat(65));
75
+ console.log(`${display.length} entries shown.`);
76
+ }
77
+ //# sourceMappingURL=review-timeline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-timeline.js","sourceRoot":"","sources":["../../src/commands/review-timeline.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.73.0",
3
+ "version": "3.74.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.73.0",
10
+ "version": "3.74.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "@kevinrabun/judges",
15
- "version": "3.73.0",
15
+ "version": "3.74.0",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }