@kevinrabun/judges 3.80.0 → 3.82.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 (78) hide show
  1. package/CHANGELOG.md +26 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +126 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/finding-age-tracker.d.ts +8 -0
  6. package/dist/commands/finding-age-tracker.d.ts.map +1 -0
  7. package/dist/commands/finding-age-tracker.js +153 -0
  8. package/dist/commands/finding-age-tracker.js.map +1 -0
  9. package/dist/commands/finding-cwe-map.d.ts +5 -0
  10. package/dist/commands/finding-cwe-map.d.ts.map +1 -0
  11. package/dist/commands/finding-cwe-map.js +134 -0
  12. package/dist/commands/finding-cwe-map.js.map +1 -0
  13. package/dist/commands/finding-duplicate-rule.d.ts +5 -0
  14. package/dist/commands/finding-duplicate-rule.d.ts.map +1 -0
  15. package/dist/commands/finding-duplicate-rule.js +104 -0
  16. package/dist/commands/finding-duplicate-rule.js.map +1 -0
  17. package/dist/commands/finding-false-neg-check.d.ts +9 -0
  18. package/dist/commands/finding-false-neg-check.d.ts.map +1 -0
  19. package/dist/commands/finding-false-neg-check.js +140 -0
  20. package/dist/commands/finding-false-neg-check.js.map +1 -0
  21. package/dist/commands/finding-line-blame.d.ts +8 -0
  22. package/dist/commands/finding-line-blame.d.ts.map +1 -0
  23. package/dist/commands/finding-line-blame.js +133 -0
  24. package/dist/commands/finding-line-blame.js.map +1 -0
  25. package/dist/commands/finding-pattern-match.d.ts +5 -0
  26. package/dist/commands/finding-pattern-match.d.ts.map +1 -0
  27. package/dist/commands/finding-pattern-match.js +166 -0
  28. package/dist/commands/finding-pattern-match.js.map +1 -0
  29. package/dist/commands/finding-risk-matrix.d.ts +5 -0
  30. package/dist/commands/finding-risk-matrix.d.ts.map +1 -0
  31. package/dist/commands/finding-risk-matrix.js +127 -0
  32. package/dist/commands/finding-risk-matrix.js.map +1 -0
  33. package/dist/commands/finding-summary-digest.d.ts +8 -0
  34. package/dist/commands/finding-summary-digest.d.ts.map +1 -0
  35. package/dist/commands/finding-summary-digest.js +146 -0
  36. package/dist/commands/finding-summary-digest.js.map +1 -0
  37. package/dist/commands/review-code-owner.d.ts +8 -0
  38. package/dist/commands/review-code-owner.d.ts.map +1 -0
  39. package/dist/commands/review-code-owner.js +165 -0
  40. package/dist/commands/review-code-owner.js.map +1 -0
  41. package/dist/commands/review-dependency-graph.d.ts +5 -0
  42. package/dist/commands/review-dependency-graph.d.ts.map +1 -0
  43. package/dist/commands/review-dependency-graph.js +95 -0
  44. package/dist/commands/review-dependency-graph.js.map +1 -0
  45. package/dist/commands/review-diff-stats.d.ts +5 -0
  46. package/dist/commands/review-diff-stats.d.ts.map +1 -0
  47. package/dist/commands/review-diff-stats.js +91 -0
  48. package/dist/commands/review-diff-stats.js.map +1 -0
  49. package/dist/commands/review-exclude-vendor.d.ts +5 -0
  50. package/dist/commands/review-exclude-vendor.d.ts.map +1 -0
  51. package/dist/commands/review-exclude-vendor.js +159 -0
  52. package/dist/commands/review-exclude-vendor.js.map +1 -0
  53. package/dist/commands/review-export-pdf.d.ts +8 -0
  54. package/dist/commands/review-export-pdf.d.ts.map +1 -0
  55. package/dist/commands/review-export-pdf.js +132 -0
  56. package/dist/commands/review-export-pdf.js.map +1 -0
  57. package/dist/commands/review-file-stats.d.ts +5 -0
  58. package/dist/commands/review-file-stats.d.ts.map +1 -0
  59. package/dist/commands/review-file-stats.js +131 -0
  60. package/dist/commands/review-file-stats.js.map +1 -0
  61. package/dist/commands/review-parallel-files.d.ts +8 -0
  62. package/dist/commands/review-parallel-files.d.ts.map +1 -0
  63. package/dist/commands/review-parallel-files.js +135 -0
  64. package/dist/commands/review-parallel-files.js.map +1 -0
  65. package/dist/commands/review-rule-filter.d.ts +5 -0
  66. package/dist/commands/review-rule-filter.d.ts.map +1 -0
  67. package/dist/commands/review-rule-filter.js +117 -0
  68. package/dist/commands/review-rule-filter.js.map +1 -0
  69. package/dist/commands/review-scope-lock.d.ts +8 -0
  70. package/dist/commands/review-scope-lock.d.ts.map +1 -0
  71. package/dist/commands/review-scope-lock.js +139 -0
  72. package/dist/commands/review-scope-lock.js.map +1 -0
  73. package/dist/commands/review-watch-mode.d.ts +8 -0
  74. package/dist/commands/review-watch-mode.d.ts.map +1 -0
  75. package/dist/commands/review-watch-mode.js +133 -0
  76. package/dist/commands/review-watch-mode.js.map +1 -0
  77. package/package.json +1 -1
  78. package/server.json +2 -2
@@ -0,0 +1,139 @@
1
+ /**
2
+ * Review-scope-lock — Lock review scope to specific files or directories.
3
+ *
4
+ * Prevents accidental review of out-of-scope code by maintaining
5
+ * a local scope configuration.
6
+ */
7
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
8
+ import { dirname, join } from "path";
9
+ // ─── Helpers ────────────────────────────────────────────────────────────────
10
+ function scopeFile() {
11
+ return join(process.cwd(), ".judges", "scope-lock.json");
12
+ }
13
+ function loadScope() {
14
+ const f = scopeFile();
15
+ if (!existsSync(f))
16
+ return { includes: [], excludes: [], lockedAt: "" };
17
+ try {
18
+ return JSON.parse(readFileSync(f, "utf-8"));
19
+ }
20
+ catch {
21
+ return { includes: [], excludes: [], lockedAt: "" };
22
+ }
23
+ }
24
+ function saveScope(scope) {
25
+ const f = scopeFile();
26
+ const d = dirname(f);
27
+ if (!existsSync(d))
28
+ mkdirSync(d, { recursive: true });
29
+ writeFileSync(f, JSON.stringify(scope, null, 2));
30
+ }
31
+ function fileInScope(filePath, scope) {
32
+ if (scope.excludes.some((e) => filePath.startsWith(e) || filePath.includes(e)))
33
+ return false;
34
+ if (scope.includes.length === 0)
35
+ return true;
36
+ return scope.includes.some((inc) => filePath.startsWith(inc) || filePath.includes(inc));
37
+ }
38
+ // ─── CLI ────────────────────────────────────────────────────────────────────
39
+ export function runReviewScopeLock(argv) {
40
+ const sub = argv[0];
41
+ if (!sub || sub === "--help" || sub === "-h") {
42
+ console.log(`
43
+ judges review-scope-lock — Lock review scope
44
+
45
+ Usage:
46
+ judges review-scope-lock show
47
+ judges review-scope-lock add-include <path>
48
+ judges review-scope-lock add-exclude <path>
49
+ judges review-scope-lock remove <path>
50
+ judges review-scope-lock test <file>
51
+ judges review-scope-lock clear
52
+
53
+ Options:
54
+ --help, -h Show this help
55
+ `);
56
+ return;
57
+ }
58
+ const scope = loadScope();
59
+ if (sub === "show") {
60
+ if (scope.includes.length === 0 && scope.excludes.length === 0) {
61
+ console.log("No scope lock configured. All files are in scope.");
62
+ return;
63
+ }
64
+ console.log("\nScope Lock Configuration");
65
+ console.log("═".repeat(50));
66
+ if (scope.includes.length > 0) {
67
+ console.log("Includes:");
68
+ for (const p of scope.includes)
69
+ console.log(` + ${p}`);
70
+ }
71
+ if (scope.excludes.length > 0) {
72
+ console.log("Excludes:");
73
+ for (const p of scope.excludes)
74
+ console.log(` - ${p}`);
75
+ }
76
+ if (scope.lockedAt)
77
+ console.log(`\nLocked at: ${scope.lockedAt}`);
78
+ console.log("═".repeat(50));
79
+ }
80
+ else if (sub === "add-include") {
81
+ const path = argv[1];
82
+ if (!path) {
83
+ console.error("Error: path required");
84
+ process.exitCode = 1;
85
+ return;
86
+ }
87
+ if (!scope.includes.includes(path)) {
88
+ scope.includes.push(path);
89
+ scope.lockedAt = new Date().toISOString();
90
+ saveScope(scope);
91
+ }
92
+ console.log(`Added include: ${path}`);
93
+ }
94
+ else if (sub === "add-exclude") {
95
+ const path = argv[1];
96
+ if (!path) {
97
+ console.error("Error: path required");
98
+ process.exitCode = 1;
99
+ return;
100
+ }
101
+ if (!scope.excludes.includes(path)) {
102
+ scope.excludes.push(path);
103
+ scope.lockedAt = new Date().toISOString();
104
+ saveScope(scope);
105
+ }
106
+ console.log(`Added exclude: ${path}`);
107
+ }
108
+ else if (sub === "remove") {
109
+ const path = argv[1];
110
+ if (!path) {
111
+ console.error("Error: path required");
112
+ process.exitCode = 1;
113
+ return;
114
+ }
115
+ scope.includes = scope.includes.filter((p) => p !== path);
116
+ scope.excludes = scope.excludes.filter((p) => p !== path);
117
+ saveScope(scope);
118
+ console.log(`Removed: ${path}`);
119
+ }
120
+ else if (sub === "test") {
121
+ const file = argv[1];
122
+ if (!file) {
123
+ console.error("Error: file path required");
124
+ process.exitCode = 1;
125
+ return;
126
+ }
127
+ const inScope = fileInScope(file, scope);
128
+ console.log(`${file}: ${inScope ? "IN SCOPE" : "OUT OF SCOPE"}`);
129
+ }
130
+ else if (sub === "clear") {
131
+ saveScope({ includes: [], excludes: [], lockedAt: "" });
132
+ console.log("Scope lock cleared.");
133
+ }
134
+ else {
135
+ console.error(`Unknown subcommand: ${sub}. Use --help for usage.`);
136
+ process.exitCode = 1;
137
+ }
138
+ }
139
+ //# sourceMappingURL=review-scope-lock.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-scope-lock.js","sourceRoot":"","sources":["../../src/commands/review-scope-lock.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Review-watch-mode — Watch files for changes and auto-trigger reviews.
3
+ *
4
+ * Monitors specified directories and re-runs review when files change.
5
+ * Uses polling-based approach for cross-platform compatibility.
6
+ */
7
+ export declare function runReviewWatchMode(argv: string[]): void;
8
+ //# sourceMappingURL=review-watch-mode.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-watch-mode.d.ts","sourceRoot":"","sources":["../../src/commands/review-watch-mode.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAwEH,wBAAgB,kBAAkB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAwEvD"}
@@ -0,0 +1,133 @@
1
+ /**
2
+ * Review-watch-mode — Watch files for changes and auto-trigger reviews.
3
+ *
4
+ * Monitors specified directories and re-runs review when files change.
5
+ * Uses polling-based approach for cross-platform compatibility.
6
+ */
7
+ import { existsSync, statSync, readdirSync } from "fs";
8
+ import { join, extname } from "path";
9
+ // ─── Helpers ────────────────────────────────────────────────────────────────
10
+ const CODE_EXTENSIONS = new Set([
11
+ ".ts",
12
+ ".js",
13
+ ".tsx",
14
+ ".jsx",
15
+ ".py",
16
+ ".java",
17
+ ".go",
18
+ ".rs",
19
+ ".cs",
20
+ ".cpp",
21
+ ".c",
22
+ ".rb",
23
+ ".php",
24
+ ".swift",
25
+ ".kt",
26
+ ]);
27
+ function collectFiles(dir, extensions) {
28
+ const results = [];
29
+ if (!existsSync(dir))
30
+ return results;
31
+ function walk(d) {
32
+ const entries = readdirSync(d);
33
+ for (const entry of entries) {
34
+ const full = join(d, String(entry));
35
+ if (String(entry).startsWith(".") || String(entry) === "node_modules")
36
+ continue;
37
+ try {
38
+ const st = statSync(full);
39
+ if (st.isDirectory())
40
+ walk(full);
41
+ else if (extensions.has(extname(String(entry)))) {
42
+ results.push({ file: full, lastModified: st.mtimeMs });
43
+ }
44
+ }
45
+ catch {
46
+ /* skip inaccessible */
47
+ }
48
+ }
49
+ }
50
+ walk(dir);
51
+ return results;
52
+ }
53
+ function detectChanges(prev, current) {
54
+ const prevMap = new Map(prev.map((s) => [s.file, s.lastModified]));
55
+ const changes = [];
56
+ for (const c of current) {
57
+ const prevTime = prevMap.get(c.file);
58
+ if (prevTime === undefined || prevTime < c.lastModified) {
59
+ changes.push(c.file);
60
+ }
61
+ }
62
+ return changes;
63
+ }
64
+ // ─── CLI ────────────────────────────────────────────────────────────────────
65
+ export function runReviewWatchMode(argv) {
66
+ const dirIdx = argv.indexOf("--dir");
67
+ const intervalIdx = argv.indexOf("--interval");
68
+ const extIdx = argv.indexOf("--ext");
69
+ const dryRunFlag = argv.includes("--dry-run");
70
+ const dir = dirIdx >= 0 ? argv[dirIdx + 1] : process.cwd();
71
+ const interval = intervalIdx >= 0 ? parseInt(argv[intervalIdx + 1], 10) : 5000;
72
+ const extFilter = extIdx >= 0 ? new Set(argv[extIdx + 1].split(",").map((e) => (e.startsWith(".") ? e : `.${e}`))) : CODE_EXTENSIONS;
73
+ if (argv.includes("--help") || argv.includes("-h")) {
74
+ console.log(`
75
+ judges review-watch-mode — Watch files and auto-trigger reviews
76
+
77
+ Usage:
78
+ judges review-watch-mode [--dir <path>] [--interval <ms>] [--ext <exts>]
79
+ [--dry-run]
80
+
81
+ Options:
82
+ --dir <path> Directory to watch (default: current directory)
83
+ --interval <ms> Poll interval in milliseconds (default: 5000)
84
+ --ext <exts> Comma-separated extensions to watch (default: common code)
85
+ --dry-run Show what would be reviewed without running
86
+ --help, -h Show this help
87
+
88
+ Press Ctrl+C to stop watching.
89
+ `);
90
+ return;
91
+ }
92
+ if (!existsSync(dir)) {
93
+ console.error(`Error: directory not found: ${dir}`);
94
+ process.exitCode = 1;
95
+ return;
96
+ }
97
+ console.log(`\nWatch Mode Active`);
98
+ console.log("═".repeat(50));
99
+ console.log(`Directory: ${dir}`);
100
+ console.log(`Interval: ${interval}ms`);
101
+ console.log(`Extensions: ${[...extFilter].join(", ")}`);
102
+ console.log("═".repeat(50));
103
+ let state = collectFiles(dir, extFilter);
104
+ console.log(`Tracking ${state.length} files. Waiting for changes...`);
105
+ if (dryRunFlag) {
106
+ console.log("\n[DRY RUN] Would watch the following files:");
107
+ for (const s of state.slice(0, 20))
108
+ console.log(` ${s.file}`);
109
+ if (state.length > 20)
110
+ console.log(` ... and ${state.length - 20} more`);
111
+ return;
112
+ }
113
+ const timer = setInterval(() => {
114
+ const current = collectFiles(dir, extFilter);
115
+ const changes = detectChanges(state, current);
116
+ if (changes.length > 0) {
117
+ const ts = new Date().toLocaleTimeString();
118
+ console.log(`\n[${ts}] ${changes.length} file(s) changed:`);
119
+ for (const f of changes.slice(0, 5))
120
+ console.log(` → ${f}`);
121
+ if (changes.length > 5)
122
+ console.log(` ... and ${changes.length - 5} more`);
123
+ console.log(" Run: judges eval --file <changed-file> to review");
124
+ state = current;
125
+ }
126
+ }, interval);
127
+ process.on("SIGINT", () => {
128
+ clearInterval(timer);
129
+ console.log("\nWatch mode stopped.");
130
+ process.exit(0);
131
+ });
132
+ }
133
+ //# sourceMappingURL=review-watch-mode.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-watch-mode.js","sourceRoot":"","sources":["../../src/commands/review-watch-mode.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.80.0",
3
+ "version": "3.82.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.80.0",
10
+ "version": "3.82.0",
11
11
  "packages": [
12
12
  {
13
13
  "registryType": "npm",
14
14
  "identifier": "@kevinrabun/judges",
15
- "version": "3.80.0",
15
+ "version": "3.82.0",
16
16
  "transport": {
17
17
  "type": "stdio"
18
18
  }