@kevinrabun/judges 3.66.0 → 3.67.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 +8 -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/config-lint.d.ts +5 -0
  6. package/dist/commands/config-lint.d.ts.map +1 -0
  7. package/dist/commands/config-lint.js +188 -0
  8. package/dist/commands/config-lint.js.map +1 -0
  9. package/dist/commands/finding-age.d.ts +5 -0
  10. package/dist/commands/finding-age.d.ts.map +1 -0
  11. package/dist/commands/finding-age.js +146 -0
  12. package/dist/commands/finding-age.js.map +1 -0
  13. package/dist/commands/finding-rank.d.ts +5 -0
  14. package/dist/commands/finding-rank.d.ts.map +1 -0
  15. package/dist/commands/finding-rank.js +139 -0
  16. package/dist/commands/finding-rank.js.map +1 -0
  17. package/dist/commands/review-dashboard.d.ts +5 -0
  18. package/dist/commands/review-dashboard.d.ts.map +1 -0
  19. package/dist/commands/review-dashboard.js +141 -0
  20. package/dist/commands/review-dashboard.js.map +1 -0
  21. package/dist/commands/review-diff-summary.d.ts +5 -0
  22. package/dist/commands/review-diff-summary.d.ts.map +1 -0
  23. package/dist/commands/review-diff-summary.js +155 -0
  24. package/dist/commands/review-diff-summary.js.map +1 -0
  25. package/dist/commands/review-notify.d.ts +5 -0
  26. package/dist/commands/review-notify.d.ts.map +1 -0
  27. package/dist/commands/review-notify.js +144 -0
  28. package/dist/commands/review-notify.js.map +1 -0
  29. package/dist/commands/review-offline.d.ts +5 -0
  30. package/dist/commands/review-offline.d.ts.map +1 -0
  31. package/dist/commands/review-offline.js +126 -0
  32. package/dist/commands/review-offline.js.map +1 -0
  33. package/dist/commands/review-quota.d.ts +5 -0
  34. package/dist/commands/review-quota.d.ts.map +1 -0
  35. package/dist/commands/review-quota.js +127 -0
  36. package/dist/commands/review-quota.js.map +1 -0
  37. package/package.json +1 -1
  38. package/server.json +2 -2
@@ -0,0 +1,141 @@
1
+ /**
2
+ * Review-dashboard — Terminal-based dashboard summary of review health.
3
+ */
4
+ import { readFileSync, existsSync, readdirSync } from "fs";
5
+ import { join } from "path";
6
+ // ─── CLI ────────────────────────────────────────────────────────────────────
7
+ export function runReviewDashboard(argv) {
8
+ if (argv.includes("--help") || argv.includes("-h")) {
9
+ console.log(`
10
+ judges review-dashboard — Terminal dashboard of review health
11
+
12
+ Usage:
13
+ judges review-dashboard Show dashboard
14
+ judges review-dashboard --dir ./results From verdict directory
15
+ judges review-dashboard --file verdict.json From single file
16
+ judges review-dashboard --format json JSON output
17
+
18
+ Options:
19
+ --file <path> Single verdict file
20
+ --dir <directory> Directory with verdict JSON files
21
+ --format json JSON output
22
+ --help, -h Show this help
23
+
24
+ Displays a summary dashboard with key metrics: score,
25
+ findings by severity, trends, and actionable insights.
26
+ `);
27
+ return;
28
+ }
29
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
30
+ const file = argv.find((_a, i) => argv[i - 1] === "--file");
31
+ const dir = argv.find((_a, i) => argv[i - 1] === "--dir");
32
+ const verdicts = [];
33
+ if (file && existsSync(file)) {
34
+ try {
35
+ verdicts.push(JSON.parse(readFileSync(file, "utf-8")));
36
+ }
37
+ catch {
38
+ /* skip */
39
+ }
40
+ }
41
+ if (dir && existsSync(dir)) {
42
+ try {
43
+ const entries = readdirSync(dir);
44
+ for (const entry of entries) {
45
+ if (typeof entry === "string" && entry.endsWith(".json")) {
46
+ try {
47
+ verdicts.push(JSON.parse(readFileSync(join(dir, entry), "utf-8")));
48
+ }
49
+ catch {
50
+ /* skip */
51
+ }
52
+ }
53
+ }
54
+ }
55
+ catch {
56
+ /* skip */
57
+ }
58
+ }
59
+ if (verdicts.length === 0) {
60
+ console.log("\n No verdict data found. Use --file or --dir to provide verdict JSON files.\n");
61
+ return;
62
+ }
63
+ // Compute metrics
64
+ const scores = verdicts.map((v) => v.overallScore || 0);
65
+ const avgScore = Math.round(scores.reduce((a, b) => a + b, 0) / scores.length);
66
+ const totalFindings = verdicts.reduce((sum, v) => sum + (v.findings || []).length, 0);
67
+ const severityCounts = {};
68
+ for (const v of verdicts) {
69
+ for (const f of v.findings || []) {
70
+ const sev = f.severity || "unknown";
71
+ severityCounts[sev] = (severityCounts[sev] || 0) + 1;
72
+ }
73
+ }
74
+ const criticalCount = severityCounts["critical"] || 0;
75
+ const highCount = severityCounts["high"] || 0;
76
+ const mediumCount = severityCounts["medium"] || 0;
77
+ const lowCount = severityCounts["low"] || 0;
78
+ const passCount = verdicts.filter((v) => v.overallVerdict === "pass").length;
79
+ const failCount = verdicts.filter((v) => v.overallVerdict === "fail").length;
80
+ const grade = avgScore >= 90 ? "A" : avgScore >= 80 ? "B" : avgScore >= 70 ? "C" : avgScore >= 60 ? "D" : "F";
81
+ if (format === "json") {
82
+ console.log(JSON.stringify({
83
+ reviewCount: verdicts.length,
84
+ avgScore,
85
+ grade,
86
+ totalFindings,
87
+ severityCounts,
88
+ passCount,
89
+ failCount,
90
+ }, null, 2));
91
+ return;
92
+ }
93
+ const barLen = Math.round((avgScore / 100) * 20);
94
+ const scoreBar = "█".repeat(barLen) + "░".repeat(20 - barLen);
95
+ console.log(`
96
+ ╔═══════════════════════════════════════════╗
97
+ ║ JUDGES REVIEW DASHBOARD ║
98
+ ╚═══════════════════════════════════════════╝
99
+
100
+ Score: ${scoreBar} ${avgScore}/100 (Grade ${grade})
101
+
102
+ ┌─────────────────────────────────────────┐
103
+ │ Reviews: ${String(verdicts.length).padEnd(6)} Pass: ${String(passCount).padEnd(6)} Fail: ${String(failCount).padEnd(4)}│
104
+ │ Findings: ${String(totalFindings).padEnd(30)}│
105
+ └─────────────────────────────────────────┘
106
+
107
+ Severity Distribution:
108
+ 🔴 Critical: ${"█".repeat(Math.min(criticalCount, 30))} ${criticalCount}
109
+ 🟠 High: ${"█".repeat(Math.min(highCount, 30))} ${highCount}
110
+ 🟡 Medium: ${"█".repeat(Math.min(mediumCount, 30))} ${mediumCount}
111
+ 🟢 Low: ${"█".repeat(Math.min(lowCount, 30))} ${lowCount}
112
+ `);
113
+ // Top rules
114
+ const ruleCounts = new Map();
115
+ for (const v of verdicts) {
116
+ for (const f of v.findings || []) {
117
+ const rule = f.ruleId || "unknown";
118
+ ruleCounts.set(rule, (ruleCounts.get(rule) || 0) + 1);
119
+ }
120
+ }
121
+ const topRules = [...ruleCounts.entries()].sort(([, a], [, b]) => b - a).slice(0, 5);
122
+ if (topRules.length > 0) {
123
+ console.log(" Top Rules:");
124
+ for (const [rule, count] of topRules) {
125
+ console.log(` ${rule.padEnd(30)} ${count} occurrence(s)`);
126
+ }
127
+ console.log();
128
+ }
129
+ // Insights
130
+ console.log(" Insights:");
131
+ if (criticalCount > 0)
132
+ console.log(` ⚠️ ${criticalCount} critical finding(s) require immediate attention`);
133
+ if (failCount > passCount)
134
+ console.log(" ⚠️ More reviews failing than passing — consider reviewing thresholds");
135
+ if (avgScore >= 80)
136
+ console.log(" ✅ Code quality is above target");
137
+ if (totalFindings === 0)
138
+ console.log(" ✅ Clean — no findings detected");
139
+ console.log();
140
+ }
141
+ //# sourceMappingURL=review-dashboard.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-dashboard.js","sourceRoot":"","sources":["../../src/commands/review-dashboard.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-diff-summary — Concise summary of changes and findings.
3
+ */
4
+ export declare function runReviewDiffSummary(argv: string[]): void;
5
+ //# sourceMappingURL=review-diff-summary.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-diff-summary.d.ts","sourceRoot":"","sources":["../../src/commands/review-diff-summary.ts"],"names":[],"mappings":"AAAA;;GAEG;AAOH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAqLzD"}
@@ -0,0 +1,155 @@
1
+ /**
2
+ * Review-diff-summary — Concise summary of changes and findings.
3
+ */
4
+ import { readFileSync, existsSync } from "fs";
5
+ // ─── CLI ────────────────────────────────────────────────────────────────────
6
+ export function runReviewDiffSummary(argv) {
7
+ if (argv.includes("--help") || argv.includes("-h")) {
8
+ console.log(`
9
+ judges review-diff-summary — Concise summary of changes + findings
10
+
11
+ Usage:
12
+ judges review-diff-summary --file verdict.json
13
+ judges review-diff-summary --before before.json --after after.json
14
+ judges review-diff-summary --format json
15
+
16
+ Options:
17
+ --file <path> Single verdict to summarize
18
+ --before <path> Baseline verdict (before changes)
19
+ --after <path> Updated verdict (after changes)
20
+ --max-lines <n> Max summary lines (default: 20)
21
+ --format json JSON output
22
+ --help, -h Show this help
23
+
24
+ Generates a compact, PR-ready summary with key changes
25
+ and finding deltas. Ideal for commit messages or PR descriptions.
26
+ `);
27
+ return;
28
+ }
29
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
30
+ const file = argv.find((_a, i) => argv[i - 1] === "--file");
31
+ const beforeFile = argv.find((_a, i) => argv[i - 1] === "--before");
32
+ const afterFile = argv.find((_a, i) => argv[i - 1] === "--after");
33
+ const maxLines = parseInt(argv.find((_a, i) => argv[i - 1] === "--max-lines") || "20", 10);
34
+ // Comparison mode
35
+ if (beforeFile && afterFile) {
36
+ if (!existsSync(beforeFile) || !existsSync(afterFile)) {
37
+ console.error("Error: Both --before and --after files must exist.");
38
+ process.exitCode = 1;
39
+ return;
40
+ }
41
+ let before;
42
+ let after;
43
+ try {
44
+ before = JSON.parse(readFileSync(beforeFile, "utf-8"));
45
+ after = JSON.parse(readFileSync(afterFile, "utf-8"));
46
+ }
47
+ catch {
48
+ console.error("Error: Could not parse verdict files.");
49
+ process.exitCode = 1;
50
+ return;
51
+ }
52
+ const beforeFindings = before.findings || [];
53
+ const afterFindings = after.findings || [];
54
+ const scoreDelta = (after.overallScore || 0) - (before.overallScore || 0);
55
+ const findingsDelta = afterFindings.length - beforeFindings.length;
56
+ const beforeKeys = new Set(beforeFindings.map(fKey));
57
+ const afterKeys = new Set(afterFindings.map(fKey));
58
+ const resolved = beforeFindings.filter((f) => !afterKeys.has(fKey(f)));
59
+ const introduced = afterFindings.filter((f) => !beforeKeys.has(fKey(f)));
60
+ if (format === "json") {
61
+ console.log(JSON.stringify({
62
+ scoreBefore: before.overallScore || 0,
63
+ scoreAfter: after.overallScore || 0,
64
+ scoreDelta,
65
+ findingsBefore: beforeFindings.length,
66
+ findingsAfter: afterFindings.length,
67
+ findingsDelta,
68
+ resolved: resolved.length,
69
+ introduced: introduced.length,
70
+ }, null, 2));
71
+ return;
72
+ }
73
+ console.log(`\n Review Diff Summary\n ═════════════════════════════`);
74
+ console.log(` Score: ${before.overallScore || 0} → ${after.overallScore || 0} (${scoreDelta >= 0 ? "+" : ""}${scoreDelta})`);
75
+ console.log(` Findings: ${beforeFindings.length} → ${afterFindings.length} (${findingsDelta >= 0 ? "+" : ""}${findingsDelta})`);
76
+ console.log(` Resolved: ${resolved.length} ✅`);
77
+ console.log(` Introduced: ${introduced.length} ${introduced.length > 0 ? "🆕" : ""}`);
78
+ if (resolved.length > 0) {
79
+ console.log("\n Resolved:");
80
+ for (const f of resolved.slice(0, maxLines)) {
81
+ console.log(` ✅ [${(f.severity || "").toUpperCase()}] ${f.title || f.ruleId}`);
82
+ }
83
+ }
84
+ if (introduced.length > 0) {
85
+ console.log("\n Introduced:");
86
+ for (const f of introduced.slice(0, maxLines)) {
87
+ console.log(` 🆕 [${(f.severity || "").toUpperCase()}] ${f.title || f.ruleId}`);
88
+ }
89
+ }
90
+ console.log();
91
+ return;
92
+ }
93
+ // Single-file mode
94
+ if (!file) {
95
+ console.error("Error: --file or both --before and --after are required.");
96
+ process.exitCode = 1;
97
+ return;
98
+ }
99
+ if (!existsSync(file)) {
100
+ console.error(`Error: File not found: ${file}`);
101
+ process.exitCode = 1;
102
+ return;
103
+ }
104
+ let verdict;
105
+ try {
106
+ verdict = JSON.parse(readFileSync(file, "utf-8"));
107
+ }
108
+ catch {
109
+ console.error(`Error: Could not parse ${file}`);
110
+ process.exitCode = 1;
111
+ return;
112
+ }
113
+ const findings = verdict.findings || [];
114
+ const severityCounts = {};
115
+ for (const f of findings) {
116
+ const sev = f.severity || "unknown";
117
+ severityCounts[sev] = (severityCounts[sev] || 0) + 1;
118
+ }
119
+ if (format === "json") {
120
+ console.log(JSON.stringify({
121
+ score: verdict.overallScore || 0,
122
+ verdict: verdict.overallVerdict || "n/a",
123
+ totalFindings: findings.length,
124
+ severityCounts,
125
+ summary: verdict.summary || "",
126
+ }, null, 2));
127
+ return;
128
+ }
129
+ console.log(`\n Review Summary\n ─────────────────────────────`);
130
+ console.log(` Score: ${verdict.overallScore || 0}/100 | Verdict: ${verdict.overallVerdict || "n/a"} | Findings: ${findings.length}`);
131
+ const sevParts = [];
132
+ for (const [sev, count] of Object.entries(severityCounts)) {
133
+ sevParts.push(`${sev}: ${count}`);
134
+ }
135
+ if (sevParts.length > 0) {
136
+ console.log(` ${sevParts.join(" | ")}`);
137
+ }
138
+ if (verdict.summary) {
139
+ console.log(`\n ${verdict.summary}`);
140
+ }
141
+ if (findings.length > 0) {
142
+ console.log("\n Top findings:");
143
+ for (const f of findings.slice(0, Math.min(maxLines, findings.length))) {
144
+ console.log(` [${(f.severity || "").toUpperCase()}] ${f.title || f.ruleId}`);
145
+ }
146
+ if (findings.length > maxLines) {
147
+ console.log(` ... and ${findings.length - maxLines} more`);
148
+ }
149
+ }
150
+ console.log();
151
+ }
152
+ function fKey(f) {
153
+ return [f.ruleId || "", f.title || "", String(f.severity || "")].join("|").toLowerCase();
154
+ }
155
+ //# sourceMappingURL=review-diff-summary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-diff-summary.js","sourceRoot":"","sources":["../../src/commands/review-diff-summary.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-notify — Local notification configuration for review events.
3
+ */
4
+ export declare function runReviewNotify(argv: string[]): void;
5
+ //# sourceMappingURL=review-notify.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-notify.d.ts","sourceRoot":"","sources":["../../src/commands/review-notify.ts"],"names":[],"mappings":"AAAA;;GAEG;AAyCH,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAqIpD"}
@@ -0,0 +1,144 @@
1
+ /**
2
+ * Review-notify — Local notification configuration for review events.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
5
+ import { join, dirname } from "path";
6
+ // ─── Storage ────────────────────────────────────────────────────────────────
7
+ const NOTIFY_FILE = join(".judges", "notify-rules.json");
8
+ function loadNotifyStore() {
9
+ if (!existsSync(NOTIFY_FILE))
10
+ return { version: "1.0.0", rules: [] };
11
+ try {
12
+ return JSON.parse(readFileSync(NOTIFY_FILE, "utf-8"));
13
+ }
14
+ catch {
15
+ return { version: "1.0.0", rules: [] };
16
+ }
17
+ }
18
+ function saveNotifyStore(store) {
19
+ mkdirSync(dirname(NOTIFY_FILE), { recursive: true });
20
+ writeFileSync(NOTIFY_FILE, JSON.stringify(store, null, 2), "utf-8");
21
+ }
22
+ // ─── CLI ────────────────────────────────────────────────────────────────────
23
+ export function runReviewNotify(argv) {
24
+ if (argv.includes("--help") || argv.includes("-h")) {
25
+ console.log(`
26
+ judges review-notify — Configure notifications for review events
27
+
28
+ Usage:
29
+ judges review-notify list List notification rules
30
+ judges review-notify add --event fail --action log --condition "score<70"
31
+ judges review-notify remove --id nfy-xxx Remove a rule
32
+ judges review-notify enable --id nfy-xxx Enable a rule
33
+ judges review-notify disable --id nfy-xxx Disable a rule
34
+
35
+ Subcommands:
36
+ list List all notification rules
37
+ add Add a notification rule
38
+ remove Remove a notification rule
39
+ enable Enable a rule
40
+ disable Disable a rule
41
+
42
+ Events:
43
+ fail Review verdict is fail
44
+ critical Critical finding detected
45
+ score-drop Score drops below threshold
46
+ new-finding New finding introduced
47
+
48
+ Actions:
49
+ log Write to .judges/notifications.log
50
+ console Print to stderr
51
+ file Write to specified file
52
+
53
+ Options:
54
+ --event <name> Event to trigger on
55
+ --action <type> Action to take
56
+ --condition <expr> Condition expression
57
+ --id <id> Rule ID
58
+ --format json JSON output
59
+ --help, -h Show this help
60
+
61
+ Notification rules are stored in .judges/notify-rules.json.
62
+ No data is sent externally — all notifications are local.
63
+ `);
64
+ return;
65
+ }
66
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
67
+ const subcommand = argv.find((a) => ["list", "add", "remove", "enable", "disable"].includes(a)) || "list";
68
+ const store = loadNotifyStore();
69
+ if (subcommand === "add") {
70
+ const event = argv.find((_a, i) => argv[i - 1] === "--event") || "fail";
71
+ const action = argv.find((_a, i) => argv[i - 1] === "--action") || "log";
72
+ const condition = argv.find((_a, i) => argv[i - 1] === "--condition") || "";
73
+ const validEvents = ["fail", "critical", "score-drop", "new-finding"];
74
+ if (!validEvents.includes(event)) {
75
+ console.error(`Error: Unknown event '${event}'. Valid: ${validEvents.join(", ")}`);
76
+ process.exitCode = 1;
77
+ return;
78
+ }
79
+ const validActions = ["log", "console", "file"];
80
+ if (!validActions.includes(action)) {
81
+ console.error(`Error: Unknown action '${action}'. Valid: ${validActions.join(", ")}`);
82
+ process.exitCode = 1;
83
+ return;
84
+ }
85
+ const rule = {
86
+ id: `nfy-${Date.now().toString(36)}`,
87
+ event,
88
+ condition,
89
+ action,
90
+ enabled: true,
91
+ createdAt: new Date().toISOString(),
92
+ };
93
+ store.rules.push(rule);
94
+ saveNotifyStore(store);
95
+ console.log(`Added notification rule '${rule.id}' — on ${event} → ${action}`);
96
+ return;
97
+ }
98
+ if (subcommand === "remove") {
99
+ const id = argv.find((_a, i) => argv[i - 1] === "--id");
100
+ if (!id) {
101
+ console.error("Error: --id is required.");
102
+ process.exitCode = 1;
103
+ return;
104
+ }
105
+ store.rules = store.rules.filter((r) => r.id !== id);
106
+ saveNotifyStore(store);
107
+ console.log(`Removed notification rule '${id}'.`);
108
+ return;
109
+ }
110
+ if (subcommand === "enable" || subcommand === "disable") {
111
+ const id = argv.find((_a, i) => argv[i - 1] === "--id");
112
+ if (!id) {
113
+ console.error("Error: --id is required.");
114
+ process.exitCode = 1;
115
+ return;
116
+ }
117
+ const rule = store.rules.find((r) => r.id === id);
118
+ if (!rule) {
119
+ console.error(`Error: Rule '${id}' not found.`);
120
+ process.exitCode = 1;
121
+ return;
122
+ }
123
+ rule.enabled = subcommand === "enable";
124
+ saveNotifyStore(store);
125
+ console.log(`Rule '${id}' ${subcommand}d.`);
126
+ return;
127
+ }
128
+ // List
129
+ if (format === "json") {
130
+ console.log(JSON.stringify(store, null, 2));
131
+ return;
132
+ }
133
+ console.log(`\n Notification Rules (${store.rules.length})\n ═════════════════════════════`);
134
+ if (store.rules.length === 0) {
135
+ console.log(" No rules. Add one with: judges review-notify add --event fail --action log");
136
+ }
137
+ for (const rule of store.rules) {
138
+ const status = rule.enabled ? "✅" : "⏸️";
139
+ const cond = rule.condition ? ` when ${rule.condition}` : "";
140
+ console.log(` ${status} ${rule.id} — on ${rule.event}${cond} → ${rule.action}`);
141
+ }
142
+ console.log();
143
+ }
144
+ //# sourceMappingURL=review-notify.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-notify.js","sourceRoot":"","sources":["../../src/commands/review-notify.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-offline — Offline mode support for air-gapped environments.
3
+ */
4
+ export declare function runReviewOffline(argv: string[]): void;
5
+ //# sourceMappingURL=review-offline.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-offline.d.ts","sourceRoot":"","sources":["../../src/commands/review-offline.ts"],"names":[],"mappings":"AAAA;;GAEG;AAoBH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAqIrD"}
@@ -0,0 +1,126 @@
1
+ /**
2
+ * Review-offline — Offline mode support for air-gapped environments.
3
+ */
4
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
5
+ import { join, dirname } from "path";
6
+ // ─── Storage ────────────────────────────────────────────────────────────────
7
+ const OFFLINE_DIR = join(".judges", "offline");
8
+ // ─── CLI ────────────────────────────────────────────────────────────────────
9
+ export function runReviewOffline(argv) {
10
+ if (argv.includes("--help") || argv.includes("-h")) {
11
+ console.log(`
12
+ judges review-offline — Offline mode support
13
+
14
+ Usage:
15
+ judges review-offline status Check offline readiness
16
+ judges review-offline prepare Prepare for offline use
17
+ judges review-offline bundle --output bundle.json Create offline bundle
18
+ judges review-offline verify Verify offline bundle
19
+
20
+ Subcommands:
21
+ status Check if judges can run offline
22
+ prepare Cache required data for offline use
23
+ bundle Create a portable offline bundle
24
+ verify Verify offline setup is complete
25
+
26
+ Options:
27
+ --output <path> Output path for bundle
28
+ --format json JSON output
29
+ --help, -h Show this help
30
+
31
+ Judges runs entirely locally without network access.
32
+ This command helps verify and document offline capabilities.
33
+ `);
34
+ return;
35
+ }
36
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
37
+ const subcommand = argv.find((a) => ["status", "prepare", "bundle", "verify"].includes(a)) || "status";
38
+ if (subcommand === "prepare") {
39
+ mkdirSync(OFFLINE_DIR, { recursive: true });
40
+ // Snapshot current config if it exists
41
+ const rcPath = ".judgesrc";
42
+ let config = {};
43
+ if (existsSync(rcPath)) {
44
+ try {
45
+ config = JSON.parse(readFileSync(rcPath, "utf-8"));
46
+ }
47
+ catch {
48
+ /* skip */
49
+ }
50
+ }
51
+ const manifest = {
52
+ version: "1.0.0",
53
+ createdAt: new Date().toISOString(),
54
+ includes: ["judges-cli", "all-judges", "config"],
55
+ configSnapshot: config,
56
+ };
57
+ writeFileSync(join(OFFLINE_DIR, "manifest.json"), JSON.stringify(manifest, null, 2), "utf-8");
58
+ console.log("Offline preparation complete. Manifest written to .judges/offline/manifest.json");
59
+ return;
60
+ }
61
+ if (subcommand === "bundle") {
62
+ const output = argv.find((_a, i) => argv[i - 1] === "--output") || join(OFFLINE_DIR, "bundle.json");
63
+ const rcPath = ".judgesrc";
64
+ let config = {};
65
+ if (existsSync(rcPath)) {
66
+ try {
67
+ config = JSON.parse(readFileSync(rcPath, "utf-8"));
68
+ }
69
+ catch {
70
+ /* skip */
71
+ }
72
+ }
73
+ const bundle = {
74
+ version: "1.0.0",
75
+ createdAt: new Date().toISOString(),
76
+ includes: ["judges-cli", "all-judges", "config", "rules"],
77
+ configSnapshot: config,
78
+ };
79
+ mkdirSync(dirname(output), { recursive: true });
80
+ writeFileSync(output, JSON.stringify(bundle, null, 2), "utf-8");
81
+ console.log(`Offline bundle written to ${output}`);
82
+ return;
83
+ }
84
+ if (subcommand === "verify") {
85
+ const manifestPath = join(OFFLINE_DIR, "manifest.json");
86
+ const checks = [
87
+ { name: "CLI installed", ok: true },
88
+ { name: "Judges available", ok: true },
89
+ { name: "Offline manifest", ok: existsSync(manifestPath) },
90
+ { name: "Config present", ok: existsSync(".judgesrc") },
91
+ ];
92
+ if (format === "json") {
93
+ console.log(JSON.stringify({ checks, allPassed: checks.every((c) => c.ok) }, null, 2));
94
+ return;
95
+ }
96
+ console.log("\n Offline Verification\n ─────────────────────────────");
97
+ for (const check of checks) {
98
+ console.log(` ${check.ok ? "✅" : "❌"} ${check.name}`);
99
+ }
100
+ const allOk = checks.every((c) => c.ok);
101
+ console.log(`\n ${allOk ? "✅ Ready for offline use" : "⚠️ Some checks failed — run 'judges review-offline prepare'"}`);
102
+ console.log();
103
+ return;
104
+ }
105
+ // Status
106
+ const capabilities = {
107
+ localExecution: true,
108
+ noNetworkRequired: true,
109
+ allJudgesLocal: true,
110
+ configLocal: existsSync(".judgesrc"),
111
+ offlinePrepared: existsSync(join(OFFLINE_DIR, "manifest.json")),
112
+ };
113
+ if (format === "json") {
114
+ console.log(JSON.stringify(capabilities, null, 2));
115
+ return;
116
+ }
117
+ console.log("\n Offline Mode Status\n ═════════════════════════════");
118
+ console.log(` Local execution: ✅ All analysis runs locally`);
119
+ console.log(` Network required: ❌ No network access needed`);
120
+ console.log(` All judges local: ✅ All ${45}+ judges are bundled`);
121
+ console.log(` Config present: ${capabilities.configLocal ? "✅" : "⚠️ No .judgesrc found"}`);
122
+ console.log(` Offline prepared: ${capabilities.offlinePrepared ? "✅" : "⚠️ Run 'judges review-offline prepare'"}`);
123
+ console.log(`\n Judges is designed for fully offline, air-gapped operation.`);
124
+ console.log(` No data is sent externally — all processing is local.\n`);
125
+ }
126
+ //# sourceMappingURL=review-offline.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"review-offline.js","sourceRoot":"","sources":["../../src/commands/review-offline.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Review-quota — Track review usage quotas locally.
3
+ */
4
+ export declare function runReviewQuota(argv: string[]): void;
5
+ //# sourceMappingURL=review-quota.d.ts.map