@kevinrabun/judges 3.68.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 (70) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +112 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/finding-fix-rate.d.ts +5 -0
  6. package/dist/commands/finding-fix-rate.d.ts.map +1 -0
  7. package/dist/commands/finding-fix-rate.js +142 -0
  8. package/dist/commands/finding-fix-rate.js.map +1 -0
  9. package/dist/commands/finding-impact.d.ts +5 -0
  10. package/dist/commands/finding-impact.d.ts.map +1 -0
  11. package/dist/commands/finding-impact.js +136 -0
  12. package/dist/commands/finding-impact.js.map +1 -0
  13. package/dist/commands/finding-recurrence.d.ts +5 -0
  14. package/dist/commands/finding-recurrence.d.ts.map +1 -0
  15. package/dist/commands/finding-recurrence.js +136 -0
  16. package/dist/commands/finding-recurrence.js.map +1 -0
  17. package/dist/commands/review-archive.d.ts +5 -0
  18. package/dist/commands/review-archive.d.ts.map +1 -0
  19. package/dist/commands/review-archive.js +136 -0
  20. package/dist/commands/review-archive.js.map +1 -0
  21. package/dist/commands/review-benchmark-self.d.ts +5 -0
  22. package/dist/commands/review-benchmark-self.d.ts.map +1 -0
  23. package/dist/commands/review-benchmark-self.js +141 -0
  24. package/dist/commands/review-benchmark-self.js.map +1 -0
  25. package/dist/commands/review-changelog-gen.d.ts +5 -0
  26. package/dist/commands/review-changelog-gen.d.ts.map +1 -0
  27. package/dist/commands/review-changelog-gen.js +118 -0
  28. package/dist/commands/review-changelog-gen.js.map +1 -0
  29. package/dist/commands/review-ci-status.d.ts +5 -0
  30. package/dist/commands/review-ci-status.d.ts.map +1 -0
  31. package/dist/commands/review-ci-status.js +201 -0
  32. package/dist/commands/review-ci-status.js.map +1 -0
  33. package/dist/commands/review-custom-prompt.d.ts +5 -0
  34. package/dist/commands/review-custom-prompt.d.ts.map +1 -0
  35. package/dist/commands/review-custom-prompt.js +171 -0
  36. package/dist/commands/review-custom-prompt.js.map +1 -0
  37. package/dist/commands/review-diff-context.d.ts +5 -0
  38. package/dist/commands/review-diff-context.d.ts.map +1 -0
  39. package/dist/commands/review-diff-context.js +159 -0
  40. package/dist/commands/review-diff-context.js.map +1 -0
  41. package/dist/commands/review-milestone.d.ts +5 -0
  42. package/dist/commands/review-milestone.d.ts.map +1 -0
  43. package/dist/commands/review-milestone.js +137 -0
  44. package/dist/commands/review-milestone.js.map +1 -0
  45. package/dist/commands/review-report-pdf.d.ts +5 -0
  46. package/dist/commands/review-report-pdf.d.ts.map +1 -0
  47. package/dist/commands/review-report-pdf.js +164 -0
  48. package/dist/commands/review-report-pdf.js.map +1 -0
  49. package/dist/commands/review-risk-score.d.ts +5 -0
  50. package/dist/commands/review-risk-score.d.ts.map +1 -0
  51. package/dist/commands/review-risk-score.js +157 -0
  52. package/dist/commands/review-risk-score.js.map +1 -0
  53. package/dist/commands/review-standup.d.ts +5 -0
  54. package/dist/commands/review-standup.d.ts.map +1 -0
  55. package/dist/commands/review-standup.js +96 -0
  56. package/dist/commands/review-standup.js.map +1 -0
  57. package/dist/commands/review-tag.d.ts +5 -0
  58. package/dist/commands/review-tag.d.ts.map +1 -0
  59. package/dist/commands/review-tag.js +137 -0
  60. package/dist/commands/review-tag.js.map +1 -0
  61. package/dist/commands/review-team-summary.d.ts +5 -0
  62. package/dist/commands/review-team-summary.d.ts.map +1 -0
  63. package/dist/commands/review-team-summary.js +156 -0
  64. package/dist/commands/review-team-summary.js.map +1 -0
  65. package/dist/commands/review-whitelist.d.ts +5 -0
  66. package/dist/commands/review-whitelist.d.ts.map +1 -0
  67. package/dist/commands/review-whitelist.js +159 -0
  68. package/dist/commands/review-whitelist.js.map +1 -0
  69. package/package.json +1 -1
  70. package/server.json +2 -2
@@ -0,0 +1,142 @@
1
+ /**
2
+ * Finding-fix-rate — Track how quickly findings are being resolved over time.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
5
+ import { join, dirname } from "path";
6
+ // ─── Storage ────────────────────────────────────────────────────────────────
7
+ const FIX_RATE_FILE = join(".judges", "fix-rate.json");
8
+ function loadStore() {
9
+ if (!existsSync(FIX_RATE_FILE))
10
+ return { version: "1.0.0", events: [] };
11
+ try {
12
+ return JSON.parse(readFileSync(FIX_RATE_FILE, "utf-8"));
13
+ }
14
+ catch {
15
+ return { version: "1.0.0", events: [] };
16
+ }
17
+ }
18
+ function saveStore(store) {
19
+ mkdirSync(dirname(FIX_RATE_FILE), { recursive: true });
20
+ writeFileSync(FIX_RATE_FILE, JSON.stringify(store, null, 2), "utf-8");
21
+ }
22
+ // ─── CLI ────────────────────────────────────────────────────────────────────
23
+ export function runFindingFixRate(argv) {
24
+ if (argv.includes("--help") || argv.includes("-h")) {
25
+ console.log(`
26
+ judges finding-fix-rate — Track finding resolution speed
27
+
28
+ Usage:
29
+ judges finding-fix-rate show Show fix rate metrics
30
+ judges finding-fix-rate record --rule SEC-001 --severity high --days 3
31
+ judges finding-fix-rate trend Show trend over time
32
+ judges finding-fix-rate clear Clear all data
33
+
34
+ Subcommands:
35
+ show Show fix rate summary
36
+ record Record a fix event
37
+ trend Show fix rate trends
38
+ clear Clear all data
39
+
40
+ Options:
41
+ --rule <ruleId> Rule ID of the fixed finding
42
+ --severity <level> Severity (critical, high, medium, low)
43
+ --days <n> Days to fix
44
+ --last <n> Show last N events (default: 20)
45
+ --format json JSON output
46
+ --help, -h Show this help
47
+
48
+ Tracks how quickly findings are resolved. Data in .judges/fix-rate.json.
49
+ `);
50
+ return;
51
+ }
52
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
53
+ const subcommand = argv.find((a) => ["show", "record", "trend", "clear"].includes(a)) || "show";
54
+ const store = loadStore();
55
+ if (subcommand === "record") {
56
+ const ruleId = argv.find((_a, i) => argv[i - 1] === "--rule") || "UNKNOWN";
57
+ const severity = argv.find((_a, i) => argv[i - 1] === "--severity") || "medium";
58
+ const days = parseInt(argv.find((_a, i) => argv[i - 1] === "--days") || "1", 10);
59
+ const now = new Date();
60
+ const foundDate = new Date(now.getTime() - days * 86400000);
61
+ store.events.push({
62
+ ruleId,
63
+ severity,
64
+ foundAt: foundDate.toISOString(),
65
+ fixedAt: now.toISOString(),
66
+ daysToFix: days,
67
+ });
68
+ saveStore(store);
69
+ console.log(`Recorded fix: ${ruleId} (${severity}) resolved in ${days} day(s).`);
70
+ return;
71
+ }
72
+ if (subcommand === "clear") {
73
+ saveStore({ version: "1.0.0", events: [] });
74
+ console.log("Fix rate data cleared.");
75
+ return;
76
+ }
77
+ if (subcommand === "trend") {
78
+ if (store.events.length === 0) {
79
+ console.log("No fix events recorded yet.");
80
+ return;
81
+ }
82
+ // Group by month
83
+ const monthly = new Map();
84
+ for (const e of store.events) {
85
+ const month = e.fixedAt.slice(0, 7);
86
+ const list = monthly.get(month) || [];
87
+ list.push(e.daysToFix);
88
+ monthly.set(month, list);
89
+ }
90
+ if (format === "json") {
91
+ const trend = [...monthly.entries()].map(([month, days]) => ({
92
+ month,
93
+ avgDays: days.reduce((s, d) => s + d, 0) / days.length,
94
+ fixes: days.length,
95
+ }));
96
+ console.log(JSON.stringify(trend, null, 2));
97
+ return;
98
+ }
99
+ console.log("\nFix Rate Trend:");
100
+ console.log("─".repeat(50));
101
+ for (const [month, days] of monthly) {
102
+ const avg = days.reduce((s, d) => s + d, 0) / days.length;
103
+ const bar = "█".repeat(Math.min(Math.round(avg), 30));
104
+ console.log(` ${month} avg ${avg.toFixed(1)}d (${days.length} fixes) ${bar}`);
105
+ }
106
+ console.log("─".repeat(50));
107
+ return;
108
+ }
109
+ // show
110
+ if (store.events.length === 0) {
111
+ console.log("No fix events recorded. Use 'judges finding-fix-rate record' to track fixes.");
112
+ return;
113
+ }
114
+ const avgDays = store.events.reduce((s, e) => s + e.daysToFix, 0) / store.events.length;
115
+ const criticals = store.events.filter((e) => e.severity === "critical");
116
+ const avgCriticalDays = criticals.length > 0 ? criticals.reduce((s, e) => s + e.daysToFix, 0) / criticals.length : 0;
117
+ if (format === "json") {
118
+ console.log(JSON.stringify({
119
+ totalFixes: store.events.length,
120
+ avgDaysToFix: avgDays,
121
+ avgCriticalDaysToFix: avgCriticalDays,
122
+ bySeverity: {
123
+ critical: criticals.length,
124
+ high: store.events.filter((e) => e.severity === "high").length,
125
+ medium: store.events.filter((e) => e.severity === "medium").length,
126
+ low: store.events.filter((e) => e.severity === "low").length,
127
+ },
128
+ }, null, 2));
129
+ return;
130
+ }
131
+ console.log("\nFix Rate Summary:");
132
+ console.log("─".repeat(40));
133
+ console.log(` Total fixes: ${store.events.length}`);
134
+ console.log(` Avg days to fix: ${avgDays.toFixed(1)}`);
135
+ console.log(` Avg critical fix time: ${avgCriticalDays > 0 ? avgCriticalDays.toFixed(1) + "d" : "N/A"}`);
136
+ console.log(` Critical fixes: ${criticals.length}`);
137
+ console.log(` High fixes: ${store.events.filter((e) => e.severity === "high").length}`);
138
+ console.log(` Medium fixes: ${store.events.filter((e) => e.severity === "medium").length}`);
139
+ console.log(` Low fixes: ${store.events.filter((e) => e.severity === "low").length}`);
140
+ console.log("─".repeat(40));
141
+ }
142
+ //# sourceMappingURL=finding-fix-rate.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-fix-rate.js","sourceRoot":"","sources":["../../src/commands/finding-fix-rate.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-impact — Estimate business impact of each finding.
3
+ */
4
+ export declare function runFindingImpact(argv: string[]): void;
5
+ //# sourceMappingURL=finding-impact.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-impact.d.ts","sourceRoot":"","sources":["../../src/commands/finding-impact.ts"],"names":[],"mappings":"AAAA;;GAEG;AA8EH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA+FrD"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Finding-impact — Estimate business impact of each finding.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
5
+ import { join, dirname } from "path";
6
+ // ─── Scoring ────────────────────────────────────────────────────────────────
7
+ const SEVERITY_IMPACT = {
8
+ critical: "critical",
9
+ high: "high",
10
+ medium: "medium",
11
+ low: "low",
12
+ info: "info",
13
+ };
14
+ const COST_ESTIMATES = {
15
+ critical: "$50,000–$500,000+ (breach, compliance penalty)",
16
+ high: "$10,000–$50,000 (data loss, downtime)",
17
+ medium: "$1,000–$10,000 (technical debt, moderate risk)",
18
+ low: "$100–$1,000 (minor refactor)",
19
+ info: "Minimal (best practice improvement)",
20
+ };
21
+ const EXPLOITABILITY = {
22
+ critical: "Easily exploitable, active attack vectors known",
23
+ high: "Exploitable with moderate skill",
24
+ medium: "Requires specific conditions to exploit",
25
+ low: "Difficult to exploit in practice",
26
+ info: "Not directly exploitable",
27
+ };
28
+ function assessFinding(finding) {
29
+ const severity = finding.severity || "medium";
30
+ const impact = SEVERITY_IMPACT[severity] || "medium";
31
+ const ruleId = finding.ruleId || "unknown";
32
+ const isInjection = /inject|sqli|xss|command/i.test(ruleId);
33
+ const isAuth = /auth|session|token|cred/i.test(ruleId);
34
+ const isCrypto = /crypt|hash|random|secret/i.test(ruleId);
35
+ let blastRadius = "Localized to component";
36
+ if (isInjection || isAuth)
37
+ blastRadius = "System-wide, potential data exfiltration";
38
+ else if (isCrypto)
39
+ blastRadius = "All encrypted data at risk";
40
+ return {
41
+ ruleId,
42
+ severity,
43
+ title: finding.title || "",
44
+ businessImpact: isInjection && impact !== "critical" ? "high" : impact,
45
+ estimatedCost: COST_ESTIMATES[impact] || COST_ESTIMATES["medium"],
46
+ exploitability: EXPLOITABILITY[impact] || EXPLOITABILITY["medium"],
47
+ blastRadius,
48
+ recommendation: finding.recommendation || "Review and remediate.",
49
+ };
50
+ }
51
+ // ─── CLI ────────────────────────────────────────────────────────────────────
52
+ export function runFindingImpact(argv) {
53
+ if (argv.includes("--help") || argv.includes("-h")) {
54
+ console.log(`
55
+ judges finding-impact — Estimate business impact of findings
56
+
57
+ Usage:
58
+ judges finding-impact --file report.json
59
+ judges finding-impact --file report.json --format json
60
+
61
+ Options:
62
+ --file <path> Path to a tribunal verdict JSON file
63
+ --format json Output as JSON
64
+ --min-impact <level> Filter by minimum impact (critical|high|medium|low|info)
65
+ --help, -h Show this help
66
+
67
+ Analyzes each finding and estimates:
68
+ • Business impact level (critical → info)
69
+ • Estimated remediation cost
70
+ • Exploitability assessment
71
+ • Blast radius (scope of potential damage)
72
+
73
+ Impact assessments are stored in .judges/finding-impact.json.
74
+ `);
75
+ return;
76
+ }
77
+ const filePath = argv.find((_a, i) => argv[i - 1] === "--file");
78
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
79
+ const minImpact = argv.find((_a, i) => argv[i - 1] === "--min-impact") || "info";
80
+ if (!filePath || !existsSync(filePath)) {
81
+ console.error("Error: --file is required and must exist.");
82
+ process.exitCode = 1;
83
+ return;
84
+ }
85
+ let verdict;
86
+ try {
87
+ verdict = JSON.parse(readFileSync(filePath, "utf-8"));
88
+ }
89
+ catch {
90
+ console.error("Error: Could not parse verdict file.");
91
+ process.exitCode = 1;
92
+ return;
93
+ }
94
+ const findings = verdict.findings || [];
95
+ if (findings.length === 0) {
96
+ console.log("No findings to assess.");
97
+ return;
98
+ }
99
+ const impactLevels = ["info", "low", "medium", "high", "critical"];
100
+ const minIdx = impactLevels.indexOf(minImpact);
101
+ const assessments = findings.map(assessFinding).filter((a) => impactLevels.indexOf(a.businessImpact) >= minIdx);
102
+ const summary = { critical: 0, high: 0, medium: 0, low: 0, info: 0 };
103
+ for (const a of assessments) {
104
+ summary[a.businessImpact]++;
105
+ }
106
+ const report = {
107
+ timestamp: new Date().toISOString(),
108
+ totalFindings: assessments.length,
109
+ assessments,
110
+ summary,
111
+ };
112
+ // Save
113
+ const outPath = join(".judges", "finding-impact.json");
114
+ mkdirSync(dirname(outPath), { recursive: true });
115
+ writeFileSync(outPath, JSON.stringify(report, null, 2), "utf-8");
116
+ if (format === "json") {
117
+ console.log(JSON.stringify(report, null, 2));
118
+ return;
119
+ }
120
+ console.log("\nFinding Impact Assessment:");
121
+ console.log("═".repeat(70));
122
+ console.log(` Total findings assessed: ${assessments.length}`);
123
+ console.log(` Critical: ${summary.critical} High: ${summary.high} Medium: ${summary.medium} Low: ${summary.low} Info: ${summary.info}`);
124
+ console.log("═".repeat(70));
125
+ for (const a of assessments) {
126
+ console.log(`\n [${a.businessImpact.toUpperCase()}] ${a.ruleId}`);
127
+ console.log(` Title: ${a.title}`);
128
+ console.log(` Est. Cost: ${a.estimatedCost}`);
129
+ console.log(` Exploitability: ${a.exploitability}`);
130
+ console.log(` Blast Radius: ${a.blastRadius}`);
131
+ console.log(` Recommendation: ${a.recommendation}`);
132
+ }
133
+ console.log("\n" + "═".repeat(70));
134
+ console.log(` Report saved to ${outPath}`);
135
+ }
136
+ //# sourceMappingURL=finding-impact.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-impact.js","sourceRoot":"","sources":["../../src/commands/finding-impact.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Finding-recurrence — Track findings that keep coming back after being fixed.
3
+ */
4
+ export declare function runFindingRecurrence(argv: string[]): void;
5
+ //# sourceMappingURL=finding-recurrence.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-recurrence.d.ts","sourceRoot":"","sources":["../../src/commands/finding-recurrence.ts"],"names":[],"mappings":"AAAA;;GAEG;AA+CH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAsHzD"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Finding-recurrence — Track findings that keep coming back after being fixed.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
5
+ import { join, dirname } from "path";
6
+ // ─── Storage ────────────────────────────────────────────────────────────────
7
+ const RECURRENCE_FILE = join(".judges", "finding-recurrence.json");
8
+ function loadStore() {
9
+ if (!existsSync(RECURRENCE_FILE))
10
+ return { version: "1.0.0", records: [] };
11
+ try {
12
+ return JSON.parse(readFileSync(RECURRENCE_FILE, "utf-8"));
13
+ }
14
+ catch {
15
+ return { version: "1.0.0", records: [] };
16
+ }
17
+ }
18
+ function saveStore(store) {
19
+ mkdirSync(dirname(RECURRENCE_FILE), { recursive: true });
20
+ writeFileSync(RECURRENCE_FILE, JSON.stringify(store, null, 2), "utf-8");
21
+ }
22
+ function fingerprint(f) {
23
+ return [f.ruleId || "", f.title || "", String(f.severity || "")].join("|").toLowerCase();
24
+ }
25
+ // ─── CLI ────────────────────────────────────────────────────────────────────
26
+ export function runFindingRecurrence(argv) {
27
+ if (argv.includes("--help") || argv.includes("-h")) {
28
+ console.log(`
29
+ judges finding-recurrence — Track recurring findings
30
+
31
+ Usage:
32
+ judges finding-recurrence update --file verdict.json Update records
33
+ judges finding-recurrence show Show recurring findings
34
+ judges finding-recurrence show --min 3 Show findings with 3+ occurrences
35
+ judges finding-recurrence clear Clear all data
36
+
37
+ Subcommands:
38
+ update Update recurrence records from verdict
39
+ show Show recurring findings
40
+ clear Clear all data
41
+
42
+ Options:
43
+ --file <path> Verdict JSON file (for update)
44
+ --min <n> Minimum occurrences to show (default: 2)
45
+ --format json JSON output
46
+ --help, -h Show this help
47
+
48
+ Tracks findings that keep reappearing. Data in .judges/finding-recurrence.json.
49
+ `);
50
+ return;
51
+ }
52
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
53
+ const subcommand = argv.find((a) => ["update", "show", "clear"].includes(a)) || "show";
54
+ const store = loadStore();
55
+ if (subcommand === "update") {
56
+ const file = argv.find((_a, i) => argv[i - 1] === "--file");
57
+ if (!file || !existsSync(file)) {
58
+ console.error("Error: --file with valid verdict JSON is required.");
59
+ process.exitCode = 1;
60
+ return;
61
+ }
62
+ let verdict;
63
+ try {
64
+ verdict = JSON.parse(readFileSync(file, "utf-8"));
65
+ }
66
+ catch {
67
+ console.error("Error: Failed to parse verdict file.");
68
+ process.exitCode = 1;
69
+ return;
70
+ }
71
+ const now = new Date().toISOString();
72
+ const seenFingerprints = new Set();
73
+ let newCount = 0;
74
+ let recurCount = 0;
75
+ for (const f of verdict.findings || []) {
76
+ const fp = fingerprint(f);
77
+ seenFingerprints.add(fp);
78
+ const existing = store.records.find((r) => r.fingerprint === fp);
79
+ if (existing) {
80
+ existing.occurrences++;
81
+ existing.lastSeen = now;
82
+ recurCount++;
83
+ }
84
+ else {
85
+ store.records.push({
86
+ fingerprint: fp,
87
+ ruleId: f.ruleId || "",
88
+ title: f.title || "",
89
+ occurrences: 1,
90
+ firstSeen: now,
91
+ lastSeen: now,
92
+ resolvedCount: 0,
93
+ });
94
+ newCount++;
95
+ }
96
+ }
97
+ // Mark resolved findings
98
+ for (const r of store.records) {
99
+ if (!seenFingerprints.has(r.fingerprint) && r.occurrences > 0) {
100
+ r.resolvedCount++;
101
+ }
102
+ }
103
+ saveStore(store);
104
+ console.log(`Updated: ${newCount} new, ${recurCount} recurring findings tracked.`);
105
+ return;
106
+ }
107
+ if (subcommand === "clear") {
108
+ saveStore({ version: "1.0.0", records: [] });
109
+ console.log("Recurrence data cleared.");
110
+ return;
111
+ }
112
+ // show
113
+ const minOccurrences = parseInt(argv.find((_a, i) => argv[i - 1] === "--min") || "2", 10);
114
+ const recurring = store.records.filter((r) => r.occurrences >= minOccurrences);
115
+ recurring.sort((a, b) => b.occurrences - a.occurrences);
116
+ if (format === "json") {
117
+ console.log(JSON.stringify(recurring, null, 2));
118
+ return;
119
+ }
120
+ if (recurring.length === 0) {
121
+ console.log(`No findings with ${minOccurrences}+ occurrences.`);
122
+ return;
123
+ }
124
+ console.log(`\nRecurring Findings (${minOccurrences}+ occurrences):`);
125
+ console.log("─".repeat(70));
126
+ console.log(" Occurrences Rule Title");
127
+ console.log("─".repeat(70));
128
+ for (const r of recurring.slice(0, 30)) {
129
+ console.log(` ${String(r.occurrences).padEnd(12)} ${(r.ruleId || "-").padEnd(13)} ${r.title.slice(0, 40)}`);
130
+ }
131
+ console.log("─".repeat(70));
132
+ console.log(` ${recurring.length} recurring finding(s) found`);
133
+ if (recurring.length > 30)
134
+ console.log(` (showing top 30 of ${recurring.length})`);
135
+ }
136
+ //# sourceMappingURL=finding-recurrence.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"finding-recurrence.js","sourceRoot":"","sources":["../../src/commands/finding-recurrence.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-archive — Archive and retrieve old review results.
3
+ */
4
+ export declare function runReviewArchive(argv: string[]): void;
5
+ //# sourceMappingURL=review-archive.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-archive.d.ts","sourceRoot":"","sources":["../../src/commands/review-archive.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6CH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAmHrD"}
@@ -0,0 +1,136 @@
1
+ /**
2
+ * Review-archive — Archive and retrieve old review results.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync, copyFileSync } from "fs";
5
+ import { join, basename, dirname } from "path";
6
+ // ─── Storage ────────────────────────────────────────────────────────────────
7
+ const ARCHIVE_DIR = join(".judges", "archive");
8
+ const INDEX_FILE = join(ARCHIVE_DIR, "index.json");
9
+ function loadIndex() {
10
+ if (!existsSync(INDEX_FILE))
11
+ return { version: "1.0.0", entries: [] };
12
+ try {
13
+ return JSON.parse(readFileSync(INDEX_FILE, "utf-8"));
14
+ }
15
+ catch {
16
+ return { version: "1.0.0", entries: [] };
17
+ }
18
+ }
19
+ function saveIndex(index) {
20
+ mkdirSync(ARCHIVE_DIR, { recursive: true });
21
+ writeFileSync(INDEX_FILE, JSON.stringify(index, null, 2), "utf-8");
22
+ }
23
+ function generateId() {
24
+ return `arc-${Date.now().toString(36)}`;
25
+ }
26
+ // ─── CLI ────────────────────────────────────────────────────────────────────
27
+ export function runReviewArchive(argv) {
28
+ if (argv.includes("--help") || argv.includes("-h")) {
29
+ console.log(`
30
+ judges review-archive — Archive and retrieve old review results
31
+
32
+ Usage:
33
+ judges review-archive add --file report.json --label sprint-42
34
+ judges review-archive list
35
+ judges review-archive restore --id arc-abc123 --out restored.json
36
+ judges review-archive clear
37
+
38
+ Subcommands:
39
+ add Archive a review result file
40
+ list List archived reviews
41
+ restore Restore an archived review
42
+ clear Clear all archived data
43
+
44
+ Options:
45
+ --file <path> File to archive
46
+ --label <text> Label for the archive entry
47
+ --id <id> Archive entry ID
48
+ --out <path> Output path for restored file
49
+ --format json JSON output
50
+ --help, -h Show this help
51
+
52
+ Archives are stored in .judges/archive/.
53
+ `);
54
+ return;
55
+ }
56
+ const subcommand = argv.find((a) => ["add", "list", "restore", "clear"].includes(a)) || "list";
57
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
58
+ const index = loadIndex();
59
+ if (subcommand === "add") {
60
+ const filePath = argv.find((_a, i) => argv[i - 1] === "--file");
61
+ const label = argv.find((_a, i) => argv[i - 1] === "--label") || "";
62
+ if (!filePath || !existsSync(filePath)) {
63
+ console.error("Error: --file is required and must exist.");
64
+ process.exitCode = 1;
65
+ return;
66
+ }
67
+ const id = generateId();
68
+ const archiveName = `${id}-${basename(filePath)}`;
69
+ const archivePath = join(ARCHIVE_DIR, archiveName);
70
+ mkdirSync(ARCHIVE_DIR, { recursive: true });
71
+ copyFileSync(filePath, archivePath);
72
+ const stat = readFileSync(filePath);
73
+ index.entries.push({
74
+ id,
75
+ originalPath: filePath,
76
+ archivedAt: new Date().toISOString(),
77
+ label,
78
+ sizeBytes: stat.length,
79
+ });
80
+ saveIndex(index);
81
+ console.log(`Archived "${filePath}" as ${id}${label ? ` (${label})` : ""}.`);
82
+ return;
83
+ }
84
+ if (subcommand === "restore") {
85
+ const id = argv.find((_a, i) => argv[i - 1] === "--id");
86
+ const out = argv.find((_a, i) => argv[i - 1] === "--out");
87
+ if (!id) {
88
+ console.error("Error: --id is required.");
89
+ process.exitCode = 1;
90
+ return;
91
+ }
92
+ const entry = index.entries.find((e) => e.id === id);
93
+ if (!entry) {
94
+ console.error(`Error: Archive "${id}" not found.`);
95
+ process.exitCode = 1;
96
+ return;
97
+ }
98
+ // Find the archived file
99
+ const files = readdirSync(ARCHIVE_DIR);
100
+ const archiveFile = files.find((f) => f.startsWith(id));
101
+ if (!archiveFile) {
102
+ console.error(`Error: Archive file for "${id}" missing from disk.`);
103
+ process.exitCode = 1;
104
+ return;
105
+ }
106
+ const dest = out || entry.originalPath;
107
+ mkdirSync(dirname(dest), { recursive: true });
108
+ copyFileSync(join(ARCHIVE_DIR, archiveFile), dest);
109
+ console.log(`Restored ${id} to "${dest}".`);
110
+ return;
111
+ }
112
+ if (subcommand === "clear") {
113
+ saveIndex({ version: "1.0.0", entries: [] });
114
+ console.log("Archive index cleared.");
115
+ return;
116
+ }
117
+ // list
118
+ if (index.entries.length === 0) {
119
+ console.log("No archived reviews. Use 'judges review-archive add' to start.");
120
+ return;
121
+ }
122
+ if (format === "json") {
123
+ console.log(JSON.stringify(index.entries, null, 2));
124
+ return;
125
+ }
126
+ console.log("\nArchived Reviews:");
127
+ console.log("─".repeat(70));
128
+ for (const e of index.entries) {
129
+ const size = e.sizeBytes < 1024 ? `${e.sizeBytes}B` : `${(e.sizeBytes / 1024).toFixed(1)}KB`;
130
+ console.log(` ${e.id} ${e.archivedAt.slice(0, 10)} ${size.padEnd(8)} ${e.label || "(no label)"}`);
131
+ console.log(` Original: ${e.originalPath}`);
132
+ }
133
+ console.log("─".repeat(70));
134
+ console.log(` Total: ${index.entries.length} archived review(s)`);
135
+ }
136
+ //# sourceMappingURL=review-archive.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-archive.js","sourceRoot":"","sources":["../../src/commands/review-archive.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-benchmark-self — Benchmark your review metrics against your own history.
3
+ */
4
+ export declare function runReviewBenchmarkSelf(argv: string[]): void;
5
+ //# sourceMappingURL=review-benchmark-self.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-benchmark-self.d.ts","sourceRoot":"","sources":["../../src/commands/review-benchmark-self.ts"],"names":[],"mappings":"AAAA;;GAEG;AAyCH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA+I3D"}