@docker-doctor/cli 0.3.2 → 0.3.4

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/dist/cli.cjs CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- const require_src = require('./src-Dz3RukyR.cjs');
2
+ const require_src = require('./src-DWIAE2Ni.cjs');
3
3
  let node_fs_promises = require("node:fs/promises");
4
4
  node_fs_promises = require_src.__toESM(node_fs_promises, 1);
5
5
  let node_path = require("node:path");
@@ -19,11 +19,42 @@ let node_child_process = require("node:child_process");
19
19
  let node_fs = require("node:fs");
20
20
  node_fs = require_src.__toESM(node_fs, 1);
21
21
 
22
- //#region ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/vendor/ansi-styles/index.js
22
+ //#region ../../node_modules/.bun/chalk@6.0.0/node_modules/chalk/source/utilities.js
23
+ function stringReplaceAll(string, substring, postfix) {
24
+ let index = string.indexOf(substring);
25
+ if (index === -1) return string;
26
+ const substringLength = substring.length;
27
+ let endIndex = 0;
28
+ let returnValue = "";
29
+ do {
30
+ returnValue += string.slice(endIndex, index) + substring + postfix;
31
+ endIndex = index + substringLength;
32
+ index = string.indexOf(substring, endIndex);
33
+ } while (index !== -1);
34
+ returnValue += string.slice(endIndex);
35
+ return returnValue;
36
+ }
37
+ function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
38
+ let endIndex = 0;
39
+ let returnValue = "";
40
+ do {
41
+ const isGotCR = string[index - 1] === "\r";
42
+ returnValue += string.slice(endIndex, isGotCR ? index - 1 : index) + prefix + (isGotCR ? "\r\n" : "\n") + postfix;
43
+ endIndex = index + 1;
44
+ index = string.indexOf("\n", endIndex);
45
+ } while (index !== -1);
46
+ returnValue += string.slice(endIndex);
47
+ return returnValue;
48
+ }
49
+
50
+ //#endregion
51
+ //#region ../../node_modules/.bun/chalk@6.0.0/node_modules/chalk/source/vendor/ansi-styles/index.js
23
52
  const ANSI_BACKGROUND_OFFSET = 10;
24
- const wrapAnsi16 = (offset = 0) => (code) => `\u001B[${code + offset}m`;
25
- const wrapAnsi256 = (offset = 0) => (code) => `\u001B[${38 + offset};5;${code}m`;
26
- const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u001B[${38 + offset};2;${red};${green};${blue}m`;
53
+ const ANSI_UNDERLINE_OFFSET = 20;
54
+ const wrapAnsi16 = (offset = 0) => (code) => `\u{1B}[${code + offset}m`;
55
+ const wrapAnsi256 = (offset = 0) => (code) => `\u{1B}[${38 + offset};5;${code}m`;
56
+ const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u{1B}[${38 + offset};2;${red};${green};${blue}m`;
57
+ const wrapUnderlineAnsi = (code) => `\u{1B}[58;5;${code < 90 ? code - 30 : code - 90 + 8}m`;
27
58
  const styles$1 = {
28
59
  modifier: {
29
60
  reset: [0, 0],
@@ -31,6 +62,10 @@ const styles$1 = {
31
62
  dim: [2, 22],
32
63
  italic: [3, 23],
33
64
  underline: [4, 24],
65
+ underlineDouble: ["4:2", 24],
66
+ underlineCurly: ["4:3", 24],
67
+ underlineDotted: ["4:4", 24],
68
+ underlineDashed: ["4:5", 24],
34
69
  overline: [53, 55],
35
70
  inverse: [7, 27],
36
71
  hidden: [8, 28],
@@ -75,22 +110,43 @@ const styles$1 = {
75
110
  bgMagentaBright: [105, 49],
76
111
  bgCyanBright: [106, 49],
77
112
  bgWhiteBright: [107, 49]
113
+ },
114
+ underlineColor: {
115
+ underlineBlack: ["58;5;0", 59],
116
+ underlineRed: ["58;5;1", 59],
117
+ underlineGreen: ["58;5;2", 59],
118
+ underlineYellow: ["58;5;3", 59],
119
+ underlineBlue: ["58;5;4", 59],
120
+ underlineMagenta: ["58;5;5", 59],
121
+ underlineCyan: ["58;5;6", 59],
122
+ underlineWhite: ["58;5;7", 59],
123
+ underlineBlackBright: ["58;5;8", 59],
124
+ underlineGray: ["58;5;8", 59],
125
+ underlineGrey: ["58;5;8", 59],
126
+ underlineRedBright: ["58;5;9", 59],
127
+ underlineGreenBright: ["58;5;10", 59],
128
+ underlineYellowBright: ["58;5;11", 59],
129
+ underlineBlueBright: ["58;5;12", 59],
130
+ underlineMagentaBright: ["58;5;13", 59],
131
+ underlineCyanBright: ["58;5;14", 59],
132
+ underlineWhiteBright: ["58;5;15", 59]
78
133
  }
79
134
  };
80
135
  const modifierNames = Object.keys(styles$1.modifier);
81
136
  const foregroundColorNames = Object.keys(styles$1.color);
82
137
  const backgroundColorNames = Object.keys(styles$1.bgColor);
138
+ const underlineColorNames = Object.keys(styles$1.underlineColor);
83
139
  const colorNames = [...foregroundColorNames, ...backgroundColorNames];
84
140
  function assembleStyles() {
85
141
  const codes = /* @__PURE__ */ new Map();
86
142
  for (const [groupName, group] of Object.entries(styles$1)) {
87
143
  for (const [styleName, style] of Object.entries(group)) {
88
144
  styles$1[styleName] = {
89
- open: `\u001B[${style[0]}m`,
90
- close: `\u001B[${style[1]}m`
145
+ open: `\u{1B}[${style[0]}m`,
146
+ close: `\u{1B}[${style[1]}m`
91
147
  };
92
148
  group[styleName] = styles$1[styleName];
93
- codes.set(style[0], style[1]);
149
+ codes.set(Number.parseInt(style[0], 10), style[1]);
94
150
  }
95
151
  Object.defineProperty(styles$1, groupName, {
96
152
  value: group,
@@ -103,12 +159,16 @@ function assembleStyles() {
103
159
  });
104
160
  styles$1.color.close = "\x1B[39m";
105
161
  styles$1.bgColor.close = "\x1B[49m";
162
+ styles$1.underlineColor.close = "\x1B[59m";
106
163
  styles$1.color.ansi = wrapAnsi16();
107
164
  styles$1.color.ansi256 = wrapAnsi256();
108
165
  styles$1.color.ansi16m = wrapAnsi16m();
109
166
  styles$1.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
110
167
  styles$1.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
111
168
  styles$1.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
169
+ styles$1.underlineColor.ansi = wrapUnderlineAnsi;
170
+ styles$1.underlineColor.ansi256 = wrapAnsi256(ANSI_UNDERLINE_OFFSET);
171
+ styles$1.underlineColor.ansi16m = wrapAnsi16m(ANSI_UNDERLINE_OFFSET);
112
172
  Object.defineProperties(styles$1, {
113
173
  rgbToAnsi256: {
114
174
  value(red, green, blue) {
@@ -123,7 +183,7 @@ function assembleStyles() {
123
183
  },
124
184
  hexToRgb: {
125
185
  value(hex) {
126
- const matches = /[a-f\d]{6}|[a-f\d]{3}/i.exec(hex.toString(16));
186
+ const matches = /[\da-f]{6}|[\da-f]{3}/i.exec(hex.toString(16));
127
187
  if (!matches) return [
128
188
  0,
129
189
  0,
@@ -184,7 +244,7 @@ function assembleStyles() {
184
244
  const ansiStyles = assembleStyles();
185
245
 
186
246
  //#endregion
187
- //#region ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/vendor/supports-color/index.js
247
+ //#region ../../node_modules/.bun/chalk@6.0.0/node_modules/chalk/source/vendor/supports-color/index.js
188
248
  function hasFlag(flag, argv = globalThis.Deno ? globalThis.Deno.args : node_process.default.argv) {
189
249
  const prefix = flag.startsWith("-") ? "" : flag.length === 1 ? "-" : "--";
190
250
  const position = argv.indexOf(prefix + flag);
@@ -195,12 +255,15 @@ const { env } = node_process.default;
195
255
  let flagForceColor;
196
256
  if (hasFlag("no-color") || hasFlag("no-colors") || hasFlag("color=false") || hasFlag("color=never")) flagForceColor = 0;
197
257
  else if (hasFlag("color") || hasFlag("colors") || hasFlag("color=true") || hasFlag("color=always")) flagForceColor = 1;
258
+ function hasNumericForceColor() {
259
+ return /^\d+$/.test(env.FORCE_COLOR);
260
+ }
198
261
  function envForceColor() {
199
- if ("FORCE_COLOR" in env) {
200
- if (env.FORCE_COLOR === "true") return 1;
201
- if (env.FORCE_COLOR === "false") return 0;
202
- return env.FORCE_COLOR.length === 0 ? 1 : Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
203
- }
262
+ if (!("FORCE_COLOR" in env)) return;
263
+ if (env.FORCE_COLOR === "false") return 0;
264
+ if (env.FORCE_COLOR === "true" || env.FORCE_COLOR.length === 0) return 1;
265
+ if (!hasNumericForceColor()) return;
266
+ return Math.min(Number.parseInt(env.FORCE_COLOR, 10), 3);
204
267
  }
205
268
  function translateLevel(level) {
206
269
  if (level === 0) return false;
@@ -220,6 +283,7 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
220
283
  if (hasFlag("color=16m") || hasFlag("color=full") || hasFlag("color=truecolor")) return 3;
221
284
  if (hasFlag("color=256")) return 2;
222
285
  }
286
+ if (forceColor !== void 0 && hasNumericForceColor()) return forceColor;
223
287
  if ("TF_BUILD" in env && "AGENT_NAME" in env) return 1;
224
288
  if (haveStream && !streamIsTTY && forceColor === void 0) return 0;
225
289
  const min = forceColor || 0;
@@ -244,19 +308,19 @@ function _supportsColor(haveStream, { streamIsTTY, sniffFlags = true } = {}) {
244
308
  ].some((sign) => sign in env) || env.CI_NAME === "codeship") return 1;
245
309
  return min;
246
310
  }
247
- if ("TEAMCITY_VERSION" in env) return /^(9\.(0*[1-9]\d*)\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
311
+ if ("TEAMCITY_VERSION" in env) return /^(?:9\.0*[1-9]\d*\.|\d{2,}\.)/.test(env.TEAMCITY_VERSION) ? 1 : 0;
248
312
  if (env.COLORTERM === "truecolor") return 3;
249
313
  if (env.TERM === "xterm-kitty") return 3;
250
314
  if (env.TERM === "xterm-ghostty") return 3;
251
315
  if (env.TERM === "wezterm") return 3;
252
316
  if ("TERM_PROGRAM" in env) {
253
- const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".")[0], 10);
317
+ const version = Number.parseInt((env.TERM_PROGRAM_VERSION || "").split(".", 1)[0], 10);
254
318
  switch (env.TERM_PROGRAM) {
255
319
  case "iTerm.app": return version >= 3 ? 3 : 2;
256
320
  case "Apple_Terminal": return 2;
257
321
  }
258
322
  }
259
- if (/-256(color)?$/i.test(env.TERM)) return 2;
323
+ if (/-256(?:color)?$/i.test(env.TERM)) return 2;
260
324
  if (/^screen|^xterm|^vt100|^vt220|^rxvt|color|ansi|cygwin|linux/i.test(env.TERM)) return 1;
261
325
  if ("COLORTERM" in env) return 1;
262
326
  return min;
@@ -273,51 +337,30 @@ const supportsColor = {
273
337
  };
274
338
 
275
339
  //#endregion
276
- //#region ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/utilities.js
277
- function stringReplaceAll(string, substring, replacer) {
278
- let index = string.indexOf(substring);
279
- if (index === -1) return string;
280
- const substringLength = substring.length;
281
- let endIndex = 0;
282
- let returnValue = "";
283
- do {
284
- returnValue += string.slice(endIndex, index) + substring + replacer;
285
- endIndex = index + substringLength;
286
- index = string.indexOf(substring, endIndex);
287
- } while (index !== -1);
288
- returnValue += string.slice(endIndex);
289
- return returnValue;
290
- }
291
- function stringEncaseCRLFWithFirstIndex(string, prefix, postfix, index) {
292
- let endIndex = 0;
293
- let returnValue = "";
294
- do {
295
- const gotCR = string[index - 1] === "\r";
296
- returnValue += string.slice(endIndex, gotCR ? index - 1 : index) + prefix + (gotCR ? "\r\n" : "\n") + postfix;
297
- endIndex = index + 1;
298
- index = string.indexOf("\n", endIndex);
299
- } while (index !== -1);
300
- returnValue += string.slice(endIndex);
301
- return returnValue;
302
- }
303
-
304
- //#endregion
305
- //#region ../../node_modules/.bun/chalk@5.6.2/node_modules/chalk/source/index.js
340
+ //#region ../../node_modules/.bun/chalk@6.0.0/node_modules/chalk/source/index.js
306
341
  const { stdout: stdoutColor, stderr: stderrColor } = supportsColor;
307
342
  const GENERATOR = Symbol("GENERATOR");
308
343
  const STYLER = Symbol("STYLER");
309
344
  const IS_EMPTY = Symbol("IS_EMPTY");
310
- const levelMapping = [
311
- "ansi",
312
- "ansi",
313
- "ansi256",
314
- "ansi16m"
315
- ];
345
+ const LEVEL = Symbol("LEVEL");
316
346
  const styles = Object.create(null);
347
+ const assertValidLevel = (level) => {
348
+ if (!Number.isSafeInteger(level) || level < 0 || level > 3) throw new Error("The `level` should be an integer from 0 to 3");
349
+ };
350
+ const levelDescriptor = {
351
+ enumerable: true,
352
+ get() {
353
+ return this[LEVEL];
354
+ },
355
+ set(level) {
356
+ assertValidLevel(level);
357
+ this[LEVEL] = level;
358
+ }
359
+ };
317
360
  const applyOptions = (object, options = {}) => {
318
- if (options.level && !(Number.isInteger(options.level) && options.level >= 0 && options.level <= 3)) throw new Error("The `level` option should be an integer from 0 to 3");
361
+ if (options.level !== void 0) assertValidLevel(options.level);
319
362
  const colorLevel = stdoutColor ? stdoutColor.level : 0;
320
- object.level = options.level === void 0 ? colorLevel : options.level;
363
+ object[LEVEL] = options.level === void 0 ? colorLevel : options.level;
321
364
  };
322
365
  const chalkFactory = (options) => {
323
366
  const chalk = (...strings) => strings.join(" ");
@@ -339,35 +382,58 @@ styles.visible = { get() {
339
382
  Object.defineProperty(this, "visible", { value: builder });
340
383
  return builder;
341
384
  } };
342
- const getModelAnsi = (model, level, type, ...arguments_) => {
385
+ const createModelConverters = (model, type) => {
386
+ const style = ansiStyles[type];
343
387
  if (model === "rgb") {
344
- if (level === "ansi16m") return ansiStyles[type].ansi16m(...arguments_);
345
- if (level === "ansi256") return ansiStyles[type].ansi256(ansiStyles.rgbToAnsi256(...arguments_));
346
- return ansiStyles[type].ansi(ansiStyles.rgbToAnsi(...arguments_));
388
+ const ansi = (red, green, blue) => style.ansi(ansiStyles.rgbToAnsi(red, green, blue));
389
+ const ansi256 = (red, green, blue) => style.ansi256(ansiStyles.rgbToAnsi256(red, green, blue));
390
+ return [
391
+ ansi,
392
+ ansi,
393
+ ansi256,
394
+ style.ansi16m
395
+ ];
396
+ }
397
+ if (model === "hex") {
398
+ const ansi = (hex) => style.ansi(ansiStyles.hexToAnsi(hex));
399
+ const ansi256 = (hex) => style.ansi256(ansiStyles.hexToAnsi256(hex));
400
+ return [
401
+ ansi,
402
+ ansi,
403
+ ansi256,
404
+ (hex) => style.ansi16m(...ansiStyles.hexToRgb(hex))
405
+ ];
347
406
  }
348
- if (model === "hex") return getModelAnsi("rgb", level, type, ...ansiStyles.hexToRgb(...arguments_));
349
- return ansiStyles[type][model](...arguments_);
407
+ const ansi = (code) => style.ansi(ansiStyles.ansi256ToAnsi(code));
408
+ return [
409
+ ansi,
410
+ ansi,
411
+ style.ansi256,
412
+ style.ansi256
413
+ ];
350
414
  };
351
415
  for (const model of [
352
416
  "rgb",
353
417
  "hex",
354
418
  "ansi256"
355
419
  ]) {
356
- styles[model] = { get() {
357
- const { level } = this;
358
- return function(...arguments_) {
359
- const styler = createStyler(getModelAnsi(model, levelMapping[level], "color", ...arguments_), ansiStyles.color.close, this[STYLER]);
360
- return createBuilder(this, styler, this[IS_EMPTY]);
361
- };
362
- } };
363
- const bgModel = "bg" + model[0].toUpperCase() + model.slice(1);
364
- styles[bgModel] = { get() {
365
- const { level } = this;
366
- return function(...arguments_) {
367
- const styler = createStyler(getModelAnsi(model, levelMapping[level], "bgColor", ...arguments_), ansiStyles.bgColor.close, this[STYLER]);
368
- return createBuilder(this, styler, this[IS_EMPTY]);
369
- };
370
- } };
420
+ const capitalizedModel = model[0].toUpperCase() + model.slice(1);
421
+ for (const [styleName, type] of [
422
+ [model, "color"],
423
+ ["bg" + capitalizedModel, "bgColor"],
424
+ ["underline" + capitalizedModel, "underlineColor"]
425
+ ]) {
426
+ const { close } = ansiStyles[type];
427
+ const converters = createModelConverters(model, type);
428
+ styles[styleName] = { get() {
429
+ const styleFunction = function(first, second, third) {
430
+ const open = converters[this.level](first, second, third);
431
+ return createBuilder(this, createStyler(open, close, this[STYLER]), this[IS_EMPTY]);
432
+ };
433
+ Object.defineProperty(this, styleName, { value: styleFunction });
434
+ return styleFunction;
435
+ } };
436
+ }
371
437
  }
372
438
  const proto = Object.defineProperties(() => {}, {
373
439
  ...styles,
@@ -400,15 +466,19 @@ const createStyler = (open, close, parent) => {
400
466
  };
401
467
  };
402
468
  const createBuilder = (self, _styler, _isEmpty) => {
403
- const builder = (...arguments_) => applyStyle(builder, arguments_.length === 1 ? "" + arguments_[0] : arguments_.join(" "));
469
+ const builder = (...arguments_) => {
470
+ if (arguments_.length === 1) return applyStyle(builder, "" + arguments_[0]);
471
+ if (arguments_.length === 2) return applyStyle(builder, arguments_[0] + " " + arguments_[1]);
472
+ return applyStyle(builder, arguments_.join(" "));
473
+ };
404
474
  Object.setPrototypeOf(builder, proto);
405
- builder[GENERATOR] = self;
475
+ builder[GENERATOR] = self[GENERATOR] ?? self;
406
476
  builder[STYLER] = _styler;
407
477
  builder[IS_EMPTY] = _isEmpty;
408
478
  return builder;
409
479
  };
410
480
  const applyStyle = (self, string) => {
411
- if (self.level <= 0 || !string) return self[IS_EMPTY] ? "" : string;
481
+ if (self[GENERATOR][LEVEL] <= 0 || !string) return self[IS_EMPTY] ? "" : string;
412
482
  let styler = self[STYLER];
413
483
  if (styler === void 0) return string;
414
484
  const { openAll, closeAll } = styler;
@@ -420,7 +490,10 @@ const applyStyle = (self, string) => {
420
490
  if (lfIndex !== -1) string = stringEncaseCRLFWithFirstIndex(string, closeAll, openAll, lfIndex);
421
491
  return openAll + string + closeAll;
422
492
  };
423
- Object.defineProperties(createChalk.prototype, styles);
493
+ Object.defineProperties(createChalk.prototype, {
494
+ ...styles,
495
+ level: levelDescriptor
496
+ });
424
497
  const chalk = createChalk();
425
498
  const chalkStderr = createChalk({ level: stderrColor ? stderrColor.level : 0 });
426
499
 
@@ -761,7 +834,13 @@ const printScoreBox = async (score, label, categoryIssueCounts, warningsCount, e
761
834
  else if (score >= 75) scoreColor = chalk.yellow.bold;
762
835
  else if (score >= 50) scoreColor = chalk.magenta.bold;
763
836
  const whaleLines = getWhaleMascot(score, scoreColor);
764
- const shareUrl = `https://docker-doctor.vercel.app/share?s=${score}&w=${warningsCount}&e=${errorsCount}`;
837
+ const shareUrl = `https://docker-doctor.vercel.app/share?${new URLSearchParams({
838
+ e: String(errorsCount),
839
+ s: String(score),
840
+ utm_medium: "terminal",
841
+ utm_source: "cli",
842
+ w: String(warningsCount)
843
+ }).toString()}`;
765
844
  if (shouldAnimate) {
766
845
  const frameCount = 20;
767
846
  const frameDelay = 15;
@@ -826,6 +905,7 @@ const formatTerminal = async (diagnostics, score, label, project, verbose = fals
826
905
 
827
906
  //#endregion
828
907
  //#region src/cli.ts
908
+ const ACTION_REF = "PunGrumpy/docker-doctor@v1";
829
909
  const askConfirm = (question, defaultYes = false) => {
830
910
  if (!process.stdin.isTTY) return Promise.resolve(defaultYes);
831
911
  return new Promise((resolve) => {
@@ -1031,7 +1111,6 @@ const runInteractiveWizard = async (context) => {
1031
1111
  const workflowDir = node_path.default.resolve(".github/workflows");
1032
1112
  await node_fs_promises.default.mkdir(workflowDir, { recursive: true });
1033
1113
  const workflowPath = node_path.default.join(workflowDir, "docker-doctor.yml");
1034
- const [actionMajor] = require_src.package_default.version.split(".");
1035
1114
  const workflowYaml = `name: Docker Doctor
1036
1115
  on:
1037
1116
  pull_request:
@@ -1044,7 +1123,7 @@ jobs:
1044
1123
  runs-on: ubuntu-latest
1045
1124
  steps:
1046
1125
  - uses: actions/checkout@v5
1047
- - uses: PunGrumpy/docker-doctor@v${actionMajor}
1126
+ - uses: ${ACTION_REF}
1048
1127
  `;
1049
1128
  await node_fs_promises.default.writeFile(workflowPath, workflowYaml, "utf-8");
1050
1129
  console.log(`\n ${chalk.green("✨")} Created ${chalk.cyan(".github/workflows/docker-doctor.yml")}!`);
@@ -1105,7 +1184,7 @@ const filterDiagnostics = (diagnostics, categories) => {
1105
1184
  });
1106
1185
  };
1107
1186
  const program = new commander.Command();
1108
- program.name("docker-doctor").description("Static analysis for Dockerfile and Docker Compose files").version(require_src.package_default.version, "-V, --version", "display the version number");
1187
+ program.name("docker-doctor").description("Static analysis for Dockerfile and Docker Compose files").version(require_src.version, "-V, --version", "display the version number");
1109
1188
  program.argument("[dir]", "directory to scan", ".").option("-v, --verbose", "show verbose diagnostics description", false).option("-s, --score", "only output numeric health score", false).option("-j, --json", "output results as JSON report", false).option("-c, --config <path>", "custom config file path").action(async (dir, options) => {
1110
1189
  const isSilent = options.score || options.json;
1111
1190
  const restoreCursor = () => {