@kevinrabun/judges 3.44.0 → 3.46.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/audit-bundle.d.ts +29 -0
  6. package/dist/commands/audit-bundle.d.ts.map +1 -0
  7. package/dist/commands/audit-bundle.js +235 -0
  8. package/dist/commands/audit-bundle.js.map +1 -0
  9. package/dist/commands/compare-runs.d.ts +38 -0
  10. package/dist/commands/compare-runs.d.ts.map +1 -0
  11. package/dist/commands/compare-runs.js +229 -0
  12. package/dist/commands/compare-runs.js.map +1 -0
  13. package/dist/commands/config-drift.d.ts +25 -0
  14. package/dist/commands/config-drift.d.ts.map +1 -0
  15. package/dist/commands/config-drift.js +214 -0
  16. package/dist/commands/config-drift.js.map +1 -0
  17. package/dist/commands/correlate.d.ts +28 -0
  18. package/dist/commands/correlate.d.ts.map +1 -0
  19. package/dist/commands/correlate.js +242 -0
  20. package/dist/commands/correlate.js.map +1 -0
  21. package/dist/commands/dev-score.d.ts +37 -0
  22. package/dist/commands/dev-score.d.ts.map +1 -0
  23. package/dist/commands/dev-score.js +204 -0
  24. package/dist/commands/dev-score.js.map +1 -0
  25. package/dist/commands/digest.d.ts +20 -0
  26. package/dist/commands/digest.d.ts.map +1 -0
  27. package/dist/commands/digest.js +222 -0
  28. package/dist/commands/digest.js.map +1 -0
  29. package/dist/commands/explain-finding.d.ts +8 -0
  30. package/dist/commands/explain-finding.d.ts.map +1 -0
  31. package/dist/commands/explain-finding.js +279 -0
  32. package/dist/commands/explain-finding.js.map +1 -0
  33. package/dist/commands/generate.d.ts +8 -0
  34. package/dist/commands/generate.d.ts.map +1 -0
  35. package/dist/commands/generate.js +404 -0
  36. package/dist/commands/generate.js.map +1 -0
  37. package/dist/commands/judge-reputation.d.ts +29 -0
  38. package/dist/commands/judge-reputation.d.ts.map +1 -0
  39. package/dist/commands/judge-reputation.js +199 -0
  40. package/dist/commands/judge-reputation.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/query.d.ts +20 -0
  50. package/dist/commands/query.d.ts.map +1 -0
  51. package/dist/commands/query.js +230 -0
  52. package/dist/commands/query.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/rule-share.d.ts +35 -0
  62. package/dist/commands/rule-share.d.ts.map +1 -0
  63. package/dist/commands/rule-share.js +203 -0
  64. package/dist/commands/rule-share.js.map +1 -0
  65. package/dist/commands/vote.d.ts +32 -0
  66. package/dist/commands/vote.d.ts.map +1 -0
  67. package/dist/commands/vote.js +201 -0
  68. package/dist/commands/vote.js.map +1 -0
  69. package/package.json +1 -1
  70. package/server.json +2 -2
@@ -0,0 +1,235 @@
1
+ /**
2
+ * Audit evidence bundle — assemble a complete, auditor-ready evidence
3
+ * package from local scan history, suppressions, votes, SLA data, and config.
4
+ *
5
+ * Outputs a structured directory or JSON manifest.
6
+ */
7
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync } from "fs";
8
+ import { join } from "path";
9
+ const EVIDENCE_SOURCES = [
10
+ {
11
+ file: ".judgesrc",
12
+ type: "config",
13
+ description: "Security policy configuration",
14
+ controls: ["SOC2-CC6.1", "ISO27001-A.8.28"],
15
+ },
16
+ {
17
+ file: ".judges-results.json",
18
+ type: "scan-results",
19
+ description: "Latest evaluation findings",
20
+ controls: ["SOC2-CC7.1", "ISO27001-A.8.8"],
21
+ },
22
+ { file: ".judges-baseline.json", type: "baseline", description: "Accepted risk baseline", controls: ["SOC2-CC3.2"] },
23
+ {
24
+ file: ".judges-suppressions.json",
25
+ type: "suppressions",
26
+ description: "Suppressed finding audit trail",
27
+ controls: ["SOC2-CC3.3", "ISO27001-A.8.28"],
28
+ },
29
+ {
30
+ file: ".judges-votes.json",
31
+ type: "review-decisions",
32
+ description: "Team consensus on findings",
33
+ controls: ["SOC2-CC4.1"],
34
+ },
35
+ {
36
+ file: ".judges-sla.json",
37
+ type: "sla-policy",
38
+ description: "SLA policies and violation tracking",
39
+ controls: ["SOC2-CC7.2", "ISO27001-A.8.8"],
40
+ },
41
+ {
42
+ file: ".judges-burndown.json",
43
+ type: "resolution-tracking",
44
+ description: "Finding resolution timeline",
45
+ controls: ["SOC2-CC7.3"],
46
+ },
47
+ {
48
+ file: ".judges-kb.json",
49
+ type: "knowledge-base",
50
+ description: "Team rule decisions and exceptions",
51
+ controls: ["SOC2-CC3.2", "ISO27001-A.5.1"],
52
+ },
53
+ {
54
+ file: ".judges-owners.json",
55
+ type: "ownership",
56
+ description: "Rule-to-owner accountability mapping",
57
+ controls: ["SOC2-CC1.3"],
58
+ },
59
+ {
60
+ file: ".judges-reputation.json",
61
+ type: "tool-effectiveness",
62
+ description: "Judge accuracy and FP tracking",
63
+ controls: ["SOC2-CC4.2"],
64
+ },
65
+ {
66
+ file: ".judges-audit.json",
67
+ type: "policy-snapshots",
68
+ description: "Policy audit trail with SHA-256 hashes",
69
+ controls: ["SOC2-CC8.1", "ISO27001-A.8.25"],
70
+ },
71
+ {
72
+ file: ".judges-review-queue.json",
73
+ type: "manual-review",
74
+ description: "Manual review queue decisions",
75
+ controls: ["SOC2-CC4.1"],
76
+ },
77
+ {
78
+ file: ".judges-correlations.json",
79
+ type: "root-cause",
80
+ description: "Root cause analysis records",
81
+ controls: ["SOC2-CC7.4"],
82
+ },
83
+ {
84
+ file: ".judges-digest.json",
85
+ type: "trend-data",
86
+ description: "Historical trend snapshots",
87
+ controls: ["SOC2-CC4.2", "ISO27001-A.8.16"],
88
+ },
89
+ {
90
+ file: ".judges-false-negatives.json",
91
+ type: "fn-tracking",
92
+ description: "False negative tracking",
93
+ controls: ["SOC2-CC7.1"],
94
+ },
95
+ ];
96
+ // ─── Core ───────────────────────────────────────────────────────────────────
97
+ export function generateBundle(standard, periodDays) {
98
+ const artifacts = [];
99
+ for (const src of EVIDENCE_SOURCES) {
100
+ const present = existsSync(src.file);
101
+ artifacts.push({
102
+ type: src.type,
103
+ source: src.file,
104
+ description: src.description,
105
+ controlMapping: src.controls,
106
+ present,
107
+ });
108
+ }
109
+ // Check for run history
110
+ const runsDir = ".judges-runs";
111
+ if (existsSync(runsDir)) {
112
+ const runs = readdirSync(runsDir).filter((f) => f.endsWith(".json"));
113
+ artifacts.push({
114
+ type: "scan-history",
115
+ source: runsDir,
116
+ description: `${runs.length} historical scan snapshot(s)`,
117
+ controlMapping: ["SOC2-CC7.1", "ISO27001-A.8.8"],
118
+ present: runs.length > 0,
119
+ });
120
+ }
121
+ const present = artifacts.filter((a) => a.present).length;
122
+ const total = artifacts.length;
123
+ return {
124
+ standard,
125
+ generatedAt: new Date().toISOString(),
126
+ period: `${periodDays} days`,
127
+ artifacts,
128
+ summary: {
129
+ present,
130
+ missing: total - present,
131
+ coveragePercent: Math.round((present / total) * 100),
132
+ },
133
+ };
134
+ }
135
+ export function exportBundle(bundle, outputDir) {
136
+ mkdirSync(outputDir, { recursive: true });
137
+ // Copy present artifacts
138
+ for (const artifact of bundle.artifacts) {
139
+ if (artifact.present && existsSync(artifact.source)) {
140
+ try {
141
+ const content = readFileSync(artifact.source, "utf-8");
142
+ const destName = artifact.source.replace(/^\./, "").replace(/\//g, "_");
143
+ writeFileSync(join(outputDir, destName), content);
144
+ }
145
+ catch {
146
+ // Skip files that can't be read (directories handled separately)
147
+ }
148
+ }
149
+ }
150
+ // Write manifest
151
+ writeFileSync(join(outputDir, "audit-manifest.json"), JSON.stringify(bundle, null, 2));
152
+ // Write human-readable summary
153
+ const lines = [];
154
+ lines.push(`# Audit Evidence Bundle — ${bundle.standard}`);
155
+ lines.push(`Generated: ${bundle.generatedAt}`);
156
+ lines.push(`Period: ${bundle.period}\n`);
157
+ lines.push(`## Coverage: ${bundle.summary.coveragePercent}% (${bundle.summary.present}/${bundle.summary.present + bundle.summary.missing})\n`);
158
+ lines.push("| Status | Type | Source | Controls |");
159
+ lines.push("|--------|------|--------|----------|");
160
+ for (const a of bundle.artifacts) {
161
+ const icon = a.present ? "✅" : "❌";
162
+ const controls = (a.controlMapping || []).join(", ");
163
+ lines.push(`| ${icon} | ${a.type} | ${a.source} | ${controls} |`);
164
+ }
165
+ lines.push("\n## Missing Evidence");
166
+ const missing = bundle.artifacts.filter((a) => !a.present);
167
+ if (missing.length === 0) {
168
+ lines.push("All evidence artifacts present.");
169
+ }
170
+ else {
171
+ for (const m of missing) {
172
+ lines.push(`- **${m.type}**: ${m.description} (${m.source})`);
173
+ }
174
+ }
175
+ writeFileSync(join(outputDir, "audit-summary.md"), lines.join("\n"));
176
+ }
177
+ // ─── CLI ────────────────────────────────────────────────────────────────────
178
+ export function runAuditBundle(argv) {
179
+ if (argv.includes("--help") || argv.includes("-h")) {
180
+ console.log(`
181
+ judges audit-bundle — Assemble auditor-ready evidence package
182
+
183
+ Usage:
184
+ judges audit-bundle --standard soc2
185
+ judges audit-bundle --standard iso27001 --period 90
186
+ judges audit-bundle --standard soc2 --output ./audit-evidence/
187
+ judges audit-bundle --check
188
+
189
+ Options:
190
+ --standard <name> Standard: soc2 | iso27001 | hitrust | generic (default: generic)
191
+ --period <days> Evidence period in days (default: 90)
192
+ --output <dir> Export evidence to directory
193
+ --check Check evidence coverage without exporting
194
+ --format json JSON output
195
+ --help, -h Show this help
196
+ `);
197
+ return;
198
+ }
199
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
200
+ const standard = argv.find((_a, i) => argv[i - 1] === "--standard") || "generic";
201
+ const periodStr = argv.find((_a, i) => argv[i - 1] === "--period");
202
+ const periodDays = periodStr ? parseInt(periodStr, 10) : 90;
203
+ const bundle = generateBundle(standard, periodDays);
204
+ // Export
205
+ const outputDir = argv.find((_a, i) => argv[i - 1] === "--output");
206
+ if (outputDir) {
207
+ exportBundle(bundle, outputDir);
208
+ console.log(` ✅ Audit bundle exported to ${outputDir}/`);
209
+ console.log(` Standard: ${standard}, Coverage: ${bundle.summary.coveragePercent}%`);
210
+ console.log(` ${bundle.summary.present} present, ${bundle.summary.missing} missing`);
211
+ return;
212
+ }
213
+ // Check or display
214
+ if (format === "json") {
215
+ console.log(JSON.stringify(bundle, null, 2));
216
+ }
217
+ else {
218
+ console.log(`\n Audit Evidence — ${standard.toUpperCase()} (${bundle.period})\n ────────────────────────────────────`);
219
+ console.log(` Coverage: ${bundle.summary.coveragePercent}% (${bundle.summary.present}/${bundle.summary.present + bundle.summary.missing})\n`);
220
+ for (const a of bundle.artifacts) {
221
+ const icon = a.present ? "✅" : "❌";
222
+ const controls = (a.controlMapping || []).slice(0, 2).join(", ");
223
+ console.log(` ${icon} ${a.type.padEnd(22)} ${controls}`);
224
+ }
225
+ const missing = bundle.artifacts.filter((a) => !a.present);
226
+ if (missing.length > 0) {
227
+ console.log(`\n Missing (${missing.length}):`);
228
+ for (const m of missing) {
229
+ console.log(` ⚠️ ${m.description} (${m.source})`);
230
+ }
231
+ }
232
+ console.log("");
233
+ }
234
+ }
235
+ //# sourceMappingURL=audit-bundle.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"audit-bundle.js","sourceRoot":"","sources":["../../src/commands/audit-bundle.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,EAAE,YAAY,EAAE,aAAa,EAAE,UAAU,EAAE,SAAS,EAAE,WAAW,EAAE,MAAM,IAAI,CAAC;AACrF,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAwB5B,MAAM,gBAAgB,GAA8E;IAClG;QACE,IAAI,EAAE,WAAW;QACjB,IAAI,EAAE,QAAQ;QACd,WAAW,EAAE,+BAA+B;QAC5C,QAAQ,EAAE,CAAC,YAAY,EAAE,iBAAiB,CAAC;KAC5C;IACD;QACE,IAAI,EAAE,sBAAsB;QAC5B,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,4BAA4B;QACzC,QAAQ,EAAE,CAAC,YAAY,EAAE,gBAAgB,CAAC;KAC3C;IACD,EAAE,IAAI,EAAE,uBAAuB,EAAE,IAAI,EAAE,UAAU,EAAE,WAAW,EAAE,wBAAwB,EAAE,QAAQ,EAAE,CAAC,YAAY,CAAC,EAAE;IACpH;QACE,IAAI,EAAE,2BAA2B;QACjC,IAAI,EAAE,cAAc;QACpB,WAAW,EAAE,gCAAgC;QAC7C,QAAQ,EAAE,CAAC,YAAY,EAAE,iBAAiB,CAAC;KAC5C;IACD;QACE,IAAI,EAAE,oBAAoB;QAC1B,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,4BAA4B;QACzC,QAAQ,EAAE,CAAC,YAAY,CAAC;KACzB;IACD;QACE,IAAI,EAAE,kBAAkB;QACxB,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,qCAAqC;QAClD,QAAQ,EAAE,CAAC,YAAY,EAAE,gBAAgB,CAAC;KAC3C;IACD;QACE,IAAI,EAAE,uBAAuB;QAC7B,IAAI,EAAE,qBAAqB;QAC3B,WAAW,EAAE,6BAA6B;QAC1C,QAAQ,EAAE,CAAC,YAAY,CAAC;KACzB;IACD;QACE,IAAI,EAAE,iBAAiB;QACvB,IAAI,EAAE,gBAAgB;QACtB,WAAW,EAAE,oCAAoC;QACjD,QAAQ,EAAE,CAAC,YAAY,EAAE,gBAAgB,CAAC;KAC3C;IACD;QACE,IAAI,EAAE,qBAAqB;QAC3B,IAAI,EAAE,WAAW;QACjB,WAAW,EAAE,sCAAsC;QACnD,QAAQ,EAAE,CAAC,YAAY,CAAC;KACzB;IACD;QACE,IAAI,EAAE,yBAAyB;QAC/B,IAAI,EAAE,oBAAoB;QAC1B,WAAW,EAAE,gCAAgC;QAC7C,QAAQ,EAAE,CAAC,YAAY,CAAC;KACzB;IACD;QACE,IAAI,EAAE,oBAAoB;QAC1B,IAAI,EAAE,kBAAkB;QACxB,WAAW,EAAE,wCAAwC;QACrD,QAAQ,EAAE,CAAC,YAAY,EAAE,iBAAiB,CAAC;KAC5C;IACD;QACE,IAAI,EAAE,2BAA2B;QACjC,IAAI,EAAE,eAAe;QACrB,WAAW,EAAE,+BAA+B;QAC5C,QAAQ,EAAE,CAAC,YAAY,CAAC;KACzB;IACD;QACE,IAAI,EAAE,2BAA2B;QACjC,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,6BAA6B;QAC1C,QAAQ,EAAE,CAAC,YAAY,CAAC;KACzB;IACD;QACE,IAAI,EAAE,qBAAqB;QAC3B,IAAI,EAAE,YAAY;QAClB,WAAW,EAAE,4BAA4B;QACzC,QAAQ,EAAE,CAAC,YAAY,EAAE,iBAAiB,CAAC;KAC5C;IACD;QACE,IAAI,EAAE,8BAA8B;QACpC,IAAI,EAAE,aAAa;QACnB,WAAW,EAAE,yBAAyB;QACtC,QAAQ,EAAE,CAAC,YAAY,CAAC;KACzB;CACF,CAAC;AAEF,+EAA+E;AAE/E,MAAM,UAAU,cAAc,CAAC,QAAgB,EAAE,UAAkB;IACjE,MAAM,SAAS,GAAoB,EAAE,CAAC;IAEtC,KAAK,MAAM,GAAG,IAAI,gBAAgB,EAAE,CAAC;QACnC,MAAM,OAAO,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC;QACrC,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,GAAG,CAAC,IAAI;YACd,MAAM,EAAE,GAAG,CAAC,IAAI;YAChB,WAAW,EAAE,GAAG,CAAC,WAAW;YAC5B,cAAc,EAAE,GAAG,CAAC,QAAQ;YAC5B,OAAO;SACR,CAAC,CAAC;IACL,CAAC;IAED,wBAAwB;IACxB,MAAM,OAAO,GAAG,cAAc,CAAC;IAC/B,IAAI,UAAU,CAAC,OAAO,CAAC,EAAE,CAAC;QACxB,MAAM,IAAI,GAAG,WAAW,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,CAAC,CAAC;QACrE,SAAS,CAAC,IAAI,CAAC;YACb,IAAI,EAAE,cAAc;YACpB,MAAM,EAAE,OAAO;YACf,WAAW,EAAE,GAAG,IAAI,CAAC,MAAM,8BAA8B;YACzD,cAAc,EAAE,CAAC,YAAY,EAAE,gBAAgB,CAAC;YAChD,OAAO,EAAE,IAAI,CAAC,MAAM,GAAG,CAAC;SACzB,CAAC,CAAC;IACL,CAAC;IAED,MAAM,OAAO,GAAG,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,MAAM,CAAC;IAC1D,MAAM,KAAK,GAAG,SAAS,CAAC,MAAM,CAAC;IAE/B,OAAO;QACL,QAAQ;QACR,WAAW,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;QACrC,MAAM,EAAE,GAAG,UAAU,OAAO;QAC5B,SAAS;QACT,OAAO,EAAE;YACP,OAAO;YACP,OAAO,EAAE,KAAK,GAAG,OAAO;YACxB,eAAe,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,OAAO,GAAG,KAAK,CAAC,GAAG,GAAG,CAAC;SACrD;KACF,CAAC;AACJ,CAAC;AAED,MAAM,UAAU,YAAY,CAAC,MAAmB,EAAE,SAAiB;IACjE,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;IAE1C,yBAAyB;IACzB,KAAK,MAAM,QAAQ,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACxC,IAAI,QAAQ,CAAC,OAAO,IAAI,UAAU,CAAC,QAAQ,CAAC,MAAM,CAAC,EAAE,CAAC;YACpD,IAAI,CAAC;gBACH,MAAM,OAAO,GAAG,YAAY,CAAC,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;gBACvD,MAAM,QAAQ,GAAG,QAAQ,CAAC,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,EAAE,CAAC,CAAC,OAAO,CAAC,KAAK,EAAE,GAAG,CAAC,CAAC;gBACxE,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,EAAE,OAAO,CAAC,CAAC;YACpD,CAAC;YAAC,MAAM,CAAC;gBACP,iEAAiE;YACnE,CAAC;QACH,CAAC;IACH,CAAC;IAED,iBAAiB;IACjB,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,qBAAqB,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAEvF,+BAA+B;IAC/B,MAAM,KAAK,GAAa,EAAE,CAAC;IAC3B,KAAK,CAAC,IAAI,CAAC,6BAA6B,MAAM,CAAC,QAAQ,EAAE,CAAC,CAAC;IAC3D,KAAK,CAAC,IAAI,CAAC,cAAc,MAAM,CAAC,WAAW,EAAE,CAAC,CAAC;IAC/C,KAAK,CAAC,IAAI,CAAC,WAAW,MAAM,CAAC,MAAM,IAAI,CAAC,CAAC;IACzC,KAAK,CAAC,IAAI,CACR,gBAAgB,MAAM,CAAC,OAAO,CAAC,eAAe,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,KAAK,CACnI,CAAC;IACF,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;IACpD,KAAK,CAAC,IAAI,CAAC,uCAAuC,CAAC,CAAC;IACpD,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;QACjC,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;QACnC,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;QACrD,KAAK,CAAC,IAAI,CAAC,KAAK,IAAI,MAAM,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,MAAM,MAAM,QAAQ,IAAI,CAAC,CAAC;IACpE,CAAC;IACD,KAAK,CAAC,IAAI,CAAC,uBAAuB,CAAC,CAAC;IACpC,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;IAC3D,IAAI,OAAO,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACzB,KAAK,CAAC,IAAI,CAAC,iCAAiC,CAAC,CAAC;IAChD,CAAC;SAAM,CAAC;QACN,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;YACxB,KAAK,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,IAAI,OAAO,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;QAChE,CAAC;IACH,CAAC;IACD,aAAa,CAAC,IAAI,CAAC,SAAS,EAAE,kBAAkB,CAAC,EAAE,KAAK,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,CAAC;AACvE,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;;;;;;;;;;;;;;;;CAgBf,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,QAAQ,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,YAAY,CAAC,IAAI,SAAS,CAAC;IACjG,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC;IACnF,MAAM,UAAU,GAAG,SAAS,CAAC,CAAC,CAAC,QAAQ,CAAC,SAAS,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;IAE5D,MAAM,MAAM,GAAG,cAAc,CAAC,QAAQ,EAAE,UAAU,CAAC,CAAC;IAEpD,SAAS;IACT,MAAM,SAAS,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,UAAU,CAAC,CAAC;IACnF,IAAI,SAAS,EAAE,CAAC;QACd,YAAY,CAAC,MAAM,EAAE,SAAS,CAAC,CAAC;QAChC,OAAO,CAAC,GAAG,CAAC,gCAAgC,SAAS,GAAG,CAAC,CAAC;QAC1D,OAAO,CAAC,GAAG,CAAC,kBAAkB,QAAQ,eAAe,MAAM,CAAC,OAAO,CAAC,eAAe,GAAG,CAAC,CAAC;QACxF,OAAO,CAAC,GAAG,CAAC,QAAQ,MAAM,CAAC,OAAO,CAAC,OAAO,aAAa,MAAM,CAAC,OAAO,CAAC,OAAO,UAAU,CAAC,CAAC;QACzF,OAAO;IACT,CAAC;IAED,mBAAmB;IACnB,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;IAC/C,CAAC;SAAM,CAAC;QACN,OAAO,CAAC,GAAG,CACT,wBAAwB,QAAQ,CAAC,WAAW,EAAE,KAAK,MAAM,CAAC,MAAM,2CAA2C,CAC5G,CAAC;QACF,OAAO,CAAC,GAAG,CACT,eAAe,MAAM,CAAC,OAAO,CAAC,eAAe,MAAM,MAAM,CAAC,OAAO,CAAC,OAAO,IAAI,MAAM,CAAC,OAAO,CAAC,OAAO,GAAG,MAAM,CAAC,OAAO,CAAC,OAAO,KAAK,CAClI,CAAC;QACF,KAAK,MAAM,CAAC,IAAI,MAAM,CAAC,SAAS,EAAE,CAAC;YACjC,MAAM,IAAI,GAAG,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,GAAG,CAAC;YACnC,MAAM,QAAQ,GAAG,CAAC,CAAC,CAAC,cAAc,IAAI,EAAE,CAAC,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC;YACjE,OAAO,CAAC,GAAG,CAAC,OAAO,IAAI,IAAI,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,QAAQ,EAAE,CAAC,CAAC;QAC9D,CAAC;QACD,MAAM,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC;QAC3D,IAAI,OAAO,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,gBAAgB,OAAO,CAAC,MAAM,IAAI,CAAC,CAAC;YAChD,KAAK,MAAM,CAAC,IAAI,OAAO,EAAE,CAAC;gBACxB,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,WAAW,KAAK,CAAC,CAAC,MAAM,GAAG,CAAC,CAAC;YACxD,CAAC;QACH,CAAC;QACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;IAClB,CAAC;AACH,CAAC"}
@@ -0,0 +1,38 @@
1
+ /**
2
+ * Compare evaluation runs — side-by-side comparison of two evaluation
3
+ * snapshots to show what changed.
4
+ *
5
+ * Uses local .judges-runs/ directory.
6
+ */
7
+ import type { Finding } from "../types.js";
8
+ interface RunSnapshot {
9
+ id: string;
10
+ label?: string;
11
+ timestamp: string;
12
+ findings: Finding[];
13
+ summary: {
14
+ total: number;
15
+ critical: number;
16
+ high: number;
17
+ medium: number;
18
+ low: number;
19
+ };
20
+ }
21
+ interface RunComparison {
22
+ runA: string;
23
+ runB: string;
24
+ added: Finding[];
25
+ removed: Finding[];
26
+ unchanged: number;
27
+ severityDelta: Record<string, number>;
28
+ ruleChanges: Record<string, {
29
+ added: number;
30
+ removed: number;
31
+ }>;
32
+ }
33
+ export declare function saveRun(findings: Finding[], label?: string): RunSnapshot;
34
+ export declare function listRuns(): RunSnapshot[];
35
+ export declare function compareRuns(runAId: string, runBId: string): RunComparison;
36
+ export declare function runCompareRuns(argv: string[]): void;
37
+ export {};
38
+ //# sourceMappingURL=compare-runs.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare-runs.d.ts","sourceRoot":"","sources":["../../src/commands/compare-runs.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAI3C,UAAU,WAAW;IACnB,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,OAAO,EAAE;QACP,KAAK,EAAE,MAAM,CAAC;QACd,QAAQ,EAAE,MAAM,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,MAAM,CAAC;QACf,GAAG,EAAE,MAAM,CAAC;KACb,CAAC;CACH;AAED,UAAU,aAAa;IACrB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,OAAO,EAAE,CAAC;IACjB,OAAO,EAAE,OAAO,EAAE,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,aAAa,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IACtC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE;QAAE,KAAK,EAAE,MAAM,CAAC;QAAC,OAAO,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjE;AAcD,wBAAgB,OAAO,CAAC,QAAQ,EAAE,OAAO,EAAE,EAAE,KAAK,CAAC,EAAE,MAAM,GAAG,WAAW,CAkBxE;AAED,wBAAgB,QAAQ,IAAI,WAAW,EAAE,CAMxC;AAED,wBAAgB,WAAW,CAAC,MAAM,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,aAAa,CA6CzE;AAID,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA6GnD"}
@@ -0,0 +1,229 @@
1
+ /**
2
+ * Compare evaluation runs — side-by-side comparison of two evaluation
3
+ * snapshots to show what changed.
4
+ *
5
+ * Uses local .judges-runs/ directory.
6
+ */
7
+ import { readFileSync, writeFileSync, existsSync, mkdirSync, readdirSync } from "fs";
8
+ import { join } from "path";
9
+ const RUNS_DIR = ".judges-runs";
10
+ // ─── Core ───────────────────────────────────────────────────────────────────
11
+ function ensureDir() {
12
+ if (!existsSync(RUNS_DIR))
13
+ mkdirSync(RUNS_DIR, { recursive: true });
14
+ }
15
+ function findingKey(f) {
16
+ return `${f.ruleId}:${f.title}:${(f.lineNumbers || []).join(",")}`;
17
+ }
18
+ export function saveRun(findings, label) {
19
+ ensureDir();
20
+ const id = `run-${Date.now()}`;
21
+ const snapshot = {
22
+ id,
23
+ label,
24
+ timestamp: new Date().toISOString(),
25
+ findings,
26
+ summary: {
27
+ total: findings.length,
28
+ critical: findings.filter((f) => f.severity === "critical").length,
29
+ high: findings.filter((f) => f.severity === "high").length,
30
+ medium: findings.filter((f) => f.severity === "medium").length,
31
+ low: findings.filter((f) => f.severity === "low").length,
32
+ },
33
+ };
34
+ writeFileSync(join(RUNS_DIR, `${id}.json`), JSON.stringify(snapshot, null, 2));
35
+ return snapshot;
36
+ }
37
+ export function listRuns() {
38
+ ensureDir();
39
+ const files = readdirSync(RUNS_DIR)
40
+ .filter((f) => f.endsWith(".json"))
41
+ .sort();
42
+ return files.map((f) => JSON.parse(readFileSync(join(RUNS_DIR, f), "utf-8")));
43
+ }
44
+ export function compareRuns(runAId, runBId) {
45
+ const runA = JSON.parse(readFileSync(join(RUNS_DIR, `${runAId}.json`), "utf-8"));
46
+ const runB = JSON.parse(readFileSync(join(RUNS_DIR, `${runBId}.json`), "utf-8"));
47
+ const keysA = new Set(runA.findings.map(findingKey));
48
+ const keysB = new Set(runB.findings.map(findingKey));
49
+ const findingsMapA = new Map(runA.findings.map((f) => [findingKey(f), f]));
50
+ const findingsMapB = new Map(runB.findings.map((f) => [findingKey(f), f]));
51
+ const added = [];
52
+ const removed = [];
53
+ let unchanged = 0;
54
+ for (const key of keysB) {
55
+ if (!keysA.has(key)) {
56
+ added.push(findingsMapB.get(key));
57
+ }
58
+ else {
59
+ unchanged++;
60
+ }
61
+ }
62
+ for (const key of keysA) {
63
+ if (!keysB.has(key)) {
64
+ removed.push(findingsMapA.get(key));
65
+ }
66
+ }
67
+ const severityDelta = {
68
+ critical: runB.summary.critical - runA.summary.critical,
69
+ high: runB.summary.high - runA.summary.high,
70
+ medium: runB.summary.medium - runA.summary.medium,
71
+ low: runB.summary.low - runA.summary.low,
72
+ };
73
+ // Rule-level changes
74
+ const ruleChanges = {};
75
+ for (const f of added) {
76
+ if (!ruleChanges[f.ruleId])
77
+ ruleChanges[f.ruleId] = { added: 0, removed: 0 };
78
+ ruleChanges[f.ruleId].added++;
79
+ }
80
+ for (const f of removed) {
81
+ if (!ruleChanges[f.ruleId])
82
+ ruleChanges[f.ruleId] = { added: 0, removed: 0 };
83
+ ruleChanges[f.ruleId].removed++;
84
+ }
85
+ return { runA: runAId, runB: runBId, added, removed, unchanged, severityDelta, ruleChanges };
86
+ }
87
+ // ─── CLI ────────────────────────────────────────────────────────────────────
88
+ export function runCompareRuns(argv) {
89
+ if (argv.includes("--help") || argv.includes("-h")) {
90
+ console.log(`
91
+ judges compare-runs — Compare evaluation runs side by side
92
+
93
+ Usage:
94
+ judges compare-runs --save Save current results as a run
95
+ judges compare-runs --save --label "baseline" Save with label
96
+ judges compare-runs --list List saved runs
97
+ judges compare-runs --compare <runA> <runB> Compare two runs
98
+ judges compare-runs --latest Compare last two runs
99
+
100
+ Options:
101
+ --save Save .judges-results.json as a run snapshot
102
+ --label <text> Label for the snapshot
103
+ --list List all saved runs
104
+ --compare <A> <B> Compare two run IDs
105
+ --latest Compare the two most recent runs
106
+ --format json JSON output
107
+ --help, -h Show this help
108
+ `);
109
+ return;
110
+ }
111
+ const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
112
+ // Save run
113
+ if (argv.includes("--save")) {
114
+ const resultsFile = ".judges-results.json";
115
+ if (!existsSync(resultsFile)) {
116
+ console.error(" ❌ No .judges-results.json found. Run an evaluation first.");
117
+ return;
118
+ }
119
+ const data = JSON.parse(readFileSync(resultsFile, "utf-8"));
120
+ const findings = Array.isArray(data) ? data : data.findings || [];
121
+ const label = argv.find((_a, i) => argv[i - 1] === "--label");
122
+ const run = saveRun(findings, label);
123
+ if (format === "json") {
124
+ console.log(JSON.stringify(run, null, 2));
125
+ }
126
+ else {
127
+ console.log(` ✅ Run saved: ${run.id}${label ? ` (${label})` : ""} — ${run.summary.total} findings`);
128
+ }
129
+ return;
130
+ }
131
+ // List runs
132
+ if (argv.includes("--list")) {
133
+ const runs = listRuns();
134
+ if (runs.length === 0) {
135
+ console.log("\n No runs saved. Use --save to capture a snapshot.\n");
136
+ return;
137
+ }
138
+ if (format === "json") {
139
+ console.log(JSON.stringify(runs.map((r) => ({ id: r.id, label: r.label, timestamp: r.timestamp, total: r.summary.total })), null, 2));
140
+ }
141
+ else {
142
+ console.log(`\n Saved Runs (${runs.length})\n ──────────────`);
143
+ for (const r of runs) {
144
+ const lbl = r.label ? ` (${r.label})` : "";
145
+ console.log(` ${r.id}${lbl} ${r.timestamp.split("T")[0]} ${r.summary.total} findings`);
146
+ }
147
+ console.log("");
148
+ }
149
+ return;
150
+ }
151
+ // Compare latest
152
+ if (argv.includes("--latest")) {
153
+ const runs = listRuns();
154
+ if (runs.length < 2) {
155
+ console.error(" ❌ Need at least 2 saved runs. Use --save to capture more.");
156
+ return;
157
+ }
158
+ const comparison = compareRuns(runs[runs.length - 2].id, runs[runs.length - 1].id);
159
+ printComparison(comparison, format);
160
+ return;
161
+ }
162
+ // Compare specific runs
163
+ const compareIdx = argv.indexOf("--compare");
164
+ if (compareIdx >= 0 && argv[compareIdx + 1] && argv[compareIdx + 2]) {
165
+ const runAId = argv[compareIdx + 1];
166
+ const runBId = argv[compareIdx + 2];
167
+ try {
168
+ const comparison = compareRuns(runAId, runBId);
169
+ printComparison(comparison, format);
170
+ }
171
+ catch {
172
+ console.error(` ❌ Could not load runs. Check IDs with --list.`);
173
+ }
174
+ return;
175
+ }
176
+ // Default: show latest
177
+ const runs = listRuns();
178
+ if (runs.length === 0) {
179
+ console.log("\n No runs saved. Use --save to start tracking.\n");
180
+ }
181
+ else {
182
+ const latest = runs[runs.length - 1];
183
+ console.log(`\n Latest Run: ${latest.id}${latest.label ? ` (${latest.label})` : ""}`);
184
+ console.log(` Date: ${latest.timestamp}`);
185
+ console.log(` Findings: ${latest.summary.total} (C:${latest.summary.critical} H:${latest.summary.high} M:${latest.summary.medium} L:${latest.summary.low})\n`);
186
+ }
187
+ }
188
+ function printComparison(comp, format) {
189
+ if (format === "json") {
190
+ console.log(JSON.stringify(comp, null, 2));
191
+ return;
192
+ }
193
+ console.log(`\n Run Comparison: ${comp.runA} → ${comp.runB}`);
194
+ console.log(` ────────────────────────────────────────`);
195
+ console.log(` Unchanged: ${comp.unchanged}`);
196
+ console.log(` Added: ${comp.added.length}`);
197
+ console.log(` Removed: ${comp.removed.length}`);
198
+ console.log("");
199
+ console.log(" Severity Changes:");
200
+ for (const [sev, delta] of Object.entries(comp.severityDelta)) {
201
+ const sign = delta > 0 ? "+" : "";
202
+ const icon = delta > 0 ? "📈" : delta < 0 ? "📉" : "➡️";
203
+ console.log(` ${sev.padEnd(10)} ${sign}${delta} ${icon}`);
204
+ }
205
+ if (comp.added.length > 0) {
206
+ console.log("\n New Findings:");
207
+ for (const f of comp.added.slice(0, 10)) {
208
+ console.log(` + [${f.severity.toUpperCase()}] ${f.ruleId} — ${f.title.slice(0, 50)}`);
209
+ }
210
+ if (comp.added.length > 10)
211
+ console.log(` ... and ${comp.added.length - 10} more`);
212
+ }
213
+ if (comp.removed.length > 0) {
214
+ console.log("\n Resolved Findings:");
215
+ for (const f of comp.removed.slice(0, 10)) {
216
+ console.log(` - [${f.severity.toUpperCase()}] ${f.ruleId} — ${f.title.slice(0, 50)}`);
217
+ }
218
+ if (comp.removed.length > 10)
219
+ console.log(` ... and ${comp.removed.length - 10} more`);
220
+ }
221
+ if (Object.keys(comp.ruleChanges).length > 0) {
222
+ console.log("\n Rule Changes:");
223
+ for (const [rule, changes] of Object.entries(comp.ruleChanges)) {
224
+ console.log(` ${rule.padEnd(15)} +${changes.added} / -${changes.removed}`);
225
+ }
226
+ }
227
+ console.log("");
228
+ }
229
+ //# sourceMappingURL=compare-runs.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare-runs.js","sourceRoot":"","sources":["../../src/commands/compare-runs.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"}