@kevinrabun/judges 3.43.0 → 3.44.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/burndown.d.ts +27 -0
  6. package/dist/commands/burndown.d.ts.map +1 -0
  7. package/dist/commands/burndown.js +180 -0
  8. package/dist/commands/burndown.js.map +1 -0
  9. package/dist/commands/kb.d.ts +41 -0
  10. package/dist/commands/kb.d.ts.map +1 -0
  11. package/dist/commands/kb.js +231 -0
  12. package/dist/commands/kb.js.map +1 -0
  13. package/dist/commands/noise-advisor.d.ts +30 -0
  14. package/dist/commands/noise-advisor.d.ts.map +1 -0
  15. package/dist/commands/noise-advisor.js +171 -0
  16. package/dist/commands/noise-advisor.js.map +1 -0
  17. package/dist/commands/recommend.d.ts +21 -0
  18. package/dist/commands/recommend.d.ts.map +1 -0
  19. package/dist/commands/recommend.js +283 -0
  20. package/dist/commands/recommend.js.map +1 -0
  21. package/dist/commands/report-template.d.ts +17 -0
  22. package/dist/commands/report-template.d.ts.map +1 -0
  23. package/dist/commands/report-template.js +291 -0
  24. package/dist/commands/report-template.js.map +1 -0
  25. package/dist/commands/review-queue.d.ts +34 -0
  26. package/dist/commands/review-queue.d.ts.map +1 -0
  27. package/dist/commands/review-queue.js +226 -0
  28. package/dist/commands/review-queue.js.map +1 -0
  29. package/dist/commands/rule-owner.d.ts +31 -0
  30. package/dist/commands/rule-owner.d.ts.map +1 -0
  31. package/dist/commands/rule-owner.js +182 -0
  32. package/dist/commands/rule-owner.js.map +1 -0
  33. package/dist/commands/suppress.d.ts +40 -0
  34. package/dist/commands/suppress.d.ts.map +1 -0
  35. package/dist/commands/suppress.js +209 -0
  36. package/dist/commands/suppress.js.map +1 -0
  37. package/package.json +1 -1
  38. package/server.json +2 -2
@@ -0,0 +1,283 @@
1
+ /**
2
+ * Rule recommendations — analyze project stack and suggest which
3
+ * judges/rules are most relevant.
4
+ *
5
+ * Uses local file analysis only — no external services.
6
+ */
7
+ import { readdirSync, readFileSync, existsSync, statSync } from "fs";
8
+ import { join, extname } from "path";
9
+ import { defaultRegistry } from "../judge-registry.js";
10
+ // ─── Stack Detection ────────────────────────────────────────────────────────
11
+ const FRAMEWORK_SIGNALS = [
12
+ { framework: "React", files: [], deps: ["react", "react-dom", "next", "@remix-run/react"] },
13
+ { framework: "Next.js", files: ["next.config.js", "next.config.mjs", "next.config.ts"], deps: ["next"] },
14
+ { framework: "Express", files: [], deps: ["express"] },
15
+ { framework: "FastAPI", files: [], deps: ["fastapi", "uvicorn"] },
16
+ { framework: "Django", files: ["manage.py", "settings.py"], deps: ["django"] },
17
+ { framework: "Spring Boot", files: ["pom.xml", "build.gradle"], deps: ["spring-boot"] },
18
+ { framework: "Rails", files: ["Gemfile", "config/routes.rb"], deps: ["rails"] },
19
+ { framework: "Terraform", files: [], deps: [] },
20
+ { framework: "Kubernetes", files: [], deps: [] },
21
+ { framework: "Docker", files: ["Dockerfile", "docker-compose.yml", "docker-compose.yaml"], deps: [] },
22
+ { framework: "Vue", files: [], deps: ["vue", "nuxt"] },
23
+ { framework: "Angular", files: ["angular.json"], deps: ["@angular/core"] },
24
+ { framework: "Svelte", files: ["svelte.config.js"], deps: ["svelte", "@sveltejs/kit"] },
25
+ { framework: "Flask", files: [], deps: ["flask"] },
26
+ { framework: "Go", files: ["go.mod", "go.sum"], deps: [] },
27
+ { framework: "Rust", files: ["Cargo.toml"], deps: [] },
28
+ ];
29
+ function scanDirectory(dir, depth = 0, maxDepth = 3) {
30
+ if (depth > maxDepth)
31
+ return [];
32
+ const files = [];
33
+ try {
34
+ for (const entry of readdirSync(dir)) {
35
+ if (entry.startsWith(".") || entry === "node_modules" || entry === "vendor" || entry === "dist")
36
+ continue;
37
+ const full = join(dir, entry);
38
+ try {
39
+ const stat = statSync(full);
40
+ if (stat.isFile())
41
+ files.push(entry);
42
+ else if (stat.isDirectory())
43
+ files.push(...scanDirectory(full, depth + 1, maxDepth).map((f) => `${entry}/${f}`));
44
+ }
45
+ catch {
46
+ /* skip */
47
+ }
48
+ }
49
+ }
50
+ catch {
51
+ /* skip */
52
+ }
53
+ return files;
54
+ }
55
+ function detectLanguages(files) {
56
+ const extMap = {
57
+ ".ts": "TypeScript",
58
+ ".tsx": "TypeScript",
59
+ ".js": "JavaScript",
60
+ ".jsx": "JavaScript",
61
+ ".py": "Python",
62
+ ".java": "Java",
63
+ ".go": "Go",
64
+ ".rs": "Rust",
65
+ ".cs": "C#",
66
+ ".cpp": "C++",
67
+ ".c": "C",
68
+ ".rb": "Ruby",
69
+ ".tf": "Terraform",
70
+ ".yaml": "YAML",
71
+ ".yml": "YAML",
72
+ ".sql": "SQL",
73
+ ".sh": "Shell",
74
+ ".ps1": "PowerShell",
75
+ };
76
+ const counts = {};
77
+ for (const f of files) {
78
+ const ext = extname(f);
79
+ const lang = extMap[ext];
80
+ if (lang)
81
+ counts[lang] = (counts[lang] || 0) + 1;
82
+ }
83
+ return counts;
84
+ }
85
+ export function detectStack(dir = ".") {
86
+ const files = scanDirectory(dir);
87
+ const signals = [];
88
+ // Check for framework config files
89
+ for (const fw of FRAMEWORK_SIGNALS) {
90
+ for (const file of fw.files) {
91
+ if (files.includes(file) || existsSync(join(dir, file))) {
92
+ signals.push({ framework: fw.framework, confidence: 0.9, detectedVia: `config file: ${file}` });
93
+ }
94
+ }
95
+ }
96
+ // Check package.json dependencies
97
+ const pkgPath = join(dir, "package.json");
98
+ if (existsSync(pkgPath)) {
99
+ try {
100
+ const pkg = JSON.parse(readFileSync(pkgPath, "utf-8"));
101
+ const allDeps = { ...pkg.dependencies, ...pkg.devDependencies };
102
+ for (const fw of FRAMEWORK_SIGNALS) {
103
+ for (const dep of fw.deps) {
104
+ if (allDeps[dep]) {
105
+ const existing = signals.find((s) => s.framework === fw.framework);
106
+ if (!existing) {
107
+ signals.push({ framework: fw.framework, confidence: 0.85, detectedVia: `package.json: ${dep}` });
108
+ }
109
+ }
110
+ }
111
+ }
112
+ }
113
+ catch {
114
+ /* skip */
115
+ }
116
+ }
117
+ // Check for Terraform files
118
+ if (files.some((f) => f.endsWith(".tf"))) {
119
+ signals.push({ framework: "Terraform", confidence: 0.95, detectedVia: "*.tf files" });
120
+ }
121
+ // Check for Kubernetes manifests
122
+ if (files.some((f) => f.endsWith(".yaml") || f.endsWith(".yml"))) {
123
+ for (const f of files.filter((f) => f.endsWith(".yaml") || f.endsWith(".yml"))) {
124
+ try {
125
+ const content = readFileSync(join(dir, f), "utf-8").slice(0, 500);
126
+ if (content.includes("apiVersion:") && content.includes("kind:")) {
127
+ signals.push({ framework: "Kubernetes", confidence: 0.9, detectedVia: `manifest: ${f}` });
128
+ break;
129
+ }
130
+ }
131
+ catch {
132
+ /* skip */
133
+ }
134
+ }
135
+ }
136
+ return signals;
137
+ }
138
+ // ─── Recommendation Engine ──────────────────────────────────────────────────
139
+ const JUDGE_FRAMEWORK_MAP = {
140
+ react: ["xss-judge", "frontend-judge"],
141
+ "next.js": ["xss-judge", "ssr-judge", "frontend-judge"],
142
+ express: ["injection-judge", "auth-judge", "ssrf-judge"],
143
+ fastapi: ["injection-judge", "auth-judge", "python-judge"],
144
+ django: ["injection-judge", "auth-judge", "python-judge"],
145
+ "spring boot": ["injection-judge", "auth-judge", "java-judge"],
146
+ terraform: ["iac-judge", "secrets-judge"],
147
+ kubernetes: ["iac-judge", "container-judge"],
148
+ docker: ["container-judge", "secrets-judge"],
149
+ };
150
+ export function getRecommendations(dir = ".") {
151
+ const stack = detectStack(dir);
152
+ const files = scanDirectory(dir);
153
+ const languages = detectLanguages(files);
154
+ const allJudges = defaultRegistry.getJudges().map((j) => j.id);
155
+ const recommendations = [];
156
+ const seen = new Set();
157
+ // Framework-specific recommendations
158
+ for (const signal of stack) {
159
+ const matching = JUDGE_FRAMEWORK_MAP[signal.framework.toLowerCase()] || [];
160
+ for (const judgeId of matching) {
161
+ if (seen.has(judgeId))
162
+ continue;
163
+ // Check if this judge actually exists
164
+ const actual = allJudges.find((j) => j.includes(judgeId.replace("-judge", "")));
165
+ if (actual) {
166
+ seen.add(actual);
167
+ recommendations.push({
168
+ judgeId: actual,
169
+ relevance: "high",
170
+ reason: `${signal.framework} detected (${signal.detectedVia}). This judge covers common ${signal.framework} patterns.`,
171
+ estimatedCoverage: "80-90%",
172
+ });
173
+ }
174
+ }
175
+ }
176
+ // Language-based recommendations
177
+ const topLang = Object.entries(languages)
178
+ .sort((a, b) => b[1] - a[1])
179
+ .slice(0, 3);
180
+ for (const [lang, count] of topLang) {
181
+ const percentage = Math.round((count / files.length) * 100);
182
+ if (percentage < 5)
183
+ continue;
184
+ for (const jId of allJudges) {
185
+ if (seen.has(jId))
186
+ continue;
187
+ if (jId.toLowerCase().includes(lang.toLowerCase().replace(/[#+]/g, ""))) {
188
+ seen.add(jId);
189
+ recommendations.push({
190
+ judgeId: jId,
191
+ relevance: "medium",
192
+ reason: `${lang} is ${percentage}% of your codebase (${count} files).`,
193
+ estimatedCoverage: "60-80%",
194
+ });
195
+ }
196
+ }
197
+ }
198
+ // Universal judges everyone should use
199
+ const universalJudges = ["security", "secrets", "error", "performance"];
200
+ for (const keyword of universalJudges) {
201
+ for (const jId of allJudges) {
202
+ if (seen.has(jId))
203
+ continue;
204
+ if (jId.toLowerCase().includes(keyword)) {
205
+ seen.add(jId);
206
+ recommendations.push({
207
+ judgeId: jId,
208
+ relevance: "medium",
209
+ reason: `Universal ${keyword} rules apply to all codebases.`,
210
+ estimatedCoverage: "70-85%",
211
+ });
212
+ }
213
+ }
214
+ }
215
+ return recommendations.sort((a, b) => {
216
+ const order = { high: 0, medium: 1, low: 2 };
217
+ return order[a.relevance] - order[b.relevance];
218
+ });
219
+ }
220
+ // ─── CLI ────────────────────────────────────────────────────────────────────
221
+ export function runRecommend(argv) {
222
+ if (argv.includes("--help") || argv.includes("-h")) {
223
+ console.log(`
224
+ judges recommend — Analyze project and recommend judges
225
+
226
+ Usage:
227
+ judges recommend Analyze current directory
228
+ judges recommend --dir /path Analyze specific directory
229
+ judges recommend --stack-only Only show detected stack
230
+
231
+ Options:
232
+ --dir <path> Directory to analyze (default: .)
233
+ --stack-only Only show detected frameworks
234
+ --format json JSON output
235
+ --help, -h Show this help
236
+ `);
237
+ return;
238
+ }
239
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
240
+ const dir = argv.find((_a, i) => argv[i - 1] === "--dir") || ".";
241
+ if (argv.includes("--stack-only")) {
242
+ const stack = detectStack(dir);
243
+ if (format === "json") {
244
+ console.log(JSON.stringify(stack, null, 2));
245
+ }
246
+ else if (stack.length === 0) {
247
+ console.log("\n No frameworks detected.\n");
248
+ }
249
+ else {
250
+ console.log("\n Detected Stack\n ──────────────");
251
+ for (const s of stack) {
252
+ console.log(` ${s.framework.padEnd(16)} (${(s.confidence * 100).toFixed(0)}%) via ${s.detectedVia}`);
253
+ }
254
+ console.log("");
255
+ }
256
+ return;
257
+ }
258
+ const recs = getRecommendations(dir);
259
+ const stack = detectStack(dir);
260
+ if (format === "json") {
261
+ console.log(JSON.stringify({ stack, recommendations: recs }, null, 2));
262
+ return;
263
+ }
264
+ console.log("\n Project Analysis\n ────────────────");
265
+ if (stack.length > 0) {
266
+ console.log("\n Detected stack:");
267
+ for (const s of stack) {
268
+ console.log(` ${s.framework.padEnd(16)} (${(s.confidence * 100).toFixed(0)}%) via ${s.detectedVia}`);
269
+ }
270
+ }
271
+ if (recs.length === 0) {
272
+ console.log("\n No specific recommendations. All judges are applicable.\n");
273
+ return;
274
+ }
275
+ console.log(`\n Recommended Judges (${recs.length}):\n`);
276
+ for (const r of recs) {
277
+ const icon = r.relevance === "high" ? "🟢" : r.relevance === "medium" ? "🟡" : "⚪";
278
+ console.log(` ${icon} ${r.judgeId.padEnd(25)} [${r.relevance}] coverage: ${r.estimatedCoverage}`);
279
+ console.log(` ${r.reason}`);
280
+ }
281
+ console.log("");
282
+ }
283
+ //# sourceMappingURL=recommend.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"recommend.js","sourceRoot":"","sources":["../../src/commands/recommend.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,17 @@
1
+ /**
2
+ * Report templates — generate reports from different predefined
3
+ * templates targeting different audiences (exec, dev, compliance).
4
+ *
5
+ * Pure local generation — no external services.
6
+ */
7
+ import type { TribunalVerdict } from "../types.js";
8
+ export interface ReportTemplate {
9
+ id: string;
10
+ name: string;
11
+ audience: string;
12
+ description: string;
13
+ }
14
+ export declare function listTemplates(): ReportTemplate[];
15
+ export declare function generateReport(templateId: string, verdict: TribunalVerdict): string;
16
+ export declare function runReportTemplate(argv: string[]): void;
17
+ //# sourceMappingURL=report-template.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-template.d.ts","sourceRoot":"","sources":["../../src/commands/report-template.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAGH,OAAO,KAAK,EAAW,eAAe,EAAE,MAAM,aAAa,CAAC;AAI5D,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;CACrB;AA8PD,wBAAgB,aAAa,IAAI,cAAc,EAAE,CAEhD;AAED,wBAAgB,cAAc,CAAC,UAAU,EAAE,MAAM,EAAE,OAAO,EAAE,eAAe,GAAG,MAAM,CAiBnF;AAID,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA6DtD"}
@@ -0,0 +1,291 @@
1
+ /**
2
+ * Report templates — generate reports from different predefined
3
+ * templates targeting different audiences (exec, dev, compliance).
4
+ *
5
+ * Pure local generation — no external services.
6
+ */
7
+ import { readFileSync, writeFileSync, existsSync } from "fs";
8
+ // ─── Templates ──────────────────────────────────────────────────────────────
9
+ const TEMPLATES = [
10
+ {
11
+ id: "exec-summary",
12
+ name: "Executive Summary",
13
+ audience: "Leadership",
14
+ description: "One-page overview with verdict, risk score, and trend",
15
+ },
16
+ {
17
+ id: "dev-detail",
18
+ name: "Developer Detail",
19
+ audience: "Developers",
20
+ description: "Full findings with code locations, fixes, and references",
21
+ },
22
+ {
23
+ id: "compliance",
24
+ name: "Compliance Report",
25
+ audience: "Auditors",
26
+ description: "SOC2/ISO-aligned report with policy hash and evidence",
27
+ },
28
+ {
29
+ id: "pr-review",
30
+ name: "PR Review",
31
+ audience: "Code Reviewers",
32
+ description: "Focused diff-aware summary for PR review",
33
+ },
34
+ {
35
+ id: "trend",
36
+ name: "Trend Report",
37
+ audience: "Management",
38
+ description: "Historical comparison showing improvement trajectory",
39
+ },
40
+ {
41
+ id: "onboarding",
42
+ name: "Onboarding Report",
43
+ audience: "New Team Members",
44
+ description: "Gentle introduction to codebase health with learning resources",
45
+ },
46
+ ];
47
+ // ─── Report Generators ─────────────────────────────────────────────────────
48
+ function renderExecSummary(verdict) {
49
+ const critical = verdict.criticalCount || 0;
50
+ const high = verdict.highCount || 0;
51
+ const lines = [
52
+ "# Executive Summary — Code Review Report",
53
+ "",
54
+ `**Date:** ${new Date().toISOString().split("T")[0]}`,
55
+ `**Verdict:** ${verdict.overallVerdict.toUpperCase()}`,
56
+ `**Score:** ${verdict.overallScore}/100`,
57
+ "",
58
+ "## Risk Overview",
59
+ "",
60
+ `| Metric | Value |`,
61
+ `|--------|-------|`,
62
+ `| Critical findings | ${critical} |`,
63
+ `| High findings | ${high} |`,
64
+ `| Total findings | ${verdict.findings.length} |`,
65
+ `| Judges evaluated | ${verdict.evaluations.length} |`,
66
+ "",
67
+ "## Summary",
68
+ "",
69
+ verdict.summary,
70
+ "",
71
+ "## Action Required",
72
+ "",
73
+ ];
74
+ if (critical > 0) {
75
+ lines.push("**IMMEDIATE ACTION:** Critical findings require attention within 24 hours.");
76
+ }
77
+ else if (high > 0) {
78
+ lines.push("**ACTION NEEDED:** High-severity findings should be addressed this sprint.");
79
+ }
80
+ else {
81
+ lines.push("**STATUS:** No critical issues. Continue monitoring.");
82
+ }
83
+ lines.push("", "---", "_Generated by Judges_");
84
+ return lines.join("\n");
85
+ }
86
+ function renderDevDetail(verdict) {
87
+ const lines = [
88
+ "# Developer Report — Detailed Findings",
89
+ "",
90
+ `**Verdict:** ${verdict.overallVerdict} (${verdict.overallScore}/100)`,
91
+ `**Findings:** ${verdict.findings.length}`,
92
+ "",
93
+ ];
94
+ const bySeverity = {};
95
+ for (const f of verdict.findings) {
96
+ (bySeverity[f.severity] ??= []).push(f);
97
+ }
98
+ for (const sev of ["critical", "high", "medium", "low", "info"]) {
99
+ const findings = bySeverity[sev];
100
+ if (!findings?.length)
101
+ continue;
102
+ lines.push(`## ${sev.toUpperCase()} (${findings.length})`, "");
103
+ for (const f of findings) {
104
+ lines.push(`### ${f.ruleId}: ${f.title}`);
105
+ if (f.lineNumbers?.length)
106
+ lines.push(`**Lines:** ${f.lineNumbers.join(", ")}`);
107
+ lines.push("", f.description, "");
108
+ lines.push("**Fix:**", f.recommendation, "");
109
+ if (f.reference)
110
+ lines.push(`**Reference:** ${f.reference}`, "");
111
+ lines.push("---", "");
112
+ }
113
+ }
114
+ return lines.join("\n");
115
+ }
116
+ function renderComplianceReport(verdict) {
117
+ const lines = [
118
+ "# Compliance Report",
119
+ "",
120
+ `**Generated:** ${new Date().toISOString()}`,
121
+ `**Verdict:** ${verdict.overallVerdict}`,
122
+ `**Score:** ${verdict.overallScore}/100`,
123
+ "",
124
+ "## Evaluation Summary",
125
+ "",
126
+ `| Judge | Verdict | Score | Findings |`,
127
+ `|-------|---------|-------|----------|`,
128
+ ];
129
+ for (const e of verdict.evaluations) {
130
+ lines.push(`| ${e.judgeId} | ${e.verdict} | ${e.score} | ${e.findings.length} |`);
131
+ }
132
+ lines.push("", "## Finding Categories", "", "| Severity | Count |", "|----------|-------|");
133
+ const bySev = {};
134
+ for (const f of verdict.findings) {
135
+ bySev[f.severity] = (bySev[f.severity] || 0) + 1;
136
+ }
137
+ for (const [s, c] of Object.entries(bySev)) {
138
+ lines.push(`| ${s} | ${c} |`);
139
+ }
140
+ lines.push("", "## Evidence", "", `- Total judges evaluated: ${verdict.evaluations.length}`, `- Total findings: ${verdict.findings.length}`, `- Critical count: ${verdict.criticalCount || 0}`, `- High count: ${verdict.highCount || 0}`, "", "---", "_Audit report generated by Judges_");
141
+ return lines.join("\n");
142
+ }
143
+ function renderTrendReport(verdict) {
144
+ const lines = [
145
+ "# Trend Report",
146
+ "",
147
+ `**Current Score:** ${verdict.overallScore}/100`,
148
+ `**Current Findings:** ${verdict.findings.length}`,
149
+ "",
150
+ "## Current Snapshot",
151
+ "",
152
+ ];
153
+ const bySev = {};
154
+ for (const f of verdict.findings) {
155
+ bySev[f.severity] = (bySev[f.severity] || 0) + 1;
156
+ }
157
+ lines.push("| Severity | Count |", "|----------|-------|");
158
+ for (const [s, c] of Object.entries(bySev)) {
159
+ lines.push(`| ${s} | ${c} |`);
160
+ }
161
+ lines.push("", "## Top Rules", "", "| Rule | Count |", "|------|-------|");
162
+ const byRule = {};
163
+ for (const f of verdict.findings) {
164
+ byRule[f.ruleId] = (byRule[f.ruleId] || 0) + 1;
165
+ }
166
+ const sorted = Object.entries(byRule)
167
+ .sort((a, b) => b[1] - a[1])
168
+ .slice(0, 10);
169
+ for (const [r, c] of sorted) {
170
+ lines.push(`| ${r} | ${c} |`);
171
+ }
172
+ lines.push("", "> Compare with `judges regression-alert --check` for baseline comparison.", "", "---", "_Generated by Judges_");
173
+ return lines.join("\n");
174
+ }
175
+ function renderOnboarding(verdict) {
176
+ const lines = [
177
+ "# Welcome to Your Codebase Health Report",
178
+ "",
179
+ "This report helps new team members understand the current code quality state.",
180
+ "",
181
+ `**Overall Score:** ${verdict.overallScore}/100 (${verdict.overallVerdict})`,
182
+ `**Total Findings:** ${verdict.findings.length}`,
183
+ "",
184
+ "## What Do These Findings Mean?",
185
+ "",
186
+ "Findings are categorized by severity:",
187
+ "- **Critical/High:** Security issues that must be fixed",
188
+ "- **Medium:** Best practice violations worth addressing",
189
+ "- **Low/Info:** Suggestions for improvement",
190
+ "",
191
+ "## Key Areas to Learn",
192
+ "",
193
+ ];
194
+ const categories = new Set(verdict.findings.map((f) => f.ruleId.split("-")[0]));
195
+ const catDescriptions = {
196
+ SEC: "Security vulnerabilities (injections, XSS, etc.)",
197
+ AUTH: "Authentication and authorization issues",
198
+ CRYPTO: "Cryptography best practices",
199
+ PERF: "Performance optimization opportunities",
200
+ ERR: "Error handling patterns",
201
+ IAC: "Infrastructure as Code security",
202
+ SSRF: "Server-side request forgery prevention",
203
+ CONCUR: "Concurrency and race condition safety",
204
+ };
205
+ for (const cat of categories) {
206
+ lines.push(`- **${cat}:** ${catDescriptions[cat] || "Code quality rules"}`);
207
+ }
208
+ lines.push("", "## Getting Started", "", "1. Run `judges remediation <rule-id>` for fix guides", "2. Run `judges explain <rule-id>` for rule details", "3. Ask your team lead about suppression policies", "", "---", "_Generated by Judges_");
209
+ return lines.join("\n");
210
+ }
211
+ // ─── Public API ─────────────────────────────────────────────────────────────
212
+ export function listTemplates() {
213
+ return TEMPLATES;
214
+ }
215
+ export function generateReport(templateId, verdict) {
216
+ switch (templateId) {
217
+ case "exec-summary":
218
+ return renderExecSummary(verdict);
219
+ case "dev-detail":
220
+ return renderDevDetail(verdict);
221
+ case "compliance":
222
+ return renderComplianceReport(verdict);
223
+ case "trend":
224
+ return renderTrendReport(verdict);
225
+ case "onboarding":
226
+ return renderOnboarding(verdict);
227
+ case "pr-review":
228
+ return renderDevDetail(verdict); // reuse dev detail for PR
229
+ default:
230
+ throw new Error(`Unknown template: ${templateId}. Use --list to see options.`);
231
+ }
232
+ }
233
+ // ─── CLI ────────────────────────────────────────────────────────────────────
234
+ export function runReportTemplate(argv) {
235
+ if (argv.includes("--help") || argv.includes("-h")) {
236
+ console.log(`
237
+ judges report-template — Generate reports from predefined templates
238
+
239
+ Usage:
240
+ judges report-template --list List available templates
241
+ judges report-template --template exec-summary --input results.json
242
+ judges report-template --template dev-detail --input results.json --output report.md
243
+
244
+ Options:
245
+ --template <id> Template to use (required)
246
+ --input <path> Results JSON file (required)
247
+ --output <path> Write report to file (default: stdout)
248
+ --list List available templates
249
+ --help, -h Show this help
250
+
251
+ Templates:
252
+ exec-summary One-page leadership overview
253
+ dev-detail Full findings with fixes
254
+ compliance SOC2/ISO-aligned evidence report
255
+ pr-review Diff-aware PR summary
256
+ trend Historical comparison
257
+ onboarding New team member introduction
258
+ `);
259
+ return;
260
+ }
261
+ if (argv.includes("--list")) {
262
+ console.log("\n Report Templates\n ────────────────");
263
+ for (const t of TEMPLATES) {
264
+ console.log(` ${t.id.padEnd(16)} ${t.name} (${t.audience})`);
265
+ console.log(` ${t.description}`);
266
+ }
267
+ console.log("");
268
+ return;
269
+ }
270
+ const templateId = argv.find((_a, i) => argv[i - 1] === "--template");
271
+ const inputPath = argv.find((_a, i) => argv[i - 1] === "--input");
272
+ const outputPath = argv.find((_a, i) => argv[i - 1] === "--output");
273
+ if (!templateId || !inputPath) {
274
+ console.error("Error: --template and --input required");
275
+ process.exit(1);
276
+ }
277
+ if (!existsSync(inputPath)) {
278
+ console.error(`Error: file not found: ${inputPath}`);
279
+ process.exit(1);
280
+ }
281
+ const verdict = JSON.parse(readFileSync(inputPath, "utf-8"));
282
+ const report = generateReport(templateId, verdict);
283
+ if (outputPath) {
284
+ writeFileSync(outputPath, report);
285
+ console.log(` Report written to ${outputPath}`);
286
+ }
287
+ else {
288
+ console.log(report);
289
+ }
290
+ }
291
+ //# sourceMappingURL=report-template.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"report-template.js","sourceRoot":"","sources":["../../src/commands/report-template.ts"],"names":[],"mappings":"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"}