@kevinrabun/judges 3.2.0 → 3.4.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 (57) hide show
  1. package/README.md +131 -7
  2. package/dist/ast/index.d.ts +7 -8
  3. package/dist/ast/index.d.ts.map +1 -1
  4. package/dist/ast/index.js +16 -18
  5. package/dist/ast/index.js.map +1 -1
  6. package/dist/ast/tree-sitter-ast.d.ts.map +1 -1
  7. package/dist/ast/tree-sitter-ast.js +215 -9
  8. package/dist/ast/tree-sitter-ast.js.map +1 -1
  9. package/dist/cli.d.ts +8 -1
  10. package/dist/cli.d.ts.map +1 -1
  11. package/dist/cli.js +169 -11
  12. package/dist/cli.js.map +1 -1
  13. package/dist/commands/ci-templates.d.ts +10 -0
  14. package/dist/commands/ci-templates.d.ts.map +1 -0
  15. package/dist/commands/ci-templates.js +90 -0
  16. package/dist/commands/ci-templates.js.map +1 -0
  17. package/dist/commands/fix.d.ts +21 -0
  18. package/dist/commands/fix.d.ts.map +1 -0
  19. package/dist/commands/fix.js +189 -0
  20. package/dist/commands/fix.js.map +1 -0
  21. package/dist/commands/hook.d.ts +9 -0
  22. package/dist/commands/hook.d.ts.map +1 -0
  23. package/dist/commands/hook.js +149 -0
  24. package/dist/commands/hook.js.map +1 -0
  25. package/dist/commands/init.d.ts +11 -0
  26. package/dist/commands/init.d.ts.map +1 -0
  27. package/dist/commands/init.js +266 -0
  28. package/dist/commands/init.js.map +1 -0
  29. package/dist/commands/report.d.ts +13 -0
  30. package/dist/commands/report.d.ts.map +1 -0
  31. package/dist/commands/report.js +140 -0
  32. package/dist/commands/report.js.map +1 -0
  33. package/dist/commands/watch.d.ts +18 -0
  34. package/dist/commands/watch.d.ts.map +1 -0
  35. package/dist/commands/watch.js +183 -0
  36. package/dist/commands/watch.js.map +1 -0
  37. package/dist/evaluators/code-structure.d.ts +3 -3
  38. package/dist/evaluators/code-structure.js +3 -3
  39. package/dist/formatters/html.d.ts +13 -0
  40. package/dist/formatters/html.d.ts.map +1 -0
  41. package/dist/formatters/html.js +219 -0
  42. package/dist/formatters/html.js.map +1 -0
  43. package/dist/index.js +8 -3
  44. package/dist/index.js.map +1 -1
  45. package/dist/language-patterns.d.ts.map +1 -1
  46. package/dist/language-patterns.js +8 -0
  47. package/dist/language-patterns.js.map +1 -1
  48. package/dist/types.d.ts +1 -1
  49. package/dist/types.d.ts.map +1 -1
  50. package/grammars/tree-sitter-cpp.wasm +0 -0
  51. package/grammars/tree-sitter-typescript.wasm +0 -0
  52. package/package.json +3 -1
  53. package/server.json +2 -2
  54. package/dist/ast/typescript-ast.d.ts +0 -7
  55. package/dist/ast/typescript-ast.d.ts.map +0 -1
  56. package/dist/ast/typescript-ast.js +0 -236
  57. package/dist/ast/typescript-ast.js.map +0 -1
@@ -0,0 +1,18 @@
1
+ /**
2
+ * `judges watch` — Watch files for changes and re-evaluate.
3
+ *
4
+ * Usage:
5
+ * judges watch src/ # Watch directory
6
+ * judges watch src/app.ts # Watch single file
7
+ * judges watch src/ --judge cyber # Single judge only
8
+ * judges watch src/ --fail-on-findings # Exit 1 on first failure
9
+ */
10
+ interface WatchArgs {
11
+ path: string;
12
+ judge: string | undefined;
13
+ failOnFindings: boolean;
14
+ }
15
+ export declare function parseWatchArgs(argv: string[]): WatchArgs;
16
+ export declare function runWatch(argv: string[]): void;
17
+ export {};
18
+ //# sourceMappingURL=watch.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.d.ts","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAwDH,UAAU,SAAS;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,GAAG,SAAS,CAAC;IAC1B,cAAc,EAAE,OAAO,CAAC;CACzB;AAED,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,SAAS,CAyBxD;AAyDD,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA0D7C"}
@@ -0,0 +1,183 @@
1
+ /**
2
+ * `judges watch` — Watch files for changes and re-evaluate.
3
+ *
4
+ * Usage:
5
+ * judges watch src/ # Watch directory
6
+ * judges watch src/app.ts # Watch single file
7
+ * judges watch src/ --judge cyber # Single judge only
8
+ * judges watch src/ --fail-on-findings # Exit 1 on first failure
9
+ */
10
+ import { existsSync, readFileSync, statSync, watch as fsWatch } from "fs";
11
+ import { resolve, extname, join, relative } from "path";
12
+ import { evaluateWithTribunal, evaluateWithJudge } from "../evaluators/index.js";
13
+ import { getJudge } from "../judges/index.js";
14
+ // ─── Language Detection ─────────────────────────────────────────────────────
15
+ const WATCH_EXTENSIONS = new Set([
16
+ ".ts",
17
+ ".tsx",
18
+ ".js",
19
+ ".jsx",
20
+ ".mjs",
21
+ ".cjs",
22
+ ".py",
23
+ ".rs",
24
+ ".go",
25
+ ".java",
26
+ ".cs",
27
+ ".cpp",
28
+ ".cc",
29
+ ".cxx",
30
+ ".h",
31
+ ".hpp",
32
+ ]);
33
+ const EXT_TO_LANG = {
34
+ ".ts": "typescript",
35
+ ".tsx": "typescript",
36
+ ".js": "javascript",
37
+ ".jsx": "javascript",
38
+ ".mjs": "javascript",
39
+ ".cjs": "javascript",
40
+ ".py": "python",
41
+ ".rs": "rust",
42
+ ".go": "go",
43
+ ".java": "java",
44
+ ".cs": "csharp",
45
+ ".cpp": "cpp",
46
+ ".cc": "cpp",
47
+ ".cxx": "cpp",
48
+ ".h": "c",
49
+ ".hpp": "cpp",
50
+ };
51
+ function detectLanguage(filePath) {
52
+ const ext = extname(filePath.toLowerCase());
53
+ return EXT_TO_LANG[ext] || "typescript";
54
+ }
55
+ export function parseWatchArgs(argv) {
56
+ const args = {
57
+ path: ".",
58
+ judge: undefined,
59
+ failOnFindings: false,
60
+ };
61
+ for (let i = 3; i < argv.length; i++) {
62
+ const arg = argv[i];
63
+ switch (arg) {
64
+ case "--judge":
65
+ case "-j":
66
+ args.judge = argv[++i];
67
+ break;
68
+ case "--fail-on-findings":
69
+ args.failOnFindings = true;
70
+ break;
71
+ default:
72
+ if (!arg.startsWith("-")) {
73
+ args.path = arg;
74
+ }
75
+ break;
76
+ }
77
+ }
78
+ return args;
79
+ }
80
+ // ─── Evaluate a Single File ────────────────────────────────────────────────
81
+ function evaluateFile(filePath, language, judgeId) {
82
+ const code = readFileSync(filePath, "utf-8");
83
+ const rel = relative(process.cwd(), filePath);
84
+ let findings;
85
+ let score;
86
+ let verdict;
87
+ if (judgeId) {
88
+ const judge = getJudge(judgeId);
89
+ if (!judge) {
90
+ console.error(` Unknown judge: ${judgeId}`);
91
+ return;
92
+ }
93
+ const evaluation = evaluateWithJudge(judge, code, language);
94
+ findings = evaluation.findings;
95
+ score = evaluation.score;
96
+ verdict = evaluation.verdict;
97
+ }
98
+ else {
99
+ const result = evaluateWithTribunal(code, language);
100
+ findings = result.evaluations.flatMap((e) => e.findings);
101
+ score = result.overallScore;
102
+ verdict = result.overallVerdict;
103
+ }
104
+ const critical = findings.filter((f) => f.severity === "critical").length;
105
+ const high = findings.filter((f) => f.severity === "high").length;
106
+ const icon = verdict === "pass" ? "✅" : verdict === "warning" ? "⚠️ " : "❌";
107
+ const time = new Date().toLocaleTimeString();
108
+ console.log(` ${icon} [${time}] ${rel} ${score}/100 ${findings.length} findings (${critical}C ${high}H)`);
109
+ // Show top 3 critical/high findings inline
110
+ const topFindings = findings.filter((f) => f.severity === "critical" || f.severity === "high").slice(0, 3);
111
+ for (const f of topFindings) {
112
+ const line = f.lineNumbers?.[0] ? `:${f.lineNumbers[0]}` : "";
113
+ console.log(` ${f.ruleId}${line}: ${f.title}`);
114
+ }
115
+ }
116
+ // ─── Debounce Helper ────────────────────────────────────────────────────────
117
+ function debounce(fn, ms) {
118
+ let timer;
119
+ return () => {
120
+ if (timer)
121
+ clearTimeout(timer);
122
+ timer = setTimeout(fn, ms);
123
+ };
124
+ }
125
+ // ─── Main Watch Command ────────────────────────────────────────────────────
126
+ export function runWatch(argv) {
127
+ const args = parseWatchArgs(argv);
128
+ const target = resolve(args.path);
129
+ if (!existsSync(target)) {
130
+ console.error(`Error: Path not found: ${target}`);
131
+ process.exit(1);
132
+ }
133
+ console.log("");
134
+ console.log("╔══════════════════════════════════════════════════════════════╗");
135
+ console.log("║ Judges Panel — Watch Mode ║");
136
+ console.log("╚══════════════════════════════════════════════════════════════╝");
137
+ console.log("");
138
+ console.log(` Watching: ${args.path}`);
139
+ if (args.judge)
140
+ console.log(` Judge : ${args.judge}`);
141
+ console.log(" Press Ctrl+C to stop.\n");
142
+ const isDir = statSync(target).isDirectory();
143
+ if (isDir) {
144
+ // Watch directory recursively
145
+ const watcher = fsWatch(target, { recursive: true });
146
+ watcher.on("change", (_event, filename) => {
147
+ if (!filename)
148
+ return;
149
+ const fname = filename.toString();
150
+ const ext = extname(fname).toLowerCase();
151
+ if (!WATCH_EXTENSIONS.has(ext))
152
+ return;
153
+ const fullPath = join(target, fname);
154
+ if (!existsSync(fullPath))
155
+ return;
156
+ const debouncedEval = debounce(() => {
157
+ try {
158
+ evaluateFile(fullPath, detectLanguage(fname), args.judge);
159
+ }
160
+ catch (err) {
161
+ console.error(` Error evaluating ${fname}:`, err);
162
+ }
163
+ }, 300);
164
+ debouncedEval();
165
+ });
166
+ }
167
+ else {
168
+ // Watch single file
169
+ const debouncedEval = debounce(() => {
170
+ try {
171
+ evaluateFile(target, detectLanguage(target), args.judge);
172
+ }
173
+ catch (err) {
174
+ console.error(` Error evaluating ${args.path}:`, err);
175
+ }
176
+ }, 300);
177
+ const watcher = fsWatch(target);
178
+ watcher.on("change", () => debouncedEval());
179
+ // Run initial evaluation
180
+ evaluateFile(target, detectLanguage(target), args.judge);
181
+ }
182
+ }
183
+ //# sourceMappingURL=watch.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"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"}
@@ -2,9 +2,9 @@ import type { Finding } from "../types.js";
2
2
  /**
3
3
  * AST / Structure-based evaluator.
4
4
  *
5
- * Unlike the regex-based evaluators this judge uses real AST parsing for
6
- * JS/TS (via the TypeScript compiler API) and a scope-tracking structural
7
- * parser for Python, Rust, Go, Java, and C#.
5
+ * Unlike the regex-based evaluators this judge uses real AST parsing via
6
+ * tree-sitter WASM grammars for TypeScript, JavaScript, Python, Rust, Go,
7
+ * Java, C#, and C++, with a scope-tracking structural parser as fallback.
8
8
  *
9
9
  * Rules produced:
10
10
  * STRUCT-001 High cyclomatic complexity (>10 per function)
@@ -2,9 +2,9 @@ import { analyzeStructure } from "../ast/index.js";
2
2
  /**
3
3
  * AST / Structure-based evaluator.
4
4
  *
5
- * Unlike the regex-based evaluators this judge uses real AST parsing for
6
- * JS/TS (via the TypeScript compiler API) and a scope-tracking structural
7
- * parser for Python, Rust, Go, Java, and C#.
5
+ * Unlike the regex-based evaluators this judge uses real AST parsing via
6
+ * tree-sitter WASM grammars for TypeScript, JavaScript, Python, Rust, Go,
7
+ * Java, C#, and C++, with a scope-tracking structural parser as fallback.
8
8
  *
9
9
  * Rules produced:
10
10
  * STRUCT-001 High cyclomatic complexity (>10 per function)
@@ -0,0 +1,13 @@
1
+ /**
2
+ * HTML Report Formatter — Self-contained HTML output with inline CSS.
3
+ *
4
+ * Generates a single-file HTML report with:
5
+ * - Executive summary with score gauge
6
+ * - Severity filter toggles
7
+ * - Per-judge accordion drill-down
8
+ * - Finding details with line numbers and suggested fixes
9
+ * - Dark/light theme auto-detection
10
+ */
11
+ import type { TribunalVerdict } from "../types.js";
12
+ export declare function verdictToHtml(verdict: TribunalVerdict, filePath?: string): string;
13
+ //# sourceMappingURL=html.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.d.ts","sourceRoot":"","sources":["../../src/formatters/html.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAEH,OAAO,KAAK,EAAE,eAAe,EAA4B,MAAM,aAAa,CAAC;AA8F7E,wBAAgB,aAAa,CAAC,OAAO,EAAE,eAAe,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,MAAM,CAiIjF"}
@@ -0,0 +1,219 @@
1
+ /**
2
+ * HTML Report Formatter — Self-contained HTML output with inline CSS.
3
+ *
4
+ * Generates a single-file HTML report with:
5
+ * - Executive summary with score gauge
6
+ * - Severity filter toggles
7
+ * - Per-judge accordion drill-down
8
+ * - Finding details with line numbers and suggested fixes
9
+ * - Dark/light theme auto-detection
10
+ */
11
+ // ─── HTML Escaping ──────────────────────────────────────────────────────────
12
+ function esc(text) {
13
+ return text
14
+ .replace(/&/g, "&amp;")
15
+ .replace(/</g, "&lt;")
16
+ .replace(/>/g, "&gt;")
17
+ .replace(/"/g, "&quot;")
18
+ .replace(/'/g, "&#39;");
19
+ }
20
+ // ─── Severity Colors ────────────────────────────────────────────────────────
21
+ function severityColor(severity) {
22
+ switch (severity) {
23
+ case "critical":
24
+ return "#dc2626";
25
+ case "high":
26
+ return "#ea580c";
27
+ case "medium":
28
+ return "#ca8a04";
29
+ case "low":
30
+ return "#2563eb";
31
+ case "info":
32
+ return "#6b7280";
33
+ default:
34
+ return "#6b7280";
35
+ }
36
+ }
37
+ function verdictColor(verdict) {
38
+ switch (verdict) {
39
+ case "pass":
40
+ return "#16a34a";
41
+ case "warning":
42
+ return "#ca8a04";
43
+ case "fail":
44
+ return "#dc2626";
45
+ default:
46
+ return "#6b7280";
47
+ }
48
+ }
49
+ // ─── Finding Row ────────────────────────────────────────────────────────────
50
+ function renderFinding(f) {
51
+ const lines = f.lineNumbers?.length ? `Line ${f.lineNumbers.join(", ")}` : "";
52
+ const color = severityColor(f.severity);
53
+ const fix = f.suggestedFix
54
+ ? `<details class="fix"><summary>Suggested Fix</summary><pre><code>${esc(f.suggestedFix)}</code></pre></details>`
55
+ : "";
56
+ return `
57
+ <div class="finding" data-severity="${f.severity}">
58
+ <div class="finding-header">
59
+ <span class="badge" style="background:${color}">${f.severity.toUpperCase()}</span>
60
+ <span class="rule-id">${esc(f.ruleId)}</span>
61
+ <span class="finding-title">${esc(f.title)}</span>
62
+ ${lines ? `<span class="line-ref">${esc(lines)}</span>` : ""}
63
+ </div>
64
+ <p class="finding-desc">${esc(f.description)}</p>
65
+ <p class="finding-rec"><strong>Recommendation:</strong> ${esc(f.recommendation)}</p>
66
+ ${f.reference ? `<p class="finding-ref"><a href="${esc(f.reference)}" target="_blank" rel="noopener">${esc(f.reference)}</a></p>` : ""}
67
+ ${fix}
68
+ </div>`;
69
+ }
70
+ // ─── Judge Section ──────────────────────────────────────────────────────────
71
+ function renderJudge(evaluation) {
72
+ const icon = evaluation.verdict === "pass" ? "✅" : evaluation.verdict === "warning" ? "⚠️" : "❌";
73
+ const findingsHtml = evaluation.findings.length > 0
74
+ ? evaluation.findings.map(renderFinding).join("")
75
+ : '<p class="no-findings">No findings</p>';
76
+ return `
77
+ <details class="judge-section">
78
+ <summary>
79
+ <span class="judge-icon">${icon}</span>
80
+ <span class="judge-name">${esc(evaluation.judgeName)}</span>
81
+ <span class="judge-score">${evaluation.score}/100</span>
82
+ <span class="judge-count">${evaluation.findings.length} finding(s)</span>
83
+ </summary>
84
+ <div class="judge-body">
85
+ <p class="judge-summary">${esc(evaluation.summary)}</p>
86
+ ${findingsHtml}
87
+ </div>
88
+ </details>`;
89
+ }
90
+ // ─── Main Export ────────────────────────────────────────────────────────────
91
+ export function verdictToHtml(verdict, filePath) {
92
+ const totalFindings = verdict.evaluations.reduce((s, e) => s + e.findings.length, 0);
93
+ const allFindings = verdict.evaluations.flatMap((e) => e.findings);
94
+ const severityCounts = {
95
+ critical: allFindings.filter((f) => f.severity === "critical").length,
96
+ high: allFindings.filter((f) => f.severity === "high").length,
97
+ medium: allFindings.filter((f) => f.severity === "medium").length,
98
+ low: allFindings.filter((f) => f.severity === "low").length,
99
+ info: allFindings.filter((f) => f.severity === "info").length,
100
+ };
101
+ const vColor = verdictColor(verdict.overallVerdict);
102
+ const timestamp = new Date(verdict.timestamp).toLocaleString();
103
+ const fileLabel = filePath ? esc(filePath) : "stdin";
104
+ return `<!DOCTYPE html>
105
+ <html lang="en">
106
+ <head>
107
+ <meta charset="utf-8">
108
+ <meta name="viewport" content="width=device-width, initial-scale=1">
109
+ <title>Judges Panel Report — ${fileLabel}</title>
110
+ <style>
111
+ :root { --bg: #ffffff; --fg: #1a1a1a; --card: #f9fafb; --border: #e5e7eb; --muted: #6b7280; }
112
+ @media (prefers-color-scheme: dark) {
113
+ :root { --bg: #0f172a; --fg: #e2e8f0; --card: #1e293b; --border: #334155; --muted: #94a3b8; }
114
+ }
115
+ * { box-sizing: border-box; margin: 0; padding: 0; }
116
+ body { font-family: -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif; background: var(--bg); color: var(--fg); line-height: 1.6; padding: 2rem; max-width: 960px; margin: 0 auto; }
117
+ h1 { font-size: 1.5rem; margin-bottom: 0.25rem; }
118
+ .meta { color: var(--muted); font-size: 0.875rem; margin-bottom: 1.5rem; }
119
+ .summary-grid { display: grid; grid-template-columns: repeat(auto-fit, minmax(140px, 1fr)); gap: 1rem; margin-bottom: 1.5rem; }
120
+ .summary-card { background: var(--card); border: 1px solid var(--border); border-radius: 8px; padding: 1rem; text-align: center; }
121
+ .summary-card .value { font-size: 2rem; font-weight: 700; }
122
+ .summary-card .label { font-size: 0.75rem; color: var(--muted); text-transform: uppercase; letter-spacing: 0.05em; }
123
+ .filters { display: flex; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 1.5rem; }
124
+ .filter-btn { border: 1px solid var(--border); background: var(--card); color: var(--fg); padding: 0.25rem 0.75rem; border-radius: 4px; cursor: pointer; font-size: 0.8rem; }
125
+ .filter-btn.active { background: var(--fg); color: var(--bg); }
126
+ .judge-section { background: var(--card); border: 1px solid var(--border); border-radius: 8px; margin-bottom: 0.75rem; }
127
+ .judge-section summary { padding: 0.75rem 1rem; cursor: pointer; display: flex; align-items: center; gap: 0.75rem; font-weight: 500; }
128
+ .judge-section summary::-webkit-details-marker { display: none; }
129
+ .judge-section summary::before { content: "▶"; font-size: 0.7rem; transition: transform 0.2s; }
130
+ .judge-section[open] summary::before { transform: rotate(90deg); }
131
+ .judge-score { margin-left: auto; font-weight: 700; }
132
+ .judge-count { color: var(--muted); font-size: 0.8rem; }
133
+ .judge-body { padding: 0 1rem 1rem; }
134
+ .judge-summary { color: var(--muted); font-size: 0.875rem; margin-bottom: 0.75rem; }
135
+ .finding { border-left: 3px solid var(--border); padding: 0.5rem 0.75rem; margin-bottom: 0.5rem; background: var(--bg); border-radius: 0 4px 4px 0; }
136
+ .finding-header { display: flex; align-items: center; gap: 0.5rem; flex-wrap: wrap; margin-bottom: 0.25rem; }
137
+ .badge { color: #fff; padding: 0.1rem 0.4rem; border-radius: 3px; font-size: 0.7rem; font-weight: 600; }
138
+ .rule-id { font-weight: 600; font-size: 0.85rem; }
139
+ .finding-title { font-weight: 500; }
140
+ .line-ref { color: var(--muted); font-size: 0.8rem; }
141
+ .finding-desc, .finding-rec, .finding-ref { font-size: 0.85rem; margin-top: 0.25rem; }
142
+ .finding-ref a { color: #3b82f6; }
143
+ .fix summary { font-size: 0.8rem; cursor: pointer; color: #3b82f6; margin-top: 0.25rem; }
144
+ .fix pre { background: var(--card); padding: 0.5rem; border-radius: 4px; overflow-x: auto; font-size: 0.8rem; margin-top: 0.25rem; }
145
+ .no-findings { color: var(--muted); font-style: italic; }
146
+ footer { margin-top: 2rem; text-align: center; color: var(--muted); font-size: 0.75rem; }
147
+ </style>
148
+ </head>
149
+ <body>
150
+ <h1>Judges Panel Report</h1>
151
+ <p class="meta">File: ${fileLabel} &middot; ${timestamp}</p>
152
+
153
+ <div class="summary-grid">
154
+ <div class="summary-card">
155
+ <div class="value" style="color:${vColor}">${verdict.overallVerdict.toUpperCase()}</div>
156
+ <div class="label">Verdict</div>
157
+ </div>
158
+ <div class="summary-card">
159
+ <div class="value">${verdict.overallScore}</div>
160
+ <div class="label">Score / 100</div>
161
+ </div>
162
+ <div class="summary-card">
163
+ <div class="value">${totalFindings}</div>
164
+ <div class="label">Findings</div>
165
+ </div>
166
+ <div class="summary-card">
167
+ <div class="value">${verdict.evaluations.length}</div>
168
+ <div class="label">Judges</div>
169
+ </div>
170
+ </div>
171
+
172
+ <div class="summary-grid">
173
+ <div class="summary-card">
174
+ <div class="value" style="color:${severityColor("critical")}">${severityCounts.critical}</div>
175
+ <div class="label">Critical</div>
176
+ </div>
177
+ <div class="summary-card">
178
+ <div class="value" style="color:${severityColor("high")}">${severityCounts.high}</div>
179
+ <div class="label">High</div>
180
+ </div>
181
+ <div class="summary-card">
182
+ <div class="value" style="color:${severityColor("medium")}">${severityCounts.medium}</div>
183
+ <div class="label">Medium</div>
184
+ </div>
185
+ <div class="summary-card">
186
+ <div class="value" style="color:${severityColor("low")}">${severityCounts.low}</div>
187
+ <div class="label">Low</div>
188
+ </div>
189
+ </div>
190
+
191
+ <div class="filters">
192
+ <button class="filter-btn active" onclick="filterFindings('all')">All</button>
193
+ <button class="filter-btn" onclick="filterFindings('critical')">Critical (${severityCounts.critical})</button>
194
+ <button class="filter-btn" onclick="filterFindings('high')">High (${severityCounts.high})</button>
195
+ <button class="filter-btn" onclick="filterFindings('medium')">Medium (${severityCounts.medium})</button>
196
+ <button class="filter-btn" onclick="filterFindings('low')">Low (${severityCounts.low})</button>
197
+ </div>
198
+
199
+ ${verdict.evaluations.map(renderJudge).join("\n")}
200
+
201
+ <footer>Generated by <a href="https://github.com/KevinRabun/judges" style="color:#3b82f6">Judges Panel</a> v3.4.0</footer>
202
+
203
+ <script>
204
+ function filterFindings(severity) {
205
+ document.querySelectorAll('.filter-btn').forEach(b => b.classList.remove('active'));
206
+ event.target.classList.add('active');
207
+ document.querySelectorAll('.finding').forEach(el => {
208
+ if (severity === 'all' || el.dataset.severity === severity) {
209
+ el.style.display = '';
210
+ } else {
211
+ el.style.display = 'none';
212
+ }
213
+ });
214
+ }
215
+ </script>
216
+ </body>
217
+ </html>`;
218
+ }
219
+ //# sourceMappingURL=html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"html.js","sourceRoot":"","sources":["../../src/formatters/html.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -18,12 +18,17 @@
18
18
  */
19
19
  // ─── CLI Detection ──────────────────────────────────────────────────────────
20
20
  // If the user passed a subcommand or flag, run as CLI instead of MCP server.
21
- const cliCommands = new Set(["eval", "list", "evaluate"]);
21
+ const cliCommands = new Set(["eval", "list", "evaluate", "init", "fix", "watch", "report", "hook"]);
22
22
  const cliFlags = new Set(["--help", "-h", "--file", "-f", "--version", "-v"]);
23
23
  const firstArg = process.argv[2];
24
24
  if (firstArg && (cliCommands.has(firstArg) || cliFlags.has(firstArg))) {
25
25
  // Dynamic import to avoid loading MCP SDK when running as CLI
26
- import("./cli.js").then(({ runCli }) => runCli(process.argv));
26
+ import("./cli.js")
27
+ .then(({ runCli }) => runCli(process.argv))
28
+ .catch((err) => {
29
+ console.error("CLI error:", err);
30
+ process.exit(1);
31
+ });
27
32
  }
28
33
  else {
29
34
  // ─── MCP Server Mode ────────────────────────────────────────────────────
@@ -34,7 +39,7 @@ else {
34
39
  const { registerPrompts } = await import("./tools/prompts.js");
35
40
  const server = new McpServer({
36
41
  name: "judges",
37
- version: "3.2.0",
42
+ version: "3.4.0",
38
43
  });
39
44
  registerTools(server);
40
45
  registerPrompts(server);
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;GAgBG;AAEH,+EAA+E;AAC/E,6EAA6E;AAE7E,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,CAAC,CAAC,CAAC;AAC1D,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;AAC9E,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEjC,IAAI,QAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;IACtE,8DAA8D;IAC9D,MAAM,CAAC,UAAU,CAAC,CAAC,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AAChE,CAAC;KAAM,CAAC;IACN,2EAA2E;IAE3E,MAAM,CAAC,yCAAyC,CAAC;SAC9C,IAAI,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QAC5B,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,2CAA2C,CAAC,CAAC;QAC3F,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;QAC9D,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAE/D,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;YAC3B,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;QAEH,aAAa,CAAC,MAAM,CAAC,CAAC;QACtB,eAAe,CAAC,MAAM,CAAC,CAAC;QAExB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC5D,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACb,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,GAAG,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";AAEA;;;;;;;;;;;;;;;;GAgBG;AAEH,+EAA+E;AAC/E,6EAA6E;AAE7E,MAAM,WAAW,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,EAAE,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,CAAC,CAAC,CAAC;AACpG,MAAM,QAAQ,GAAG,IAAI,GAAG,CAAC,CAAC,QAAQ,EAAE,IAAI,EAAE,QAAQ,EAAE,IAAI,EAAE,WAAW,EAAE,IAAI,CAAC,CAAC,CAAC;AAC9E,MAAM,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;AAEjC,IAAI,QAAQ,IAAI,CAAC,WAAW,CAAC,GAAG,CAAC,QAAQ,CAAC,IAAI,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC;IACtE,8DAA8D;IAC9D,MAAM,CAAC,UAAU,CAAC;SACf,IAAI,CAAC,CAAC,EAAE,MAAM,EAAE,EAAE,EAAE,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC;SAC1C,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACb,OAAO,CAAC,KAAK,CAAC,YAAY,EAAE,GAAG,CAAC,CAAC;QACjC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC;KAAM,CAAC;IACN,2EAA2E;IAE3E,MAAM,CAAC,yCAAyC,CAAC;SAC9C,IAAI,CAAC,KAAK,EAAE,EAAE,SAAS,EAAE,EAAE,EAAE;QAC5B,MAAM,EAAE,oBAAoB,EAAE,GAAG,MAAM,MAAM,CAAC,2CAA2C,CAAC,CAAC;QAC3F,MAAM,EAAE,aAAa,EAAE,GAAG,MAAM,MAAM,CAAC,qBAAqB,CAAC,CAAC;QAC9D,MAAM,EAAE,eAAe,EAAE,GAAG,MAAM,MAAM,CAAC,oBAAoB,CAAC,CAAC;QAE/D,MAAM,MAAM,GAAG,IAAI,SAAS,CAAC;YAC3B,IAAI,EAAE,QAAQ;YACd,OAAO,EAAE,OAAO;SACjB,CAAC,CAAC;QAEH,aAAa,CAAC,MAAM,CAAC,CAAC;QACtB,eAAe,CAAC,MAAM,CAAC,CAAC;QAExB,MAAM,SAAS,GAAG,IAAI,oBAAoB,EAAE,CAAC;QAC7C,MAAM,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,CAAC;QAChC,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,CAAC;IAC5D,CAAC,CAAC;SACD,KAAK,CAAC,CAAC,GAAG,EAAE,EAAE;QACb,OAAO,CAAC,KAAK,CAAC,+BAA+B,EAAE,GAAG,CAAC,CAAC;QACpD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC,CAAC,CAAC;AACP,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"language-patterns.d.ts","sourceRoot":"","sources":["../src/language-patterns.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"language-patterns.d.ts","sourceRoot":"","sources":["../src/language-patterns.ts"],"names":[],"mappings":"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"}
@@ -24,6 +24,13 @@ const LANG_ALIAS_MAP = {
24
24
  java: "java",
25
25
  go: "go",
26
26
  golang: "go",
27
+ cpp: "cpp",
28
+ "c++": "cpp",
29
+ cc: "cpp",
30
+ cxx: "cpp",
31
+ c: "cpp",
32
+ h: "cpp",
33
+ hpp: "cpp",
27
34
  };
28
35
  /**
29
36
  * Normalise a user-supplied language string to a canonical LangFamily.
@@ -350,6 +357,7 @@ export const MANIFEST_FILES = {
350
357
  csharp: ["*.csproj", "packages.config", "Directory.Packages.props"],
351
358
  java: ["pom.xml", "build.gradle", "build.gradle.kts"],
352
359
  go: ["go.mod"],
360
+ cpp: ["CMakeLists.txt", "Makefile", "conanfile.txt", "vcpkg.json"],
353
361
  unknown: [],
354
362
  };
355
363
  // ── Input Validation ─────────────────────────────────────────────────────────