@kevinrabun/judges 3.51.0 → 3.53.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +24 -0
- package/dist/cli.d.ts.map +1 -1
- package/dist/cli.js +112 -0
- package/dist/cli.js.map +1 -1
- package/dist/commands/chat-notify.d.ts +9 -0
- package/dist/commands/chat-notify.d.ts.map +1 -0
- package/dist/commands/chat-notify.js +259 -0
- package/dist/commands/chat-notify.js.map +1 -0
- package/dist/commands/code-similarity.d.ts +9 -0
- package/dist/commands/code-similarity.d.ts.map +1 -0
- package/dist/commands/code-similarity.js +232 -0
- package/dist/commands/code-similarity.js.map +1 -0
- package/dist/commands/compliance-weight.d.ts +9 -0
- package/dist/commands/compliance-weight.d.ts.map +1 -0
- package/dist/commands/compliance-weight.js +273 -0
- package/dist/commands/compliance-weight.js.map +1 -0
- package/dist/commands/cross-pr-regression.d.ts +9 -0
- package/dist/commands/cross-pr-regression.d.ts.map +1 -0
- package/dist/commands/cross-pr-regression.js +298 -0
- package/dist/commands/cross-pr-regression.js.map +1 -0
- package/dist/commands/design-audit.d.ts +9 -0
- package/dist/commands/design-audit.d.ts.map +1 -0
- package/dist/commands/design-audit.js +302 -0
- package/dist/commands/design-audit.js.map +1 -0
- package/dist/commands/doc-drift.d.ts +9 -0
- package/dist/commands/doc-drift.d.ts.map +1 -0
- package/dist/commands/doc-drift.js +259 -0
- package/dist/commands/doc-drift.js.map +1 -0
- package/dist/commands/exception-consistency.d.ts +7 -0
- package/dist/commands/exception-consistency.d.ts.map +1 -0
- package/dist/commands/exception-consistency.js +193 -0
- package/dist/commands/exception-consistency.js.map +1 -0
- package/dist/commands/impact-scan.d.ts +9 -0
- package/dist/commands/impact-scan.d.ts.map +1 -0
- package/dist/commands/impact-scan.js +282 -0
- package/dist/commands/impact-scan.js.map +1 -0
- package/dist/commands/judge-learn.d.ts +9 -0
- package/dist/commands/judge-learn.d.ts.map +1 -0
- package/dist/commands/judge-learn.js +218 -0
- package/dist/commands/judge-learn.js.map +1 -0
- package/dist/commands/model-report.d.ts +9 -0
- package/dist/commands/model-report.d.ts.map +1 -0
- package/dist/commands/model-report.js +195 -0
- package/dist/commands/model-report.js.map +1 -0
- package/dist/commands/refactor-safety.d.ts +9 -0
- package/dist/commands/refactor-safety.d.ts.map +1 -0
- package/dist/commands/refactor-safety.js +274 -0
- package/dist/commands/refactor-safety.js.map +1 -0
- package/dist/commands/remediation-lib.d.ts +9 -0
- package/dist/commands/remediation-lib.d.ts.map +1 -0
- package/dist/commands/remediation-lib.js +266 -0
- package/dist/commands/remediation-lib.js.map +1 -0
- package/dist/commands/resource-cleanup.d.ts +7 -0
- package/dist/commands/resource-cleanup.d.ts.map +1 -0
- package/dist/commands/resource-cleanup.js +236 -0
- package/dist/commands/resource-cleanup.js.map +1 -0
- package/dist/commands/team-trust.d.ts +8 -0
- package/dist/commands/team-trust.d.ts.map +1 -0
- package/dist/commands/team-trust.js +175 -0
- package/dist/commands/team-trust.js.map +1 -0
- package/dist/commands/trust-adaptive.d.ts +9 -0
- package/dist/commands/trust-adaptive.d.ts.map +1 -0
- package/dist/commands/trust-adaptive.js +194 -0
- package/dist/commands/trust-adaptive.js.map +1 -0
- package/dist/commands/watch-judge.d.ts +8 -0
- package/dist/commands/watch-judge.d.ts.map +1 -0
- package/dist/commands/watch-judge.js +180 -0
- package/dist/commands/watch-judge.js.map +1 -0
- package/package.json +1 -1
- package/server.json +2 -2
|
@@ -0,0 +1,218 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Judge-learn — interactive wizard that ingests false positive/negative
|
|
3
|
+
* feedback to automatically generate domain-specific judges with
|
|
4
|
+
* detection rules and confidence calibration.
|
|
5
|
+
*
|
|
6
|
+
* All data stored locally in `.judges-learned/`.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
9
|
+
import { join } from "path";
|
|
10
|
+
// ─── Storage ────────────────────────────────────────────────────────────────
|
|
11
|
+
const DATA_DIR = ".judges-learned";
|
|
12
|
+
function ensureDir() {
|
|
13
|
+
if (!existsSync(DATA_DIR))
|
|
14
|
+
mkdirSync(DATA_DIR, { recursive: true });
|
|
15
|
+
}
|
|
16
|
+
function loadFeedback() {
|
|
17
|
+
const file = join(DATA_DIR, "feedback.json");
|
|
18
|
+
if (!existsSync(file))
|
|
19
|
+
return [];
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(readFileSync(file, "utf-8"));
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function saveFeedback(entries) {
|
|
28
|
+
ensureDir();
|
|
29
|
+
writeFileSync(join(DATA_DIR, "feedback.json"), JSON.stringify(entries, null, 2));
|
|
30
|
+
}
|
|
31
|
+
function loadJudges() {
|
|
32
|
+
const file = join(DATA_DIR, "judges.json");
|
|
33
|
+
if (!existsSync(file))
|
|
34
|
+
return [];
|
|
35
|
+
try {
|
|
36
|
+
return JSON.parse(readFileSync(file, "utf-8"));
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return [];
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
function saveJudges(judges) {
|
|
43
|
+
ensureDir();
|
|
44
|
+
writeFileSync(join(DATA_DIR, "judges.json"), JSON.stringify(judges, null, 2));
|
|
45
|
+
}
|
|
46
|
+
// ─── Pattern extraction ─────────────────────────────────────────────────────
|
|
47
|
+
function extractPatterns(feedback) {
|
|
48
|
+
const patternMap = new Map();
|
|
49
|
+
for (const entry of feedback) {
|
|
50
|
+
const key = `${entry.pattern}:${entry.language}`;
|
|
51
|
+
const existing = patternMap.get(key) || { entries: [], fpCount: 0, fnCount: 0 };
|
|
52
|
+
existing.entries.push(entry);
|
|
53
|
+
if (entry.type === "false-positive")
|
|
54
|
+
existing.fpCount++;
|
|
55
|
+
if (entry.type === "false-negative")
|
|
56
|
+
existing.fnCount++;
|
|
57
|
+
patternMap.set(key, existing);
|
|
58
|
+
}
|
|
59
|
+
const rules = [];
|
|
60
|
+
for (const [key, data] of patternMap) {
|
|
61
|
+
const [pattern, language] = key.split(":");
|
|
62
|
+
const total = data.entries.length;
|
|
63
|
+
const correctRate = total > 0 ? (total - data.fpCount) / total : 0;
|
|
64
|
+
const confidence = Math.round(correctRate * 100);
|
|
65
|
+
// Only create rules for patterns with enough feedback
|
|
66
|
+
if (total >= 2) {
|
|
67
|
+
rules.push({
|
|
68
|
+
id: `learned-${rules.length + 1}`,
|
|
69
|
+
name: `${pattern}-detector`,
|
|
70
|
+
pattern,
|
|
71
|
+
language: language || "any",
|
|
72
|
+
confidence,
|
|
73
|
+
feedbackCount: total,
|
|
74
|
+
description: `Detects "${pattern}" pattern (${total} feedback entries, ${confidence}% confidence)`,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
return rules.sort((a, b) => b.confidence - a.confidence);
|
|
79
|
+
}
|
|
80
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
81
|
+
export function runJudgeLearn(argv) {
|
|
82
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
83
|
+
console.log(`
|
|
84
|
+
judges judge-learn — Generate custom judges from feedback
|
|
85
|
+
|
|
86
|
+
Usage:
|
|
87
|
+
judges judge-learn --feedback --type fp --pattern "unused-import" --lang ts
|
|
88
|
+
judges judge-learn --feedback --type fn --pattern "sql-injection" --lang py --context "raw query"
|
|
89
|
+
judges judge-learn --generate --name "my-team-judge"
|
|
90
|
+
judges judge-learn --show
|
|
91
|
+
|
|
92
|
+
Options:
|
|
93
|
+
--feedback Record feedback entry
|
|
94
|
+
--type <fp|fn|ok> Feedback type: fp (false positive), fn (false negative), ok (correct)
|
|
95
|
+
--pattern <name> Pattern/rule that triggered
|
|
96
|
+
--lang <language> Language context
|
|
97
|
+
--context <text> Additional context
|
|
98
|
+
--generate Generate judge from accumulated feedback
|
|
99
|
+
--name <name> Judge name for generation
|
|
100
|
+
--show Show learned judges and feedback stats
|
|
101
|
+
--format json JSON output
|
|
102
|
+
--help, -h Show this help
|
|
103
|
+
|
|
104
|
+
Workflow:
|
|
105
|
+
1. Record feedback as you review findings (--feedback)
|
|
106
|
+
2. Generate a custom judge once patterns emerge (--generate)
|
|
107
|
+
3. Use generated judge in .judgesrc config
|
|
108
|
+
`);
|
|
109
|
+
return;
|
|
110
|
+
}
|
|
111
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
112
|
+
const isFeedback = argv.includes("--feedback");
|
|
113
|
+
const isGenerate = argv.includes("--generate");
|
|
114
|
+
const _isShow = argv.includes("--show");
|
|
115
|
+
if (isFeedback) {
|
|
116
|
+
const typeMap = {
|
|
117
|
+
fp: "false-positive",
|
|
118
|
+
fn: "false-negative",
|
|
119
|
+
ok: "correct",
|
|
120
|
+
};
|
|
121
|
+
const typeArg = argv.find((_a, i) => argv[i - 1] === "--type") || "fp";
|
|
122
|
+
const pattern = argv.find((_a, i) => argv[i - 1] === "--pattern") || "";
|
|
123
|
+
const lang = argv.find((_a, i) => argv[i - 1] === "--lang") || "any";
|
|
124
|
+
const context = argv.find((_a, i) => argv[i - 1] === "--context") || "";
|
|
125
|
+
if (!pattern) {
|
|
126
|
+
console.error(" --pattern is required");
|
|
127
|
+
return;
|
|
128
|
+
}
|
|
129
|
+
const entry = {
|
|
130
|
+
id: `fb-${Date.now()}`,
|
|
131
|
+
type: typeMap[typeArg] || "false-positive",
|
|
132
|
+
pattern,
|
|
133
|
+
language: lang,
|
|
134
|
+
context,
|
|
135
|
+
timestamp: new Date().toISOString(),
|
|
136
|
+
};
|
|
137
|
+
const feedback = loadFeedback();
|
|
138
|
+
feedback.push(entry);
|
|
139
|
+
saveFeedback(feedback);
|
|
140
|
+
console.log(` ✅ Recorded ${entry.type} feedback for "${pattern}" (${lang})`);
|
|
141
|
+
return;
|
|
142
|
+
}
|
|
143
|
+
if (isGenerate) {
|
|
144
|
+
const name = argv.find((_a, i) => argv[i - 1] === "--name") || "custom-judge";
|
|
145
|
+
const feedback = loadFeedback();
|
|
146
|
+
if (feedback.length < 3) {
|
|
147
|
+
console.log(` Need at least 3 feedback entries to generate a judge (have ${feedback.length}).`);
|
|
148
|
+
return;
|
|
149
|
+
}
|
|
150
|
+
const rules = extractPatterns(feedback);
|
|
151
|
+
if (rules.length === 0) {
|
|
152
|
+
console.log(" No patterns with enough feedback to generate rules.");
|
|
153
|
+
return;
|
|
154
|
+
}
|
|
155
|
+
const judge = {
|
|
156
|
+
id: `learned-${name}`,
|
|
157
|
+
name,
|
|
158
|
+
description: `Auto-generated judge from ${feedback.length} feedback entries`,
|
|
159
|
+
rules,
|
|
160
|
+
createdAt: new Date().toISOString(),
|
|
161
|
+
updatedAt: new Date().toISOString(),
|
|
162
|
+
};
|
|
163
|
+
const judges = loadJudges();
|
|
164
|
+
const existing = judges.findIndex((j) => j.id === judge.id);
|
|
165
|
+
if (existing >= 0) {
|
|
166
|
+
judges[existing] = judge;
|
|
167
|
+
}
|
|
168
|
+
else {
|
|
169
|
+
judges.push(judge);
|
|
170
|
+
}
|
|
171
|
+
saveJudges(judges);
|
|
172
|
+
if (format === "json") {
|
|
173
|
+
console.log(JSON.stringify(judge, null, 2));
|
|
174
|
+
}
|
|
175
|
+
else {
|
|
176
|
+
console.log(`\n ✅ Generated judge: ${name}`);
|
|
177
|
+
console.log(` ${rules.length} rule(s) from ${feedback.length} feedback entries\n`);
|
|
178
|
+
for (const rule of rules) {
|
|
179
|
+
const icon = rule.confidence >= 80 ? "🟢" : rule.confidence >= 50 ? "🟡" : "🔴";
|
|
180
|
+
console.log(` ${icon} ${rule.name} — ${rule.confidence}% confidence (${rule.feedbackCount} entries)`);
|
|
181
|
+
}
|
|
182
|
+
console.log(`\n Add to .judgesrc: { "customJudges": ["${judge.id}"] }\n`);
|
|
183
|
+
}
|
|
184
|
+
return;
|
|
185
|
+
}
|
|
186
|
+
// Show
|
|
187
|
+
const feedback = loadFeedback();
|
|
188
|
+
const judges = loadJudges();
|
|
189
|
+
if (format === "json") {
|
|
190
|
+
console.log(JSON.stringify({ feedback: feedback.length, judges, timestamp: new Date().toISOString() }, null, 2));
|
|
191
|
+
return;
|
|
192
|
+
}
|
|
193
|
+
console.log(`\n Judge Learn — ${feedback.length} feedback entries, ${judges.length} generated judges\n ──────────────────────────`);
|
|
194
|
+
if (feedback.length > 0) {
|
|
195
|
+
const fpCount = feedback.filter((f) => f.type === "false-positive").length;
|
|
196
|
+
const fnCount = feedback.filter((f) => f.type === "false-negative").length;
|
|
197
|
+
const okCount = feedback.filter((f) => f.type === "correct").length;
|
|
198
|
+
console.log(` Feedback: ${fpCount} false positives, ${fnCount} false negatives, ${okCount} correct`);
|
|
199
|
+
const patterns = extractPatterns(feedback);
|
|
200
|
+
if (patterns.length > 0) {
|
|
201
|
+
console.log(` Learnable patterns: ${patterns.length}`);
|
|
202
|
+
for (const p of patterns.slice(0, 5)) {
|
|
203
|
+
console.log(` • ${p.name} — ${p.confidence}% confidence`);
|
|
204
|
+
}
|
|
205
|
+
}
|
|
206
|
+
}
|
|
207
|
+
if (judges.length > 0) {
|
|
208
|
+
console.log(`\n Generated Judges:`);
|
|
209
|
+
for (const j of judges) {
|
|
210
|
+
console.log(` 📋 ${j.name} — ${j.rules.length} rules (${j.updatedAt})`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
if (feedback.length === 0 && judges.length === 0) {
|
|
214
|
+
console.log(" No data yet. Use --feedback to record findings feedback.");
|
|
215
|
+
}
|
|
216
|
+
console.log("");
|
|
217
|
+
}
|
|
218
|
+
//# sourceMappingURL=judge-learn.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"judge-learn.js","sourceRoot":"","sources":["../../src/commands/judge-learn.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,EAAE,UAAU,EAAE,YAAY,EAAE,aAAa,EAAE,SAAS,EAAE,MAAM,IAAI,CAAC;AACxE,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAC;AAgC5B,+EAA+E;AAE/E,MAAM,QAAQ,GAAG,iBAAiB,CAAC;AAEnC,SAAS,SAAS;IAChB,IAAI,CAAC,UAAU,CAAC,QAAQ,CAAC;QAAE,SAAS,CAAC,QAAQ,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;AACtE,CAAC;AAED,SAAS,YAAY;IACnB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,CAAC;IAC7C,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,SAAS,YAAY,CAAC,OAAwB;IAC5C,SAAS,EAAE,CAAC;IACZ,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,eAAe,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AACnF,CAAC;AAED,SAAS,UAAU;IACjB,MAAM,IAAI,GAAG,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;IAC3C,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,SAAS,UAAU,CAAC,MAAsB;IACxC,SAAS,EAAE,CAAC;IACZ,aAAa,CAAC,IAAI,CAAC,QAAQ,EAAE,aAAa,CAAC,EAAE,IAAI,CAAC,SAAS,CAAC,MAAM,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;AAChF,CAAC;AAED,+EAA+E;AAE/E,SAAS,eAAe,CAAC,QAAyB;IAChD,MAAM,UAAU,GAAG,IAAI,GAAG,EAA0E,CAAC;IAErG,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;QAC7B,MAAM,GAAG,GAAG,GAAG,KAAK,CAAC,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE,CAAC;QACjD,MAAM,QAAQ,GAAG,UAAU,CAAC,GAAG,CAAC,GAAG,CAAC,IAAI,EAAE,OAAO,EAAE,EAAE,EAAE,OAAO,EAAE,CAAC,EAAE,OAAO,EAAE,CAAC,EAAE,CAAC;QAChF,QAAQ,CAAC,OAAO,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAC7B,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB;YAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;QACxD,IAAI,KAAK,CAAC,IAAI,KAAK,gBAAgB;YAAE,QAAQ,CAAC,OAAO,EAAE,CAAC;QACxD,UAAU,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;IAChC,CAAC;IAED,MAAM,KAAK,GAAkB,EAAE,CAAC;IAChC,KAAK,MAAM,CAAC,GAAG,EAAE,IAAI,CAAC,IAAI,UAAU,EAAE,CAAC;QACrC,MAAM,CAAC,OAAO,EAAE,QAAQ,CAAC,GAAG,GAAG,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC;QAC3C,MAAM,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,MAAM,CAAC;QAClC,MAAM,WAAW,GAAG,KAAK,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC,KAAK,GAAG,IAAI,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,CAAC;QACnE,MAAM,UAAU,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,GAAG,GAAG,CAAC,CAAC;QAEjD,sDAAsD;QACtD,IAAI,KAAK,IAAI,CAAC,EAAE,CAAC;YACf,KAAK,CAAC,IAAI,CAAC;gBACT,EAAE,EAAE,WAAW,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE;gBACjC,IAAI,EAAE,GAAG,OAAO,WAAW;gBAC3B,OAAO;gBACP,QAAQ,EAAE,QAAQ,IAAI,KAAK;gBAC3B,UAAU;gBACV,aAAa,EAAE,KAAK;gBACpB,WAAW,EAAE,YAAY,OAAO,cAAc,KAAK,sBAAsB,UAAU,eAAe;aACnG,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,UAAU,GAAG,CAAC,CAAC,UAAU,CAAC,CAAC;AAC3D,CAAC;AAED,+EAA+E;AAE/E,MAAM,UAAU,aAAa,CAAC,IAAc;IAC1C,IAAI,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,IAAI,IAAI,CAAC,QAAQ,CAAC,IAAI,CAAC,EAAE,CAAC;QACnD,OAAO,CAAC,GAAG,CAAC;;;;;;;;;;;;;;;;;;;;;;;;;CAyBf,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,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC/C,MAAM,UAAU,GAAG,IAAI,CAAC,QAAQ,CAAC,YAAY,CAAC,CAAC;IAC/C,MAAM,OAAO,GAAG,IAAI,CAAC,QAAQ,CAAC,QAAQ,CAAC,CAAC;IAExC,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,OAAO,GAA0C;YACrD,EAAE,EAAE,gBAAgB;YACpB,EAAE,EAAE,gBAAgB;YACpB,EAAE,EAAE,SAAS;SACd,CAAC;QACF,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,QAAQ,CAAC,IAAI,IAAI,CAAC;QACvF,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,WAAW,CAAC,IAAI,EAAE,CAAC;QACxF,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,QAAQ,CAAC,IAAI,KAAK,CAAC;QACrF,MAAM,OAAO,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,WAAW,CAAC,IAAI,EAAE,CAAC;QAExF,IAAI,CAAC,OAAO,EAAE,CAAC;YACb,OAAO,CAAC,KAAK,CAAC,yBAAyB,CAAC,CAAC;YACzC,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAkB;YAC3B,EAAE,EAAE,MAAM,IAAI,CAAC,GAAG,EAAE,EAAE;YACtB,IAAI,EAAE,OAAO,CAAC,OAAO,CAAC,IAAI,gBAAgB;YAC1C,OAAO;YACP,QAAQ,EAAE,IAAI;YACd,OAAO;YACP,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QAEF,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;QAChC,QAAQ,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,YAAY,CAAC,QAAQ,CAAC,CAAC;QACvB,OAAO,CAAC,GAAG,CAAC,gBAAgB,KAAK,CAAC,IAAI,kBAAkB,OAAO,MAAM,IAAI,GAAG,CAAC,CAAC;QAC9E,OAAO;IACT,CAAC;IAED,IAAI,UAAU,EAAE,CAAC;QACf,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAAC,EAAU,EAAE,CAAS,EAAE,EAAE,CAAC,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,KAAK,QAAQ,CAAC,IAAI,cAAc,CAAC;QAC9F,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;QAEhC,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,gEAAgE,QAAQ,CAAC,MAAM,IAAI,CAAC,CAAC;YACjG,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;QACxC,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,uDAAuD,CAAC,CAAC;YACrE,OAAO;QACT,CAAC;QAED,MAAM,KAAK,GAAiB;YAC1B,EAAE,EAAE,WAAW,IAAI,EAAE;YACrB,IAAI;YACJ,WAAW,EAAE,6BAA6B,QAAQ,CAAC,MAAM,mBAAmB;YAC5E,KAAK;YACL,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;YACnC,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE;SACpC,CAAC;QAEF,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;QAC5B,MAAM,QAAQ,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,EAAE,KAAK,KAAK,CAAC,EAAE,CAAC,CAAC;QAC5D,IAAI,QAAQ,IAAI,CAAC,EAAE,CAAC;YAClB,MAAM,CAAC,QAAQ,CAAC,GAAG,KAAK,CAAC;QAC3B,CAAC;aAAM,CAAC;YACN,MAAM,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QACrB,CAAC;QACD,UAAU,CAAC,MAAM,CAAC,CAAC;QAEnB,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;YACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QAC9C,CAAC;aAAM,CAAC;YACN,OAAO,CAAC,GAAG,CAAC,0BAA0B,IAAI,EAAE,CAAC,CAAC;YAC9C,OAAO,CAAC,GAAG,CAAC,QAAQ,KAAK,CAAC,MAAM,iBAAiB,QAAQ,CAAC,MAAM,qBAAqB,CAAC,CAAC;YACvF,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;gBACzB,MAAM,IAAI,GAAG,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,IAAI,EAAE,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,IAAI,CAAC;gBAChF,OAAO,CAAC,GAAG,CAAC,QAAQ,IAAI,IAAI,IAAI,CAAC,IAAI,MAAM,IAAI,CAAC,UAAU,iBAAiB,IAAI,CAAC,aAAa,WAAW,CAAC,CAAC;YAC5G,CAAC;YACD,OAAO,CAAC,GAAG,CAAC,gDAAgD,KAAK,CAAC,EAAE,QAAQ,CAAC,CAAC;QAChF,CAAC;QACD,OAAO;IACT,CAAC;IAED,OAAO;IACP,MAAM,QAAQ,GAAG,YAAY,EAAE,CAAC;IAChC,MAAM,MAAM,GAAG,UAAU,EAAE,CAAC;IAE5B,IAAI,MAAM,KAAK,MAAM,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,IAAI,CAAC,SAAS,CAAC,EAAE,QAAQ,EAAE,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,SAAS,EAAE,IAAI,IAAI,EAAE,CAAC,WAAW,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,CAAC;QACjH,OAAO;IACT,CAAC;IAED,OAAO,CAAC,GAAG,CACT,qBAAqB,QAAQ,CAAC,MAAM,sBAAsB,MAAM,CAAC,MAAM,iDAAiD,CACzH,CAAC;IAEF,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACxB,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,gBAAgB,CAAC,CAAC,MAAM,CAAC;QAC3E,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,gBAAgB,CAAC,CAAC,MAAM,CAAC;QAC3E,MAAM,OAAO,GAAG,QAAQ,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC,CAAC,IAAI,KAAK,SAAS,CAAC,CAAC,MAAM,CAAC;QACpE,OAAO,CAAC,GAAG,CAAC,iBAAiB,OAAO,qBAAqB,OAAO,qBAAqB,OAAO,UAAU,CAAC,CAAC;QAExG,MAAM,QAAQ,GAAG,eAAe,CAAC,QAAQ,CAAC,CAAC;QAC3C,IAAI,QAAQ,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;YACxB,OAAO,CAAC,GAAG,CAAC,2BAA2B,QAAQ,CAAC,MAAM,EAAE,CAAC,CAAC;YAC1D,KAAK,MAAM,CAAC,IAAI,QAAQ,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,EAAE,CAAC;gBACrC,OAAO,CAAC,GAAG,CAAC,WAAW,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,UAAU,cAAc,CAAC,CAAC;YACjE,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACtB,OAAO,CAAC,GAAG,CAAC,yBAAyB,CAAC,CAAC;QACvC,KAAK,MAAM,CAAC,IAAI,MAAM,EAAE,CAAC;YACvB,OAAO,CAAC,GAAG,CAAC,YAAY,CAAC,CAAC,IAAI,MAAM,CAAC,CAAC,KAAK,CAAC,MAAM,WAAW,CAAC,CAAC,SAAS,GAAG,CAAC,CAAC;QAC/E,CAAC;IACH,CAAC;IAED,IAAI,QAAQ,CAAC,MAAM,KAAK,CAAC,IAAI,MAAM,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QACjD,OAAO,CAAC,GAAG,CAAC,8DAA8D,CAAC,CAAC;IAC9E,CAAC;IACD,OAAO,CAAC,GAAG,CAAC,EAAE,CAAC,CAAC;AAClB,CAAC"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model report — track which AI model/version produced each finding
|
|
3
|
+
* across evaluation runs. Generates model scorecards with pass rates,
|
|
4
|
+
* failure categories, and vendor-specific blind spots.
|
|
5
|
+
*
|
|
6
|
+
* All data stored locally in `.judges-model-reports/`.
|
|
7
|
+
*/
|
|
8
|
+
export declare function runModelReport(argv: string[]): void;
|
|
9
|
+
//# sourceMappingURL=model-report.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-report.d.ts","sourceRoot":"","sources":["../../src/commands/model-report.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAkHH,wBAAgB,cAAc,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA6HnD"}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Model report — track which AI model/version produced each finding
|
|
3
|
+
* across evaluation runs. Generates model scorecards with pass rates,
|
|
4
|
+
* failure categories, and vendor-specific blind spots.
|
|
5
|
+
*
|
|
6
|
+
* All data stored locally in `.judges-model-reports/`.
|
|
7
|
+
*/
|
|
8
|
+
import { existsSync, readFileSync, writeFileSync, mkdirSync } from "fs";
|
|
9
|
+
import { join } from "path";
|
|
10
|
+
// ─── Storage ────────────────────────────────────────────────────────────────
|
|
11
|
+
const DATA_DIR = ".judges-model-reports";
|
|
12
|
+
function ensureDir() {
|
|
13
|
+
if (!existsSync(DATA_DIR))
|
|
14
|
+
mkdirSync(DATA_DIR, { recursive: true });
|
|
15
|
+
}
|
|
16
|
+
function loadEntries() {
|
|
17
|
+
const file = join(DATA_DIR, "history.json");
|
|
18
|
+
if (!existsSync(file))
|
|
19
|
+
return [];
|
|
20
|
+
try {
|
|
21
|
+
return JSON.parse(readFileSync(file, "utf-8"));
|
|
22
|
+
}
|
|
23
|
+
catch {
|
|
24
|
+
return [];
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
function saveEntries(entries) {
|
|
28
|
+
ensureDir();
|
|
29
|
+
writeFileSync(join(DATA_DIR, "history.json"), JSON.stringify(entries, null, 2));
|
|
30
|
+
}
|
|
31
|
+
// ─── Analysis ───────────────────────────────────────────────────────────────
|
|
32
|
+
function categorizeFindings(content) {
|
|
33
|
+
const cats = {};
|
|
34
|
+
const patterns = [
|
|
35
|
+
["security", /injection|xss|csrf|auth|password|secret|token|key/gi],
|
|
36
|
+
["error-handling", /catch|error|exception|throw|reject|finally/gi],
|
|
37
|
+
["performance", /loop|recursion|allocation|memory|cache|lazy|eager/gi],
|
|
38
|
+
["naming", /naming|variable|identifier|abbreviation|convention/gi],
|
|
39
|
+
["complexity", /complex|nested|depth|cyclomatic|conditional/gi],
|
|
40
|
+
["duplication", /duplicate|copy|clone|repeat|redundant/gi],
|
|
41
|
+
["documentation", /comment|doc|readme|jsdoc|annotation/gi],
|
|
42
|
+
["testing", /test|assert|mock|stub|coverage|spec/gi],
|
|
43
|
+
];
|
|
44
|
+
for (const [cat, re] of patterns) {
|
|
45
|
+
const matches = (content.match(re) || []).length;
|
|
46
|
+
if (matches > 0)
|
|
47
|
+
cats[cat] = matches;
|
|
48
|
+
}
|
|
49
|
+
return cats;
|
|
50
|
+
}
|
|
51
|
+
function generateReports(entries) {
|
|
52
|
+
const models = new Map();
|
|
53
|
+
for (const entry of entries) {
|
|
54
|
+
const list = models.get(entry.model) || [];
|
|
55
|
+
list.push(entry);
|
|
56
|
+
models.set(entry.model, list);
|
|
57
|
+
}
|
|
58
|
+
const reports = [];
|
|
59
|
+
for (const [model, evalList] of models) {
|
|
60
|
+
const avgScore = Math.round(evalList.reduce((s, e) => s + e.score, 0) / evalList.length);
|
|
61
|
+
const avgFindings = Math.round(evalList.reduce((s, e) => s + e.totalFindings, 0) / evalList.length);
|
|
62
|
+
// Aggregate categories
|
|
63
|
+
const catTotals = {};
|
|
64
|
+
for (const e of evalList) {
|
|
65
|
+
for (const [cat, count] of Object.entries(e.categories)) {
|
|
66
|
+
catTotals[cat] = (catTotals[cat] || 0) + count;
|
|
67
|
+
}
|
|
68
|
+
}
|
|
69
|
+
const topCategories = Object.entries(catTotals)
|
|
70
|
+
.sort((a, b) => b[1] - a[1])
|
|
71
|
+
.slice(0, 5)
|
|
72
|
+
.map(([category, count]) => ({ category, count }));
|
|
73
|
+
// Trend
|
|
74
|
+
let trend = "stable";
|
|
75
|
+
if (evalList.length >= 3) {
|
|
76
|
+
const recent = evalList.slice(-3);
|
|
77
|
+
const scoreDiff = recent[recent.length - 1].score - recent[0].score;
|
|
78
|
+
if (scoreDiff > 5)
|
|
79
|
+
trend = "improving";
|
|
80
|
+
else if (scoreDiff < -5)
|
|
81
|
+
trend = "declining";
|
|
82
|
+
}
|
|
83
|
+
reports.push({ model, evaluations: evalList.length, avgScore, avgFindings, topCategories, trend });
|
|
84
|
+
}
|
|
85
|
+
return reports.sort((a, b) => b.avgScore - a.avgScore);
|
|
86
|
+
}
|
|
87
|
+
// ─── CLI ────────────────────────────────────────────────────────────────────
|
|
88
|
+
export function runModelReport(argv) {
|
|
89
|
+
if (argv.includes("--help") || argv.includes("-h")) {
|
|
90
|
+
console.log(`
|
|
91
|
+
judges model-report — AI model scorecard and comparison
|
|
92
|
+
|
|
93
|
+
Usage:
|
|
94
|
+
judges model-report --record --model "gpt-4" --score 85 --findings 3
|
|
95
|
+
judges model-report --record --model "claude-4" --file eval-output.json
|
|
96
|
+
judges model-report --show
|
|
97
|
+
judges model-report --compare
|
|
98
|
+
|
|
99
|
+
Options:
|
|
100
|
+
--record Record a new evaluation entry
|
|
101
|
+
--model <name> Model name/version
|
|
102
|
+
--score <n> Evaluation score (0-100)
|
|
103
|
+
--findings <n> Number of findings
|
|
104
|
+
--file <path> Import findings from evaluation output
|
|
105
|
+
--show Display model scorecards
|
|
106
|
+
--compare Side-by-side model comparison
|
|
107
|
+
--format json JSON output
|
|
108
|
+
--help, -h Show this help
|
|
109
|
+
`);
|
|
110
|
+
return;
|
|
111
|
+
}
|
|
112
|
+
const format = argv.find((_a, i) => argv[i - 1] === "--format") || "text";
|
|
113
|
+
const record = argv.includes("--record");
|
|
114
|
+
const show = argv.includes("--show");
|
|
115
|
+
const compare = argv.includes("--compare");
|
|
116
|
+
const modelName = argv.find((_a, i) => argv[i - 1] === "--model") || "";
|
|
117
|
+
const scoreArg = argv.find((_a, i) => argv[i - 1] === "--score");
|
|
118
|
+
const findingsArg = argv.find((_a, i) => argv[i - 1] === "--findings");
|
|
119
|
+
const fileArg = argv.find((_a, i) => argv[i - 1] === "--file");
|
|
120
|
+
if (record) {
|
|
121
|
+
if (!modelName) {
|
|
122
|
+
console.error(" --model is required for --record");
|
|
123
|
+
return;
|
|
124
|
+
}
|
|
125
|
+
let totalFindings = parseInt(findingsArg || "0");
|
|
126
|
+
let score = parseInt(scoreArg || "0");
|
|
127
|
+
let categories = {};
|
|
128
|
+
if (fileArg && existsSync(fileArg)) {
|
|
129
|
+
try {
|
|
130
|
+
const data = readFileSync(fileArg, "utf-8");
|
|
131
|
+
categories = categorizeFindings(data);
|
|
132
|
+
const parsed = JSON.parse(data);
|
|
133
|
+
if (parsed.findings)
|
|
134
|
+
totalFindings = Array.isArray(parsed.findings) ? parsed.findings.length : totalFindings;
|
|
135
|
+
if (parsed.overallScore)
|
|
136
|
+
score = parsed.overallScore;
|
|
137
|
+
}
|
|
138
|
+
catch {
|
|
139
|
+
/* use manual values */
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
const entry = {
|
|
143
|
+
model: modelName,
|
|
144
|
+
timestamp: new Date().toISOString(),
|
|
145
|
+
totalFindings,
|
|
146
|
+
criticalCount: 0,
|
|
147
|
+
highCount: 0,
|
|
148
|
+
mediumCount: Math.round(totalFindings * 0.6),
|
|
149
|
+
lowCount: Math.round(totalFindings * 0.4),
|
|
150
|
+
score,
|
|
151
|
+
categories,
|
|
152
|
+
};
|
|
153
|
+
const entries = loadEntries();
|
|
154
|
+
entries.push(entry);
|
|
155
|
+
saveEntries(entries);
|
|
156
|
+
console.log(` ✅ Recorded evaluation for ${modelName} (score: ${score}, findings: ${totalFindings})`);
|
|
157
|
+
return;
|
|
158
|
+
}
|
|
159
|
+
const entries = loadEntries();
|
|
160
|
+
if (entries.length === 0) {
|
|
161
|
+
console.log(" No model data recorded yet. Use --record to add evaluations.");
|
|
162
|
+
return;
|
|
163
|
+
}
|
|
164
|
+
const reports = generateReports(entries);
|
|
165
|
+
if (format === "json") {
|
|
166
|
+
console.log(JSON.stringify({ reports, totalEntries: entries.length, timestamp: new Date().toISOString() }, null, 2));
|
|
167
|
+
return;
|
|
168
|
+
}
|
|
169
|
+
if (compare) {
|
|
170
|
+
console.log(`\n Model Comparison — ${reports.length} models\n ──────────────────────────`);
|
|
171
|
+
console.log(` ${"Model".padEnd(25)} ${"Evals".padEnd(8)} ${"Avg Score".padEnd(12)} ${"Avg Findings".padEnd(14)} Trend`);
|
|
172
|
+
console.log(` ${"─".repeat(25)} ${"─".repeat(8)} ${"─".repeat(12)} ${"─".repeat(14)} ${"─".repeat(10)}`);
|
|
173
|
+
for (const r of reports) {
|
|
174
|
+
const trendIcon = r.trend === "improving" ? "📈" : r.trend === "declining" ? "📉" : "➡️";
|
|
175
|
+
console.log(` ${r.model.padEnd(25)} ${String(r.evaluations).padEnd(8)} ${String(r.avgScore).padEnd(12)} ${String(r.avgFindings).padEnd(14)} ${trendIcon} ${r.trend}`);
|
|
176
|
+
}
|
|
177
|
+
console.log("");
|
|
178
|
+
return;
|
|
179
|
+
}
|
|
180
|
+
// Show (default)
|
|
181
|
+
if (show || !compare) {
|
|
182
|
+
console.log(`\n Model Report Cards — ${entries.length} evaluations across ${reports.length} models\n ──────────────────────────`);
|
|
183
|
+
for (const r of reports) {
|
|
184
|
+
const icon = r.avgScore >= 80 ? "🟢" : r.avgScore >= 60 ? "🟡" : "🔴";
|
|
185
|
+
const trendIcon = r.trend === "improving" ? "📈" : r.trend === "declining" ? "📉" : "➡️";
|
|
186
|
+
console.log(`\n ${icon} ${r.model}`);
|
|
187
|
+
console.log(` Score: ${r.avgScore}/100 | Findings: ${r.avgFindings} avg | Evals: ${r.evaluations} | ${trendIcon} ${r.trend}`);
|
|
188
|
+
if (r.topCategories.length > 0) {
|
|
189
|
+
console.log(` Top issues: ${r.topCategories.map((c) => `${c.category}(${c.count})`).join(", ")}`);
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
console.log("");
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
//# sourceMappingURL=model-report.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"model-report.js","sourceRoot":"","sources":["../../src/commands/model-report.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,9 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Refactor safety — analyze proposed refactorings for breaking changes,
|
|
3
|
+
* incomplete migrations, orphaned references, and behavioral changes.
|
|
4
|
+
*
|
|
5
|
+
* Compares two directory snapshots or a list of changed files against
|
|
6
|
+
* the broader codebase to detect incomplete refactors.
|
|
7
|
+
*/
|
|
8
|
+
export declare function runRefactorSafety(argv: string[]): void;
|
|
9
|
+
//# sourceMappingURL=refactor-safety.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"refactor-safety.d.ts","sourceRoot":"","sources":["../../src/commands/refactor-safety.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AA4NH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,IAAI,CA4EtD"}
|