@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.
Files changed (70) hide show
  1. package/CHANGELOG.md +24 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +112 -0
  4. package/dist/cli.js.map +1 -1
  5. package/dist/commands/adoption-report.d.ts +8 -0
  6. package/dist/commands/adoption-report.d.ts.map +1 -0
  7. package/dist/commands/adoption-report.js +219 -0
  8. package/dist/commands/adoption-report.js.map +1 -0
  9. package/dist/commands/ai-model-trust.d.ts +17 -0
  10. package/dist/commands/ai-model-trust.d.ts.map +1 -0
  11. package/dist/commands/ai-model-trust.js +235 -0
  12. package/dist/commands/ai-model-trust.js.map +1 -0
  13. package/dist/commands/ai-prompt-audit.d.ts +23 -0
  14. package/dist/commands/ai-prompt-audit.d.ts.map +1 -0
  15. package/dist/commands/ai-prompt-audit.js +255 -0
  16. package/dist/commands/ai-prompt-audit.js.map +1 -0
  17. package/dist/commands/audit-trail.d.ts +18 -0
  18. package/dist/commands/audit-trail.d.ts.map +1 -0
  19. package/dist/commands/audit-trail.js +155 -0
  20. package/dist/commands/audit-trail.js.map +1 -0
  21. package/dist/commands/auto-fix.d.ts +18 -0
  22. package/dist/commands/auto-fix.d.ts.map +1 -0
  23. package/dist/commands/auto-fix.js +241 -0
  24. package/dist/commands/auto-fix.js.map +1 -0
  25. package/dist/commands/code-owner-suggest.d.ts +17 -0
  26. package/dist/commands/code-owner-suggest.d.ts.map +1 -0
  27. package/dist/commands/code-owner-suggest.js +215 -0
  28. package/dist/commands/code-owner-suggest.js.map +1 -0
  29. package/dist/commands/cost-forecast.d.ts +19 -0
  30. package/dist/commands/cost-forecast.d.ts.map +1 -0
  31. package/dist/commands/cost-forecast.js +194 -0
  32. package/dist/commands/cost-forecast.js.map +1 -0
  33. package/dist/commands/dep-correlate.d.ts +9 -0
  34. package/dist/commands/dep-correlate.d.ts.map +1 -0
  35. package/dist/commands/dep-correlate.js +208 -0
  36. package/dist/commands/dep-correlate.js.map +1 -0
  37. package/dist/commands/doc-gen.d.ts +8 -0
  38. package/dist/commands/doc-gen.d.ts.map +1 -0
  39. package/dist/commands/doc-gen.js +209 -0
  40. package/dist/commands/doc-gen.js.map +1 -0
  41. package/dist/commands/judge-author.d.ts +8 -0
  42. package/dist/commands/judge-author.d.ts.map +1 -0
  43. package/dist/commands/judge-author.js +261 -0
  44. package/dist/commands/judge-author.js.map +1 -0
  45. package/dist/commands/pattern-registry.d.ts +23 -0
  46. package/dist/commands/pattern-registry.d.ts.map +1 -0
  47. package/dist/commands/pattern-registry.js +227 -0
  48. package/dist/commands/pattern-registry.js.map +1 -0
  49. package/dist/commands/perf-hotspot.d.ts +8 -0
  50. package/dist/commands/perf-hotspot.d.ts.map +1 -0
  51. package/dist/commands/perf-hotspot.js +274 -0
  52. package/dist/commands/perf-hotspot.js.map +1 -0
  53. package/dist/commands/pr-quality-gate.d.ts +29 -0
  54. package/dist/commands/pr-quality-gate.d.ts.map +1 -0
  55. package/dist/commands/pr-quality-gate.js +208 -0
  56. package/dist/commands/pr-quality-gate.js.map +1 -0
  57. package/dist/commands/security-maturity.d.ts +8 -0
  58. package/dist/commands/security-maturity.d.ts.map +1 -0
  59. package/dist/commands/security-maturity.js +313 -0
  60. package/dist/commands/security-maturity.js.map +1 -0
  61. package/dist/commands/team-leaderboard.d.ts +25 -0
  62. package/dist/commands/team-leaderboard.d.ts.map +1 -0
  63. package/dist/commands/team-leaderboard.js +228 -0
  64. package/dist/commands/team-leaderboard.js.map +1 -0
  65. package/dist/commands/team-rules-sync.d.ts +8 -0
  66. package/dist/commands/team-rules-sync.d.ts.map +1 -0
  67. package/dist/commands/team-rules-sync.js +251 -0
  68. package/dist/commands/team-rules-sync.js.map +1 -0
  69. package/package.json +1 -1
  70. 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"}