brady-cli 1.1.0 → 1.2.5

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/index.js CHANGED
@@ -26,16 +26,71 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
26
26
  mod
27
27
  ));
28
28
 
29
- // node_modules/commander/lib/error.js
29
+ // node_modules/.pnpm/sisteransi@1.0.5/node_modules/sisteransi/src/index.js
30
+ var require_src = __commonJS({
31
+ "node_modules/.pnpm/sisteransi@1.0.5/node_modules/sisteransi/src/index.js"(exports2, module2) {
32
+ "use strict";
33
+ var ESC2 = "\x1B";
34
+ var CSI2 = `${ESC2}[`;
35
+ var beep = "\x07";
36
+ var cursor = {
37
+ to(x, y) {
38
+ if (!y) return `${CSI2}${x + 1}G`;
39
+ return `${CSI2}${y + 1};${x + 1}H`;
40
+ },
41
+ move(x, y) {
42
+ let ret = "";
43
+ if (x < 0) ret += `${CSI2}${-x}D`;
44
+ else if (x > 0) ret += `${CSI2}${x}C`;
45
+ if (y < 0) ret += `${CSI2}${-y}A`;
46
+ else if (y > 0) ret += `${CSI2}${y}B`;
47
+ return ret;
48
+ },
49
+ up: (count = 1) => `${CSI2}${count}A`,
50
+ down: (count = 1) => `${CSI2}${count}B`,
51
+ forward: (count = 1) => `${CSI2}${count}C`,
52
+ backward: (count = 1) => `${CSI2}${count}D`,
53
+ nextLine: (count = 1) => `${CSI2}E`.repeat(count),
54
+ prevLine: (count = 1) => `${CSI2}F`.repeat(count),
55
+ left: `${CSI2}G`,
56
+ hide: `${CSI2}?25l`,
57
+ show: `${CSI2}?25h`,
58
+ save: `${ESC2}7`,
59
+ restore: `${ESC2}8`
60
+ };
61
+ var scroll = {
62
+ up: (count = 1) => `${CSI2}S`.repeat(count),
63
+ down: (count = 1) => `${CSI2}T`.repeat(count)
64
+ };
65
+ var erase = {
66
+ screen: `${CSI2}2J`,
67
+ up: (count = 1) => `${CSI2}1J`.repeat(count),
68
+ down: (count = 1) => `${CSI2}J`.repeat(count),
69
+ line: `${CSI2}2K`,
70
+ lineEnd: `${CSI2}K`,
71
+ lineStart: `${CSI2}1K`,
72
+ lines(count) {
73
+ let clear = "";
74
+ for (let i = 0; i < count; i++)
75
+ clear += this.line + (i < count - 1 ? cursor.up() : "");
76
+ if (count)
77
+ clear += cursor.left;
78
+ return clear;
79
+ }
80
+ };
81
+ module2.exports = { cursor, scroll, erase, beep };
82
+ }
83
+ });
84
+
85
+ // node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/error.js
30
86
  var require_error = __commonJS({
31
- "node_modules/commander/lib/error.js"(exports) {
87
+ "node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/error.js"(exports2) {
32
88
  var CommanderError2 = class extends Error {
33
89
  /**
34
90
  * Constructs the CommanderError class
35
91
  * @param {number} exitCode suggested exit code which could be used with process.exit
36
92
  * @param {string} code an id string representing the error
37
93
  * @param {string} message human-readable description of the error
38
- * @constructor
39
94
  */
40
95
  constructor(exitCode, code, message) {
41
96
  super(message);
@@ -50,7 +105,6 @@ var require_error = __commonJS({
50
105
  /**
51
106
  * Constructs the InvalidArgumentError class
52
107
  * @param {string} [message] explanation of why argument is invalid
53
- * @constructor
54
108
  */
55
109
  constructor(message) {
56
110
  super(1, "commander.invalidArgument", message);
@@ -58,14 +112,14 @@ var require_error = __commonJS({
58
112
  this.name = this.constructor.name;
59
113
  }
60
114
  };
61
- exports.CommanderError = CommanderError2;
62
- exports.InvalidArgumentError = InvalidArgumentError2;
115
+ exports2.CommanderError = CommanderError2;
116
+ exports2.InvalidArgumentError = InvalidArgumentError2;
63
117
  }
64
118
  });
65
119
 
66
- // node_modules/commander/lib/argument.js
120
+ // node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/argument.js
67
121
  var require_argument = __commonJS({
68
- "node_modules/commander/lib/argument.js"(exports) {
122
+ "node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/argument.js"(exports2) {
69
123
  var { InvalidArgumentError: InvalidArgumentError2 } = require_error();
70
124
  var Argument2 = class {
71
125
  /**
@@ -97,7 +151,7 @@ var require_argument = __commonJS({
97
151
  this._name = name;
98
152
  break;
99
153
  }
100
- if (this._name.length > 3 && this._name.slice(-3) === "...") {
154
+ if (this._name.endsWith("...")) {
101
155
  this.variadic = true;
102
156
  this._name = this._name.slice(0, -3);
103
157
  }
@@ -111,18 +165,19 @@ var require_argument = __commonJS({
111
165
  return this._name;
112
166
  }
113
167
  /**
114
- * @api private
168
+ * @package
115
169
  */
116
- _concatValue(value, previous) {
170
+ _collectValue(value, previous) {
117
171
  if (previous === this.defaultValue || !Array.isArray(previous)) {
118
172
  return [value];
119
173
  }
120
- return previous.concat(value);
174
+ previous.push(value);
175
+ return previous;
121
176
  }
122
177
  /**
123
178
  * Set the default value, and optionally supply the description to be displayed in the help.
124
179
  *
125
- * @param {any} value
180
+ * @param {*} value
126
181
  * @param {string} [description]
127
182
  * @return {Argument}
128
183
  */
@@ -151,10 +206,12 @@ var require_argument = __commonJS({
151
206
  this.argChoices = values.slice();
152
207
  this.parseArg = (arg, previous) => {
153
208
  if (!this.argChoices.includes(arg)) {
154
- throw new InvalidArgumentError2(`Allowed choices are ${this.argChoices.join(", ")}.`);
209
+ throw new InvalidArgumentError2(
210
+ `Allowed choices are ${this.argChoices.join(", ")}.`
211
+ );
155
212
  }
156
213
  if (this.variadic) {
157
- return this._concatValue(arg, previous);
214
+ return this._collectValue(arg, previous);
158
215
  }
159
216
  return arg;
160
217
  };
@@ -162,6 +219,8 @@ var require_argument = __commonJS({
162
219
  }
163
220
  /**
164
221
  * Make argument required.
222
+ *
223
+ * @returns {Argument}
165
224
  */
166
225
  argRequired() {
167
226
  this.required = true;
@@ -169,6 +228,8 @@ var require_argument = __commonJS({
169
228
  }
170
229
  /**
171
230
  * Make argument optional.
231
+ *
232
+ * @returns {Argument}
172
233
  */
173
234
  argOptional() {
174
235
  this.required = false;
@@ -179,22 +240,34 @@ var require_argument = __commonJS({
179
240
  const nameOutput = arg.name() + (arg.variadic === true ? "..." : "");
180
241
  return arg.required ? "<" + nameOutput + ">" : "[" + nameOutput + "]";
181
242
  }
182
- exports.Argument = Argument2;
183
- exports.humanReadableArgName = humanReadableArgName;
243
+ exports2.Argument = Argument2;
244
+ exports2.humanReadableArgName = humanReadableArgName;
184
245
  }
185
246
  });
186
247
 
187
- // node_modules/commander/lib/help.js
248
+ // node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/help.js
188
249
  var require_help = __commonJS({
189
- "node_modules/commander/lib/help.js"(exports) {
250
+ "node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/help.js"(exports2) {
190
251
  var { humanReadableArgName } = require_argument();
191
252
  var Help2 = class {
192
253
  constructor() {
193
254
  this.helpWidth = void 0;
255
+ this.minWidthToWrap = 40;
194
256
  this.sortSubcommands = false;
195
257
  this.sortOptions = false;
196
258
  this.showGlobalOptions = false;
197
259
  }
260
+ /**
261
+ * prepareContext is called by Commander after applying overrides from `Command.configureHelp()`
262
+ * and just before calling `formatHelp()`.
263
+ *
264
+ * Commander just uses the helpWidth and the rest is provided for optional use by more complex subclasses.
265
+ *
266
+ * @param {{ error?: boolean, helpWidth?: number, outputHasColors?: boolean }} contextOptions
267
+ */
268
+ prepareContext(contextOptions) {
269
+ this.helpWidth = this.helpWidth ?? contextOptions.helpWidth ?? 80;
270
+ }
198
271
  /**
199
272
  * Get an array of the visible subcommands. Includes a placeholder for the implicit help command, if there is one.
200
273
  *
@@ -203,12 +276,8 @@ var require_help = __commonJS({
203
276
  */
204
277
  visibleCommands(cmd) {
205
278
  const visibleCommands = cmd.commands.filter((cmd2) => !cmd2._hidden);
206
- if (cmd._hasImplicitHelpCommand()) {
207
- const [, helpName, helpArgs] = cmd._helpCommandnameAndArgs.match(/([^ ]+) *(.*)/);
208
- const helpCommand = cmd.createCommand(helpName).helpOption(false);
209
- helpCommand.description(cmd._helpCommandDescription);
210
- if (helpArgs)
211
- helpCommand.arguments(helpArgs);
279
+ const helpCommand = cmd._getHelpCommand();
280
+ if (helpCommand && !helpCommand._hidden) {
212
281
  visibleCommands.push(helpCommand);
213
282
  }
214
283
  if (this.sortSubcommands) {
@@ -223,7 +292,7 @@ var require_help = __commonJS({
223
292
  *
224
293
  * @param {Option} a
225
294
  * @param {Option} b
226
- * @returns number
295
+ * @returns {number}
227
296
  */
228
297
  compareOptions(a, b) {
229
298
  const getSortKey = (option) => {
@@ -239,18 +308,21 @@ var require_help = __commonJS({
239
308
  */
240
309
  visibleOptions(cmd) {
241
310
  const visibleOptions = cmd.options.filter((option) => !option.hidden);
242
- const showShortHelpFlag = cmd._hasHelpOption && cmd._helpShortFlag && !cmd._findOption(cmd._helpShortFlag);
243
- const showLongHelpFlag = cmd._hasHelpOption && !cmd._findOption(cmd._helpLongFlag);
244
- if (showShortHelpFlag || showLongHelpFlag) {
245
- let helpOption;
246
- if (!showShortHelpFlag) {
247
- helpOption = cmd.createOption(cmd._helpLongFlag, cmd._helpDescription);
248
- } else if (!showLongHelpFlag) {
249
- helpOption = cmd.createOption(cmd._helpShortFlag, cmd._helpDescription);
250
- } else {
251
- helpOption = cmd.createOption(cmd._helpFlags, cmd._helpDescription);
311
+ const helpOption = cmd._getHelpOption();
312
+ if (helpOption && !helpOption.hidden) {
313
+ const removeShort = helpOption.short && cmd._findOption(helpOption.short);
314
+ const removeLong = helpOption.long && cmd._findOption(helpOption.long);
315
+ if (!removeShort && !removeLong) {
316
+ visibleOptions.push(helpOption);
317
+ } else if (helpOption.long && !removeLong) {
318
+ visibleOptions.push(
319
+ cmd.createOption(helpOption.long, helpOption.description)
320
+ );
321
+ } else if (helpOption.short && !removeShort) {
322
+ visibleOptions.push(
323
+ cmd.createOption(helpOption.short, helpOption.description)
324
+ );
252
325
  }
253
- visibleOptions.push(helpOption);
254
326
  }
255
327
  if (this.sortOptions) {
256
328
  visibleOptions.sort(this.compareOptions);
@@ -264,11 +336,12 @@ var require_help = __commonJS({
264
336
  * @returns {Option[]}
265
337
  */
266
338
  visibleGlobalOptions(cmd) {
267
- if (!this.showGlobalOptions)
268
- return [];
339
+ if (!this.showGlobalOptions) return [];
269
340
  const globalOptions = [];
270
- for (let parentCmd = cmd.parent; parentCmd; parentCmd = parentCmd.parent) {
271
- const visibleOptions = parentCmd.options.filter((option) => !option.hidden);
341
+ for (let ancestorCmd = cmd.parent; ancestorCmd; ancestorCmd = ancestorCmd.parent) {
342
+ const visibleOptions = ancestorCmd.options.filter(
343
+ (option) => !option.hidden
344
+ );
272
345
  globalOptions.push(...visibleOptions);
273
346
  }
274
347
  if (this.sortOptions) {
@@ -284,12 +357,12 @@ var require_help = __commonJS({
284
357
  */
285
358
  visibleArguments(cmd) {
286
359
  if (cmd._argsDescription) {
287
- cmd._args.forEach((argument) => {
360
+ cmd.registeredArguments.forEach((argument) => {
288
361
  argument.description = argument.description || cmd._argsDescription[argument.name()] || "";
289
362
  });
290
363
  }
291
- if (cmd._args.find((argument) => argument.description)) {
292
- return cmd._args;
364
+ if (cmd.registeredArguments.find((argument) => argument.description)) {
365
+ return cmd.registeredArguments;
293
366
  }
294
367
  return [];
295
368
  }
@@ -300,7 +373,7 @@ var require_help = __commonJS({
300
373
  * @returns {string}
301
374
  */
302
375
  subcommandTerm(cmd) {
303
- const args = cmd._args.map((arg) => humanReadableArgName(arg)).join(" ");
376
+ const args = cmd.registeredArguments.map((arg) => humanReadableArgName(arg)).join(" ");
304
377
  return cmd._name + (cmd._aliases[0] ? "|" + cmd._aliases[0] : "") + (cmd.options.length ? " [options]" : "") + // simplistic check for non-help option
305
378
  (args ? " " + args : "");
306
379
  }
@@ -331,7 +404,12 @@ var require_help = __commonJS({
331
404
  */
332
405
  longestSubcommandTermLength(cmd, helper) {
333
406
  return helper.visibleCommands(cmd).reduce((max, command) => {
334
- return Math.max(max, helper.subcommandTerm(command).length);
407
+ return Math.max(
408
+ max,
409
+ this.displayWidth(
410
+ helper.styleSubcommandTerm(helper.subcommandTerm(command))
411
+ )
412
+ );
335
413
  }, 0);
336
414
  }
337
415
  /**
@@ -343,7 +421,10 @@ var require_help = __commonJS({
343
421
  */
344
422
  longestOptionTermLength(cmd, helper) {
345
423
  return helper.visibleOptions(cmd).reduce((max, option) => {
346
- return Math.max(max, helper.optionTerm(option).length);
424
+ return Math.max(
425
+ max,
426
+ this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option)))
427
+ );
347
428
  }, 0);
348
429
  }
349
430
  /**
@@ -355,7 +436,10 @@ var require_help = __commonJS({
355
436
  */
356
437
  longestGlobalOptionTermLength(cmd, helper) {
357
438
  return helper.visibleGlobalOptions(cmd).reduce((max, option) => {
358
- return Math.max(max, helper.optionTerm(option).length);
439
+ return Math.max(
440
+ max,
441
+ this.displayWidth(helper.styleOptionTerm(helper.optionTerm(option)))
442
+ );
359
443
  }, 0);
360
444
  }
361
445
  /**
@@ -367,7 +451,12 @@ var require_help = __commonJS({
367
451
  */
368
452
  longestArgumentTermLength(cmd, helper) {
369
453
  return helper.visibleArguments(cmd).reduce((max, argument) => {
370
- return Math.max(max, helper.argumentTerm(argument).length);
454
+ return Math.max(
455
+ max,
456
+ this.displayWidth(
457
+ helper.styleArgumentTerm(helper.argumentTerm(argument))
458
+ )
459
+ );
371
460
  }, 0);
372
461
  }
373
462
  /**
@@ -381,11 +470,11 @@ var require_help = __commonJS({
381
470
  if (cmd._aliases[0]) {
382
471
  cmdName = cmdName + "|" + cmd._aliases[0];
383
472
  }
384
- let parentCmdNames = "";
385
- for (let parentCmd = cmd.parent; parentCmd; parentCmd = parentCmd.parent) {
386
- parentCmdNames = parentCmd.name() + " " + parentCmdNames;
473
+ let ancestorCmdNames = "";
474
+ for (let ancestorCmd = cmd.parent; ancestorCmd; ancestorCmd = ancestorCmd.parent) {
475
+ ancestorCmdNames = ancestorCmd.name() + " " + ancestorCmdNames;
387
476
  }
388
- return parentCmdNames + cmdName + " " + cmd.usage();
477
+ return ancestorCmdNames + cmdName + " " + cmd.usage();
389
478
  }
390
479
  /**
391
480
  * Get the description for the command.
@@ -423,7 +512,9 @@ var require_help = __commonJS({
423
512
  if (option.defaultValue !== void 0) {
424
513
  const showDefault = option.required || option.optional || option.isBoolean() && typeof option.defaultValue === "boolean";
425
514
  if (showDefault) {
426
- extraInfo.push(`default: ${option.defaultValueDescription || JSON.stringify(option.defaultValue)}`);
515
+ extraInfo.push(
516
+ `default: ${option.defaultValueDescription || JSON.stringify(option.defaultValue)}`
517
+ );
427
518
  }
428
519
  }
429
520
  if (option.presetArg !== void 0 && option.optional) {
@@ -433,7 +524,11 @@ var require_help = __commonJS({
433
524
  extraInfo.push(`env: ${option.envVar}`);
434
525
  }
435
526
  if (extraInfo.length > 0) {
436
- return `${option.description} (${extraInfo.join(", ")})`;
527
+ const extraDescription = `(${extraInfo.join(", ")})`;
528
+ if (option.description) {
529
+ return `${option.description} ${extraDescription}`;
530
+ }
531
+ return extraDescription;
437
532
  }
438
533
  return option.description;
439
534
  }
@@ -452,17 +547,54 @@ var require_help = __commonJS({
452
547
  );
453
548
  }
454
549
  if (argument.defaultValue !== void 0) {
455
- extraInfo.push(`default: ${argument.defaultValueDescription || JSON.stringify(argument.defaultValue)}`);
550
+ extraInfo.push(
551
+ `default: ${argument.defaultValueDescription || JSON.stringify(argument.defaultValue)}`
552
+ );
456
553
  }
457
554
  if (extraInfo.length > 0) {
458
- const extraDescripton = `(${extraInfo.join(", ")})`;
555
+ const extraDescription = `(${extraInfo.join(", ")})`;
459
556
  if (argument.description) {
460
- return `${argument.description} ${extraDescripton}`;
557
+ return `${argument.description} ${extraDescription}`;
461
558
  }
462
- return extraDescripton;
559
+ return extraDescription;
463
560
  }
464
561
  return argument.description;
465
562
  }
563
+ /**
564
+ * Format a list of items, given a heading and an array of formatted items.
565
+ *
566
+ * @param {string} heading
567
+ * @param {string[]} items
568
+ * @param {Help} helper
569
+ * @returns string[]
570
+ */
571
+ formatItemList(heading, items, helper) {
572
+ if (items.length === 0) return [];
573
+ return [helper.styleTitle(heading), ...items, ""];
574
+ }
575
+ /**
576
+ * Group items by their help group heading.
577
+ *
578
+ * @param {Command[] | Option[]} unsortedItems
579
+ * @param {Command[] | Option[]} visibleItems
580
+ * @param {Function} getGroup
581
+ * @returns {Map<string, Command[] | Option[]>}
582
+ */
583
+ groupItems(unsortedItems, visibleItems, getGroup) {
584
+ const result = /* @__PURE__ */ new Map();
585
+ unsortedItems.forEach((item) => {
586
+ const group = getGroup(item);
587
+ if (!result.has(group)) result.set(group, []);
588
+ });
589
+ visibleItems.forEach((item) => {
590
+ const group = getGroup(item);
591
+ if (!result.has(group)) {
592
+ result.set(group, []);
593
+ }
594
+ result.get(group).push(item);
595
+ });
596
+ return result;
597
+ }
466
598
  /**
467
599
  * Generate the built-in help text.
468
600
  *
@@ -472,52 +604,142 @@ var require_help = __commonJS({
472
604
  */
473
605
  formatHelp(cmd, helper) {
474
606
  const termWidth = helper.padWidth(cmd, helper);
475
- const helpWidth = helper.helpWidth || 80;
476
- const itemIndentWidth = 2;
477
- const itemSeparatorWidth = 2;
478
- function formatItem(term, description) {
479
- if (description) {
480
- const fullText = `${term.padEnd(termWidth + itemSeparatorWidth)}${description}`;
481
- return helper.wrap(fullText, helpWidth - itemIndentWidth, termWidth + itemSeparatorWidth);
482
- }
483
- return term;
607
+ const helpWidth = helper.helpWidth ?? 80;
608
+ function callFormatItem(term, description) {
609
+ return helper.formatItem(term, termWidth, description, helper);
484
610
  }
485
- function formatList(textArray) {
486
- return textArray.join("\n").replace(/^/gm, " ".repeat(itemIndentWidth));
487
- }
488
- let output = [`Usage: ${helper.commandUsage(cmd)}`, ""];
611
+ let output = [
612
+ `${helper.styleTitle("Usage:")} ${helper.styleUsage(helper.commandUsage(cmd))}`,
613
+ ""
614
+ ];
489
615
  const commandDescription = helper.commandDescription(cmd);
490
616
  if (commandDescription.length > 0) {
491
- output = output.concat([helper.wrap(commandDescription, helpWidth, 0), ""]);
617
+ output = output.concat([
618
+ helper.boxWrap(
619
+ helper.styleCommandDescription(commandDescription),
620
+ helpWidth
621
+ ),
622
+ ""
623
+ ]);
492
624
  }
493
625
  const argumentList = helper.visibleArguments(cmd).map((argument) => {
494
- return formatItem(helper.argumentTerm(argument), helper.argumentDescription(argument));
626
+ return callFormatItem(
627
+ helper.styleArgumentTerm(helper.argumentTerm(argument)),
628
+ helper.styleArgumentDescription(helper.argumentDescription(argument))
629
+ );
495
630
  });
496
- if (argumentList.length > 0) {
497
- output = output.concat(["Arguments:", formatList(argumentList), ""]);
498
- }
499
- const optionList = helper.visibleOptions(cmd).map((option) => {
500
- return formatItem(helper.optionTerm(option), helper.optionDescription(option));
631
+ output = output.concat(
632
+ this.formatItemList("Arguments:", argumentList, helper)
633
+ );
634
+ const optionGroups = this.groupItems(
635
+ cmd.options,
636
+ helper.visibleOptions(cmd),
637
+ (option) => option.helpGroupHeading ?? "Options:"
638
+ );
639
+ optionGroups.forEach((options, group) => {
640
+ const optionList = options.map((option) => {
641
+ return callFormatItem(
642
+ helper.styleOptionTerm(helper.optionTerm(option)),
643
+ helper.styleOptionDescription(helper.optionDescription(option))
644
+ );
645
+ });
646
+ output = output.concat(this.formatItemList(group, optionList, helper));
501
647
  });
502
- if (optionList.length > 0) {
503
- output = output.concat(["Options:", formatList(optionList), ""]);
504
- }
505
- if (this.showGlobalOptions) {
648
+ if (helper.showGlobalOptions) {
506
649
  const globalOptionList = helper.visibleGlobalOptions(cmd).map((option) => {
507
- return formatItem(helper.optionTerm(option), helper.optionDescription(option));
650
+ return callFormatItem(
651
+ helper.styleOptionTerm(helper.optionTerm(option)),
652
+ helper.styleOptionDescription(helper.optionDescription(option))
653
+ );
508
654
  });
509
- if (globalOptionList.length > 0) {
510
- output = output.concat(["Global Options:", formatList(globalOptionList), ""]);
511
- }
655
+ output = output.concat(
656
+ this.formatItemList("Global Options:", globalOptionList, helper)
657
+ );
512
658
  }
513
- const commandList = helper.visibleCommands(cmd).map((cmd2) => {
514
- return formatItem(helper.subcommandTerm(cmd2), helper.subcommandDescription(cmd2));
659
+ const commandGroups = this.groupItems(
660
+ cmd.commands,
661
+ helper.visibleCommands(cmd),
662
+ (sub) => sub.helpGroup() || "Commands:"
663
+ );
664
+ commandGroups.forEach((commands, group) => {
665
+ const commandList = commands.map((sub) => {
666
+ return callFormatItem(
667
+ helper.styleSubcommandTerm(helper.subcommandTerm(sub)),
668
+ helper.styleSubcommandDescription(helper.subcommandDescription(sub))
669
+ );
670
+ });
671
+ output = output.concat(this.formatItemList(group, commandList, helper));
515
672
  });
516
- if (commandList.length > 0) {
517
- output = output.concat(["Commands:", formatList(commandList), ""]);
518
- }
519
673
  return output.join("\n");
520
674
  }
675
+ /**
676
+ * Return display width of string, ignoring ANSI escape sequences. Used in padding and wrapping calculations.
677
+ *
678
+ * @param {string} str
679
+ * @returns {number}
680
+ */
681
+ displayWidth(str) {
682
+ return stripColor(str).length;
683
+ }
684
+ /**
685
+ * Style the title for displaying in the help. Called with 'Usage:', 'Options:', etc.
686
+ *
687
+ * @param {string} str
688
+ * @returns {string}
689
+ */
690
+ styleTitle(str) {
691
+ return str;
692
+ }
693
+ styleUsage(str) {
694
+ return str.split(" ").map((word) => {
695
+ if (word === "[options]") return this.styleOptionText(word);
696
+ if (word === "[command]") return this.styleSubcommandText(word);
697
+ if (word[0] === "[" || word[0] === "<")
698
+ return this.styleArgumentText(word);
699
+ return this.styleCommandText(word);
700
+ }).join(" ");
701
+ }
702
+ styleCommandDescription(str) {
703
+ return this.styleDescriptionText(str);
704
+ }
705
+ styleOptionDescription(str) {
706
+ return this.styleDescriptionText(str);
707
+ }
708
+ styleSubcommandDescription(str) {
709
+ return this.styleDescriptionText(str);
710
+ }
711
+ styleArgumentDescription(str) {
712
+ return this.styleDescriptionText(str);
713
+ }
714
+ styleDescriptionText(str) {
715
+ return str;
716
+ }
717
+ styleOptionTerm(str) {
718
+ return this.styleOptionText(str);
719
+ }
720
+ styleSubcommandTerm(str) {
721
+ return str.split(" ").map((word) => {
722
+ if (word === "[options]") return this.styleOptionText(word);
723
+ if (word[0] === "[" || word[0] === "<")
724
+ return this.styleArgumentText(word);
725
+ return this.styleSubcommandText(word);
726
+ }).join(" ");
727
+ }
728
+ styleArgumentTerm(str) {
729
+ return this.styleArgumentText(str);
730
+ }
731
+ styleOptionText(str) {
732
+ return str;
733
+ }
734
+ styleArgumentText(str) {
735
+ return str;
736
+ }
737
+ styleSubcommandText(str) {
738
+ return str;
739
+ }
740
+ styleCommandText(str) {
741
+ return str;
742
+ }
521
743
  /**
522
744
  * Calculate the pad width from the maximum term length.
523
745
  *
@@ -534,46 +756,100 @@ var require_help = __commonJS({
534
756
  );
535
757
  }
536
758
  /**
537
- * Wrap the given string to width characters per line, with lines after the first indented.
538
- * Do not wrap if insufficient room for wrapping (minColumnWidth), or string is manually formatted.
759
+ * Detect manually wrapped and indented strings by checking for line break followed by whitespace.
539
760
  *
540
761
  * @param {string} str
541
- * @param {number} width
542
- * @param {number} indent
543
- * @param {number} [minColumnWidth=40]
544
- * @return {string}
762
+ * @returns {boolean}
763
+ */
764
+ preformatted(str) {
765
+ return /\n[^\S\r\n]/.test(str);
766
+ }
767
+ /**
768
+ * Format the "item", which consists of a term and description. Pad the term and wrap the description, indenting the following lines.
769
+ *
770
+ * So "TTT", 5, "DDD DDDD DD DDD" might be formatted for this.helpWidth=17 like so:
771
+ * TTT DDD DDDD
772
+ * DD DDD
773
+ *
774
+ * @param {string} term
775
+ * @param {number} termWidth
776
+ * @param {string} description
777
+ * @param {Help} helper
778
+ * @returns {string}
779
+ */
780
+ formatItem(term, termWidth, description, helper) {
781
+ const itemIndent = 2;
782
+ const itemIndentStr = " ".repeat(itemIndent);
783
+ if (!description) return itemIndentStr + term;
784
+ const paddedTerm = term.padEnd(
785
+ termWidth + term.length - helper.displayWidth(term)
786
+ );
787
+ const spacerWidth = 2;
788
+ const helpWidth = this.helpWidth ?? 80;
789
+ const remainingWidth = helpWidth - termWidth - spacerWidth - itemIndent;
790
+ let formattedDescription;
791
+ if (remainingWidth < this.minWidthToWrap || helper.preformatted(description)) {
792
+ formattedDescription = description;
793
+ } else {
794
+ const wrappedDescription = helper.boxWrap(description, remainingWidth);
795
+ formattedDescription = wrappedDescription.replace(
796
+ /\n/g,
797
+ "\n" + " ".repeat(termWidth + spacerWidth)
798
+ );
799
+ }
800
+ return itemIndentStr + paddedTerm + " ".repeat(spacerWidth) + formattedDescription.replace(/\n/g, `
801
+ ${itemIndentStr}`);
802
+ }
803
+ /**
804
+ * Wrap a string at whitespace, preserving existing line breaks.
805
+ * Wrapping is skipped if the width is less than `minWidthToWrap`.
545
806
  *
807
+ * @param {string} str
808
+ * @param {number} width
809
+ * @returns {string}
546
810
  */
547
- wrap(str, width, indent, minColumnWidth = 40) {
548
- const indents = " \\f\\t\\v\xA0\u1680\u2000-\u200A\u202F\u205F\u3000\uFEFF";
549
- const manualIndent = new RegExp(`[\\n][${indents}]+`);
550
- if (str.match(manualIndent))
551
- return str;
552
- const columnWidth = width - indent;
553
- if (columnWidth < minColumnWidth)
554
- return str;
555
- const leadingStr = str.slice(0, indent);
556
- const columnText = str.slice(indent).replace("\r\n", "\n");
557
- const indentString = " ".repeat(indent);
558
- const zeroWidthSpace = "\u200B";
559
- const breaks = `\\s${zeroWidthSpace}`;
560
- const regex = new RegExp(`
561
- |.{1,${columnWidth - 1}}([${breaks}]|$)|[^${breaks}]+?([${breaks}]|$)`, "g");
562
- const lines = columnText.match(regex) || [];
563
- return leadingStr + lines.map((line, i) => {
564
- if (line === "\n")
565
- return "";
566
- return (i > 0 ? indentString : "") + line.trimEnd();
567
- }).join("\n");
811
+ boxWrap(str, width) {
812
+ if (width < this.minWidthToWrap) return str;
813
+ const rawLines = str.split(/\r\n|\n/);
814
+ const chunkPattern = /[\s]*[^\s]+/g;
815
+ const wrappedLines = [];
816
+ rawLines.forEach((line) => {
817
+ const chunks = line.match(chunkPattern);
818
+ if (chunks === null) {
819
+ wrappedLines.push("");
820
+ return;
821
+ }
822
+ let sumChunks = [chunks.shift()];
823
+ let sumWidth = this.displayWidth(sumChunks[0]);
824
+ chunks.forEach((chunk) => {
825
+ const visibleWidth = this.displayWidth(chunk);
826
+ if (sumWidth + visibleWidth <= width) {
827
+ sumChunks.push(chunk);
828
+ sumWidth += visibleWidth;
829
+ return;
830
+ }
831
+ wrappedLines.push(sumChunks.join(""));
832
+ const nextChunk = chunk.trimStart();
833
+ sumChunks = [nextChunk];
834
+ sumWidth = this.displayWidth(nextChunk);
835
+ });
836
+ wrappedLines.push(sumChunks.join(""));
837
+ });
838
+ return wrappedLines.join("\n");
568
839
  }
569
840
  };
570
- exports.Help = Help2;
841
+ function stripColor(str) {
842
+ const sgrPattern = /\x1b\[\d*(;\d*)*m/g;
843
+ return str.replace(sgrPattern, "");
844
+ }
845
+ exports2.Help = Help2;
846
+ exports2.stripColor = stripColor;
571
847
  }
572
848
  });
573
849
 
574
- // node_modules/commander/lib/option.js
850
+ // node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/option.js
575
851
  var require_option = __commonJS({
576
- "node_modules/commander/lib/option.js"(exports) {
852
+ "node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/option.js"(exports2) {
577
853
  var { InvalidArgumentError: InvalidArgumentError2 } = require_error();
578
854
  var Option2 = class {
579
855
  /**
@@ -605,11 +881,12 @@ var require_option = __commonJS({
605
881
  this.argChoices = void 0;
606
882
  this.conflictsWith = [];
607
883
  this.implied = void 0;
884
+ this.helpGroupHeading = void 0;
608
885
  }
609
886
  /**
610
887
  * Set the default value, and optionally supply the description to be displayed in the help.
611
888
  *
612
- * @param {any} value
889
+ * @param {*} value
613
890
  * @param {string} [description]
614
891
  * @return {Option}
615
892
  */
@@ -626,7 +903,7 @@ var require_option = __commonJS({
626
903
  * new Option('--color').default('GREYSCALE').preset('RGB');
627
904
  * new Option('--donate [amount]').preset('20').argParser(parseFloat);
628
905
  *
629
- * @param {any} arg
906
+ * @param {*} arg
630
907
  * @return {Option}
631
908
  */
632
909
  preset(arg) {
@@ -641,7 +918,7 @@ var require_option = __commonJS({
641
918
  * new Option('--rgb').conflicts('cmyk');
642
919
  * new Option('--js').conflicts(['ts', 'jsx']);
643
920
  *
644
- * @param {string | string[]} names
921
+ * @param {(string | string[])} names
645
922
  * @return {Option}
646
923
  */
647
924
  conflicts(names) {
@@ -658,7 +935,7 @@ var require_option = __commonJS({
658
935
  * .addOption(new Option('--log', 'write logging information to file'))
659
936
  * .addOption(new Option('--trace', 'log extra details').implies({ log: 'trace.txt' }));
660
937
  *
661
- * @param {Object} impliedOptionValues
938
+ * @param {object} impliedOptionValues
662
939
  * @return {Option}
663
940
  */
664
941
  implies(impliedOptionValues) {
@@ -713,13 +990,14 @@ var require_option = __commonJS({
713
990
  return this;
714
991
  }
715
992
  /**
716
- * @api private
993
+ * @package
717
994
  */
718
- _concatValue(value, previous) {
995
+ _collectValue(value, previous) {
719
996
  if (previous === this.defaultValue || !Array.isArray(previous)) {
720
997
  return [value];
721
998
  }
722
- return previous.concat(value);
999
+ previous.push(value);
1000
+ return previous;
723
1001
  }
724
1002
  /**
725
1003
  * Only allow option value to be one of choices.
@@ -731,10 +1009,12 @@ var require_option = __commonJS({
731
1009
  this.argChoices = values.slice();
732
1010
  this.parseArg = (arg, previous) => {
733
1011
  if (!this.argChoices.includes(arg)) {
734
- throw new InvalidArgumentError2(`Allowed choices are ${this.argChoices.join(", ")}.`);
1012
+ throw new InvalidArgumentError2(
1013
+ `Allowed choices are ${this.argChoices.join(", ")}.`
1014
+ );
735
1015
  }
736
1016
  if (this.variadic) {
737
- return this._concatValue(arg, previous);
1017
+ return this._collectValue(arg, previous);
738
1018
  }
739
1019
  return arg;
740
1020
  };
@@ -753,20 +1033,32 @@ var require_option = __commonJS({
753
1033
  }
754
1034
  /**
755
1035
  * Return option name, in a camelcase format that can be used
756
- * as a object attribute key.
1036
+ * as an object attribute key.
757
1037
  *
758
1038
  * @return {string}
759
- * @api private
760
1039
  */
761
1040
  attributeName() {
762
- return camelcase(this.name().replace(/^no-/, ""));
1041
+ if (this.negate) {
1042
+ return camelcase(this.name().replace(/^no-/, ""));
1043
+ }
1044
+ return camelcase(this.name());
1045
+ }
1046
+ /**
1047
+ * Set the help group heading.
1048
+ *
1049
+ * @param {string} heading
1050
+ * @return {Option}
1051
+ */
1052
+ helpGroup(heading) {
1053
+ this.helpGroupHeading = heading;
1054
+ return this;
763
1055
  }
764
1056
  /**
765
1057
  * Check if `arg` matches the short or long flag.
766
1058
  *
767
1059
  * @param {string} arg
768
1060
  * @return {boolean}
769
- * @api private
1061
+ * @package
770
1062
  */
771
1063
  is(arg) {
772
1064
  return this.short === arg || this.long === arg;
@@ -777,7 +1069,7 @@ var require_option = __commonJS({
777
1069
  * Options are one of boolean, negated, required argument, or optional argument.
778
1070
  *
779
1071
  * @return {boolean}
780
- * @api private
1072
+ * @package
781
1073
  */
782
1074
  isBoolean() {
783
1075
  return !this.required && !this.optional && !this.negate;
@@ -807,14 +1099,13 @@ var require_option = __commonJS({
807
1099
  /**
808
1100
  * Did the value come from the option, and not from possible matching dual option?
809
1101
  *
810
- * @param {any} value
1102
+ * @param {*} value
811
1103
  * @param {Option} option
812
1104
  * @returns {boolean}
813
1105
  */
814
1106
  valueFromOption(value, option) {
815
1107
  const optionKey = option.attributeName();
816
- if (!this.dualOptions.has(optionKey))
817
- return true;
1108
+ if (!this.dualOptions.has(optionKey)) return true;
818
1109
  const preset = this.negativeOptions.get(optionKey).presetArg;
819
1110
  const negativeValue = preset !== void 0 ? preset : false;
820
1111
  return option.negate === (negativeValue === value);
@@ -828,62 +1119,86 @@ var require_option = __commonJS({
828
1119
  function splitOptionFlags(flags) {
829
1120
  let shortFlag;
830
1121
  let longFlag;
831
- const flagParts = flags.split(/[ |,]+/);
832
- if (flagParts.length > 1 && !/^[[<]/.test(flagParts[1]))
1122
+ const shortFlagExp = /^-[^-]$/;
1123
+ const longFlagExp = /^--[^-]/;
1124
+ const flagParts = flags.split(/[ |,]+/).concat("guard");
1125
+ if (shortFlagExp.test(flagParts[0])) shortFlag = flagParts.shift();
1126
+ if (longFlagExp.test(flagParts[0])) longFlag = flagParts.shift();
1127
+ if (!shortFlag && shortFlagExp.test(flagParts[0]))
833
1128
  shortFlag = flagParts.shift();
834
- longFlag = flagParts.shift();
835
- if (!shortFlag && /^-[^-]$/.test(longFlag)) {
1129
+ if (!shortFlag && longFlagExp.test(flagParts[0])) {
836
1130
  shortFlag = longFlag;
837
- longFlag = void 0;
838
- }
1131
+ longFlag = flagParts.shift();
1132
+ }
1133
+ if (flagParts[0].startsWith("-")) {
1134
+ const unsupportedFlag = flagParts[0];
1135
+ const baseError = `option creation failed due to '${unsupportedFlag}' in option flags '${flags}'`;
1136
+ if (/^-[^-][^-]/.test(unsupportedFlag))
1137
+ throw new Error(
1138
+ `${baseError}
1139
+ - a short flag is a single dash and a single character
1140
+ - either use a single dash and a single character (for a short flag)
1141
+ - or use a double dash for a long option (and can have two, like '--ws, --workspace')`
1142
+ );
1143
+ if (shortFlagExp.test(unsupportedFlag))
1144
+ throw new Error(`${baseError}
1145
+ - too many short flags`);
1146
+ if (longFlagExp.test(unsupportedFlag))
1147
+ throw new Error(`${baseError}
1148
+ - too many long flags`);
1149
+ throw new Error(`${baseError}
1150
+ - unrecognised flag format`);
1151
+ }
1152
+ if (shortFlag === void 0 && longFlag === void 0)
1153
+ throw new Error(
1154
+ `option creation failed due to no flags found in '${flags}'.`
1155
+ );
839
1156
  return { shortFlag, longFlag };
840
1157
  }
841
- exports.Option = Option2;
842
- exports.splitOptionFlags = splitOptionFlags;
843
- exports.DualOptions = DualOptions;
1158
+ exports2.Option = Option2;
1159
+ exports2.DualOptions = DualOptions;
844
1160
  }
845
1161
  });
846
1162
 
847
- // node_modules/commander/lib/suggestSimilar.js
1163
+ // node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/suggestSimilar.js
848
1164
  var require_suggestSimilar = __commonJS({
849
- "node_modules/commander/lib/suggestSimilar.js"(exports) {
1165
+ "node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/suggestSimilar.js"(exports2) {
850
1166
  var maxDistance = 3;
851
1167
  function editDistance(a, b) {
852
1168
  if (Math.abs(a.length - b.length) > maxDistance)
853
1169
  return Math.max(a.length, b.length);
854
- const d = [];
1170
+ const d2 = [];
855
1171
  for (let i = 0; i <= a.length; i++) {
856
- d[i] = [i];
1172
+ d2[i] = [i];
857
1173
  }
858
- for (let j = 0; j <= b.length; j++) {
859
- d[0][j] = j;
1174
+ for (let j3 = 0; j3 <= b.length; j3++) {
1175
+ d2[0][j3] = j3;
860
1176
  }
861
- for (let j = 1; j <= b.length; j++) {
1177
+ for (let j3 = 1; j3 <= b.length; j3++) {
862
1178
  for (let i = 1; i <= a.length; i++) {
863
1179
  let cost = 1;
864
- if (a[i - 1] === b[j - 1]) {
1180
+ if (a[i - 1] === b[j3 - 1]) {
865
1181
  cost = 0;
866
1182
  } else {
867
1183
  cost = 1;
868
1184
  }
869
- d[i][j] = Math.min(
870
- d[i - 1][j] + 1,
1185
+ d2[i][j3] = Math.min(
1186
+ d2[i - 1][j3] + 1,
871
1187
  // deletion
872
- d[i][j - 1] + 1,
1188
+ d2[i][j3 - 1] + 1,
873
1189
  // insertion
874
- d[i - 1][j - 1] + cost
1190
+ d2[i - 1][j3 - 1] + cost
875
1191
  // substitution
876
1192
  );
877
- if (i > 1 && j > 1 && a[i - 1] === b[j - 2] && a[i - 2] === b[j - 1]) {
878
- d[i][j] = Math.min(d[i][j], d[i - 2][j - 2] + 1);
1193
+ if (i > 1 && j3 > 1 && a[i - 1] === b[j3 - 2] && a[i - 2] === b[j3 - 1]) {
1194
+ d2[i][j3] = Math.min(d2[i][j3], d2[i - 2][j3 - 2] + 1);
879
1195
  }
880
1196
  }
881
1197
  }
882
- return d[a.length][b.length];
1198
+ return d2[a.length][b.length];
883
1199
  }
884
1200
  function suggestSimilar(word, candidates) {
885
- if (!candidates || candidates.length === 0)
886
- return "";
1201
+ if (!candidates || candidates.length === 0) return "";
887
1202
  candidates = Array.from(new Set(candidates));
888
1203
  const searchingOptions = word.startsWith("--");
889
1204
  if (searchingOptions) {
@@ -894,8 +1209,7 @@ var require_suggestSimilar = __commonJS({
894
1209
  let bestDistance = maxDistance;
895
1210
  const minSimilarity = 0.4;
896
1211
  candidates.forEach((candidate) => {
897
- if (candidate.length <= 1)
898
- return;
1212
+ if (candidate.length <= 1) return;
899
1213
  const distance = editDistance(word, candidate);
900
1214
  const length = Math.max(word.length, candidate.length);
901
1215
  const similarity = (length - distance) / length;
@@ -922,24 +1236,24 @@ var require_suggestSimilar = __commonJS({
922
1236
  }
923
1237
  return "";
924
1238
  }
925
- exports.suggestSimilar = suggestSimilar;
1239
+ exports2.suggestSimilar = suggestSimilar;
926
1240
  }
927
1241
  });
928
1242
 
929
- // node_modules/commander/lib/command.js
1243
+ // node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/command.js
930
1244
  var require_command = __commonJS({
931
- "node_modules/commander/lib/command.js"(exports) {
932
- var EventEmitter = require("events").EventEmitter;
933
- var childProcess = require("child_process");
934
- var path = require("path");
935
- var fs = require("fs");
936
- var process2 = require("process");
1245
+ "node_modules/.pnpm/commander@14.0.3/node_modules/commander/lib/command.js"(exports2) {
1246
+ var EventEmitter = require("node:events").EventEmitter;
1247
+ var childProcess = require("node:child_process");
1248
+ var path2 = require("node:path");
1249
+ var fs = require("node:fs");
1250
+ var process2 = require("node:process");
937
1251
  var { Argument: Argument2, humanReadableArgName } = require_argument();
938
1252
  var { CommanderError: CommanderError2 } = require_error();
939
- var { Help: Help2 } = require_help();
940
- var { Option: Option2, splitOptionFlags, DualOptions } = require_option();
1253
+ var { Help: Help2, stripColor } = require_help();
1254
+ var { Option: Option2, DualOptions } = require_option();
941
1255
  var { suggestSimilar } = require_suggestSimilar();
942
- var Command2 = class extends EventEmitter {
1256
+ var Command2 = class _Command extends EventEmitter {
943
1257
  /**
944
1258
  * Initialize a new `Command`.
945
1259
  *
@@ -951,8 +1265,9 @@ var require_command = __commonJS({
951
1265
  this.options = [];
952
1266
  this.parent = null;
953
1267
  this._allowUnknownOption = false;
954
- this._allowExcessArguments = true;
955
- this._args = [];
1268
+ this._allowExcessArguments = false;
1269
+ this.registeredArguments = [];
1270
+ this._args = this.registeredArguments;
956
1271
  this.args = [];
957
1272
  this.rawArgs = [];
958
1273
  this.processedArgs = [];
@@ -977,24 +1292,25 @@ var require_command = __commonJS({
977
1292
  this._lifeCycleHooks = {};
978
1293
  this._showHelpAfterError = false;
979
1294
  this._showSuggestionAfterError = true;
1295
+ this._savedState = null;
980
1296
  this._outputConfiguration = {
981
1297
  writeOut: (str) => process2.stdout.write(str),
982
1298
  writeErr: (str) => process2.stderr.write(str),
1299
+ outputError: (str, write) => write(str),
983
1300
  getOutHelpWidth: () => process2.stdout.isTTY ? process2.stdout.columns : void 0,
984
1301
  getErrHelpWidth: () => process2.stderr.isTTY ? process2.stderr.columns : void 0,
985
- outputError: (str, write) => write(str)
1302
+ getOutHasColors: () => useColor() ?? (process2.stdout.isTTY && process2.stdout.hasColors?.()),
1303
+ getErrHasColors: () => useColor() ?? (process2.stderr.isTTY && process2.stderr.hasColors?.()),
1304
+ stripColor: (str) => stripColor(str)
986
1305
  };
987
1306
  this._hidden = false;
988
- this._hasHelpOption = true;
989
- this._helpFlags = "-h, --help";
990
- this._helpDescription = "display help for command";
991
- this._helpShortFlag = "-h";
992
- this._helpLongFlag = "--help";
1307
+ this._helpOption = void 0;
993
1308
  this._addImplicitHelpCommand = void 0;
994
- this._helpCommandName = "help";
995
- this._helpCommandnameAndArgs = "help [command]";
996
- this._helpCommandDescription = "display help for command";
1309
+ this._helpCommand = void 0;
997
1310
  this._helpConfiguration = {};
1311
+ this._helpGroupHeading = void 0;
1312
+ this._defaultCommandGroup = void 0;
1313
+ this._defaultOptionGroup = void 0;
998
1314
  }
999
1315
  /**
1000
1316
  * Copy settings that are useful to have in common across root command and subcommands.
@@ -1006,14 +1322,8 @@ var require_command = __commonJS({
1006
1322
  */
1007
1323
  copyInheritedSettings(sourceCommand) {
1008
1324
  this._outputConfiguration = sourceCommand._outputConfiguration;
1009
- this._hasHelpOption = sourceCommand._hasHelpOption;
1010
- this._helpFlags = sourceCommand._helpFlags;
1011
- this._helpDescription = sourceCommand._helpDescription;
1012
- this._helpShortFlag = sourceCommand._helpShortFlag;
1013
- this._helpLongFlag = sourceCommand._helpLongFlag;
1014
- this._helpCommandName = sourceCommand._helpCommandName;
1015
- this._helpCommandnameAndArgs = sourceCommand._helpCommandnameAndArgs;
1016
- this._helpCommandDescription = sourceCommand._helpCommandDescription;
1325
+ this._helpOption = sourceCommand._helpOption;
1326
+ this._helpCommand = sourceCommand._helpCommand;
1017
1327
  this._helpConfiguration = sourceCommand._helpConfiguration;
1018
1328
  this._exitCallback = sourceCommand._exitCallback;
1019
1329
  this._storeOptionsAsProperties = sourceCommand._storeOptionsAsProperties;
@@ -1024,6 +1334,17 @@ var require_command = __commonJS({
1024
1334
  this._showSuggestionAfterError = sourceCommand._showSuggestionAfterError;
1025
1335
  return this;
1026
1336
  }
1337
+ /**
1338
+ * @returns {Command[]}
1339
+ * @private
1340
+ */
1341
+ _getCommandAndAncestors() {
1342
+ const result = [];
1343
+ for (let command = this; command; command = command.parent) {
1344
+ result.push(command);
1345
+ }
1346
+ return result;
1347
+ }
1027
1348
  /**
1028
1349
  * Define a command.
1029
1350
  *
@@ -1044,8 +1365,8 @@ var require_command = __commonJS({
1044
1365
  * .command('stop [service]', 'stop named service, or all if no name supplied');
1045
1366
  *
1046
1367
  * @param {string} nameAndArgs - command name and arguments, args are `<required>` or `[optional]` and last may also be `variadic...`
1047
- * @param {Object|string} [actionOptsOrExecDesc] - configuration options (for action), or description (for executable)
1048
- * @param {Object} [execOpts] - configuration options (for executable)
1368
+ * @param {(object | string)} [actionOptsOrExecDesc] - configuration options (for action), or description (for executable)
1369
+ * @param {object} [execOpts] - configuration options (for executable)
1049
1370
  * @return {Command} returns new command for action handler, or `this` for executable command
1050
1371
  */
1051
1372
  command(nameAndArgs, actionOptsOrExecDesc, execOpts) {
@@ -1062,17 +1383,14 @@ var require_command = __commonJS({
1062
1383
  cmd.description(desc);
1063
1384
  cmd._executableHandler = true;
1064
1385
  }
1065
- if (opts.isDefault)
1066
- this._defaultCommandName = cmd._name;
1386
+ if (opts.isDefault) this._defaultCommandName = cmd._name;
1067
1387
  cmd._hidden = !!(opts.noHelp || opts.hidden);
1068
1388
  cmd._executableFile = opts.executableFile || null;
1069
- if (args)
1070
- cmd.arguments(args);
1071
- this.commands.push(cmd);
1389
+ if (args) cmd.arguments(args);
1390
+ this._registerCommand(cmd);
1072
1391
  cmd.parent = this;
1073
1392
  cmd.copyInheritedSettings(this);
1074
- if (desc)
1075
- return this;
1393
+ if (desc) return this;
1076
1394
  return cmd;
1077
1395
  }
1078
1396
  /**
@@ -1085,7 +1403,7 @@ var require_command = __commonJS({
1085
1403
  * @return {Command} new command
1086
1404
  */
1087
1405
  createCommand(name) {
1088
- return new Command2(name);
1406
+ return new _Command(name);
1089
1407
  }
1090
1408
  /**
1091
1409
  * You can customise the help with a subclass of Help by overriding createHelp,
@@ -1100,12 +1418,11 @@ var require_command = __commonJS({
1100
1418
  * You can customise the help by overriding Help properties using configureHelp(),
1101
1419
  * or with a subclass of Help by overriding createHelp().
1102
1420
  *
1103
- * @param {Object} [configuration] - configuration options
1104
- * @return {Command|Object} `this` command for chaining, or stored configuration
1421
+ * @param {object} [configuration] - configuration options
1422
+ * @return {(Command | object)} `this` command for chaining, or stored configuration
1105
1423
  */
1106
1424
  configureHelp(configuration) {
1107
- if (configuration === void 0)
1108
- return this._helpConfiguration;
1425
+ if (configuration === void 0) return this._helpConfiguration;
1109
1426
  this._helpConfiguration = configuration;
1110
1427
  return this;
1111
1428
  }
@@ -1115,33 +1432,38 @@ var require_command = __commonJS({
1115
1432
  *
1116
1433
  * The configuration properties are all functions:
1117
1434
  *
1118
- * // functions to change where being written, stdout and stderr
1435
+ * // change how output being written, defaults to stdout and stderr
1119
1436
  * writeOut(str)
1120
1437
  * writeErr(str)
1121
- * // matching functions to specify width for wrapping help
1438
+ * // change how output being written for errors, defaults to writeErr
1439
+ * outputError(str, write) // used for displaying errors and not used for displaying help
1440
+ * // specify width for wrapping help
1122
1441
  * getOutHelpWidth()
1123
1442
  * getErrHelpWidth()
1124
- * // functions based on what is being written out
1125
- * outputError(str, write) // used for displaying errors, and not used for displaying help
1443
+ * // color support, currently only used with Help
1444
+ * getOutHasColors()
1445
+ * getErrHasColors()
1446
+ * stripColor() // used to remove ANSI escape codes if output does not have colors
1126
1447
  *
1127
- * @param {Object} [configuration] - configuration options
1128
- * @return {Command|Object} `this` command for chaining, or stored configuration
1448
+ * @param {object} [configuration] - configuration options
1449
+ * @return {(Command | object)} `this` command for chaining, or stored configuration
1129
1450
  */
1130
1451
  configureOutput(configuration) {
1131
- if (configuration === void 0)
1132
- return this._outputConfiguration;
1133
- Object.assign(this._outputConfiguration, configuration);
1452
+ if (configuration === void 0) return this._outputConfiguration;
1453
+ this._outputConfiguration = {
1454
+ ...this._outputConfiguration,
1455
+ ...configuration
1456
+ };
1134
1457
  return this;
1135
1458
  }
1136
1459
  /**
1137
1460
  * Display the help or a custom message after an error occurs.
1138
1461
  *
1139
- * @param {boolean|string} [displayHelp]
1462
+ * @param {(boolean|string)} [displayHelp]
1140
1463
  * @return {Command} `this` command for chaining
1141
1464
  */
1142
1465
  showHelpAfterError(displayHelp = true) {
1143
- if (typeof displayHelp !== "string")
1144
- displayHelp = !!displayHelp;
1466
+ if (typeof displayHelp !== "string") displayHelp = !!displayHelp;
1145
1467
  this._showHelpAfterError = displayHelp;
1146
1468
  return this;
1147
1469
  }
@@ -1161,7 +1483,7 @@ var require_command = __commonJS({
1161
1483
  * See .command() for creating an attached subcommand which inherits settings from its parent.
1162
1484
  *
1163
1485
  * @param {Command} cmd - new subcommand
1164
- * @param {Object} [opts] - configuration options
1486
+ * @param {object} [opts] - configuration options
1165
1487
  * @return {Command} `this` command for chaining
1166
1488
  */
1167
1489
  addCommand(cmd, opts) {
@@ -1170,12 +1492,11 @@ var require_command = __commonJS({
1170
1492
  - specify the name in Command constructor or using .name()`);
1171
1493
  }
1172
1494
  opts = opts || {};
1173
- if (opts.isDefault)
1174
- this._defaultCommandName = cmd._name;
1175
- if (opts.noHelp || opts.hidden)
1176
- cmd._hidden = true;
1177
- this.commands.push(cmd);
1495
+ if (opts.isDefault) this._defaultCommandName = cmd._name;
1496
+ if (opts.noHelp || opts.hidden) cmd._hidden = true;
1497
+ this._registerCommand(cmd);
1178
1498
  cmd.parent = this;
1499
+ cmd._checkForBrokenPassThrough();
1179
1500
  return this;
1180
1501
  }
1181
1502
  /**
@@ -1203,16 +1524,16 @@ var require_command = __commonJS({
1203
1524
  *
1204
1525
  * @param {string} name
1205
1526
  * @param {string} [description]
1206
- * @param {Function|*} [fn] - custom argument processing function
1527
+ * @param {(Function|*)} [parseArg] - custom argument processing function or default value
1207
1528
  * @param {*} [defaultValue]
1208
1529
  * @return {Command} `this` command for chaining
1209
1530
  */
1210
- argument(name, description, fn, defaultValue) {
1531
+ argument(name, description, parseArg, defaultValue) {
1211
1532
  const argument = this.createArgument(name, description);
1212
- if (typeof fn === "function") {
1213
- argument.default(defaultValue).argParser(fn);
1533
+ if (typeof parseArg === "function") {
1534
+ argument.default(defaultValue).argParser(parseArg);
1214
1535
  } else {
1215
- argument.default(fn);
1536
+ argument.default(parseArg);
1216
1537
  }
1217
1538
  this.addArgument(argument);
1218
1539
  return this;
@@ -1229,7 +1550,7 @@ var require_command = __commonJS({
1229
1550
  * @return {Command} `this` command for chaining
1230
1551
  */
1231
1552
  arguments(names) {
1232
- names.split(/ +/).forEach((detail) => {
1553
+ names.trim().split(/ +/).forEach((detail) => {
1233
1554
  this.argument(detail);
1234
1555
  });
1235
1556
  return this;
@@ -1241,47 +1562,85 @@ var require_command = __commonJS({
1241
1562
  * @return {Command} `this` command for chaining
1242
1563
  */
1243
1564
  addArgument(argument) {
1244
- const previousArgument = this._args.slice(-1)[0];
1245
- if (previousArgument && previousArgument.variadic) {
1246
- throw new Error(`only the last argument can be variadic '${previousArgument.name()}'`);
1565
+ const previousArgument = this.registeredArguments.slice(-1)[0];
1566
+ if (previousArgument?.variadic) {
1567
+ throw new Error(
1568
+ `only the last argument can be variadic '${previousArgument.name()}'`
1569
+ );
1247
1570
  }
1248
1571
  if (argument.required && argument.defaultValue !== void 0 && argument.parseArg === void 0) {
1249
- throw new Error(`a default value for a required argument is never used: '${argument.name()}'`);
1572
+ throw new Error(
1573
+ `a default value for a required argument is never used: '${argument.name()}'`
1574
+ );
1250
1575
  }
1251
- this._args.push(argument);
1576
+ this.registeredArguments.push(argument);
1252
1577
  return this;
1253
1578
  }
1254
1579
  /**
1255
- * Override default decision whether to add implicit help command.
1580
+ * Customise or override default help command. By default a help command is automatically added if your command has subcommands.
1256
1581
  *
1257
- * addHelpCommand() // force on
1258
- * addHelpCommand(false); // force off
1259
- * addHelpCommand('help [cmd]', 'display help for [cmd]'); // force on with custom details
1582
+ * @example
1583
+ * program.helpCommand('help [cmd]');
1584
+ * program.helpCommand('help [cmd]', 'show help');
1585
+ * program.helpCommand(false); // suppress default help command
1586
+ * program.helpCommand(true); // add help command even if no subcommands
1260
1587
  *
1588
+ * @param {string|boolean} enableOrNameAndArgs - enable with custom name and/or arguments, or boolean to override whether added
1589
+ * @param {string} [description] - custom description
1261
1590
  * @return {Command} `this` command for chaining
1262
1591
  */
1263
- addHelpCommand(enableOrNameAndArgs, description) {
1264
- if (enableOrNameAndArgs === false) {
1265
- this._addImplicitHelpCommand = false;
1266
- } else {
1267
- this._addImplicitHelpCommand = true;
1268
- if (typeof enableOrNameAndArgs === "string") {
1269
- this._helpCommandName = enableOrNameAndArgs.split(" ")[0];
1270
- this._helpCommandnameAndArgs = enableOrNameAndArgs;
1592
+ helpCommand(enableOrNameAndArgs, description) {
1593
+ if (typeof enableOrNameAndArgs === "boolean") {
1594
+ this._addImplicitHelpCommand = enableOrNameAndArgs;
1595
+ if (enableOrNameAndArgs && this._defaultCommandGroup) {
1596
+ this._initCommandGroup(this._getHelpCommand());
1271
1597
  }
1272
- this._helpCommandDescription = description || this._helpCommandDescription;
1598
+ return this;
1273
1599
  }
1600
+ const nameAndArgs = enableOrNameAndArgs ?? "help [command]";
1601
+ const [, helpName, helpArgs] = nameAndArgs.match(/([^ ]+) *(.*)/);
1602
+ const helpDescription = description ?? "display help for command";
1603
+ const helpCommand = this.createCommand(helpName);
1604
+ helpCommand.helpOption(false);
1605
+ if (helpArgs) helpCommand.arguments(helpArgs);
1606
+ if (helpDescription) helpCommand.description(helpDescription);
1607
+ this._addImplicitHelpCommand = true;
1608
+ this._helpCommand = helpCommand;
1609
+ if (enableOrNameAndArgs || description) this._initCommandGroup(helpCommand);
1274
1610
  return this;
1275
1611
  }
1276
1612
  /**
1277
- * @return {boolean}
1278
- * @api private
1613
+ * Add prepared custom help command.
1614
+ *
1615
+ * @param {(Command|string|boolean)} helpCommand - custom help command, or deprecated enableOrNameAndArgs as for `.helpCommand()`
1616
+ * @param {string} [deprecatedDescription] - deprecated custom description used with custom name only
1617
+ * @return {Command} `this` command for chaining
1618
+ */
1619
+ addHelpCommand(helpCommand, deprecatedDescription) {
1620
+ if (typeof helpCommand !== "object") {
1621
+ this.helpCommand(helpCommand, deprecatedDescription);
1622
+ return this;
1623
+ }
1624
+ this._addImplicitHelpCommand = true;
1625
+ this._helpCommand = helpCommand;
1626
+ this._initCommandGroup(helpCommand);
1627
+ return this;
1628
+ }
1629
+ /**
1630
+ * Lazy create help command.
1631
+ *
1632
+ * @return {(Command|null)}
1633
+ * @package
1279
1634
  */
1280
- _hasImplicitHelpCommand() {
1281
- if (this._addImplicitHelpCommand === void 0) {
1282
- return this.commands.length && !this._actionHandler && !this._findCommand("help");
1635
+ _getHelpCommand() {
1636
+ const hasImplicitHelpCommand = this._addImplicitHelpCommand ?? (this.commands.length && !this._actionHandler && !this._findCommand("help"));
1637
+ if (hasImplicitHelpCommand) {
1638
+ if (this._helpCommand === void 0) {
1639
+ this.helpCommand(void 0, void 0);
1640
+ }
1641
+ return this._helpCommand;
1283
1642
  }
1284
- return this._addImplicitHelpCommand;
1643
+ return null;
1285
1644
  }
1286
1645
  /**
1287
1646
  * Add hook for life cycle event.
@@ -1329,7 +1688,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1329
1688
  * @param {string} code an id string representing the error
1330
1689
  * @param {string} message human-readable description of the error
1331
1690
  * @return never
1332
- * @api private
1691
+ * @private
1333
1692
  */
1334
1693
  _exit(exitCode, code, message) {
1335
1694
  if (this._exitCallback) {
@@ -1353,7 +1712,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1353
1712
  */
1354
1713
  action(fn) {
1355
1714
  const listener = (args) => {
1356
- const expectedArgsCount = this._args.length;
1715
+ const expectedArgsCount = this.registeredArguments.length;
1357
1716
  const actionArgs = args.slice(0, expectedArgsCount);
1358
1717
  if (this._storeOptionsAsProperties) {
1359
1718
  actionArgs[expectedArgsCount] = this;
@@ -1379,6 +1738,67 @@ Expecting one of '${allowedValues.join("', '")}'`);
1379
1738
  createOption(flags, description) {
1380
1739
  return new Option2(flags, description);
1381
1740
  }
1741
+ /**
1742
+ * Wrap parseArgs to catch 'commander.invalidArgument'.
1743
+ *
1744
+ * @param {(Option | Argument)} target
1745
+ * @param {string} value
1746
+ * @param {*} previous
1747
+ * @param {string} invalidArgumentMessage
1748
+ * @private
1749
+ */
1750
+ _callParseArg(target, value, previous, invalidArgumentMessage) {
1751
+ try {
1752
+ return target.parseArg(value, previous);
1753
+ } catch (err) {
1754
+ if (err.code === "commander.invalidArgument") {
1755
+ const message = `${invalidArgumentMessage} ${err.message}`;
1756
+ this.error(message, { exitCode: err.exitCode, code: err.code });
1757
+ }
1758
+ throw err;
1759
+ }
1760
+ }
1761
+ /**
1762
+ * Check for option flag conflicts.
1763
+ * Register option if no conflicts found, or throw on conflict.
1764
+ *
1765
+ * @param {Option} option
1766
+ * @private
1767
+ */
1768
+ _registerOption(option) {
1769
+ const matchingOption = option.short && this._findOption(option.short) || option.long && this._findOption(option.long);
1770
+ if (matchingOption) {
1771
+ const matchingFlag = option.long && this._findOption(option.long) ? option.long : option.short;
1772
+ throw new Error(`Cannot add option '${option.flags}'${this._name && ` to command '${this._name}'`} due to conflicting flag '${matchingFlag}'
1773
+ - already used by option '${matchingOption.flags}'`);
1774
+ }
1775
+ this._initOptionGroup(option);
1776
+ this.options.push(option);
1777
+ }
1778
+ /**
1779
+ * Check for command name and alias conflicts with existing commands.
1780
+ * Register command if no conflicts found, or throw on conflict.
1781
+ *
1782
+ * @param {Command} command
1783
+ * @private
1784
+ */
1785
+ _registerCommand(command) {
1786
+ const knownBy = (cmd) => {
1787
+ return [cmd.name()].concat(cmd.aliases());
1788
+ };
1789
+ const alreadyUsed = knownBy(command).find(
1790
+ (name) => this._findCommand(name)
1791
+ );
1792
+ if (alreadyUsed) {
1793
+ const existingCmd = knownBy(this._findCommand(alreadyUsed)).join("|");
1794
+ const newCmd = knownBy(command).join("|");
1795
+ throw new Error(
1796
+ `cannot add command '${newCmd}' as already have command '${existingCmd}'`
1797
+ );
1798
+ }
1799
+ this._initCommandGroup(command);
1800
+ this.commands.push(command);
1801
+ }
1382
1802
  /**
1383
1803
  * Add an option.
1384
1804
  *
@@ -1386,34 +1806,30 @@ Expecting one of '${allowedValues.join("', '")}'`);
1386
1806
  * @return {Command} `this` command for chaining
1387
1807
  */
1388
1808
  addOption(option) {
1809
+ this._registerOption(option);
1389
1810
  const oname = option.name();
1390
1811
  const name = option.attributeName();
1391
1812
  if (option.negate) {
1392
1813
  const positiveLongFlag = option.long.replace(/^--no-/, "--");
1393
1814
  if (!this._findOption(positiveLongFlag)) {
1394
- this.setOptionValueWithSource(name, option.defaultValue === void 0 ? true : option.defaultValue, "default");
1815
+ this.setOptionValueWithSource(
1816
+ name,
1817
+ option.defaultValue === void 0 ? true : option.defaultValue,
1818
+ "default"
1819
+ );
1395
1820
  }
1396
1821
  } else if (option.defaultValue !== void 0) {
1397
1822
  this.setOptionValueWithSource(name, option.defaultValue, "default");
1398
1823
  }
1399
- this.options.push(option);
1400
1824
  const handleOptionValue = (val, invalidValueMessage, valueSource) => {
1401
1825
  if (val == null && option.presetArg !== void 0) {
1402
1826
  val = option.presetArg;
1403
1827
  }
1404
1828
  const oldValue = this.getOptionValue(name);
1405
1829
  if (val !== null && option.parseArg) {
1406
- try {
1407
- val = option.parseArg(val, oldValue);
1408
- } catch (err) {
1409
- if (err.code === "commander.invalidArgument") {
1410
- const message = `${invalidValueMessage} ${err.message}`;
1411
- this.error(message, { exitCode: err.exitCode, code: err.code });
1412
- }
1413
- throw err;
1414
- }
1830
+ val = this._callParseArg(option, val, oldValue, invalidValueMessage);
1415
1831
  } else if (val !== null && option.variadic) {
1416
- val = option._concatValue(val, oldValue);
1832
+ val = option._collectValue(val, oldValue);
1417
1833
  }
1418
1834
  if (val == null) {
1419
1835
  if (option.negate) {
@@ -1441,11 +1857,14 @@ Expecting one of '${allowedValues.join("', '")}'`);
1441
1857
  /**
1442
1858
  * Internal implementation shared by .option() and .requiredOption()
1443
1859
  *
1444
- * @api private
1860
+ * @return {Command} `this` command for chaining
1861
+ * @private
1445
1862
  */
1446
1863
  _optionEx(config, flags, description, fn, defaultValue) {
1447
1864
  if (typeof flags === "object" && flags instanceof Option2) {
1448
- throw new Error("To add an Option object use addOption() instead of option() or requiredOption()");
1865
+ throw new Error(
1866
+ "To add an Option object use addOption() instead of option() or requiredOption()"
1867
+ );
1449
1868
  }
1450
1869
  const option = this.createOption(flags, description);
1451
1870
  option.makeOptionMandatory(!!config.mandatory);
@@ -1464,71 +1883,49 @@ Expecting one of '${allowedValues.join("', '")}'`);
1464
1883
  return this.addOption(option);
1465
1884
  }
1466
1885
  /**
1467
- * Define option with `flags`, `description` and optional
1468
- * coercion `fn`.
1886
+ * Define option with `flags`, `description`, and optional argument parsing function or `defaultValue` or both.
1469
1887
  *
1470
- * The `flags` string contains the short and/or long flags,
1471
- * separated by comma, a pipe or space. The following are all valid
1472
- * all will output this way when `--help` is used.
1888
+ * The `flags` string contains the short and/or long flags, separated by comma, a pipe or space. A required
1889
+ * option-argument is indicated by `<>` and an optional option-argument by `[]`.
1473
1890
  *
1474
- * "-p, --pepper"
1475
- * "-p|--pepper"
1476
- * "-p --pepper"
1891
+ * See the README for more details, and see also addOption() and requiredOption().
1477
1892
  *
1478
1893
  * @example
1479
- * // simple boolean defaulting to undefined
1480
- * program.option('-p, --pepper', 'add pepper');
1481
- *
1482
- * program.pepper
1483
- * // => undefined
1484
- *
1485
- * --pepper
1486
- * program.pepper
1487
- * // => true
1488
- *
1489
- * // simple boolean defaulting to true (unless non-negated option is also defined)
1490
- * program.option('-C, --no-cheese', 'remove cheese');
1491
- *
1492
- * program.cheese
1493
- * // => true
1494
- *
1495
- * --no-cheese
1496
- * program.cheese
1497
- * // => false
1498
- *
1499
- * // required argument
1500
- * program.option('-C, --chdir <path>', 'change the working directory');
1501
- *
1502
- * --chdir /tmp
1503
- * program.chdir
1504
- * // => "/tmp"
1505
- *
1506
- * // optional argument
1507
- * program.option('-c, --cheese [type]', 'add cheese [marble]');
1894
+ * program
1895
+ * .option('-p, --pepper', 'add pepper')
1896
+ * .option('--pt, --pizza-type <TYPE>', 'type of pizza') // required option-argument
1897
+ * .option('-c, --cheese [CHEESE]', 'add extra cheese', 'mozzarella') // optional option-argument with default
1898
+ * .option('-t, --tip <VALUE>', 'add tip to purchase cost', parseFloat) // custom parse function
1508
1899
  *
1509
1900
  * @param {string} flags
1510
1901
  * @param {string} [description]
1511
- * @param {Function|*} [fn] - custom option processing function or default value
1902
+ * @param {(Function|*)} [parseArg] - custom option processing function or default value
1512
1903
  * @param {*} [defaultValue]
1513
1904
  * @return {Command} `this` command for chaining
1514
1905
  */
1515
- option(flags, description, fn, defaultValue) {
1516
- return this._optionEx({}, flags, description, fn, defaultValue);
1906
+ option(flags, description, parseArg, defaultValue) {
1907
+ return this._optionEx({}, flags, description, parseArg, defaultValue);
1517
1908
  }
1518
1909
  /**
1519
- * Add a required option which must have a value after parsing. This usually means
1520
- * the option must be specified on the command line. (Otherwise the same as .option().)
1521
- *
1522
- * The `flags` string contains the short and/or long flags, separated by comma, a pipe or space.
1523
- *
1524
- * @param {string} flags
1525
- * @param {string} [description]
1526
- * @param {Function|*} [fn] - custom option processing function or default value
1527
- * @param {*} [defaultValue]
1528
- * @return {Command} `this` command for chaining
1529
- */
1530
- requiredOption(flags, description, fn, defaultValue) {
1531
- return this._optionEx({ mandatory: true }, flags, description, fn, defaultValue);
1910
+ * Add a required option which must have a value after parsing. This usually means
1911
+ * the option must be specified on the command line. (Otherwise the same as .option().)
1912
+ *
1913
+ * The `flags` string contains the short and/or long flags, separated by comma, a pipe or space.
1914
+ *
1915
+ * @param {string} flags
1916
+ * @param {string} [description]
1917
+ * @param {(Function|*)} [parseArg] - custom option processing function or default value
1918
+ * @param {*} [defaultValue]
1919
+ * @return {Command} `this` command for chaining
1920
+ */
1921
+ requiredOption(flags, description, parseArg, defaultValue) {
1922
+ return this._optionEx(
1923
+ { mandatory: true },
1924
+ flags,
1925
+ description,
1926
+ parseArg,
1927
+ defaultValue
1928
+ );
1532
1929
  }
1533
1930
  /**
1534
1931
  * Alter parsing of short flags with optional values.
@@ -1538,7 +1935,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
1538
1935
  * program.combineFlagAndOptionalValue(true); // `-f80` is treated like `--flag=80`, this is the default behaviour
1539
1936
  * program.combineFlagAndOptionalValue(false) // `-fb` is treated like `-f -b`
1540
1937
  *
1541
- * @param {Boolean} [combine=true] - if `true` or omitted, an optional value can be specified directly after the flag.
1938
+ * @param {boolean} [combine] - if `true` or omitted, an optional value can be specified directly after the flag.
1939
+ * @return {Command} `this` command for chaining
1542
1940
  */
1543
1941
  combineFlagAndOptionalValue(combine = true) {
1544
1942
  this._combineFlagAndOptionalValue = !!combine;
@@ -1547,8 +1945,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
1547
1945
  /**
1548
1946
  * Allow unknown options on the command line.
1549
1947
  *
1550
- * @param {Boolean} [allowUnknown=true] - if `true` or omitted, no error will be thrown
1551
- * for unknown options.
1948
+ * @param {boolean} [allowUnknown] - if `true` or omitted, no error will be thrown for unknown options.
1949
+ * @return {Command} `this` command for chaining
1552
1950
  */
1553
1951
  allowUnknownOption(allowUnknown = true) {
1554
1952
  this._allowUnknownOption = !!allowUnknown;
@@ -1557,8 +1955,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
1557
1955
  /**
1558
1956
  * Allow excess command-arguments on the command line. Pass false to make excess arguments an error.
1559
1957
  *
1560
- * @param {Boolean} [allowExcess=true] - if `true` or omitted, no error will be thrown
1561
- * for excess arguments.
1958
+ * @param {boolean} [allowExcess] - if `true` or omitted, no error will be thrown for excess arguments.
1959
+ * @return {Command} `this` command for chaining
1562
1960
  */
1563
1961
  allowExcessArguments(allowExcess = true) {
1564
1962
  this._allowExcessArguments = !!allowExcess;
@@ -1569,7 +1967,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
1569
1967
  * subcommands reuse the same option names, and also enables subcommands to turn on passThroughOptions.
1570
1968
  * The default behaviour is non-positional and global options may appear anywhere on the command line.
1571
1969
  *
1572
- * @param {Boolean} [positional=true]
1970
+ * @param {boolean} [positional]
1971
+ * @return {Command} `this` command for chaining
1573
1972
  */
1574
1973
  enablePositionalOptions(positional = true) {
1575
1974
  this._enablePositionalOptions = !!positional;
@@ -1581,35 +1980,48 @@ Expecting one of '${allowedValues.join("', '")}'`);
1581
1980
  * positional options to have been enabled on the program (parent commands).
1582
1981
  * The default behaviour is non-positional and options may appear before or after command-arguments.
1583
1982
  *
1584
- * @param {Boolean} [passThrough=true]
1585
- * for unknown options.
1983
+ * @param {boolean} [passThrough] for unknown options.
1984
+ * @return {Command} `this` command for chaining
1586
1985
  */
1587
1986
  passThroughOptions(passThrough = true) {
1588
1987
  this._passThroughOptions = !!passThrough;
1589
- if (!!this.parent && passThrough && !this.parent._enablePositionalOptions) {
1590
- throw new Error("passThroughOptions can not be used without turning on enablePositionalOptions for parent command(s)");
1591
- }
1988
+ this._checkForBrokenPassThrough();
1592
1989
  return this;
1593
1990
  }
1594
1991
  /**
1595
- * Whether to store option values as properties on command object,
1596
- * or store separately (specify false). In both cases the option values can be accessed using .opts().
1597
- *
1598
- * @param {boolean} [storeAsProperties=true]
1599
- * @return {Command} `this` command for chaining
1600
- */
1992
+ * @private
1993
+ */
1994
+ _checkForBrokenPassThrough() {
1995
+ if (this.parent && this._passThroughOptions && !this.parent._enablePositionalOptions) {
1996
+ throw new Error(
1997
+ `passThroughOptions cannot be used for '${this._name}' without turning on enablePositionalOptions for parent command(s)`
1998
+ );
1999
+ }
2000
+ }
2001
+ /**
2002
+ * Whether to store option values as properties on command object,
2003
+ * or store separately (specify false). In both cases the option values can be accessed using .opts().
2004
+ *
2005
+ * @param {boolean} [storeAsProperties=true]
2006
+ * @return {Command} `this` command for chaining
2007
+ */
1601
2008
  storeOptionsAsProperties(storeAsProperties = true) {
1602
- this._storeOptionsAsProperties = !!storeAsProperties;
1603
2009
  if (this.options.length) {
1604
2010
  throw new Error("call .storeOptionsAsProperties() before adding options");
1605
2011
  }
2012
+ if (Object.keys(this._optionValues).length) {
2013
+ throw new Error(
2014
+ "call .storeOptionsAsProperties() before setting option values"
2015
+ );
2016
+ }
2017
+ this._storeOptionsAsProperties = !!storeAsProperties;
1606
2018
  return this;
1607
2019
  }
1608
2020
  /**
1609
2021
  * Retrieve option value.
1610
2022
  *
1611
2023
  * @param {string} key
1612
- * @return {Object} value
2024
+ * @return {object} value
1613
2025
  */
1614
2026
  getOptionValue(key) {
1615
2027
  if (this._storeOptionsAsProperties) {
@@ -1621,20 +2033,20 @@ Expecting one of '${allowedValues.join("', '")}'`);
1621
2033
  * Store option value.
1622
2034
  *
1623
2035
  * @param {string} key
1624
- * @param {Object} value
2036
+ * @param {object} value
1625
2037
  * @return {Command} `this` command for chaining
1626
2038
  */
1627
2039
  setOptionValue(key, value) {
1628
2040
  return this.setOptionValueWithSource(key, value, void 0);
1629
2041
  }
1630
2042
  /**
1631
- * Store option value and where the value came from.
1632
- *
1633
- * @param {string} key
1634
- * @param {Object} value
1635
- * @param {string} source - expected values are default/config/env/cli/implied
1636
- * @return {Command} `this` command for chaining
1637
- */
2043
+ * Store option value and where the value came from.
2044
+ *
2045
+ * @param {string} key
2046
+ * @param {object} value
2047
+ * @param {string} source - expected values are default/config/env/cli/implied
2048
+ * @return {Command} `this` command for chaining
2049
+ */
1638
2050
  setOptionValueWithSource(key, value, source) {
1639
2051
  if (this._storeOptionsAsProperties) {
1640
2052
  this[key] = value;
@@ -1645,25 +2057,25 @@ Expecting one of '${allowedValues.join("', '")}'`);
1645
2057
  return this;
1646
2058
  }
1647
2059
  /**
1648
- * Get source of option value.
1649
- * Expected values are default | config | env | cli | implied
1650
- *
1651
- * @param {string} key
1652
- * @return {string}
1653
- */
2060
+ * Get source of option value.
2061
+ * Expected values are default | config | env | cli | implied
2062
+ *
2063
+ * @param {string} key
2064
+ * @return {string}
2065
+ */
1654
2066
  getOptionValueSource(key) {
1655
2067
  return this._optionValueSources[key];
1656
2068
  }
1657
2069
  /**
1658
- * Get source of option value. See also .optsWithGlobals().
1659
- * Expected values are default | config | env | cli | implied
1660
- *
1661
- * @param {string} key
1662
- * @return {string}
1663
- */
2070
+ * Get source of option value. See also .optsWithGlobals().
2071
+ * Expected values are default | config | env | cli | implied
2072
+ *
2073
+ * @param {string} key
2074
+ * @return {string}
2075
+ */
1664
2076
  getOptionValueSourceWithGlobals(key) {
1665
2077
  let source;
1666
- getCommandAndParents(this).forEach((cmd) => {
2078
+ this._getCommandAndAncestors().forEach((cmd) => {
1667
2079
  if (cmd.getOptionValueSource(key) !== void 0) {
1668
2080
  source = cmd.getOptionValueSource(key);
1669
2081
  }
@@ -1674,18 +2086,24 @@ Expecting one of '${allowedValues.join("', '")}'`);
1674
2086
  * Get user arguments from implied or explicit arguments.
1675
2087
  * Side-effects: set _scriptPath if args included script. Used for default program name, and subcommand searches.
1676
2088
  *
1677
- * @api private
2089
+ * @private
1678
2090
  */
1679
2091
  _prepareUserArgs(argv, parseOptions) {
1680
2092
  if (argv !== void 0 && !Array.isArray(argv)) {
1681
2093
  throw new Error("first parameter to parse must be array or undefined");
1682
2094
  }
1683
2095
  parseOptions = parseOptions || {};
1684
- if (argv === void 0) {
1685
- argv = process2.argv;
1686
- if (process2.versions && process2.versions.electron) {
2096
+ if (argv === void 0 && parseOptions.from === void 0) {
2097
+ if (process2.versions?.electron) {
1687
2098
  parseOptions.from = "electron";
1688
2099
  }
2100
+ const execArgv = process2.execArgv ?? [];
2101
+ if (execArgv.includes("-e") || execArgv.includes("--eval") || execArgv.includes("-p") || execArgv.includes("--print")) {
2102
+ parseOptions.from = "eval";
2103
+ }
2104
+ }
2105
+ if (argv === void 0) {
2106
+ argv = process2.argv;
1689
2107
  }
1690
2108
  this.rawArgs = argv.slice();
1691
2109
  let userArgs;
@@ -1706,8 +2124,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
1706
2124
  case "user":
1707
2125
  userArgs = argv.slice(0);
1708
2126
  break;
2127
+ case "eval":
2128
+ userArgs = argv.slice(1);
2129
+ break;
1709
2130
  default:
1710
- throw new Error(`unexpected parse option { from: '${parseOptions.from}' }`);
2131
+ throw new Error(
2132
+ `unexpected parse option { from: '${parseOptions.from}' }`
2133
+ );
1711
2134
  }
1712
2135
  if (!this._name && this._scriptPath)
1713
2136
  this.nameFromFilename(this._scriptPath);
@@ -1717,20 +2140,27 @@ Expecting one of '${allowedValues.join("', '")}'`);
1717
2140
  /**
1718
2141
  * Parse `argv`, setting options and invoking commands when defined.
1719
2142
  *
1720
- * The default expectation is that the arguments are from node and have the application as argv[0]
1721
- * and the script being run in argv[1], with user parameters after that.
2143
+ * Use parseAsync instead of parse if any of your action handlers are async.
2144
+ *
2145
+ * Call with no parameters to parse `process.argv`. Detects Electron and special node options like `node --eval`. Easy mode!
2146
+ *
2147
+ * Or call with an array of strings to parse, and optionally where the user arguments start by specifying where the arguments are `from`:
2148
+ * - `'node'`: default, `argv[0]` is the application and `argv[1]` is the script being run, with user arguments after that
2149
+ * - `'electron'`: `argv[0]` is the application and `argv[1]` varies depending on whether the electron application is packaged
2150
+ * - `'user'`: just user arguments
1722
2151
  *
1723
2152
  * @example
1724
- * program.parse(process.argv);
1725
- * program.parse(); // implicitly use process.argv and auto-detect node vs electron conventions
2153
+ * program.parse(); // parse process.argv and auto-detect electron and special node flags
2154
+ * program.parse(process.argv); // assume argv[0] is app and argv[1] is script
1726
2155
  * program.parse(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
1727
2156
  *
1728
2157
  * @param {string[]} [argv] - optional, defaults to process.argv
1729
- * @param {Object} [parseOptions] - optionally specify style of options with from: node/user/electron
2158
+ * @param {object} [parseOptions] - optionally specify style of options with from: node/user/electron
1730
2159
  * @param {string} [parseOptions.from] - where the args are from: 'node', 'user', 'electron'
1731
2160
  * @return {Command} `this` command for chaining
1732
2161
  */
1733
2162
  parse(argv, parseOptions) {
2163
+ this._prepareForParse();
1734
2164
  const userArgs = this._prepareUserArgs(argv, parseOptions);
1735
2165
  this._parseCommand([], userArgs);
1736
2166
  return this;
@@ -1738,44 +2168,103 @@ Expecting one of '${allowedValues.join("', '")}'`);
1738
2168
  /**
1739
2169
  * Parse `argv`, setting options and invoking commands when defined.
1740
2170
  *
1741
- * Use parseAsync instead of parse if any of your action handlers are async. Returns a Promise.
2171
+ * Call with no parameters to parse `process.argv`. Detects Electron and special node options like `node --eval`. Easy mode!
1742
2172
  *
1743
- * The default expectation is that the arguments are from node and have the application as argv[0]
1744
- * and the script being run in argv[1], with user parameters after that.
2173
+ * Or call with an array of strings to parse, and optionally where the user arguments start by specifying where the arguments are `from`:
2174
+ * - `'node'`: default, `argv[0]` is the application and `argv[1]` is the script being run, with user arguments after that
2175
+ * - `'electron'`: `argv[0]` is the application and `argv[1]` varies depending on whether the electron application is packaged
2176
+ * - `'user'`: just user arguments
1745
2177
  *
1746
2178
  * @example
1747
- * await program.parseAsync(process.argv);
1748
- * await program.parseAsync(); // implicitly use process.argv and auto-detect node vs electron conventions
2179
+ * await program.parseAsync(); // parse process.argv and auto-detect electron and special node flags
2180
+ * await program.parseAsync(process.argv); // assume argv[0] is app and argv[1] is script
1749
2181
  * await program.parseAsync(my-args, { from: 'user' }); // just user supplied arguments, nothing special about argv[0]
1750
2182
  *
1751
2183
  * @param {string[]} [argv]
1752
- * @param {Object} [parseOptions]
2184
+ * @param {object} [parseOptions]
1753
2185
  * @param {string} parseOptions.from - where the args are from: 'node', 'user', 'electron'
1754
2186
  * @return {Promise}
1755
2187
  */
1756
2188
  async parseAsync(argv, parseOptions) {
2189
+ this._prepareForParse();
1757
2190
  const userArgs = this._prepareUserArgs(argv, parseOptions);
1758
2191
  await this._parseCommand([], userArgs);
1759
2192
  return this;
1760
2193
  }
2194
+ _prepareForParse() {
2195
+ if (this._savedState === null) {
2196
+ this.saveStateBeforeParse();
2197
+ } else {
2198
+ this.restoreStateBeforeParse();
2199
+ }
2200
+ }
2201
+ /**
2202
+ * Called the first time parse is called to save state and allow a restore before subsequent calls to parse.
2203
+ * Not usually called directly, but available for subclasses to save their custom state.
2204
+ *
2205
+ * This is called in a lazy way. Only commands used in parsing chain will have state saved.
2206
+ */
2207
+ saveStateBeforeParse() {
2208
+ this._savedState = {
2209
+ // name is stable if supplied by author, but may be unspecified for root command and deduced during parsing
2210
+ _name: this._name,
2211
+ // option values before parse have default values (including false for negated options)
2212
+ // shallow clones
2213
+ _optionValues: { ...this._optionValues },
2214
+ _optionValueSources: { ...this._optionValueSources }
2215
+ };
2216
+ }
2217
+ /**
2218
+ * Restore state before parse for calls after the first.
2219
+ * Not usually called directly, but available for subclasses to save their custom state.
2220
+ *
2221
+ * This is called in a lazy way. Only commands used in parsing chain will have state restored.
2222
+ */
2223
+ restoreStateBeforeParse() {
2224
+ if (this._storeOptionsAsProperties)
2225
+ throw new Error(`Can not call parse again when storeOptionsAsProperties is true.
2226
+ - either make a new Command for each call to parse, or stop storing options as properties`);
2227
+ this._name = this._savedState._name;
2228
+ this._scriptPath = null;
2229
+ this.rawArgs = [];
2230
+ this._optionValues = { ...this._savedState._optionValues };
2231
+ this._optionValueSources = { ...this._savedState._optionValueSources };
2232
+ this.args = [];
2233
+ this.processedArgs = [];
2234
+ }
2235
+ /**
2236
+ * Throw if expected executable is missing. Add lots of help for author.
2237
+ *
2238
+ * @param {string} executableFile
2239
+ * @param {string} executableDir
2240
+ * @param {string} subcommandName
2241
+ */
2242
+ _checkForMissingExecutable(executableFile, executableDir, subcommandName) {
2243
+ if (fs.existsSync(executableFile)) return;
2244
+ const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
2245
+ const executableMissing = `'${executableFile}' does not exist
2246
+ - if '${subcommandName}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
2247
+ - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
2248
+ - ${executableDirMessage}`;
2249
+ throw new Error(executableMissing);
2250
+ }
1761
2251
  /**
1762
2252
  * Execute a sub-command executable.
1763
2253
  *
1764
- * @api private
2254
+ * @private
1765
2255
  */
1766
2256
  _executeSubCommand(subcommand, args) {
1767
2257
  args = args.slice();
1768
2258
  let launchWithNode = false;
1769
2259
  const sourceExt = [".js", ".ts", ".tsx", ".mjs", ".cjs"];
1770
2260
  function findFile(baseDir, baseName) {
1771
- const localBin = path.resolve(baseDir, baseName);
1772
- if (fs.existsSync(localBin))
1773
- return localBin;
1774
- if (sourceExt.includes(path.extname(baseName)))
1775
- return void 0;
1776
- const foundExt = sourceExt.find((ext) => fs.existsSync(`${localBin}${ext}`));
1777
- if (foundExt)
1778
- return `${localBin}${foundExt}`;
2261
+ const localBin = path2.resolve(baseDir, baseName);
2262
+ if (fs.existsSync(localBin)) return localBin;
2263
+ if (sourceExt.includes(path2.extname(baseName))) return void 0;
2264
+ const foundExt = sourceExt.find(
2265
+ (ext) => fs.existsSync(`${localBin}${ext}`)
2266
+ );
2267
+ if (foundExt) return `${localBin}${foundExt}`;
1779
2268
  return void 0;
1780
2269
  }
1781
2270
  this._checkForMissingMandatoryOptions();
@@ -1786,22 +2275,31 @@ Expecting one of '${allowedValues.join("', '")}'`);
1786
2275
  let resolvedScriptPath;
1787
2276
  try {
1788
2277
  resolvedScriptPath = fs.realpathSync(this._scriptPath);
1789
- } catch (err) {
2278
+ } catch {
1790
2279
  resolvedScriptPath = this._scriptPath;
1791
2280
  }
1792
- executableDir = path.resolve(path.dirname(resolvedScriptPath), executableDir);
2281
+ executableDir = path2.resolve(
2282
+ path2.dirname(resolvedScriptPath),
2283
+ executableDir
2284
+ );
1793
2285
  }
1794
2286
  if (executableDir) {
1795
2287
  let localFile = findFile(executableDir, executableFile);
1796
2288
  if (!localFile && !subcommand._executableFile && this._scriptPath) {
1797
- const legacyName = path.basename(this._scriptPath, path.extname(this._scriptPath));
2289
+ const legacyName = path2.basename(
2290
+ this._scriptPath,
2291
+ path2.extname(this._scriptPath)
2292
+ );
1798
2293
  if (legacyName !== this._name) {
1799
- localFile = findFile(executableDir, `${legacyName}-${subcommand._name}`);
2294
+ localFile = findFile(
2295
+ executableDir,
2296
+ `${legacyName}-${subcommand._name}`
2297
+ );
1800
2298
  }
1801
2299
  }
1802
2300
  executableFile = localFile || executableFile;
1803
2301
  }
1804
- launchWithNode = sourceExt.includes(path.extname(executableFile));
2302
+ launchWithNode = sourceExt.includes(path2.extname(executableFile));
1805
2303
  let proc;
1806
2304
  if (process2.platform !== "win32") {
1807
2305
  if (launchWithNode) {
@@ -1812,6 +2310,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
1812
2310
  proc = childProcess.spawn(executableFile, args, { stdio: "inherit" });
1813
2311
  }
1814
2312
  } else {
2313
+ this._checkForMissingExecutable(
2314
+ executableFile,
2315
+ executableDir,
2316
+ subcommand._name
2317
+ );
1815
2318
  args.unshift(executableFile);
1816
2319
  args = incrementNodeInspectorPort(process2.execArgv).concat(args);
1817
2320
  proc = childProcess.spawn(process2.execPath, args, { stdio: "inherit" });
@@ -1827,28 +2330,38 @@ Expecting one of '${allowedValues.join("', '")}'`);
1827
2330
  });
1828
2331
  }
1829
2332
  const exitCallback = this._exitCallback;
1830
- if (!exitCallback) {
1831
- proc.on("close", process2.exit.bind(process2));
1832
- } else {
1833
- proc.on("close", () => {
1834
- exitCallback(new CommanderError2(process2.exitCode || 0, "commander.executeSubCommandAsync", "(close)"));
1835
- });
1836
- }
2333
+ proc.on("close", (code) => {
2334
+ code = code ?? 1;
2335
+ if (!exitCallback) {
2336
+ process2.exit(code);
2337
+ } else {
2338
+ exitCallback(
2339
+ new CommanderError2(
2340
+ code,
2341
+ "commander.executeSubCommandAsync",
2342
+ "(close)"
2343
+ )
2344
+ );
2345
+ }
2346
+ });
1837
2347
  proc.on("error", (err) => {
1838
2348
  if (err.code === "ENOENT") {
1839
- const executableDirMessage = executableDir ? `searched for local subcommand relative to directory '${executableDir}'` : "no directory for search for local subcommand, use .executableDir() to supply a custom directory";
1840
- const executableMissing = `'${executableFile}' does not exist
1841
- - if '${subcommand._name}' is not meant to be an executable command, remove description parameter from '.command()' and use '.description()' instead
1842
- - if the default executable name is not suitable, use the executableFile option to supply a custom name or path
1843
- - ${executableDirMessage}`;
1844
- throw new Error(executableMissing);
2349
+ this._checkForMissingExecutable(
2350
+ executableFile,
2351
+ executableDir,
2352
+ subcommand._name
2353
+ );
1845
2354
  } else if (err.code === "EACCES") {
1846
2355
  throw new Error(`'${executableFile}' not executable`);
1847
2356
  }
1848
2357
  if (!exitCallback) {
1849
2358
  process2.exit(1);
1850
2359
  } else {
1851
- const wrappedError = new CommanderError2(1, "commander.executeSubCommandAsync", "(error)");
2360
+ const wrappedError = new CommanderError2(
2361
+ 1,
2362
+ "commander.executeSubCommandAsync",
2363
+ "(error)"
2364
+ );
1852
2365
  wrappedError.nestedError = err;
1853
2366
  exitCallback(wrappedError);
1854
2367
  }
@@ -1856,65 +2369,87 @@ Expecting one of '${allowedValues.join("', '")}'`);
1856
2369
  this.runningCommand = proc;
1857
2370
  }
1858
2371
  /**
1859
- * @api private
2372
+ * @private
1860
2373
  */
1861
2374
  _dispatchSubcommand(commandName, operands, unknown) {
1862
2375
  const subCommand = this._findCommand(commandName);
1863
- if (!subCommand)
1864
- this.help({ error: true });
1865
- let hookResult;
1866
- hookResult = this._chainOrCallSubCommandHook(hookResult, subCommand, "preSubcommand");
1867
- hookResult = this._chainOrCall(hookResult, () => {
2376
+ if (!subCommand) this.help({ error: true });
2377
+ subCommand._prepareForParse();
2378
+ let promiseChain;
2379
+ promiseChain = this._chainOrCallSubCommandHook(
2380
+ promiseChain,
2381
+ subCommand,
2382
+ "preSubcommand"
2383
+ );
2384
+ promiseChain = this._chainOrCall(promiseChain, () => {
1868
2385
  if (subCommand._executableHandler) {
1869
2386
  this._executeSubCommand(subCommand, operands.concat(unknown));
1870
2387
  } else {
1871
2388
  return subCommand._parseCommand(operands, unknown);
1872
2389
  }
1873
2390
  });
1874
- return hookResult;
2391
+ return promiseChain;
2392
+ }
2393
+ /**
2394
+ * Invoke help directly if possible, or dispatch if necessary.
2395
+ * e.g. help foo
2396
+ *
2397
+ * @private
2398
+ */
2399
+ _dispatchHelpCommand(subcommandName) {
2400
+ if (!subcommandName) {
2401
+ this.help();
2402
+ }
2403
+ const subCommand = this._findCommand(subcommandName);
2404
+ if (subCommand && !subCommand._executableHandler) {
2405
+ subCommand.help();
2406
+ }
2407
+ return this._dispatchSubcommand(
2408
+ subcommandName,
2409
+ [],
2410
+ [this._getHelpOption()?.long ?? this._getHelpOption()?.short ?? "--help"]
2411
+ );
1875
2412
  }
1876
2413
  /**
1877
- * Check this.args against expected this._args.
2414
+ * Check this.args against expected this.registeredArguments.
1878
2415
  *
1879
- * @api private
2416
+ * @private
1880
2417
  */
1881
2418
  _checkNumberOfArguments() {
1882
- this._args.forEach((arg, i) => {
2419
+ this.registeredArguments.forEach((arg, i) => {
1883
2420
  if (arg.required && this.args[i] == null) {
1884
2421
  this.missingArgument(arg.name());
1885
2422
  }
1886
2423
  });
1887
- if (this._args.length > 0 && this._args[this._args.length - 1].variadic) {
2424
+ if (this.registeredArguments.length > 0 && this.registeredArguments[this.registeredArguments.length - 1].variadic) {
1888
2425
  return;
1889
2426
  }
1890
- if (this.args.length > this._args.length) {
2427
+ if (this.args.length > this.registeredArguments.length) {
1891
2428
  this._excessArguments(this.args);
1892
2429
  }
1893
2430
  }
1894
2431
  /**
1895
- * Process this.args using this._args and save as this.processedArgs!
2432
+ * Process this.args using this.registeredArguments and save as this.processedArgs!
1896
2433
  *
1897
- * @api private
2434
+ * @private
1898
2435
  */
1899
2436
  _processArguments() {
1900
2437
  const myParseArg = (argument, value, previous) => {
1901
2438
  let parsedValue = value;
1902
2439
  if (value !== null && argument.parseArg) {
1903
- try {
1904
- parsedValue = argument.parseArg(value, previous);
1905
- } catch (err) {
1906
- if (err.code === "commander.invalidArgument") {
1907
- const message = `error: command-argument value '${value}' is invalid for argument '${argument.name()}'. ${err.message}`;
1908
- this.error(message, { exitCode: err.exitCode, code: err.code });
1909
- }
1910
- throw err;
1911
- }
2440
+ const invalidValueMessage = `error: command-argument value '${value}' is invalid for argument '${argument.name()}'.`;
2441
+ parsedValue = this._callParseArg(
2442
+ argument,
2443
+ value,
2444
+ previous,
2445
+ invalidValueMessage
2446
+ );
1912
2447
  }
1913
2448
  return parsedValue;
1914
2449
  };
1915
2450
  this._checkNumberOfArguments();
1916
2451
  const processedArgs = [];
1917
- this._args.forEach((declaredArg, index) => {
2452
+ this.registeredArguments.forEach((declaredArg, index) => {
1918
2453
  let value = declaredArg.defaultValue;
1919
2454
  if (declaredArg.variadic) {
1920
2455
  if (index < this.args.length) {
@@ -1940,28 +2475,28 @@ Expecting one of '${allowedValues.join("', '")}'`);
1940
2475
  /**
1941
2476
  * Once we have a promise we chain, but call synchronously until then.
1942
2477
  *
1943
- * @param {Promise|undefined} promise
2478
+ * @param {(Promise|undefined)} promise
1944
2479
  * @param {Function} fn
1945
- * @return {Promise|undefined}
1946
- * @api private
2480
+ * @return {(Promise|undefined)}
2481
+ * @private
1947
2482
  */
1948
2483
  _chainOrCall(promise, fn) {
1949
- if (promise && promise.then && typeof promise.then === "function") {
2484
+ if (promise?.then && typeof promise.then === "function") {
1950
2485
  return promise.then(() => fn());
1951
2486
  }
1952
2487
  return fn();
1953
2488
  }
1954
2489
  /**
1955
2490
  *
1956
- * @param {Promise|undefined} promise
2491
+ * @param {(Promise|undefined)} promise
1957
2492
  * @param {string} event
1958
- * @return {Promise|undefined}
1959
- * @api private
2493
+ * @return {(Promise|undefined)}
2494
+ * @private
1960
2495
  */
1961
2496
  _chainOrCallHooks(promise, event) {
1962
2497
  let result = promise;
1963
2498
  const hooks = [];
1964
- getCommandAndParents(this).reverse().filter((cmd) => cmd._lifeCycleHooks[event] !== void 0).forEach((hookedCommand) => {
2499
+ this._getCommandAndAncestors().reverse().filter((cmd) => cmd._lifeCycleHooks[event] !== void 0).forEach((hookedCommand) => {
1965
2500
  hookedCommand._lifeCycleHooks[event].forEach((callback) => {
1966
2501
  hooks.push({ hookedCommand, callback });
1967
2502
  });
@@ -1978,11 +2513,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
1978
2513
  }
1979
2514
  /**
1980
2515
  *
1981
- * @param {Promise|undefined} promise
2516
+ * @param {(Promise|undefined)} promise
1982
2517
  * @param {Command} subCommand
1983
2518
  * @param {string} event
1984
- * @return {Promise|undefined}
1985
- * @api private
2519
+ * @return {(Promise|undefined)}
2520
+ * @private
1986
2521
  */
1987
2522
  _chainOrCallSubCommandHook(promise, subCommand, event) {
1988
2523
  let result = promise;
@@ -1999,7 +2534,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
1999
2534
  * Process arguments in context of this command.
2000
2535
  * Returns action result, in case it is a promise.
2001
2536
  *
2002
- * @api private
2537
+ * @private
2003
2538
  */
2004
2539
  _parseCommand(operands, unknown) {
2005
2540
  const parsed = this.parseOptions(unknown);
@@ -2011,20 +2546,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
2011
2546
  if (operands && this._findCommand(operands[0])) {
2012
2547
  return this._dispatchSubcommand(operands[0], operands.slice(1), unknown);
2013
2548
  }
2014
- if (this._hasImplicitHelpCommand() && operands[0] === this._helpCommandName) {
2015
- if (operands.length === 1) {
2016
- this.help();
2017
- }
2018
- return this._dispatchSubcommand(operands[1], [], [this._helpLongFlag]);
2549
+ if (this._getHelpCommand() && operands[0] === this._getHelpCommand().name()) {
2550
+ return this._dispatchHelpCommand(operands[1]);
2019
2551
  }
2020
2552
  if (this._defaultCommandName) {
2021
- outputHelpIfRequested(this, unknown);
2022
- return this._dispatchSubcommand(this._defaultCommandName, operands, unknown);
2553
+ this._outputHelpIfRequested(unknown);
2554
+ return this._dispatchSubcommand(
2555
+ this._defaultCommandName,
2556
+ operands,
2557
+ unknown
2558
+ );
2023
2559
  }
2024
2560
  if (this.commands.length && this.args.length === 0 && !this._actionHandler && !this._defaultCommandName) {
2025
2561
  this.help({ error: true });
2026
2562
  }
2027
- outputHelpIfRequested(this, parsed.unknown);
2563
+ this._outputHelpIfRequested(parsed.unknown);
2028
2564
  this._checkForMissingMandatoryOptions();
2029
2565
  this._checkForConflictingOptions();
2030
2566
  const checkForUnknownOptions = () => {
@@ -2036,18 +2572,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
2036
2572
  if (this._actionHandler) {
2037
2573
  checkForUnknownOptions();
2038
2574
  this._processArguments();
2039
- let actionResult;
2040
- actionResult = this._chainOrCallHooks(actionResult, "preAction");
2041
- actionResult = this._chainOrCall(actionResult, () => this._actionHandler(this.processedArgs));
2575
+ let promiseChain;
2576
+ promiseChain = this._chainOrCallHooks(promiseChain, "preAction");
2577
+ promiseChain = this._chainOrCall(
2578
+ promiseChain,
2579
+ () => this._actionHandler(this.processedArgs)
2580
+ );
2042
2581
  if (this.parent) {
2043
- actionResult = this._chainOrCall(actionResult, () => {
2582
+ promiseChain = this._chainOrCall(promiseChain, () => {
2044
2583
  this.parent.emit(commandEvent, operands, unknown);
2045
2584
  });
2046
2585
  }
2047
- actionResult = this._chainOrCallHooks(actionResult, "postAction");
2048
- return actionResult;
2586
+ promiseChain = this._chainOrCallHooks(promiseChain, "postAction");
2587
+ return promiseChain;
2049
2588
  }
2050
- if (this.parent && this.parent.listenerCount(commandEvent)) {
2589
+ if (this.parent?.listenerCount(commandEvent)) {
2051
2590
  checkForUnknownOptions();
2052
2591
  this._processArguments();
2053
2592
  this.parent.emit(commandEvent, operands, unknown);
@@ -2074,19 +2613,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
2074
2613
  /**
2075
2614
  * Find matching command.
2076
2615
  *
2077
- * @api private
2616
+ * @private
2617
+ * @return {Command | undefined}
2078
2618
  */
2079
2619
  _findCommand(name) {
2080
- if (!name)
2081
- return void 0;
2082
- return this.commands.find((cmd) => cmd._name === name || cmd._aliases.includes(name));
2620
+ if (!name) return void 0;
2621
+ return this.commands.find(
2622
+ (cmd) => cmd._name === name || cmd._aliases.includes(name)
2623
+ );
2083
2624
  }
2084
2625
  /**
2085
2626
  * Return an option matching `arg` if any.
2086
2627
  *
2087
2628
  * @param {string} arg
2088
2629
  * @return {Option}
2089
- * @api private
2630
+ * @package
2090
2631
  */
2091
2632
  _findOption(arg) {
2092
2633
  return this.options.find((option) => option.is(arg));
@@ -2095,32 +2636,30 @@ Expecting one of '${allowedValues.join("', '")}'`);
2095
2636
  * Display an error message if a mandatory option does not have a value.
2096
2637
  * Called after checking for help flags in leaf subcommand.
2097
2638
  *
2098
- * @api private
2639
+ * @private
2099
2640
  */
2100
2641
  _checkForMissingMandatoryOptions() {
2101
- for (let cmd = this; cmd; cmd = cmd.parent) {
2642
+ this._getCommandAndAncestors().forEach((cmd) => {
2102
2643
  cmd.options.forEach((anOption) => {
2103
2644
  if (anOption.mandatory && cmd.getOptionValue(anOption.attributeName()) === void 0) {
2104
2645
  cmd.missingMandatoryOptionValue(anOption);
2105
2646
  }
2106
2647
  });
2107
- }
2648
+ });
2108
2649
  }
2109
2650
  /**
2110
2651
  * Display an error message if conflicting options are used together in this.
2111
2652
  *
2112
- * @api private
2653
+ * @private
2113
2654
  */
2114
2655
  _checkForConflictingLocalOptions() {
2115
- const definedNonDefaultOptions = this.options.filter(
2116
- (option) => {
2117
- const optionKey = option.attributeName();
2118
- if (this.getOptionValue(optionKey) === void 0) {
2119
- return false;
2120
- }
2121
- return this.getOptionValueSource(optionKey) !== "default";
2656
+ const definedNonDefaultOptions = this.options.filter((option) => {
2657
+ const optionKey = option.attributeName();
2658
+ if (this.getOptionValue(optionKey) === void 0) {
2659
+ return false;
2122
2660
  }
2123
- );
2661
+ return this.getOptionValueSource(optionKey) !== "default";
2662
+ });
2124
2663
  const optionsWithConflicting = definedNonDefaultOptions.filter(
2125
2664
  (option) => option.conflictsWith.length > 0
2126
2665
  );
@@ -2137,17 +2676,19 @@ Expecting one of '${allowedValues.join("', '")}'`);
2137
2676
  * Display an error message if conflicting options are used together.
2138
2677
  * Called after checking for help flags in leaf subcommand.
2139
2678
  *
2140
- * @api private
2679
+ * @private
2141
2680
  */
2142
2681
  _checkForConflictingOptions() {
2143
- for (let cmd = this; cmd; cmd = cmd.parent) {
2682
+ this._getCommandAndAncestors().forEach((cmd) => {
2144
2683
  cmd._checkForConflictingLocalOptions();
2145
- }
2684
+ });
2146
2685
  }
2147
2686
  /**
2148
2687
  * Parse options from `argv` removing known options,
2149
2688
  * and return argv split into operands and unknown arguments.
2150
2689
  *
2690
+ * Side effects: modifies command by storing options. Does not reset state if called again.
2691
+ *
2151
2692
  * Examples:
2152
2693
  *
2153
2694
  * argv => operands, unknown
@@ -2156,27 +2697,34 @@ Expecting one of '${allowedValues.join("', '")}'`);
2156
2697
  * sub --unknown uuu op => [sub], [--unknown uuu op]
2157
2698
  * sub -- --unknown uuu op => [sub --unknown uuu op], []
2158
2699
  *
2159
- * @param {String[]} argv
2160
- * @return {{operands: String[], unknown: String[]}}
2700
+ * @param {string[]} args
2701
+ * @return {{operands: string[], unknown: string[]}}
2161
2702
  */
2162
- parseOptions(argv) {
2703
+ parseOptions(args) {
2163
2704
  const operands = [];
2164
2705
  const unknown = [];
2165
2706
  let dest = operands;
2166
- const args = argv.slice();
2167
2707
  function maybeOption(arg) {
2168
2708
  return arg.length > 1 && arg[0] === "-";
2169
2709
  }
2710
+ const negativeNumberArg = (arg) => {
2711
+ if (!/^-(\d+|\d*\.\d+)(e[+-]?\d+)?$/.test(arg)) return false;
2712
+ return !this._getCommandAndAncestors().some(
2713
+ (cmd) => cmd.options.map((opt) => opt.short).some((short) => /^-\d$/.test(short))
2714
+ );
2715
+ };
2170
2716
  let activeVariadicOption = null;
2171
- while (args.length) {
2172
- const arg = args.shift();
2717
+ let activeGroup = null;
2718
+ let i = 0;
2719
+ while (i < args.length || activeGroup) {
2720
+ const arg = activeGroup ?? args[i++];
2721
+ activeGroup = null;
2173
2722
  if (arg === "--") {
2174
- if (dest === unknown)
2175
- dest.push(arg);
2176
- dest.push(...args);
2723
+ if (dest === unknown) dest.push(arg);
2724
+ dest.push(...args.slice(i));
2177
2725
  break;
2178
2726
  }
2179
- if (activeVariadicOption && !maybeOption(arg)) {
2727
+ if (activeVariadicOption && (!maybeOption(arg) || negativeNumberArg(arg))) {
2180
2728
  this.emit(`option:${activeVariadicOption.name()}`, arg);
2181
2729
  continue;
2182
2730
  }
@@ -2185,14 +2733,13 @@ Expecting one of '${allowedValues.join("', '")}'`);
2185
2733
  const option = this._findOption(arg);
2186
2734
  if (option) {
2187
2735
  if (option.required) {
2188
- const value = args.shift();
2189
- if (value === void 0)
2190
- this.optionMissingArgument(option);
2736
+ const value = args[i++];
2737
+ if (value === void 0) this.optionMissingArgument(option);
2191
2738
  this.emit(`option:${option.name()}`, value);
2192
2739
  } else if (option.optional) {
2193
2740
  let value = null;
2194
- if (args.length > 0 && !maybeOption(args[0])) {
2195
- value = args.shift();
2741
+ if (i < args.length && (!maybeOption(args[i]) || negativeNumberArg(args[i]))) {
2742
+ value = args[i++];
2196
2743
  }
2197
2744
  this.emit(`option:${option.name()}`, value);
2198
2745
  } else {
@@ -2209,7 +2756,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2209
2756
  this.emit(`option:${option.name()}`, arg.slice(2));
2210
2757
  } else {
2211
2758
  this.emit(`option:${option.name()}`);
2212
- args.unshift(`-${arg.slice(2)}`);
2759
+ activeGroup = `-${arg.slice(2)}`;
2213
2760
  }
2214
2761
  continue;
2215
2762
  }
@@ -2222,31 +2769,24 @@ Expecting one of '${allowedValues.join("', '")}'`);
2222
2769
  continue;
2223
2770
  }
2224
2771
  }
2225
- if (maybeOption(arg)) {
2772
+ if (dest === operands && maybeOption(arg) && !(this.commands.length === 0 && negativeNumberArg(arg))) {
2226
2773
  dest = unknown;
2227
2774
  }
2228
2775
  if ((this._enablePositionalOptions || this._passThroughOptions) && operands.length === 0 && unknown.length === 0) {
2229
2776
  if (this._findCommand(arg)) {
2230
2777
  operands.push(arg);
2231
- if (args.length > 0)
2232
- unknown.push(...args);
2778
+ unknown.push(...args.slice(i));
2233
2779
  break;
2234
- } else if (arg === this._helpCommandName && this._hasImplicitHelpCommand()) {
2235
- operands.push(arg);
2236
- if (args.length > 0)
2237
- operands.push(...args);
2780
+ } else if (this._getHelpCommand() && arg === this._getHelpCommand().name()) {
2781
+ operands.push(arg, ...args.slice(i));
2238
2782
  break;
2239
2783
  } else if (this._defaultCommandName) {
2240
- unknown.push(arg);
2241
- if (args.length > 0)
2242
- unknown.push(...args);
2784
+ unknown.push(arg, ...args.slice(i));
2243
2785
  break;
2244
2786
  }
2245
2787
  }
2246
2788
  if (this._passThroughOptions) {
2247
- dest.push(arg);
2248
- if (args.length > 0)
2249
- dest.push(...args);
2789
+ dest.push(arg, ...args.slice(i));
2250
2790
  break;
2251
2791
  }
2252
2792
  dest.push(arg);
@@ -2256,7 +2796,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2256
2796
  /**
2257
2797
  * Return an object containing local option values as key-value pairs.
2258
2798
  *
2259
- * @return {Object}
2799
+ * @return {object}
2260
2800
  */
2261
2801
  opts() {
2262
2802
  if (this._storeOptionsAsProperties) {
@@ -2273,10 +2813,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
2273
2813
  /**
2274
2814
  * Return an object containing merged local and global option values as key-value pairs.
2275
2815
  *
2276
- * @return {Object}
2816
+ * @return {object}
2277
2817
  */
2278
2818
  optsWithGlobals() {
2279
- return getCommandAndParents(this).reduce(
2819
+ return this._getCommandAndAncestors().reduce(
2280
2820
  (combinedOptions, cmd) => Object.assign(combinedOptions, cmd.opts()),
2281
2821
  {}
2282
2822
  );
@@ -2285,13 +2825,16 @@ Expecting one of '${allowedValues.join("', '")}'`);
2285
2825
  * Display error message and exit (or call exitOverride).
2286
2826
  *
2287
2827
  * @param {string} message
2288
- * @param {Object} [errorOptions]
2828
+ * @param {object} [errorOptions]
2289
2829
  * @param {string} [errorOptions.code] - an id string representing the error
2290
2830
  * @param {number} [errorOptions.exitCode] - used with process.exit
2291
2831
  */
2292
2832
  error(message, errorOptions) {
2293
- this._outputConfiguration.outputError(`${message}
2294
- `, this._outputConfiguration.writeErr);
2833
+ this._outputConfiguration.outputError(
2834
+ `${message}
2835
+ `,
2836
+ this._outputConfiguration.writeErr
2837
+ );
2295
2838
  if (typeof this._showHelpAfterError === "string") {
2296
2839
  this._outputConfiguration.writeErr(`${this._showHelpAfterError}
2297
2840
  `);
@@ -2308,13 +2851,15 @@ Expecting one of '${allowedValues.join("', '")}'`);
2308
2851
  * Apply any option related environment variables, if option does
2309
2852
  * not have a value from cli or client code.
2310
2853
  *
2311
- * @api private
2854
+ * @private
2312
2855
  */
2313
2856
  _parseOptionsEnv() {
2314
2857
  this.options.forEach((option) => {
2315
2858
  if (option.envVar && option.envVar in process2.env) {
2316
2859
  const optionKey = option.attributeName();
2317
- if (this.getOptionValue(optionKey) === void 0 || ["default", "config", "env"].includes(this.getOptionValueSource(optionKey))) {
2860
+ if (this.getOptionValue(optionKey) === void 0 || ["default", "config", "env"].includes(
2861
+ this.getOptionValueSource(optionKey)
2862
+ )) {
2318
2863
  if (option.required || option.optional) {
2319
2864
  this.emit(`optionEnv:${option.name()}`, process2.env[option.envVar]);
2320
2865
  } else {
@@ -2327,16 +2872,25 @@ Expecting one of '${allowedValues.join("', '")}'`);
2327
2872
  /**
2328
2873
  * Apply any implied option values, if option is undefined or default value.
2329
2874
  *
2330
- * @api private
2875
+ * @private
2331
2876
  */
2332
2877
  _parseOptionsImplied() {
2333
2878
  const dualHelper = new DualOptions(this.options);
2334
2879
  const hasCustomOptionValue = (optionKey) => {
2335
2880
  return this.getOptionValue(optionKey) !== void 0 && !["default", "implied"].includes(this.getOptionValueSource(optionKey));
2336
2881
  };
2337
- this.options.filter((option) => option.implied !== void 0 && hasCustomOptionValue(option.attributeName()) && dualHelper.valueFromOption(this.getOptionValue(option.attributeName()), option)).forEach((option) => {
2882
+ this.options.filter(
2883
+ (option) => option.implied !== void 0 && hasCustomOptionValue(option.attributeName()) && dualHelper.valueFromOption(
2884
+ this.getOptionValue(option.attributeName()),
2885
+ option
2886
+ )
2887
+ ).forEach((option) => {
2338
2888
  Object.keys(option.implied).filter((impliedKey) => !hasCustomOptionValue(impliedKey)).forEach((impliedKey) => {
2339
- this.setOptionValueWithSource(impliedKey, option.implied[impliedKey], "implied");
2889
+ this.setOptionValueWithSource(
2890
+ impliedKey,
2891
+ option.implied[impliedKey],
2892
+ "implied"
2893
+ );
2340
2894
  });
2341
2895
  });
2342
2896
  }
@@ -2344,7 +2898,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2344
2898
  * Argument `name` is missing.
2345
2899
  *
2346
2900
  * @param {string} name
2347
- * @api private
2901
+ * @private
2348
2902
  */
2349
2903
  missingArgument(name) {
2350
2904
  const message = `error: missing required argument '${name}'`;
@@ -2354,7 +2908,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2354
2908
  * `Option` is missing an argument.
2355
2909
  *
2356
2910
  * @param {Option} option
2357
- * @api private
2911
+ * @private
2358
2912
  */
2359
2913
  optionMissingArgument(option) {
2360
2914
  const message = `error: option '${option.flags}' argument missing`;
@@ -2364,7 +2918,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2364
2918
  * `Option` does not have a value, and is a mandatory option.
2365
2919
  *
2366
2920
  * @param {Option} option
2367
- * @api private
2921
+ * @private
2368
2922
  */
2369
2923
  missingMandatoryOptionValue(option) {
2370
2924
  const message = `error: required option '${option.flags}' not specified`;
@@ -2375,14 +2929,18 @@ Expecting one of '${allowedValues.join("', '")}'`);
2375
2929
  *
2376
2930
  * @param {Option} option
2377
2931
  * @param {Option} conflictingOption
2378
- * @api private
2932
+ * @private
2379
2933
  */
2380
2934
  _conflictingOption(option, conflictingOption) {
2381
2935
  const findBestOptionFromValue = (option2) => {
2382
2936
  const optionKey = option2.attributeName();
2383
2937
  const optionValue = this.getOptionValue(optionKey);
2384
- const negativeOption = this.options.find((target) => target.negate && optionKey === target.attributeName());
2385
- const positiveOption = this.options.find((target) => !target.negate && optionKey === target.attributeName());
2938
+ const negativeOption = this.options.find(
2939
+ (target) => target.negate && optionKey === target.attributeName()
2940
+ );
2941
+ const positiveOption = this.options.find(
2942
+ (target) => !target.negate && optionKey === target.attributeName()
2943
+ );
2386
2944
  if (negativeOption && (negativeOption.presetArg === void 0 && optionValue === false || negativeOption.presetArg !== void 0 && optionValue === negativeOption.presetArg)) {
2387
2945
  return negativeOption;
2388
2946
  }
@@ -2404,11 +2962,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
2404
2962
  * Unknown option `flag`.
2405
2963
  *
2406
2964
  * @param {string} flag
2407
- * @api private
2965
+ * @private
2408
2966
  */
2409
2967
  unknownOption(flag) {
2410
- if (this._allowUnknownOption)
2411
- return;
2968
+ if (this._allowUnknownOption) return;
2412
2969
  let suggestion = "";
2413
2970
  if (flag.startsWith("--") && this._showSuggestionAfterError) {
2414
2971
  let candidateFlags = [];
@@ -2427,12 +2984,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
2427
2984
  * Excess arguments, more than expected.
2428
2985
  *
2429
2986
  * @param {string[]} receivedArgs
2430
- * @api private
2987
+ * @private
2431
2988
  */
2432
2989
  _excessArguments(receivedArgs) {
2433
- if (this._allowExcessArguments)
2434
- return;
2435
- const expected = this._args.length;
2990
+ if (this._allowExcessArguments) return;
2991
+ const expected = this.registeredArguments.length;
2436
2992
  const s = expected === 1 ? "" : "s";
2437
2993
  const forSubcommand = this.parent ? ` for '${this.name()}'` : "";
2438
2994
  const message = `error: too many arguments${forSubcommand}. Expected ${expected} argument${s} but got ${receivedArgs.length}.`;
@@ -2441,7 +2997,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2441
2997
  /**
2442
2998
  * Unknown command.
2443
2999
  *
2444
- * @api private
3000
+ * @private
2445
3001
  */
2446
3002
  unknownCommand() {
2447
3003
  const unknownName = this.args[0];
@@ -2450,8 +3006,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2450
3006
  const candidateNames = [];
2451
3007
  this.createHelp().visibleCommands(this).forEach((command) => {
2452
3008
  candidateNames.push(command.name());
2453
- if (command.alias())
2454
- candidateNames.push(command.alias());
3009
+ if (command.alias()) candidateNames.push(command.alias());
2455
3010
  });
2456
3011
  suggestion = suggestSimilar(unknownName, candidateNames);
2457
3012
  }
@@ -2459,27 +3014,25 @@ Expecting one of '${allowedValues.join("', '")}'`);
2459
3014
  this.error(message, { code: "commander.unknownCommand" });
2460
3015
  }
2461
3016
  /**
2462
- * Set the program version to `str`.
3017
+ * Get or set the program version.
2463
3018
  *
2464
- * This method auto-registers the "-V, --version" flag
2465
- * which will print the version number when passed.
3019
+ * This method auto-registers the "-V, --version" option which will print the version number.
2466
3020
  *
2467
- * You can optionally supply the flags and description to override the defaults.
3021
+ * You can optionally supply the flags and description to override the defaults.
2468
3022
  *
2469
- * @param {string} str
3023
+ * @param {string} [str]
2470
3024
  * @param {string} [flags]
2471
3025
  * @param {string} [description]
2472
- * @return {this | string} `this` command for chaining, or version string if no arguments
3026
+ * @return {(this | string | undefined)} `this` command for chaining, or version string if no arguments
2473
3027
  */
2474
3028
  version(str, flags, description) {
2475
- if (str === void 0)
2476
- return this._version;
3029
+ if (str === void 0) return this._version;
2477
3030
  this._version = str;
2478
3031
  flags = flags || "-V, --version";
2479
3032
  description = description || "output the version number";
2480
3033
  const versionOption = this.createOption(flags, description);
2481
3034
  this._versionOptionName = versionOption.attributeName();
2482
- this.options.push(versionOption);
3035
+ this._registerOption(versionOption);
2483
3036
  this.on("option:" + versionOption.name(), () => {
2484
3037
  this._outputConfiguration.writeOut(`${str}
2485
3038
  `);
@@ -2491,8 +3044,8 @@ Expecting one of '${allowedValues.join("', '")}'`);
2491
3044
  * Set the description.
2492
3045
  *
2493
3046
  * @param {string} [str]
2494
- * @param {Object} [argsDescription]
2495
- * @return {string|Command}
3047
+ * @param {object} [argsDescription]
3048
+ * @return {(string|Command)}
2496
3049
  */
2497
3050
  description(str, argsDescription) {
2498
3051
  if (str === void 0 && argsDescription === void 0)
@@ -2507,11 +3060,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
2507
3060
  * Set the summary. Used when listed as subcommand of parent.
2508
3061
  *
2509
3062
  * @param {string} [str]
2510
- * @return {string|Command}
3063
+ * @return {(string|Command)}
2511
3064
  */
2512
3065
  summary(str) {
2513
- if (str === void 0)
2514
- return this._summary;
3066
+ if (str === void 0) return this._summary;
2515
3067
  this._summary = str;
2516
3068
  return this;
2517
3069
  }
@@ -2521,17 +3073,23 @@ Expecting one of '${allowedValues.join("', '")}'`);
2521
3073
  * You may call more than once to add multiple aliases. Only the first alias is shown in the auto-generated help.
2522
3074
  *
2523
3075
  * @param {string} [alias]
2524
- * @return {string|Command}
3076
+ * @return {(string|Command)}
2525
3077
  */
2526
3078
  alias(alias) {
2527
- if (alias === void 0)
2528
- return this._aliases[0];
3079
+ if (alias === void 0) return this._aliases[0];
2529
3080
  let command = this;
2530
3081
  if (this.commands.length !== 0 && this.commands[this.commands.length - 1]._executableHandler) {
2531
3082
  command = this.commands[this.commands.length - 1];
2532
3083
  }
2533
3084
  if (alias === command._name)
2534
3085
  throw new Error("Command alias can't be the same as its name");
3086
+ const matchingCommand = this.parent?._findCommand(alias);
3087
+ if (matchingCommand) {
3088
+ const existingCmd = [matchingCommand.name()].concat(matchingCommand.aliases()).join("|");
3089
+ throw new Error(
3090
+ `cannot add alias '${alias}' to command '${this.name()}' as already have command '${existingCmd}'`
3091
+ );
3092
+ }
2535
3093
  command._aliases.push(alias);
2536
3094
  return this;
2537
3095
  }
@@ -2541,11 +3099,10 @@ Expecting one of '${allowedValues.join("', '")}'`);
2541
3099
  * Only the first alias is shown in the auto-generated help.
2542
3100
  *
2543
3101
  * @param {string[]} [aliases]
2544
- * @return {string[]|Command}
3102
+ * @return {(string[]|Command)}
2545
3103
  */
2546
3104
  aliases(aliases) {
2547
- if (aliases === void 0)
2548
- return this._aliases;
3105
+ if (aliases === void 0) return this._aliases;
2549
3106
  aliases.forEach((alias) => this.alias(alias));
2550
3107
  return this;
2551
3108
  }
@@ -2553,19 +3110,18 @@ Expecting one of '${allowedValues.join("', '")}'`);
2553
3110
  * Set / get the command usage `str`.
2554
3111
  *
2555
3112
  * @param {string} [str]
2556
- * @return {String|Command}
3113
+ * @return {(string|Command)}
2557
3114
  */
2558
3115
  usage(str) {
2559
3116
  if (str === void 0) {
2560
- if (this._usage)
2561
- return this._usage;
2562
- const args = this._args.map((arg) => {
3117
+ if (this._usage) return this._usage;
3118
+ const args = this.registeredArguments.map((arg) => {
2563
3119
  return humanReadableArgName(arg);
2564
3120
  });
2565
3121
  return [].concat(
2566
- this.options.length || this._hasHelpOption ? "[options]" : [],
3122
+ this.options.length || this._helpOption !== null ? "[options]" : [],
2567
3123
  this.commands.length ? "[command]" : [],
2568
- this._args.length ? args : []
3124
+ this.registeredArguments.length ? args : []
2569
3125
  ).join(" ");
2570
3126
  }
2571
3127
  this._usage = str;
@@ -2575,14 +3131,76 @@ Expecting one of '${allowedValues.join("', '")}'`);
2575
3131
  * Get or set the name of the command.
2576
3132
  *
2577
3133
  * @param {string} [str]
2578
- * @return {string|Command}
3134
+ * @return {(string|Command)}
2579
3135
  */
2580
3136
  name(str) {
2581
- if (str === void 0)
2582
- return this._name;
3137
+ if (str === void 0) return this._name;
2583
3138
  this._name = str;
2584
3139
  return this;
2585
3140
  }
3141
+ /**
3142
+ * Set/get the help group heading for this subcommand in parent command's help.
3143
+ *
3144
+ * @param {string} [heading]
3145
+ * @return {Command | string}
3146
+ */
3147
+ helpGroup(heading) {
3148
+ if (heading === void 0) return this._helpGroupHeading ?? "";
3149
+ this._helpGroupHeading = heading;
3150
+ return this;
3151
+ }
3152
+ /**
3153
+ * Set/get the default help group heading for subcommands added to this command.
3154
+ * (This does not override a group set directly on the subcommand using .helpGroup().)
3155
+ *
3156
+ * @example
3157
+ * program.commandsGroup('Development Commands:);
3158
+ * program.command('watch')...
3159
+ * program.command('lint')...
3160
+ * ...
3161
+ *
3162
+ * @param {string} [heading]
3163
+ * @returns {Command | string}
3164
+ */
3165
+ commandsGroup(heading) {
3166
+ if (heading === void 0) return this._defaultCommandGroup ?? "";
3167
+ this._defaultCommandGroup = heading;
3168
+ return this;
3169
+ }
3170
+ /**
3171
+ * Set/get the default help group heading for options added to this command.
3172
+ * (This does not override a group set directly on the option using .helpGroup().)
3173
+ *
3174
+ * @example
3175
+ * program
3176
+ * .optionsGroup('Development Options:')
3177
+ * .option('-d, --debug', 'output extra debugging')
3178
+ * .option('-p, --profile', 'output profiling information')
3179
+ *
3180
+ * @param {string} [heading]
3181
+ * @returns {Command | string}
3182
+ */
3183
+ optionsGroup(heading) {
3184
+ if (heading === void 0) return this._defaultOptionGroup ?? "";
3185
+ this._defaultOptionGroup = heading;
3186
+ return this;
3187
+ }
3188
+ /**
3189
+ * @param {Option} option
3190
+ * @private
3191
+ */
3192
+ _initOptionGroup(option) {
3193
+ if (this._defaultOptionGroup && !option.helpGroupHeading)
3194
+ option.helpGroup(this._defaultOptionGroup);
3195
+ }
3196
+ /**
3197
+ * @param {Command} cmd
3198
+ * @private
3199
+ */
3200
+ _initCommandGroup(cmd) {
3201
+ if (this._defaultCommandGroup && !cmd.helpGroup())
3202
+ cmd.helpGroup(this._defaultCommandGroup);
3203
+ }
2586
3204
  /**
2587
3205
  * Set the name of the command from script filename, such as process.argv[1],
2588
3206
  * or require.main.filename, or __filename.
@@ -2596,7 +3214,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2596
3214
  * @return {Command}
2597
3215
  */
2598
3216
  nameFromFilename(filename) {
2599
- this._name = path.basename(filename, path.extname(filename));
3217
+ this._name = path2.basename(filename, path2.extname(filename));
2600
3218
  return this;
2601
3219
  }
2602
3220
  /**
@@ -2608,12 +3226,11 @@ Expecting one of '${allowedValues.join("', '")}'`);
2608
3226
  * program.executableDir('subcommands');
2609
3227
  *
2610
3228
  * @param {string} [path]
2611
- * @return {string|Command}
3229
+ * @return {(string|null|Command)}
2612
3230
  */
2613
- executableDir(path2) {
2614
- if (path2 === void 0)
2615
- return this._executableDir;
2616
- this._executableDir = path2;
3231
+ executableDir(path3) {
3232
+ if (path3 === void 0) return this._executableDir;
3233
+ this._executableDir = path3;
2617
3234
  return this;
2618
3235
  }
2619
3236
  /**
@@ -2624,26 +3241,47 @@ Expecting one of '${allowedValues.join("', '")}'`);
2624
3241
  */
2625
3242
  helpInformation(contextOptions) {
2626
3243
  const helper = this.createHelp();
2627
- if (helper.helpWidth === void 0) {
2628
- helper.helpWidth = contextOptions && contextOptions.error ? this._outputConfiguration.getErrHelpWidth() : this._outputConfiguration.getOutHelpWidth();
2629
- }
2630
- return helper.formatHelp(this, helper);
3244
+ const context = this._getOutputContext(contextOptions);
3245
+ helper.prepareContext({
3246
+ error: context.error,
3247
+ helpWidth: context.helpWidth,
3248
+ outputHasColors: context.hasColors
3249
+ });
3250
+ const text = helper.formatHelp(this, helper);
3251
+ if (context.hasColors) return text;
3252
+ return this._outputConfiguration.stripColor(text);
2631
3253
  }
2632
3254
  /**
2633
- * @api private
3255
+ * @typedef HelpContext
3256
+ * @type {object}
3257
+ * @property {boolean} error
3258
+ * @property {number} helpWidth
3259
+ * @property {boolean} hasColors
3260
+ * @property {function} write - includes stripColor if needed
3261
+ *
3262
+ * @returns {HelpContext}
3263
+ * @private
2634
3264
  */
2635
- _getHelpContext(contextOptions) {
3265
+ _getOutputContext(contextOptions) {
2636
3266
  contextOptions = contextOptions || {};
2637
- const context = { error: !!contextOptions.error };
2638
- let write;
2639
- if (context.error) {
2640
- write = (arg) => this._outputConfiguration.writeErr(arg);
3267
+ const error = !!contextOptions.error;
3268
+ let baseWrite;
3269
+ let hasColors;
3270
+ let helpWidth;
3271
+ if (error) {
3272
+ baseWrite = (str) => this._outputConfiguration.writeErr(str);
3273
+ hasColors = this._outputConfiguration.getErrHasColors();
3274
+ helpWidth = this._outputConfiguration.getErrHelpWidth();
2641
3275
  } else {
2642
- write = (arg) => this._outputConfiguration.writeOut(arg);
3276
+ baseWrite = (str) => this._outputConfiguration.writeOut(str);
3277
+ hasColors = this._outputConfiguration.getOutHasColors();
3278
+ helpWidth = this._outputConfiguration.getOutHelpWidth();
2643
3279
  }
2644
- context.write = contextOptions.write || write;
2645
- context.command = this;
2646
- return context;
3280
+ const write = (str) => {
3281
+ if (!hasColors) str = this._outputConfiguration.stripColor(str);
3282
+ return baseWrite(str);
3283
+ };
3284
+ return { error, write, hasColors, helpWidth };
2647
3285
  }
2648
3286
  /**
2649
3287
  * Output help information for this command.
@@ -2658,40 +3296,84 @@ Expecting one of '${allowedValues.join("', '")}'`);
2658
3296
  deprecatedCallback = contextOptions;
2659
3297
  contextOptions = void 0;
2660
3298
  }
2661
- const context = this._getHelpContext(contextOptions);
2662
- getCommandAndParents(this).reverse().forEach((command) => command.emit("beforeAllHelp", context));
2663
- this.emit("beforeHelp", context);
2664
- let helpInformation = this.helpInformation(context);
3299
+ const outputContext = this._getOutputContext(contextOptions);
3300
+ const eventContext = {
3301
+ error: outputContext.error,
3302
+ write: outputContext.write,
3303
+ command: this
3304
+ };
3305
+ this._getCommandAndAncestors().reverse().forEach((command) => command.emit("beforeAllHelp", eventContext));
3306
+ this.emit("beforeHelp", eventContext);
3307
+ let helpInformation = this.helpInformation({ error: outputContext.error });
2665
3308
  if (deprecatedCallback) {
2666
3309
  helpInformation = deprecatedCallback(helpInformation);
2667
3310
  if (typeof helpInformation !== "string" && !Buffer.isBuffer(helpInformation)) {
2668
3311
  throw new Error("outputHelp callback must return a string or a Buffer");
2669
3312
  }
2670
3313
  }
2671
- context.write(helpInformation);
2672
- this.emit(this._helpLongFlag);
2673
- this.emit("afterHelp", context);
2674
- getCommandAndParents(this).forEach((command) => command.emit("afterAllHelp", context));
3314
+ outputContext.write(helpInformation);
3315
+ if (this._getHelpOption()?.long) {
3316
+ this.emit(this._getHelpOption().long);
3317
+ }
3318
+ this.emit("afterHelp", eventContext);
3319
+ this._getCommandAndAncestors().forEach(
3320
+ (command) => command.emit("afterAllHelp", eventContext)
3321
+ );
2675
3322
  }
2676
3323
  /**
2677
- * You can pass in flags and a description to override the help
2678
- * flags and help description for your command. Pass in false to
2679
- * disable the built-in help option.
3324
+ * You can pass in flags and a description to customise the built-in help option.
3325
+ * Pass in false to disable the built-in help option.
3326
+ *
3327
+ * @example
3328
+ * program.helpOption('-?, --help' 'show help'); // customise
3329
+ * program.helpOption(false); // disable
2680
3330
  *
2681
- * @param {string | boolean} [flags]
3331
+ * @param {(string | boolean)} flags
2682
3332
  * @param {string} [description]
2683
3333
  * @return {Command} `this` command for chaining
2684
3334
  */
2685
3335
  helpOption(flags, description) {
2686
3336
  if (typeof flags === "boolean") {
2687
- this._hasHelpOption = flags;
3337
+ if (flags) {
3338
+ if (this._helpOption === null) this._helpOption = void 0;
3339
+ if (this._defaultOptionGroup) {
3340
+ this._initOptionGroup(this._getHelpOption());
3341
+ }
3342
+ } else {
3343
+ this._helpOption = null;
3344
+ }
2688
3345
  return this;
2689
3346
  }
2690
- this._helpFlags = flags || this._helpFlags;
2691
- this._helpDescription = description || this._helpDescription;
2692
- const helpFlags = splitOptionFlags(this._helpFlags);
2693
- this._helpShortFlag = helpFlags.shortFlag;
2694
- this._helpLongFlag = helpFlags.longFlag;
3347
+ this._helpOption = this.createOption(
3348
+ flags ?? "-h, --help",
3349
+ description ?? "display help for command"
3350
+ );
3351
+ if (flags || description) this._initOptionGroup(this._helpOption);
3352
+ return this;
3353
+ }
3354
+ /**
3355
+ * Lazy create help option.
3356
+ * Returns null if has been disabled with .helpOption(false).
3357
+ *
3358
+ * @returns {(Option | null)} the help option
3359
+ * @package
3360
+ */
3361
+ _getHelpOption() {
3362
+ if (this._helpOption === void 0) {
3363
+ this.helpOption(void 0, void 0);
3364
+ }
3365
+ return this._helpOption;
3366
+ }
3367
+ /**
3368
+ * Supply your own option to use for the built-in help option.
3369
+ * This is an alternative to using helpOption() to customise the flags and description etc.
3370
+ *
3371
+ * @param {Option} option
3372
+ * @return {Command} `this` command for chaining
3373
+ */
3374
+ addHelpOption(option) {
3375
+ this._helpOption = option;
3376
+ this._initOptionGroup(option);
2695
3377
  return this;
2696
3378
  }
2697
3379
  /**
@@ -2703,12 +3385,20 @@ Expecting one of '${allowedValues.join("', '")}'`);
2703
3385
  */
2704
3386
  help(contextOptions) {
2705
3387
  this.outputHelp(contextOptions);
2706
- let exitCode = process2.exitCode || 0;
3388
+ let exitCode = Number(process2.exitCode ?? 0);
2707
3389
  if (exitCode === 0 && contextOptions && typeof contextOptions !== "function" && contextOptions.error) {
2708
3390
  exitCode = 1;
2709
3391
  }
2710
3392
  this._exit(exitCode, "commander.help", "(outputHelp)");
2711
3393
  }
3394
+ /**
3395
+ * // Do a little typing to coordinate emit and listener for the help text events.
3396
+ * @typedef HelpTextEventContext
3397
+ * @type {object}
3398
+ * @property {boolean} error
3399
+ * @property {Command} command
3400
+ * @property {function} write
3401
+ */
2712
3402
  /**
2713
3403
  * Add additional text to be displayed with the built-in help.
2714
3404
  *
@@ -2716,7 +3406,7 @@ Expecting one of '${allowedValues.join("', '")}'`);
2716
3406
  * and 'beforeAll' or 'afterAll' to affect this command and all its subcommands.
2717
3407
  *
2718
3408
  * @param {string} position - before or after built-in help
2719
- * @param {string | Function} text - string to add, or a function returning a string
3409
+ * @param {(string | Function)} text - string to add, or a function returning a string
2720
3410
  * @return {Command} `this` command for chaining
2721
3411
  */
2722
3412
  addHelpText(position, text) {
@@ -2740,14 +3430,21 @@ Expecting one of '${allowedValues.join("', '")}'`);
2740
3430
  });
2741
3431
  return this;
2742
3432
  }
2743
- };
2744
- function outputHelpIfRequested(cmd, args) {
2745
- const helpOption = cmd._hasHelpOption && args.find((arg) => arg === cmd._helpLongFlag || arg === cmd._helpShortFlag);
2746
- if (helpOption) {
2747
- cmd.outputHelp();
2748
- cmd._exit(0, "commander.helpDisplayed", "(outputHelp)");
3433
+ /**
3434
+ * Output help information if help flags specified
3435
+ *
3436
+ * @param {Array} args - array of options to search for help flags
3437
+ * @private
3438
+ */
3439
+ _outputHelpIfRequested(args) {
3440
+ const helpOption = this._getHelpOption();
3441
+ const helpRequested = helpOption && args.find((arg) => helpOption.is(arg));
3442
+ if (helpRequested) {
3443
+ this.outputHelp();
3444
+ this._exit(0, "commander.helpDisplayed", "(outputHelp)");
3445
+ }
2749
3446
  }
2750
- }
3447
+ };
2751
3448
  function incrementNodeInspectorPort(args) {
2752
3449
  return args.map((arg) => {
2753
3450
  if (!arg.startsWith("--inspect")) {
@@ -2777,42 +3474,809 @@ Expecting one of '${allowedValues.join("', '")}'`);
2777
3474
  return arg;
2778
3475
  });
2779
3476
  }
2780
- function getCommandAndParents(startCommand) {
2781
- const result = [];
2782
- for (let command = startCommand; command; command = command.parent) {
2783
- result.push(command);
2784
- }
2785
- return result;
3477
+ function useColor() {
3478
+ if (process2.env.NO_COLOR || process2.env.FORCE_COLOR === "0" || process2.env.FORCE_COLOR === "false")
3479
+ return false;
3480
+ if (process2.env.FORCE_COLOR || process2.env.CLICOLOR_FORCE !== void 0)
3481
+ return true;
3482
+ return void 0;
2786
3483
  }
2787
- exports.Command = Command2;
3484
+ exports2.Command = Command2;
3485
+ exports2.useColor = useColor;
2788
3486
  }
2789
3487
  });
2790
3488
 
2791
- // node_modules/commander/index.js
3489
+ // node_modules/.pnpm/commander@14.0.3/node_modules/commander/index.js
2792
3490
  var require_commander = __commonJS({
2793
- "node_modules/commander/index.js"(exports, module2) {
3491
+ "node_modules/.pnpm/commander@14.0.3/node_modules/commander/index.js"(exports2) {
2794
3492
  var { Argument: Argument2 } = require_argument();
2795
3493
  var { Command: Command2 } = require_command();
2796
3494
  var { CommanderError: CommanderError2, InvalidArgumentError: InvalidArgumentError2 } = require_error();
2797
3495
  var { Help: Help2 } = require_help();
2798
3496
  var { Option: Option2 } = require_option();
2799
- exports = module2.exports = new Command2();
2800
- exports.program = exports;
2801
- exports.Argument = Argument2;
2802
- exports.Command = Command2;
2803
- exports.CommanderError = CommanderError2;
2804
- exports.Help = Help2;
2805
- exports.InvalidArgumentError = InvalidArgumentError2;
2806
- exports.InvalidOptionArgumentError = InvalidArgumentError2;
2807
- exports.Option = Option2;
3497
+ exports2.program = new Command2();
3498
+ exports2.createCommand = (name) => new Command2(name);
3499
+ exports2.createOption = (flags, description) => new Option2(flags, description);
3500
+ exports2.createArgument = (name, description) => new Argument2(name, description);
3501
+ exports2.Command = Command2;
3502
+ exports2.Option = Option2;
3503
+ exports2.Argument = Argument2;
3504
+ exports2.Help = Help2;
3505
+ exports2.CommanderError = CommanderError2;
3506
+ exports2.InvalidArgumentError = InvalidArgumentError2;
3507
+ exports2.InvalidOptionArgumentError = InvalidArgumentError2;
2808
3508
  }
2809
3509
  });
2810
3510
 
3511
+ // node_modules/.pnpm/@clack+core@1.3.0/node_modules/@clack/core/dist/index.mjs
3512
+ var import_node_process = require("node:process");
3513
+ var import_node_readline = __toESM(require("node:readline"), 1);
3514
+
3515
+ // node_modules/.pnpm/fast-string-truncated-width@3.0.3/node_modules/fast-string-truncated-width/dist/utils.js
3516
+ var getCodePointsLength = /* @__PURE__ */ (() => {
3517
+ const SURROGATE_PAIR_RE = /[\uD800-\uDBFF][\uDC00-\uDFFF]/g;
3518
+ return (input) => {
3519
+ let surrogatePairsNr = 0;
3520
+ SURROGATE_PAIR_RE.lastIndex = 0;
3521
+ while (SURROGATE_PAIR_RE.test(input)) {
3522
+ surrogatePairsNr += 1;
3523
+ }
3524
+ return input.length - surrogatePairsNr;
3525
+ };
3526
+ })();
3527
+ var isFullWidth = (x) => {
3528
+ return x === 12288 || x >= 65281 && x <= 65376 || x >= 65504 && x <= 65510;
3529
+ };
3530
+ var isWideNotCJKTNotEmoji = (x) => {
3531
+ return x === 8987 || x === 9001 || x >= 12272 && x <= 12287 || x >= 12289 && x <= 12350 || x >= 12441 && x <= 12543 || x >= 12549 && x <= 12591 || x >= 12593 && x <= 12686 || x >= 12688 && x <= 12771 || x >= 12783 && x <= 12830 || x >= 12832 && x <= 12871 || x >= 12880 && x <= 19903 || x >= 65040 && x <= 65049 || x >= 65072 && x <= 65106 || x >= 65108 && x <= 65126 || x >= 65128 && x <= 65131 || x >= 127488 && x <= 127490 || x >= 127504 && x <= 127547 || x >= 127552 && x <= 127560 || x >= 131072 && x <= 196605 || x >= 196608 && x <= 262141;
3532
+ };
3533
+
3534
+ // node_modules/.pnpm/fast-string-truncated-width@3.0.3/node_modules/fast-string-truncated-width/dist/index.js
3535
+ var ANSI_RE = /[\u001b\u009b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><]|\u001b\]8;[^;]*;.*?(?:\u0007|\u001b\u005c)/y;
3536
+ var CONTROL_RE = /[\x00-\x08\x0A-\x1F\x7F-\x9F]{1,1000}/y;
3537
+ var CJKT_WIDE_RE = /(?:(?![\uFF61-\uFF9F\uFF00-\uFFEF])[\p{Script=Han}\p{Script=Hiragana}\p{Script=Katakana}\p{Script=Hangul}\p{Script=Tangut}]){1,1000}/yu;
3538
+ var TAB_RE = /\t{1,1000}/y;
3539
+ var EMOJI_RE = new RegExp("[\\u{1F1E6}-\\u{1F1FF}]{2}|\\u{1F3F4}[\\u{E0061}-\\u{E007A}]{2}[\\u{E0030}-\\u{E0039}\\u{E0061}-\\u{E007A}]{1,3}\\u{E007F}|(?:\\p{Emoji}\\uFE0F\\u20E3?|\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation})(?:\\u200D(?:\\p{Emoji_Modifier_Base}\\p{Emoji_Modifier}?|\\p{Emoji_Presentation}|\\p{Emoji}\\uFE0F\\u20E3?))*", "yu");
3540
+ var LATIN_RE = /(?:[\x20-\x7E\xA0-\xFF](?!\uFE0F)){1,1000}/y;
3541
+ var MODIFIER_RE = new RegExp("\\p{M}+", "gu");
3542
+ var NO_TRUNCATION = { limit: Infinity, ellipsis: "" };
3543
+ var getStringTruncatedWidth = (input, truncationOptions = {}, widthOptions = {}) => {
3544
+ const LIMIT = truncationOptions.limit ?? Infinity;
3545
+ const ELLIPSIS = truncationOptions.ellipsis ?? "";
3546
+ const ELLIPSIS_WIDTH = truncationOptions?.ellipsisWidth ?? (ELLIPSIS ? getStringTruncatedWidth(ELLIPSIS, NO_TRUNCATION, widthOptions).width : 0);
3547
+ const ANSI_WIDTH = 0;
3548
+ const CONTROL_WIDTH = widthOptions.controlWidth ?? 0;
3549
+ const TAB_WIDTH = widthOptions.tabWidth ?? 8;
3550
+ const EMOJI_WIDTH = widthOptions.emojiWidth ?? 2;
3551
+ const FULL_WIDTH_WIDTH = 2;
3552
+ const REGULAR_WIDTH = widthOptions.regularWidth ?? 1;
3553
+ const WIDE_WIDTH = widthOptions.wideWidth ?? FULL_WIDTH_WIDTH;
3554
+ const PARSE_BLOCKS = [
3555
+ [LATIN_RE, REGULAR_WIDTH],
3556
+ [ANSI_RE, ANSI_WIDTH],
3557
+ [CONTROL_RE, CONTROL_WIDTH],
3558
+ [TAB_RE, TAB_WIDTH],
3559
+ [EMOJI_RE, EMOJI_WIDTH],
3560
+ [CJKT_WIDE_RE, WIDE_WIDTH]
3561
+ ];
3562
+ let indexPrev = 0;
3563
+ let index = 0;
3564
+ let length = input.length;
3565
+ let lengthExtra = 0;
3566
+ let truncationEnabled = false;
3567
+ let truncationIndex = length;
3568
+ let truncationLimit = Math.max(0, LIMIT - ELLIPSIS_WIDTH);
3569
+ let unmatchedStart = 0;
3570
+ let unmatchedEnd = 0;
3571
+ let width = 0;
3572
+ let widthExtra = 0;
3573
+ outer: while (true) {
3574
+ if (unmatchedEnd > unmatchedStart || index >= length && index > indexPrev) {
3575
+ const unmatched = input.slice(unmatchedStart, unmatchedEnd) || input.slice(indexPrev, index);
3576
+ lengthExtra = 0;
3577
+ for (const char of unmatched.replaceAll(MODIFIER_RE, "")) {
3578
+ const codePoint = char.codePointAt(0) || 0;
3579
+ if (isFullWidth(codePoint)) {
3580
+ widthExtra = FULL_WIDTH_WIDTH;
3581
+ } else if (isWideNotCJKTNotEmoji(codePoint)) {
3582
+ widthExtra = WIDE_WIDTH;
3583
+ } else {
3584
+ widthExtra = REGULAR_WIDTH;
3585
+ }
3586
+ if (width + widthExtra > truncationLimit) {
3587
+ truncationIndex = Math.min(truncationIndex, Math.max(unmatchedStart, indexPrev) + lengthExtra);
3588
+ }
3589
+ if (width + widthExtra > LIMIT) {
3590
+ truncationEnabled = true;
3591
+ break outer;
3592
+ }
3593
+ lengthExtra += char.length;
3594
+ width += widthExtra;
3595
+ }
3596
+ unmatchedStart = unmatchedEnd = 0;
3597
+ }
3598
+ if (index >= length) {
3599
+ break outer;
3600
+ }
3601
+ for (let i = 0, l = PARSE_BLOCKS.length; i < l; i++) {
3602
+ const [BLOCK_RE, BLOCK_WIDTH] = PARSE_BLOCKS[i];
3603
+ BLOCK_RE.lastIndex = index;
3604
+ if (BLOCK_RE.test(input)) {
3605
+ lengthExtra = BLOCK_RE === CJKT_WIDE_RE ? getCodePointsLength(input.slice(index, BLOCK_RE.lastIndex)) : BLOCK_RE === EMOJI_RE ? 1 : BLOCK_RE.lastIndex - index;
3606
+ widthExtra = lengthExtra * BLOCK_WIDTH;
3607
+ if (width + widthExtra > truncationLimit) {
3608
+ truncationIndex = Math.min(truncationIndex, index + Math.floor((truncationLimit - width) / BLOCK_WIDTH));
3609
+ }
3610
+ if (width + widthExtra > LIMIT) {
3611
+ truncationEnabled = true;
3612
+ break outer;
3613
+ }
3614
+ width += widthExtra;
3615
+ unmatchedStart = indexPrev;
3616
+ unmatchedEnd = index;
3617
+ index = indexPrev = BLOCK_RE.lastIndex;
3618
+ continue outer;
3619
+ }
3620
+ }
3621
+ index += 1;
3622
+ }
3623
+ return {
3624
+ width: truncationEnabled ? truncationLimit : width,
3625
+ index: truncationEnabled ? truncationIndex : length,
3626
+ truncated: truncationEnabled,
3627
+ ellipsed: truncationEnabled && LIMIT >= ELLIPSIS_WIDTH
3628
+ };
3629
+ };
3630
+ var dist_default = getStringTruncatedWidth;
3631
+
3632
+ // node_modules/.pnpm/fast-string-width@3.0.2/node_modules/fast-string-width/dist/index.js
3633
+ var NO_TRUNCATION2 = {
3634
+ limit: Infinity,
3635
+ ellipsis: "",
3636
+ ellipsisWidth: 0
3637
+ };
3638
+ var fastStringWidth = (input, options = {}) => {
3639
+ return dist_default(input, NO_TRUNCATION2, options).width;
3640
+ };
3641
+ var dist_default2 = fastStringWidth;
3642
+
3643
+ // node_modules/.pnpm/fast-wrap-ansi@0.2.0/node_modules/fast-wrap-ansi/lib/main.js
3644
+ var ESC = "\x1B";
3645
+ var CSI = "\x9B";
3646
+ var END_CODE = 39;
3647
+ var ANSI_ESCAPE_BELL = "\x07";
3648
+ var ANSI_CSI = "[";
3649
+ var ANSI_OSC = "]";
3650
+ var ANSI_SGR_TERMINATOR = "m";
3651
+ var ANSI_ESCAPE_LINK = `${ANSI_OSC}8;;`;
3652
+ var GROUP_REGEX = new RegExp(`(?:\\${ANSI_CSI}(?<code>\\d+)m|\\${ANSI_ESCAPE_LINK}(?<uri>.*)${ANSI_ESCAPE_BELL})`, "y");
3653
+ var getClosingCode = (openingCode) => {
3654
+ if (openingCode >= 30 && openingCode <= 37)
3655
+ return 39;
3656
+ if (openingCode >= 90 && openingCode <= 97)
3657
+ return 39;
3658
+ if (openingCode >= 40 && openingCode <= 47)
3659
+ return 49;
3660
+ if (openingCode >= 100 && openingCode <= 107)
3661
+ return 49;
3662
+ if (openingCode === 1 || openingCode === 2)
3663
+ return 22;
3664
+ if (openingCode === 3)
3665
+ return 23;
3666
+ if (openingCode === 4)
3667
+ return 24;
3668
+ if (openingCode === 7)
3669
+ return 27;
3670
+ if (openingCode === 8)
3671
+ return 28;
3672
+ if (openingCode === 9)
3673
+ return 29;
3674
+ if (openingCode === 0)
3675
+ return 0;
3676
+ return void 0;
3677
+ };
3678
+ var wrapAnsiCode = (code) => `${ESC}${ANSI_CSI}${code}${ANSI_SGR_TERMINATOR}`;
3679
+ var wrapAnsiHyperlink = (url) => `${ESC}${ANSI_ESCAPE_LINK}${url}${ANSI_ESCAPE_BELL}`;
3680
+ var wrapWord = (rows, word, columns) => {
3681
+ const characters = word[Symbol.iterator]();
3682
+ let isInsideEscape = false;
3683
+ let isInsideLinkEscape = false;
3684
+ let lastRow = rows.at(-1);
3685
+ let visible = lastRow === void 0 ? 0 : dist_default2(lastRow);
3686
+ let currentCharacter = characters.next();
3687
+ let nextCharacter = characters.next();
3688
+ let rawCharacterIndex = 0;
3689
+ while (!currentCharacter.done) {
3690
+ const character = currentCharacter.value;
3691
+ const characterLength = dist_default2(character);
3692
+ if (visible + characterLength <= columns) {
3693
+ rows[rows.length - 1] += character;
3694
+ } else {
3695
+ rows.push(character);
3696
+ visible = 0;
3697
+ }
3698
+ if (character === ESC || character === CSI) {
3699
+ isInsideEscape = true;
3700
+ isInsideLinkEscape = word.startsWith(ANSI_ESCAPE_LINK, rawCharacterIndex + 1);
3701
+ }
3702
+ if (isInsideEscape) {
3703
+ if (isInsideLinkEscape) {
3704
+ if (character === ANSI_ESCAPE_BELL) {
3705
+ isInsideEscape = false;
3706
+ isInsideLinkEscape = false;
3707
+ }
3708
+ } else if (character === ANSI_SGR_TERMINATOR) {
3709
+ isInsideEscape = false;
3710
+ }
3711
+ } else {
3712
+ visible += characterLength;
3713
+ if (visible === columns && !nextCharacter.done) {
3714
+ rows.push("");
3715
+ visible = 0;
3716
+ }
3717
+ }
3718
+ currentCharacter = nextCharacter;
3719
+ nextCharacter = characters.next();
3720
+ rawCharacterIndex += character.length;
3721
+ }
3722
+ lastRow = rows.at(-1);
3723
+ if (!visible && lastRow !== void 0 && lastRow.length && rows.length > 1) {
3724
+ rows[rows.length - 2] += rows.pop();
3725
+ }
3726
+ };
3727
+ var stringVisibleTrimSpacesRight = (string) => {
3728
+ const words = string.split(" ");
3729
+ let last = words.length;
3730
+ while (last) {
3731
+ if (dist_default2(words[last - 1])) {
3732
+ break;
3733
+ }
3734
+ last--;
3735
+ }
3736
+ if (last === words.length) {
3737
+ return string;
3738
+ }
3739
+ return words.slice(0, last).join(" ") + words.slice(last).join("");
3740
+ };
3741
+ var exec = (string, columns, options = {}) => {
3742
+ if (options.trim !== false && string.trim() === "") {
3743
+ return "";
3744
+ }
3745
+ let returnValue = "";
3746
+ let escapeCode;
3747
+ let escapeUrl;
3748
+ const words = string.split(" ");
3749
+ let rows = [""];
3750
+ let rowLength = 0;
3751
+ for (let index = 0; index < words.length; index++) {
3752
+ const word = words[index];
3753
+ if (options.trim !== false) {
3754
+ const row = rows.at(-1) ?? "";
3755
+ const trimmed = row.trimStart();
3756
+ if (row.length !== trimmed.length) {
3757
+ rows[rows.length - 1] = trimmed;
3758
+ rowLength = dist_default2(trimmed);
3759
+ }
3760
+ }
3761
+ if (index !== 0) {
3762
+ if (rowLength >= columns && (options.wordWrap === false || options.trim === false)) {
3763
+ rows.push("");
3764
+ rowLength = 0;
3765
+ }
3766
+ if (rowLength || options.trim === false) {
3767
+ rows[rows.length - 1] += " ";
3768
+ rowLength++;
3769
+ }
3770
+ }
3771
+ const wordLength = dist_default2(word);
3772
+ if (options.hard && wordLength > columns) {
3773
+ const remainingColumns = columns - rowLength;
3774
+ const breaksStartingThisLine = 1 + Math.floor((wordLength - remainingColumns - 1) / columns);
3775
+ const breaksStartingNextLine = Math.floor((wordLength - 1) / columns);
3776
+ if (breaksStartingNextLine < breaksStartingThisLine) {
3777
+ rows.push("");
3778
+ }
3779
+ wrapWord(rows, word, columns);
3780
+ rowLength = dist_default2(rows.at(-1) ?? "");
3781
+ continue;
3782
+ }
3783
+ if (rowLength + wordLength > columns && rowLength && wordLength) {
3784
+ if (options.wordWrap === false && rowLength < columns) {
3785
+ wrapWord(rows, word, columns);
3786
+ rowLength = dist_default2(rows.at(-1) ?? "");
3787
+ continue;
3788
+ }
3789
+ rows.push("");
3790
+ rowLength = 0;
3791
+ }
3792
+ if (rowLength + wordLength > columns && options.wordWrap === false) {
3793
+ wrapWord(rows, word, columns);
3794
+ rowLength = dist_default2(rows.at(-1) ?? "");
3795
+ continue;
3796
+ }
3797
+ rows[rows.length - 1] += word;
3798
+ rowLength += wordLength;
3799
+ }
3800
+ if (options.trim !== false) {
3801
+ rows = rows.map((row) => stringVisibleTrimSpacesRight(row));
3802
+ }
3803
+ const preString = rows.join("\n");
3804
+ let inSurrogate = false;
3805
+ for (let i = 0; i < preString.length; i++) {
3806
+ const character = preString[i];
3807
+ returnValue += character;
3808
+ if (!inSurrogate) {
3809
+ inSurrogate = character >= "\uD800" && character <= "\uDBFF";
3810
+ if (inSurrogate) {
3811
+ continue;
3812
+ }
3813
+ } else {
3814
+ inSurrogate = false;
3815
+ }
3816
+ if (character === ESC || character === CSI) {
3817
+ GROUP_REGEX.lastIndex = i + 1;
3818
+ const groupsResult = GROUP_REGEX.exec(preString);
3819
+ const groups = groupsResult?.groups;
3820
+ if (groups?.code !== void 0) {
3821
+ const code = Number.parseFloat(groups.code);
3822
+ escapeCode = code === END_CODE ? void 0 : code;
3823
+ } else if (groups?.uri !== void 0) {
3824
+ escapeUrl = groups.uri.length === 0 ? void 0 : groups.uri;
3825
+ }
3826
+ }
3827
+ if (preString[i + 1] === "\n") {
3828
+ if (escapeUrl) {
3829
+ returnValue += wrapAnsiHyperlink("");
3830
+ }
3831
+ const closingCode = escapeCode ? getClosingCode(escapeCode) : void 0;
3832
+ if (escapeCode && closingCode) {
3833
+ returnValue += wrapAnsiCode(closingCode);
3834
+ }
3835
+ } else if (character === "\n") {
3836
+ if (escapeCode && getClosingCode(escapeCode)) {
3837
+ returnValue += wrapAnsiCode(escapeCode);
3838
+ }
3839
+ if (escapeUrl) {
3840
+ returnValue += wrapAnsiHyperlink(escapeUrl);
3841
+ }
3842
+ }
3843
+ }
3844
+ return returnValue;
3845
+ };
3846
+ var CRLF_OR_LF = /\r?\n/;
3847
+ function wrapAnsi(string, columns, options) {
3848
+ return String(string).normalize().split(CRLF_OR_LF).map((line) => exec(line, columns, options)).join("\n");
3849
+ }
3850
+
3851
+ // node_modules/.pnpm/@clack+core@1.3.0/node_modules/@clack/core/dist/index.mjs
3852
+ var import_sisteransi = __toESM(require_src(), 1);
3853
+ function d(r, t, s) {
3854
+ if (!s.some((o) => !o.disabled)) return r;
3855
+ const e2 = r + t, i = Math.max(s.length - 1, 0), n = e2 < 0 ? i : e2 > i ? 0 : e2;
3856
+ return s[n].disabled ? d(n, t < 0 ? -1 : 1, s) : n;
3857
+ }
3858
+ var G = ["up", "down", "left", "right", "space", "enter", "cancel"];
3859
+ var K = ["January", "February", "March", "April", "May", "June", "July", "August", "September", "October", "November", "December"];
3860
+ var h = { actions: new Set(G), aliases: /* @__PURE__ */ new Map([["k", "up"], ["j", "down"], ["h", "left"], ["l", "right"], ["", "cancel"], ["escape", "cancel"]]), messages: { cancel: "Canceled", error: "Something went wrong" }, withGuide: true, date: { monthNames: [...K], messages: { required: "Please enter a valid date", invalidMonth: "There are only 12 months in a year", invalidDay: (r, t) => `There are only ${r} days in ${t}`, afterMin: (r) => `Date must be on or after ${r.toISOString().slice(0, 10)}`, beforeMax: (r) => `Date must be on or before ${r.toISOString().slice(0, 10)}` } } };
3861
+ function C(r, t) {
3862
+ if (typeof r == "string") return h.aliases.get(r) === t;
3863
+ for (const s of r) if (s !== void 0 && C(s, t)) return true;
3864
+ return false;
3865
+ }
3866
+ function z(r, t) {
3867
+ if (r === t) return;
3868
+ const s = r.split(`
3869
+ `), e2 = t.split(`
3870
+ `), i = Math.max(s.length, e2.length), n = [];
3871
+ for (let o = 0; o < i; o++) s[o] !== e2[o] && n.push(o);
3872
+ return { lines: n, numLinesBefore: s.length, numLinesAfter: e2.length, numLines: i };
3873
+ }
3874
+ var Y = globalThis.process.platform.startsWith("win");
3875
+ var k = /* @__PURE__ */ Symbol("clack:cancel");
3876
+ function q(r) {
3877
+ return r === k;
3878
+ }
3879
+ function w(r, t) {
3880
+ const s = r;
3881
+ s.isTTY && s.setRawMode(t);
3882
+ }
3883
+ var A = (r) => "columns" in r && typeof r.columns == "number" ? r.columns : 80;
3884
+ var L = (r) => "rows" in r && typeof r.rows == "number" ? r.rows : 20;
3885
+ function W(r, t, s, e2 = s, i) {
3886
+ const n = A(r ?? import_node_process.stdout);
3887
+ return wrapAnsi(t, n - s.length, { hard: true, trim: false }).split(`
3888
+ `).map((o, u) => {
3889
+ const a = i ? i(o, u) : o;
3890
+ return `${u === 0 ? e2 : s}${a}`;
3891
+ }).join(`
3892
+ `);
3893
+ }
3894
+ var p = class {
3895
+ input;
3896
+ output;
3897
+ _abortSignal;
3898
+ rl;
3899
+ opts;
3900
+ _render;
3901
+ _track = false;
3902
+ _prevFrame = "";
3903
+ _subscribers = /* @__PURE__ */ new Map();
3904
+ _cursor = 0;
3905
+ state = "initial";
3906
+ error = "";
3907
+ value;
3908
+ userInput = "";
3909
+ constructor(t, s = true) {
3910
+ const { input: e2 = import_node_process.stdin, output: i = import_node_process.stdout, render: n, signal: o, ...u } = t;
3911
+ this.opts = u, this.onKeypress = this.onKeypress.bind(this), this.close = this.close.bind(this), this.render = this.render.bind(this), this._render = n.bind(this), this._track = s, this._abortSignal = o, this.input = e2, this.output = i;
3912
+ }
3913
+ unsubscribe() {
3914
+ this._subscribers.clear();
3915
+ }
3916
+ setSubscriber(t, s) {
3917
+ const e2 = this._subscribers.get(t) ?? [];
3918
+ e2.push(s), this._subscribers.set(t, e2);
3919
+ }
3920
+ on(t, s) {
3921
+ this.setSubscriber(t, { cb: s });
3922
+ }
3923
+ once(t, s) {
3924
+ this.setSubscriber(t, { cb: s, once: true });
3925
+ }
3926
+ emit(t, ...s) {
3927
+ const e2 = this._subscribers.get(t) ?? [], i = [];
3928
+ for (const n of e2) n.cb(...s), n.once && i.push(() => e2.splice(e2.indexOf(n), 1));
3929
+ for (const n of i) n();
3930
+ }
3931
+ prompt() {
3932
+ return new Promise((t) => {
3933
+ if (this._abortSignal) {
3934
+ if (this._abortSignal.aborted) return this.state = "cancel", this.close(), t(k);
3935
+ this._abortSignal.addEventListener("abort", () => {
3936
+ this.state = "cancel", this.close();
3937
+ }, { once: true });
3938
+ }
3939
+ this.rl = import_node_readline.default.createInterface({ input: this.input, tabSize: 2, prompt: "", escapeCodeTimeout: 50, terminal: true }), this.rl.prompt(), this.opts.initialUserInput !== void 0 && this._setUserInput(this.opts.initialUserInput, true), this.input.on("keypress", this.onKeypress), w(this.input, true), this.output.on("resize", this.render), this.render(), this.once("submit", () => {
3940
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), w(this.input, false), t(this.value);
3941
+ }), this.once("cancel", () => {
3942
+ this.output.write(import_sisteransi.cursor.show), this.output.off("resize", this.render), w(this.input, false), t(k);
3943
+ });
3944
+ });
3945
+ }
3946
+ _isActionKey(t, s) {
3947
+ return t === " ";
3948
+ }
3949
+ _shouldSubmit(t, s) {
3950
+ return true;
3951
+ }
3952
+ _setValue(t) {
3953
+ this.value = t, this.emit("value", this.value);
3954
+ }
3955
+ _setUserInput(t, s) {
3956
+ this.userInput = t ?? "", this.emit("userInput", this.userInput), s && this._track && this.rl && (this.rl.write(this.userInput), this._cursor = this.rl.cursor);
3957
+ }
3958
+ _clearUserInput() {
3959
+ this.rl?.write(null, { ctrl: true, name: "u" }), this._setUserInput("");
3960
+ }
3961
+ onKeypress(t, s) {
3962
+ if (this._track && s.name !== "return" && (s.name && this._isActionKey(t, s) && this.rl?.write(null, { ctrl: true, name: "h" }), this._cursor = this.rl?.cursor ?? 0, this._setUserInput(this.rl?.line)), this.state === "error" && (this.state = "active"), s?.name && (!this._track && h.aliases.has(s.name) && this.emit("cursor", h.aliases.get(s.name)), h.actions.has(s.name) && this.emit("cursor", s.name)), t && (t.toLowerCase() === "y" || t.toLowerCase() === "n") && this.emit("confirm", t.toLowerCase() === "y"), this.emit("key", t?.toLowerCase(), s), s?.name === "return" && this._shouldSubmit(t, s)) {
3963
+ if (this.opts.validate) {
3964
+ const e2 = this.opts.validate(this.value);
3965
+ e2 && (this.error = e2 instanceof Error ? e2.message : e2, this.state = "error", this.rl?.write(this.userInput));
3966
+ }
3967
+ this.state !== "error" && (this.state = "submit");
3968
+ }
3969
+ C([t, s?.name, s?.sequence], "cancel") && (this.state = "cancel"), (this.state === "submit" || this.state === "cancel") && this.emit("finalize"), this.render(), (this.state === "submit" || this.state === "cancel") && this.close();
3970
+ }
3971
+ close() {
3972
+ this.input.unpipe(), this.input.removeListener("keypress", this.onKeypress), this.output.write(`
3973
+ `), w(this.input, false), this.rl?.close(), this.rl = void 0, this.emit(`${this.state}`, this.value), this.unsubscribe();
3974
+ }
3975
+ restoreCursor() {
3976
+ const t = wrapAnsi(this._prevFrame, process.stdout.columns, { hard: true, trim: false }).split(`
3977
+ `).length - 1;
3978
+ this.output.write(import_sisteransi.cursor.move(-999, t * -1));
3979
+ }
3980
+ render() {
3981
+ const t = wrapAnsi(this._render(this) ?? "", process.stdout.columns, { hard: true, trim: false });
3982
+ if (t !== this._prevFrame) {
3983
+ if (this.state === "initial") this.output.write(import_sisteransi.cursor.hide);
3984
+ else {
3985
+ const s = z(this._prevFrame, t), e2 = L(this.output);
3986
+ if (this.restoreCursor(), s) {
3987
+ const i = Math.max(0, s.numLinesAfter - e2), n = Math.max(0, s.numLinesBefore - e2);
3988
+ let o = s.lines.find((u) => u >= i);
3989
+ if (o === void 0) {
3990
+ this._prevFrame = t;
3991
+ return;
3992
+ }
3993
+ if (s.lines.length === 1) {
3994
+ this.output.write(import_sisteransi.cursor.move(0, o - n)), this.output.write(import_sisteransi.erase.lines(1));
3995
+ const u = t.split(`
3996
+ `);
3997
+ this.output.write(u[o]), this._prevFrame = t, this.output.write(import_sisteransi.cursor.move(0, u.length - o - 1));
3998
+ return;
3999
+ } else if (s.lines.length > 1) {
4000
+ if (i < n) o = i;
4001
+ else {
4002
+ const a = o - n;
4003
+ a > 0 && this.output.write(import_sisteransi.cursor.move(0, a));
4004
+ }
4005
+ this.output.write(import_sisteransi.erase.down());
4006
+ const u = t.split(`
4007
+ `).slice(o);
4008
+ this.output.write(u.join(`
4009
+ `)), this._prevFrame = t;
4010
+ return;
4011
+ }
4012
+ }
4013
+ this.output.write(import_sisteransi.erase.down());
4014
+ }
4015
+ this.output.write(t), this.state === "initial" && (this.state = "active"), this._prevFrame = t;
4016
+ }
4017
+ }
4018
+ };
4019
+ var X = class extends p {
4020
+ get cursor() {
4021
+ return this.value ? 0 : 1;
4022
+ }
4023
+ get _value() {
4024
+ return this.cursor === 0;
4025
+ }
4026
+ constructor(t) {
4027
+ super(t, false), this.value = !!t.initialValue, this.on("userInput", () => {
4028
+ this.value = this._value;
4029
+ }), this.on("confirm", (s) => {
4030
+ this.output.write(import_sisteransi.cursor.move(0, -1)), this.value = s, this.state = "submit", this.close();
4031
+ }), this.on("cursor", () => {
4032
+ this.value = !this.value;
4033
+ });
4034
+ }
4035
+ };
4036
+ var nt = class extends p {
4037
+ options;
4038
+ cursor = 0;
4039
+ get _value() {
4040
+ return this.options[this.cursor].value;
4041
+ }
4042
+ get _enabledOptions() {
4043
+ return this.options.filter((t) => t.disabled !== true);
4044
+ }
4045
+ toggleAll() {
4046
+ const t = this._enabledOptions, s = this.value !== void 0 && this.value.length === t.length;
4047
+ this.value = s ? [] : t.map((e2) => e2.value);
4048
+ }
4049
+ toggleInvert() {
4050
+ const t = this.value;
4051
+ if (!t) return;
4052
+ const s = this._enabledOptions.filter((e2) => !t.includes(e2.value));
4053
+ this.value = s.map((e2) => e2.value);
4054
+ }
4055
+ toggleValue() {
4056
+ this.value === void 0 && (this.value = []);
4057
+ const t = this.value.includes(this._value);
4058
+ this.value = t ? this.value.filter((s) => s !== this._value) : [...this.value, this._value];
4059
+ }
4060
+ constructor(t) {
4061
+ super(t, false), this.options = t.options, this.value = [...t.initialValues ?? []];
4062
+ const s = Math.max(this.options.findIndex(({ value: e2 }) => e2 === t.cursorAt), 0);
4063
+ this.cursor = this.options[s].disabled ? d(s, 1, this.options) : s, this.on("key", (e2) => {
4064
+ e2 === "a" && this.toggleAll(), e2 === "i" && this.toggleInvert();
4065
+ }), this.on("cursor", (e2) => {
4066
+ switch (e2) {
4067
+ case "left":
4068
+ case "up":
4069
+ this.cursor = d(this.cursor, -1, this.options);
4070
+ break;
4071
+ case "down":
4072
+ case "right":
4073
+ this.cursor = d(this.cursor, 1, this.options);
4074
+ break;
4075
+ case "space":
4076
+ this.toggleValue();
4077
+ break;
4078
+ }
4079
+ });
4080
+ }
4081
+ };
4082
+
4083
+ // node_modules/.pnpm/@clack+prompts@1.3.0/node_modules/@clack/prompts/dist/index.mjs
4084
+ var import_node_util = require("node:util");
4085
+ var import_node_process2 = __toESM(require("node:process"), 1);
4086
+ var import_sisteransi2 = __toESM(require_src(), 1);
4087
+ function te() {
4088
+ return import_node_process2.default.platform !== "win32" ? import_node_process2.default.env.TERM !== "linux" : !!import_node_process2.default.env.CI || !!import_node_process2.default.env.WT_SESSION || !!import_node_process2.default.env.TERMINUS_SUBLIME || import_node_process2.default.env.ConEmuTask === "{cmd::Cmder}" || import_node_process2.default.env.TERM_PROGRAM === "Terminus-Sublime" || import_node_process2.default.env.TERM_PROGRAM === "vscode" || import_node_process2.default.env.TERM === "xterm-256color" || import_node_process2.default.env.TERM === "alacritty" || import_node_process2.default.env.TERMINAL_EMULATOR === "JetBrains-JediTerm";
4089
+ }
4090
+ var tt = te();
4091
+ var w2 = (t, r) => tt ? t : r;
4092
+ var _t = w2("\u25C6", "*");
4093
+ var ot2 = w2("\u25A0", "x");
4094
+ var ut2 = w2("\u25B2", "x");
4095
+ var F = w2("\u25C7", "o");
4096
+ var lt = w2("\u250C", "T");
4097
+ var $ = w2("\u2502", "|");
4098
+ var E2 = w2("\u2514", "\u2014");
4099
+ var It = w2("\u2510", "T");
4100
+ var Et = w2("\u2518", "\u2014");
4101
+ var z2 = w2("\u25CF", ">");
4102
+ var H = w2("\u25CB", " ");
4103
+ var et2 = w2("\u25FB", "[\u2022]");
4104
+ var U = w2("\u25FC", "[+]");
4105
+ var J = w2("\u25FB", "[ ]");
4106
+ var Gt = w2("\u25AA", "\u2022");
4107
+ var st = w2("\u2500", "-");
4108
+ var ct = w2("\u256E", "+");
4109
+ var xt = w2("\u251C", "+");
4110
+ var $t = w2("\u256F", "+");
4111
+ var dt = w2("\u2570", "+");
4112
+ var Ot = w2("\u256D", "+");
4113
+ var ht2 = w2("\u25CF", "\u2022");
4114
+ var pt = w2("\u25C6", "*");
4115
+ var mt = w2("\u25B2", "!");
4116
+ var gt = w2("\u25A0", "x");
4117
+ var M = (t) => {
4118
+ switch (t) {
4119
+ case "initial":
4120
+ case "active":
4121
+ return (0, import_node_util.styleText)("cyan", _t);
4122
+ case "cancel":
4123
+ return (0, import_node_util.styleText)("red", ot2);
4124
+ case "error":
4125
+ return (0, import_node_util.styleText)("yellow", ut2);
4126
+ case "submit":
4127
+ return (0, import_node_util.styleText)("green", F);
4128
+ }
4129
+ };
4130
+ var yt = (t) => {
4131
+ switch (t) {
4132
+ case "initial":
4133
+ case "active":
4134
+ return (0, import_node_util.styleText)("cyan", $);
4135
+ case "cancel":
4136
+ return (0, import_node_util.styleText)("red", $);
4137
+ case "error":
4138
+ return (0, import_node_util.styleText)("yellow", $);
4139
+ case "submit":
4140
+ return (0, import_node_util.styleText)("green", $);
4141
+ }
4142
+ };
4143
+ var ee = (t, r, s, i, u) => {
4144
+ let n = r, o = 0;
4145
+ for (let c2 = s; c2 < i; c2++) {
4146
+ const a = t[c2];
4147
+ if (n = n - a.length, o++, n <= u) break;
4148
+ }
4149
+ return { lineCount: n, removals: o };
4150
+ };
4151
+ var Y2 = ({ cursor: t, options: r, style: s, output: i = process.stdout, maxItems: u = Number.POSITIVE_INFINITY, columnPadding: n = 0, rowPadding: o = 4 }) => {
4152
+ const c2 = A(i) - n, a = L(i), l = (0, import_node_util.styleText)("dim", "..."), d2 = Math.max(a - o, 0), y = Math.max(Math.min(u, d2), 5);
4153
+ let p2 = 0;
4154
+ t >= y - 3 && (p2 = Math.max(Math.min(t - y + 3, r.length - y), 0));
4155
+ let m = y < r.length && p2 > 0, g = y < r.length && p2 + y < r.length;
4156
+ const S2 = Math.min(p2 + y, r.length), h2 = [];
4157
+ let f = 0;
4158
+ m && f++, g && f++;
4159
+ const v = p2 + (m ? 1 : 0), T = S2 - (g ? 1 : 0);
4160
+ for (let b = v; b < T; b++) {
4161
+ const G2 = wrapAnsi(s(r[b], b === t), c2, { hard: true, trim: false }).split(`
4162
+ `);
4163
+ h2.push(G2), f += G2.length;
4164
+ }
4165
+ if (f > d2) {
4166
+ let b = 0, G2 = 0, x = f;
4167
+ const A2 = t - v, P = (N, D2) => ee(h2, x, N, D2, d2);
4168
+ m ? ({ lineCount: x, removals: b } = P(0, A2), x > d2 && ({ lineCount: x, removals: G2 } = P(A2 + 1, h2.length))) : ({ lineCount: x, removals: G2 } = P(A2 + 1, h2.length), x > d2 && ({ lineCount: x, removals: b } = P(0, A2))), b > 0 && (m = true, h2.splice(0, b)), G2 > 0 && (g = true, h2.splice(h2.length - G2, G2));
4169
+ }
4170
+ const C2 = [];
4171
+ m && C2.push(l);
4172
+ for (const b of h2) for (const G2 of b) C2.push(G2);
4173
+ return g && C2.push(l), C2;
4174
+ };
4175
+ var ue = (t) => {
4176
+ const r = t.active ?? "Yes", s = t.inactive ?? "No";
4177
+ return new X({ active: r, inactive: s, signal: t.signal, input: t.input, output: t.output, initialValue: t.initialValue ?? true, render() {
4178
+ const i = t.withGuide ?? h.withGuide, u = `${M(this.state)} `, n = i ? `${(0, import_node_util.styleText)("gray", $)} ` : "", o = W(t.output, t.message, n, u), c2 = `${i ? `${(0, import_node_util.styleText)("gray", $)}
4179
+ ` : ""}${o}
4180
+ `, a = this.value ? r : s;
4181
+ switch (this.state) {
4182
+ case "submit": {
4183
+ const l = i ? `${(0, import_node_util.styleText)("gray", $)} ` : "";
4184
+ return `${c2}${l}${(0, import_node_util.styleText)("dim", a)}`;
4185
+ }
4186
+ case "cancel": {
4187
+ const l = i ? `${(0, import_node_util.styleText)("gray", $)} ` : "";
4188
+ return `${c2}${l}${(0, import_node_util.styleText)(["strikethrough", "dim"], a)}${i ? `
4189
+ ${(0, import_node_util.styleText)("gray", $)}` : ""}`;
4190
+ }
4191
+ default: {
4192
+ const l = i ? `${(0, import_node_util.styleText)("cyan", $)} ` : "", d2 = i ? (0, import_node_util.styleText)("cyan", E2) : "";
4193
+ return `${c2}${l}${this.value ? `${(0, import_node_util.styleText)("green", z2)} ${r}` : `${(0, import_node_util.styleText)("dim", H)} ${(0, import_node_util.styleText)("dim", r)}`}${t.vertical ? i ? `
4194
+ ${(0, import_node_util.styleText)("cyan", $)} ` : `
4195
+ ` : ` ${(0, import_node_util.styleText)("dim", "/")} `}${this.value ? `${(0, import_node_util.styleText)("dim", H)} ${(0, import_node_util.styleText)("dim", s)}` : `${(0, import_node_util.styleText)("green", z2)} ${s}`}
4196
+ ${d2}
4197
+ `;
4198
+ }
4199
+ }
4200
+ } }).prompt();
4201
+ };
4202
+ var me = (t = "", r) => {
4203
+ const s = r?.output ?? process.stdout, i = r?.withGuide ?? h.withGuide ? `${(0, import_node_util.styleText)("gray", E2)} ` : "";
4204
+ s.write(`${i}${(0, import_node_util.styleText)("red", t)}
4205
+
4206
+ `);
4207
+ };
4208
+ var ge = (t = "", r) => {
4209
+ const s = r?.output ?? process.stdout, i = r?.withGuide ?? h.withGuide ? `${(0, import_node_util.styleText)("gray", lt)} ` : "";
4210
+ s.write(`${i}${t}
4211
+ `);
4212
+ };
4213
+ var ye = (t = "", r) => {
4214
+ const s = r?.output ?? process.stdout, i = r?.withGuide ?? h.withGuide ? `${(0, import_node_util.styleText)("gray", $)}
4215
+ ${(0, import_node_util.styleText)("gray", E2)} ` : "";
4216
+ s.write(`${i}${t}
4217
+
4218
+ `);
4219
+ };
4220
+ var Q2 = (t, r) => t.split(`
4221
+ `).map((s) => r(s)).join(`
4222
+ `);
4223
+ var ve = (t) => {
4224
+ const r = (i, u) => {
4225
+ const n = i.label ?? String(i.value);
4226
+ return u === "disabled" ? `${(0, import_node_util.styleText)("gray", J)} ${Q2(n, (o) => (0, import_node_util.styleText)(["strikethrough", "gray"], o))}${i.hint ? ` ${(0, import_node_util.styleText)("dim", `(${i.hint ?? "disabled"})`)}` : ""}` : u === "active" ? `${(0, import_node_util.styleText)("cyan", et2)} ${n}${i.hint ? ` ${(0, import_node_util.styleText)("dim", `(${i.hint})`)}` : ""}` : u === "selected" ? `${(0, import_node_util.styleText)("green", U)} ${Q2(n, (o) => (0, import_node_util.styleText)("dim", o))}${i.hint ? ` ${(0, import_node_util.styleText)("dim", `(${i.hint})`)}` : ""}` : u === "cancelled" ? `${Q2(n, (o) => (0, import_node_util.styleText)(["strikethrough", "dim"], o))}` : u === "active-selected" ? `${(0, import_node_util.styleText)("green", U)} ${n}${i.hint ? ` ${(0, import_node_util.styleText)("dim", `(${i.hint})`)}` : ""}` : u === "submitted" ? `${Q2(n, (o) => (0, import_node_util.styleText)("dim", o))}` : `${(0, import_node_util.styleText)("dim", J)} ${Q2(n, (o) => (0, import_node_util.styleText)("dim", o))}`;
4227
+ }, s = t.required ?? true;
4228
+ return new nt({ options: t.options, signal: t.signal, input: t.input, output: t.output, initialValues: t.initialValues, required: s, cursorAt: t.cursorAt, validate(i) {
4229
+ if (s && (i === void 0 || i.length === 0)) return `Please select at least one option.
4230
+ ${(0, import_node_util.styleText)("reset", (0, import_node_util.styleText)("dim", `Press ${(0, import_node_util.styleText)(["gray", "bgWhite", "inverse"], " space ")} to select, ${(0, import_node_util.styleText)("gray", (0, import_node_util.styleText)("bgWhite", (0, import_node_util.styleText)("inverse", " enter ")))} to submit`))}`;
4231
+ }, render() {
4232
+ const i = t.withGuide ?? h.withGuide, u = W(t.output, t.message, i ? `${yt(this.state)} ` : "", `${M(this.state)} `), n = `${i ? `${(0, import_node_util.styleText)("gray", $)}
4233
+ ` : ""}${u}
4234
+ `, o = this.value ?? [], c2 = (a, l) => {
4235
+ if (a.disabled) return r(a, "disabled");
4236
+ const d2 = o.includes(a.value);
4237
+ return l && d2 ? r(a, "active-selected") : d2 ? r(a, "selected") : r(a, l ? "active" : "inactive");
4238
+ };
4239
+ switch (this.state) {
4240
+ case "submit": {
4241
+ const a = this.options.filter(({ value: d2 }) => o.includes(d2)).map((d2) => r(d2, "submitted")).join((0, import_node_util.styleText)("dim", ", ")) || (0, import_node_util.styleText)("dim", "none"), l = W(t.output, a, i ? `${(0, import_node_util.styleText)("gray", $)} ` : "");
4242
+ return `${n}${l}`;
4243
+ }
4244
+ case "cancel": {
4245
+ const a = this.options.filter(({ value: d2 }) => o.includes(d2)).map((d2) => r(d2, "cancelled")).join((0, import_node_util.styleText)("dim", ", "));
4246
+ if (a.trim() === "") return `${n}${(0, import_node_util.styleText)("gray", $)}`;
4247
+ const l = W(t.output, a, i ? `${(0, import_node_util.styleText)("gray", $)} ` : "");
4248
+ return `${n}${l}${i ? `
4249
+ ${(0, import_node_util.styleText)("gray", $)}` : ""}`;
4250
+ }
4251
+ case "error": {
4252
+ const a = i ? `${(0, import_node_util.styleText)("yellow", $)} ` : "", l = this.error.split(`
4253
+ `).map((p2, m) => m === 0 ? `${i ? `${(0, import_node_util.styleText)("yellow", E2)} ` : ""}${(0, import_node_util.styleText)("yellow", p2)}` : ` ${p2}`).join(`
4254
+ `), d2 = n.split(`
4255
+ `).length, y = l.split(`
4256
+ `).length + 1;
4257
+ return `${n}${a}${Y2({ output: t.output, options: this.options, cursor: this.cursor, maxItems: t.maxItems, columnPadding: a.length, rowPadding: d2 + y, style: c2 }).join(`
4258
+ ${a}`)}
4259
+ ${l}
4260
+ `;
4261
+ }
4262
+ default: {
4263
+ const a = i ? `${(0, import_node_util.styleText)("cyan", $)} ` : "", l = n.split(`
4264
+ `).length, d2 = i ? 2 : 1;
4265
+ return `${n}${a}${Y2({ output: t.output, options: this.options, cursor: this.cursor, maxItems: t.maxItems, columnPadding: a.length, rowPadding: l + d2, style: c2 }).join(`
4266
+ ${a}`)}
4267
+ ${i ? (0, import_node_util.styleText)("cyan", E2) : ""}
4268
+ `;
4269
+ }
4270
+ }
4271
+ } }).prompt();
4272
+ };
4273
+ var Vt = { light: w2("\u2500", "-"), heavy: w2("\u2501", "="), block: w2("\u2588", "#") };
4274
+ var jt = `${(0, import_node_util.styleText)("gray", $)} `;
4275
+
2811
4276
  // src/index.ts
2812
4277
  var import_child_process = require("child_process");
2813
- var import_promises = require("fs/promises");
2814
4278
 
2815
- // node_modules/commander/esm.mjs
4279
+ // node_modules/.pnpm/commander@14.0.3/node_modules/commander/esm.mjs
2816
4280
  var import_index = __toESM(require_commander(), 1);
2817
4281
  var {
2818
4282
  program,
@@ -2829,28 +4293,53 @@ var {
2829
4293
  Help
2830
4294
  } = import_index.default;
2831
4295
 
4296
+ // src/index.ts
4297
+ var import_promises = require("fs/promises");
4298
+ var import_path = __toESM(require("path"));
4299
+
2832
4300
  // src/eslintConfig.json
2833
4301
  var eslintConfig_default = {
2834
4302
  extends: "@bharper7/eslint-config"
2835
4303
  };
2836
4304
 
2837
4305
  // src/index.ts
4306
+ var DOTFILES_OWNER = "bharper77";
4307
+ var DOTFILES_REPO = "dotfiles";
4308
+ var SKILLS_PATH = ".agents/skills";
2838
4309
  var program2 = new Command();
2839
4310
  program2.command("init").option("-d, --directory <directory>", "Directory name for project").action(init);
4311
+ var skillsCmd = new Command("skills").description(
4312
+ "Manage agent skills from dotfiles"
4313
+ );
4314
+ skillsCmd.addCommand(
4315
+ new Command("list").description("List available skills from dotfiles").action(listSkills)
4316
+ );
4317
+ skillsCmd.addCommand(
4318
+ new Command("add").description("Download one or more skills into .agents/skills/").argument(
4319
+ "[skill]",
4320
+ "Skill name to download directly (omit for interactive picker)"
4321
+ ).action(addSkill)
4322
+ );
4323
+ program2.addCommand(skillsCmd);
2840
4324
  program2.parseAsync(process.argv);
2841
4325
  async function init(opts) {
2842
- exec(`mkdir ${opts.directory}`);
2843
- exec("mkdir src", opts.directory);
2844
- exec("new-item index.ts", `${opts.directory}/src`);
2845
- exec("git init", opts.directory);
2846
- exec("echo 'node_modules' 'dist' > .gitignore", opts.directory);
2847
- exec("npm init -y", opts.directory);
2848
- const packageJson = JSON.parse((await (0, import_promises.readFile)(`${opts.directory}/package.json`)).toString());
4326
+ exec2(`mkdir ${opts.directory}`);
4327
+ exec2("mkdir src", opts.directory);
4328
+ exec2("new-item index.ts", `${opts.directory}/src`);
4329
+ exec2("git init", opts.directory);
4330
+ exec2("echo 'node_modules' 'dist' > .gitignore", opts.directory);
4331
+ exec2("npm init -y", opts.directory);
4332
+ const packageJson = JSON.parse(
4333
+ (await (0, import_promises.readFile)(`${opts.directory}/package.json`)).toString()
4334
+ );
2849
4335
  packageJson.scripts = {
2850
- "start": "node src/index.js",
2851
- "build": "tsc"
4336
+ start: "node src/index.js",
4337
+ build: "tsc"
2852
4338
  };
2853
- await (0, import_promises.writeFile)(`${opts.directory}/package.json`, JSON.stringify(packageJson, null, 2));
4339
+ await (0, import_promises.writeFile)(
4340
+ `${opts.directory}/package.json`,
4341
+ JSON.stringify(packageJson, null, 2)
4342
+ );
2854
4343
  const devDependencies = [
2855
4344
  "typescript",
2856
4345
  "@types/node",
@@ -2860,12 +4349,105 @@ async function init(opts) {
2860
4349
  "@typescript-eslint/eslint-plugin",
2861
4350
  "eslint-plugin-import"
2862
4351
  ].join(" ");
2863
- exec(`npm i -D ${devDependencies}`, opts.directory);
2864
- exec("tsc --init", opts.directory);
2865
- await (0, import_promises.writeFile)(`${opts.directory}/.eslintrc.json`, JSON.stringify(eslintConfig_default));
2866
- exec("echo 'node_modules' 'dist' > .eslintignore", opts.directory);
4352
+ exec2(`npm i -D ${devDependencies}`, opts.directory);
4353
+ exec2("tsc --init", opts.directory);
4354
+ await (0, import_promises.writeFile)(
4355
+ `${opts.directory}/.eslintrc.json`,
4356
+ JSON.stringify(eslintConfig_default)
4357
+ );
4358
+ exec2("echo 'node_modules' 'dist' > .eslintignore", opts.directory);
4359
+ }
4360
+ async function listSkills() {
4361
+ await ensureGhAuth();
4362
+ const entries = fetchGhJson(
4363
+ `repos/${DOTFILES_OWNER}/${DOTFILES_REPO}/contents/${SKILLS_PATH}`
4364
+ );
4365
+ const skills = entries.filter((e2) => e2.type === "dir").map((e2) => e2.name);
4366
+ if (skills.length === 0) {
4367
+ console.log("No skills found.");
4368
+ return;
4369
+ }
4370
+ console.log("Available skills:");
4371
+ for (const skill of skills) {
4372
+ console.log(` \u2022 ${skill}`);
4373
+ }
4374
+ }
4375
+ async function addSkill(skill) {
4376
+ await ensureGhAuth();
4377
+ if (skill) {
4378
+ await downloadSkill(skill);
4379
+ } else {
4380
+ const entries = fetchGhJson(
4381
+ `repos/${DOTFILES_OWNER}/${DOTFILES_REPO}/contents/${SKILLS_PATH}`
4382
+ );
4383
+ const skills = entries.filter((e2) => e2.type === "dir").map((e2) => e2.name);
4384
+ if (skills.length === 0) {
4385
+ console.log("No skills available.");
4386
+ return;
4387
+ }
4388
+ ge("brady skills add");
4389
+ const selected = await ve({
4390
+ message: "Select skills to download (space = toggle, enter = confirm):",
4391
+ options: skills.map((s) => ({ value: s, label: s })),
4392
+ required: true
4393
+ });
4394
+ if (q(selected)) {
4395
+ me("Cancelled.");
4396
+ process.exit(0);
4397
+ }
4398
+ const chosen = selected;
4399
+ for (const s of chosen) {
4400
+ await downloadSkill(s);
4401
+ }
4402
+ ye(`Downloaded ${chosen.length} skill(s).`);
4403
+ }
4404
+ }
4405
+ async function ensureGhAuth() {
4406
+ try {
4407
+ (0, import_child_process.execSync)("gh auth status", { stdio: "pipe" });
4408
+ } catch {
4409
+ ge("GitHub authentication required");
4410
+ const answer = await ue({
4411
+ message: "You are not authenticated with GitHub CLI. Run `gh auth login` now?"
4412
+ });
4413
+ if (q(answer) || !answer) {
4414
+ console.error(
4415
+ "Error: Not authenticated. Run `gh auth login` to authenticate, then retry."
4416
+ );
4417
+ process.exit(1);
4418
+ }
4419
+ const result = (0, import_child_process.spawnSync)("gh", ["auth", "login"], {
4420
+ stdio: "inherit",
4421
+ shell: "powershell.exe"
4422
+ });
4423
+ if (result.status !== 0) {
4424
+ console.error(
4425
+ "Authentication failed. Run `gh auth login` to authenticate, then retry."
4426
+ );
4427
+ process.exit(1);
4428
+ }
4429
+ }
4430
+ }
4431
+ function fetchGhJson(apiPath) {
4432
+ const output = (0, import_child_process.execSync)(`gh api ${apiPath}`, { encoding: "utf-8" });
4433
+ return JSON.parse(output);
4434
+ }
4435
+ async function downloadSkill(skillName) {
4436
+ const apiPath = `repos/${DOTFILES_OWNER}/${DOTFILES_REPO}/contents/${SKILLS_PATH}/${skillName}`;
4437
+ const files = fetchGhJson(apiPath);
4438
+ const destDir = import_path.default.join(process.cwd(), SKILLS_PATH, skillName);
4439
+ await (0, import_promises.mkdir)(destDir, { recursive: true });
4440
+ for (const file of files) {
4441
+ if (file.type !== "file") continue;
4442
+ const fileEntry = fetchGhJson(
4443
+ `repos/${DOTFILES_OWNER}/${DOTFILES_REPO}/contents/${SKILLS_PATH}/${skillName}/${file.name}`
4444
+ );
4445
+ const content = Buffer.from(fileEntry.content, "base64").toString("utf-8");
4446
+ await (0, import_promises.writeFile)(import_path.default.join(destDir, file.name), content, "utf-8");
4447
+ }
4448
+ console.log(`\u2713 Downloaded skill: ${skillName}`);
2867
4449
  }
2868
- function exec(command, cwd) {
4450
+ function exec2(command, cwd) {
2869
4451
  return (0, import_child_process.execSync)(command, {
2870
4452
  cwd,
2871
4453
  shell: "powershell.exe"