@kevinrabun/judges 3.40.0 → 3.42.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 +39 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +133 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/auto-calibrate.d.ts +15 -0
- package/dist/commands/auto-calibrate.d.ts.map +1 -0
- package/dist/commands/auto-calibrate.js +107 -0
- package/dist/commands/auto-calibrate.js.map +1 -0
- package/dist/commands/auto-triage.d.ts +32 -0
- package/dist/commands/auto-triage.d.ts.map +1 -0
- package/dist/commands/auto-triage.js +126 -0
- package/dist/commands/auto-triage.js.map +1 -0
- package/dist/commands/config-migrate.d.ts +44 -0
- package/dist/commands/config-migrate.d.ts.map +1 -0
- package/dist/commands/config-migrate.js +241 -0
- package/dist/commands/config-migrate.js.map +1 -0
- package/dist/commands/coverage-map.d.ts +23 -0
- package/dist/commands/coverage-map.d.ts.map +1 -0
- package/dist/commands/coverage-map.js +223 -0
- package/dist/commands/coverage-map.js.map +1 -0
- package/dist/commands/dedup-report.d.ts +13 -0
- package/dist/commands/dedup-report.d.ts.map +1 -0
- package/dist/commands/dedup-report.js +138 -0
- package/dist/commands/dedup-report.js.map +1 -0
- package/dist/commands/dep-audit.d.ts +53 -0
- package/dist/commands/dep-audit.d.ts.map +1 -0
- package/dist/commands/dep-audit.js +278 -0
- package/dist/commands/dep-audit.js.map +1 -0
- package/dist/commands/deprecated.d.ts +48 -0
- package/dist/commands/deprecated.d.ts.map +1 -0
- package/dist/commands/deprecated.js +202 -0
- package/dist/commands/deprecated.js.map +1 -0
- package/dist/commands/diff-only.d.ts +34 -0
- package/dist/commands/diff-only.d.ts.map +1 -0
- package/dist/commands/diff-only.js +152 -0
- package/dist/commands/diff-only.js.map +1 -0
- package/dist/commands/fix-pr.d.ts +23 -0
- package/dist/commands/fix-pr.d.ts.map +1 -0
- package/dist/commands/fix-pr.js +323 -0
- package/dist/commands/fix-pr.js.map +1 -0
- package/dist/commands/group-findings.d.ts +23 -0
- package/dist/commands/group-findings.d.ts.map +1 -0
- package/dist/commands/group-findings.js +155 -0
- package/dist/commands/group-findings.js.map +1 -0
- package/dist/commands/interactive-fix.d.ts +23 -0
- package/dist/commands/interactive-fix.d.ts.map +1 -0
- package/dist/commands/interactive-fix.js +140 -0
- package/dist/commands/interactive-fix.js.map +1 -0
- package/dist/commands/monorepo.d.ts +38 -0
- package/dist/commands/monorepo.d.ts.map +1 -0
- package/dist/commands/monorepo.js +233 -0
- package/dist/commands/monorepo.js.map +1 -0
- package/dist/commands/notify.d.ts +79 -0
- package/dist/commands/notify.d.ts.map +1 -0
- package/dist/commands/notify.js +325 -0
- package/dist/commands/notify.js.map +1 -0
- package/dist/commands/pr-summary.d.ts +26 -0
- package/dist/commands/pr-summary.d.ts.map +1 -0
- package/dist/commands/pr-summary.js +188 -0
- package/dist/commands/pr-summary.js.map +1 -0
- package/dist/commands/profile.d.ts +38 -0
- package/dist/commands/profile.d.ts.map +1 -0
- package/dist/commands/profile.js +102 -0
- package/dist/commands/profile.js.map +1 -0
- package/dist/commands/quality-gate.d.ts +70 -0
- package/dist/commands/quality-gate.d.ts.map +1 -0
- package/dist/commands/quality-gate.js +264 -0
- package/dist/commands/quality-gate.js.map +1 -0
- package/dist/commands/smart-select.d.ts +27 -0
- package/dist/commands/smart-select.d.ts.map +1 -0
- package/dist/commands/smart-select.js +346 -0
- package/dist/commands/smart-select.js.map +1 -0
- package/dist/commands/upload.d.ts +14 -0
- package/dist/commands/upload.d.ts.map +1 -0
- package/dist/commands/upload.js +173 -0
- package/dist/commands/upload.js.map +1 -0
- package/dist/commands/validate-config.d.ts +17 -0
- package/dist/commands/validate-config.d.ts.map +1 -0
- package/dist/commands/validate-config.js +268 -0
- package/dist/commands/validate-config.js.map +1 -0
- package/dist/commands/warm-cache.d.ts +31 -0
- package/dist/commands/warm-cache.d.ts.map +1 -0
- package/dist/commands/warm-cache.js +166 -0
- package/dist/commands/warm-cache.js.map +1 -0
- package/dist/evaluators/framework-rules.d.ts +59 -0
- package/dist/evaluators/framework-rules.d.ts.map +1 -0
- package/dist/evaluators/framework-rules.js +292 -0
- package/dist/evaluators/framework-rules.js.map +1 -0
- package/dist/parallel.d.ts +53 -0
- package/dist/parallel.d.ts.map +1 -0
- package/dist/parallel.js +170 -0
- package/dist/parallel.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,268 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Config validation — validate .judgesrc against the JSON schema
|
|
3
|
+
* and report errors with line numbers and fix suggestions.
|
|
4
|
+
*/
|
|
5
|
+
// ─── Known Fields ───────────────────────────────────────────────────────────
|
|
6
|
+
const KNOWN_TOP_FIELDS = new Set([
|
|
7
|
+
"preset",
|
|
8
|
+
"presets",
|
|
9
|
+
"severity",
|
|
10
|
+
"minSeverity",
|
|
11
|
+
"format",
|
|
12
|
+
"disabledJudges",
|
|
13
|
+
"disabledRules",
|
|
14
|
+
"ruleOverrides",
|
|
15
|
+
"parallel",
|
|
16
|
+
"concurrency",
|
|
17
|
+
"failOnFindings",
|
|
18
|
+
"summary",
|
|
19
|
+
"baseline",
|
|
20
|
+
"exclude",
|
|
21
|
+
"include",
|
|
22
|
+
"judges",
|
|
23
|
+
"notifications",
|
|
24
|
+
"qualityGate",
|
|
25
|
+
"plugins",
|
|
26
|
+
"extends",
|
|
27
|
+
"language",
|
|
28
|
+
"framework",
|
|
29
|
+
"dataAdapter",
|
|
30
|
+
"smartSelect",
|
|
31
|
+
"customRules",
|
|
32
|
+
"organizationPolicy",
|
|
33
|
+
"cache",
|
|
34
|
+
"autoFix",
|
|
35
|
+
"triage",
|
|
36
|
+
"deprecated",
|
|
37
|
+
"ignorePatterns",
|
|
38
|
+
]);
|
|
39
|
+
const KNOWN_SEVERITIES = new Set(["critical", "high", "medium", "low", "info"]);
|
|
40
|
+
const KNOWN_FORMATS = new Set([
|
|
41
|
+
"text",
|
|
42
|
+
"json",
|
|
43
|
+
"sarif",
|
|
44
|
+
"markdown",
|
|
45
|
+
"html",
|
|
46
|
+
"pdf",
|
|
47
|
+
"junit",
|
|
48
|
+
"codeclimate",
|
|
49
|
+
"github-actions",
|
|
50
|
+
]);
|
|
51
|
+
// ─── Validation Logic ───────────────────────────────────────────────────────
|
|
52
|
+
export function validateConfig(config) {
|
|
53
|
+
const errors = [];
|
|
54
|
+
const warnings = [];
|
|
55
|
+
// Check for unknown top-level fields
|
|
56
|
+
for (const key of Object.keys(config)) {
|
|
57
|
+
if (!KNOWN_TOP_FIELDS.has(key)) {
|
|
58
|
+
warnings.push({
|
|
59
|
+
path: key,
|
|
60
|
+
message: `Unknown field "${key}"`,
|
|
61
|
+
suggestion: findClosestMatch(key, KNOWN_TOP_FIELDS),
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
// Validate severity
|
|
66
|
+
if (config.minSeverity !== undefined) {
|
|
67
|
+
if (typeof config.minSeverity !== "string" || !KNOWN_SEVERITIES.has(config.minSeverity)) {
|
|
68
|
+
errors.push({
|
|
69
|
+
path: "minSeverity",
|
|
70
|
+
message: `Invalid severity "${config.minSeverity}". Must be one of: ${[...KNOWN_SEVERITIES].join(", ")}`,
|
|
71
|
+
});
|
|
72
|
+
}
|
|
73
|
+
}
|
|
74
|
+
// Validate format
|
|
75
|
+
if (config.format !== undefined) {
|
|
76
|
+
if (typeof config.format !== "string" || !KNOWN_FORMATS.has(config.format)) {
|
|
77
|
+
errors.push({
|
|
78
|
+
path: "format",
|
|
79
|
+
message: `Invalid format "${config.format}". Must be one of: ${[...KNOWN_FORMATS].join(", ")}`,
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
// Validate disabledJudges is array of strings
|
|
84
|
+
if (config.disabledJudges !== undefined) {
|
|
85
|
+
if (!Array.isArray(config.disabledJudges)) {
|
|
86
|
+
errors.push({
|
|
87
|
+
path: "disabledJudges",
|
|
88
|
+
message: "disabledJudges must be an array of strings",
|
|
89
|
+
});
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// Validate disabledRules is array of strings
|
|
93
|
+
if (config.disabledRules !== undefined) {
|
|
94
|
+
if (!Array.isArray(config.disabledRules)) {
|
|
95
|
+
errors.push({
|
|
96
|
+
path: "disabledRules",
|
|
97
|
+
message: "disabledRules must be an array of strings",
|
|
98
|
+
});
|
|
99
|
+
}
|
|
100
|
+
}
|
|
101
|
+
// Validate ruleOverrides
|
|
102
|
+
if (config.ruleOverrides !== undefined) {
|
|
103
|
+
if (typeof config.ruleOverrides !== "object" || config.ruleOverrides === null) {
|
|
104
|
+
errors.push({
|
|
105
|
+
path: "ruleOverrides",
|
|
106
|
+
message: "ruleOverrides must be an object",
|
|
107
|
+
});
|
|
108
|
+
}
|
|
109
|
+
else {
|
|
110
|
+
for (const [rule, override] of Object.entries(config.ruleOverrides)) {
|
|
111
|
+
if (typeof override === "object" && override !== null) {
|
|
112
|
+
const ov = override;
|
|
113
|
+
if (ov.severity && !KNOWN_SEVERITIES.has(ov.severity)) {
|
|
114
|
+
errors.push({
|
|
115
|
+
path: `ruleOverrides.${rule}.severity`,
|
|
116
|
+
message: `Invalid severity "${ov.severity}"`,
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
// Validate concurrency
|
|
124
|
+
if (config.concurrency !== undefined) {
|
|
125
|
+
if (typeof config.concurrency !== "number" || config.concurrency < 1) {
|
|
126
|
+
errors.push({
|
|
127
|
+
path: "concurrency",
|
|
128
|
+
message: "concurrency must be a positive number",
|
|
129
|
+
});
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
// Validate exclude/include patterns
|
|
133
|
+
for (const field of ["exclude", "include"]) {
|
|
134
|
+
if (config[field] !== undefined) {
|
|
135
|
+
if (!Array.isArray(config[field])) {
|
|
136
|
+
errors.push({
|
|
137
|
+
path: field,
|
|
138
|
+
message: `${field} must be an array of glob patterns`,
|
|
139
|
+
});
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
}
|
|
143
|
+
// Validate notifications
|
|
144
|
+
if (config.notifications !== undefined) {
|
|
145
|
+
const notifs = config.notifications;
|
|
146
|
+
if (notifs.channels && !Array.isArray(notifs.channels)) {
|
|
147
|
+
errors.push({
|
|
148
|
+
path: "notifications.channels",
|
|
149
|
+
message: "notifications.channels must be an array",
|
|
150
|
+
});
|
|
151
|
+
}
|
|
152
|
+
}
|
|
153
|
+
// Validate qualityGate
|
|
154
|
+
if (config.qualityGate !== undefined) {
|
|
155
|
+
const qg = config.qualityGate;
|
|
156
|
+
if (qg.maxFindings !== undefined && (typeof qg.maxFindings !== "number" || qg.maxFindings < 0)) {
|
|
157
|
+
errors.push({
|
|
158
|
+
path: "qualityGate.maxFindings",
|
|
159
|
+
message: "qualityGate.maxFindings must be a non-negative number",
|
|
160
|
+
});
|
|
161
|
+
}
|
|
162
|
+
if (qg.minScore !== undefined &&
|
|
163
|
+
(typeof qg.minScore !== "number" || qg.minScore < 0 || qg.minScore > 100)) {
|
|
164
|
+
errors.push({
|
|
165
|
+
path: "qualityGate.minScore",
|
|
166
|
+
message: "qualityGate.minScore must be between 0 and 100",
|
|
167
|
+
});
|
|
168
|
+
}
|
|
169
|
+
}
|
|
170
|
+
return {
|
|
171
|
+
valid: errors.length === 0,
|
|
172
|
+
errors,
|
|
173
|
+
warnings,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
function findClosestMatch(input, candidates) {
|
|
177
|
+
let best;
|
|
178
|
+
let bestDist = Infinity;
|
|
179
|
+
for (const c of candidates) {
|
|
180
|
+
const dist = levenshtein(input.toLowerCase(), c.toLowerCase());
|
|
181
|
+
if (dist < bestDist && dist <= 3) {
|
|
182
|
+
bestDist = dist;
|
|
183
|
+
best = c;
|
|
184
|
+
}
|
|
185
|
+
}
|
|
186
|
+
return best ? `Did you mean "${best}"?` : undefined;
|
|
187
|
+
}
|
|
188
|
+
function levenshtein(a, b) {
|
|
189
|
+
const m = a.length, n = b.length;
|
|
190
|
+
const dp = Array.from({ length: m + 1 }, (_, i) => Array.from({ length: n + 1 }, (_, j) => (i === 0 ? j : j === 0 ? i : 0)));
|
|
191
|
+
for (let i = 1; i <= m; i++) {
|
|
192
|
+
for (let j = 1; j <= n; j++) {
|
|
193
|
+
dp[i][j] = a[i - 1] === b[j - 1] ? dp[i - 1][j - 1] : 1 + Math.min(dp[i - 1][j], dp[i][j - 1], dp[i - 1][j - 1]);
|
|
194
|
+
}
|
|
195
|
+
}
|
|
196
|
+
return dp[m][n];
|
|
197
|
+
}
|
|
198
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
199
|
+
export function runValidateConfig(argv) {
|
|
200
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
201
|
+
console.log(`
|
|
202
|
+
judges validate-config — Validate .judgesrc configuration
|
|
203
|
+
|
|
204
|
+
Usage:
|
|
205
|
+
judges validate-config Validate .judgesrc in current directory
|
|
206
|
+
judges validate-config --config path/to/.judgesrc Validate specific file
|
|
207
|
+
|
|
208
|
+
Options:
|
|
209
|
+
--config <path> Config file to validate (default: .judgesrc)
|
|
210
|
+
--format json JSON output
|
|
211
|
+
--strict Treat warnings as errors
|
|
212
|
+
--help, -h Show this help
|
|
213
|
+
`);
|
|
214
|
+
return;
|
|
215
|
+
}
|
|
216
|
+
const { readFileSync, existsSync } = require("fs");
|
|
217
|
+
const { resolve } = require("path");
|
|
218
|
+
const configPath = argv.find((_a, i) => argv[i - 1] === "--config") || ".judgesrc";
|
|
219
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
220
|
+
const strict = argv.includes("--strict");
|
|
221
|
+
const resolved = resolve(configPath);
|
|
222
|
+
if (!existsSync(resolved)) {
|
|
223
|
+
console.error(`Error: config file not found: ${resolved}`);
|
|
224
|
+
process.exit(1);
|
|
225
|
+
}
|
|
226
|
+
let config;
|
|
227
|
+
try {
|
|
228
|
+
config = JSON.parse(readFileSync(resolved, "utf-8"));
|
|
229
|
+
}
|
|
230
|
+
catch (e) {
|
|
231
|
+
console.error(`Error: invalid JSON in ${resolved}: ${e instanceof Error ? e.message : e}`);
|
|
232
|
+
process.exit(1);
|
|
233
|
+
}
|
|
234
|
+
const result = validateConfig(config);
|
|
235
|
+
if (strict && result.warnings.length > 0) {
|
|
236
|
+
result.valid = false;
|
|
237
|
+
result.errors.push(...result.warnings);
|
|
238
|
+
}
|
|
239
|
+
if (format === "json") {
|
|
240
|
+
console.log(JSON.stringify(result, null, 2));
|
|
241
|
+
process.exit(result.valid ? 0 : 1);
|
|
242
|
+
}
|
|
243
|
+
if (result.valid && result.warnings.length === 0) {
|
|
244
|
+
console.log(`\n ✅ Config is valid: ${resolved}\n`);
|
|
245
|
+
return;
|
|
246
|
+
}
|
|
247
|
+
console.log(`\n Config Validation: ${resolved}\n`);
|
|
248
|
+
if (result.errors.length > 0) {
|
|
249
|
+
console.log(` ❌ Errors (${result.errors.length}):`);
|
|
250
|
+
for (const e of result.errors) {
|
|
251
|
+
console.log(` ${e.path}: ${e.message}`);
|
|
252
|
+
if (e.suggestion)
|
|
253
|
+
console.log(` 💡 ${e.suggestion}`);
|
|
254
|
+
}
|
|
255
|
+
console.log("");
|
|
256
|
+
}
|
|
257
|
+
if (result.warnings.length > 0) {
|
|
258
|
+
console.log(` ⚠️ Warnings (${result.warnings.length}):`);
|
|
259
|
+
for (const w of result.warnings) {
|
|
260
|
+
console.log(` ${w.path}: ${w.message}`);
|
|
261
|
+
if (w.suggestion)
|
|
262
|
+
console.log(` 💡 ${w.suggestion}`);
|
|
263
|
+
}
|
|
264
|
+
console.log("");
|
|
265
|
+
}
|
|
266
|
+
process.exit(result.valid ? 0 : 1);
|
|
267
|
+
}
|
|
268
|
+
//# sourceMappingURL=validate-config.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"validate-config.js","sourceRoot":"","sources":["../../src/commands/validate-config.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Eval cache warming — pre-populate the evaluation cache with
|
|
3
|
+
* common patterns so CI runs start warm and skip known-good files.
|
|
4
|
+
*
|
|
5
|
+
* Works with the existing disk-cache system: scans the project,
|
|
6
|
+
* evaluates files, and stores results. Subsequent CI runs check
|
|
7
|
+
* the cache first and skip files whose hash hasn't changed.
|
|
8
|
+
*/
|
|
9
|
+
export interface WarmingResult {
|
|
10
|
+
filesScanned: number;
|
|
11
|
+
filesCached: number;
|
|
12
|
+
filesSkipped: number;
|
|
13
|
+
durationMs: number;
|
|
14
|
+
cacheDir: string;
|
|
15
|
+
}
|
|
16
|
+
export interface WarmingOptions {
|
|
17
|
+
/** Root directory to scan */
|
|
18
|
+
root: string;
|
|
19
|
+
/** File extensions to include */
|
|
20
|
+
extensions: string[];
|
|
21
|
+
/** Glob patterns to exclude */
|
|
22
|
+
exclude: string[];
|
|
23
|
+
/** Maximum files to warm */
|
|
24
|
+
maxFiles: number;
|
|
25
|
+
/** Cache directory */
|
|
26
|
+
cacheDir?: string;
|
|
27
|
+
}
|
|
28
|
+
export declare function computeFileHash(content: string): string;
|
|
29
|
+
export declare function warmCache(options?: Partial<WarmingOptions>): Promise<WarmingResult>;
|
|
30
|
+
export declare function runWarmCache(argv: string[]): Promise<void>;
|
|
31
|
+
//# sourceMappingURL=warm-cache.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"warm-cache.d.ts","sourceRoot":"","sources":["../../src/commands/warm-cache.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH,MAAM,WAAW,aAAa;IAC5B,YAAY,EAAE,MAAM,CAAC;IACrB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;CAClB;AAED,MAAM,WAAW,cAAc;IAC7B,6BAA6B;IAC7B,IAAI,EAAE,MAAM,CAAC;IACb,iCAAiC;IACjC,UAAU,EAAE,MAAM,EAAE,CAAC;IACrB,+BAA+B;IAC/B,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,4BAA4B;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,sBAAsB;IACtB,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAID,wBAAgB,eAAe,CAAC,OAAO,EAAE,MAAM,GAAG,MAAM,CAEvD;AAsCD,wBAAsB,SAAS,CAAC,OAAO,GAAE,OAAO,CAAC,cAAc,CAAM,GAAG,OAAO,CAAC,aAAa,CAAC,CAmF7F;AAID,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CA8ChE"}
|
|
@@ -0,0 +1,166 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Eval cache warming — pre-populate the evaluation cache with
|
|
3
|
+
* common patterns so CI runs start warm and skip known-good files.
|
|
4
|
+
*
|
|
5
|
+
* Works with the existing disk-cache system: scans the project,
|
|
6
|
+
* evaluates files, and stores results. Subsequent CI runs check
|
|
7
|
+
* the cache first and skip files whose hash hasn't changed.
|
|
8
|
+
*/
|
|
9
|
+
import { createHash } from "crypto";
|
|
10
|
+
import { DiskCache } from "../disk-cache.js";
|
|
11
|
+
// ─── Hash Computation ───────────────────────────────────────────────────────
|
|
12
|
+
export function computeFileHash(content) {
|
|
13
|
+
return createHash("sha256").update(content).digest("hex").slice(0, 16);
|
|
14
|
+
}
|
|
15
|
+
// ─── Cache Warming Logic ────────────────────────────────────────────────────
|
|
16
|
+
const DEFAULT_EXTENSIONS = [
|
|
17
|
+
".ts",
|
|
18
|
+
".tsx",
|
|
19
|
+
".js",
|
|
20
|
+
".jsx",
|
|
21
|
+
".py",
|
|
22
|
+
".go",
|
|
23
|
+
".rs",
|
|
24
|
+
".java",
|
|
25
|
+
".cs",
|
|
26
|
+
".rb",
|
|
27
|
+
".php",
|
|
28
|
+
".kt",
|
|
29
|
+
".scala",
|
|
30
|
+
".swift",
|
|
31
|
+
".c",
|
|
32
|
+
".cpp",
|
|
33
|
+
".h",
|
|
34
|
+
".hpp",
|
|
35
|
+
];
|
|
36
|
+
const DEFAULT_EXCLUDE = [
|
|
37
|
+
"node_modules",
|
|
38
|
+
"dist",
|
|
39
|
+
"build",
|
|
40
|
+
".git",
|
|
41
|
+
"__pycache__",
|
|
42
|
+
"vendor",
|
|
43
|
+
"target",
|
|
44
|
+
".next",
|
|
45
|
+
".nuxt",
|
|
46
|
+
"coverage",
|
|
47
|
+
];
|
|
48
|
+
export async function warmCache(options = {}) {
|
|
49
|
+
const { readdirSync, readFileSync, statSync } = await import("fs");
|
|
50
|
+
const { join, extname } = await import("path");
|
|
51
|
+
const root = options.root || process.cwd();
|
|
52
|
+
const extensions = new Set(options.extensions || DEFAULT_EXTENSIONS);
|
|
53
|
+
const excludeDirs = new Set(options.exclude || DEFAULT_EXCLUDE);
|
|
54
|
+
const maxFiles = options.maxFiles || 500;
|
|
55
|
+
const cache = new DiskCache({ cacheDir: options.cacheDir });
|
|
56
|
+
const cacheDir = options.cacheDir || process.env.JUDGES_CACHE_DIR || ".judges-cache";
|
|
57
|
+
const start = performance.now();
|
|
58
|
+
let filesScanned = 0;
|
|
59
|
+
let filesCached = 0;
|
|
60
|
+
let filesSkipped = 0;
|
|
61
|
+
function walkDir(dir) {
|
|
62
|
+
if (filesScanned >= maxFiles)
|
|
63
|
+
return;
|
|
64
|
+
let entries;
|
|
65
|
+
try {
|
|
66
|
+
entries = readdirSync(dir, { withFileTypes: true });
|
|
67
|
+
}
|
|
68
|
+
catch {
|
|
69
|
+
return;
|
|
70
|
+
}
|
|
71
|
+
for (const entry of entries) {
|
|
72
|
+
if (filesScanned >= maxFiles)
|
|
73
|
+
break;
|
|
74
|
+
if (entry.isDirectory()) {
|
|
75
|
+
if (!excludeDirs.has(entry.name) && !entry.name.startsWith(".")) {
|
|
76
|
+
walkDir(join(dir, entry.name));
|
|
77
|
+
}
|
|
78
|
+
continue;
|
|
79
|
+
}
|
|
80
|
+
const ext = extname(entry.name).toLowerCase();
|
|
81
|
+
if (!extensions.has(ext))
|
|
82
|
+
continue;
|
|
83
|
+
const filePath = join(dir, entry.name);
|
|
84
|
+
filesScanned++;
|
|
85
|
+
try {
|
|
86
|
+
const content = readFileSync(filePath, "utf-8");
|
|
87
|
+
const hash = computeFileHash(content);
|
|
88
|
+
const cacheKey = `warm:${filePath}:${hash}`;
|
|
89
|
+
// Check if already cached
|
|
90
|
+
const existing = cache.get(cacheKey);
|
|
91
|
+
if (existing) {
|
|
92
|
+
filesSkipped++;
|
|
93
|
+
continue;
|
|
94
|
+
}
|
|
95
|
+
// Store a warming marker — actual eval results will be populated
|
|
96
|
+
// on first real evaluation when the hash matches
|
|
97
|
+
const stat = statSync(filePath);
|
|
98
|
+
cache.set(cacheKey, JSON.stringify({
|
|
99
|
+
warmed: true,
|
|
100
|
+
hash,
|
|
101
|
+
size: stat.size,
|
|
102
|
+
timestamp: new Date().toISOString(),
|
|
103
|
+
}));
|
|
104
|
+
filesCached++;
|
|
105
|
+
}
|
|
106
|
+
catch {
|
|
107
|
+
// Skip files that can't be read
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
walkDir(root);
|
|
112
|
+
return {
|
|
113
|
+
filesScanned,
|
|
114
|
+
filesCached,
|
|
115
|
+
filesSkipped,
|
|
116
|
+
durationMs: Math.round(performance.now() - start),
|
|
117
|
+
cacheDir,
|
|
118
|
+
};
|
|
119
|
+
}
|
|
120
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
121
|
+
export async function runWarmCache(argv) {
|
|
122
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
123
|
+
console.log(`
|
|
124
|
+
judges warm-cache — Pre-populate evaluation cache for faster CI
|
|
125
|
+
|
|
126
|
+
Usage:
|
|
127
|
+
judges warm-cache Warm cache for current directory
|
|
128
|
+
judges warm-cache --root src/ Warm specific directory
|
|
129
|
+
judges warm-cache --max 200 Limit files to warm
|
|
130
|
+
|
|
131
|
+
Options:
|
|
132
|
+
--root <dir> Root directory to scan (default: .)
|
|
133
|
+
--max <n> Max files to warm (default: 500)
|
|
134
|
+
--extensions <list> Comma-separated extensions (default: .ts,.js,.py,.go,...)
|
|
135
|
+
--format json JSON output
|
|
136
|
+
--help, -h Show this help
|
|
137
|
+
|
|
138
|
+
Pre-populates the disk cache with file hashes. Subsequent evaluations
|
|
139
|
+
skip files whose content hasn't changed, dramatically speeding up CI.
|
|
140
|
+
`);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
144
|
+
const root = argv.find((_a, i) => argv[i - 1] === "--root");
|
|
145
|
+
const maxStr = argv.find((_a, i) => argv[i - 1] === "--max");
|
|
146
|
+
const extStr = argv.find((_a, i) => argv[i - 1] === "--extensions");
|
|
147
|
+
const options = {};
|
|
148
|
+
if (root)
|
|
149
|
+
options.root = root;
|
|
150
|
+
if (maxStr)
|
|
151
|
+
options.maxFiles = parseInt(maxStr, 10);
|
|
152
|
+
if (extStr)
|
|
153
|
+
options.extensions = extStr.split(",").map((s) => s.trim());
|
|
154
|
+
const result = await warmCache(options);
|
|
155
|
+
if (format === "json") {
|
|
156
|
+
console.log(JSON.stringify(result, null, 2));
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
console.log(`\n Cache Warming Results\n`);
|
|
160
|
+
console.log(` Files scanned: ${result.filesScanned}`);
|
|
161
|
+
console.log(` Newly cached: ${result.filesCached}`);
|
|
162
|
+
console.log(` Already warm: ${result.filesSkipped}`);
|
|
163
|
+
console.log(` Duration: ${result.durationMs}ms`);
|
|
164
|
+
console.log(` Cache dir: ${result.cacheDir}\n`);
|
|
165
|
+
}
|
|
166
|
+
//# sourceMappingURL=warm-cache.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"warm-cache.js","sourceRoot":"","sources":["../../src/commands/warm-cache.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,59 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Framework-aware detection module.
|
|
3
|
+
*
|
|
4
|
+
* Detects which framework(s) are in use and provides framework-specific
|
|
5
|
+
* pattern adjustments to reduce false positives. For example:
|
|
6
|
+
* - React: hooks ordering rules, JSX injection awareness
|
|
7
|
+
* - Express/Fastify: middleware chain analysis
|
|
8
|
+
* - Django: ORM injection patterns
|
|
9
|
+
* - Spring: security annotation awareness
|
|
10
|
+
* - Next.js: server-component vs client-component context
|
|
11
|
+
*
|
|
12
|
+
* This module is used by evaluators to adjust their confidence scores
|
|
13
|
+
* and disable irrelevant rules based on framework context.
|
|
14
|
+
*/
|
|
15
|
+
import type { Finding, Severity } from "../types.js";
|
|
16
|
+
export type FrameworkId = "react" | "nextjs" | "angular" | "vue" | "express" | "fastify" | "nestjs" | "django" | "flask" | "fastapi" | "spring" | "rails" | "actix" | "gin" | "echo";
|
|
17
|
+
export interface FrameworkProfile {
|
|
18
|
+
/** Framework identifier */
|
|
19
|
+
id: FrameworkId;
|
|
20
|
+
/** Human-readable name */
|
|
21
|
+
name: string;
|
|
22
|
+
/** Languages this framework applies to */
|
|
23
|
+
languages: string[];
|
|
24
|
+
/** Import/require patterns that identify this framework */
|
|
25
|
+
detectPatterns: RegExp[];
|
|
26
|
+
/** Rule IDs that are typically false positives in this framework */
|
|
27
|
+
fpProne: string[];
|
|
28
|
+
/** Rules whose severity should be adjusted in this framework context */
|
|
29
|
+
severityAdjustments: Array<{
|
|
30
|
+
rulePattern: string;
|
|
31
|
+
adjustment: "downgrade" | "upgrade";
|
|
32
|
+
reason: string;
|
|
33
|
+
}>;
|
|
34
|
+
/** Additional patterns to check for framework-specific issues */
|
|
35
|
+
frameworkRules: Array<{
|
|
36
|
+
id: string;
|
|
37
|
+
pattern: RegExp;
|
|
38
|
+
severity: Severity;
|
|
39
|
+
title: string;
|
|
40
|
+
description: string;
|
|
41
|
+
}>;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Detect which frameworks are present in the given code.
|
|
45
|
+
*/
|
|
46
|
+
export declare function detectFrameworks(code: string, language: string): FrameworkProfile[];
|
|
47
|
+
/**
|
|
48
|
+
* Adjust findings based on detected framework context.
|
|
49
|
+
* - Downgrades severity for FP-prone rules in the framework
|
|
50
|
+
* - Applies framework-specific severity adjustments
|
|
51
|
+
* - Tags adjusted findings with provenance
|
|
52
|
+
*/
|
|
53
|
+
export declare function adjustFindingsForFramework(findings: Finding[], frameworks: FrameworkProfile[]): Finding[];
|
|
54
|
+
/**
|
|
55
|
+
* Run framework-specific rules against code.
|
|
56
|
+
* Returns additional findings from framework-aware patterns.
|
|
57
|
+
*/
|
|
58
|
+
export declare function evaluateFrameworkRules(code: string, language: string): Finding[];
|
|
59
|
+
//# sourceMappingURL=framework-rules.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"framework-rules.d.ts","sourceRoot":"","sources":["../../src/evaluators/framework-rules.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;GAaG;AAEH,OAAO,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,aAAa,CAAC;AAIrD,MAAM,MAAM,WAAW,GACnB,OAAO,GACP,QAAQ,GACR,SAAS,GACT,KAAK,GACL,SAAS,GACT,SAAS,GACT,QAAQ,GACR,QAAQ,GACR,OAAO,GACP,SAAS,GACT,QAAQ,GACR,OAAO,GACP,OAAO,GACP,KAAK,GACL,MAAM,CAAC;AAEX,MAAM,WAAW,gBAAgB;IAC/B,2BAA2B;IAC3B,EAAE,EAAE,WAAW,CAAC;IAChB,0BAA0B;IAC1B,IAAI,EAAE,MAAM,CAAC;IACb,0CAA0C;IAC1C,SAAS,EAAE,MAAM,EAAE,CAAC;IACpB,2DAA2D;IAC3D,cAAc,EAAE,MAAM,EAAE,CAAC;IACzB,oEAAoE;IACpE,OAAO,EAAE,MAAM,EAAE,CAAC;IAClB,wEAAwE;IACxE,mBAAmB,EAAE,KAAK,CAAC;QACzB,WAAW,EAAE,MAAM,CAAC;QACpB,UAAU,EAAE,WAAW,GAAG,SAAS,CAAC;QACpC,MAAM,EAAE,MAAM,CAAC;KAChB,CAAC,CAAC;IACH,iEAAiE;IACjE,cAAc,EAAE,KAAK,CAAC;QACpB,EAAE,EAAE,MAAM,CAAC;QACX,OAAO,EAAE,MAAM,CAAC;QAChB,QAAQ,EAAE,QAAQ,CAAC;QACnB,KAAK,EAAE,MAAM,CAAC;QACd,WAAW,EAAE,MAAM,CAAC;KACrB,CAAC,CAAC;CACJ;AA0MD;;GAEG;AACH,wBAAgB,gBAAgB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,gBAAgB,EAAE,CAKnF;AAOD;;;;;GAKG;AACH,wBAAgB,0BAA0B,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,UAAU,EAAE,gBAAgB,EAAE,GAAG,OAAO,EAAE,CAqCzG;AAID;;;GAGG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,EAAE,CAwBhF"}
|