@kevinrabun/judges 3.4.0 → 3.5.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/README.md +189 -4
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +280 -12
- package/dist/cli.js.map +1 -1
- package/dist/commands/baseline.d.ts +2 -0
- package/dist/commands/baseline.d.ts.map +1 -0
- package/dist/commands/baseline.js +126 -0
- package/dist/commands/baseline.js.map +1 -0
- package/dist/commands/completions.d.ts +2 -0
- package/dist/commands/completions.d.ts.map +1 -0
- package/dist/commands/completions.js +226 -0
- package/dist/commands/completions.js.map +1 -0
- package/dist/commands/deps.d.ts +6 -0
- package/dist/commands/deps.d.ts.map +1 -0
- package/dist/commands/deps.js +123 -0
- package/dist/commands/deps.js.map +1 -0
- package/dist/commands/diff.d.ts +7 -0
- package/dist/commands/diff.d.ts.map +1 -0
- package/dist/commands/diff.js +209 -0
- package/dist/commands/diff.js.map +1 -0
- package/dist/commands/docs.d.ts +2 -0
- package/dist/commands/docs.d.ts.map +1 -0
- package/dist/commands/docs.js +157 -0
- package/dist/commands/docs.js.map +1 -0
- package/dist/commands/watch.js.map +1 -1
- package/dist/formatters/badge.d.ts +17 -0
- package/dist/formatters/badge.d.ts.map +1 -0
- package/dist/formatters/badge.js +79 -0
- package/dist/formatters/badge.js.map +1 -0
- package/dist/formatters/codeclimate.d.ts +25 -0
- package/dist/formatters/codeclimate.d.ts.map +1 -0
- package/dist/formatters/codeclimate.js +81 -0
- package/dist/formatters/codeclimate.js.map +1 -0
- package/dist/formatters/junit.d.ts +7 -0
- package/dist/formatters/junit.d.ts.map +1 -0
- package/dist/formatters/junit.js +69 -0
- package/dist/formatters/junit.js.map +1 -0
- package/dist/index.js +17 -2
- package/dist/index.js.map +1 -1
- package/dist/presets.d.ts +22 -0
- package/dist/presets.d.ts.map +1 -0
- package/dist/presets.js +115 -0
- package/dist/presets.js.map +1 -0
- package/judgesrc.schema.json +74 -0
- package/package.json +14 -1
|
@@ -0,0 +1,209 @@
|
|
|
1
|
+
// ─── Diff Command ────────────────────────────────────────────────────────────
|
|
2
|
+
// Evaluate only changed lines from a unified diff or git diff output.
|
|
3
|
+
//
|
|
4
|
+
// Usage:
|
|
5
|
+
// git diff HEAD~1 | judges diff --language typescript
|
|
6
|
+
// judges diff --file changes.patch --language typescript
|
|
7
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
8
|
+
import { readFileSync, existsSync } from "fs";
|
|
9
|
+
import { resolve, extname } from "path";
|
|
10
|
+
import { evaluateDiff } from "../evaluators/index.js";
|
|
11
|
+
/**
|
|
12
|
+
* Parse a unified diff into hunks with changed line information.
|
|
13
|
+
* Handles `git diff` and standard `diff -u` output.
|
|
14
|
+
*/
|
|
15
|
+
function parseUnifiedDiff(diffText) {
|
|
16
|
+
const hunks = [];
|
|
17
|
+
const lines = diffText.split("\n");
|
|
18
|
+
let currentFile;
|
|
19
|
+
let newLines = [];
|
|
20
|
+
let changedLineNumbers = [];
|
|
21
|
+
let newLineNum = 0;
|
|
22
|
+
function flushFile() {
|
|
23
|
+
if (currentFile && (newLines.length > 0 || changedLineNumbers.length > 0)) {
|
|
24
|
+
hunks.push({
|
|
25
|
+
filePath: currentFile,
|
|
26
|
+
newContent: newLines.join("\n"),
|
|
27
|
+
changedLines: changedLineNumbers,
|
|
28
|
+
});
|
|
29
|
+
}
|
|
30
|
+
newLines = [];
|
|
31
|
+
changedLineNumbers = [];
|
|
32
|
+
newLineNum = 0;
|
|
33
|
+
}
|
|
34
|
+
for (const line of lines) {
|
|
35
|
+
// New file header: +++ b/path/to/file.ts
|
|
36
|
+
if (line.startsWith("+++ ")) {
|
|
37
|
+
const path = line.slice(4).replace(/^b\//, "").trim();
|
|
38
|
+
if (path !== "/dev/null") {
|
|
39
|
+
flushFile();
|
|
40
|
+
currentFile = path;
|
|
41
|
+
}
|
|
42
|
+
continue;
|
|
43
|
+
}
|
|
44
|
+
// Skip --- header
|
|
45
|
+
if (line.startsWith("--- "))
|
|
46
|
+
continue;
|
|
47
|
+
// Hunk header: @@ -10,5 +20,8 @@
|
|
48
|
+
const hunkMatch = line.match(/^@@ -\d+(?:,\d+)? \+(\d+)(?:,\d+)? @@/);
|
|
49
|
+
if (hunkMatch) {
|
|
50
|
+
newLineNum = parseInt(hunkMatch[1], 10) - 1; // will increment on first line
|
|
51
|
+
continue;
|
|
52
|
+
}
|
|
53
|
+
// diff --git header — skip
|
|
54
|
+
if (line.startsWith("diff --git ") || line.startsWith("index "))
|
|
55
|
+
continue;
|
|
56
|
+
// Context line (starts with space or is empty in diff)
|
|
57
|
+
if (line.startsWith(" ") || (line === "" && newLineNum > 0)) {
|
|
58
|
+
newLineNum++;
|
|
59
|
+
newLines.push(line.startsWith(" ") ? line.slice(1) : line);
|
|
60
|
+
continue;
|
|
61
|
+
}
|
|
62
|
+
// Added line
|
|
63
|
+
if (line.startsWith("+")) {
|
|
64
|
+
newLineNum++;
|
|
65
|
+
changedLineNumbers.push(newLineNum);
|
|
66
|
+
newLines.push(line.slice(1));
|
|
67
|
+
continue;
|
|
68
|
+
}
|
|
69
|
+
// Removed line — skip (not in new content)
|
|
70
|
+
if (line.startsWith("-")) {
|
|
71
|
+
continue;
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
flushFile();
|
|
75
|
+
return hunks;
|
|
76
|
+
}
|
|
77
|
+
// ─── Language Detection ─────────────────────────────────────────────────────
|
|
78
|
+
const EXT_TO_LANG = {
|
|
79
|
+
".ts": "typescript",
|
|
80
|
+
".tsx": "typescript",
|
|
81
|
+
".js": "javascript",
|
|
82
|
+
".jsx": "javascript",
|
|
83
|
+
".mjs": "javascript",
|
|
84
|
+
".cjs": "javascript",
|
|
85
|
+
".py": "python",
|
|
86
|
+
".rs": "rust",
|
|
87
|
+
".go": "go",
|
|
88
|
+
".java": "java",
|
|
89
|
+
".cs": "csharp",
|
|
90
|
+
".rb": "ruby",
|
|
91
|
+
".php": "php",
|
|
92
|
+
".swift": "swift",
|
|
93
|
+
".kt": "kotlin",
|
|
94
|
+
".scala": "scala",
|
|
95
|
+
".c": "c",
|
|
96
|
+
".cpp": "cpp",
|
|
97
|
+
".h": "c",
|
|
98
|
+
".hpp": "cpp",
|
|
99
|
+
".yaml": "yaml",
|
|
100
|
+
".yml": "yaml",
|
|
101
|
+
".json": "json",
|
|
102
|
+
".tf": "terraform",
|
|
103
|
+
".hcl": "terraform",
|
|
104
|
+
".sh": "bash",
|
|
105
|
+
".bash": "bash",
|
|
106
|
+
};
|
|
107
|
+
function detectLanguage(filePath) {
|
|
108
|
+
const ext = extname(filePath.toLowerCase());
|
|
109
|
+
if (filePath.toLowerCase().includes("dockerfile"))
|
|
110
|
+
return "dockerfile";
|
|
111
|
+
return EXT_TO_LANG[ext];
|
|
112
|
+
}
|
|
113
|
+
// ─── CLI Entry Point ────────────────────────────────────────────────────────
|
|
114
|
+
export function parseDiffArgs(argv) {
|
|
115
|
+
let file;
|
|
116
|
+
let language;
|
|
117
|
+
let format = "text";
|
|
118
|
+
for (let i = 3; i < argv.length; i++) {
|
|
119
|
+
const arg = argv[i];
|
|
120
|
+
switch (arg) {
|
|
121
|
+
case "--file":
|
|
122
|
+
case "-f":
|
|
123
|
+
file = argv[++i];
|
|
124
|
+
break;
|
|
125
|
+
case "--language":
|
|
126
|
+
case "-l":
|
|
127
|
+
language = argv[++i];
|
|
128
|
+
break;
|
|
129
|
+
case "--format":
|
|
130
|
+
case "-o":
|
|
131
|
+
format = argv[++i];
|
|
132
|
+
break;
|
|
133
|
+
default:
|
|
134
|
+
if (!arg.startsWith("-") && !file)
|
|
135
|
+
file = arg;
|
|
136
|
+
break;
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
return { file, language, format };
|
|
140
|
+
}
|
|
141
|
+
export function runDiff(argv) {
|
|
142
|
+
const args = parseDiffArgs(argv);
|
|
143
|
+
// Read diff from file or stdin
|
|
144
|
+
let diffText;
|
|
145
|
+
if (args.file) {
|
|
146
|
+
const abs = resolve(args.file);
|
|
147
|
+
if (!existsSync(abs)) {
|
|
148
|
+
console.error(`Error: File not found: ${abs}`);
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
diffText = readFileSync(abs, "utf-8");
|
|
152
|
+
}
|
|
153
|
+
else if (!process.stdin.isTTY) {
|
|
154
|
+
try {
|
|
155
|
+
diffText = readFileSync(0, "utf-8");
|
|
156
|
+
}
|
|
157
|
+
catch {
|
|
158
|
+
console.error("Error: Could not read diff from stdin");
|
|
159
|
+
process.exit(1);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
else {
|
|
163
|
+
console.error("Usage: git diff | judges diff --language <lang>");
|
|
164
|
+
console.error(" judges diff --file changes.patch");
|
|
165
|
+
process.exit(1);
|
|
166
|
+
return; // unreachable but satisfies TS
|
|
167
|
+
}
|
|
168
|
+
const hunks = parseUnifiedDiff(diffText);
|
|
169
|
+
if (hunks.length === 0) {
|
|
170
|
+
console.log("No changed files found in diff.");
|
|
171
|
+
process.exit(0);
|
|
172
|
+
}
|
|
173
|
+
let totalFindings = 0;
|
|
174
|
+
let worstScore = 100;
|
|
175
|
+
const allResults = [];
|
|
176
|
+
for (const hunk of hunks) {
|
|
177
|
+
if (hunk.changedLines.length === 0)
|
|
178
|
+
continue;
|
|
179
|
+
const lang = args.language || detectLanguage(hunk.filePath) || "typescript";
|
|
180
|
+
const verdict = evaluateDiff(hunk.newContent, lang, hunk.changedLines);
|
|
181
|
+
totalFindings += verdict.findings.length;
|
|
182
|
+
if (verdict.score < worstScore)
|
|
183
|
+
worstScore = verdict.score;
|
|
184
|
+
allResults.push({ file: hunk.filePath, verdict });
|
|
185
|
+
}
|
|
186
|
+
if (args.format === "json") {
|
|
187
|
+
console.log(JSON.stringify({ files: allResults, totalFindings, worstScore }, null, 2));
|
|
188
|
+
}
|
|
189
|
+
else {
|
|
190
|
+
// Text output
|
|
191
|
+
console.log("");
|
|
192
|
+
console.log("╔══════════════════════════════════════════════════════════════╗");
|
|
193
|
+
console.log("║ Judges Panel — Diff Analysis ║");
|
|
194
|
+
console.log("╚══════════════════════════════════════════════════════════════╝");
|
|
195
|
+
console.log("");
|
|
196
|
+
for (const { file, verdict } of allResults) {
|
|
197
|
+
const icon = verdict.verdict === "pass" ? "✅" : verdict.verdict === "warning" ? "⚠️ " : "❌";
|
|
198
|
+
console.log(` ${icon} ${file} — ${verdict.score}/100 (${verdict.findings.length} findings, ${verdict.linesAnalyzed} lines changed)`);
|
|
199
|
+
for (const f of verdict.findings) {
|
|
200
|
+
console.log(` [${f.severity.toUpperCase().padEnd(8)}] ${f.ruleId}: ${f.title}`);
|
|
201
|
+
}
|
|
202
|
+
}
|
|
203
|
+
console.log("");
|
|
204
|
+
console.log(` Total: ${totalFindings} finding(s) across ${allResults.length} file(s), worst score: ${worstScore}/100`);
|
|
205
|
+
console.log("");
|
|
206
|
+
}
|
|
207
|
+
process.exit(totalFindings > 0 && worstScore < 50 ? 1 : 0);
|
|
208
|
+
}
|
|
209
|
+
//# sourceMappingURL=diff.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"diff.js","sourceRoot":"","sources":["../../src/commands/diff.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,sEAAsE;AACtE,EAAE;AACF,SAAS;AACT,wDAAwD;AACxD,2DAA2D;AAC3D,iFAAiF;AAEjF,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,MAAM,IAAI,CAAC;AAC9C,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,MAAM,MAAM,CAAC;AACxC,OAAO,EAAE,YAAY,EAAE,MAAM,wBAAwB,CAAC;AAatD;;;GAGG;AACH,SAAS,gBAAgB,CAAC,QAAgB;IACxC,MAAM,KAAK,GAAe,EAAE,CAAC;IAC7B,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEnC,IAAI,WAA+B,CAAC;IACpC,IAAI,QAAQ,GAAa,EAAE,CAAC;IAC5B,IAAI,kBAAkB,GAAa,EAAE,CAAC;IACtC,IAAI,UAAU,GAAG,CAAC,CAAC;IAEnB,SAAS,SAAS;QAChB,IAAI,WAAW,IAAI,CAAC,QAAQ,CAAC,MAAM,GAAG,CAAC,IAAI,kBAAkB,CAAC,MAAM,GAAG,CAAC,CAAC,EAAE,CAAC;YAC1E,KAAK,CAAC,IAAI,CAAC;gBACT,QAAQ,EAAE,WAAW;gBACrB,UAAU,EAAE,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC;gBAC/B,YAAY,EAAE,kBAAkB;aACjC,CAAC,CAAC;QACL,CAAC;QACD,QAAQ,GAAG,EAAE,CAAC;QACd,kBAAkB,GAAG,EAAE,CAAC;QACxB,UAAU,GAAG,CAAC,CAAC;IACjB,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,yCAAyC;QACzC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,EAAE,CAAC;YAC5B,MAAM,IAAI,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,MAAM,EAAE,EAAE,CAAC,CAAC,IAAI,EAAE,CAAC;YACtD,IAAI,IAAI,KAAK,WAAW,EAAE,CAAC;gBACzB,SAAS,EAAE,CAAC;gBACZ,WAAW,GAAG,IAAI,CAAC;YACrB,CAAC;YACD,SAAS;QACX,CAAC;QAED,kBAAkB;QAClB,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC;YAAE,SAAS;QAEtC,iCAAiC;QACjC,MAAM,SAAS,GAAG,IAAI,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;QACtE,IAAI,SAAS,EAAE,CAAC;YACd,UAAU,GAAG,QAAQ,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAC,+BAA+B;YAC5E,SAAS;QACX,CAAC;QAED,2BAA2B;QAC3B,IAAI,IAAI,CAAC,UAAU,CAAC,aAAa,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;YAAE,SAAS;QAE1E,uDAAuD;QACvD,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI,KAAK,EAAE,IAAI,UAAU,GAAG,CAAC,CAAC,EAAE,CAAC;YAC5D,UAAU,EAAE,CAAC;YACb,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC;YAC3D,SAAS;QACX,CAAC;QAED,aAAa;QACb,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,UAAU,EAAE,CAAC;YACb,kBAAkB,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;YACpC,QAAQ,CAAC,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;YAC7B,SAAS;QACX,CAAC;QAED,2CAA2C;QAC3C,IAAI,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACzB,SAAS;QACX,CAAC;IACH,CAAC;IAED,SAAS,EAAE,CAAC;IACZ,OAAO,KAAK,CAAC;AACf,CAAC;AAED,+EAA+E;AAE/E,MAAM,WAAW,GAA2B;IAC1C,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,YAAY;IACpB,KAAK,EAAE,YAAY;IACnB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,MAAM,EAAE,YAAY;IACpB,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,MAAM;IACb,KAAK,EAAE,IAAI;IACX,OAAO,EAAE,MAAM;IACf,KAAK,EAAE,QAAQ;IACf,KAAK,EAAE,MAAM;IACb,MAAM,EAAE,KAAK;IACb,QAAQ,EAAE,OAAO;IACjB,KAAK,EAAE,QAAQ;IACf,QAAQ,EAAE,OAAO;IACjB,IAAI,EAAE,GAAG;IACT,MAAM,EAAE,KAAK;IACb,IAAI,EAAE,GAAG;IACT,MAAM,EAAE,KAAK;IACb,OAAO,EAAE,MAAM;IACf,MAAM,EAAE,MAAM;IACd,OAAO,EAAE,MAAM;IACf,KAAK,EAAE,WAAW;IAClB,MAAM,EAAE,WAAW;IACnB,KAAK,EAAE,MAAM;IACb,OAAO,EAAE,MAAM;CAChB,CAAC;AAEF,SAAS,cAAc,CAAC,QAAgB;IACtC,MAAM,GAAG,GAAG,OAAO,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,CAAC;IAC5C,IAAI,QAAQ,CAAC,WAAW,EAAE,CAAC,QAAQ,CAAC,YAAY,CAAC;QAAE,OAAO,YAAY,CAAC;IACvE,OAAO,WAAW,CAAC,GAAG,CAAC,CAAC;AAC1B,CAAC;AAED,+EAA+E;AAE/E,MAAM,UAAU,aAAa,CAAC,IAAc;IAC1C,IAAI,IAAwB,CAAC;IAC7B,IAAI,QAA4B,CAAC;IACjC,IAAI,MAAM,GAAG,MAAM,CAAC;IAEpB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,IAAI,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACrC,MAAM,GAAG,GAAG,IAAI,CAAC,CAAC,CAAC,CAAC;QACpB,QAAQ,GAAG,EAAE,CAAC;YACZ,KAAK,QAAQ,CAAC;YACd,KAAK,IAAI;gBACP,IAAI,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACjB,MAAM;YACR,KAAK,YAAY,CAAC;YAClB,KAAK,IAAI;gBACP,QAAQ,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACrB,MAAM;YACR,KAAK,UAAU,CAAC;YAChB,KAAK,IAAI;gBACP,MAAM,GAAG,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC;gBACnB,MAAM;YACR;gBACE,IAAI,CAAC,GAAG,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,IAAI;oBAAE,IAAI,GAAG,GAAG,CAAC;gBAC9C,MAAM;QACV,CAAC;IACH,CAAC;IAED,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,EAAE,CAAC;AACpC,CAAC;AAED,MAAM,UAAU,OAAO,CAAC,IAAc;IACpC,MAAM,IAAI,GAAG,aAAa,CAAC,IAAI,CAAC,CAAC;IAEjC,+BAA+B;IAC/B,IAAI,QAAgB,CAAC;IACrB,IAAI,IAAI,CAAC,IAAI,EAAE,CAAC;QACd,MAAM,GAAG,GAAG,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/B,IAAI,CAAC,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;YACrB,OAAO,CAAC,KAAK,CAAC,0BAA0B,GAAG,EAAE,CAAC,CAAC;YAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;QACD,QAAQ,GAAG,YAAY,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IACxC,CAAC;SAAM,IAAI,CAAC,OAAO,CAAC,KAAK,CAAC,KAAK,EAAE,CAAC;QAChC,IAAI,CAAC;YACH,QAAQ,GAAG,YAAY,CAAC,CAAC,EAAE,OAAO,CAAC,CAAC;QACtC,CAAC;QAAC,MAAM,CAAC;YACP,OAAO,CAAC,KAAK,CAAC,uCAAuC,CAAC,CAAC;YACvD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAClB,CAAC;IACH,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,KAAK,CAAC,iDAAiD,CAAC,CAAC;QACjE,OAAO,CAAC,KAAK,CAAC,yCAAyC,CAAC,CAAC;QACzD,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;QAChB,OAAO,CAAC,+BAA+B;IACzC,CAAC;IAED,MAAM,KAAK,GAAG,gBAAgB,CAAC,QAAQ,CAAC,CAAC;IAEzC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,iCAAiC,CAAC,CAAC;QAC/C,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC;IAClB,CAAC;IAED,IAAI,aAAa,GAAG,CAAC,CAAC;IACtB,IAAI,UAAU,GAAG,GAAG,CAAC;IACrB,MAAM,UAAU,GAAsE,EAAE,CAAC;IAEzF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,IAAI,IAAI,CAAC,YAAY,CAAC,MAAM,KAAK,CAAC;YAAE,SAAS;QAE7C,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,IAAI,cAAc,CAAC,IAAI,CAAC,QAAQ,CAAC,IAAI,YAAY,CAAC;QAC5E,MAAM,OAAO,GAAG,YAAY,CAAC,IAAI,CAAC,UAAU,EAAE,IAAI,EAAE,IAAI,CAAC,YAAY,CAAC,CAAC;QACvE,aAAa,IAAI,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAC;QACzC,IAAI,OAAO,CAAC,KAAK,GAAG,UAAU;YAAE,UAAU,GAAG,OAAO,CAAC,KAAK,CAAC;QAC3D,UAAU,CAAC,IAAI,CAAC,EAAE,IAAI,EAAE,IAAI,CAAC,QAAQ,EAAE,OAAO,EAAE,CAAC,CAAC;IACpD,CAAC;IAED,IAAI,IAAI,CAAC,MAAM,KAAK,MAAM,EAAE,CAAC;QAC3B,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,KAAK,EAAE,UAAU,EAAE,aAAa,EAAE,UAAU,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IACzF,CAAC;SAAM,CAAC;QACN,cAAc;QACd,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC;QAChF,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC;QAChF,OAAO,CAAC,GAAG,CAAC,kEAAkE,CAAC,CAAC;QAChF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAEhB,KAAK,MAAM,EAAE,IAAI,EAAE,OAAO,EAAE,IAAI,UAAU,EAAE,CAAC;YAC3C,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,KAAK,MAAM,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,OAAO,CAAC,OAAO,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC;YAC5F,OAAO,CAAC,GAAG,CACT,KAAK,IAAI,IAAI,IAAI,MAAM,OAAO,CAAC,KAAK,SAAS,OAAO,CAAC,QAAQ,CAAC,MAAM,cAAc,OAAO,CAAC,aAAa,iBAAiB,CACzH,CAAC;YACF,KAAK,MAAM,CAAC,IAAI,OAAO,CAAC,QAAQ,EAAE,CAAC;gBACjC,OAAO,CAAC,GAAG,CAAC,SAAS,CAAC,CAAC,QAAQ,CAAC,WAAW,EAAE,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,MAAM,KAAK,CAAC,CAAC,KAAK,EAAE,CAAC,CAAC;YACtF,CAAC;QACH,CAAC;QAED,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAChB,OAAO,CAAC,GAAG,CACT,YAAY,aAAa,sBAAsB,UAAU,CAAC,MAAM,0BAA0B,UAAU,MAAM,CAC3G,CAAC;QACF,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;IAED,OAAO,CAAC,IAAI,CAAC,aAAa,GAAG,CAAC,IAAI,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;AAC7D,CAAC"}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.d.ts","sourceRoot":"","sources":["../../src/commands/docs.ts"],"names":[],"mappings":"AAuHA,wBAAgB,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAkE5C"}
|
|
@@ -0,0 +1,157 @@
|
|
|
1
|
+
// ─── Rule Documentation Generator ────────────────────────────────────────────
|
|
2
|
+
// Generate per-judge/per-rule documentation in Markdown format.
|
|
3
|
+
//
|
|
4
|
+
// Usage:
|
|
5
|
+
// judges docs # output all judge docs to stdout
|
|
6
|
+
// judges docs --output docs/rules/ # write individual files
|
|
7
|
+
// judges docs --judge cybersecurity # single judge
|
|
8
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
9
|
+
import { writeFileSync, mkdirSync, existsSync } from "fs";
|
|
10
|
+
import { join, resolve } from "path";
|
|
11
|
+
import { JUDGES, getJudge } from "../judges/index.js";
|
|
12
|
+
function extractRulesFromPrompt(judge) {
|
|
13
|
+
const rules = [];
|
|
14
|
+
const prompt = judge.systemPrompt;
|
|
15
|
+
// Typically rules are documented in the system prompt with patterns like:
|
|
16
|
+
// SEC-001: Title — Description
|
|
17
|
+
// or SEC-001 | Title | Description
|
|
18
|
+
const rulePattern = new RegExp(`(${judge.rulePrefix}-\\d{3})[:\\s|]+([^\\n|]+?)(?:\\s*[—|]\\s*([^\\n]+))?$`, "gm");
|
|
19
|
+
let match;
|
|
20
|
+
while ((match = rulePattern.exec(prompt)) !== null) {
|
|
21
|
+
rules.push({
|
|
22
|
+
ruleId: match[1],
|
|
23
|
+
title: match[2].trim(),
|
|
24
|
+
description: match[3]?.trim() || match[2].trim(),
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
return rules;
|
|
28
|
+
}
|
|
29
|
+
// ─── Generate Documentation ─────────────────────────────────────────────────
|
|
30
|
+
function generateJudgeDoc(judge) {
|
|
31
|
+
const rules = extractRulesFromPrompt(judge);
|
|
32
|
+
const lines = [];
|
|
33
|
+
lines.push(`# ${judge.name}`);
|
|
34
|
+
lines.push("");
|
|
35
|
+
lines.push(`**Domain:** ${judge.domain}`);
|
|
36
|
+
lines.push(`**Rule Prefix:** \`${judge.rulePrefix}\``);
|
|
37
|
+
lines.push(`**Judge ID:** \`${judge.id}\``);
|
|
38
|
+
lines.push("");
|
|
39
|
+
lines.push("## Description");
|
|
40
|
+
lines.push("");
|
|
41
|
+
lines.push(judge.description);
|
|
42
|
+
lines.push("");
|
|
43
|
+
if (rules.length > 0) {
|
|
44
|
+
lines.push("## Rules");
|
|
45
|
+
lines.push("");
|
|
46
|
+
lines.push("| Rule ID | Title | Description |");
|
|
47
|
+
lines.push("|---------|-------|-------------|");
|
|
48
|
+
for (const rule of rules) {
|
|
49
|
+
lines.push(`| \`${rule.ruleId}\` | ${rule.title} | ${rule.description} |`);
|
|
50
|
+
}
|
|
51
|
+
lines.push("");
|
|
52
|
+
}
|
|
53
|
+
lines.push("## Usage");
|
|
54
|
+
lines.push("");
|
|
55
|
+
lines.push("```bash");
|
|
56
|
+
lines.push(`# Evaluate with this judge only`);
|
|
57
|
+
lines.push(`judges eval --judge ${judge.id} --file <path>`);
|
|
58
|
+
lines.push("");
|
|
59
|
+
lines.push("# As part of the full tribunal");
|
|
60
|
+
lines.push("judges eval --file <path>");
|
|
61
|
+
lines.push("```");
|
|
62
|
+
lines.push("");
|
|
63
|
+
return lines.join("\n");
|
|
64
|
+
}
|
|
65
|
+
function generateIndexDoc() {
|
|
66
|
+
const lines = [];
|
|
67
|
+
lines.push("# Judges Panel — Rule Reference");
|
|
68
|
+
lines.push("");
|
|
69
|
+
lines.push(`The Judges Panel includes **${JUDGES.length}** specialized judges that evaluate AI-generated code.`);
|
|
70
|
+
lines.push("");
|
|
71
|
+
lines.push("## Judges");
|
|
72
|
+
lines.push("");
|
|
73
|
+
lines.push("| Judge | Domain | Rule Prefix | Description |");
|
|
74
|
+
lines.push("|-------|--------|-------------|-------------|");
|
|
75
|
+
for (const judge of JUDGES) {
|
|
76
|
+
lines.push(`| [${judge.name}](${judge.id}.md) | ${judge.domain} | \`${judge.rulePrefix}\` | ${judge.description} |`);
|
|
77
|
+
}
|
|
78
|
+
lines.push("");
|
|
79
|
+
lines.push("## Quick Start");
|
|
80
|
+
lines.push("");
|
|
81
|
+
lines.push("```bash");
|
|
82
|
+
lines.push("# Evaluate a file with all judges");
|
|
83
|
+
lines.push("judges eval --file src/app.ts");
|
|
84
|
+
lines.push("");
|
|
85
|
+
lines.push("# Evaluate with a specific judge");
|
|
86
|
+
lines.push("judges eval --judge cybersecurity --file src/app.ts");
|
|
87
|
+
lines.push("");
|
|
88
|
+
lines.push("# List all available judges");
|
|
89
|
+
lines.push("judges list");
|
|
90
|
+
lines.push("```");
|
|
91
|
+
lines.push("");
|
|
92
|
+
return lines.join("\n");
|
|
93
|
+
}
|
|
94
|
+
// ─── CLI Entry Point ────────────────────────────────────────────────────────
|
|
95
|
+
export function runDocs(argv) {
|
|
96
|
+
let output;
|
|
97
|
+
let judgeId;
|
|
98
|
+
for (let i = 3; i < argv.length; i++) {
|
|
99
|
+
const arg = argv[i];
|
|
100
|
+
switch (arg) {
|
|
101
|
+
case "--output":
|
|
102
|
+
case "-o":
|
|
103
|
+
output = argv[++i];
|
|
104
|
+
break;
|
|
105
|
+
case "--judge":
|
|
106
|
+
case "-j":
|
|
107
|
+
judgeId = argv[++i];
|
|
108
|
+
break;
|
|
109
|
+
case "--help":
|
|
110
|
+
case "-h":
|
|
111
|
+
console.log(`
|
|
112
|
+
Judges Panel — Rule Documentation Generator
|
|
113
|
+
|
|
114
|
+
USAGE:
|
|
115
|
+
judges docs Print all docs to stdout
|
|
116
|
+
judges docs --output docs/rules/ Write per-judge .md files
|
|
117
|
+
judges docs --judge cybersecurity Show single judge documentation
|
|
118
|
+
|
|
119
|
+
OPTIONS:
|
|
120
|
+
--output, -o <dir> Output directory for .md files
|
|
121
|
+
--judge, -j <id> Generate docs for a single judge
|
|
122
|
+
`);
|
|
123
|
+
process.exit(0);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
if (judgeId) {
|
|
127
|
+
const judge = getJudge(judgeId);
|
|
128
|
+
if (!judge) {
|
|
129
|
+
console.error(`Unknown judge: ${judgeId}`);
|
|
130
|
+
console.error('Run "judges list" to see available judges.');
|
|
131
|
+
process.exit(1);
|
|
132
|
+
}
|
|
133
|
+
console.log(generateJudgeDoc(judge));
|
|
134
|
+
process.exit(0);
|
|
135
|
+
}
|
|
136
|
+
if (output) {
|
|
137
|
+
const dir = resolve(output);
|
|
138
|
+
if (!existsSync(dir))
|
|
139
|
+
mkdirSync(dir, { recursive: true });
|
|
140
|
+
// Write index
|
|
141
|
+
writeFileSync(join(dir, "README.md"), generateIndexDoc(), "utf-8");
|
|
142
|
+
// Write per-judge docs
|
|
143
|
+
for (const judge of JUDGES) {
|
|
144
|
+
writeFileSync(join(dir, `${judge.id}.md`), generateJudgeDoc(judge), "utf-8");
|
|
145
|
+
}
|
|
146
|
+
console.log(`✅ Generated documentation for ${JUDGES.length} judges in ${dir}`);
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
// Print everything to stdout
|
|
150
|
+
console.log(generateIndexDoc());
|
|
151
|
+
for (const judge of JUDGES) {
|
|
152
|
+
console.log(generateJudgeDoc(judge));
|
|
153
|
+
}
|
|
154
|
+
}
|
|
155
|
+
process.exit(0);
|
|
156
|
+
}
|
|
157
|
+
//# sourceMappingURL=docs.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"docs.js","sourceRoot":"","sources":["../../src/commands/docs.ts"],"names":[],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,QAAQ,EAAE,KAAK,IAAI,OAAO,
|
|
1
|
+
{"version":3,"file":"watch.js","sourceRoot":"","sources":["../../src/commands/watch.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Generate an SVG badge in shields.io flat style.
|
|
3
|
+
*
|
|
4
|
+
* @param score - Score 0–100
|
|
5
|
+
* @param label - Left label text (default: "judges")
|
|
6
|
+
* @returns SVG string
|
|
7
|
+
*/
|
|
8
|
+
export declare function generateBadgeSvg(score: number, label?: string): string;
|
|
9
|
+
/**
|
|
10
|
+
* Generate a simple text-based badge string for terminals.
|
|
11
|
+
*
|
|
12
|
+
* @param score - Score 0–100
|
|
13
|
+
* @param label - Label text
|
|
14
|
+
* @returns Formatted badge string like "[ judges: 85/100 ✓ ]"
|
|
15
|
+
*/
|
|
16
|
+
export declare function generateBadgeText(score: number, label?: string): string;
|
|
17
|
+
//# sourceMappingURL=badge.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"badge.d.ts","sourceRoot":"","sources":["../../src/formatters/badge.ts"],"names":[],"mappings":"AA8BA;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAW,GAAG,MAAM,CA4BxE;AAED;;;;;;GAMG;AACH,wBAAgB,iBAAiB,CAAC,KAAK,EAAE,MAAM,EAAE,KAAK,SAAW,GAAG,MAAM,CAGzE"}
|
|
@@ -0,0 +1,79 @@
|
|
|
1
|
+
// ─── Score Badge Generator ───────────────────────────────────────────────────
|
|
2
|
+
// Generate SVG badge images from evaluation scores.
|
|
3
|
+
// Compatible with shields.io style badges for use in README files.
|
|
4
|
+
//
|
|
5
|
+
// Usage:
|
|
6
|
+
// import { generateBadgeSvg } from "./badge.js";
|
|
7
|
+
// const svg = generateBadgeSvg(85); // green badge "judges | 85/100"
|
|
8
|
+
// const svg = generateBadgeSvg(42); // red badge "judges | 42/100"
|
|
9
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
10
|
+
/**
|
|
11
|
+
* Determine badge color based on score.
|
|
12
|
+
*/
|
|
13
|
+
function scoreColor(score) {
|
|
14
|
+
if (score >= 90)
|
|
15
|
+
return "#4c1"; // bright green
|
|
16
|
+
if (score >= 80)
|
|
17
|
+
return "#97ca00"; // green
|
|
18
|
+
if (score >= 70)
|
|
19
|
+
return "#a4a61d"; // yellow-green
|
|
20
|
+
if (score >= 60)
|
|
21
|
+
return "#dfb317"; // yellow
|
|
22
|
+
if (score >= 50)
|
|
23
|
+
return "#fe7d37"; // orange
|
|
24
|
+
return "#e05d44"; // red
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Estimate text width for SVG rendering.
|
|
28
|
+
*/
|
|
29
|
+
function textWidth(text) {
|
|
30
|
+
// Approximate character widths at 11px Verdana
|
|
31
|
+
return text.length * 6.5 + 10;
|
|
32
|
+
}
|
|
33
|
+
/**
|
|
34
|
+
* Generate an SVG badge in shields.io flat style.
|
|
35
|
+
*
|
|
36
|
+
* @param score - Score 0–100
|
|
37
|
+
* @param label - Left label text (default: "judges")
|
|
38
|
+
* @returns SVG string
|
|
39
|
+
*/
|
|
40
|
+
export function generateBadgeSvg(score, label = "judges") {
|
|
41
|
+
const value = `${Math.round(score)} / 100`;
|
|
42
|
+
const color = scoreColor(score);
|
|
43
|
+
const lw = textWidth(label);
|
|
44
|
+
const vw = textWidth(value);
|
|
45
|
+
const totalWidth = lw + vw;
|
|
46
|
+
return `<svg xmlns="http://www.w3.org/2000/svg" width="${totalWidth}" height="20" role="img" aria-label="${label}: ${value}">
|
|
47
|
+
<title>${label}: ${value}</title>
|
|
48
|
+
<linearGradient id="s" x2="0" y2="100%">
|
|
49
|
+
<stop offset="0" stop-color="#bbb" stop-opacity=".1"/>
|
|
50
|
+
<stop offset="1" stop-opacity=".1"/>
|
|
51
|
+
</linearGradient>
|
|
52
|
+
<clipPath id="r">
|
|
53
|
+
<rect width="${totalWidth}" height="20" rx="3" fill="#fff"/>
|
|
54
|
+
</clipPath>
|
|
55
|
+
<g clip-path="url(#r)">
|
|
56
|
+
<rect width="${lw}" height="20" fill="#555"/>
|
|
57
|
+
<rect x="${lw}" width="${vw}" height="20" fill="${color}"/>
|
|
58
|
+
<rect width="${totalWidth}" height="20" fill="url(#s)"/>
|
|
59
|
+
</g>
|
|
60
|
+
<g fill="#fff" text-anchor="middle" font-family="Verdana,Geneva,DejaVu Sans,sans-serif" text-rendering="geometricPrecision" font-size="11">
|
|
61
|
+
<text aria-hidden="true" x="${lw / 2}" y="15" fill="#010101" fill-opacity=".3">${label}</text>
|
|
62
|
+
<text x="${lw / 2}" y="14">${label}</text>
|
|
63
|
+
<text aria-hidden="true" x="${lw + vw / 2}" y="15" fill="#010101" fill-opacity=".3">${value}</text>
|
|
64
|
+
<text x="${lw + vw / 2}" y="14">${value}</text>
|
|
65
|
+
</g>
|
|
66
|
+
</svg>`;
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Generate a simple text-based badge string for terminals.
|
|
70
|
+
*
|
|
71
|
+
* @param score - Score 0–100
|
|
72
|
+
* @param label - Label text
|
|
73
|
+
* @returns Formatted badge string like "[ judges: 85/100 ✓ ]"
|
|
74
|
+
*/
|
|
75
|
+
export function generateBadgeText(score, label = "judges") {
|
|
76
|
+
const icon = score >= 80 ? "✓" : score >= 60 ? "⚠" : "✗";
|
|
77
|
+
return `[ ${label}: ${Math.round(score)}/100 ${icon} ]`;
|
|
78
|
+
}
|
|
79
|
+
//# sourceMappingURL=badge.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"badge.js","sourceRoot":"","sources":["../../src/formatters/badge.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,oDAAoD;AACpD,mEAAmE;AACnE,EAAE;AACF,SAAS;AACT,mDAAmD;AACnD,4EAA4E;AAC5E,4EAA4E;AAC5E,iFAAiF;AAEjF;;GAEG;AACH,SAAS,UAAU,CAAC,KAAa;IAC/B,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,MAAM,CAAC,CAAC,eAAe;IAC/C,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,SAAS,CAAC,CAAC,QAAQ;IAC3C,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,SAAS,CAAC,CAAC,eAAe;IAClD,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,SAAS,CAAC,CAAC,SAAS;IAC5C,IAAI,KAAK,IAAI,EAAE;QAAE,OAAO,SAAS,CAAC,CAAC,SAAS;IAC5C,OAAO,SAAS,CAAC,CAAC,MAAM;AAC1B,CAAC;AAED;;GAEG;AACH,SAAS,SAAS,CAAC,IAAY;IAC7B,+CAA+C;IAC/C,OAAO,IAAI,CAAC,MAAM,GAAG,GAAG,GAAG,EAAE,CAAC;AAChC,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,gBAAgB,CAAC,KAAa,EAAE,KAAK,GAAG,QAAQ;IAC9D,MAAM,KAAK,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC;IAC3C,MAAM,KAAK,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC;IAChC,MAAM,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC5B,MAAM,EAAE,GAAG,SAAS,CAAC,KAAK,CAAC,CAAC;IAC5B,MAAM,UAAU,GAAG,EAAE,GAAG,EAAE,CAAC;IAE3B,OAAO,kDAAkD,UAAU,wCAAwC,KAAK,KAAK,KAAK;WACjH,KAAK,KAAK,KAAK;;;;;;mBAMP,UAAU;;;mBAGV,EAAE;eACN,EAAE,YAAY,EAAE,uBAAuB,KAAK;mBACxC,UAAU;;;kCAGK,EAAE,GAAG,CAAC,6CAA6C,KAAK;eAC3E,EAAE,GAAG,CAAC,YAAY,KAAK;kCACJ,EAAE,GAAG,EAAE,GAAG,CAAC,6CAA6C,KAAK;eAChF,EAAE,GAAG,EAAE,GAAG,CAAC,YAAY,KAAK;;OAEpC,CAAC;AACR,CAAC;AAED;;;;;;GAMG;AACH,MAAM,UAAU,iBAAiB,CAAC,KAAa,EAAE,KAAK,GAAG,QAAQ;IAC/D,MAAM,IAAI,GAAG,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,KAAK,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;IACzD,OAAO,KAAK,KAAK,KAAK,IAAI,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,IAAI,IAAI,CAAC;AAC1D,CAAC"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { TribunalVerdict } from "../types.js";
|
|
2
|
+
interface CodeClimateIssue {
|
|
3
|
+
type: "issue";
|
|
4
|
+
check_name: string;
|
|
5
|
+
description: string;
|
|
6
|
+
content: {
|
|
7
|
+
body: string;
|
|
8
|
+
};
|
|
9
|
+
categories: string[];
|
|
10
|
+
severity: string;
|
|
11
|
+
fingerprint: string;
|
|
12
|
+
location: {
|
|
13
|
+
path: string;
|
|
14
|
+
lines: {
|
|
15
|
+
begin: number;
|
|
16
|
+
end: number;
|
|
17
|
+
};
|
|
18
|
+
};
|
|
19
|
+
}
|
|
20
|
+
/**
|
|
21
|
+
* Convert a TribunalVerdict into CodeClimate / GitLab Code Quality JSON.
|
|
22
|
+
*/
|
|
23
|
+
export declare function verdictToCodeClimate(verdict: TribunalVerdict, filePath?: string): CodeClimateIssue[];
|
|
24
|
+
export {};
|
|
25
|
+
//# sourceMappingURL=codeclimate.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"codeclimate.d.ts","sourceRoot":"","sources":["../../src/formatters/codeclimate.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAAE,eAAe,EAAqB,MAAM,aAAa,CAAC;AAuBtE,UAAU,gBAAgB;IACxB,IAAI,EAAE,OAAO,CAAC;IACd,UAAU,EAAE,MAAM,CAAC;IACnB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAA;KAAE,CAAC;IAC1B,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,QAAQ,EAAE;QACR,IAAI,EAAE,MAAM,CAAC;QACb,KAAK,EAAE;YAAE,KAAK,EAAE,MAAM,CAAC;YAAC,GAAG,EAAE,MAAM,CAAA;SAAE,CAAC;KACvC,CAAC;CACH;AAkBD;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,eAAe,EAAE,QAAQ,CAAC,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAiCpG"}
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
// ─── CodeClimate JSON Formatter ──────────────────────────────────────────────
|
|
2
|
+
// Converts a TribunalVerdict into GitLab Code Quality / CodeClimate format.
|
|
3
|
+
// Compatible with GitLab CI Code Quality widget.
|
|
4
|
+
// Spec: https://docs.gitlab.com/ee/ci/testing/code_quality.html
|
|
5
|
+
// ──────────────────────────────────────────────────────────────────────────────
|
|
6
|
+
import { createHash } from "crypto";
|
|
7
|
+
/**
|
|
8
|
+
* CodeClimate issue severity mapping.
|
|
9
|
+
* CodeClimate uses: info, minor, major, critical, blocker
|
|
10
|
+
*/
|
|
11
|
+
function mapSeverity(severity) {
|
|
12
|
+
switch (severity) {
|
|
13
|
+
case "critical":
|
|
14
|
+
return "blocker";
|
|
15
|
+
case "high":
|
|
16
|
+
return "critical";
|
|
17
|
+
case "medium":
|
|
18
|
+
return "major";
|
|
19
|
+
case "low":
|
|
20
|
+
return "minor";
|
|
21
|
+
case "info":
|
|
22
|
+
return "info";
|
|
23
|
+
default:
|
|
24
|
+
return "minor";
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function findingToCategories(finding) {
|
|
28
|
+
const cats = [];
|
|
29
|
+
const rid = finding.ruleId.toUpperCase();
|
|
30
|
+
if (rid.startsWith("SEC") || rid.startsWith("AUTH") || rid.startsWith("CYBER"))
|
|
31
|
+
cats.push("Security");
|
|
32
|
+
if (rid.startsWith("PERF") || rid.startsWith("CACHE"))
|
|
33
|
+
cats.push("Performance");
|
|
34
|
+
if (rid.startsWith("ERR") || rid.startsWith("RESIL"))
|
|
35
|
+
cats.push("Bug Risk");
|
|
36
|
+
if (rid.startsWith("STYLE") || rid.startsWith("CODE") || rid.startsWith("DOC"))
|
|
37
|
+
cats.push("Style");
|
|
38
|
+
if (rid.startsWith("COMPAT") || rid.startsWith("API"))
|
|
39
|
+
cats.push("Compatibility");
|
|
40
|
+
if (rid.startsWith("COST"))
|
|
41
|
+
cats.push("Performance");
|
|
42
|
+
if (rid.startsWith("DATA") || rid.startsWith("PRIV"))
|
|
43
|
+
cats.push("Security");
|
|
44
|
+
if (cats.length === 0)
|
|
45
|
+
cats.push("Bug Risk");
|
|
46
|
+
return cats;
|
|
47
|
+
}
|
|
48
|
+
/**
|
|
49
|
+
* Convert a TribunalVerdict into CodeClimate / GitLab Code Quality JSON.
|
|
50
|
+
*/
|
|
51
|
+
export function verdictToCodeClimate(verdict, filePath) {
|
|
52
|
+
const issues = [];
|
|
53
|
+
const path = filePath || "unknown";
|
|
54
|
+
for (const evaluation of verdict.evaluations) {
|
|
55
|
+
for (const finding of evaluation.findings) {
|
|
56
|
+
const beginLine = finding.lineNumbers?.[0] ?? 1;
|
|
57
|
+
const endLine = finding.lineNumbers?.[finding.lineNumbers.length - 1] ?? beginLine;
|
|
58
|
+
// Deterministic fingerprint
|
|
59
|
+
const fingerprint = createHash("md5")
|
|
60
|
+
.update(`${finding.ruleId}:${path}:${beginLine}:${finding.title}`)
|
|
61
|
+
.digest("hex");
|
|
62
|
+
issues.push({
|
|
63
|
+
type: "issue",
|
|
64
|
+
check_name: finding.ruleId,
|
|
65
|
+
description: finding.title,
|
|
66
|
+
content: {
|
|
67
|
+
body: `${finding.description}\n\n**Recommendation:** ${finding.recommendation}${finding.reference ? `\n\n**Reference:** ${finding.reference}` : ""}`,
|
|
68
|
+
},
|
|
69
|
+
categories: findingToCategories(finding),
|
|
70
|
+
severity: mapSeverity(finding.severity),
|
|
71
|
+
fingerprint,
|
|
72
|
+
location: {
|
|
73
|
+
path,
|
|
74
|
+
lines: { begin: beginLine, end: endLine },
|
|
75
|
+
},
|
|
76
|
+
});
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
return issues;
|
|
80
|
+
}
|
|
81
|
+
//# sourceMappingURL=codeclimate.js.map
|