@kevinrabun/judges 3.46.0 → 3.48.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/adoption-report.d.ts +8 -0
- package/dist/commands/adoption-report.d.ts.map +1 -0
- package/dist/commands/adoption-report.js +219 -0
- package/dist/commands/adoption-report.js.map +1 -0
- package/dist/commands/ai-model-trust.d.ts +17 -0
- package/dist/commands/ai-model-trust.d.ts.map +1 -0
- package/dist/commands/ai-model-trust.js +235 -0
- package/dist/commands/ai-model-trust.js.map +1 -0
- package/dist/commands/ai-prompt-audit.d.ts +23 -0
- package/dist/commands/ai-prompt-audit.d.ts.map +1 -0
- package/dist/commands/ai-prompt-audit.js +255 -0
- package/dist/commands/ai-prompt-audit.js.map +1 -0
- package/dist/commands/audit-trail.d.ts +18 -0
- package/dist/commands/audit-trail.d.ts.map +1 -0
- package/dist/commands/audit-trail.js +155 -0
- package/dist/commands/audit-trail.js.map +1 -0
- package/dist/commands/auto-fix.d.ts +18 -0
- package/dist/commands/auto-fix.d.ts.map +1 -0
- package/dist/commands/auto-fix.js +241 -0
- package/dist/commands/auto-fix.js.map +1 -0
- package/dist/commands/code-owner-suggest.d.ts +17 -0
- package/dist/commands/code-owner-suggest.d.ts.map +1 -0
- package/dist/commands/code-owner-suggest.js +215 -0
- package/dist/commands/code-owner-suggest.js.map +1 -0
- package/dist/commands/cost-forecast.d.ts +19 -0
- package/dist/commands/cost-forecast.d.ts.map +1 -0
- package/dist/commands/cost-forecast.js +194 -0
- package/dist/commands/cost-forecast.js.map +1 -0
- package/dist/commands/dep-correlate.d.ts +9 -0
- package/dist/commands/dep-correlate.d.ts.map +1 -0
- package/dist/commands/dep-correlate.js +208 -0
- package/dist/commands/dep-correlate.js.map +1 -0
- package/dist/commands/doc-gen.d.ts +8 -0
- package/dist/commands/doc-gen.d.ts.map +1 -0
- package/dist/commands/doc-gen.js +209 -0
- package/dist/commands/doc-gen.js.map +1 -0
- package/dist/commands/judge-author.d.ts +8 -0
- package/dist/commands/judge-author.d.ts.map +1 -0
- package/dist/commands/judge-author.js +261 -0
- package/dist/commands/judge-author.js.map +1 -0
- package/dist/commands/pattern-registry.d.ts +23 -0
- package/dist/commands/pattern-registry.d.ts.map +1 -0
- package/dist/commands/pattern-registry.js +227 -0
- package/dist/commands/pattern-registry.js.map +1 -0
- package/dist/commands/perf-hotspot.d.ts +8 -0
- package/dist/commands/perf-hotspot.d.ts.map +1 -0
- package/dist/commands/perf-hotspot.js +274 -0
- package/dist/commands/perf-hotspot.js.map +1 -0
- package/dist/commands/pr-quality-gate.d.ts +29 -0
- package/dist/commands/pr-quality-gate.d.ts.map +1 -0
- package/dist/commands/pr-quality-gate.js +208 -0
- package/dist/commands/pr-quality-gate.js.map +1 -0
- package/dist/commands/security-maturity.d.ts +8 -0
- package/dist/commands/security-maturity.d.ts.map +1 -0
- package/dist/commands/security-maturity.js +313 -0
- package/dist/commands/security-maturity.js.map +1 -0
- package/dist/commands/team-leaderboard.d.ts +25 -0
- package/dist/commands/team-leaderboard.d.ts.map +1 -0
- package/dist/commands/team-leaderboard.js +228 -0
- package/dist/commands/team-leaderboard.js.map +1 -0
- package/dist/commands/team-rules-sync.d.ts +8 -0
- package/dist/commands/team-rules-sync.d.ts.map +1 -0
- package/dist/commands/team-rules-sync.js +251 -0
- package/dist/commands/team-rules-sync.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,241 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Auto-fix — generates safe, automated fix suggestions for
|
|
3
|
+
* common finding patterns. All processing is local.
|
|
4
|
+
*/
|
|
5
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
6
|
+
import { join } from "path";
|
|
7
|
+
const FIX_DIR = ".judges-auto-fix";
|
|
8
|
+
const FIX_FILE = join(FIX_DIR, "fix-history.json");
|
|
9
|
+
// ─── Fix template library ───────────────────────────────────────────────────
|
|
10
|
+
const FIX_TEMPLATES = [
|
|
11
|
+
{
|
|
12
|
+
rulePattern: "SQL-",
|
|
13
|
+
title: "Use parameterized queries",
|
|
14
|
+
description: "Replace string concatenation in SQL with parameterized queries",
|
|
15
|
+
before: 'db.query("SELECT * FROM users WHERE id = " + userId)',
|
|
16
|
+
after: 'db.query("SELECT * FROM users WHERE id = $1", [userId])',
|
|
17
|
+
language: "typescript",
|
|
18
|
+
},
|
|
19
|
+
{
|
|
20
|
+
rulePattern: "XSS-",
|
|
21
|
+
title: "Use textContent instead of innerHTML",
|
|
22
|
+
description: "Replace innerHTML with textContent to prevent XSS",
|
|
23
|
+
before: "element.innerHTML = userInput",
|
|
24
|
+
after: "element.textContent = userInput",
|
|
25
|
+
language: "typescript",
|
|
26
|
+
},
|
|
27
|
+
{
|
|
28
|
+
rulePattern: "CMD-",
|
|
29
|
+
title: "Use execFile with argument array",
|
|
30
|
+
description: "Replace exec with execFile and separate arguments",
|
|
31
|
+
before: 'exec("git " + command)',
|
|
32
|
+
after: 'execFile("git", [command])',
|
|
33
|
+
language: "typescript",
|
|
34
|
+
},
|
|
35
|
+
{
|
|
36
|
+
rulePattern: "CRYPTO-",
|
|
37
|
+
title: "Replace MD5 with SHA-256",
|
|
38
|
+
description: "Use cryptographically secure hash function",
|
|
39
|
+
before: "crypto.createHash('md5').update(data).digest('hex')",
|
|
40
|
+
after: "crypto.createHash('sha256').update(data).digest('hex')",
|
|
41
|
+
language: "typescript",
|
|
42
|
+
},
|
|
43
|
+
{
|
|
44
|
+
rulePattern: "AUTH-",
|
|
45
|
+
title: "Add bcrypt password hashing",
|
|
46
|
+
description: "Hash passwords with bcrypt instead of plaintext storage",
|
|
47
|
+
before: "user.password = password",
|
|
48
|
+
after: "user.password = await bcrypt.hash(password, 12)",
|
|
49
|
+
language: "typescript",
|
|
50
|
+
},
|
|
51
|
+
{
|
|
52
|
+
rulePattern: "SEC-",
|
|
53
|
+
title: "Validate input before use",
|
|
54
|
+
description: "Add input validation before processing user data",
|
|
55
|
+
before: "const data = req.body",
|
|
56
|
+
after: "const data = validateInput(req.body, schema)",
|
|
57
|
+
language: "typescript",
|
|
58
|
+
},
|
|
59
|
+
{
|
|
60
|
+
rulePattern: "SSRF-",
|
|
61
|
+
title: "Validate URL against allowlist",
|
|
62
|
+
description: "Check URL against trusted domains before requesting",
|
|
63
|
+
before: "await fetch(userUrl)",
|
|
64
|
+
after: "if (isAllowedUrl(userUrl)) await fetch(userUrl)",
|
|
65
|
+
language: "typescript",
|
|
66
|
+
},
|
|
67
|
+
{
|
|
68
|
+
rulePattern: "PATH-",
|
|
69
|
+
title: "Sanitize file path",
|
|
70
|
+
description: "Resolve and validate file path within allowed directory",
|
|
71
|
+
before: 'readFileSync(userPath, "utf-8")',
|
|
72
|
+
after: 'readFileSync(path.resolve(SAFE_DIR, path.basename(userPath)), "utf-8")',
|
|
73
|
+
language: "typescript",
|
|
74
|
+
},
|
|
75
|
+
{
|
|
76
|
+
rulePattern: "ERR-",
|
|
77
|
+
title: "Use safe error response",
|
|
78
|
+
description: "Return generic error message instead of stack trace",
|
|
79
|
+
before: "res.status(500).json({ error: err.stack })",
|
|
80
|
+
after: 'res.status(500).json({ error: "Internal server error" })',
|
|
81
|
+
language: "typescript",
|
|
82
|
+
},
|
|
83
|
+
{
|
|
84
|
+
rulePattern: "CORS-",
|
|
85
|
+
title: "Restrict CORS origins",
|
|
86
|
+
description: "Replace wildcard CORS with specific trusted origins",
|
|
87
|
+
before: 'cors({ origin: "*" })',
|
|
88
|
+
after: 'cors({ origin: ["https://app.example.com"] })',
|
|
89
|
+
language: "typescript",
|
|
90
|
+
},
|
|
91
|
+
];
|
|
92
|
+
// ─── Core ───────────────────────────────────────────────────────────────────
|
|
93
|
+
function ensureDir() {
|
|
94
|
+
if (!existsSync(FIX_DIR))
|
|
95
|
+
mkdirSync(FIX_DIR, { recursive: true });
|
|
96
|
+
}
|
|
97
|
+
function loadStore() {
|
|
98
|
+
if (!existsSync(FIX_FILE))
|
|
99
|
+
return { suggestions: [], applied: 0, updatedAt: new Date().toISOString() };
|
|
100
|
+
try {
|
|
101
|
+
return JSON.parse(readFileSync(FIX_FILE, "utf-8"));
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return { suggestions: [], applied: 0, updatedAt: new Date().toISOString() };
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
function saveStore(store) {
|
|
108
|
+
ensureDir();
|
|
109
|
+
store.updatedAt = new Date().toISOString();
|
|
110
|
+
writeFileSync(FIX_FILE, JSON.stringify(store, null, 2));
|
|
111
|
+
}
|
|
112
|
+
export function suggestFix(ruleId, file, line) {
|
|
113
|
+
const template = FIX_TEMPLATES.find((t) => ruleId.startsWith(t.rulePattern));
|
|
114
|
+
if (!template)
|
|
115
|
+
return null;
|
|
116
|
+
const suggestion = {
|
|
117
|
+
ruleId,
|
|
118
|
+
title: template.title,
|
|
119
|
+
file,
|
|
120
|
+
line,
|
|
121
|
+
before: template.before,
|
|
122
|
+
after: template.after,
|
|
123
|
+
confidence: 75,
|
|
124
|
+
timestamp: new Date().toISOString(),
|
|
125
|
+
};
|
|
126
|
+
const store = loadStore();
|
|
127
|
+
store.suggestions.push(suggestion);
|
|
128
|
+
if (store.suggestions.length > 500)
|
|
129
|
+
store.suggestions = store.suggestions.slice(-500);
|
|
130
|
+
saveStore(store);
|
|
131
|
+
return suggestion;
|
|
132
|
+
}
|
|
133
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
134
|
+
export function runAutoFix(argv) {
|
|
135
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
136
|
+
console.log(`
|
|
137
|
+
judges auto-fix — Automated fix suggestions for findings
|
|
138
|
+
|
|
139
|
+
Usage:
|
|
140
|
+
judges auto-fix --rule SQL-001 --file src/db.ts --line 42
|
|
141
|
+
judges auto-fix --catalog
|
|
142
|
+
judges auto-fix --history
|
|
143
|
+
judges auto-fix --stats
|
|
144
|
+
|
|
145
|
+
Options:
|
|
146
|
+
--rule <id> Rule ID to generate fix for
|
|
147
|
+
--file <path> File containing the finding
|
|
148
|
+
--line <n> Line number of the finding
|
|
149
|
+
--catalog Show all available fix templates
|
|
150
|
+
--history Show past fix suggestions
|
|
151
|
+
--stats Show fix statistics
|
|
152
|
+
--format json JSON output
|
|
153
|
+
--help, -h Show this help
|
|
154
|
+
`);
|
|
155
|
+
return;
|
|
156
|
+
}
|
|
157
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
158
|
+
// Catalog
|
|
159
|
+
if (argv.includes("--catalog")) {
|
|
160
|
+
if (format === "json") {
|
|
161
|
+
console.log(JSON.stringify(FIX_TEMPLATES, null, 2));
|
|
162
|
+
}
|
|
163
|
+
else {
|
|
164
|
+
console.log(`\n Fix Template Catalog (${FIX_TEMPLATES.length})\n ──────────────────────────`);
|
|
165
|
+
for (const t of FIX_TEMPLATES) {
|
|
166
|
+
console.log(` [${t.rulePattern.padEnd(8)}] ${t.title}`);
|
|
167
|
+
console.log(` Before: ${t.before}`);
|
|
168
|
+
console.log(` After: ${t.after}`);
|
|
169
|
+
console.log("");
|
|
170
|
+
}
|
|
171
|
+
}
|
|
172
|
+
return;
|
|
173
|
+
}
|
|
174
|
+
// History
|
|
175
|
+
if (argv.includes("--history")) {
|
|
176
|
+
const store = loadStore();
|
|
177
|
+
if (format === "json") {
|
|
178
|
+
console.log(JSON.stringify(store.suggestions.slice(-20), null, 2));
|
|
179
|
+
}
|
|
180
|
+
else {
|
|
181
|
+
console.log(`\n Fix History (${store.suggestions.length} suggestions)\n ──────────────────────────`);
|
|
182
|
+
for (const s of store.suggestions.slice(-15)) {
|
|
183
|
+
console.log(` ${s.timestamp.slice(0, 16)} ${s.ruleId.padEnd(10)} ${s.title} ${s.file}:${s.line}`);
|
|
184
|
+
}
|
|
185
|
+
console.log("");
|
|
186
|
+
}
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
// Stats
|
|
190
|
+
if (argv.includes("--stats")) {
|
|
191
|
+
const store = loadStore();
|
|
192
|
+
const byRule = new Map();
|
|
193
|
+
for (const s of store.suggestions) {
|
|
194
|
+
const prefix = s.ruleId.split("-")[0] + "-";
|
|
195
|
+
byRule.set(prefix, (byRule.get(prefix) || 0) + 1);
|
|
196
|
+
}
|
|
197
|
+
if (format === "json") {
|
|
198
|
+
console.log(JSON.stringify({ total: store.suggestions.length, applied: store.applied, byRule: Object.fromEntries(byRule) }, null, 2));
|
|
199
|
+
}
|
|
200
|
+
else {
|
|
201
|
+
console.log(`\n Fix Statistics\n ──────────────────────────`);
|
|
202
|
+
console.log(` Total suggestions: ${store.suggestions.length}`);
|
|
203
|
+
console.log(` Applied: ${store.applied}`);
|
|
204
|
+
if (byRule.size > 0) {
|
|
205
|
+
console.log(`\n By category:`);
|
|
206
|
+
for (const [rule, count] of byRule) {
|
|
207
|
+
console.log(` ${rule.padEnd(10)} ${count} suggestions`);
|
|
208
|
+
}
|
|
209
|
+
}
|
|
210
|
+
console.log("");
|
|
211
|
+
}
|
|
212
|
+
return;
|
|
213
|
+
}
|
|
214
|
+
// Suggest fix
|
|
215
|
+
const ruleId = argv.find((_a, i) => argv[i - 1] === "--rule");
|
|
216
|
+
const file = argv.find((_a, i) => argv[i - 1] === "--file");
|
|
217
|
+
const line = parseInt(argv.find((_a, i) => argv[i - 1] === "--line") || "1", 10);
|
|
218
|
+
if (!ruleId) {
|
|
219
|
+
console.error(" Use --rule <id>, --catalog, --history, or --stats. --help for usage.");
|
|
220
|
+
return;
|
|
221
|
+
}
|
|
222
|
+
const suggestion = suggestFix(ruleId, file || "unknown", line);
|
|
223
|
+
if (!suggestion) {
|
|
224
|
+
console.log(` No fix template for rule: ${ruleId}`);
|
|
225
|
+
console.log(` Available patterns: ${FIX_TEMPLATES.map((t) => t.rulePattern).join(", ")}`);
|
|
226
|
+
return;
|
|
227
|
+
}
|
|
228
|
+
if (format === "json") {
|
|
229
|
+
console.log(JSON.stringify(suggestion, null, 2));
|
|
230
|
+
}
|
|
231
|
+
else {
|
|
232
|
+
console.log(`\n Fix Suggestion — ${suggestion.ruleId}`);
|
|
233
|
+
console.log(` ──────────────────────────`);
|
|
234
|
+
console.log(` Title: ${suggestion.title}`);
|
|
235
|
+
console.log(` File: ${suggestion.file}:${suggestion.line}`);
|
|
236
|
+
console.log(`\n Before: ${suggestion.before}`);
|
|
237
|
+
console.log(` After: ${suggestion.after}`);
|
|
238
|
+
console.log(`\n Confidence: ${suggestion.confidence}%\n`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
241
|
+
//# sourceMappingURL=auto-fix.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"auto-fix.js","sourceRoot":"","sources":["../../src/commands/auto-fix.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code owner suggest — auto-recommend CODEOWNERS entries
|
|
3
|
+
* based on finding patterns and resolution history.
|
|
4
|
+
*
|
|
5
|
+
* All analysis uses local data only.
|
|
6
|
+
*/
|
|
7
|
+
interface OwnerSuggestion {
|
|
8
|
+
path: string;
|
|
9
|
+
suggestedOwner: string;
|
|
10
|
+
reason: string;
|
|
11
|
+
confidence: number;
|
|
12
|
+
ruleCategories: string[];
|
|
13
|
+
}
|
|
14
|
+
export declare function suggestOwner(path: string, author: string, ruleCategories: string[]): OwnerSuggestion;
|
|
15
|
+
export declare function runCodeOwnerSuggest(argv: string[]): void;
|
|
16
|
+
export {};
|
|
17
|
+
//# sourceMappingURL=code-owner-suggest.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-owner-suggest.d.ts","sourceRoot":"","sources":["../../src/commands/code-owner-suggest.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,UAAU,eAAe;IACvB,IAAI,EAAE,MAAM,CAAC;IACb,cAAc,EAAE,MAAM,CAAC;IACvB,MAAM,EAAE,MAAM,CAAC;IACf,UAAU,EAAE,MAAM,CAAC;IACnB,cAAc,EAAE,MAAM,EAAE,CAAC;CAC1B;AAuDD,wBAAgB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,cAAc,EAAE,MAAM,EAAE,GAAG,eAAe,CAkBpG;AAwBD,wBAAgB,mBAAmB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA2HxD"}
|
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Code owner suggest — auto-recommend CODEOWNERS entries
|
|
3
|
+
* based on finding patterns and resolution history.
|
|
4
|
+
*
|
|
5
|
+
* All analysis uses local data only.
|
|
6
|
+
*/
|
|
7
|
+
import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
|
|
8
|
+
import { join } from "path";
|
|
9
|
+
const OWNER_DIR = ".judges-code-owners";
|
|
10
|
+
const OWNER_FILE = join(OWNER_DIR, "suggestions.json");
|
|
11
|
+
// ─── Core ───────────────────────────────────────────────────────────────────
|
|
12
|
+
function ensureDir() {
|
|
13
|
+
if (!existsSync(OWNER_DIR))
|
|
14
|
+
mkdirSync(OWNER_DIR, { recursive: true });
|
|
15
|
+
}
|
|
16
|
+
function loadStore() {
|
|
17
|
+
if (!existsSync(OWNER_FILE))
|
|
18
|
+
return { suggestions: [], updatedAt: new Date().toISOString() };
|
|
19
|
+
try {
|
|
20
|
+
return JSON.parse(readFileSync(OWNER_FILE, "utf-8"));
|
|
21
|
+
}
|
|
22
|
+
catch {
|
|
23
|
+
return { suggestions: [], updatedAt: new Date().toISOString() };
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
function saveStore(store) {
|
|
27
|
+
ensureDir();
|
|
28
|
+
store.updatedAt = new Date().toISOString();
|
|
29
|
+
writeFileSync(OWNER_FILE, JSON.stringify(store, null, 2));
|
|
30
|
+
}
|
|
31
|
+
function loadScoreData() {
|
|
32
|
+
// Try to load from dev-score data
|
|
33
|
+
const scoreDir = ".judges-scores";
|
|
34
|
+
if (!existsSync(scoreDir))
|
|
35
|
+
return [];
|
|
36
|
+
try {
|
|
37
|
+
const { readdirSync: rds } = require("fs");
|
|
38
|
+
const files = rds(scoreDir).filter((f) => f.endsWith(".json"));
|
|
39
|
+
return files.map((f) => {
|
|
40
|
+
try {
|
|
41
|
+
const data = JSON.parse(readFileSync(join(scoreDir, f), "utf-8"));
|
|
42
|
+
return {
|
|
43
|
+
author: data.author || f.replace(".json", ""),
|
|
44
|
+
findingsFixed: data.findingsFixed || data.score || 0,
|
|
45
|
+
categories: data.topCategories || [],
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return { author: f.replace(".json", ""), findingsFixed: 0, categories: [] };
|
|
50
|
+
}
|
|
51
|
+
});
|
|
52
|
+
}
|
|
53
|
+
catch {
|
|
54
|
+
return [];
|
|
55
|
+
}
|
|
56
|
+
}
|
|
57
|
+
export function suggestOwner(path, author, ruleCategories) {
|
|
58
|
+
const suggestion = {
|
|
59
|
+
path,
|
|
60
|
+
suggestedOwner: author,
|
|
61
|
+
reason: `Most active reviewer for ${ruleCategories.join(", ")} findings`,
|
|
62
|
+
confidence: Math.min(100, 50 + ruleCategories.length * 10),
|
|
63
|
+
ruleCategories,
|
|
64
|
+
};
|
|
65
|
+
const store = loadStore();
|
|
66
|
+
// Replace existing suggestion for same path
|
|
67
|
+
const idx = store.suggestions.findIndex((s) => s.path === path);
|
|
68
|
+
if (idx >= 0)
|
|
69
|
+
store.suggestions[idx] = suggestion;
|
|
70
|
+
else
|
|
71
|
+
store.suggestions.push(suggestion);
|
|
72
|
+
if (store.suggestions.length > 200)
|
|
73
|
+
store.suggestions = store.suggestions.slice(-200);
|
|
74
|
+
saveStore(store);
|
|
75
|
+
return suggestion;
|
|
76
|
+
}
|
|
77
|
+
function generateCodeowners(suggestions) {
|
|
78
|
+
const lines = [
|
|
79
|
+
"# CODEOWNERS — Generated by judges code-owner-suggest",
|
|
80
|
+
"# Review and customize before committing",
|
|
81
|
+
"",
|
|
82
|
+
];
|
|
83
|
+
const grouped = new Map();
|
|
84
|
+
for (const s of suggestions) {
|
|
85
|
+
const existing = grouped.get(s.suggestedOwner) || [];
|
|
86
|
+
existing.push(s.path);
|
|
87
|
+
grouped.set(s.suggestedOwner, existing);
|
|
88
|
+
}
|
|
89
|
+
for (const [owner, paths] of grouped) {
|
|
90
|
+
for (const p of paths) {
|
|
91
|
+
lines.push(`${p} @${owner}`);
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
return lines.join("\n") + "\n";
|
|
95
|
+
}
|
|
96
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
97
|
+
export function runCodeOwnerSuggest(argv) {
|
|
98
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
99
|
+
console.log(`
|
|
100
|
+
judges code-owner-suggest — Auto-recommend CODEOWNERS entries
|
|
101
|
+
|
|
102
|
+
Usage:
|
|
103
|
+
judges code-owner-suggest --analyze
|
|
104
|
+
judges code-owner-suggest --suggest --path "src/auth/" --owner "alice@co.com" --rules SEC,AUTH
|
|
105
|
+
judges code-owner-suggest --export
|
|
106
|
+
judges code-owner-suggest --export --out CODEOWNERS
|
|
107
|
+
|
|
108
|
+
Options:
|
|
109
|
+
--analyze Auto-suggest from dev-score and finding data
|
|
110
|
+
--suggest Manually add a suggestion
|
|
111
|
+
--path <path> File/directory path for suggestion
|
|
112
|
+
--owner <name> Owner email/username
|
|
113
|
+
--rules <csv> Rule categories (comma-separated)
|
|
114
|
+
--export Export as CODEOWNERS format
|
|
115
|
+
--out <file> Write CODEOWNERS to file
|
|
116
|
+
--format json JSON output
|
|
117
|
+
--help, -h Show this help
|
|
118
|
+
`);
|
|
119
|
+
return;
|
|
120
|
+
}
|
|
121
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
122
|
+
// Manual suggestion
|
|
123
|
+
if (argv.includes("--suggest")) {
|
|
124
|
+
const path = argv.find((_a, i) => argv[i - 1] === "--path");
|
|
125
|
+
const owner = argv.find((_a, i) => argv[i - 1] === "--owner");
|
|
126
|
+
const rulesStr = argv.find((_a, i) => argv[i - 1] === "--rules");
|
|
127
|
+
if (!path || !owner) {
|
|
128
|
+
console.error(" --path and --owner required for --suggest");
|
|
129
|
+
return;
|
|
130
|
+
}
|
|
131
|
+
const rules = rulesStr ? rulesStr.split(",") : [];
|
|
132
|
+
const suggestion = suggestOwner(path, owner, rules);
|
|
133
|
+
if (format === "json") {
|
|
134
|
+
console.log(JSON.stringify(suggestion, null, 2));
|
|
135
|
+
}
|
|
136
|
+
else {
|
|
137
|
+
console.log(`\n ✅ Suggestion recorded:`);
|
|
138
|
+
console.log(` ${suggestion.path} → @${suggestion.suggestedOwner} (${suggestion.confidence}% confidence)`);
|
|
139
|
+
console.log(` Reason: ${suggestion.reason}\n`);
|
|
140
|
+
}
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
// Auto-analyze
|
|
144
|
+
if (argv.includes("--analyze")) {
|
|
145
|
+
const devs = loadScoreData();
|
|
146
|
+
if (devs.length === 0) {
|
|
147
|
+
console.log(" No dev-score data found. Record developer activity with `judges dev-score` first.");
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const suggestions = [];
|
|
151
|
+
// Map categories to path prefixes
|
|
152
|
+
const categoryPaths = {
|
|
153
|
+
SEC: "src/security/",
|
|
154
|
+
AUTH: "src/auth/",
|
|
155
|
+
SQL: "src/database/",
|
|
156
|
+
XSS: "src/frontend/",
|
|
157
|
+
CRYPTO: "src/crypto/",
|
|
158
|
+
SSRF: "src/network/",
|
|
159
|
+
CMD: "src/commands/",
|
|
160
|
+
};
|
|
161
|
+
for (const dev of devs) {
|
|
162
|
+
for (const cat of dev.categories) {
|
|
163
|
+
const path = categoryPaths[cat] || `src/${cat.toLowerCase()}/`;
|
|
164
|
+
suggestions.push(suggestOwner(path, dev.author, [cat]));
|
|
165
|
+
}
|
|
166
|
+
}
|
|
167
|
+
if (format === "json") {
|
|
168
|
+
console.log(JSON.stringify(suggestions, null, 2));
|
|
169
|
+
}
|
|
170
|
+
else {
|
|
171
|
+
console.log(`\n Auto-Analyzed Code Owners (${suggestions.length} suggestions)\n ──────────────────────────`);
|
|
172
|
+
for (const s of suggestions) {
|
|
173
|
+
console.log(` ${s.path.padEnd(25)} → @${s.suggestedOwner.padEnd(20)} ${s.ruleCategories.join(",")}`);
|
|
174
|
+
}
|
|
175
|
+
console.log(`\n Export with: judges code-owner-suggest --export\n`);
|
|
176
|
+
}
|
|
177
|
+
return;
|
|
178
|
+
}
|
|
179
|
+
// Export
|
|
180
|
+
if (argv.includes("--export")) {
|
|
181
|
+
const store = loadStore();
|
|
182
|
+
if (store.suggestions.length === 0) {
|
|
183
|
+
console.log(" No suggestions yet. Use --analyze or --suggest first.");
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
const content = generateCodeowners(store.suggestions);
|
|
187
|
+
const outPath = argv.find((_a, i) => argv[i - 1] === "--out");
|
|
188
|
+
if (outPath) {
|
|
189
|
+
writeFileSync(outPath, content);
|
|
190
|
+
console.log(` ✅ Written to ${outPath} (${store.suggestions.length} entries)`);
|
|
191
|
+
}
|
|
192
|
+
else {
|
|
193
|
+
console.log(content);
|
|
194
|
+
}
|
|
195
|
+
return;
|
|
196
|
+
}
|
|
197
|
+
// Default: show current suggestions
|
|
198
|
+
const store = loadStore();
|
|
199
|
+
if (format === "json") {
|
|
200
|
+
console.log(JSON.stringify(store, null, 2));
|
|
201
|
+
}
|
|
202
|
+
else {
|
|
203
|
+
console.log(`\n Code Owner Suggestions (${store.suggestions.length})\n ──────────────────────────`);
|
|
204
|
+
if (store.suggestions.length === 0) {
|
|
205
|
+
console.log(" No suggestions yet. Use --analyze or --suggest to add.");
|
|
206
|
+
}
|
|
207
|
+
else {
|
|
208
|
+
for (const s of store.suggestions) {
|
|
209
|
+
console.log(` ${s.path.padEnd(25)} → @${s.suggestedOwner.padEnd(20)} ${s.confidence}% ${s.ruleCategories.join(",")}`);
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
console.log("");
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
//# sourceMappingURL=code-owner-suggest.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"code-owner-suggest.js","sourceRoot":"","sources":["../../src/commands/code-owner-suggest.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Cost forecast — projects 30/60/90-day security debt and
|
|
3
|
+
* remediation cost trends from local finding history.
|
|
4
|
+
*
|
|
5
|
+
* All data stays local — no upload or external services.
|
|
6
|
+
*/
|
|
7
|
+
interface CostSnapshot {
|
|
8
|
+
date: string;
|
|
9
|
+
critical: number;
|
|
10
|
+
high: number;
|
|
11
|
+
medium: number;
|
|
12
|
+
low: number;
|
|
13
|
+
totalFindings: number;
|
|
14
|
+
estimatedCost: number;
|
|
15
|
+
}
|
|
16
|
+
export declare function recordSnapshot(critical: number, high: number, medium: number, low: number): CostSnapshot;
|
|
17
|
+
export declare function runCostForecast(argv: string[]): void;
|
|
18
|
+
export {};
|
|
19
|
+
//# sourceMappingURL=cost-forecast.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cost-forecast.d.ts","sourceRoot":"","sources":["../../src/commands/cost-forecast.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,UAAU,YAAY;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,MAAM,CAAC;IACb,MAAM,EAAE,MAAM,CAAC;IACf,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB;AAoDD,wBAAgB,cAAc,CAAC,QAAQ,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,YAAY,CAkDxG;AAID,wBAAgB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA6GpD"}
|