@kevinrabun/judges 3.45.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 (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-bundle.d.ts +29 -0
  18. package/dist/commands/audit-bundle.d.ts.map +1 -0
  19. package/dist/commands/audit-bundle.js +235 -0
  20. package/dist/commands/audit-bundle.js.map +1 -0
  21. package/dist/commands/code-owner-suggest.d.ts +17 -0
  22. package/dist/commands/code-owner-suggest.d.ts.map +1 -0
  23. package/dist/commands/code-owner-suggest.js +215 -0
  24. package/dist/commands/code-owner-suggest.js.map +1 -0
  25. package/dist/commands/config-drift.d.ts +25 -0
  26. package/dist/commands/config-drift.d.ts.map +1 -0
  27. package/dist/commands/config-drift.js +214 -0
  28. package/dist/commands/config-drift.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/dev-score.d.ts +37 -0
  34. package/dist/commands/dev-score.d.ts.map +1 -0
  35. package/dist/commands/dev-score.js +204 -0
  36. package/dist/commands/dev-score.js.map +1 -0
  37. package/dist/commands/generate.d.ts +8 -0
  38. package/dist/commands/generate.d.ts.map +1 -0
  39. package/dist/commands/generate.js +404 -0
  40. package/dist/commands/generate.js.map +1 -0
  41. package/dist/commands/learn.d.ts +27 -0
  42. package/dist/commands/learn.d.ts.map +1 -0
  43. package/dist/commands/learn.js +289 -0
  44. package/dist/commands/learn.js.map +1 -0
  45. package/dist/commands/model-risk.d.ts +28 -0
  46. package/dist/commands/model-risk.d.ts.map +1 -0
  47. package/dist/commands/model-risk.js +221 -0
  48. package/dist/commands/model-risk.js.map +1 -0
  49. package/dist/commands/pr-quality-gate.d.ts +29 -0
  50. package/dist/commands/pr-quality-gate.d.ts.map +1 -0
  51. package/dist/commands/pr-quality-gate.js +208 -0
  52. package/dist/commands/pr-quality-gate.js.map +1 -0
  53. package/dist/commands/reg-watch.d.ts +21 -0
  54. package/dist/commands/reg-watch.d.ts.map +1 -0
  55. package/dist/commands/reg-watch.js +220 -0
  56. package/dist/commands/reg-watch.js.map +1 -0
  57. package/dist/commands/retro.d.ts +23 -0
  58. package/dist/commands/retro.d.ts.map +1 -0
  59. package/dist/commands/retro.js +217 -0
  60. package/dist/commands/retro.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,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,25 @@
1
+ /**
2
+ * Config drift detector — compare team configurations against an
3
+ * organizational baseline to detect policy divergence.
4
+ *
5
+ * Uses local .judgesrc files.
6
+ */
7
+ interface DriftItem {
8
+ type: "disabled-rule" | "disabled-judge" | "severity-override" | "missing-preset" | "extra-rule";
9
+ key: string;
10
+ baselineValue?: string;
11
+ actualValue?: string;
12
+ impact: "high" | "medium" | "low";
13
+ }
14
+ interface ConfigDriftReport {
15
+ configFile: string;
16
+ baselineFile: string;
17
+ driftScore: number;
18
+ items: DriftItem[];
19
+ summary: string;
20
+ }
21
+ export declare function detectDrift(baselineFile: string, configFile: string): ConfigDriftReport;
22
+ export declare function scanDirectory(baselineFile: string, dir: string): ConfigDriftReport[];
23
+ export declare function runConfigDrift(argv: string[]): void;
24
+ export {};
25
+ //# sourceMappingURL=config-drift.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-drift.d.ts","sourceRoot":"","sources":["../../src/commands/config-drift.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAOH,UAAU,SAAS;IACjB,IAAI,EAAE,eAAe,GAAG,gBAAgB,GAAG,mBAAmB,GAAG,gBAAgB,GAAG,YAAY,CAAC;IACjG,GAAG,EAAE,MAAM,CAAC;IACZ,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,MAAM,EAAE,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;CACnC;AAED,UAAU,iBAAiB;IACzB,UAAU,EAAE,MAAM,CAAC;IACnB,YAAY,EAAE,MAAM,CAAC;IACrB,UAAU,EAAE,MAAM,CAAC;IACnB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,OAAO,EAAE,MAAM,CAAC;CACjB;AAaD,wBAAgB,WAAW,CAAC,YAAY,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,GAAG,iBAAiB,CAuFvF;AAED,wBAAgB,aAAa,CAAC,YAAY,EAAE,MAAM,EAAE,GAAG,EAAE,MAAM,GAAG,iBAAiB,EAAE,CAqBpF;AAID,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CAgFnD"}
@@ -0,0 +1,214 @@
1
+ /**
2
+ * Config drift detector — compare team configurations against an
3
+ * organizational baseline to detect policy divergence.
4
+ *
5
+ * Uses local .judgesrc files.
6
+ */
7
+ import { readFileSync, existsSync, readdirSync, statSync } from "fs";
8
+ import { join, basename } from "path";
9
+ // ─── Core ───────────────────────────────────────────────────────────────────
10
+ function loadConfig(file) {
11
+ if (!existsSync(file))
12
+ return {};
13
+ try {
14
+ return JSON.parse(readFileSync(file, "utf-8"));
15
+ }
16
+ catch {
17
+ return {};
18
+ }
19
+ }
20
+ export function detectDrift(baselineFile, configFile) {
21
+ const baseline = loadConfig(baselineFile);
22
+ const config = loadConfig(configFile);
23
+ const items = [];
24
+ // Check disabled rules
25
+ const baselineDisabledRules = new Set(baseline.disabledRules || []);
26
+ const configDisabledRules = new Set(config.disabledRules || []);
27
+ for (const rule of configDisabledRules) {
28
+ if (!baselineDisabledRules.has(rule)) {
29
+ items.push({
30
+ type: "disabled-rule",
31
+ key: rule,
32
+ baselineValue: "enabled",
33
+ actualValue: "disabled",
34
+ impact: rule.startsWith("SEC") || rule.startsWith("AUTH") || rule.startsWith("CRYPTO") ? "high" : "medium",
35
+ });
36
+ }
37
+ }
38
+ // Check disabled judges
39
+ const baselineDisabledJudges = new Set(baseline.disabledJudges || []);
40
+ const configDisabledJudges = new Set(config.disabledJudges || []);
41
+ for (const judge of configDisabledJudges) {
42
+ if (!baselineDisabledJudges.has(judge)) {
43
+ items.push({
44
+ type: "disabled-judge",
45
+ key: judge,
46
+ baselineValue: "enabled",
47
+ actualValue: "disabled",
48
+ impact: ["cybersecurity", "authentication", "injection"].includes(judge) ? "high" : "medium",
49
+ });
50
+ }
51
+ }
52
+ // Check severity overrides
53
+ const baselineOverrides = (baseline.ruleOverrides || {});
54
+ const configOverrides = (config.ruleOverrides || {});
55
+ for (const [ruleId, override] of Object.entries(configOverrides)) {
56
+ const baseOverride = baselineOverrides[ruleId];
57
+ if (override.severity && (!baseOverride || override.severity !== baseOverride.severity)) {
58
+ const severityOrder = ["critical", "high", "medium", "low"];
59
+ const configIdx = severityOrder.indexOf(override.severity);
60
+ const baseIdx = baseOverride ? severityOrder.indexOf(baseOverride.severity) : -1;
61
+ const weakened = configIdx > baseIdx;
62
+ items.push({
63
+ type: "severity-override",
64
+ key: ruleId,
65
+ baselineValue: baseOverride?.severity || "default",
66
+ actualValue: override.severity,
67
+ impact: weakened ? "high" : "low",
68
+ });
69
+ }
70
+ }
71
+ // Check preset alignment
72
+ if (baseline.preset && config.preset !== baseline.preset) {
73
+ items.push({
74
+ type: "missing-preset",
75
+ key: "preset",
76
+ baselineValue: baseline.preset,
77
+ actualValue: config.preset || "none",
78
+ impact: "medium",
79
+ });
80
+ }
81
+ // Drift score
82
+ const highCount = items.filter((i) => i.impact === "high").length;
83
+ const medCount = items.filter((i) => i.impact === "medium").length;
84
+ const lowCount = items.filter((i) => i.impact === "low").length;
85
+ const driftScore = Math.min(100, highCount * 20 + medCount * 10 + lowCount * 5);
86
+ return {
87
+ configFile,
88
+ baselineFile,
89
+ driftScore,
90
+ items,
91
+ summary: items.length === 0
92
+ ? "Configuration is aligned with baseline."
93
+ : `${items.length} deviation(s) detected. Drift score: ${driftScore}/100.`,
94
+ };
95
+ }
96
+ export function scanDirectory(baselineFile, dir) {
97
+ const reports = [];
98
+ function walk(d) {
99
+ for (const entry of readdirSync(d)) {
100
+ const full = join(d, entry);
101
+ try {
102
+ const stat = statSync(full);
103
+ if (stat.isDirectory() && !entry.startsWith(".") && entry !== "node_modules") {
104
+ walk(full);
105
+ }
106
+ else if (entry === ".judgesrc" || entry === ".judgesrc.json") {
107
+ reports.push(detectDrift(baselineFile, full));
108
+ }
109
+ }
110
+ catch {
111
+ // Skip inaccessible entries
112
+ }
113
+ }
114
+ }
115
+ walk(dir);
116
+ return reports;
117
+ }
118
+ // ─── CLI ────────────────────────────────────────────────────────────────────
119
+ export function runConfigDrift(argv) {
120
+ if (argv.includes("--help") || argv.includes("-h")) {
121
+ console.log(`
122
+ judges config-drift — Detect configuration divergence from baseline
123
+
124
+ Usage:
125
+ judges config-drift --baseline org-baseline.judgesrc --config team/.judgesrc
126
+ judges config-drift --baseline org-baseline.judgesrc --scan ./teams/
127
+ judges config-drift --baseline org-baseline.judgesrc --self
128
+
129
+ Options:
130
+ --baseline <file> Organization baseline config file
131
+ --config <file> Team config to compare
132
+ --scan <dir> Scan directory for .judgesrc files and compare all
133
+ --self Compare local .judgesrc against baseline
134
+ --format json JSON output
135
+ --help, -h Show this help
136
+ `);
137
+ return;
138
+ }
139
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
140
+ const baselineFile = argv.find((_a, i) => argv[i - 1] === "--baseline");
141
+ if (!baselineFile) {
142
+ console.error(" ❌ Provide --baseline <file>. Use --help for usage.");
143
+ return;
144
+ }
145
+ if (!existsSync(baselineFile)) {
146
+ console.error(` ❌ Baseline not found: ${baselineFile}`);
147
+ return;
148
+ }
149
+ // Scan directory
150
+ const scanDir = argv.find((_a, i) => argv[i - 1] === "--scan");
151
+ if (scanDir) {
152
+ const reports = scanDirectory(baselineFile, scanDir);
153
+ if (format === "json") {
154
+ console.log(JSON.stringify(reports, null, 2));
155
+ }
156
+ else if (reports.length === 0) {
157
+ console.log("\n No .judgesrc files found in scan directory.\n");
158
+ }
159
+ else {
160
+ console.log(`\n Config Drift Scan (${reports.length} config(s))\n ──────────────────────────────`);
161
+ for (const r of reports) {
162
+ const icon = r.driftScore === 0 ? "✅" : r.driftScore > 50 ? "🚨" : "⚠️";
163
+ console.log(` ${icon} ${basename(r.configFile).padEnd(20)} drift: ${r.driftScore}/100 (${r.items.length} item(s))`);
164
+ }
165
+ console.log("");
166
+ }
167
+ return;
168
+ }
169
+ // Compare self
170
+ if (argv.includes("--self")) {
171
+ const localConfig = existsSync(".judgesrc") ? ".judgesrc" : ".judgesrc.json";
172
+ if (!existsSync(localConfig)) {
173
+ console.error(" ❌ No local .judgesrc found");
174
+ return;
175
+ }
176
+ const report = detectDrift(baselineFile, localConfig);
177
+ printReport(report, format);
178
+ return;
179
+ }
180
+ // Compare specific config
181
+ const configFile = argv.find((_a, i) => argv[i - 1] === "--config");
182
+ if (configFile) {
183
+ if (!existsSync(configFile)) {
184
+ console.error(` ❌ Config not found: ${configFile}`);
185
+ return;
186
+ }
187
+ const report = detectDrift(baselineFile, configFile);
188
+ printReport(report, format);
189
+ return;
190
+ }
191
+ console.error(" ❌ Provide --config, --scan, or --self. Use --help for usage.");
192
+ }
193
+ function printReport(report, format) {
194
+ if (format === "json") {
195
+ console.log(JSON.stringify(report, null, 2));
196
+ return;
197
+ }
198
+ const icon = report.driftScore === 0 ? "✅" : report.driftScore > 50 ? "🚨" : "⚠️";
199
+ console.log(`\n ${icon} Config Drift Report`);
200
+ console.log(` Baseline: ${report.baselineFile}`);
201
+ console.log(` Config: ${report.configFile}`);
202
+ console.log(` Drift Score: ${report.driftScore}/100`);
203
+ console.log(` ─────────────────────────`);
204
+ if (report.items.length === 0) {
205
+ console.log(" Configuration is aligned with baseline.\n");
206
+ return;
207
+ }
208
+ for (const item of report.items) {
209
+ const impactIcon = item.impact === "high" ? "🔴" : item.impact === "medium" ? "🟡" : "🟢";
210
+ console.log(` ${impactIcon} [${item.type}] ${item.key}: ${item.baselineValue} → ${item.actualValue}`);
211
+ }
212
+ console.log("");
213
+ }
214
+ //# sourceMappingURL=config-drift.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"config-drift.js","sourceRoot":"","sources":["../../src/commands/config-drift.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,UAAU,EAAE,WAAW,EAAE,QAAQ,EAAE,MAAM,IAAI,CAAC;AACrE,OAAO,EAAE,IAAI,EAAE,QAAQ,EAAE,MAAM,MAAM,CAAC;AAoBtC,+EAA+E;AAE/E,SAAS,UAAU,CAAC,IAAY;IAC9B,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC;QAAE,OAAO,EAAE,CAAC;IACjC,IAAI,CAAC;QACH,OAAO,IAAI,CAAC,KAAK,CAAC,YAAY,CAAC,IAAI,EAAE,OAAO,CAAC,CAAC,CAAC;IACjD,CAAC;IAAC,MAAM,CAAC;QACP,OAAO,EAAE,CAAC;IACZ,CAAC;AACH,CAAC;AAED,MAAM,UAAU,WAAW,CAAC,YAAoB,EAAE,UAAkB;IAClE,MAAM,QAAQ,GAAG,UAAU,CAAC,YAAY,CAAC,CAAC;IAC1C,MAAM,MAAM,GAAG,UAAU,CAAC,UAAU,CAAC,CAAC;IAEtC,MAAM,KAAK,GAAgB,EAAE,CAAC;IAE9B,uBAAuB;IACvB,MAAM,qBAAqB,GAAG,IAAI,GAAG,CAAE,QAAQ,CAAC,aAA0B,IAAI,EAAE,CAAC,CAAC;IAClF,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAE,MAAM,CAAC,aAA0B,IAAI,EAAE,CAAC,CAAC;IAE9E,KAAK,MAAM,IAAI,IAAI,mBAAmB,EAAE,CAAC;QACvC,IAAI,CAAC,qBAAqB,CAAC,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC;YACrC,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,eAAe;gBACrB,GAAG,EAAE,IAAI;gBACT,aAAa,EAAE,SAAS;gBACxB,WAAW,EAAE,UAAU;gBACvB,MAAM,EAAE,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,MAAM,CAAC,IAAI,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ;aAC3G,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,wBAAwB;IACxB,MAAM,sBAAsB,GAAG,IAAI,GAAG,CAAE,QAAQ,CAAC,cAA2B,IAAI,EAAE,CAAC,CAAC;IACpF,MAAM,oBAAoB,GAAG,IAAI,GAAG,CAAE,MAAM,CAAC,cAA2B,IAAI,EAAE,CAAC,CAAC;IAEhF,KAAK,MAAM,KAAK,IAAI,oBAAoB,EAAE,CAAC;QACzC,IAAI,CAAC,sBAAsB,CAAC,GAAG,CAAC,KAAK,CAAC,EAAE,CAAC;YACvC,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,gBAAgB;gBACtB,GAAG,EAAE,KAAK;gBACV,aAAa,EAAE,SAAS;gBACxB,WAAW,EAAE,UAAU;gBACvB,MAAM,EAAE,CAAC,eAAe,EAAE,gBAAgB,EAAE,WAAW,CAAC,CAAC,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ;aAC7F,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,2BAA2B;IAC3B,MAAM,iBAAiB,GAAG,CAAC,QAAQ,CAAC,aAAa,IAAI,EAAE,CAA4C,CAAC;IACpG,MAAM,eAAe,GAAG,CAAC,MAAM,CAAC,aAAa,IAAI,EAAE,CAA4C,CAAC;IAEhG,KAAK,MAAM,CAAC,MAAM,EAAE,QAAQ,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,eAAe,CAAC,EAAE,CAAC;QACjE,MAAM,YAAY,GAAG,iBAAiB,CAAC,MAAM,CAAC,CAAC;QAC/C,IAAI,QAAQ,CAAC,QAAQ,IAAI,CAAC,CAAC,YAAY,IAAI,QAAQ,CAAC,QAAQ,KAAK,YAAY,CAAC,QAAQ,CAAC,EAAE,CAAC;YACxF,MAAM,aAAa,GAAG,CAAC,UAAU,EAAE,MAAM,EAAE,QAAQ,EAAE,KAAK,CAAC,CAAC;YAC5D,MAAM,SAAS,GAAG,aAAa,CAAC,OAAO,CAAC,QAAQ,CAAC,QAAkB,CAAC,CAAC;YACrE,MAAM,OAAO,GAAG,YAAY,CAAC,CAAC,CAAC,aAAa,CAAC,OAAO,CAAC,YAAY,CAAC,QAAkB,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC;YAC3F,MAAM,QAAQ,GAAG,SAAS,GAAG,OAAO,CAAC;YAErC,KAAK,CAAC,IAAI,CAAC;gBACT,IAAI,EAAE,mBAAmB;gBACzB,GAAG,EAAE,MAAM;gBACX,aAAa,EAAG,YAAY,EAAE,QAAmB,IAAI,SAAS;gBAC9D,WAAW,EAAE,QAAQ,CAAC,QAAkB;gBACxC,MAAM,EAAE,QAAQ,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,KAAK;aAClC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,yBAAyB;IACzB,IAAI,QAAQ,CAAC,MAAM,IAAI,MAAM,CAAC,MAAM,KAAK,QAAQ,CAAC,MAAM,EAAE,CAAC;QACzD,KAAK,CAAC,IAAI,CAAC;YACT,IAAI,EAAE,gBAAgB;YACtB,GAAG,EAAE,QAAQ;YACb,aAAa,EAAE,QAAQ,CAAC,MAAgB;YACxC,WAAW,EAAG,MAAM,CAAC,MAAiB,IAAI,MAAM;YAChD,MAAM,EAAE,QAAQ;SACjB,CAAC,CAAC;IACL,CAAC;IAED,cAAc;IACd,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,MAAM,CAAC;IAClE,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM,CAAC;IACnE,MAAM,QAAQ,GAAG,KAAK,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,MAAM,KAAK,KAAK,CAAC,CAAC,MAAM,CAAC;IAChE,MAAM,UAAU,GAAG,IAAI,CAAC,GAAG,CAAC,GAAG,EAAE,SAAS,GAAG,EAAE,GAAG,QAAQ,GAAG,EAAE,GAAG,QAAQ,GAAG,CAAC,CAAC,CAAC;IAEhF,OAAO;QACL,UAAU;QACV,YAAY;QACZ,UAAU;QACV,KAAK;QACL,OAAO,EACL,KAAK,CAAC,MAAM,KAAK,CAAC;YAChB,CAAC,CAAC,yCAAyC;YAC3C,CAAC,CAAC,GAAG,KAAK,CAAC,MAAM,wCAAwC,UAAU,OAAO;KAC/E,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,aAAa,CAAC,YAAoB,EAAE,GAAW;IAC7D,MAAM,OAAO,GAAwB,EAAE,CAAC;IAExC,SAAS,IAAI,CAAC,CAAS;QACrB,KAAK,MAAM,KAAK,IAAI,WAAW,CAAC,CAAC,CAAC,EAAE,CAAC;YACnC,MAAM,IAAI,GAAG,IAAI,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC;YAC5B,IAAI,CAAC;gBACH,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC,CAAC;gBAC5B,IAAI,IAAI,CAAC,WAAW,EAAE,IAAI,CAAC,KAAK,CAAC,UAAU,CAAC,GAAG,CAAC,IAAI,KAAK,KAAK,cAAc,EAAE,CAAC;oBAC7E,IAAI,CAAC,IAAI,CAAC,CAAC;gBACb,CAAC;qBAAM,IAAI,KAAK,KAAK,WAAW,IAAI,KAAK,KAAK,gBAAgB,EAAE,CAAC;oBAC/D,OAAO,CAAC,IAAI,CAAC,WAAW,CAAC,YAAY,EAAE,IAAI,CAAC,CAAC,CAAC;gBAChD,CAAC;YACH,CAAC;YAAC,MAAM,CAAC;gBACP,4BAA4B;YAC9B,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,CAAC,GAAG,CAAC,CAAC;IACV,OAAO,OAAO,CAAC;AACjB,CAAC;AAED,+EAA+E;AAE/E,MAAM,UAAU,cAAc,CAAC,IAAc;IAC3C,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;CAef,CAAC,CAAC;QACC,OAAO;IACT,CAAC;IAED,MAAM,MAAM,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,UAAU,CAAC,IAAI,MAAM,CAAC;IAC1F,MAAM,YAAY,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,YAAY,CAAC,CAAC;IAExF,IAAI,CAAC,YAAY,EAAE,CAAC;QAClB,OAAO,CAAC,KAAK,CAAC,sDAAsD,CAAC,CAAC;QACtE,OAAO;IACT,CAAC;IAED,IAAI,CAAC,UAAU,CAAC,YAAY,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,KAAK,CAAC,2BAA2B,YAAY,EAAE,CAAC,CAAC;QACzD,OAAO;IACT,CAAC;IAED,iBAAiB;IACjB,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,QAAQ,CAAC,CAAC;IAC/E,IAAI,OAAO,EAAE,CAAC;QACZ,MAAM,OAAO,GAAG,aAAa,CAAC,YAAY,EAAE,OAAO,CAAC,CAAC;QACrD,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAChD,CAAC;aAAM,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YAChC,OAAO,CAAC,GAAG,CAAC,mDAAmD,CAAC,CAAC;QACnE,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,0BAA0B,OAAO,CAAC,MAAM,+CAA+C,CAAC,CAAC;YACrG,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,MAAM,IAAI,GAAG,CAAC,CAAC,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;gBACxE,OAAO,CAAC,GAAG,CACT,OAAO,IAAI,IAAI,QAAQ,CAAC,CAAC,CAAC,UAAU,CAAC,CAAC,MAAM,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,UAAU,SAAS,CAAC,CAAC,KAAK,CAAC,MAAM,WAAW,CAC1G,CAAC;YACJ,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;QAClB,CAAC;QACD,OAAO;IACT,CAAC;IAED,eAAe;IACf,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,EAAE,CAAC;QAC5B,MAAM,WAAW,GAAG,UAAU,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC,WAAW,CAAC,CAAC,CAAC,gBAAgB,CAAC;QAC7E,IAAI,CAAC,UAAU,CAAC,WAAW,CAAC,EAAE,CAAC;YAC7B,OAAO,CAAC,KAAK,CAAC,8BAA8B,CAAC,CAAC;YAC9C,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,WAAW,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;QACtD,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,0BAA0B;IAC1B,MAAM,UAAU,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC;IACpF,IAAI,UAAU,EAAE,CAAC;QACf,IAAI,CAAC,UAAU,CAAC,UAAU,CAAC,EAAE,CAAC;YAC5B,OAAO,CAAC,KAAK,CAAC,yBAAyB,UAAU,EAAE,CAAC,CAAC;YACrD,OAAO;QACT,CAAC;QACD,MAAM,MAAM,GAAG,WAAW,CAAC,YAAY,EAAE,UAAU,CAAC,CAAC;QACrD,WAAW,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;QAC5B,OAAO;IACT,CAAC;IAED,OAAO,CAAC,KAAK,CAAC,gEAAgE,CAAC,CAAC;AAClF,CAAC;AAED,SAAS,WAAW,CAAC,MAAyB,EAAE,MAAc;IAC5D,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC7C,OAAO;IACT,CAAC;IAED,MAAM,IAAI,GAAG,MAAM,CAAC,UAAU,KAAK,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,MAAM,CAAC,UAAU,GAAG,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;IAClF,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,sBAAsB,CAAC,CAAC;IAC/C,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,YAAY,EAAE,CAAC,CAAC;IAClD,OAAO,CAAC,GAAG,CAAC,eAAe,MAAM,CAAC,UAAU,EAAE,CAAC,CAAC;IAChD,OAAO,CAAC,GAAG,CAAC,kBAAkB,MAAM,CAAC,UAAU,MAAM,CAAC,CAAC;IACvD,OAAO,CAAC,GAAG,CAAC,6BAA6B,CAAC,CAAC;IAE3C,IAAI,MAAM,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC9B,OAAO,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;QAC3D,OAAO;IACT,CAAC;IAED,KAAK,MAAM,IAAI,IAAI,MAAM,CAAC,KAAK,EAAE,CAAC;QAChC,MAAM,UAAU,GAAG,IAAI,CAAC,MAAM,KAAK,MAAM,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,MAAM,KAAK,QAAQ,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;QAC1F,OAAO,CAAC,GAAG,CAAC,OAAO,UAAU,KAAK,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,GAAG,KAAK,IAAI,CAAC,aAAa,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC;IAC3G,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
@@ -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"}