@kevinrabun/judges 3.46.0 → 3.47.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 (38) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/cli.d.ts.map +1 -1
  3. package/dist/cli.js +56 -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/code-owner-suggest.d.ts +17 -0
  18. package/dist/commands/code-owner-suggest.d.ts.map +1 -0
  19. package/dist/commands/code-owner-suggest.js +215 -0
  20. package/dist/commands/code-owner-suggest.js.map +1 -0
  21. package/dist/commands/cost-forecast.d.ts +19 -0
  22. package/dist/commands/cost-forecast.d.ts.map +1 -0
  23. package/dist/commands/cost-forecast.js +194 -0
  24. package/dist/commands/cost-forecast.js.map +1 -0
  25. package/dist/commands/pr-quality-gate.d.ts +29 -0
  26. package/dist/commands/pr-quality-gate.d.ts.map +1 -0
  27. package/dist/commands/pr-quality-gate.js +208 -0
  28. package/dist/commands/pr-quality-gate.js.map +1 -0
  29. package/dist/commands/team-leaderboard.d.ts +25 -0
  30. package/dist/commands/team-leaderboard.d.ts.map +1 -0
  31. package/dist/commands/team-leaderboard.js +228 -0
  32. package/dist/commands/team-leaderboard.js.map +1 -0
  33. package/dist/commands/team-rules-sync.d.ts +8 -0
  34. package/dist/commands/team-rules-sync.d.ts.map +1 -0
  35. package/dist/commands/team-rules-sync.js +251 -0
  36. package/dist/commands/team-rules-sync.js.map +1 -0
  37. package/package.json +1 -1
  38. package/server.json +2 -2
@@ -0,0 +1,255 @@
1
+ /**
2
+ * AI prompt audit — scans AI-generated code for prompt injection
3
+ * risks: user input echoed into SQL, shell, config, etc.
4
+ *
5
+ * Pattern-based analysis only — no data stored externally.
6
+ */
7
+ import { readFileSync, writeFileSync, existsSync, mkdirSync } from "fs";
8
+ import { join } from "path";
9
+ const AUDIT_DIR = ".judges-prompt-audit";
10
+ const AUDIT_FILE = join(AUDIT_DIR, "audit-history.json");
11
+ const RISK_PATTERNS = [
12
+ {
13
+ id: "sql-template-literal",
14
+ regex: /`[^`]*\$\{[^}]*(?:user|input|param|query|req\.|request|body|args)[^}]*\}[^`]*(?:SELECT|INSERT|UPDATE|DELETE|FROM|WHERE)/i,
15
+ severity: "critical",
16
+ description: "Template literal with user input in SQL context",
17
+ recommendation: "Use parameterized queries ($1, $2) instead of string interpolation",
18
+ },
19
+ {
20
+ id: "sql-concat",
21
+ regex: /(?:query|sql|execute|prepare)\s*\([^)]*(?:\+|\bconcat)\s*[^)]*(?:user|input|param|req\.|request|body)/i,
22
+ severity: "critical",
23
+ description: "String concatenation with user input in SQL query",
24
+ recommendation: "Use parameterized queries with placeholder values",
25
+ },
26
+ {
27
+ id: "shell-injection",
28
+ regex: /(?:exec|spawn|execSync|execFile|system|popen)\s*\([^)]*(?:\$\{|[\s+].*(?:user|input|param|req\.|args))/i,
29
+ severity: "critical",
30
+ description: "User input in shell command execution",
31
+ recommendation: "Use execFile with argument array, or validate against an allowlist",
32
+ },
33
+ {
34
+ id: "eval-user-input",
35
+ regex: /(?:eval|Function|setTimeout|setInterval)\s*\([^)]*(?:user|input|param|req\.|request|body|query)/i,
36
+ severity: "critical",
37
+ description: "User input passed to eval or dynamic code execution",
38
+ recommendation: "Never use eval with user input; use safe parsers instead",
39
+ },
40
+ {
41
+ id: "innerHTML-assignment",
42
+ regex: /\.innerHTML\s*=\s*(?!['"`](?:''|""|``)).*(?:user|input|param|data|response|result)/i,
43
+ severity: "high",
44
+ description: "Dynamic content assigned to innerHTML without sanitization",
45
+ recommendation: "Use textContent for text or a sanitization library (DOMPurify) for HTML",
46
+ },
47
+ {
48
+ id: "hardcoded-secret",
49
+ regex: /(?:password|secret|api_key|apiKey|token|auth)\s*[:=]\s*['"][^'"]{8,}['"]/i,
50
+ severity: "high",
51
+ description: "Hardcoded credential or secret in source code",
52
+ recommendation: "Use environment variables or a secrets manager",
53
+ },
54
+ {
55
+ id: "url-user-input",
56
+ regex: /(?:fetch|axios|http\.get|request|got)\s*\([^)]*(?:\$\{|[\s+].*(?:user|input|param|req\.|url|host))/i,
57
+ severity: "high",
58
+ description: "User-controlled URL in HTTP request (SSRF risk)",
59
+ recommendation: "Validate URLs against an allowlist and block private IP ranges",
60
+ },
61
+ {
62
+ id: "path-traversal",
63
+ regex: /(?:readFile|readFileSync|createReadStream|writeFile|writeFileSync|unlink|rmdir)\s*\([^)]*(?:\$\{|[\s+].*(?:user|input|param|req\.|path|file|name))/i,
64
+ severity: "high",
65
+ description: "User input in file system operation (path traversal risk)",
66
+ recommendation: "Sanitize paths with path.resolve and validate within allowed directory",
67
+ },
68
+ {
69
+ id: "prompt-echo",
70
+ regex: /(?:\/\/|#)\s*(?:TODO|FIXME|HACK|generated|copilot|cursor|claude|gpt|ai)[:\s].*(?:user|implement|replace|change)/i,
71
+ severity: "medium",
72
+ description: "AI prompt remnant in code comment — may expose intent or instructions",
73
+ recommendation: "Remove AI generation comments and prompt artifacts before committing",
74
+ },
75
+ {
76
+ id: "cors-wildcard",
77
+ regex: /(?:Access-Control-Allow-Origin|cors|origin)\s*[:=]\s*['"`]\*['"`]/i,
78
+ severity: "medium",
79
+ description: "Wildcard CORS allows any origin to access the API",
80
+ recommendation: "Restrict CORS to specific trusted origins",
81
+ },
82
+ ];
83
+ // ─── Core ───────────────────────────────────────────────────────────────────
84
+ function ensureDir() {
85
+ if (!existsSync(AUDIT_DIR))
86
+ mkdirSync(AUDIT_DIR, { recursive: true });
87
+ }
88
+ function loadStore() {
89
+ if (!existsSync(AUDIT_FILE))
90
+ return { results: [], updatedAt: new Date().toISOString() };
91
+ try {
92
+ return JSON.parse(readFileSync(AUDIT_FILE, "utf-8"));
93
+ }
94
+ catch {
95
+ return { results: [], updatedAt: new Date().toISOString() };
96
+ }
97
+ }
98
+ function saveStore(store) {
99
+ ensureDir();
100
+ store.updatedAt = new Date().toISOString();
101
+ writeFileSync(AUDIT_FILE, JSON.stringify(store, null, 2));
102
+ }
103
+ export function auditFile(filePath) {
104
+ const content = readFileSync(filePath, "utf-8");
105
+ const lines = content.split("\n");
106
+ const risks = [];
107
+ for (let i = 0; i < lines.length; i++) {
108
+ const line = lines[i];
109
+ for (const pattern of RISK_PATTERNS) {
110
+ if (pattern.regex.test(line)) {
111
+ risks.push({
112
+ line: i + 1,
113
+ pattern: pattern.id,
114
+ severity: pattern.severity,
115
+ description: pattern.description,
116
+ recommendation: pattern.recommendation,
117
+ });
118
+ }
119
+ }
120
+ }
121
+ // Risk score: critical=30, high=15, medium=5
122
+ const riskScore = risks.reduce((sum, r) => {
123
+ if (r.severity === "critical")
124
+ return sum + 30;
125
+ if (r.severity === "high")
126
+ return sum + 15;
127
+ return sum + 5;
128
+ }, 0);
129
+ const result = {
130
+ file: filePath,
131
+ risks,
132
+ riskScore: Math.min(100, riskScore),
133
+ timestamp: new Date().toISOString(),
134
+ };
135
+ // Persist
136
+ const store = loadStore();
137
+ store.results.push(result);
138
+ if (store.results.length > 200)
139
+ store.results = store.results.slice(-200);
140
+ saveStore(store);
141
+ return result;
142
+ }
143
+ // ─── CLI ────────────────────────────────────────────────────────────────────
144
+ export function runAiPromptAudit(argv) {
145
+ if (argv.includes("--help") || argv.includes("-h")) {
146
+ console.log(`
147
+ judges ai-prompt-audit — Scan for prompt injection risks in AI-generated code
148
+
149
+ Usage:
150
+ judges ai-prompt-audit --file src/app.ts
151
+ judges ai-prompt-audit --patterns
152
+ judges ai-prompt-audit --history
153
+ judges ai-prompt-audit --summary
154
+
155
+ Options:
156
+ --file <path> Scan a file for prompt injection risks
157
+ --patterns Show all detection patterns
158
+ --history Show audit history
159
+ --summary Show risk summary across all audits
160
+ --format json JSON output
161
+ --help, -h Show this help
162
+ `);
163
+ return;
164
+ }
165
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
166
+ // Patterns
167
+ if (argv.includes("--patterns")) {
168
+ const patterns = RISK_PATTERNS.map(({ id, severity, description, recommendation }) => ({
169
+ id,
170
+ severity,
171
+ description,
172
+ recommendation,
173
+ }));
174
+ if (format === "json") {
175
+ console.log(JSON.stringify(patterns, null, 2));
176
+ }
177
+ else {
178
+ console.log(`\n Prompt Audit Patterns (${patterns.length})\n ──────────────────────────`);
179
+ for (const p of patterns) {
180
+ console.log(` [${p.severity.padEnd(8)}] ${p.id.padEnd(25)} ${p.description}`);
181
+ }
182
+ console.log("");
183
+ }
184
+ return;
185
+ }
186
+ // History
187
+ if (argv.includes("--history")) {
188
+ const store = loadStore();
189
+ if (format === "json") {
190
+ console.log(JSON.stringify(store, null, 2));
191
+ }
192
+ else {
193
+ console.log(`\n Audit History (${store.results.length} scans)\n ──────────────────────────`);
194
+ for (const r of store.results.slice(-15)) {
195
+ const icon = r.riskScore === 0 ? "✅" : r.riskScore >= 50 ? "🔴" : "⚠️";
196
+ console.log(` ${icon} ${r.timestamp.slice(0, 16)} risk:${r.riskScore.toString().padEnd(4)} ${r.risks.length} issues ${r.file}`);
197
+ }
198
+ console.log("");
199
+ }
200
+ return;
201
+ }
202
+ // Summary
203
+ if (argv.includes("--summary")) {
204
+ const store = loadStore();
205
+ const totalRisks = store.results.reduce((s, r) => s + r.risks.length, 0);
206
+ const critCount = store.results.reduce((s, r) => s + r.risks.filter((x) => x.severity === "critical").length, 0);
207
+ const highCount = store.results.reduce((s, r) => s + r.risks.filter((x) => x.severity === "high").length, 0);
208
+ const avgScore = store.results.length > 0
209
+ ? Math.round(store.results.reduce((s, r) => s + r.riskScore, 0) / store.results.length)
210
+ : 0;
211
+ if (format === "json") {
212
+ console.log(JSON.stringify({ totalScans: store.results.length, totalRisks, critCount, highCount, avgScore }, null, 2));
213
+ }
214
+ else {
215
+ console.log(`\n Prompt Audit Summary\n ──────────────────────────`);
216
+ console.log(` Scans: ${store.results.length}`);
217
+ console.log(` Risks: ${totalRisks} (${critCount} critical, ${highCount} high)`);
218
+ console.log(` Avg risk: ${avgScore}/100`);
219
+ console.log("");
220
+ }
221
+ return;
222
+ }
223
+ // Scan file
224
+ const filePath = argv.find((_a, i) => argv[i - 1] === "--file");
225
+ if (!filePath) {
226
+ console.error(" Use --file <path>, --patterns, --history, or --summary. --help for usage.");
227
+ return;
228
+ }
229
+ if (!existsSync(filePath)) {
230
+ console.error(` File not found: ${filePath}`);
231
+ return;
232
+ }
233
+ const result = auditFile(filePath);
234
+ if (format === "json") {
235
+ console.log(JSON.stringify(result, null, 2));
236
+ }
237
+ else {
238
+ const icon = result.riskScore === 0 ? "✅" : result.riskScore >= 50 ? "🔴" : "⚠️";
239
+ console.log(`\n ${icon} Prompt Audit — ${filePath}`);
240
+ console.log(` Risk score: ${result.riskScore}/100 | Issues: ${result.risks.length}`);
241
+ console.log(` ──────────────────────────`);
242
+ if (result.risks.length === 0) {
243
+ console.log(" No prompt injection risks detected.");
244
+ }
245
+ else {
246
+ for (const r of result.risks) {
247
+ console.log(` L${r.line.toString().padEnd(5)} [${r.severity.padEnd(8)}] ${r.pattern}`);
248
+ console.log(` ${r.description}`);
249
+ console.log(` Fix: ${r.recommendation}`);
250
+ }
251
+ }
252
+ console.log("");
253
+ }
254
+ }
255
+ //# sourceMappingURL=ai-prompt-audit.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"ai-prompt-audit.js","sourceRoot":"","sources":["../../src/commands/ai-prompt-audit.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"}