@kaynooo/cli-doctor 0.12.0 → 0.13.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 +6 -0
- package/dist/cli-bin.js +333 -95
- package/dist/cli.js +268 -94
- package/package.json +2 -2
package/dist/cli.js
CHANGED
|
@@ -2,13 +2,13 @@
|
|
|
2
2
|
// @bun
|
|
3
3
|
|
|
4
4
|
// src/cli.ts
|
|
5
|
-
import
|
|
5
|
+
import process20 from "process";
|
|
6
6
|
// ../kit/src/args.ts
|
|
7
|
-
import
|
|
7
|
+
import process9 from "process";
|
|
8
8
|
import { parseArgs } from "util";
|
|
9
9
|
|
|
10
10
|
// ../kit/src/format.ts
|
|
11
|
-
import
|
|
11
|
+
import process7 from "process";
|
|
12
12
|
|
|
13
13
|
// ../kit/src/mode.ts
|
|
14
14
|
import process2 from "process";
|
|
@@ -32,7 +32,7 @@ function isInteractive(streams = process2) {
|
|
|
32
32
|
}
|
|
33
33
|
|
|
34
34
|
// ../kit/src/style.ts
|
|
35
|
-
import
|
|
35
|
+
import process6 from "process";
|
|
36
36
|
|
|
37
37
|
// ../../node_modules/.bun/@kaynooo+utils@2.31.2+d0769e28dc4dad16/node_modules/@kaynooo/utils/dist/chunk-mtetydvc.js
|
|
38
38
|
function x(s) {
|
|
@@ -295,28 +295,188 @@ function le(i = {}) {
|
|
|
295
295
|
}
|
|
296
296
|
var t = le();
|
|
297
297
|
|
|
298
|
+
// ../kit/src/theme.ts
|
|
299
|
+
import { existsSync as existsSync3, readFileSync, statSync } from "fs";
|
|
300
|
+
import { homedir as homedir2 } from "os";
|
|
301
|
+
import { join as join3, resolve as resolve2 } from "path";
|
|
302
|
+
import process5 from "process";
|
|
303
|
+
|
|
304
|
+
// ../kit/src/config.ts
|
|
305
|
+
import { existsSync } from "fs";
|
|
306
|
+
import { dirname, join, resolve } from "path";
|
|
307
|
+
import process3 from "process";
|
|
308
|
+
function findUp(names, from = process3.cwd(), stop = () => false) {
|
|
309
|
+
const wanted = typeof names === "string" ? [names] : names;
|
|
310
|
+
for (let dir = resolve(from);; dir = dirname(dir)) {
|
|
311
|
+
const found = wanted.map((name) => join(dir, name)).find((path) => existsSync(path));
|
|
312
|
+
if (found !== undefined)
|
|
313
|
+
return found;
|
|
314
|
+
if (stop(dir) || dirname(dir) === dir)
|
|
315
|
+
return;
|
|
316
|
+
}
|
|
317
|
+
}
|
|
318
|
+
|
|
298
319
|
// ../kit/src/user-config.ts
|
|
320
|
+
import { existsSync as existsSync2 } from "fs";
|
|
299
321
|
import { homedir } from "os";
|
|
300
|
-
import { join } from "path";
|
|
301
|
-
import
|
|
322
|
+
import { join as join2 } from "path";
|
|
323
|
+
import process4 from "process";
|
|
302
324
|
function configBase(where = {}) {
|
|
303
|
-
const xdg = where.xdg ?? (where.home === undefined ?
|
|
304
|
-
return xdg !== undefined && xdg !== "" ? xdg :
|
|
325
|
+
const xdg = where.xdg ?? (where.home === undefined ? process4.env.XDG_CONFIG_HOME : undefined);
|
|
326
|
+
return xdg !== undefined && xdg !== "" ? xdg : join2(where.home ?? homedir(), ".config");
|
|
305
327
|
}
|
|
306
328
|
function userConfigPath(bin, where = {}) {
|
|
307
|
-
return
|
|
329
|
+
return join2(configBase(where), "kaynooo-cli", `${bin}.json`);
|
|
330
|
+
}
|
|
331
|
+
function userConfigReadPath(bin, legacy = [], where = {}) {
|
|
332
|
+
const current = userConfigPath(bin, where);
|
|
333
|
+
if (existsSync2(current))
|
|
334
|
+
return current;
|
|
335
|
+
const base = configBase(where);
|
|
336
|
+
return legacy.map((parts) => join2(base, ...parts)).find((path) => existsSync2(path)) ?? current;
|
|
308
337
|
}
|
|
309
338
|
|
|
310
339
|
// ../kit/src/theme.ts
|
|
340
|
+
var DEFAULT = {
|
|
341
|
+
colors: { accent: "cyan", id: "yellow", path: "blue", label: "dim", value: "bold", ok: "green", warn: "yellow", problem: "red", note: "dim", passed: "green", failed: "red", running: "cyan", queued: "yellow", skipped: "dim" },
|
|
342
|
+
glyphs: { ok: "\u2713", warn: "\u25B2", problem: "\u2717", note: "\u203A", passed: "\u2713", failed: "\u2717", running: "\u25CF", queued: "\u25CB", skipped: "-", bar: "\u2501" },
|
|
343
|
+
accents: ["cyan", "magenta", "green", "blue", "yellow", "redBright"],
|
|
344
|
+
bins: {}
|
|
345
|
+
};
|
|
346
|
+
var BRIGHT = { accent: "cyanBright", id: "yellowBright", path: "blueBright", label: "white", value: "bold whiteBright", ok: "greenBright", warn: "yellowBright", problem: "redBright", note: "white", passed: "greenBright", failed: "redBright", running: "cyanBright", queued: "yellowBright", skipped: "white" };
|
|
347
|
+
var MONO = { accent: "bold", id: "bold", path: "underline", label: "dim", value: "bold", ok: "bold", warn: "bold", problem: "bold", note: "dim", passed: "bold", failed: "bold", running: "bold", queued: "dim", skipped: "dim" };
|
|
348
|
+
var ASCII = { ok: "+", warn: "!", problem: "x", note: ">", passed: "+", failed: "x", running: "*", queued: "o", skipped: "-", bar: "#" };
|
|
349
|
+
var PRESETS = {
|
|
350
|
+
default: {},
|
|
351
|
+
"high-contrast": { colors: BRIGHT, accents: ["cyanBright", "magentaBright", "greenBright", "blueBright", "yellowBright", "redBright"] },
|
|
352
|
+
mono: { colors: MONO, accents: ["bold"] },
|
|
353
|
+
ascii: { glyphs: ASCII }
|
|
354
|
+
};
|
|
311
355
|
var STYLES = new Set(["bold", "dim", "italic", "underline", "inverse", "strikethrough", "black", "red", "green", "yellow", "blue", "magenta", "cyan", "white", "gray", "grey", "blackBright", "redBright", "greenBright", "yellowBright", "blueBright", "magentaBright", "cyanBright", "whiteBright"]);
|
|
356
|
+
var HEX = /^#[0-9a-f]{6}$/i;
|
|
357
|
+
var CONTROL = /\p{Cc}/u;
|
|
312
358
|
var MAX_FILE_BYTES = 64 * 1024;
|
|
359
|
+
var SPACES = /\s+/;
|
|
360
|
+
function isColorSpec(spec) {
|
|
361
|
+
if (typeof spec === "number")
|
|
362
|
+
return Number.isInteger(spec) && spec >= 0 && spec <= 255;
|
|
363
|
+
return typeof spec === "string" && spec.trim() !== "" && spec.trim().split(SPACES).every((token) => STYLES.has(token) || HEX.test(token));
|
|
364
|
+
}
|
|
365
|
+
function isRecord(value) {
|
|
366
|
+
return typeof value === "object" && value !== null && !Array.isArray(value);
|
|
367
|
+
}
|
|
368
|
+
function readThemeFile(path, warn) {
|
|
369
|
+
try {
|
|
370
|
+
const stat = statSync(path, { throwIfNoEntry: false });
|
|
371
|
+
if (stat === undefined)
|
|
372
|
+
return;
|
|
373
|
+
if (!stat.isFile() || stat.size > MAX_FILE_BYTES) {
|
|
374
|
+
warn(`${path} is not a regular file under ${MAX_FILE_BYTES / 1024} KiB, theme ignored`);
|
|
375
|
+
return;
|
|
376
|
+
}
|
|
377
|
+
const parsed = JSON.parse(readFileSync(path, "utf8"));
|
|
378
|
+
if (isRecord(parsed))
|
|
379
|
+
return parsed;
|
|
380
|
+
warn(`${path} is not a JSON object, theme ignored`);
|
|
381
|
+
} catch (error) {
|
|
382
|
+
warn(`${path} does not parse (${error instanceof Error ? error.message : String(error)}), theme ignored`);
|
|
383
|
+
}
|
|
384
|
+
return;
|
|
385
|
+
}
|
|
386
|
+
function applyPreset(theme, name, warn, where) {
|
|
387
|
+
if (name === undefined)
|
|
388
|
+
return;
|
|
389
|
+
if (typeof name !== "string" || !Object.hasOwn(PRESETS, name)) {
|
|
390
|
+
warn(`${where}: no preset ${String(name)}, one of ${Object.keys(PRESETS).join(", ")}`);
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
const preset = PRESETS[name];
|
|
394
|
+
Object.assign(theme.colors, preset.colors);
|
|
395
|
+
Object.assign(theme.glyphs, preset.glyphs);
|
|
396
|
+
if (preset.accents !== undefined)
|
|
397
|
+
theme.accents = [...preset.accents];
|
|
398
|
+
return name;
|
|
399
|
+
}
|
|
400
|
+
function applyFile(theme, file, where, warn) {
|
|
401
|
+
if (isRecord(file.colors)) {
|
|
402
|
+
for (const [key, value] of Object.entries(file.colors)) {
|
|
403
|
+
if (!Object.hasOwn(DEFAULT.colors, key))
|
|
404
|
+
warn(`${where}: no colour ${key}, one of ${Object.keys(DEFAULT.colors).join(", ")}`);
|
|
405
|
+
else if (!isColorSpec(value))
|
|
406
|
+
warn(`${where}: colour ${key} is not an ANSI name, \`#rrggbb\` or a number up to 255`);
|
|
407
|
+
else
|
|
408
|
+
theme.colors[key] = value;
|
|
409
|
+
}
|
|
410
|
+
}
|
|
411
|
+
if (isRecord(file.glyphs)) {
|
|
412
|
+
for (const [key, value] of Object.entries(file.glyphs)) {
|
|
413
|
+
if (!Object.hasOwn(DEFAULT.glyphs, key))
|
|
414
|
+
warn(`${where}: no glyph ${key}, one of ${Object.keys(DEFAULT.glyphs).join(", ")}`);
|
|
415
|
+
else if (typeof value !== "string" || CONTROL.test(value) || Bun.stringWidth(value) !== 1)
|
|
416
|
+
warn(`${where}: glyph ${key} must be one visible character wide, with no control character`);
|
|
417
|
+
else
|
|
418
|
+
theme.glyphs[key] = value;
|
|
419
|
+
}
|
|
420
|
+
}
|
|
421
|
+
if (Array.isArray(file.accents) && file.accents.length > 0 && file.accents.every(isColorSpec))
|
|
422
|
+
theme.accents = [...file.accents];
|
|
423
|
+
else if (file.accents !== undefined)
|
|
424
|
+
warn(`${where}: accents must be a non-empty list of colours`);
|
|
425
|
+
if (isRecord(file.bins)) {
|
|
426
|
+
for (const [bin, value] of Object.entries(file.bins)) {
|
|
427
|
+
if (isColorSpec(value))
|
|
428
|
+
theme.bins[bin] = value;
|
|
429
|
+
else
|
|
430
|
+
warn(`${where}: bin ${bin} has no valid colour`);
|
|
431
|
+
}
|
|
432
|
+
}
|
|
433
|
+
}
|
|
434
|
+
function endsWalk(home) {
|
|
435
|
+
return (dir) => dir === resolve2(home) || existsSync3(join3(dir, ".git"));
|
|
436
|
+
}
|
|
313
437
|
var warned = new Set;
|
|
438
|
+
function warnOnce(message) {
|
|
439
|
+
if (warned.has(message))
|
|
440
|
+
return;
|
|
441
|
+
warned.add(message);
|
|
442
|
+
console.error(`warning: theme ${message}`);
|
|
443
|
+
}
|
|
444
|
+
function isPath(chosen) {
|
|
445
|
+
return chosen.includes("/") || chosen.endsWith(".json");
|
|
446
|
+
}
|
|
447
|
+
function loadTheme({ env = process5.env, from = process5.cwd(), home = homedir2(), warn = warnOnce } = {}) {
|
|
448
|
+
const theme = { colors: { ...DEFAULT.colors }, glyphs: { ...DEFAULT.glyphs }, accents: [...DEFAULT.accents], bins: Object.create(null) };
|
|
449
|
+
const sources = [];
|
|
450
|
+
const chosen = env.KIT_THEME ?? "";
|
|
451
|
+
const wanted = chosen === "" ? [userConfigPath("theme", { home, xdg: env.XDG_CONFIG_HOME }), findUp(join3(".kaynooo", "theme.json"), from, endsWalk(home))] : [];
|
|
452
|
+
if (isPath(chosen))
|
|
453
|
+
wanted.push(resolve2(from, chosen));
|
|
454
|
+
const files = [];
|
|
455
|
+
for (const path of wanted) {
|
|
456
|
+
const file = path === undefined ? undefined : readThemeFile(path, warn);
|
|
457
|
+
if (path !== undefined && file !== undefined)
|
|
458
|
+
files.push({ path, file });
|
|
459
|
+
}
|
|
460
|
+
let preset = "default";
|
|
461
|
+
if (chosen !== "" && !isPath(chosen)) {
|
|
462
|
+
preset = applyPreset(theme, chosen, warn, "KIT_THEME") ?? preset;
|
|
463
|
+
} else {
|
|
464
|
+
const named = files.findLast(({ file }) => file.preset !== undefined);
|
|
465
|
+
if (named !== undefined)
|
|
466
|
+
preset = applyPreset(theme, named.file.preset, warn, named.path) ?? preset;
|
|
467
|
+
}
|
|
468
|
+
for (const { path, file } of files) {
|
|
469
|
+
applyFile(theme, file, path, warn);
|
|
470
|
+
sources.push(path);
|
|
471
|
+
}
|
|
472
|
+
return { theme, sources, preset };
|
|
473
|
+
}
|
|
314
474
|
|
|
315
475
|
// ../kit/src/style.ts
|
|
316
|
-
function takesControlCodes(stream, env =
|
|
476
|
+
function takesControlCodes(stream, env = process6.env) {
|
|
317
477
|
return stream.isTTY === true && env.NO_COLOR === undefined && env.NODE_DISABLE_COLORS === undefined && env.TERM !== "dumb" && outputMode(stream, env) === "terminal";
|
|
318
478
|
}
|
|
319
|
-
function paint(stream, env =
|
|
479
|
+
function paint(stream, env = process6.env) {
|
|
320
480
|
return le({ stream: { isTTY: takesControlCodes(stream, env) }, env });
|
|
321
481
|
}
|
|
322
482
|
var STATUS_WORDS = {
|
|
@@ -341,7 +501,7 @@ var ESCAPE = String.fromCharCode(27);
|
|
|
341
501
|
function textWidth(text) {
|
|
342
502
|
return Bun.stringWidth(text);
|
|
343
503
|
}
|
|
344
|
-
function table(rows, { cellWidth, header = false, align = [], fit, stream =
|
|
504
|
+
function table(rows, { cellWidth, header = false, align = [], fit, stream = process7.stdout, env = process7.env } = {}) {
|
|
345
505
|
const cells = cellWidth === undefined ? rows : rows.map((row) => row.map((cell) => truncate(cell.replaceAll(LINE_BREAKS, " "), cellWidth)));
|
|
346
506
|
if (outputMode(stream, env) === "agent")
|
|
347
507
|
return cells.map((row) => row.map((cell) => Bun.stripANSI(cell).replaceAll(/[\t\r\n]+/g, " ")).join("\t")).join(`
|
|
@@ -380,7 +540,7 @@ function narrow(rows, widths, limit) {
|
|
|
380
540
|
}
|
|
381
541
|
return rows.map((row) => row.map((cell, index) => textWidth(cell) > (widths[index] ?? 0) ? truncate(cell, widths[index] ?? 0) : cell));
|
|
382
542
|
}
|
|
383
|
-
function jsonText(value, replacer, { stream =
|
|
543
|
+
function jsonText(value, replacer, { stream = process7.stdout, env = process7.env } = {}) {
|
|
384
544
|
return JSON.stringify(value, replacer, outputMode(stream, env) === "agent" ? undefined : 2);
|
|
385
545
|
}
|
|
386
546
|
function printJson(value) {
|
|
@@ -388,27 +548,27 @@ function printJson(value) {
|
|
|
388
548
|
}
|
|
389
549
|
|
|
390
550
|
// ../kit/src/help.ts
|
|
391
|
-
import
|
|
551
|
+
import process8 from "process";
|
|
392
552
|
var OPTIONAL = /\[[^\]]+\]/g;
|
|
393
553
|
var USAGE_PREFIX = /^usage:\s*/i;
|
|
394
554
|
var FULL_STOP = /\.$/;
|
|
395
|
-
function usageLine(usage, colors = paint(
|
|
555
|
+
function usageLine(usage, colors = paint(process8.stdout)) {
|
|
396
556
|
return `${colors.bold("Usage:")} ${usage.replace(USAGE_PREFIX, "").replaceAll(OPTIONAL, (part) => colors.dim(part))}`;
|
|
397
557
|
}
|
|
398
|
-
function helpText(usage, options, colors = paint(
|
|
558
|
+
function helpText(usage, options, colors = paint(process8.stdout), { examples = [], replaces, exits = [] } = {}) {
|
|
399
559
|
return [usageLine(usage, colors), ...replacesRows(replaces, colors), "", colors.bold("Options:"), ...optionRows(options, colors), ...exitRows(exits, colors), ...exampleRows(examples, colors)].join(`
|
|
400
560
|
`);
|
|
401
561
|
}
|
|
402
|
-
function exitRows(exits, colors = paint(
|
|
562
|
+
function exitRows(exits, colors = paint(process8.stdout)) {
|
|
403
563
|
if (exits.length === 0)
|
|
404
564
|
return [];
|
|
405
565
|
const width = Math.max(...exits.map(([code]) => String(code).length));
|
|
406
566
|
return ["", colors.bold("Exits:"), ...exits.map(([code, meaning]) => ` ${colors.cyan(String(code).padEnd(width))} ${meaning}`)];
|
|
407
567
|
}
|
|
408
|
-
function replacesRows(replaces, colors = paint(
|
|
568
|
+
function replacesRows(replaces, colors = paint(process8.stdout)) {
|
|
409
569
|
return replaces === undefined || outputMode() === "agent" ? [] : ["", `${colors.bold("Instead of:")} ${replaces}`];
|
|
410
570
|
}
|
|
411
|
-
function wantsHelpJson(env =
|
|
571
|
+
function wantsHelpJson(env = process8.env) {
|
|
412
572
|
return env.KIT_HELP === "json";
|
|
413
573
|
}
|
|
414
574
|
function description(usage, { examples = [], replaces, exits } = {}, options) {
|
|
@@ -427,12 +587,12 @@ function description(usage, { examples = [], replaces, exits } = {}, options) {
|
|
|
427
587
|
...options === undefined ? {} : { options: Object.entries(options).map(([name, { short, description }]) => ({ name, ...short === undefined ? {} : { short }, ...description === undefined ? {} : { description } })) }
|
|
428
588
|
};
|
|
429
589
|
}
|
|
430
|
-
function exampleRows(examples, colors = paint(
|
|
590
|
+
function exampleRows(examples, colors = paint(process8.stdout)) {
|
|
431
591
|
if (examples.length === 0 || outputMode() === "agent")
|
|
432
592
|
return [];
|
|
433
593
|
return ["", colors.bold("Examples:"), ...examples.map((example) => typeof example === "string" ? ` ${example}` : ` ${example[0]} ${colors.dim(`# ${example[1]}`)}`)];
|
|
434
594
|
}
|
|
435
|
-
function optionRows(options, colors = paint(
|
|
595
|
+
function optionRows(options, colors = paint(process8.stdout)) {
|
|
436
596
|
const rows = Object.entries(options).map(([name, option]) => {
|
|
437
597
|
const short = option.short === undefined ? " " : `${colors.cyan(`-${option.short}`)}, `;
|
|
438
598
|
const named = option.choices === undefined ? "<value>" : `<${option.choices.join("|")}>`;
|
|
@@ -524,7 +684,7 @@ var OUTPUT_OPTIONS = {
|
|
|
524
684
|
color: { type: "string", description: "auto (on a terminal alone), always or never" },
|
|
525
685
|
plain: { type: "boolean", description: "plain text, no colour or spinner: --color never" }
|
|
526
686
|
};
|
|
527
|
-
function applyOutput(color, plain, env =
|
|
687
|
+
function applyOutput(color, plain, env = process9.env) {
|
|
528
688
|
const when = plain === true ? "never" : color ?? "auto";
|
|
529
689
|
if (when === "auto")
|
|
530
690
|
return;
|
|
@@ -695,7 +855,7 @@ function nearestOption(message, options, allowNegative) {
|
|
|
695
855
|
}
|
|
696
856
|
// ../kit/src/process.ts
|
|
697
857
|
import { constants } from "os";
|
|
698
|
-
import
|
|
858
|
+
import process10 from "process";
|
|
699
859
|
var KILL_GRACE_MS = 2000;
|
|
700
860
|
function exitCodeOf(code, signal) {
|
|
701
861
|
if (code !== null)
|
|
@@ -715,7 +875,7 @@ async function runCommand(argv, { cwd, env, stdin = "ignore", timeoutMs, signal,
|
|
|
715
875
|
return;
|
|
716
876
|
try {
|
|
717
877
|
if (grouped)
|
|
718
|
-
|
|
878
|
+
process10.kill(-proc.pid, killing);
|
|
719
879
|
else
|
|
720
880
|
proc.kill(killing);
|
|
721
881
|
} catch {}
|
|
@@ -789,15 +949,15 @@ var ESCAPE_CODE = new RegExp(`${ESC}(?:\\[[\\x30-\\x3F]*[\\x20-\\x2F]*[\\x40-\\x
|
|
|
789
949
|
var RESET_STYLE = `${ESC}[0m`;
|
|
790
950
|
var CLOSE_LINK = `${ESC}]8;;${ESC}\\`;
|
|
791
951
|
// ../kit/src/cli.ts
|
|
792
|
-
import { readFileSync, realpathSync } from "fs";
|
|
793
|
-
import { dirname as
|
|
794
|
-
import
|
|
952
|
+
import { readFileSync as readFileSync2, realpathSync } from "fs";
|
|
953
|
+
import { dirname as dirname3, join as join5 } from "path";
|
|
954
|
+
import process12 from "process";
|
|
795
955
|
|
|
796
956
|
// ../kit/src/usage.ts
|
|
797
957
|
import { appendFileSync, mkdirSync } from "fs";
|
|
798
|
-
import { homedir as
|
|
799
|
-
import { dirname, isAbsolute, join as
|
|
800
|
-
import
|
|
958
|
+
import { homedir as homedir3 } from "os";
|
|
959
|
+
import { dirname as dirname2, isAbsolute, join as join4 } from "path";
|
|
960
|
+
import process11 from "process";
|
|
801
961
|
|
|
802
962
|
// ../kit/src/logs.ts
|
|
803
963
|
var DAY_MS = 24 * 60 * 60 * 1000;
|
|
@@ -811,14 +971,14 @@ var usageError;
|
|
|
811
971
|
function noteUsageError(message) {
|
|
812
972
|
usageError = message;
|
|
813
973
|
}
|
|
814
|
-
function stateHome(env =
|
|
974
|
+
function stateHome(env = process11.env) {
|
|
815
975
|
const dir = env.XDG_STATE_HOME;
|
|
816
|
-
return dir !== undefined && isAbsolute(dir) ? dir :
|
|
976
|
+
return dir !== undefined && isAbsolute(dir) ? dir : join4(homedir3(), ".local", "state");
|
|
817
977
|
}
|
|
818
|
-
function usagePath(env =
|
|
819
|
-
return
|
|
978
|
+
function usagePath(env = process11.env) {
|
|
979
|
+
return join4(stateHome(env), CLI_FOLDER, "usage.jsonl");
|
|
820
980
|
}
|
|
821
|
-
function usageRecorded(env =
|
|
981
|
+
function usageRecorded(env = process11.env) {
|
|
822
982
|
const off = env.KAYNOOO_CLI_NO_USAGE;
|
|
823
983
|
return env.NODE_ENV !== "test" && (off === undefined || off === "" || off === "0");
|
|
824
984
|
}
|
|
@@ -832,12 +992,12 @@ function usageEntry(bin, command, argv, code, now = new Date) {
|
|
|
832
992
|
usageError = undefined;
|
|
833
993
|
return { at: now.toISOString(), bin, ...command === undefined ? {} : { command }, flags: flagNames(argv), code, ...unknown === undefined ? {} : { unknown } };
|
|
834
994
|
}
|
|
835
|
-
function recordUsage(entry, env =
|
|
995
|
+
function recordUsage(entry, env = process11.env) {
|
|
836
996
|
if (!usageRecorded(env))
|
|
837
997
|
return;
|
|
838
998
|
try {
|
|
839
999
|
const path = usagePath(env);
|
|
840
|
-
mkdirSync(
|
|
1000
|
+
mkdirSync(dirname2(path), { recursive: true, mode: 448 });
|
|
841
1001
|
appendFileSync(path, `${JSON.stringify(entry)}
|
|
842
1002
|
`, { mode: 384 });
|
|
843
1003
|
} catch {}
|
|
@@ -971,8 +1131,8 @@ async function help2({ path, header, summary: lazySummary, commands, defaultComm
|
|
|
971
1131
|
`);
|
|
972
1132
|
}
|
|
973
1133
|
function printError(prefix, message, hint, cause) {
|
|
974
|
-
const colors = paint(
|
|
975
|
-
const styled = takesControlCodes(
|
|
1134
|
+
const colors = paint(process12.stderr);
|
|
1135
|
+
const styled = takesControlCodes(process12.stderr);
|
|
976
1136
|
const head = styled ? `${colors.red.bold("error")} ${colors.dim(`${prefix}:`)}` : `error: ${prefix}:`;
|
|
977
1137
|
const under = (label, text, tint) => text === undefined ? "" : `
|
|
978
1138
|
${styled ? tint(label) : `${label}:`} ${text}`;
|
|
@@ -1015,11 +1175,11 @@ async function dispatch(level, typed, { version, redact }) {
|
|
|
1015
1175
|
}
|
|
1016
1176
|
}
|
|
1017
1177
|
if (name === undefined && level.path.length > 1) {
|
|
1018
|
-
console.error(await help2(await expand(level, [...level.path.slice(1), ...argv]),
|
|
1178
|
+
console.error(await help2(await expand(level, [...level.path.slice(1), ...argv]), process12.stderr));
|
|
1019
1179
|
return 2;
|
|
1020
1180
|
}
|
|
1021
1181
|
if (name === undefined || name === "help" || name === "--help" || name === "-h") {
|
|
1022
|
-
console.log(await help2(await expand(level, [...level.path.slice(1), ...argv]),
|
|
1182
|
+
console.log(await help2(await expand(level, [...level.path.slice(1), ...argv]), process12.stdout));
|
|
1023
1183
|
return 0;
|
|
1024
1184
|
}
|
|
1025
1185
|
if (level.path.length === 1 && (name === "--version" || name === "-v")) {
|
|
@@ -1136,17 +1296,17 @@ async function printCandidates(found) {
|
|
|
1136
1296
|
return 0;
|
|
1137
1297
|
}
|
|
1138
1298
|
function packageVersion(entry = Bun.main) {
|
|
1139
|
-
for (let dir =
|
|
1299
|
+
for (let dir = dirname3(realpathSync(entry));; dir = dirname3(dir)) {
|
|
1140
1300
|
try {
|
|
1141
|
-
const { version } = JSON.parse(
|
|
1301
|
+
const { version } = JSON.parse(readFileSync2(join5(dir, "package.json"), "utf8"));
|
|
1142
1302
|
if (typeof version === "string")
|
|
1143
1303
|
return version;
|
|
1144
1304
|
} catch {}
|
|
1145
|
-
if (
|
|
1305
|
+
if (dirname3(dir) === dir)
|
|
1146
1306
|
return "0.0.0";
|
|
1147
1307
|
}
|
|
1148
1308
|
}
|
|
1149
|
-
async function runCli(cli, argv =
|
|
1309
|
+
async function runCli(cli, argv = process12.argv.slice(2)) {
|
|
1150
1310
|
const version = cli.version ?? packageVersion();
|
|
1151
1311
|
if (argv[0] === COMPLETE)
|
|
1152
1312
|
return printCandidates(candidates(scopeOf(cli.commands, cli.extraCommands, cli.aliases), cli.defaultCommand, argv.slice(1)));
|
|
@@ -1173,7 +1333,7 @@ function commandPath(scope, argv) {
|
|
|
1173
1333
|
}
|
|
1174
1334
|
return path.length === 0 ? undefined : path.join(" ");
|
|
1175
1335
|
}
|
|
1176
|
-
async function runMain({ name, version, run, redact, usage }, argv =
|
|
1336
|
+
async function runMain({ name, version, run, redact, usage }, argv = process12.argv.slice(2)) {
|
|
1177
1337
|
if (argv[0] === COMPLETE)
|
|
1178
1338
|
return printCandidates(leafCandidates(run, argv.slice(1)));
|
|
1179
1339
|
if (argv.length === 1 && (argv[0] === "--version" || argv[0] === "-v")) {
|
|
@@ -1193,6 +1353,8 @@ async function runMain({ name, version, run, redact, usage }, argv = process10.a
|
|
|
1193
1353
|
}
|
|
1194
1354
|
return code;
|
|
1195
1355
|
}
|
|
1356
|
+
// ../kit/src/folders.ts
|
|
1357
|
+
var SKIPPED_FOLDERS = new Set(["node_modules", "vendor", "dist", "build", "target", "coverage", "venv", "__pycache__"]);
|
|
1196
1358
|
// ../kit/src/secrets.ts
|
|
1197
1359
|
var SECRET_WORDS = new Set(["key", "pass", "pwd", "auth", "salt", "cookie", "session", "jwt", "ssn", "iban", "card", "cvv", "otp"]);
|
|
1198
1360
|
// ../kit/src/sessions.ts
|
|
@@ -1200,40 +1362,40 @@ var {Glob } = globalThis.Bun;
|
|
|
1200
1362
|
var SESSION_FILES = new Glob("*.json");
|
|
1201
1363
|
var ACCOUNT_DIRS = new Glob("*/sessions");
|
|
1202
1364
|
// ../kit/src/workspace-root.ts
|
|
1203
|
-
import { existsSync, mkdirSync as mkdirSync2, readFileSync as
|
|
1204
|
-
import { homedir as
|
|
1205
|
-
import { dirname as
|
|
1206
|
-
import
|
|
1365
|
+
import { existsSync as existsSync4, mkdirSync as mkdirSync2, readFileSync as readFileSync3, writeFileSync } from "fs";
|
|
1366
|
+
import { homedir as homedir4 } from "os";
|
|
1367
|
+
import { dirname as dirname4, join as join6, resolve as resolve3 } from "path";
|
|
1368
|
+
import process13 from "process";
|
|
1207
1369
|
function expandHome(path, home) {
|
|
1208
1370
|
if (path === "~")
|
|
1209
1371
|
return home;
|
|
1210
|
-
return path.startsWith("~/") ?
|
|
1372
|
+
return path.startsWith("~/") ? join6(home, path.slice(2)) : path;
|
|
1211
1373
|
}
|
|
1212
1374
|
function configured(env, home) {
|
|
1213
1375
|
const path = userConfigPath("config", { home, xdg: env.XDG_CONFIG_HOME });
|
|
1214
|
-
if (!
|
|
1376
|
+
if (!existsSync4(path))
|
|
1215
1377
|
return;
|
|
1216
1378
|
try {
|
|
1217
|
-
const parsed = JSON.parse(
|
|
1379
|
+
const parsed = JSON.parse(readFileSync3(path, "utf8"));
|
|
1218
1380
|
const folder = typeof parsed === "object" && parsed !== null ? parsed.workspace : undefined;
|
|
1219
1381
|
return typeof folder === "string" && folder !== "" ? folder : undefined;
|
|
1220
1382
|
} catch {
|
|
1221
1383
|
return;
|
|
1222
1384
|
}
|
|
1223
1385
|
}
|
|
1224
|
-
function workspaceRoot({ given, env =
|
|
1386
|
+
function workspaceRoot({ given, env = process13.env, home = homedir4() } = {}) {
|
|
1225
1387
|
const fromEnv = env.KAYNOOO_WORKSPACE === "" ? undefined : env.KAYNOOO_WORKSPACE;
|
|
1226
|
-
return
|
|
1388
|
+
return resolve3(expandHome(given ?? fromEnv ?? configured(env, home) ?? join6(home, "Workspace"), home));
|
|
1227
1389
|
}
|
|
1228
|
-
function workspaceChosen({ env =
|
|
1390
|
+
function workspaceChosen({ env = process13.env, home = homedir4() } = {}) {
|
|
1229
1391
|
return (env.KAYNOOO_WORKSPACE ?? "") !== "" || configured(env, home) !== undefined;
|
|
1230
1392
|
}
|
|
1231
|
-
function saveWorkspace(folder, { env =
|
|
1393
|
+
function saveWorkspace(folder, { env = process13.env, home = homedir4() } = {}) {
|
|
1232
1394
|
const path = userConfigPath("config", { home, xdg: env.XDG_CONFIG_HOME });
|
|
1233
1395
|
let current = {};
|
|
1234
|
-
if (
|
|
1396
|
+
if (existsSync4(path)) {
|
|
1235
1397
|
try {
|
|
1236
|
-
const parsed = JSON.parse(
|
|
1398
|
+
const parsed = JSON.parse(readFileSync3(path, "utf8"));
|
|
1237
1399
|
if (typeof parsed !== "object" || parsed === null || Array.isArray(parsed))
|
|
1238
1400
|
return false;
|
|
1239
1401
|
current = parsed;
|
|
@@ -1241,17 +1403,17 @@ function saveWorkspace(folder, { env = process11.env, home = homedir3() } = {})
|
|
|
1241
1403
|
return false;
|
|
1242
1404
|
}
|
|
1243
1405
|
}
|
|
1244
|
-
mkdirSync2(
|
|
1406
|
+
mkdirSync2(dirname4(path), { recursive: true });
|
|
1245
1407
|
writeFileSync(path, `${JSON.stringify({ ...current, workspace: folder }, undefined, 2)}
|
|
1246
1408
|
`);
|
|
1247
1409
|
return true;
|
|
1248
1410
|
}
|
|
1249
1411
|
// src/doctor.ts
|
|
1250
|
-
import
|
|
1412
|
+
import process19 from "process";
|
|
1251
1413
|
|
|
1252
1414
|
// src/checks.ts
|
|
1253
|
-
import { existsSync as
|
|
1254
|
-
import { basename, join as
|
|
1415
|
+
import { existsSync as existsSync6, readFileSync as readFileSync5 } from "fs";
|
|
1416
|
+
import { basename, join as join8 } from "path";
|
|
1255
1417
|
|
|
1256
1418
|
// src/catalog.ts
|
|
1257
1419
|
var HOOKS_REQUIRES = "@kaynooo/cli-guard";
|
|
@@ -1287,9 +1449,9 @@ var NEEDS = {
|
|
|
1287
1449
|
};
|
|
1288
1450
|
|
|
1289
1451
|
// src/completions.ts
|
|
1290
|
-
import { existsSync as
|
|
1291
|
-
import { join as
|
|
1292
|
-
import
|
|
1452
|
+
import { existsSync as existsSync5, mkdirSync as mkdirSync3, readdirSync, readFileSync as readFileSync4, rmSync } from "fs";
|
|
1453
|
+
import { join as join7 } from "path";
|
|
1454
|
+
import process15 from "process";
|
|
1293
1455
|
var MARKER = "# Generated by `cli completions fish`";
|
|
1294
1456
|
var FISH_FILE = /\.fish$/;
|
|
1295
1457
|
var FUNCTION = `functions -q __kaynooo_cli_complete; or function __kaynooo_cli_complete --argument-names bin --description 'what a @kaynooo/cli-* bin offers for the word being typed'
|
|
@@ -1345,8 +1507,8 @@ ${BASH_FUNCTION}
|
|
|
1345
1507
|
complete -F __kaynooo_cli_complete ${bins.join(" ")}
|
|
1346
1508
|
`;
|
|
1347
1509
|
}
|
|
1348
|
-
function completionDir(home, env =
|
|
1349
|
-
return
|
|
1510
|
+
function completionDir(home, env = process15.env) {
|
|
1511
|
+
return join7(env.XDG_CACHE_HOME ?? join7(home, ".cache"), "fish", "kaynooo-cli");
|
|
1350
1512
|
}
|
|
1351
1513
|
function installedBins(host) {
|
|
1352
1514
|
return Object.values(TOOLS).flat().filter((bin) => host.which(bin) !== null);
|
|
@@ -1360,14 +1522,14 @@ complete -c ${bin} -f -a '(__kaynooo_cli_complete ${bin})'
|
|
|
1360
1522
|
async function installCompletions(host, dir) {
|
|
1361
1523
|
const bins = installedBins(host);
|
|
1362
1524
|
mkdirSync3(dir, { recursive: true });
|
|
1363
|
-
const removed = readdirSync(dir).filter((name) => FISH_FILE.test(name) && !bins.includes(name.replace(FISH_FILE, "")) &&
|
|
1525
|
+
const removed = readdirSync(dir).filter((name) => FISH_FILE.test(name) && !bins.includes(name.replace(FISH_FILE, "")) && readFileSync4(join7(dir, name), "utf8").startsWith(MARKER));
|
|
1364
1526
|
for (const name of removed)
|
|
1365
|
-
rmSync(
|
|
1366
|
-
await Promise.all(bins.map(async (bin) => Bun.write(
|
|
1527
|
+
rmSync(join7(dir, name));
|
|
1528
|
+
await Promise.all(bins.map(async (bin) => Bun.write(join7(dir, `${bin}.fish`), completionFile(bin))));
|
|
1367
1529
|
return { written: bins, removed: removed.map((name) => name.replace(FISH_FILE, "")) };
|
|
1368
1530
|
}
|
|
1369
1531
|
function missingCompletions(host, dir) {
|
|
1370
|
-
return installedBins(host).filter((bin) => !
|
|
1532
|
+
return installedBins(host).filter((bin) => !existsSync5(join7(dir, `${bin}.fish`)));
|
|
1371
1533
|
}
|
|
1372
1534
|
|
|
1373
1535
|
// src/checks.ts
|
|
@@ -1411,7 +1573,7 @@ function readJsonText(text) {
|
|
|
1411
1573
|
}
|
|
1412
1574
|
}
|
|
1413
1575
|
function readJson(path) {
|
|
1414
|
-
return
|
|
1576
|
+
return existsSync6(path) ? readJsonText(readFileSync5(path, "utf8")) : undefined;
|
|
1415
1577
|
}
|
|
1416
1578
|
function firstLine(text) {
|
|
1417
1579
|
const trimmed = text.trim();
|
|
@@ -1420,7 +1582,7 @@ function firstLine(text) {
|
|
|
1420
1582
|
return end === -1 ? trimmed : trimmed.slice(0, end);
|
|
1421
1583
|
}
|
|
1422
1584
|
function installed(host, name) {
|
|
1423
|
-
return readJson(
|
|
1585
|
+
return readJson(join8(host.globalModules, name, "package.json"));
|
|
1424
1586
|
}
|
|
1425
1587
|
function isInstalled(host, name) {
|
|
1426
1588
|
return installed(host, name)?.version !== undefined;
|
|
@@ -1428,7 +1590,7 @@ function isInstalled(host, name) {
|
|
|
1428
1590
|
function ownBin(host, name, bin) {
|
|
1429
1591
|
const declared = installed(host, name)?.bin;
|
|
1430
1592
|
const file = typeof declared === "string" ? declared : declared?.[bin];
|
|
1431
|
-
return file === undefined ? undefined :
|
|
1593
|
+
return file === undefined ? undefined : join8(host.globalModules, name, file);
|
|
1432
1594
|
}
|
|
1433
1595
|
async function checkTool(host, name, bins) {
|
|
1434
1596
|
const check = name.slice(name.indexOf("/") + 1);
|
|
@@ -1443,17 +1605,29 @@ async function checkTool(host, name, bins) {
|
|
|
1443
1605
|
if (latest !== "" && Bun.semver.order(version, latest) < 0)
|
|
1444
1606
|
return { check, ok: false, detail: `${version}, ${latest} released${off.length > 0 ? `, ${off.join(", ")} not on the PATH` : ""}`, fix: `bun install -g ${name}@${latest}` };
|
|
1445
1607
|
if (off.length > 0)
|
|
1446
|
-
return { check, ok: false, detail: `${version}, ${off.join(", ")} not on the PATH`, fix: `add ${
|
|
1608
|
+
return { check, ok: false, detail: `${version}, ${off.join(", ")} not on the PATH`, fix: `add ${join8(host.globalModules, "..", "..", "..", "bin")} to the PATH` };
|
|
1447
1609
|
if (latest === "")
|
|
1448
1610
|
return { check, ok: true, detail: `${version}, the registry did not answer: ${firstLine(info.stderr) || answered || "no version"}` };
|
|
1449
1611
|
return { check, ok: true, detail: version };
|
|
1450
1612
|
}
|
|
1613
|
+
function extraForgeHosts(home) {
|
|
1614
|
+
try {
|
|
1615
|
+
const path = userConfigReadPath("doctor", [], { home, xdg: process.env.XDG_CONFIG_HOME });
|
|
1616
|
+
if (!existsSync6(path))
|
|
1617
|
+
return [];
|
|
1618
|
+
const raw = Bun.JSONC.parse(readFileSync5(path, "utf8"));
|
|
1619
|
+
return Array.isArray(raw?.forgeHosts) ? raw.forgeHosts.filter((each) => typeof each === "string") : [];
|
|
1620
|
+
} catch {
|
|
1621
|
+
return [];
|
|
1622
|
+
}
|
|
1623
|
+
}
|
|
1451
1624
|
async function checkTea(host) {
|
|
1452
1625
|
if (host.which("tea") === null)
|
|
1453
1626
|
return { check: "tea", ok: false, detail: "not installed, and ft goes through it", fix: "install tea from https://gitea.com/gitea/tea/releases" };
|
|
1454
1627
|
const logins = await host.run(["tea", "login", "list", "-o", "json"]);
|
|
1455
1628
|
const parsed = logins.code === 0 ? readJsonText(logins.stdout) : undefined;
|
|
1456
|
-
const
|
|
1629
|
+
const hosts = new Set([...FORGE_HOSTS, ...extraForgeHosts(host.home)]);
|
|
1630
|
+
const login = parsed?.find((each) => URL.canParse(each.url) && hosts.has(new URL(each.url).host));
|
|
1457
1631
|
if (login === undefined)
|
|
1458
1632
|
return { check: "tea", ok: false, detail: `no login to ${FORGE}`, fix: `tea login add --url https://${FORGE} --oauth` };
|
|
1459
1633
|
const version = await host.run(["tea", "api", "--login", login.name, "version"]);
|
|
@@ -1464,9 +1638,9 @@ async function checkTea(host) {
|
|
|
1464
1638
|
return { check: "tea", ok: true, detail: `logged in to ${forge} as ${login.name}, Forgejo ${served}` };
|
|
1465
1639
|
}
|
|
1466
1640
|
function hooksWiring(host) {
|
|
1467
|
-
const settings = readJson(
|
|
1641
|
+
const settings = readJson(join8(host.home, ".claude", "settings.json")) ?? {};
|
|
1468
1642
|
const plugin = settings.enabledPlugins?.[PLUGIN] === true;
|
|
1469
|
-
const mod = (settings.env?.CLAUDE_CODE_PLUGIN_DIRS ?? "").split(":").map((dir) => dir.replace(LEADING_TILDE, host.home)).find((dir) => basename(dir) === "cli" &&
|
|
1643
|
+
const mod = (settings.env?.CLAUDE_CODE_PLUGIN_DIRS ?? "").split(":").map((dir) => dir.replace(LEADING_TILDE, host.home)).find((dir) => basename(dir) === "cli" && existsSync6(join8(dir, "hooks", "hooks.json")));
|
|
1470
1644
|
return { plugin, mod };
|
|
1471
1645
|
}
|
|
1472
1646
|
function checkHooks(host) {
|
|
@@ -1509,7 +1683,7 @@ var FORGEJO = "@kaynooo/cli-forgejo";
|
|
|
1509
1683
|
var WORKSPACE = "@kaynooo/cli-workspace";
|
|
1510
1684
|
function checkWorkspace(host, env = process.env) {
|
|
1511
1685
|
const folder = workspaceRoot({ home: host.home, env });
|
|
1512
|
-
if (
|
|
1686
|
+
if (existsSync6(folder))
|
|
1513
1687
|
return { check: "workspace", ok: true, detail: folder };
|
|
1514
1688
|
return { check: "workspace", ok: false, detail: `${folder} does not exist`, fix: `mkdir -p ${folder}, or set "workspace" in ~/.config/kaynooo-cli/config.json to your folder` };
|
|
1515
1689
|
}
|
|
@@ -1571,19 +1745,19 @@ async function applyFixes(host, steps, dry) {
|
|
|
1571
1745
|
}
|
|
1572
1746
|
|
|
1573
1747
|
// src/host.ts
|
|
1574
|
-
import { homedir as
|
|
1575
|
-
import { join as
|
|
1576
|
-
import
|
|
1748
|
+
import { homedir as homedir5 } from "os";
|
|
1749
|
+
import { join as join9 } from "path";
|
|
1750
|
+
import process16 from "process";
|
|
1577
1751
|
var RUN_TIMEOUT_MS = 20000;
|
|
1578
1752
|
function hostHere() {
|
|
1579
|
-
const home =
|
|
1753
|
+
const home = homedir5();
|
|
1580
1754
|
return {
|
|
1581
1755
|
home,
|
|
1582
|
-
globalModules:
|
|
1756
|
+
globalModules: join9(process16.env.BUN_INSTALL ?? join9(home, ".bun"), "install", "global", "node_modules"),
|
|
1583
1757
|
bunVersion: Bun.version,
|
|
1584
1758
|
which: (bin) => Bun.which(bin),
|
|
1585
1759
|
run: async (argv, env) => {
|
|
1586
|
-
const ran = await runCommand(argv, { timeoutMs: RUN_TIMEOUT_MS, ...env === undefined ? {} : { env: { ...
|
|
1760
|
+
const ran = await runCommand(argv, { timeoutMs: RUN_TIMEOUT_MS, ...env === undefined ? {} : { env: { ...process16.env, ...env } } });
|
|
1587
1761
|
if (ran.timedOut)
|
|
1588
1762
|
return { code: 1, stdout: "", stderr: `timed out after ${RUN_TIMEOUT_MS / 1000}s` };
|
|
1589
1763
|
const of = (stream) => Buffer.concat(ran.chunks.filter((chunk) => chunk.stream === stream).map((chunk) => chunk.data)).toString();
|
|
@@ -1593,10 +1767,10 @@ function hostHere() {
|
|
|
1593
1767
|
}
|
|
1594
1768
|
|
|
1595
1769
|
// src/install.ts
|
|
1596
|
-
import
|
|
1770
|
+
import process18 from "process";
|
|
1597
1771
|
|
|
1598
1772
|
// ../kit/src/prompt.ts
|
|
1599
|
-
import
|
|
1773
|
+
import process17 from "process";
|
|
1600
1774
|
|
|
1601
1775
|
// ../kit/src/picker/score.ts
|
|
1602
1776
|
var BOUNDARY_AFTER = new Set([" ", "/", "-", "_", ".", ":", "\\", "(", "[", ",", "\t"]);
|
|
@@ -1799,7 +1973,7 @@ function asking(colors, question, typed, keys) {
|
|
|
1799
1973
|
function answer(colors, question, state, picked) {
|
|
1800
1974
|
return state === "enter" ? `${colors.green("\u2713")} ${question} ${colors.cyan(picked)}` : `${colors.red("\u2717")} ${question} ${colors.dim("cancelled")}`;
|
|
1801
1975
|
}
|
|
1802
|
-
async function ask(question, { hint, terminal =
|
|
1976
|
+
async function ask(question, { hint, terminal = process17 }, render, press) {
|
|
1803
1977
|
const { stdin, stderr } = terminal;
|
|
1804
1978
|
if (!isInteractive(terminal))
|
|
1805
1979
|
fail(`cannot ask "${question}" off a terminal`, 2, hint);
|
|
@@ -1934,7 +2108,7 @@ async function askWorkspace(host) {
|
|
|
1934
2108
|
async function install(host, options, recheck, choosing = ask2) {
|
|
1935
2109
|
const all = candidates2(host);
|
|
1936
2110
|
const pool = all.filter((each) => !each.installed);
|
|
1937
|
-
const { dim, green, red, yellow } = paint(
|
|
2111
|
+
const { dim, green, red, yellow } = paint(process18.stdout);
|
|
1938
2112
|
if (options.list) {
|
|
1939
2113
|
for (const each of pool)
|
|
1940
2114
|
console.log(`${each.label.padEnd(12)} ${dim(each.hint)}`);
|
|
@@ -2042,7 +2216,7 @@ var OPTIONS = {
|
|
|
2042
2216
|
function print(results) {
|
|
2043
2217
|
if (results.length === 0)
|
|
2044
2218
|
return;
|
|
2045
|
-
const { green, red, dim } = paint(
|
|
2219
|
+
const { green, red, dim } = paint(process19.stdout);
|
|
2046
2220
|
const width = Math.max(...results.map((result) => result.check.length));
|
|
2047
2221
|
for (const { check, ok, detail, fix } of results)
|
|
2048
2222
|
console.log(`${ok ? green("ok ") : red("FAIL")} ${check.padEnd(width)} ${detail}${fix === undefined ? "" : ` ${dim("fix:")} ${fix}`}`);
|
|
@@ -2052,7 +2226,7 @@ function print(results) {
|
|
|
2052
2226
|
${dim("fix them all:")} ${INSTALL2}${installs.join(" ")}`);
|
|
2053
2227
|
}
|
|
2054
2228
|
function printOutcomes(outcomes, log) {
|
|
2055
|
-
const { green, red, dim } = paint(
|
|
2229
|
+
const { green, red, dim } = paint(process19.stdout);
|
|
2056
2230
|
const marks = { ran: green("ran "), failed: red("failed "), "dry-run": dim("would "), "not run": dim("not run") };
|
|
2057
2231
|
for (const { command, status, detail } of outcomes)
|
|
2058
2232
|
log(`${marks[status]} ${command}${detail === undefined ? "" : ` ${dim(detail)}`}`);
|
|
@@ -2092,9 +2266,9 @@ after the fixes:`);
|
|
|
2092
2266
|
const absent = Object.keys(TOOLS).filter((name) => !isInstalled(host, name)).length;
|
|
2093
2267
|
if (!json && only.length === 0 && absent > 0)
|
|
2094
2268
|
console.log(`
|
|
2095
|
-
${paint(
|
|
2269
|
+
${paint(process19.stdout).dim(`${absent} packages not installed: doctor --install`)}`);
|
|
2096
2270
|
return results.every((result) => result.ok) ? 0 : 1;
|
|
2097
2271
|
}
|
|
2098
2272
|
|
|
2099
2273
|
// src/cli.ts
|
|
2100
|
-
|
|
2274
|
+
process20.exitCode = await runMain({ name: "doctor", run: async (args) => main(args) });
|