@kevinrabun/judges 3.70.0 → 3.72.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 +24 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +112 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/finding-auto-fix.d.ts +5 -0
- package/dist/commands/finding-auto-fix.d.ts.map +1 -0
- package/dist/commands/finding-auto-fix.js +189 -0
- package/dist/commands/finding-auto-fix.js.map +1 -0
- package/dist/commands/finding-context.d.ts +5 -0
- package/dist/commands/finding-context.d.ts.map +1 -0
- package/dist/commands/finding-context.js +141 -0
- package/dist/commands/finding-context.js.map +1 -0
- package/dist/commands/finding-deduplicate.d.ts +5 -0
- package/dist/commands/finding-deduplicate.d.ts.map +1 -0
- package/dist/commands/finding-deduplicate.js +142 -0
- package/dist/commands/finding-deduplicate.js.map +1 -0
- package/dist/commands/finding-severity-override.d.ts +5 -0
- package/dist/commands/finding-severity-override.d.ts.map +1 -0
- package/dist/commands/finding-severity-override.js +132 -0
- package/dist/commands/finding-severity-override.js.map +1 -0
- package/dist/commands/review-approval.d.ts +5 -0
- package/dist/commands/review-approval.d.ts.map +1 -0
- package/dist/commands/review-approval.js +134 -0
- package/dist/commands/review-approval.js.map +1 -0
- package/dist/commands/review-config-export.d.ts +5 -0
- package/dist/commands/review-config-export.d.ts.map +1 -0
- package/dist/commands/review-config-export.js +125 -0
- package/dist/commands/review-config-export.js.map +1 -0
- package/dist/commands/review-coverage-map.d.ts +5 -0
- package/dist/commands/review-coverage-map.d.ts.map +1 -0
- package/dist/commands/review-coverage-map.js +195 -0
- package/dist/commands/review-coverage-map.js.map +1 -0
- package/dist/commands/review-feedback.d.ts +5 -0
- package/dist/commands/review-feedback.d.ts.map +1 -0
- package/dist/commands/review-feedback.js +146 -0
- package/dist/commands/review-feedback.js.map +1 -0
- package/dist/commands/review-history-search.d.ts +5 -0
- package/dist/commands/review-history-search.d.ts.map +1 -0
- package/dist/commands/review-history-search.js +215 -0
- package/dist/commands/review-history-search.js.map +1 -0
- package/dist/commands/review-ignore-path.d.ts +5 -0
- package/dist/commands/review-ignore-path.d.ts.map +1 -0
- package/dist/commands/review-ignore-path.js +148 -0
- package/dist/commands/review-ignore-path.js.map +1 -0
- package/dist/commands/review-language-stats.d.ts +5 -0
- package/dist/commands/review-language-stats.d.ts.map +1 -0
- package/dist/commands/review-language-stats.js +153 -0
- package/dist/commands/review-language-stats.js.map +1 -0
- package/dist/commands/review-onboard.d.ts +5 -0
- package/dist/commands/review-onboard.d.ts.map +1 -0
- package/dist/commands/review-onboard.js +155 -0
- package/dist/commands/review-onboard.js.map +1 -0
- package/dist/commands/review-parallel.d.ts +5 -0
- package/dist/commands/review-parallel.d.ts.map +1 -0
- package/dist/commands/review-parallel.js +183 -0
- package/dist/commands/review-parallel.js.map +1 -0
- package/dist/commands/review-pr-comment.d.ts +5 -0
- package/dist/commands/review-pr-comment.d.ts.map +1 -0
- package/dist/commands/review-pr-comment.js +107 -0
- package/dist/commands/review-pr-comment.js.map +1 -0
- package/dist/commands/review-rollback.d.ts +5 -0
- package/dist/commands/review-rollback.d.ts.map +1 -0
- package/dist/commands/review-rollback.js +172 -0
- package/dist/commands/review-rollback.js.map +1 -0
- package/dist/commands/review-score-history.d.ts +5 -0
- package/dist/commands/review-score-history.d.ts.map +1 -0
- package/dist/commands/review-score-history.js +138 -0
- package/dist/commands/review-score-history.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,132 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Finding-severity-override — Override finding severity per project.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
5
|
+
import { join, dirname } from "path";
|
|
6
|
+
// ─── Storage ────────────────────────────────────────────────────────────────
|
|
7
|
+
const OVERRIDE_FILE = join(".judges", "severity-overrides.json");
|
|
8
|
+
function loadStore() {
|
|
9
|
+
if (!existsSync(OVERRIDE_FILE))
|
|
10
|
+
return { version: "1.0.0", overrides: [] };
|
|
11
|
+
try {
|
|
12
|
+
return JSON.parse(readFileSync(OVERRIDE_FILE, "utf-8"));
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return { version: "1.0.0", overrides: [] };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function saveStore(store) {
|
|
19
|
+
mkdirSync(dirname(OVERRIDE_FILE), { recursive: true });
|
|
20
|
+
writeFileSync(OVERRIDE_FILE, JSON.stringify(store, null, 2), "utf-8");
|
|
21
|
+
}
|
|
22
|
+
const VALID_SEVERITIES = ["critical", "high", "medium", "low", "info"];
|
|
23
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
24
|
+
export function runFindingSeverityOverride(argv) {
|
|
25
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
26
|
+
console.log(`
|
|
27
|
+
judges finding-severity-override — Override finding severity per project
|
|
28
|
+
|
|
29
|
+
Usage:
|
|
30
|
+
judges finding-severity-override set --rule sql-injection --severity low --reason "Internal tool only"
|
|
31
|
+
judges finding-severity-override list
|
|
32
|
+
judges finding-severity-override remove --rule sql-injection
|
|
33
|
+
judges finding-severity-override clear
|
|
34
|
+
|
|
35
|
+
Subcommands:
|
|
36
|
+
set Set a severity override
|
|
37
|
+
list List all overrides
|
|
38
|
+
remove Remove an override
|
|
39
|
+
clear Clear all overrides
|
|
40
|
+
|
|
41
|
+
Options:
|
|
42
|
+
--rule <ruleId> Rule ID to override
|
|
43
|
+
--severity <level> New severity (critical|high|medium|low|info)
|
|
44
|
+
--reason <text> Reason for the override
|
|
45
|
+
--format json JSON output
|
|
46
|
+
--help, -h Show this help
|
|
47
|
+
|
|
48
|
+
Override data stored in .judges/severity-overrides.json.
|
|
49
|
+
`);
|
|
50
|
+
return;
|
|
51
|
+
}
|
|
52
|
+
const subcommand = argv.find((a) => ["set", "list", "remove", "clear"].includes(a)) || "list";
|
|
53
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
54
|
+
const store = loadStore();
|
|
55
|
+
if (subcommand === "set") {
|
|
56
|
+
const ruleId = argv.find((_a, i) => argv[i - 1] === "--rule") || "";
|
|
57
|
+
const severity = argv.find((_a, i) => argv[i - 1] === "--severity") || "";
|
|
58
|
+
const reason = argv.find((_a, i) => argv[i - 1] === "--reason") || "";
|
|
59
|
+
if (!ruleId || !severity) {
|
|
60
|
+
console.error("Error: --rule and --severity are required.");
|
|
61
|
+
process.exitCode = 1;
|
|
62
|
+
return;
|
|
63
|
+
}
|
|
64
|
+
if (!VALID_SEVERITIES.includes(severity)) {
|
|
65
|
+
console.error(`Error: Invalid severity. Use: ${VALID_SEVERITIES.join(", ")}`);
|
|
66
|
+
process.exitCode = 1;
|
|
67
|
+
return;
|
|
68
|
+
}
|
|
69
|
+
// Replace existing or add
|
|
70
|
+
const existing = store.overrides.findIndex((o) => o.ruleId === ruleId);
|
|
71
|
+
const entry = {
|
|
72
|
+
ruleId,
|
|
73
|
+
originalSeverity: "",
|
|
74
|
+
overrideSeverity: severity,
|
|
75
|
+
reason,
|
|
76
|
+
addedAt: new Date().toISOString(),
|
|
77
|
+
};
|
|
78
|
+
if (existing >= 0) {
|
|
79
|
+
entry.originalSeverity = store.overrides[existing].originalSeverity;
|
|
80
|
+
store.overrides[existing] = entry;
|
|
81
|
+
console.log(`Updated severity override for "${ruleId}" to ${severity}.`);
|
|
82
|
+
}
|
|
83
|
+
else {
|
|
84
|
+
store.overrides.push(entry);
|
|
85
|
+
console.log(`Set severity override for "${ruleId}" to ${severity}.`);
|
|
86
|
+
}
|
|
87
|
+
saveStore(store);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (subcommand === "remove") {
|
|
91
|
+
const ruleId = argv.find((_a, i) => argv[i - 1] === "--rule") || "";
|
|
92
|
+
if (!ruleId) {
|
|
93
|
+
console.error("Error: --rule is required.");
|
|
94
|
+
process.exitCode = 1;
|
|
95
|
+
return;
|
|
96
|
+
}
|
|
97
|
+
const before = store.overrides.length;
|
|
98
|
+
store.overrides = store.overrides.filter((o) => o.ruleId !== ruleId);
|
|
99
|
+
if (store.overrides.length === before) {
|
|
100
|
+
console.error(`Error: No override found for "${ruleId}".`);
|
|
101
|
+
process.exitCode = 1;
|
|
102
|
+
return;
|
|
103
|
+
}
|
|
104
|
+
saveStore(store);
|
|
105
|
+
console.log(`Removed severity override for "${ruleId}".`);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
if (subcommand === "clear") {
|
|
109
|
+
saveStore({ version: "1.0.0", overrides: [] });
|
|
110
|
+
console.log("Severity overrides cleared.");
|
|
111
|
+
return;
|
|
112
|
+
}
|
|
113
|
+
// list
|
|
114
|
+
if (store.overrides.length === 0) {
|
|
115
|
+
console.log("No severity overrides. Use 'judges finding-severity-override set' to add one.");
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
if (format === "json") {
|
|
119
|
+
console.log(JSON.stringify(store.overrides, null, 2));
|
|
120
|
+
return;
|
|
121
|
+
}
|
|
122
|
+
console.log("\nSeverity Overrides:");
|
|
123
|
+
console.log("─".repeat(70));
|
|
124
|
+
for (const o of store.overrides) {
|
|
125
|
+
console.log(` ${o.ruleId.padEnd(30)} → ${o.overrideSeverity.padEnd(10)} ${o.addedAt.slice(0, 10)}`);
|
|
126
|
+
if (o.reason)
|
|
127
|
+
console.log(` Reason: ${o.reason}`);
|
|
128
|
+
}
|
|
129
|
+
console.log("─".repeat(70));
|
|
130
|
+
console.log(` Total: ${store.overrides.length} override(s)`);
|
|
131
|
+
}
|
|
132
|
+
//# sourceMappingURL=finding-severity-override.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"finding-severity-override.js","sourceRoot":"","sources":["../../src/commands/finding-severity-override.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-approval.d.ts","sourceRoot":"","sources":["../../src/commands/review-approval.ts"],"names":[],"mappings":"AAAA;;GAEG;AA8CH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAmHtD"}
|
|
@@ -0,0 +1,134 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review-approval — Approval workflows for review results.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
5
|
+
import { join, dirname } from "path";
|
|
6
|
+
// ─── Storage ────────────────────────────────────────────────────────────────
|
|
7
|
+
const APPROVAL_FILE = join(".judges", "approvals.json");
|
|
8
|
+
function loadStore() {
|
|
9
|
+
if (!existsSync(APPROVAL_FILE))
|
|
10
|
+
return { version: "1.0.0", entries: [] };
|
|
11
|
+
try {
|
|
12
|
+
return JSON.parse(readFileSync(APPROVAL_FILE, "utf-8"));
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return { version: "1.0.0", entries: [] };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function saveStore(store) {
|
|
19
|
+
mkdirSync(dirname(APPROVAL_FILE), { recursive: true });
|
|
20
|
+
writeFileSync(APPROVAL_FILE, JSON.stringify(store, null, 2), "utf-8");
|
|
21
|
+
}
|
|
22
|
+
function generateId() {
|
|
23
|
+
return `apr-${Date.now().toString(36)}`;
|
|
24
|
+
}
|
|
25
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
26
|
+
export function runReviewApproval(argv) {
|
|
27
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
28
|
+
console.log(`
|
|
29
|
+
judges review-approval — Approval workflows for review results
|
|
30
|
+
|
|
31
|
+
Usage:
|
|
32
|
+
judges review-approval request --review rev-123 --approver alice
|
|
33
|
+
judges review-approval approve --id apr-abc --comment "Looks good"
|
|
34
|
+
judges review-approval reject --id apr-abc --comment "Needs fixes"
|
|
35
|
+
judges review-approval list
|
|
36
|
+
judges review-approval clear
|
|
37
|
+
|
|
38
|
+
Subcommands:
|
|
39
|
+
request Request approval for a review
|
|
40
|
+
approve Approve a pending request
|
|
41
|
+
reject Reject a pending request
|
|
42
|
+
list List all approval entries
|
|
43
|
+
clear Clear all approval data
|
|
44
|
+
|
|
45
|
+
Options:
|
|
46
|
+
--review <id> Review ID
|
|
47
|
+
--approver <name> Approver name
|
|
48
|
+
--id <id> Approval entry ID
|
|
49
|
+
--comment <text> Approval/rejection comment
|
|
50
|
+
--score <n> Review score
|
|
51
|
+
--format json JSON output
|
|
52
|
+
--help, -h Show this help
|
|
53
|
+
|
|
54
|
+
Approval data stored locally in .judges/approvals.json.
|
|
55
|
+
`);
|
|
56
|
+
return;
|
|
57
|
+
}
|
|
58
|
+
const subcommand = argv.find((a) => ["request", "approve", "reject", "list", "clear"].includes(a)) || "list";
|
|
59
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
60
|
+
const store = loadStore();
|
|
61
|
+
if (subcommand === "request") {
|
|
62
|
+
const reviewId = argv.find((_a, i) => argv[i - 1] === "--review") || "";
|
|
63
|
+
const approver = argv.find((_a, i) => argv[i - 1] === "--approver") || "";
|
|
64
|
+
const score = parseFloat(argv.find((_a, i) => argv[i - 1] === "--score") || "0");
|
|
65
|
+
if (!reviewId || !approver) {
|
|
66
|
+
console.error("Error: --review and --approver are required.");
|
|
67
|
+
process.exitCode = 1;
|
|
68
|
+
return;
|
|
69
|
+
}
|
|
70
|
+
const id = generateId();
|
|
71
|
+
store.entries.push({
|
|
72
|
+
id,
|
|
73
|
+
reviewId,
|
|
74
|
+
approver,
|
|
75
|
+
status: "pending",
|
|
76
|
+
comment: "",
|
|
77
|
+
timestamp: new Date().toISOString(),
|
|
78
|
+
score,
|
|
79
|
+
});
|
|
80
|
+
saveStore(store);
|
|
81
|
+
console.log(`Approval request ${id} created for review ${reviewId} (approver: ${approver}).`);
|
|
82
|
+
return;
|
|
83
|
+
}
|
|
84
|
+
if (subcommand === "approve" || subcommand === "reject") {
|
|
85
|
+
const id = argv.find((_a, i) => argv[i - 1] === "--id");
|
|
86
|
+
const comment = argv.find((_a, i) => argv[i - 1] === "--comment") || "";
|
|
87
|
+
if (!id) {
|
|
88
|
+
console.error("Error: --id is required.");
|
|
89
|
+
process.exitCode = 1;
|
|
90
|
+
return;
|
|
91
|
+
}
|
|
92
|
+
const entry = store.entries.find((e) => e.id === id);
|
|
93
|
+
if (!entry) {
|
|
94
|
+
console.error(`Error: Approval "${id}" not found.`);
|
|
95
|
+
process.exitCode = 1;
|
|
96
|
+
return;
|
|
97
|
+
}
|
|
98
|
+
entry.status = subcommand === "approve" ? "approved" : "rejected";
|
|
99
|
+
entry.comment = comment;
|
|
100
|
+
entry.timestamp = new Date().toISOString();
|
|
101
|
+
saveStore(store);
|
|
102
|
+
console.log(`${subcommand === "approve" ? "Approved" : "Rejected"} ${id}.`);
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
if (subcommand === "clear") {
|
|
106
|
+
saveStore({ version: "1.0.0", entries: [] });
|
|
107
|
+
console.log("Approval data cleared.");
|
|
108
|
+
return;
|
|
109
|
+
}
|
|
110
|
+
// list
|
|
111
|
+
if (store.entries.length === 0) {
|
|
112
|
+
console.log("No approval entries. Use 'judges review-approval request' to start.");
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
if (format === "json") {
|
|
116
|
+
console.log(JSON.stringify(store.entries, null, 2));
|
|
117
|
+
return;
|
|
118
|
+
}
|
|
119
|
+
const pending = store.entries.filter((e) => e.status === "pending");
|
|
120
|
+
const approved = store.entries.filter((e) => e.status === "approved");
|
|
121
|
+
const rejected = store.entries.filter((e) => e.status === "rejected");
|
|
122
|
+
console.log("\nApproval Dashboard:");
|
|
123
|
+
console.log("═".repeat(60));
|
|
124
|
+
console.log(` Pending: ${pending.length} Approved: ${approved.length} Rejected: ${rejected.length}`);
|
|
125
|
+
console.log("═".repeat(60));
|
|
126
|
+
for (const e of store.entries) {
|
|
127
|
+
const icon = e.status === "approved" ? "✓" : e.status === "rejected" ? "✗" : "○";
|
|
128
|
+
console.log(` ${icon} ${e.id} review=${e.reviewId} approver=${e.approver} ${e.status}`);
|
|
129
|
+
if (e.comment)
|
|
130
|
+
console.log(` Comment: ${e.comment}`);
|
|
131
|
+
}
|
|
132
|
+
console.log("═".repeat(60));
|
|
133
|
+
}
|
|
134
|
+
//# sourceMappingURL=review-approval.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-approval.js","sourceRoot":"","sources":["../../src/commands/review-approval.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-config-export.d.ts","sourceRoot":"","sources":["../../src/commands/review-config-export.ts"],"names":[],"mappings":"AAAA;;GAEG;AA4BH,wBAAgB,qBAAqB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAsH1D"}
|
|
@@ -0,0 +1,125 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review-config-export — Export and import review configurations.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
5
|
+
import { dirname } from "path";
|
|
6
|
+
// ─── Config Discovery ───────────────────────────────────────────────────────
|
|
7
|
+
const CONFIG_FILES = [".judgesrc", ".judgesrc.json", "judgesrc.json"];
|
|
8
|
+
function findConfigFile() {
|
|
9
|
+
for (const f of CONFIG_FILES) {
|
|
10
|
+
if (existsSync(f))
|
|
11
|
+
return f;
|
|
12
|
+
}
|
|
13
|
+
return null;
|
|
14
|
+
}
|
|
15
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
16
|
+
export function runReviewConfigExport(argv) {
|
|
17
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
18
|
+
console.log(`
|
|
19
|
+
judges review-config-export — Export and import review configurations
|
|
20
|
+
|
|
21
|
+
Usage:
|
|
22
|
+
judges review-config-export export --out config-bundle.json
|
|
23
|
+
judges review-config-export import --file config-bundle.json
|
|
24
|
+
judges review-config-export show
|
|
25
|
+
|
|
26
|
+
Subcommands:
|
|
27
|
+
export Export current config as a shareable bundle
|
|
28
|
+
import Import a config bundle
|
|
29
|
+
show Show current config
|
|
30
|
+
|
|
31
|
+
Options:
|
|
32
|
+
--out <path> Output path for export
|
|
33
|
+
--file <path> Config bundle to import
|
|
34
|
+
--config <path> Config file path (auto-detected)
|
|
35
|
+
--name <text> Bundle name
|
|
36
|
+
--desc <text> Bundle description
|
|
37
|
+
--format json JSON output
|
|
38
|
+
--help, -h Show this help
|
|
39
|
+
|
|
40
|
+
Enables sharing review configurations between projects and team members.
|
|
41
|
+
`);
|
|
42
|
+
return;
|
|
43
|
+
}
|
|
44
|
+
const subcommand = argv.find((a) => ["export", "import", "show"].includes(a)) || "show";
|
|
45
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
46
|
+
if (subcommand === "export") {
|
|
47
|
+
const configArg = argv.find((_a, i) => argv[i - 1] === "--config");
|
|
48
|
+
const configFile = configArg || findConfigFile();
|
|
49
|
+
const outPath = argv.find((_a, i) => argv[i - 1] === "--out") || "judges-config-bundle.json";
|
|
50
|
+
const name = argv.find((_a, i) => argv[i - 1] === "--name") || "Judges Config";
|
|
51
|
+
const desc = argv.find((_a, i) => argv[i - 1] === "--desc") || "";
|
|
52
|
+
if (!configFile || !existsSync(configFile)) {
|
|
53
|
+
console.error("Error: No config file found. Use --config to specify.");
|
|
54
|
+
process.exitCode = 1;
|
|
55
|
+
return;
|
|
56
|
+
}
|
|
57
|
+
let config;
|
|
58
|
+
try {
|
|
59
|
+
config = JSON.parse(readFileSync(configFile, "utf-8"));
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
console.error("Error: Could not parse config file.");
|
|
63
|
+
process.exitCode = 1;
|
|
64
|
+
return;
|
|
65
|
+
}
|
|
66
|
+
const bundle = {
|
|
67
|
+
version: "1.0.0",
|
|
68
|
+
exportedAt: new Date().toISOString(),
|
|
69
|
+
source: configFile,
|
|
70
|
+
config,
|
|
71
|
+
metadata: { name, description: desc },
|
|
72
|
+
};
|
|
73
|
+
mkdirSync(dirname(outPath), { recursive: true });
|
|
74
|
+
writeFileSync(outPath, JSON.stringify(bundle, null, 2), "utf-8");
|
|
75
|
+
console.log(`Exported config to "${outPath}".`);
|
|
76
|
+
return;
|
|
77
|
+
}
|
|
78
|
+
if (subcommand === "import") {
|
|
79
|
+
const filePath = argv.find((_a, i) => argv[i - 1] === "--file");
|
|
80
|
+
if (!filePath || !existsSync(filePath)) {
|
|
81
|
+
console.error("Error: --file is required and must exist.");
|
|
82
|
+
process.exitCode = 1;
|
|
83
|
+
return;
|
|
84
|
+
}
|
|
85
|
+
let bundle;
|
|
86
|
+
try {
|
|
87
|
+
bundle = JSON.parse(readFileSync(filePath, "utf-8"));
|
|
88
|
+
}
|
|
89
|
+
catch {
|
|
90
|
+
console.error("Error: Could not parse config bundle.");
|
|
91
|
+
process.exitCode = 1;
|
|
92
|
+
return;
|
|
93
|
+
}
|
|
94
|
+
if (!bundle.config) {
|
|
95
|
+
console.error("Error: Invalid config bundle (missing 'config' field).");
|
|
96
|
+
process.exitCode = 1;
|
|
97
|
+
return;
|
|
98
|
+
}
|
|
99
|
+
const targetFile = findConfigFile() || ".judgesrc.json";
|
|
100
|
+
mkdirSync(dirname(targetFile), { recursive: true });
|
|
101
|
+
writeFileSync(targetFile, JSON.stringify(bundle.config, null, 2), "utf-8");
|
|
102
|
+
console.log(`Imported config from "${filePath}" to "${targetFile}".`);
|
|
103
|
+
if (bundle.metadata.name)
|
|
104
|
+
console.log(` Bundle: ${bundle.metadata.name}`);
|
|
105
|
+
if (bundle.metadata.description)
|
|
106
|
+
console.log(` Description: ${bundle.metadata.description}`);
|
|
107
|
+
return;
|
|
108
|
+
}
|
|
109
|
+
// show
|
|
110
|
+
const configFile = findConfigFile();
|
|
111
|
+
if (!configFile || !existsSync(configFile)) {
|
|
112
|
+
console.log("No config file found.");
|
|
113
|
+
return;
|
|
114
|
+
}
|
|
115
|
+
const content = readFileSync(configFile, "utf-8");
|
|
116
|
+
if (format === "json") {
|
|
117
|
+
console.log(content);
|
|
118
|
+
return;
|
|
119
|
+
}
|
|
120
|
+
console.log(`\nCurrent Config (${configFile}):`);
|
|
121
|
+
console.log("─".repeat(50));
|
|
122
|
+
console.log(content);
|
|
123
|
+
console.log("─".repeat(50));
|
|
124
|
+
}
|
|
125
|
+
//# sourceMappingURL=review-config-export.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-config-export.js","sourceRoot":"","sources":["../../src/commands/review-config-export.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"review-coverage-map.d.ts","sourceRoot":"","sources":["../../src/commands/review-coverage-map.ts"],"names":[],"mappings":"AAAA;;GAEG;AAqGH,wBAAgB,oBAAoB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAkIzD"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Review-coverage-map — Map which files have been reviewed.
|
|
3
|
+
*/
|
|
4
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync } from "fs";
|
|
5
|
+
import { join, dirname, extname } from "path";
|
|
6
|
+
// ─── Storage ────────────────────────────────────────────────────────────────
|
|
7
|
+
const COVERAGE_FILE = join(".judges", "coverage-map.json");
|
|
8
|
+
function loadCoverage() {
|
|
9
|
+
if (!existsSync(COVERAGE_FILE))
|
|
10
|
+
return { version: "1.0.0", reviewed: {} };
|
|
11
|
+
try {
|
|
12
|
+
return JSON.parse(readFileSync(COVERAGE_FILE, "utf-8"));
|
|
13
|
+
}
|
|
14
|
+
catch {
|
|
15
|
+
return { version: "1.0.0", reviewed: {} };
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
function saveCoverage(store) {
|
|
19
|
+
mkdirSync(dirname(COVERAGE_FILE), { recursive: true });
|
|
20
|
+
writeFileSync(COVERAGE_FILE, JSON.stringify(store, null, 2), "utf-8");
|
|
21
|
+
}
|
|
22
|
+
// ─── File Discovery ─────────────────────────────────────────────────────────
|
|
23
|
+
const SOURCE_EXTS = new Set([
|
|
24
|
+
".ts",
|
|
25
|
+
".tsx",
|
|
26
|
+
".js",
|
|
27
|
+
".jsx",
|
|
28
|
+
".py",
|
|
29
|
+
".java",
|
|
30
|
+
".cs",
|
|
31
|
+
".go",
|
|
32
|
+
".rs",
|
|
33
|
+
".rb",
|
|
34
|
+
".php",
|
|
35
|
+
".cpp",
|
|
36
|
+
".c",
|
|
37
|
+
".h",
|
|
38
|
+
".swift",
|
|
39
|
+
".kt",
|
|
40
|
+
".scala",
|
|
41
|
+
".vue",
|
|
42
|
+
".svelte",
|
|
43
|
+
]);
|
|
44
|
+
function discoverFiles(dir, files) {
|
|
45
|
+
try {
|
|
46
|
+
const entries = readdirSync(dir);
|
|
47
|
+
for (const entry of entries) {
|
|
48
|
+
const name = entry;
|
|
49
|
+
if (name.startsWith(".") || name === "node_modules" || name === "dist" || name === "build")
|
|
50
|
+
continue;
|
|
51
|
+
const full = join(dir, name);
|
|
52
|
+
const ext = extname(name);
|
|
53
|
+
if (SOURCE_EXTS.has(ext)) {
|
|
54
|
+
files.push(full);
|
|
55
|
+
}
|
|
56
|
+
else if (!ext) {
|
|
57
|
+
// Might be a directory
|
|
58
|
+
try {
|
|
59
|
+
discoverFiles(full, files);
|
|
60
|
+
}
|
|
61
|
+
catch {
|
|
62
|
+
// Skip
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
else {
|
|
66
|
+
try {
|
|
67
|
+
discoverFiles(full, files);
|
|
68
|
+
}
|
|
69
|
+
catch {
|
|
70
|
+
// Skip
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
}
|
|
75
|
+
catch {
|
|
76
|
+
// Skip
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
80
|
+
export function runReviewCoverageMap(argv) {
|
|
81
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
82
|
+
console.log(`
|
|
83
|
+
judges review-coverage-map — Map which files have been reviewed
|
|
84
|
+
|
|
85
|
+
Usage:
|
|
86
|
+
judges review-coverage-map Show coverage map
|
|
87
|
+
judges review-coverage-map mark --file src/api.ts Mark a file as reviewed
|
|
88
|
+
judges review-coverage-map unmark --file src/api.ts
|
|
89
|
+
judges review-coverage-map clear
|
|
90
|
+
|
|
91
|
+
Subcommands:
|
|
92
|
+
(default) Show coverage map
|
|
93
|
+
mark Mark a file as reviewed
|
|
94
|
+
unmark Remove reviewed status
|
|
95
|
+
clear Clear coverage data
|
|
96
|
+
|
|
97
|
+
Options:
|
|
98
|
+
--dir <path> Directory to scan (default: current directory)
|
|
99
|
+
--file <path> File to mark/unmark
|
|
100
|
+
--unreviewed Show only unreviewed files
|
|
101
|
+
--format json JSON output
|
|
102
|
+
--help, -h Show this help
|
|
103
|
+
|
|
104
|
+
Coverage data stored in .judges/coverage-map.json.
|
|
105
|
+
`);
|
|
106
|
+
return;
|
|
107
|
+
}
|
|
108
|
+
const subcommand = argv.find((a) => ["mark", "unmark", "clear"].includes(a));
|
|
109
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
110
|
+
const store = loadCoverage();
|
|
111
|
+
if (subcommand === "mark") {
|
|
112
|
+
const filePath = argv.find((_a, i) => argv[i - 1] === "--file");
|
|
113
|
+
if (!filePath) {
|
|
114
|
+
console.error("Error: --file is required.");
|
|
115
|
+
process.exitCode = 1;
|
|
116
|
+
return;
|
|
117
|
+
}
|
|
118
|
+
const existing = store.reviewed[filePath] || { lastDate: "", count: 0 };
|
|
119
|
+
existing.lastDate = new Date().toISOString();
|
|
120
|
+
existing.count++;
|
|
121
|
+
store.reviewed[filePath] = existing;
|
|
122
|
+
saveCoverage(store);
|
|
123
|
+
console.log(`Marked "${filePath}" as reviewed (review #${existing.count}).`);
|
|
124
|
+
return;
|
|
125
|
+
}
|
|
126
|
+
if (subcommand === "unmark") {
|
|
127
|
+
const filePath = argv.find((_a, i) => argv[i - 1] === "--file");
|
|
128
|
+
if (!filePath) {
|
|
129
|
+
console.error("Error: --file is required.");
|
|
130
|
+
process.exitCode = 1;
|
|
131
|
+
return;
|
|
132
|
+
}
|
|
133
|
+
delete store.reviewed[filePath];
|
|
134
|
+
saveCoverage(store);
|
|
135
|
+
console.log(`Unmarked "${filePath}".`);
|
|
136
|
+
return;
|
|
137
|
+
}
|
|
138
|
+
if (subcommand === "clear") {
|
|
139
|
+
saveCoverage({ version: "1.0.0", reviewed: {} });
|
|
140
|
+
console.log("Coverage data cleared.");
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
// Default: show coverage map
|
|
144
|
+
const dir = argv.find((_a, i) => argv[i - 1] === "--dir") || ".";
|
|
145
|
+
const unreviewedOnly = argv.includes("--unreviewed");
|
|
146
|
+
const files = [];
|
|
147
|
+
discoverFiles(dir, files);
|
|
148
|
+
if (files.length === 0) {
|
|
149
|
+
console.log("No source files found.");
|
|
150
|
+
return;
|
|
151
|
+
}
|
|
152
|
+
const fileStatuses = files.map((f) => {
|
|
153
|
+
const reviewInfo = store.reviewed[f];
|
|
154
|
+
return {
|
|
155
|
+
file: f,
|
|
156
|
+
reviewed: !!reviewInfo,
|
|
157
|
+
lastReviewDate: reviewInfo?.lastDate || "",
|
|
158
|
+
reviewCount: reviewInfo?.count || 0,
|
|
159
|
+
};
|
|
160
|
+
});
|
|
161
|
+
const reviewedCount = fileStatuses.filter((f) => f.reviewed).length;
|
|
162
|
+
const coveragePercent = (reviewedCount / files.length) * 100;
|
|
163
|
+
const report = {
|
|
164
|
+
timestamp: new Date().toISOString(),
|
|
165
|
+
totalFiles: files.length,
|
|
166
|
+
reviewedFiles: reviewedCount,
|
|
167
|
+
coveragePercent,
|
|
168
|
+
files: fileStatuses,
|
|
169
|
+
};
|
|
170
|
+
if (format === "json") {
|
|
171
|
+
console.log(JSON.stringify(report, null, 2));
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
const displayFiles = unreviewedOnly ? fileStatuses.filter((f) => !f.reviewed) : fileStatuses;
|
|
175
|
+
console.log("\nReview Coverage Map:");
|
|
176
|
+
console.log("═".repeat(70));
|
|
177
|
+
console.log(` Total: ${files.length} Reviewed: ${reviewedCount} Coverage: ${coveragePercent.toFixed(1)}%`);
|
|
178
|
+
console.log("═".repeat(70));
|
|
179
|
+
const bar = (pct) => {
|
|
180
|
+
const filled = Math.round(pct / 5);
|
|
181
|
+
return "█".repeat(filled) + "░".repeat(20 - filled);
|
|
182
|
+
};
|
|
183
|
+
console.log(` [${bar(coveragePercent)}] ${coveragePercent.toFixed(1)}%`);
|
|
184
|
+
console.log("");
|
|
185
|
+
for (const f of displayFiles.slice(0, 50)) {
|
|
186
|
+
const icon = f.reviewed ? "✓" : "○";
|
|
187
|
+
const info = f.reviewed ? ` reviewed=${f.reviewCount} ${f.lastReviewDate.slice(0, 10)}` : "";
|
|
188
|
+
console.log(` ${icon} ${f.file}${info}`);
|
|
189
|
+
}
|
|
190
|
+
if (displayFiles.length > 50) {
|
|
191
|
+
console.log(` ... and ${displayFiles.length - 50} more`);
|
|
192
|
+
}
|
|
193
|
+
console.log("═".repeat(70));
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=review-coverage-map.js.map
|