@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.
- package/CHANGELOG.md +8 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +56 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/config-lint.d.ts +5 -0
- package/dist/commands/config-lint.d.ts.map +1 -0
- package/dist/commands/config-lint.js +188 -0
- package/dist/commands/config-lint.js.map +1 -0
- package/dist/commands/finding-age.d.ts +5 -0
- package/dist/commands/finding-age.d.ts.map +1 -0
- package/dist/commands/finding-age.js +146 -0
- package/dist/commands/finding-age.js.map +1 -0
- package/dist/commands/finding-rank.d.ts +5 -0
- package/dist/commands/finding-rank.d.ts.map +1 -0
- package/dist/commands/finding-rank.js +139 -0
- package/dist/commands/finding-rank.js.map +1 -0
- package/dist/commands/review-dashboard.d.ts +5 -0
- package/dist/commands/review-dashboard.d.ts.map +1 -0
- package/dist/commands/review-dashboard.js +141 -0
- package/dist/commands/review-dashboard.js.map +1 -0
- package/dist/commands/review-diff-summary.d.ts +5 -0
- package/dist/commands/review-diff-summary.d.ts.map +1 -0
- package/dist/commands/review-diff-summary.js +155 -0
- package/dist/commands/review-diff-summary.js.map +1 -0
- package/dist/commands/review-notify.d.ts +5 -0
- package/dist/commands/review-notify.d.ts.map +1 -0
- package/dist/commands/review-notify.js +144 -0
- package/dist/commands/review-notify.js.map +1 -0
- package/dist/commands/review-offline.d.ts +5 -0
- package/dist/commands/review-offline.d.ts.map +1 -0
- package/dist/commands/review-offline.js +126 -0
- package/dist/commands/review-offline.js.map +1 -0
- package/dist/commands/review-quota.d.ts +5 -0
- package/dist/commands/review-quota.d.ts.map +1 -0
- package/dist/commands/review-quota.js +127 -0
- package/dist/commands/review-quota.js.map +1 -0
- package/package.json +1 -1
- 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 @@
|
|
|
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 @@
|
|
|
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 @@
|
|
|
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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"}
|