@kevinrabun/judges 3.69.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.
- package/CHANGELOG.md +11 -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/finding-impact.d.ts +5 -0
- package/dist/commands/finding-impact.d.ts.map +1 -0
- package/dist/commands/finding-impact.js +136 -0
- package/dist/commands/finding-impact.js.map +1 -0
- package/dist/commands/review-archive.d.ts +5 -0
- package/dist/commands/review-archive.d.ts.map +1 -0
- package/dist/commands/review-archive.js +136 -0
- package/dist/commands/review-archive.js.map +1 -0
- package/dist/commands/review-ci-status.d.ts +5 -0
- package/dist/commands/review-ci-status.d.ts.map +1 -0
- package/dist/commands/review-ci-status.js +201 -0
- package/dist/commands/review-ci-status.js.map +1 -0
- package/dist/commands/review-custom-prompt.d.ts +5 -0
- package/dist/commands/review-custom-prompt.d.ts.map +1 -0
- package/dist/commands/review-custom-prompt.js +171 -0
- package/dist/commands/review-custom-prompt.js.map +1 -0
- package/dist/commands/review-diff-context.d.ts +5 -0
- package/dist/commands/review-diff-context.d.ts.map +1 -0
- package/dist/commands/review-diff-context.js +159 -0
- package/dist/commands/review-diff-context.js.map +1 -0
- package/dist/commands/review-tag.d.ts +5 -0
- package/dist/commands/review-tag.d.ts.map +1 -0
- package/dist/commands/review-tag.js +137 -0
- package/dist/commands/review-tag.js.map +1 -0
- package/dist/commands/review-team-summary.d.ts +5 -0
- package/dist/commands/review-team-summary.d.ts.map +1 -0
- package/dist/commands/review-team-summary.js +156 -0
- package/dist/commands/review-team-summary.js.map +1 -0
- package/dist/commands/review-whitelist.d.ts +5 -0
- package/dist/commands/review-whitelist.d.ts.map +1 -0
- package/dist/commands/review-whitelist.js +159 -0
- package/dist/commands/review-whitelist.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -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 @@
|
|
|
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 @@
|
|
|
1
|
+
{"version":3,"file":"review-ci-status.d.ts","sourceRoot":"","sources":["../../src/commands/review-ci-status.ts"],"names":[],"mappings":"AAAA;;GAEG;AA6JH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA0EtD"}
|
|
@@ -0,0 +1,201 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review-ci-status — Check CI pipeline review status.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
5
|
+
import { join, dirname } from "path";
|
|
6
|
+
import { execSync } from "child_process";
|
|
7
|
+
// ─── Storage ────────────────────────────────────────────────────────────────
|
|
8
|
+
const STATUS_FILE = join(".judges", "ci-status.json");
|
|
9
|
+
function saveReport(report) {
|
|
10
|
+
mkdirSync(dirname(STATUS_FILE), { recursive: true });
|
|
11
|
+
writeFileSync(STATUS_FILE, JSON.stringify(report, null, 2), "utf-8");
|
|
12
|
+
}
|
|
13
|
+
// ─── Git Helpers ────────────────────────────────────────────────────────────
|
|
14
|
+
function getGitInfo() {
|
|
15
|
+
try {
|
|
16
|
+
const branch = execSync("git rev-parse --abbrev-ref HEAD", { encoding: "utf-8" }).trim();
|
|
17
|
+
const commit = execSync("git rev-parse --short HEAD", { encoding: "utf-8" }).trim();
|
|
18
|
+
return { branch, commit };
|
|
19
|
+
}
|
|
20
|
+
catch {
|
|
21
|
+
return { branch: "unknown", commit: "unknown" };
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
function checkUncommittedChanges() {
|
|
25
|
+
try {
|
|
26
|
+
const status = execSync("git status --porcelain", { encoding: "utf-8" }).trim();
|
|
27
|
+
return {
|
|
28
|
+
name: "Uncommitted Changes",
|
|
29
|
+
status: status.length === 0 ? "pass" : "fail",
|
|
30
|
+
detail: status.length === 0 ? "Working tree clean" : `${status.split("\n").length} uncommitted change(s)`,
|
|
31
|
+
timestamp: new Date().toISOString(),
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
catch {
|
|
35
|
+
return {
|
|
36
|
+
name: "Uncommitted Changes",
|
|
37
|
+
status: "unknown",
|
|
38
|
+
detail: "Could not check",
|
|
39
|
+
timestamp: new Date().toISOString(),
|
|
40
|
+
};
|
|
41
|
+
}
|
|
42
|
+
}
|
|
43
|
+
function checkPackageJson() {
|
|
44
|
+
if (!existsSync("package.json")) {
|
|
45
|
+
return {
|
|
46
|
+
name: "package.json",
|
|
47
|
+
status: "unknown",
|
|
48
|
+
detail: "No package.json found",
|
|
49
|
+
timestamp: new Date().toISOString(),
|
|
50
|
+
};
|
|
51
|
+
}
|
|
52
|
+
try {
|
|
53
|
+
const pkg = JSON.parse(readFileSync("package.json", "utf-8"));
|
|
54
|
+
const hasTest = pkg.scripts?.test !== undefined;
|
|
55
|
+
const hasBuild = pkg.scripts?.build !== undefined;
|
|
56
|
+
const hasLint = pkg.scripts?.lint !== undefined;
|
|
57
|
+
const detail = [
|
|
58
|
+
hasTest ? "test ✓" : "test ✗",
|
|
59
|
+
hasBuild ? "build ✓" : "build ✗",
|
|
60
|
+
hasLint ? "lint ✓" : "lint ✗",
|
|
61
|
+
].join(", ");
|
|
62
|
+
return { name: "CI Scripts", status: hasTest ? "pass" : "fail", detail, timestamp: new Date().toISOString() };
|
|
63
|
+
}
|
|
64
|
+
catch {
|
|
65
|
+
return {
|
|
66
|
+
name: "CI Scripts",
|
|
67
|
+
status: "unknown",
|
|
68
|
+
detail: "Could not parse package.json",
|
|
69
|
+
timestamp: new Date().toISOString(),
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
function checkJudgesConfig() {
|
|
74
|
+
const configPaths = [".judgesrc", ".judgesrc.json", "judgesrc.json"];
|
|
75
|
+
const found = configPaths.find(existsSync);
|
|
76
|
+
if (found) {
|
|
77
|
+
return { name: "Judges Config", status: "pass", detail: `Found ${found}`, timestamp: new Date().toISOString() };
|
|
78
|
+
}
|
|
79
|
+
return {
|
|
80
|
+
name: "Judges Config",
|
|
81
|
+
status: "pending",
|
|
82
|
+
detail: "No .judgesrc found (optional)",
|
|
83
|
+
timestamp: new Date().toISOString(),
|
|
84
|
+
};
|
|
85
|
+
}
|
|
86
|
+
function checkGitHooks() {
|
|
87
|
+
const huskyDir = join(".husky");
|
|
88
|
+
if (existsSync(huskyDir)) {
|
|
89
|
+
return { name: "Git Hooks", status: "pass", detail: "Husky hooks configured", timestamp: new Date().toISOString() };
|
|
90
|
+
}
|
|
91
|
+
const gitHooksDir = join(".git", "hooks");
|
|
92
|
+
if (existsSync(gitHooksDir)) {
|
|
93
|
+
return {
|
|
94
|
+
name: "Git Hooks",
|
|
95
|
+
status: "pass",
|
|
96
|
+
detail: "Git hooks directory exists",
|
|
97
|
+
timestamp: new Date().toISOString(),
|
|
98
|
+
};
|
|
99
|
+
}
|
|
100
|
+
return {
|
|
101
|
+
name: "Git Hooks",
|
|
102
|
+
status: "pending",
|
|
103
|
+
detail: "No git hooks configured",
|
|
104
|
+
timestamp: new Date().toISOString(),
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
function checkCIConfig() {
|
|
108
|
+
const ciFiles = [
|
|
109
|
+
".github/workflows",
|
|
110
|
+
".gitlab-ci.yml",
|
|
111
|
+
"Jenkinsfile",
|
|
112
|
+
".circleci/config.yml",
|
|
113
|
+
"azure-pipelines.yml",
|
|
114
|
+
".travis.yml",
|
|
115
|
+
];
|
|
116
|
+
const found = ciFiles.filter(existsSync);
|
|
117
|
+
if (found.length > 0) {
|
|
118
|
+
return {
|
|
119
|
+
name: "CI Configuration",
|
|
120
|
+
status: "pass",
|
|
121
|
+
detail: `Found: ${found.join(", ")}`,
|
|
122
|
+
timestamp: new Date().toISOString(),
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
return {
|
|
126
|
+
name: "CI Configuration",
|
|
127
|
+
status: "fail",
|
|
128
|
+
detail: "No CI configuration found",
|
|
129
|
+
timestamp: new Date().toISOString(),
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
133
|
+
export function runReviewCiStatus(argv) {
|
|
134
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
135
|
+
console.log(`
|
|
136
|
+
judges review-ci-status — Check CI pipeline review status
|
|
137
|
+
|
|
138
|
+
Usage:
|
|
139
|
+
judges review-ci-status
|
|
140
|
+
judges review-ci-status --format json
|
|
141
|
+
|
|
142
|
+
Options:
|
|
143
|
+
--format json JSON output
|
|
144
|
+
--help, -h Show this help
|
|
145
|
+
|
|
146
|
+
Checks:
|
|
147
|
+
• Uncommitted changes
|
|
148
|
+
• CI scripts (test, build, lint)
|
|
149
|
+
• Judges configuration
|
|
150
|
+
• Git hooks
|
|
151
|
+
• CI configuration files
|
|
152
|
+
|
|
153
|
+
Report saved to .judges/ci-status.json.
|
|
154
|
+
`);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
158
|
+
const { branch, commit } = getGitInfo();
|
|
159
|
+
const checks = [
|
|
160
|
+
checkUncommittedChanges(),
|
|
161
|
+
checkPackageJson(),
|
|
162
|
+
checkJudgesConfig(),
|
|
163
|
+
checkGitHooks(),
|
|
164
|
+
checkCIConfig(),
|
|
165
|
+
];
|
|
166
|
+
const hasFail = checks.some((c) => c.status === "fail");
|
|
167
|
+
const hasPending = checks.some((c) => c.status === "pending");
|
|
168
|
+
const overall = hasFail ? "fail" : hasPending ? "pending" : "pass";
|
|
169
|
+
const report = {
|
|
170
|
+
branch,
|
|
171
|
+
commit,
|
|
172
|
+
timestamp: new Date().toISOString(),
|
|
173
|
+
checks,
|
|
174
|
+
overall,
|
|
175
|
+
};
|
|
176
|
+
saveReport(report);
|
|
177
|
+
if (format === "json") {
|
|
178
|
+
console.log(JSON.stringify(report, null, 2));
|
|
179
|
+
return;
|
|
180
|
+
}
|
|
181
|
+
const statusIcon = (s) => {
|
|
182
|
+
if (s === "pass")
|
|
183
|
+
return "✓";
|
|
184
|
+
if (s === "fail")
|
|
185
|
+
return "✗";
|
|
186
|
+
if (s === "pending")
|
|
187
|
+
return "○";
|
|
188
|
+
return "?";
|
|
189
|
+
};
|
|
190
|
+
console.log("\nCI Status Report:");
|
|
191
|
+
console.log("═".repeat(60));
|
|
192
|
+
console.log(` Branch: ${branch} Commit: ${commit}`);
|
|
193
|
+
console.log(` Overall: ${overall.toUpperCase()} ${statusIcon(overall)}`);
|
|
194
|
+
console.log("═".repeat(60));
|
|
195
|
+
for (const c of checks) {
|
|
196
|
+
console.log(` ${statusIcon(c.status)} ${c.name.padEnd(25)} ${c.detail}`);
|
|
197
|
+
}
|
|
198
|
+
console.log("═".repeat(60));
|
|
199
|
+
console.log(` Report saved to ${STATUS_FILE}`);
|
|
200
|
+
}
|
|
201
|
+
//# sourceMappingURL=review-ci-status.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-ci-status.js","sourceRoot":"","sources":["../../src/commands/review-ci-status.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-custom-prompt.d.ts","sourceRoot":"","sources":["../../src/commands/review-custom-prompt.ts"],"names":[],"mappings":"AAAA;;GAEG;AAwDH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAqJ1D"}
|