@nebulord/sickbay 0.1.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/README.md +231 -0
- package/dist/DiffApp-YF2PYQZK.js +187 -0
- package/dist/DoctorApp-U465IMK7.js +447 -0
- package/dist/FixApp-RJPCWNXJ.js +344 -0
- package/dist/StatsApp-BI6COY7S.js +375 -0
- package/dist/TrendApp-XL77HKDR.js +118 -0
- package/dist/TuiApp-VJNV4FD3.js +982 -0
- package/dist/ai-7DGOLNJX.js +64 -0
- package/dist/badge-KQ73KEIN.js +41 -0
- package/dist/chunk-5KJOYSVJ.js +95 -0
- package/dist/chunk-BIK4EL4H.js +19 -0
- package/dist/chunk-BUD5BE6U.js +61 -0
- package/dist/chunk-D24FSOW4.js +22 -0
- package/dist/chunk-POUHUMJN.js +21 -0
- package/dist/chunk-SSUXSMGH.js +25 -0
- package/dist/history-DYFJ65XH.js +14 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +535 -0
- package/dist/init-J2NPRPDO.js +54 -0
- package/dist/resolve-package-PHPJWOLY.js +8 -0
- package/dist/web-EE2VYPEX.js +198 -0
- package/package.json +58 -0
|
@@ -0,0 +1,344 @@
|
|
|
1
|
+
import {
|
|
2
|
+
ProgressList
|
|
3
|
+
} from "./chunk-D24FSOW4.js";
|
|
4
|
+
import {
|
|
5
|
+
Header
|
|
6
|
+
} from "./chunk-BIK4EL4H.js";
|
|
7
|
+
import {
|
|
8
|
+
shortName
|
|
9
|
+
} from "./chunk-BUD5BE6U.js";
|
|
10
|
+
|
|
11
|
+
// src/components/FixApp.tsx
|
|
12
|
+
import React, { useState, useEffect, useCallback } from "react";
|
|
13
|
+
import { Box, Text, useApp, useInput } from "ink";
|
|
14
|
+
import Spinner from "ink-spinner";
|
|
15
|
+
import { runSickbay } from "@nebulord/sickbay-core";
|
|
16
|
+
|
|
17
|
+
// src/commands/fix.ts
|
|
18
|
+
import { execFile } from "child_process";
|
|
19
|
+
import { promisify } from "util";
|
|
20
|
+
var execFileAsync = promisify(execFile);
|
|
21
|
+
function collectFixableIssues(report) {
|
|
22
|
+
const seen = /* @__PURE__ */ new Set();
|
|
23
|
+
const fixable = [];
|
|
24
|
+
for (const check of report.checks) {
|
|
25
|
+
for (const issue of check.issues) {
|
|
26
|
+
if (issue.fix) {
|
|
27
|
+
const dedupeKey = issue.fix.command ?? issue.fix.description;
|
|
28
|
+
if (!seen.has(dedupeKey)) {
|
|
29
|
+
seen.add(dedupeKey);
|
|
30
|
+
fixable.push({
|
|
31
|
+
issue,
|
|
32
|
+
checkId: check.id,
|
|
33
|
+
checkName: check.name,
|
|
34
|
+
command: issue.fix.command
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
}
|
|
39
|
+
}
|
|
40
|
+
const order = { critical: 0, warning: 1, info: 2 };
|
|
41
|
+
fixable.sort((a, b) => order[a.issue.severity] - order[b.issue.severity]);
|
|
42
|
+
return fixable;
|
|
43
|
+
}
|
|
44
|
+
async function executeFix(fix, projectPath) {
|
|
45
|
+
const start = Date.now();
|
|
46
|
+
if (!fix.command) {
|
|
47
|
+
return {
|
|
48
|
+
fixable: fix,
|
|
49
|
+
success: false,
|
|
50
|
+
stdout: "",
|
|
51
|
+
stderr: "No command to execute (guidance-only fix)",
|
|
52
|
+
duration: 0
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
try {
|
|
56
|
+
const parts = fix.command.split(/\s+/);
|
|
57
|
+
const cmd = parts[0];
|
|
58
|
+
const args = parts.slice(1);
|
|
59
|
+
const { stdout, stderr } = await execFileAsync(cmd, args, {
|
|
60
|
+
cwd: projectPath,
|
|
61
|
+
timeout: 6e4,
|
|
62
|
+
shell: true
|
|
63
|
+
});
|
|
64
|
+
return {
|
|
65
|
+
fixable: fix,
|
|
66
|
+
success: true,
|
|
67
|
+
stdout: stdout ?? "",
|
|
68
|
+
stderr: stderr ?? "",
|
|
69
|
+
duration: Date.now() - start
|
|
70
|
+
};
|
|
71
|
+
} catch (err) {
|
|
72
|
+
return {
|
|
73
|
+
fixable: fix,
|
|
74
|
+
success: false,
|
|
75
|
+
stdout: "",
|
|
76
|
+
stderr: err instanceof Error ? err.message : String(err),
|
|
77
|
+
duration: Date.now() - start
|
|
78
|
+
};
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
// src/components/FixApp.tsx
|
|
83
|
+
var SEVERITY_COLOR = {
|
|
84
|
+
critical: "red",
|
|
85
|
+
warning: "yellow",
|
|
86
|
+
info: "gray"
|
|
87
|
+
};
|
|
88
|
+
function FixApp({
|
|
89
|
+
projectPath,
|
|
90
|
+
checks,
|
|
91
|
+
applyAll,
|
|
92
|
+
dryRun,
|
|
93
|
+
verbose,
|
|
94
|
+
isMonorepo,
|
|
95
|
+
packagePaths,
|
|
96
|
+
packageNames
|
|
97
|
+
}) {
|
|
98
|
+
const { exit } = useApp();
|
|
99
|
+
const [phase, setPhase] = useState("scanning");
|
|
100
|
+
const [fixableIssues, setFixableIssues] = useState(
|
|
101
|
+
[]
|
|
102
|
+
);
|
|
103
|
+
const [selected, setSelected] = useState(/* @__PURE__ */ new Set());
|
|
104
|
+
const [cursor, setCursor] = useState(0);
|
|
105
|
+
const [results, setResults] = useState([]);
|
|
106
|
+
const [currentFixIndex, setCurrentFixIndex] = useState(0);
|
|
107
|
+
const [error, setError] = useState(null);
|
|
108
|
+
const [progress, setProgress] = useState([]);
|
|
109
|
+
const [projectName, setProjectName] = useState();
|
|
110
|
+
const [confirmQueue, setConfirmQueue] = useState([]);
|
|
111
|
+
const [confirmIndex, setConfirmIndex] = useState(0);
|
|
112
|
+
const [confirmedFixes, setConfirmedFixes] = useState([]);
|
|
113
|
+
useEffect(() => {
|
|
114
|
+
if (isMonorepo && packagePaths && packageNames) {
|
|
115
|
+
const pkgItems = packagePaths.map((p) => ({
|
|
116
|
+
name: shortName(packageNames.get(p) ?? p),
|
|
117
|
+
status: "pending"
|
|
118
|
+
}));
|
|
119
|
+
setProgress(pkgItems);
|
|
120
|
+
(async () => {
|
|
121
|
+
try {
|
|
122
|
+
const allFixable = [];
|
|
123
|
+
for (const pkgPath of packagePaths) {
|
|
124
|
+
const pkgName = packageNames.get(pkgPath) ?? pkgPath;
|
|
125
|
+
const display = shortName(pkgName);
|
|
126
|
+
setProgress(
|
|
127
|
+
(prev) => prev.map(
|
|
128
|
+
(p) => p.name === display ? { ...p, status: "running" } : p
|
|
129
|
+
)
|
|
130
|
+
);
|
|
131
|
+
const report = await runSickbay({
|
|
132
|
+
projectPath: pkgPath,
|
|
133
|
+
checks,
|
|
134
|
+
verbose
|
|
135
|
+
});
|
|
136
|
+
const fixable = collectFixableIssues(report);
|
|
137
|
+
for (const fix of fixable) {
|
|
138
|
+
allFixable.push({
|
|
139
|
+
...fix,
|
|
140
|
+
packageName: pkgName,
|
|
141
|
+
packagePath: pkgPath
|
|
142
|
+
});
|
|
143
|
+
}
|
|
144
|
+
setProgress(
|
|
145
|
+
(prev) => prev.map(
|
|
146
|
+
(p) => p.name === display ? { ...p, status: "done" } : p
|
|
147
|
+
)
|
|
148
|
+
);
|
|
149
|
+
}
|
|
150
|
+
setFixableIssues(allFixable);
|
|
151
|
+
const hasActionable = allFixable.some((f) => f.command);
|
|
152
|
+
if (!hasActionable) {
|
|
153
|
+
setPhase("done");
|
|
154
|
+
} else if (applyAll) {
|
|
155
|
+
setSelected(new Set(allFixable.map((_, i) => i)));
|
|
156
|
+
startConfirmation(allFixable, new Set(allFixable.map((_, i) => i)), true);
|
|
157
|
+
} else {
|
|
158
|
+
setPhase("selecting");
|
|
159
|
+
}
|
|
160
|
+
} catch (err) {
|
|
161
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
162
|
+
setPhase("error");
|
|
163
|
+
setTimeout(() => exit(), 100);
|
|
164
|
+
}
|
|
165
|
+
})();
|
|
166
|
+
} else {
|
|
167
|
+
const initial = (checks ?? [
|
|
168
|
+
"knip",
|
|
169
|
+
"depcheck",
|
|
170
|
+
"npm-check-updates",
|
|
171
|
+
"npm-audit",
|
|
172
|
+
"madge",
|
|
173
|
+
"source-map-explorer",
|
|
174
|
+
"coverage",
|
|
175
|
+
"license-checker",
|
|
176
|
+
"jscpd",
|
|
177
|
+
"git",
|
|
178
|
+
"eslint",
|
|
179
|
+
"typescript",
|
|
180
|
+
"todo-scanner",
|
|
181
|
+
"complexity",
|
|
182
|
+
"secrets",
|
|
183
|
+
"heavy-deps",
|
|
184
|
+
"react-perf",
|
|
185
|
+
"asset-size"
|
|
186
|
+
]).map((name) => ({ name, status: "pending" }));
|
|
187
|
+
setProgress(initial);
|
|
188
|
+
runSickbay({
|
|
189
|
+
projectPath,
|
|
190
|
+
checks,
|
|
191
|
+
verbose,
|
|
192
|
+
onCheckStart: (name) => {
|
|
193
|
+
setProgress(
|
|
194
|
+
(prev) => prev.map(
|
|
195
|
+
(p) => p.name === name ? { ...p, status: "running" } : p
|
|
196
|
+
)
|
|
197
|
+
);
|
|
198
|
+
},
|
|
199
|
+
onCheckComplete: (result) => {
|
|
200
|
+
setProgress(
|
|
201
|
+
(prev) => prev.map(
|
|
202
|
+
(p) => p.name === result.id ? { ...p, status: "done" } : p
|
|
203
|
+
)
|
|
204
|
+
);
|
|
205
|
+
}
|
|
206
|
+
}).then((r) => {
|
|
207
|
+
setProjectName(r.projectInfo.name);
|
|
208
|
+
const fixable = collectFixableIssues(r);
|
|
209
|
+
const tagged = fixable.map((f) => ({
|
|
210
|
+
...f,
|
|
211
|
+
packageName: r.projectInfo.name,
|
|
212
|
+
packagePath: projectPath
|
|
213
|
+
}));
|
|
214
|
+
setFixableIssues(tagged);
|
|
215
|
+
const hasActionable = tagged.some((f) => f.command);
|
|
216
|
+
if (!hasActionable) {
|
|
217
|
+
setPhase("done");
|
|
218
|
+
} else if (applyAll) {
|
|
219
|
+
setSelected(new Set(fixable.map((_, i) => i)));
|
|
220
|
+
startConfirmation(tagged, new Set(fixable.map((_, i) => i)), true);
|
|
221
|
+
} else {
|
|
222
|
+
setPhase("selecting");
|
|
223
|
+
}
|
|
224
|
+
}).catch((err) => {
|
|
225
|
+
setError(err instanceof Error ? err.message : String(err));
|
|
226
|
+
setPhase("error");
|
|
227
|
+
setTimeout(() => exit(), 100);
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}, []);
|
|
231
|
+
function startConfirmation(issues, selectedSet, isApplyAll) {
|
|
232
|
+
const actionable = issues.filter((f, i) => selectedSet.has(i) && f.command);
|
|
233
|
+
if (isApplyAll) {
|
|
234
|
+
const tier2 = actionable.filter((f) => f.issue.fix?.modifiesSource);
|
|
235
|
+
const autoApproved = actionable.filter((f) => !f.issue.fix?.modifiesSource);
|
|
236
|
+
if (tier2.length === 0) {
|
|
237
|
+
setConfirmedFixes(autoApproved);
|
|
238
|
+
setPhase("fixing");
|
|
239
|
+
return;
|
|
240
|
+
}
|
|
241
|
+
setConfirmedFixes(autoApproved);
|
|
242
|
+
setConfirmQueue(tier2);
|
|
243
|
+
} else {
|
|
244
|
+
setConfirmedFixes([]);
|
|
245
|
+
setConfirmQueue(actionable);
|
|
246
|
+
}
|
|
247
|
+
setConfirmIndex(0);
|
|
248
|
+
if (actionable.length === 0) {
|
|
249
|
+
setPhase("done");
|
|
250
|
+
setTimeout(() => exit(), 100);
|
|
251
|
+
return;
|
|
252
|
+
}
|
|
253
|
+
setPhase("confirming");
|
|
254
|
+
}
|
|
255
|
+
useEffect(() => {
|
|
256
|
+
if (phase !== "fixing") return;
|
|
257
|
+
const toFix = confirmedFixes;
|
|
258
|
+
if (toFix.length === 0) {
|
|
259
|
+
setPhase("done");
|
|
260
|
+
setTimeout(() => exit(), 100);
|
|
261
|
+
return;
|
|
262
|
+
}
|
|
263
|
+
(async () => {
|
|
264
|
+
const fixResults = [];
|
|
265
|
+
for (let i = 0; i < toFix.length; i++) {
|
|
266
|
+
setCurrentFixIndex(i);
|
|
267
|
+
if (dryRun) {
|
|
268
|
+
fixResults.push({
|
|
269
|
+
fixable: toFix[i],
|
|
270
|
+
success: true,
|
|
271
|
+
stdout: "(dry run)",
|
|
272
|
+
stderr: "",
|
|
273
|
+
duration: 0
|
|
274
|
+
});
|
|
275
|
+
} else {
|
|
276
|
+
const result = await executeFix(toFix[i], toFix[i].packagePath);
|
|
277
|
+
fixResults.push(result);
|
|
278
|
+
}
|
|
279
|
+
setResults([...fixResults]);
|
|
280
|
+
}
|
|
281
|
+
setPhase("done");
|
|
282
|
+
setTimeout(() => exit(), 100);
|
|
283
|
+
})();
|
|
284
|
+
}, [phase]);
|
|
285
|
+
const handleInput = useCallback(
|
|
286
|
+
(input, key) => {
|
|
287
|
+
if (phase === "selecting") {
|
|
288
|
+
const actionable = fixableIssues.filter((f) => f.command);
|
|
289
|
+
if (key.upArrow) {
|
|
290
|
+
setCursor((c) => Math.max(0, c - 1));
|
|
291
|
+
} else if (key.downArrow) {
|
|
292
|
+
setCursor((c) => Math.min(actionable.length - 1, c + 1));
|
|
293
|
+
} else if (input === " ") {
|
|
294
|
+
setSelected((prev) => {
|
|
295
|
+
const next = new Set(prev);
|
|
296
|
+
if (next.has(cursor)) {
|
|
297
|
+
next.delete(cursor);
|
|
298
|
+
} else {
|
|
299
|
+
next.add(cursor);
|
|
300
|
+
}
|
|
301
|
+
return next;
|
|
302
|
+
});
|
|
303
|
+
} else if (input === "a") {
|
|
304
|
+
setSelected(new Set(actionable.map((_, i) => i)));
|
|
305
|
+
} else if (input === "n") {
|
|
306
|
+
setSelected(/* @__PURE__ */ new Set());
|
|
307
|
+
} else if (key.return) {
|
|
308
|
+
if (selected.size > 0) {
|
|
309
|
+
const selectedIssues = actionable.filter((_, i) => selected.has(i));
|
|
310
|
+
startConfirmation(selectedIssues, new Set(selectedIssues.map((_, i) => i)), false);
|
|
311
|
+
}
|
|
312
|
+
}
|
|
313
|
+
} else if (phase === "confirming") {
|
|
314
|
+
const lower = input.toLowerCase();
|
|
315
|
+
if (lower === "y" || key.return) {
|
|
316
|
+
setConfirmedFixes((prev) => [...prev, confirmQueue[confirmIndex]]);
|
|
317
|
+
if (confirmIndex + 1 < confirmQueue.length) {
|
|
318
|
+
setConfirmIndex((i) => i + 1);
|
|
319
|
+
} else {
|
|
320
|
+
setPhase("fixing");
|
|
321
|
+
}
|
|
322
|
+
} else if (lower === "n") {
|
|
323
|
+
if (confirmIndex + 1 < confirmQueue.length) {
|
|
324
|
+
setConfirmIndex((i) => i + 1);
|
|
325
|
+
} else {
|
|
326
|
+
setPhase("fixing");
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
}
|
|
330
|
+
},
|
|
331
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
332
|
+
[phase, cursor, selected, confirmIndex, confirmQueue, fixableIssues]
|
|
333
|
+
);
|
|
334
|
+
useInput(handleInput);
|
|
335
|
+
const currentConfirmFix = confirmQueue[confirmIndex];
|
|
336
|
+
const isTier2 = currentConfirmFix?.issue.fix?.modifiesSource;
|
|
337
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", padding: 1 }, /* @__PURE__ */ React.createElement(Header, { projectName }), phase === "scanning" && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Scanning for fixable issues", isMonorepo ? ` across ${packagePaths?.length} packages` : "", "..."), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, marginLeft: 2 }, /* @__PURE__ */ React.createElement(ProgressList, { items: progress }))), phase === "error" && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "red" }, "\u2717 Error: ", error)), phase === "selecting" && (() => {
|
|
338
|
+
const actionable = fixableIssues.filter((f) => f.command);
|
|
339
|
+
return /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "\u26A0 "), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Sickbay can make mistakes. Review each fix before applying \u2014 false positives exist and some commands modify your project.")), /* @__PURE__ */ React.createElement(Text, { bold: true }, "Select fixes to apply (", actionable.length, " available)"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1, marginLeft: 2 }, actionable.map((fix, i) => /* @__PURE__ */ React.createElement(Box, { key: `${fix.packageName}-${fix.checkId}-${fix.command}` }, /* @__PURE__ */ React.createElement(Text, { color: i === cursor ? "cyan" : void 0 }, i === cursor ? "\u276F " : " "), /* @__PURE__ */ React.createElement(Text, { color: i === cursor ? "cyan" : void 0 }, selected.has(i) ? "[\u2713] " : "[ ] "), isMonorepo && /* @__PURE__ */ React.createElement(Text, { color: "magenta", dimColor: true }, "[", shortName(fix.packageName), "]", " "), /* @__PURE__ */ React.createElement(Text, { color: SEVERITY_COLOR[fix.issue.severity] }, fix.issue.fix.description), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " (", fix.command, ")")))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\u2191\u2193 navigate \xB7 space toggle \xB7 a all \xB7 n none \xB7 enter confirm", selected.size > 0 && ` (${selected.size} selected)`)), dryRun && /* @__PURE__ */ React.createElement(Box, { marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "\u26A0 Dry run mode \u2014 no changes will be made")));
|
|
340
|
+
})(), phase === "confirming" && currentConfirmFix && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true }, "Confirming fixes (", confirmIndex + 1, "/", confirmQueue.length, ")"), /* @__PURE__ */ React.createElement(Box, { marginTop: 1, marginLeft: 2, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, null, currentConfirmFix.issue.fix.description, " (", currentConfirmFix.command, ")"), isTier2 ? /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "\u26A0 This will modify source files. Proceed? (Y/n)") : /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\u2192 Proceed? (Y/n)"))), phase === "fixing" && !dryRun && /* @__PURE__ */ React.createElement(Box, { marginBottom: 1 }, /* @__PURE__ */ React.createElement(Text, { color: "yellow" }, "\u26A0 "), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Sickbay can make mistakes \u2014 verify results afterwards and revert anything that looks wrong.")), phase === "fixing" && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Text, { bold: true }, dryRun ? "Dry run" : "Applying fixes", "... (", results.length, "/", confirmedFixes.length, ")"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1, marginLeft: 2 }, results.map((r) => /* @__PURE__ */ React.createElement(Box, { key: `${r.fixable.checkId}-${r.fixable.command ?? r.fixable.issue.fix?.description}`, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: r.success ? "green" : "red" }, r.success ? "\u2713" : "\u2717", " "), isMonorepo && /* @__PURE__ */ React.createElement(Text, { color: "magenta", dimColor: true }, "[", shortName(r.fixable.packageName), "]", " "), /* @__PURE__ */ React.createElement(Text, null, r.fixable.issue.fix.description)), r.success && r.fixable.issue.fix?.nextSteps && /* @__PURE__ */ React.createElement(Box, { marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2192 Next: ", r.fixable.issue.fix.nextSteps)))), results.length < confirmedFixes.length && /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "green" }, /* @__PURE__ */ React.createElement(Spinner, { type: "dots" })), /* @__PURE__ */ React.createElement(Text, null, " ", confirmedFixes[currentFixIndex]?.issue.fix.description)))), phase === "done" && /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, results.length === 0 ? /* @__PURE__ */ React.createElement(Box, { flexDirection: "column" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: "green" }, "\u2713 "), /* @__PURE__ */ React.createElement(Text, null, "No auto-fixable issues found", isMonorepo ? " across any package" : "")), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Run ", /* @__PURE__ */ React.createElement(Text, { color: "cyan" }, "sickbay"), " to see the full report \u2014 there may be issues that require manual attention."))) : /* @__PURE__ */ React.createElement(React.Fragment, null, /* @__PURE__ */ React.createElement(Text, { bold: true }, dryRun ? "Dry Run Results" : "Fix Results"), /* @__PURE__ */ React.createElement(Box, { flexDirection: "column", marginTop: 1, marginLeft: 2 }, results.map((r) => /* @__PURE__ */ React.createElement(Box, { key: `${r.fixable.checkId}-${r.fixable.command ?? r.fixable.issue.fix?.description}`, flexDirection: "column" }, /* @__PURE__ */ React.createElement(Box, null, /* @__PURE__ */ React.createElement(Text, { color: r.success ? "green" : "red" }, r.success ? "\u2713" : "\u2717", " "), isMonorepo && /* @__PURE__ */ React.createElement(Text, { color: "magenta", dimColor: true }, "[", shortName(r.fixable.packageName), "]", " "), /* @__PURE__ */ React.createElement(Text, null, r.fixable.issue.fix.description), r.duration > 0 && /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " (", r.duration, "ms)")), r.success && r.fixable.issue.fix?.nextSteps && /* @__PURE__ */ React.createElement(Box, { marginLeft: 2 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " \u2192 Next: ", r.fixable.issue.fix.nextSteps))))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "\u2501".repeat(52))), /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { bold: true }, results.filter((r) => r.success).length, "/", results.length, " ", "fixes ", dryRun ? "would be applied" : "applied successfully")), !dryRun && results.some((r) => r.success) && /* @__PURE__ */ React.createElement(Box, { marginTop: 1 }, /* @__PURE__ */ React.createElement(Text, { dimColor: true }, "Run "), /* @__PURE__ */ React.createElement(Text, { color: "cyan" }, "sickbay"), /* @__PURE__ */ React.createElement(Text, { dimColor: true }, " to see your updated score")))));
|
|
341
|
+
}
|
|
342
|
+
export {
|
|
343
|
+
FixApp
|
|
344
|
+
};
|