auto-mode 1.0.1 → 2.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli.js CHANGED
@@ -1,11 +1,2570 @@
1
1
  #!/usr/bin/env node
2
- import { C as resolveXDGDir, D as string, E as strictObject, S as CLI_LIMITS, T as number, _ as findGitEntry, a as EMPTY_SESSION_SCOPE, b as readHostEnvironment, c as loadPolicy, d as writeActionDiagnostic, f as toRepositorySlug, g as findCheckout, h as isUnresolvedWord, i as loadSessionScope, l as resolveShippedPolicyDir, m as resolveShellPath, n as classifyAction, o as splitGitCommand, p as collectShellCommands, r as resolveSessionScopePath, s as M, t as parseActionRequest, u as loadCheckoutFacts, v as DEFAULT_SCOPE_SOURCES, w as updateJSONFile, x as runCapped, y as loadConfig } from "./parse-action-request-BfkmQxEC.js";
3
- import { randomUUID } from "node:crypto";
2
+ import { C as pickJudgeLane, E as updateJSONFile, S as CLI_LIMITS, T as resolveXDGDir, _ as findCheckout, a as resolveSessionScopePath, b as loadConfig, c as splitGitCommand, d as loadCheckoutFacts, f as writeActionDiagnostic, g as isUnresolvedWord, h as resolveShellPath, i as classifyAction, l as loadPolicy, m as collectShellCommands, n as readRuntime, o as loadSessionScope, p as toRepositorySlug, s as EMPTY_SESSION_SCOPE, t as parseActionRequest, u as resolveShippedPolicyDir, v as findGitEntry, w as M, x as runCapped, y as DEFAULT_SCOPE_SOURCES } from "./parse-action-request-neI2tNwd.js";
3
+ import { a as literal, d as string, i as discriminatedUnion, r as boolean, s as number, u as strictObject } from "./schemas-Dc2424NY.js";
4
+ import { createHash, randomUUID } from "node:crypto";
4
5
  import { chmod, mkdir, open, readFile, realpath, stat } from "node:fs/promises";
5
6
  import { basename, dirname, isAbsolute, join, resolve } from "node:path";
6
- import { constants, existsSync } from "node:fs";
7
+ import { setTimeout } from "node:timers/promises";
8
+ import { spawn } from "node:child_process";
9
+ import { constants, existsSync, statSync } from "node:fs";
7
10
  import { text } from "node:stream/consumers";
8
- import { parseArgs } from "node:util";
11
+ import { connect } from "node:net";
12
+ //#region node_modules/.bun/gunshi@1.0.0-rc.1/node_modules/gunshi/lib/utils-D-MmF6sM.js
13
+ /**
14
+ * Entry point of utils.
15
+ *
16
+ * Note that this entry point is used by gunshi to import utility functions.
17
+ *
18
+ * @module
19
+ */
20
+ /**
21
+ * @author kazuya kawaguchi (a.k.a. kazupon)
22
+ * @license MIT
23
+ */
24
+ /**
25
+ * Convert a string to kebab-case.
26
+ *
27
+ * @param str - A string to convert
28
+ * @returns Converted string into kebab-case.
29
+ */
30
+ function kebabnize(str) {
31
+ return str.replace(/[A-Z]/g, (match, offset) => (offset > 0 ? "-" : "") + match.toLowerCase());
32
+ }
33
+ /**
34
+ * Format allowed argument choices for validation error values and fallback messages.
35
+ *
36
+ * @param choices - Choice values to format
37
+ * @returns JSON-quoted choices joined with `, `.
38
+ */
39
+ function formatChoices(choices) {
40
+ return choices.map((value) => JSON.stringify(value)).join(", ");
41
+ }
42
+ //#endregion
43
+ //#region node_modules/.bun/gunshi@1.0.0-rc.1/node_modules/gunshi/lib/utils.js
44
+ /**
45
+ * @author kazuya kawaguchi (a.k.a. kazupon)
46
+ * @license MIT
47
+ */
48
+ /**
49
+ * Check if the given command is a {@link LazyCommand}.
50
+ *
51
+ * @param cmd - A command to check
52
+ * @returns `true` if the command is a {@link LazyCommand}, otherwise `false`
53
+ *
54
+ * A lazy command is identified by its `commandName` property. The property may be
55
+ * `undefined` when the lazy command has no definition name.
56
+ */
57
+ function isLazyCommand(cmd) {
58
+ return typeof cmd === "function" && "commandName" in cmd;
59
+ }
60
+ /**
61
+ * Resolve a lazy command to a {@link Command}.
62
+ *
63
+ * If the loader returns a command, the properties of the loaded command take precedence,
64
+ * and the properties that it does not define fall back to the definition that is given to `lazy`.
65
+ *
66
+ * @param cmd - A {@link Commandable} or {@link LazyCommand} to resolve
67
+ * @param name - Optional name of the command, if not provided, it will use the name from the command itself.
68
+ * @param needRunResolving - Whether to run the resolving function of the lazy command.
69
+ * @returns A resolved {@link Command}
70
+ */
71
+ async function resolveLazyCommand(cmd, name, needRunResolving = false) {
72
+ let command;
73
+ if (isLazyCommand(cmd)) {
74
+ const baseCommand = {
75
+ name: cmd.commandName,
76
+ description: cmd.description,
77
+ args: cmd.args,
78
+ examples: cmd.examples,
79
+ internal: cmd.internal,
80
+ entry: cmd.entry,
81
+ toKebab: cmd.toKebab,
82
+ rendering: cmd.rendering,
83
+ subCommands: cmd.subCommands
84
+ };
85
+ if ("resource" in cmd && cmd.resource) baseCommand.resource = cmd.resource;
86
+ command = Object.assign(create(), baseCommand);
87
+ if (needRunResolving) {
88
+ const loaded = await cmd();
89
+ if (typeof loaded === "function") command.run = loaded;
90
+ else if (typeof loaded === "object") {
91
+ if (loaded.run == null) throw new TypeError(`'run' is required in command: ${cmd.name || name}`);
92
+ /**
93
+ * NOTE(kazupon): the loaded command wins, and the definition that is given to `lazy` is the fallback
94
+ * for what the loaded command does not define. A loader that returns `{ run }` keeps the whole definition,
95
+ * like a loader that returns the runner itself.
96
+ */
97
+ command.run = loaded.run;
98
+ command.name = loaded.name ?? cmd.commandName;
99
+ command.description = loaded.description ?? cmd.description;
100
+ command.args = loaded.args ?? cmd.args;
101
+ command.examples = loaded.examples ?? cmd.examples;
102
+ command.internal = loaded.internal ?? cmd.internal;
103
+ command.entry = loaded.entry ?? cmd.entry;
104
+ command.toKebab = loaded.toKebab ?? cmd.toKebab;
105
+ command.rendering = loaded.rendering ?? cmd.rendering;
106
+ command.subCommands = loaded.subCommands || cmd.subCommands;
107
+ if ("resource" in loaded && loaded.resource) command.resource = loaded.resource;
108
+ } else throw new TypeError(`Cannot resolve command: ${cmd.name || name}`);
109
+ }
110
+ } else command = Object.assign(create(), cmd);
111
+ if (command.name == null && name) command.name = name;
112
+ return deepFreeze(command);
113
+ }
114
+ /**
115
+ * Create an object with the specified prototype. A shorthand for `Object.create`.
116
+ *
117
+ * @param obj - An object to use as the prototype for the new object. If `null`, it will create an object with no prototype.
118
+ * @returns A new object with the specified prototype
119
+ */
120
+ function create(obj = null) {
121
+ return Object.create(obj);
122
+ }
123
+ /**
124
+ * Log a message to the console.
125
+ *
126
+ * @param args - Arguments to log
127
+ */
128
+ function log(...args) {
129
+ console.log(...args);
130
+ }
131
+ /**
132
+ * Get the sub-commands of a command as a normalized Map.
133
+ *
134
+ * @param cmd - A command or lazy command
135
+ * @returns A Map of sub-commands, or undefined if the command has no sub-commands.
136
+ */
137
+ function getCommandSubCommands(cmd) {
138
+ const subCommands = isLazyCommand(cmd) ? cmd.subCommands : typeof cmd === "object" ? cmd.subCommands : void 0;
139
+ if (!subCommands) return;
140
+ if (subCommands instanceof Map) return subCommands.size > 0 ? subCommands : void 0;
141
+ if (typeof subCommands === "object") {
142
+ const entries = Object.entries(subCommands);
143
+ if (entries.length === 0) return;
144
+ const map = /* @__PURE__ */ new Map();
145
+ for (const [name, cmd] of entries) map.set(name, cmd);
146
+ return map;
147
+ }
148
+ }
149
+ /**
150
+ * Deep freeze an object, making it immutable.
151
+ *
152
+ * @param obj - The object to freeze
153
+ * @param ignores - Properties to ignore during freezing
154
+ * @returns A frozen object
155
+ */
156
+ function deepFreeze(obj, ignores = []) {
157
+ if (obj === null || typeof obj !== "object") return obj;
158
+ for (const key of Object.keys(obj)) {
159
+ const value = obj[key];
160
+ if (ignores.includes(key)) continue;
161
+ if (typeof value === "object" && value !== null) deepFreeze(value, ignores);
162
+ }
163
+ return Object.freeze(obj);
164
+ }
165
+ //#endregion
166
+ //#region node_modules/.bun/gunshi@1.0.0-rc.1/node_modules/gunshi/lib/context-CSecf6R5.js
167
+ /**
168
+ * @author kazuya kawaguchi (a.k.a. kazupon)
169
+ * @license MIT
170
+ */
171
+ const ANONYMOUS_COMMAND_NAME = "(anonymous)";
172
+ /**
173
+ * A no-operation function.
174
+ */
175
+ const NOOP = () => {};
176
+ const CLI_OPTIONS_DEFAULT = {
177
+ name: void 0,
178
+ description: void 0,
179
+ version: void 0,
180
+ cwd: void 0,
181
+ usageSilent: false,
182
+ subCommands: void 0,
183
+ leftMargin: 2,
184
+ middleMargin: 10,
185
+ usageOptionType: false,
186
+ usageOptionValue: true,
187
+ strict: false,
188
+ renderHeader: void 0,
189
+ renderUsage: void 0,
190
+ renderValidationErrors: void 0,
191
+ plugins: void 0,
192
+ fallbackToEntry: false
193
+ };
194
+ /**
195
+ * The entry for gunshi context.
196
+ * This module is exported for the purpose of testing the command.
197
+ *
198
+ * @example
199
+ * ```js
200
+ * import { createCommandContext } from 'gunshi/context'
201
+ * ```
202
+ *
203
+ * @module
204
+ */
205
+ /**
206
+ * @author kazuya kawaguchi (a.k.a. kazupon)
207
+ * @license MIT
208
+ */
209
+ /**
210
+ * Create a command context.
211
+ *
212
+ * @param param - A {@link CommandContextParams | parameters} to create a command context.
213
+ * @returns A {@link CommandContext | command context}, which is readonly.
214
+ */
215
+ async function createCommandContext({ args = {}, explicit = {}, values = {}, positionals = [], rest = [], argv = [], tokens = [], command = {}, extensions = {}, cliOptions = {}, callMode = "entry", commandPath = [], omitted = false, validationError }) {
216
+ /**
217
+ * normailize the options schema and values, to avoid prototype pollution
218
+ */
219
+ const _args = Object.entries(args).reduce((acc, [key, value]) => {
220
+ acc[key] = Object.assign(create(), value);
221
+ return acc;
222
+ }, create());
223
+ /**
224
+ * setup the environment
225
+ */
226
+ const env = Object.assign(create(), CLI_OPTIONS_DEFAULT, cliOptions);
227
+ /**
228
+ * apply Command definition's rendering option with highest priority
229
+ */
230
+ if (command.rendering) {
231
+ const { header, usage, validationErrors } = command.rendering;
232
+ if (header !== void 0) env.renderHeader = header;
233
+ if (usage !== void 0) env.renderUsage = usage;
234
+ if (validationErrors !== void 0) env.renderValidationErrors = validationErrors;
235
+ }
236
+ /**
237
+ * create the command context
238
+ */
239
+ const core = Object.assign(create(), {
240
+ name: getCommandName(command),
241
+ description: command.description,
242
+ omitted,
243
+ callMode,
244
+ commandPath,
245
+ env,
246
+ args: _args,
247
+ explicit,
248
+ values,
249
+ positionals,
250
+ rest,
251
+ _: argv,
252
+ tokens,
253
+ toKebab: command.toKebab,
254
+ log: cliOptions.usageSilent ? NOOP : log,
255
+ validationError
256
+ });
257
+ /**
258
+ * extend the command context with extensions
259
+ */
260
+ if (Object.keys(extensions).length > 0) {
261
+ const ext = create(null);
262
+ Object.defineProperty(core, "extensions", {
263
+ value: ext,
264
+ writable: false,
265
+ enumerable: true,
266
+ configurable: true
267
+ });
268
+ for (const [key, extension] of Object.entries(extensions)) {
269
+ ext[key] = await extension.factory(core, command);
270
+ if (extension.onFactory) await extension.onFactory(core, command);
271
+ }
272
+ }
273
+ return deepFreeze(core, ["extensions", "entryCommand"]);
274
+ }
275
+ function getCommandName(cmd) {
276
+ if (isLazyCommand(cmd)) return cmd.commandName || cmd.name || "(anonymous)";
277
+ else if (typeof cmd === "object") return cmd.name || "(anonymous)";
278
+ else return ANONYMOUS_COMMAND_NAME;
279
+ }
280
+ //#endregion
281
+ //#region node_modules/.bun/gunshi@1.0.0-rc.1/node_modules/gunshi/lib/resolver-CAlgxe_R-3pz9PVFu.js
282
+ /**
283
+ * forked from `nodejs/node` (`pkgjs/parseargs`)
284
+ * repository url: https://github.com/nodejs/node (https://github.com/pkgjs/parseargs)
285
+ * code url: https://github.com/nodejs/node/blob/main/lib/internal/util/parse_args/parse_args.js
286
+ *
287
+ * @author kazuya kawaguchi (a.k.a. kazupon)
288
+ * @license MIT
289
+ */
290
+ const HYPHEN_CHAR = "-";
291
+ const HYPHEN_CODE = HYPHEN_CHAR.codePointAt(0);
292
+ const EQUAL_CHAR = "=";
293
+ const EQUAL_CODE = EQUAL_CHAR.codePointAt(0);
294
+ const TERMINATOR = "--";
295
+ const SHORT_OPTION_PREFIX = HYPHEN_CHAR;
296
+ const LONG_OPTION_PREFIX = "--";
297
+ /**
298
+ * Parse command line arguments.
299
+ *
300
+ * @param args - command line arguments
301
+ * @param options - parse options, about details see {@link ParserOptions}
302
+ * @returns Argument tokens.
303
+ *
304
+ * @example
305
+ * ```js
306
+ * import { parseArgs } from 'args-tokens' // for Node.js and Bun
307
+ * // import { parseArgs } from 'jsr:@kazupon/args-tokens' // for Deno
308
+ *
309
+ * const tokens = parseArgs(['--foo', 'bar', '-x', '--bar=baz'])
310
+ * // do something with using tokens
311
+ * // ...
312
+ * console.log('tokens:', tokens)
313
+ * ```
314
+ */
315
+ function parseArgs(args, options = {}) {
316
+ const { allowCompatible = false } = options;
317
+ const tokens = [];
318
+ const remainings = [...args];
319
+ let index = -1;
320
+ let groupCount = 0;
321
+ let hasShortGroupValue = false;
322
+ let shortGroupValueInline = true;
323
+ while (remainings.length > 0) {
324
+ const arg = remainings.shift();
325
+ if (arg == void 0) break;
326
+ if (groupCount > 0) groupCount--;
327
+ else index++;
328
+ if (arg === TERMINATOR) {
329
+ tokens.push({
330
+ kind: "option-terminator",
331
+ index
332
+ });
333
+ const mapped = remainings.map((arg) => {
334
+ return {
335
+ kind: "positional",
336
+ index: ++index,
337
+ value: arg
338
+ };
339
+ });
340
+ tokens.push(...mapped);
341
+ break;
342
+ }
343
+ if (isShortOption(arg)) {
344
+ const shortOption = arg.charAt(1);
345
+ let value;
346
+ let inlineValue;
347
+ if (groupCount) {
348
+ tokens.push({
349
+ kind: "option",
350
+ name: shortOption,
351
+ rawName: arg,
352
+ index,
353
+ value,
354
+ inlineValue
355
+ });
356
+ if (groupCount === 1 && hasShortGroupValue) {
357
+ value = remainings.shift();
358
+ inlineValue = shortGroupValueInline;
359
+ hasShortGroupValue = false;
360
+ tokens.push({
361
+ kind: "option",
362
+ index,
363
+ value,
364
+ inlineValue
365
+ });
366
+ }
367
+ } else tokens.push({
368
+ kind: "option",
369
+ name: shortOption,
370
+ rawName: arg,
371
+ index,
372
+ value,
373
+ inlineValue
374
+ });
375
+ if (value != null) ++index;
376
+ continue;
377
+ }
378
+ if (isShortOptionGroup(arg)) {
379
+ const expanded = [];
380
+ let separated = false;
381
+ let dashed = false;
382
+ let shortValue = "";
383
+ for (let i = 1; i < arg.length; i++) {
384
+ const shortableOption = arg.charAt(i);
385
+ if (separated) shortValue += shortableOption;
386
+ else if (!allowCompatible && shortableOption.codePointAt(0) === EQUAL_CODE && expanded.length > 0) separated = true;
387
+ else if (!allowCompatible && shortableOption.codePointAt(0) === HYPHEN_CODE) {
388
+ separated = true;
389
+ dashed = true;
390
+ shortValue += shortableOption;
391
+ } else expanded.push(`${SHORT_OPTION_PREFIX}${shortableOption}`);
392
+ }
393
+ hasShortGroupValue = separated;
394
+ shortGroupValueInline = !dashed;
395
+ if (separated) expanded.push(shortValue);
396
+ remainings.unshift(...expanded);
397
+ groupCount = expanded.length;
398
+ continue;
399
+ }
400
+ if (isLongOption(arg)) {
401
+ const longOption = arg.slice(2);
402
+ tokens.push({
403
+ kind: "option",
404
+ name: longOption,
405
+ rawName: arg,
406
+ index,
407
+ value: void 0,
408
+ inlineValue: void 0
409
+ });
410
+ continue;
411
+ }
412
+ if (isLongOptionAndValue(arg)) {
413
+ const equalIndex = arg.indexOf(EQUAL_CHAR);
414
+ const longOption = arg.slice(2, equalIndex);
415
+ const value = arg.slice(equalIndex + 1);
416
+ tokens.push({
417
+ kind: "option",
418
+ name: longOption,
419
+ rawName: `${LONG_OPTION_PREFIX}${longOption}`,
420
+ index,
421
+ value,
422
+ inlineValue: true
423
+ });
424
+ continue;
425
+ }
426
+ tokens.push({
427
+ kind: "positional",
428
+ index,
429
+ value: arg
430
+ });
431
+ }
432
+ return tokens;
433
+ }
434
+ /**
435
+ * Check if `arg` is a short option (e.g. `-f`).
436
+ *
437
+ * @param arg - An argument to check
438
+ * @returns Whether `arg` is a short option.
439
+ */
440
+ function isShortOption(arg) {
441
+ return arg.length === 2 && arg.codePointAt(0) === HYPHEN_CODE && arg.codePointAt(1) !== HYPHEN_CODE;
442
+ }
443
+ /**
444
+ * Check if `arg` is a short option group (e.g. `-abc`).
445
+ *
446
+ * @param arg - An argument to check
447
+ * @returns Whether `arg` is a short option group.
448
+ */
449
+ function isShortOptionGroup(arg) {
450
+ if (arg.length <= 2) return false;
451
+ if (arg.codePointAt(0) !== HYPHEN_CODE) return false;
452
+ if (arg.codePointAt(1) === HYPHEN_CODE) return false;
453
+ return true;
454
+ }
455
+ /**
456
+ * Check if `arg` is a long option (e.g. `--foo`).
457
+ *
458
+ * @param arg - An argument to check
459
+ * @returns Whether `arg` is a long option.
460
+ */
461
+ function isLongOption(arg) {
462
+ return hasLongOptionPrefix(arg) && !arg.includes(EQUAL_CHAR, 3);
463
+ }
464
+ /**
465
+ * Check if `arg` is a long option with value (e.g. `--foo=bar`).
466
+ *
467
+ * @param arg - An argument to check
468
+ * @returns Whether `arg` is a long option.
469
+ */
470
+ function isLongOptionAndValue(arg) {
471
+ return hasLongOptionPrefix(arg) && arg.includes(EQUAL_CHAR, 3);
472
+ }
473
+ /**
474
+ * Check if `arg` starts with the long option prefix `--` and has more after it, such as `--foo`.
475
+ * The option terminator `--` alone does not.
476
+ *
477
+ * @param arg - An argument to check
478
+ * @returns Whether `arg` has the long option prefix and more after it.
479
+ */
480
+ function hasLongOptionPrefix(arg) {
481
+ return arg.startsWith(LONG_OPTION_PREFIX) && arg.length > 2;
482
+ }
483
+ /**
484
+ * Internal definitions shared by the modules of `args-tokens`.
485
+ *
486
+ * This module is not an entry point: it is not in the `exports` of `package.json` and `jsr.json`,
487
+ * so what it exports is not part of the public API.
488
+ */
489
+ /**
490
+ * @author kazuya kawaguchi (a.k.a. kazupon)
491
+ * @license MIT
492
+ */
493
+ /**
494
+ * Brand of a `parse` function that has no side effects, set by `string()`, `number()`,
495
+ * `integer()`, `float()`, `choice()` and `positional()` without a parser, so that the resolver may
496
+ * call it with a value that the option was not given, to check the value before suggesting it.
497
+ *
498
+ * The brand is looked up in the global symbol registry with `Symbol.for`, so it stays identical
499
+ * across bundled copies of `args-tokens`, where the resolver and the combinators may come from
500
+ * different copies.
501
+ */
502
+ const PURE_PARSE = Symbol.for("args-tokens.pureParse");
503
+ /**
504
+ * Entry point of argument options resolver.
505
+ *
506
+ * @module
507
+ */
508
+ /**
509
+ * @author kazuya kawaguchi (a.k.a. kazupon)
510
+ * @license MIT
511
+ */
512
+ /**
513
+ * Machine-readable error codes for {@link ArgsValidationError}.
514
+ *
515
+ * Each code identifies a validation failure category and is also suitable as an
516
+ * i18n resource key for localized rendering.
517
+ *
518
+ * {@link resolveArgs} and `parse()` do not report `unknownOption`. An option that is not in the
519
+ * schema takes the argument after it as its value, unless that argument is an option, and the value
520
+ * is dropped: with no `foo` in the schema, `--foo bar` gives no positional argument.
521
+ */
522
+ const ArgsValidationErrorKeys = {
523
+ requiredOption: "err:arg:required-option",
524
+ requiredPositional: "err:arg:required-positional",
525
+ invalidType: "err:arg:invalid-type",
526
+ invalidChoice: "err:arg:invalid-choice",
527
+ customParse: "err:arg:custom-parse",
528
+ unknownOption: "err:arg:unknown-option",
529
+ unexpectedValue: "err:arg:unexpected-value",
530
+ missingValue: "err:arg:missing-value",
531
+ conflict: "err:arg:conflict",
532
+ invalidDefault: "err:arg:invalid-default"
533
+ };
534
+ /**
535
+ * Brand that marks {@link ArgsValidationError} instances.
536
+ *
537
+ * The brand is looked up in the global symbol registry with `Symbol.for`, so it stays
538
+ * identical across bundled copies of this module and across realms. It lets
539
+ * {@link isArgsValidationError} recognize errors created by another copy of `args-tokens`,
540
+ * where `instanceof` cannot match.
541
+ */
542
+ const ARGS_VALIDATION_ERROR_BRAND = Symbol.for("args-tokens.ArgsValidationError");
543
+ /**
544
+ * An error that contains structured metadata for argument validation failures.
545
+ *
546
+ * The `message` remains the English fallback message. Renderers can use `code`
547
+ * and `values` to localize the error, falling back to `message` when localization
548
+ * is unavailable.
549
+ *
550
+ * Each instance carries a non-enumerable brand keyed by
551
+ * `Symbol.for('args-tokens.ArgsValidationError')`, which {@link isArgsValidationError}
552
+ * uses to recognize instances created by another bundled copy of `args-tokens`.
553
+ */
554
+ var ArgsValidationError = class extends Error {
555
+ /**
556
+ * Machine-readable error code for this validation failure.
557
+ *
558
+ * This code can also be used as an i18n resource key.
559
+ */
560
+ code;
561
+ /**
562
+ * Interpolation values for `code`.
563
+ */
564
+ values;
565
+ /**
566
+ * Create an `ArgsValidationError` instance.
567
+ *
568
+ * @param message - fallback error message
569
+ * @param options - structured validation metadata
570
+ */
571
+ constructor(message, options = {}) {
572
+ super(message, { cause: options.cause });
573
+ this.name = "ArgsValidationError";
574
+ this.code = options.code;
575
+ this.values = options.values ?? {};
576
+ Object.defineProperty(this, ARGS_VALIDATION_ERROR_BRAND, {
577
+ value: true,
578
+ enumerable: false,
579
+ writable: false,
580
+ configurable: false
581
+ });
582
+ }
583
+ };
584
+ /**
585
+ * Check whether the given value is an {@link ArgsValidationError}.
586
+ *
587
+ * This guard also recognizes errors created by another bundled copy of `args-tokens`
588
+ * (0.29.0 or later), where `instanceof` does not match. Such an error must have an own brand
589
+ * keyed by `Symbol.for('args-tokens.ArgsValidationError')` set to `true`, and a `values` object.
590
+ * The guard does not rely on `error.name`, so subclasses such as {@link ArgResolveError} that
591
+ * override `name` are still recognized.
592
+ *
593
+ * The guard narrows to `ArgsValidationError` only. Across bundled copies,
594
+ * `instanceof ArgResolveError` still does not match.
595
+ *
596
+ * @param error - value to check
597
+ * @returns `true` when the value is an `ArgsValidationError`
598
+ */
599
+ function isArgsValidationError$1(error) {
600
+ if (error instanceof ArgsValidationError) return true;
601
+ if (typeof error !== "object" || error === null) return false;
602
+ if (!Object.hasOwn(error, ARGS_VALIDATION_ERROR_BRAND) || error[ARGS_VALIDATION_ERROR_BRAND] !== true) return false;
603
+ const values = error.values;
604
+ return typeof values === "object" && values !== null;
605
+ }
606
+ const SKIP_POSITIONAL_DEFAULT = -1;
607
+ const ARG_TYPES = /* @__PURE__ */ new Set([
608
+ "string",
609
+ "boolean",
610
+ "number",
611
+ "enum",
612
+ "positional",
613
+ "custom"
614
+ ]);
615
+ /**
616
+ * Resolve command line arguments.
617
+ *
618
+ * @typeParam A - {@link Args | Arguments}, which is an object that defines the command line arguments.
619
+ *
620
+ * @param args - An arguments that contains {@link ArgSchema | arguments schema}.
621
+ * @param tokens - An array of {@link ArgToken | tokens}.
622
+ * @param resolveArgs - An arguments that contains {@link ResolveArgs | resolve arguments}.
623
+ * @returns An object that contains the values of the arguments, positional arguments, rest arguments, {@link AggregateError | validation errors}, and explicit provision status.
624
+ *
625
+ * @example
626
+ * ```typescript
627
+ * // passed tokens: --port 3000
628
+ *
629
+ * const { values, explicit } = resolveArgs({
630
+ * port: {
631
+ * type: 'number',
632
+ * default: 8080
633
+ * },
634
+ * host: {
635
+ * type: 'string',
636
+ * default: 'localhost'
637
+ * }
638
+ * }, parsedTokens)
639
+ *
640
+ * values.port // 3000
641
+ * values.host // 'localhost'
642
+ *
643
+ * explicit.port // true (explicitly provided)
644
+ * explicit.host // false (not provided, fallback to default)
645
+ * ```
646
+ */
647
+ function resolveArgs(args, tokens, { shortGrouping = false, skipPositional = SKIP_POSITIONAL_DEFAULT, toKebab = false } = {}) {
648
+ const skipPositionalIndex = typeof skipPositional === "number" ? Math.max(skipPositional, SKIP_POSITIONAL_DEFAULT) : SKIP_POSITIONAL_DEFAULT;
649
+ const rest = [];
650
+ const optionTokens = [];
651
+ const positionalTokens = [];
652
+ const argEntries = Object.entries(args);
653
+ let currentLongOption;
654
+ let currentShortOption;
655
+ const expandableShortOptions = [];
656
+ function getOptionName(rawArg, schema) {
657
+ return toKebab || schema.toKebab ? kebabnize(rawArg) : rawArg;
658
+ }
659
+ function checkLongTokenName(option, schema, token) {
660
+ if (token.rawName == void 0 || !hasLongOptionPrefix(token.rawName)) return false;
661
+ return token.name === option || isNegatedToken(token, option, schema);
662
+ }
663
+ function toShortValue() {
664
+ if (expandableShortOptions.length === 0) return;
665
+ else {
666
+ let value = "";
667
+ for (let i = 0; i < expandableShortOptions.length; i++) value += expandableShortOptions[i].name ?? "";
668
+ expandableShortOptions.length = 0;
669
+ return value;
670
+ }
671
+ }
672
+ function applyLongOptionValue(value) {
673
+ if (currentLongOption) {
674
+ currentLongOption.value = value;
675
+ optionTokens.push({ ...currentLongOption });
676
+ currentLongOption = void 0;
677
+ }
678
+ }
679
+ function applyShortOptionValue(value) {
680
+ if (currentShortOption) {
681
+ currentShortOption.value = value ?? toShortValue();
682
+ optionTokens.push({ ...currentShortOption });
683
+ currentShortOption = void 0;
684
+ }
685
+ }
686
+ /**
687
+ * analyze phase to resolve value
688
+ * separate tokens into positionals, long and short options, after that resolve values
689
+ */
690
+ const schemas = Object.values(args);
691
+ const booleanLongOptionNames = /* @__PURE__ */ new Set();
692
+ for (let i = 0; i < argEntries.length; i++) {
693
+ const entry = argEntries[i];
694
+ const rawArg = entry[0];
695
+ const schema = entry[1];
696
+ if (typeof schema.parse !== "function") {
697
+ if (schema.type === "custom") throw new TypeError(`argument '${getOptionName(rawArg, schema)}' should have a 'parse' function`);
698
+ if (schema.type === "enum" && !Array.isArray(schema.choices)) throw new TypeError(`argument '${getOptionName(rawArg, schema)}' should have a 'choices' array`);
699
+ if (!ARG_TYPES.has(schema.type)) throw new Error(`Unsupported argument type '${schema.type}' for option '${getOptionName(rawArg, schema)}'`);
700
+ }
701
+ if (schema.type !== "boolean") continue;
702
+ const arg = toKebab || schema.toKebab ? kebabnize(rawArg) : rawArg;
703
+ booleanLongOptionNames.add(arg);
704
+ if (schema.negatable === true) booleanLongOptionNames.add(`no-${arg}`);
705
+ }
706
+ let terminated = false;
707
+ for (let i = 0; i < tokens.length; i++) {
708
+ const token = tokens[i];
709
+ if (token.kind === "positional") {
710
+ if (terminated) {
711
+ rest.push(token.value);
712
+ continue;
713
+ }
714
+ if (currentShortOption) {
715
+ if (schemas.find((schema) => schema.short === currentShortOption.name && schema.type === "boolean") || expandableShortOptions.length > 0) {
716
+ positionalTokens.push({ ...token });
717
+ applyShortOptionValue();
718
+ } else applyShortOptionValue(token.value);
719
+ } else if (currentLongOption) {
720
+ if (booleanLongOptionNames.has(currentLongOption.name)) {
721
+ positionalTokens.push({ ...token });
722
+ applyLongOptionValue();
723
+ } else applyLongOptionValue(token.value);
724
+ } else positionalTokens.push({ ...token });
725
+ } else if (token.kind === "option") {
726
+ if (token.rawName) {
727
+ if (token.rawName.startsWith("--")) {
728
+ applyLongOptionValue();
729
+ applyShortOptionValue();
730
+ if (token.inlineValue) optionTokens.push({ ...token });
731
+ else currentLongOption = { ...token };
732
+ } else if (isShortOption(token.rawName)) {
733
+ if (currentShortOption) {
734
+ if (currentShortOption.index === token.index) {
735
+ if (shortGrouping) {
736
+ currentShortOption.value = token.value;
737
+ optionTokens.push({ ...currentShortOption });
738
+ currentShortOption = { ...token };
739
+ } else expandableShortOptions.push({ ...token });
740
+ } else {
741
+ currentShortOption.value = toShortValue();
742
+ optionTokens.push({ ...currentShortOption });
743
+ currentShortOption = { ...token };
744
+ }
745
+ applyLongOptionValue();
746
+ } else {
747
+ currentShortOption = { ...token };
748
+ applyLongOptionValue();
749
+ }
750
+ }
751
+ } else {
752
+ if (currentShortOption && currentShortOption.index == token.index) {
753
+ const letters = toShortValue();
754
+ currentShortOption.value = letters === void 0 ? token.value : `${letters}${token.inlineValue ? "=" : ""}${token.value ?? ""}`;
755
+ currentShortOption.inlineValue = token.inlineValue;
756
+ optionTokens.push({ ...currentShortOption });
757
+ currentShortOption = void 0;
758
+ }
759
+ applyLongOptionValue();
760
+ }
761
+ } else {
762
+ if (token.kind === "option-terminator") terminated = true;
763
+ applyLongOptionValue();
764
+ applyShortOptionValue();
765
+ }
766
+ }
767
+ /**
768
+ * check if the last long or short option is not resolved
769
+ */
770
+ applyLongOptionValue();
771
+ applyShortOptionValue();
772
+ /**
773
+ * resolve values
774
+ */
775
+ const values = Object.create(null);
776
+ const errors = [];
777
+ const explicit = Object.create(null);
778
+ const actualInputNames = /* @__PURE__ */ new Map();
779
+ let requiredPositionalsAfter;
780
+ const positionalItemCount = tokens.filter((token) => token.kind === "positional").length;
781
+ function getPositionalSkipIndex() {
782
+ return Math.min(skipPositionalIndex, positionalItemCount);
783
+ }
784
+ function getRequiredPositionalsAfter(rawArg) {
785
+ requiredPositionalsAfter ??= createRequiredPositionalsAfter(argEntries);
786
+ return requiredPositionalsAfter[rawArg] ?? 0;
787
+ }
788
+ let positionalsCount = 0;
789
+ for (let argIndex = 0; argIndex < argEntries.length; argIndex++) {
790
+ const entry = argEntries[argIndex];
791
+ const rawArg = entry[0];
792
+ const schema = entry[1];
793
+ const arg = getOptionName(rawArg, schema);
794
+ explicit[rawArg] = false;
795
+ if (schema.type === "positional") {
796
+ if (skipPositionalIndex > SKIP_POSITIONAL_DEFAULT) while (positionalsCount <= getPositionalSkipIndex()) positionalsCount++;
797
+ if (schema.multiple) {
798
+ const availablePositionals = Math.max(positionalTokens.length - positionalsCount, 0);
799
+ const positionalsToConsume = availablePositionals > 0 ? Math.max(availablePositionals - getRequiredPositionalsAfter(rawArg), 0) : 0;
800
+ if (positionalsToConsume > 0) {
801
+ const endPositionals = positionalsCount + positionalsToConsume;
802
+ if (typeof schema.parse === "function") {
803
+ const parsed = [];
804
+ for (let i = positionalsCount; i < endPositionals; i++) {
805
+ const p = positionalTokens[i];
806
+ const [parsedValue, error] = parseSchemaValue(p.value, rawArg, arg, schema);
807
+ if (error) errors.push(error);
808
+ else parsed.push(parsedValue);
809
+ }
810
+ values[rawArg] = parsed;
811
+ } else {
812
+ const valuesArray = [];
813
+ for (let i = positionalsCount; i < endPositionals; i++) valuesArray.push(positionalTokens[i].value);
814
+ values[rawArg] = valuesArray;
815
+ }
816
+ positionalsCount = endPositionals;
817
+ explicit[rawArg] = true;
818
+ } else if (schema.required) errors.push(createRequireError(rawArg, arg, schema));
819
+ else if (hasDefault(schema)) values[rawArg] = getDefaultValue(schema);
820
+ } else {
821
+ const positional = positionalTokens[positionalsCount];
822
+ if (shouldRequireMissingSinglePositional(schema)) {
823
+ if (positional != null) {
824
+ resolveSinglePositionalValue(values, errors, rawArg, arg, schema, positional);
825
+ explicit[rawArg] = true;
826
+ positionalsCount++;
827
+ } else errors.push(createRequireError(rawArg, arg, schema));
828
+ continue;
829
+ }
830
+ if (positional != null) {
831
+ const requiredPositionals = getRequiredPositionalsAfter(rawArg);
832
+ if (Math.max(positionalTokens.length - positionalsCount, 0) > requiredPositionals) {
833
+ resolveSinglePositionalValue(values, errors, rawArg, arg, schema, positional);
834
+ explicit[rawArg] = true;
835
+ positionalsCount++;
836
+ continue;
837
+ }
838
+ }
839
+ if (hasDefault(schema)) values[rawArg] = schema.default;
840
+ }
841
+ continue;
842
+ }
843
+ if (schema.required) {
844
+ if (!optionTokens.find((token) => {
845
+ return schema.short && token.name === schema.short && token.rawName != void 0 && isShortOption(token.rawName) || checkLongTokenName(arg, schema, token);
846
+ })) {
847
+ errors.push(createRequireError(rawArg, arg, schema));
848
+ continue;
849
+ }
850
+ }
851
+ let resolved = false;
852
+ for (let i = 0; i < optionTokens.length; i++) {
853
+ const token = optionTokens[i];
854
+ if (checkLongTokenName(arg, schema, token) || schema.short === token.name && token.rawName != void 0 && isShortOption(token.rawName)) {
855
+ explicit[rawArg] = true;
856
+ const rawName = token.rawName;
857
+ const actualInputName = isShortOption(rawName) ? `-${token.name}` : rawName;
858
+ actualInputNames.set(rawArg, actualInputName);
859
+ const missing = schema.type !== "boolean" && token.value === void 0;
860
+ if (!missing) {
861
+ const invalid = validateRequire(token, rawArg, arg, schema);
862
+ if (invalid) {
863
+ errors.push(invalid);
864
+ continue;
865
+ }
866
+ }
867
+ const [parsedValue, error] = missing ? [void 0, createMissingValueError(rawArg, arg, schema, findOptionLikeNextArgument(tokens, optionTokens, i, argEntries, toKebab))] : parse$1(token, rawArg, arg, schema);
868
+ if (error) errors.push(error);
869
+ else {
870
+ resolved = true;
871
+ if (schema.multiple) {
872
+ values[rawArg] ||= [];
873
+ values[rawArg].push(parsedValue);
874
+ } else values[rawArg] = parsedValue;
875
+ }
876
+ }
877
+ }
878
+ if (!resolved && schema.default != null) {
879
+ if (hasDefaultOutsideChoices(schema)) errors.push(createDefaultChoiceError(rawArg, arg, schema));
880
+ else values[rawArg] = getDefaultValue(schema);
881
+ }
882
+ }
883
+ const conflictErrors = checkConflicts(args, explicit, toKebab, actualInputNames);
884
+ errors.push(...conflictErrors);
885
+ return {
886
+ values,
887
+ positionals: positionalTokens.map((token) => token.value),
888
+ rest,
889
+ error: errors.length > 0 ? new AggregateError(errors) : void 0,
890
+ explicit
891
+ };
892
+ }
893
+ /**
894
+ * Check whether an option token is the negated form (`--no-<option>`) of a negatable boolean option.
895
+ *
896
+ * The negated name is always `no-` followed by the full option name, so an option named
897
+ * `no-cache` is negated only by `--no-no-cache`, and `--no-cache` is the option itself.
898
+ *
899
+ * @param token - The option token
900
+ * @param option - The option name used on the command line (after `toKebab` conversion)
901
+ * @param schema - The argument schema
902
+ * @returns Whether the token negates the option.
903
+ */
904
+ function isNegatedToken(token, option, schema) {
905
+ return schema.type === "boolean" && schema.negatable === true && token.name === `no-${option}`;
906
+ }
907
+ /**
908
+ * Resolve the value of an option token that matches the schema.
909
+ *
910
+ * A token of a non-boolean option always has a value here: `resolveArgs()` reports an option
911
+ * given without a value before calling this function.
912
+ *
913
+ * @param token - The option token
914
+ * @param rawArg - The argument key in the schema
915
+ * @param option - The option name used on the command line
916
+ * @param schema - The argument schema
917
+ * @returns The resolved value, or a validation error
918
+ */
919
+ function parse$1(token, rawArg, option, schema) {
920
+ if (schema.type === "enum" && schema.choices && !schema.choices.includes(token.value)) return [void 0, createChoiceError(rawArg, option, schema, token.value)];
921
+ if (typeof schema.parse === "function") {
922
+ if (schema.type === "boolean") {
923
+ const [boolValue, error] = resolveBooleanValue(token, rawArg, option, schema);
924
+ if (error) return [void 0, error];
925
+ return parseSchemaValue(String(boolValue), rawArg, option, schema);
926
+ }
927
+ return parseSchemaValue(token.value, rawArg, option, schema);
928
+ }
929
+ switch (schema.type) {
930
+ case "string": return typeof token.value === "string" ? [token.value, void 0] : [void 0, createTypeError(rawArg, option, schema, token.value)];
931
+ case "boolean": return resolveBooleanValue(token, rawArg, option, schema);
932
+ case "number":
933
+ if (typeof token.value !== "string" || !isNumeric(token.value)) return [void 0, createTypeError(rawArg, option, schema, token.value)];
934
+ return [+token.value, void 0];
935
+ case "enum": return [token.value, void 0];
936
+ case "custom": throw new TypeError(`argument '${option}' should have a 'parse' function`);
937
+ default: throw new Error(`Unsupported argument type '${schema.type}' for option '${option}'`);
938
+ }
939
+ }
940
+ /**
941
+ * Resolve the value of a boolean option token.
942
+ *
943
+ * `--flag` is `true` and `--no-flag` is `false`. An explicit inline value (`--flag=true`,
944
+ * `--flag=false`, `-f=false`) is read instead; any other inline value is a type error.
945
+ * The negated form does not take a value, so `--no-flag=<value>` is an error.
946
+ *
947
+ * @param token - The option token
948
+ * @param rawArg - The argument key in the schema
949
+ * @param option - The option name used on the command line
950
+ * @param schema - The argument schema
951
+ * @returns The resolved boolean, or a validation error
952
+ */
953
+ function resolveBooleanValue(token, rawArg, option, schema) {
954
+ const negated = isNegatedToken(token, option, schema);
955
+ if (!token.inlineValue) return [!negated, void 0];
956
+ if (negated) return [void 0, createUnexpectedValueError(rawArg, option, schema, token)];
957
+ if (token.value !== "true" && token.value !== "false") return [void 0, createTypeError(rawArg, option, schema, token.value)];
958
+ return [token.value === "true", void 0];
959
+ }
960
+ function parseSchemaValue(value, rawArg, option, schema) {
961
+ try {
962
+ return [schema.parse(value), void 0];
963
+ } catch (error) {
964
+ return [void 0, createCustomParseError(error, rawArg, option, schema, value)];
965
+ }
966
+ }
967
+ function createRequireError(rawArg, option, schema) {
968
+ return new ArgResolveError(schema.type === "positional" ? `Positional argument '${option}' is required` : `Optional argument ${createOptionDisplayName(option, schema)} is required`, option, "required", schema, {
969
+ code: schema.type === "positional" ? ArgsValidationErrorKeys.requiredPositional : ArgsValidationErrorKeys.requiredOption,
970
+ values: schema.type === "positional" ? {
971
+ displayName: createArgumentDisplayName(option, schema),
972
+ name: rawArg
973
+ } : {
974
+ displayName: createOptionDisplayName(option, schema),
975
+ name: rawArg
976
+ }
977
+ });
978
+ }
979
+ function resolveSinglePositionalValue(values, errors, rawArg, option, schema, positional) {
980
+ if (typeof schema.parse === "function") {
981
+ const [parsedValue, error] = parseSchemaValue(positional.value, rawArg, option, schema);
982
+ if (error) errors.push(error);
983
+ else values[rawArg] = parsedValue;
984
+ } else values[rawArg] = positional.value;
985
+ }
986
+ function hasDefault(schema) {
987
+ return schema.default != null;
988
+ }
989
+ /**
990
+ * Get the value that the default of an argument gives.
991
+ *
992
+ * The value of a `multiple` argument is an array, so its default becomes the only element of an
993
+ * array. A default that is an array already, which only untyped code can give, is used as is.
994
+ *
995
+ * @param schema - The argument schema
996
+ * @returns The value that the default gives
997
+ */
998
+ function getDefaultValue(schema) {
999
+ const value = schema.default;
1000
+ return schema.multiple && !Array.isArray(value) ? [value] : value;
1001
+ }
1002
+ /**
1003
+ * Check whether the default of an `enum` option is not one of its `choices`.
1004
+ *
1005
+ * The default does not go through `parse`, so with a `parse` function of your own, or a `map()`
1006
+ * transform, it is a value that the function returns, which need not be one of the choices, and it
1007
+ * is not checked. The `parse` function of `choice()` returns the value as is, so its default is
1008
+ * checked: among the schemas that the combinators make, it is the only `enum` schema whose `parse`
1009
+ * has the {@link PURE_PARSE} brand. An `enum` schema written by hand with another branded `parse`
1010
+ * would be checked too.
1011
+ *
1012
+ * Only a string, number or boolean default, as the type of `default` allows, is checked against an
1013
+ * array of choices. Anything else, which only untyped code can give, is used as before.
1014
+ *
1015
+ * @param schema - The argument schema
1016
+ * @returns Whether the default is not one of the choices
1017
+ */
1018
+ function hasDefaultOutsideChoices(schema) {
1019
+ const defaultType = typeof schema.default;
1020
+ if (schema.type !== "enum" || !Array.isArray(schema.choices) || defaultType !== "string" && defaultType !== "number" && defaultType !== "boolean" || schema.choices.includes(schema.default)) return false;
1021
+ const { parse } = schema;
1022
+ if (typeof parse !== "function") return true;
1023
+ try {
1024
+ return hasPureParseBrand(parse);
1025
+ } catch {
1026
+ return false;
1027
+ }
1028
+ }
1029
+ function shouldRequireMissingSinglePositional(schema) {
1030
+ if (schema.required === true) return true;
1031
+ if (schema.required === false) return false;
1032
+ return !hasDefault(schema);
1033
+ }
1034
+ function getRequiredPositionalInputCount(schema) {
1035
+ if (schema.type !== "positional") return 0;
1036
+ if (schema.multiple) return schema.required === true ? 1 : 0;
1037
+ return shouldRequireMissingSinglePositional(schema) ? 1 : 0;
1038
+ }
1039
+ function createRequiredPositionalsAfter(argEntries) {
1040
+ const requiredPositionalsAfter = Object.create(null);
1041
+ let minimumRequiredPositionals = 0;
1042
+ for (let i = argEntries.length - 1; i >= 0; i--) {
1043
+ const [rawArg, schema] = argEntries[i];
1044
+ if (schema.type !== "positional") continue;
1045
+ requiredPositionalsAfter[rawArg] = minimumRequiredPositionals;
1046
+ minimumRequiredPositionals += getRequiredPositionalInputCount(schema);
1047
+ }
1048
+ return requiredPositionalsAfter;
1049
+ }
1050
+ /**
1051
+ * An error that occurs when resolving arguments.
1052
+ *
1053
+ * It is not thrown: when an argument is not valid, {@link resolveArgs} returns it in the `errors`
1054
+ * of the `AggregateError` in `error`, and so does `parse()`.
1055
+ */
1056
+ var ArgResolveError = class extends ArgsValidationError {
1057
+ /**
1058
+ * The name of the argument on the command line, without the leading dashes: the schema key, in
1059
+ * kebab-case with `toKebab`, such as `input-file` for `inputFile`, whether the option is given in
1060
+ * the long form, as a short option or in the negated form. For a conflict, it is the name of the
1061
+ * argument whose `conflicts` names the other one (the first in the schema when both name each
1062
+ * other). `values.name` has the schema key.
1063
+ */
1064
+ name;
1065
+ schema;
1066
+ type;
1067
+ /**
1068
+ * Create an `ArgResolveError` instance.
1069
+ *
1070
+ * @param message - the error message
1071
+ * @param name - the name of the argument on the command line, in kebab-case with `toKebab`
1072
+ * @param type - the type of the error: 'type', 'required', or 'conflict'
1073
+ * @param schema - the argument schema that caused the error
1074
+ * @param options - structured validation metadata
1075
+ */
1076
+ constructor(message, name, type, schema, options = {}) {
1077
+ super(message, options);
1078
+ this.name = name;
1079
+ this.type = type;
1080
+ this.schema = schema;
1081
+ }
1082
+ };
1083
+ function validateRequire(token, rawArg, option, schema) {
1084
+ if (schema.required && schema.type !== "boolean" && !token.value) return createRequireError(rawArg, option, schema);
1085
+ }
1086
+ function isNumeric(str) {
1087
+ return str.trim() !== "" && !isNaN(str);
1088
+ }
1089
+ function createTypeError(rawArg, option, schema, actual, expected = schema.type) {
1090
+ return new ArgResolveError(`Optional argument ${createOptionDisplayName(option, schema)} should be '${expected}'`, option, "type", schema, {
1091
+ code: ArgsValidationErrorKeys.invalidType,
1092
+ values: {
1093
+ displayName: createOptionDisplayName(option, schema),
1094
+ name: rawArg,
1095
+ expected,
1096
+ ...actual != null ? { actual } : {}
1097
+ }
1098
+ });
1099
+ }
1100
+ /**
1101
+ * Create the error for an option that is given without a value.
1102
+ *
1103
+ * `expected` names what the option takes: its type, or for a `custom` type its `metavar` (for
1104
+ * example `'integer'` for the `integer()` combinator). An `enum` also gets its choices. When the
1105
+ * argument after the option may be a value that starts with `-`, and the option may take it (see
1106
+ * `acceptsSuggestedValue()`), the error suggests the long form with `=`, which passes such a value in
1107
+ * every mode of the tokenizer.
1108
+ *
1109
+ * @param rawArg - The argument key in the schema
1110
+ * @param option - The option name used on the command line
1111
+ * @param schema - The argument schema
1112
+ * @param next - The argument after the option, when it may be a value that starts with `-`
1113
+ * @returns The validation error
1114
+ */
1115
+ function createMissingValueError(rawArg, option, schema, next) {
1116
+ const displayName = createOptionDisplayName(option, schema);
1117
+ const suggestion = next === void 0 || !acceptsSuggestedValue(schema, next) ? void 0 : `--${option}=${next}`;
1118
+ const hint = suggestion === void 0 ? "" : ` (to pass '${next}' as its value, write '${suggestion}')`;
1119
+ const choices = schema.choices ?? [];
1120
+ return new ArgResolveError(`Optional argument ${displayName} requires a value${hint}`, option, "type", schema, {
1121
+ code: ArgsValidationErrorKeys.missingValue,
1122
+ values: {
1123
+ displayName,
1124
+ name: rawArg,
1125
+ expected: schema.type === "custom" ? schema.metavar ?? schema.type : schema.type,
1126
+ ...schema.type === "enum" ? {
1127
+ choices: formatChoices(choices),
1128
+ choiceValues: [...choices]
1129
+ } : {},
1130
+ ...suggestion === void 0 ? {} : {
1131
+ next,
1132
+ suggestion
1133
+ }
1134
+ }
1135
+ });
1136
+ }
1137
+ /**
1138
+ * Find the argument right after an option that is given without a value, when it may be a value
1139
+ * that starts with `-`.
1140
+ *
1141
+ * The option must end its own argument (with `shortGrouping`, `-pv` gives `-p` no value because of
1142
+ * `-v`), and the next argument must be read as options that are not all defined, such as `-5` or
1143
+ * `--foo`. Without `shortGrouping`, a group is read as its first option, which takes the other
1144
+ * letters as its value, so `-p5` is defined when `-p` is. The argument is rebuilt from its tokens.
1145
+ * Without `allowCompatible`, a short option written with a value, such as `-x=1`, `-x=` or `-x-1`,
1146
+ * has a value, and is not suggested.
1147
+ *
1148
+ * @param tokens - The tokens given to `resolveArgs()`
1149
+ * @param optionTokens - The option tokens that `resolveArgs()` resolves
1150
+ * @param position - The position of the option given without a value in `optionTokens`
1151
+ * @param argEntries - The argument schemas
1152
+ * @param toKebab - Whether every option name is converted to kebab-case
1153
+ * @returns The next argument rebuilt from its tokens, or `undefined` when there is nothing to
1154
+ * suggest
1155
+ */
1156
+ function findOptionLikeNextArgument(tokens, optionTokens, position, argEntries, toKebab) {
1157
+ const token = optionTokens[position];
1158
+ for (let i = position + 1; i < optionTokens.length; i++) if (optionTokens[i].index === token.index) return;
1159
+ const nextArg = tokens.filter((t) => t.index === token.index + 1);
1160
+ if (nextArg.length === 0 || nextArg.some((t) => t.kind !== "option" || t.rawName == null)) return;
1161
+ let text;
1162
+ let known;
1163
+ if (nextArg.length === 1 && nextArg[0].rawName.startsWith("--")) {
1164
+ const [option] = nextArg;
1165
+ text = option.inlineValue ? `${option.rawName}=${option.value}` : option.rawName;
1166
+ known = createKnownOptionNames(argEntries, toKebab).long.has(option.name);
1167
+ } else if (nextArg.every((t) => isShortOption(t.rawName) && t.value === void 0)) {
1168
+ text = `-${nextArg.map((t) => t.name).join("")}`;
1169
+ const { short } = createKnownOptionNames(argEntries, toKebab);
1170
+ known = optionTokens.every((t) => t.index !== token.index + 1 || short.has(t.name));
1171
+ } else return;
1172
+ return known ? void 0 : text;
1173
+ }
1174
+ /**
1175
+ * Collect the names of the defined options: the long names, with the negated form of negatable
1176
+ * booleans, and the short names.
1177
+ *
1178
+ * @param argEntries - The argument schemas
1179
+ * @param toKebab - Whether every option name is converted to kebab-case
1180
+ * @returns The long and short option names
1181
+ */
1182
+ function createKnownOptionNames(argEntries, toKebab) {
1183
+ const long = /* @__PURE__ */ new Set();
1184
+ const short = /* @__PURE__ */ new Set();
1185
+ for (const [rawArg, schema] of argEntries) {
1186
+ if (schema.type === "positional") continue;
1187
+ const name = toKebab || schema.toKebab ? kebabnize(rawArg) : rawArg;
1188
+ long.add(name);
1189
+ if (schema.type === "boolean" && schema.negatable === true) long.add(`no-${name}`);
1190
+ if (schema.short) short.add(schema.short);
1191
+ }
1192
+ return {
1193
+ long,
1194
+ short
1195
+ };
1196
+ }
1197
+ /**
1198
+ * Check whether the argument after an option given without a value may be suggested as its value.
1199
+ *
1200
+ * The value of a `number` option must be numeric, as the error expects a number, and the value of
1201
+ * an `enum` option with `choices` must be one of them, which is checked before any `parse`
1202
+ * function. A `parse` function with its own {@link PURE_PARSE} brand is then called with the
1203
+ * value, which must not throw. Any other `parse` function may have side effects, so it is not
1204
+ * called: a `number` option or an `enum` option with `choices` is then checked only as above, and
1205
+ * any other option is not suggested.
1206
+ *
1207
+ * @param schema - The argument schema
1208
+ * @param value - The argument after the option
1209
+ * @returns Whether the value may be suggested
1210
+ */
1211
+ function acceptsSuggestedValue(schema, value) {
1212
+ if (schema.type === "number" && !isNumeric(value)) return false;
1213
+ if (schema.type === "enum" && schema.choices && !schema.choices.includes(value)) return false;
1214
+ const { parse } = schema;
1215
+ if (typeof parse !== "function") return true;
1216
+ try {
1217
+ if (!hasPureParseBrand(parse)) return schema.type === "number" || schema.type === "enum" && schema.choices !== void 0;
1218
+ parse(value);
1219
+ return true;
1220
+ } catch {
1221
+ return false;
1222
+ }
1223
+ }
1224
+ /**
1225
+ * Check whether a `parse` function has its own {@link PURE_PARSE} brand.
1226
+ *
1227
+ * Only an own brand counts, as for `isArgsValidationError()`. Reading it may throw, for example for
1228
+ * a revoked proxy, so call this function in `try`.
1229
+ *
1230
+ * @param parse - The `parse` function of a schema
1231
+ * @returns Whether the function has no side effects
1232
+ */
1233
+ function hasPureParseBrand(parse) {
1234
+ return Object.hasOwn(parse, PURE_PARSE) && parse[PURE_PARSE] === true;
1235
+ }
1236
+ function createUnexpectedValueError(rawArg, option, schema, token) {
1237
+ const rawName = token.rawName;
1238
+ const displayName = `'${rawName}'`;
1239
+ return new ArgResolveError(`Optional argument ${displayName} does not take a value`, option, "type", schema, {
1240
+ code: ArgsValidationErrorKeys.unexpectedValue,
1241
+ values: {
1242
+ displayName,
1243
+ name: rawArg,
1244
+ rawName,
1245
+ ...token.value != null ? { actual: token.value } : {}
1246
+ }
1247
+ });
1248
+ }
1249
+ function createChoiceError(rawArg, option, schema, actual) {
1250
+ const choices = schema.choices ?? [];
1251
+ return new ArgResolveError(`Optional argument ${createOptionDisplayName(option, schema)} should be chosen from '${schema.type}' [${formatChoices(choices)}] values`, option, "type", schema, {
1252
+ code: ArgsValidationErrorKeys.invalidChoice,
1253
+ values: {
1254
+ displayName: createOptionDisplayName(option, schema),
1255
+ name: rawArg,
1256
+ expected: schema.type,
1257
+ choices: formatChoices(choices),
1258
+ choiceValues: [...choices],
1259
+ ...actual != null ? { actual } : {}
1260
+ }
1261
+ });
1262
+ }
1263
+ /**
1264
+ * Create the error for the default of an `enum` option that is not one of its `choices`.
1265
+ *
1266
+ * Its `values` have the same keys as those of `err:arg:invalid-choice`, with the default as
1267
+ * `actual`.
1268
+ *
1269
+ * @param rawArg - The argument key in the schema
1270
+ * @param option - The option name used on the command line
1271
+ * @param schema - The argument schema
1272
+ * @returns The error
1273
+ */
1274
+ function createDefaultChoiceError(rawArg, option, schema) {
1275
+ const choices = schema.choices ?? [];
1276
+ const displayName = createOptionDisplayName(option, schema);
1277
+ return new ArgResolveError(`Optional argument ${displayName} has the default ${typeof schema.default === "string" ? JSON.stringify(schema.default) : String(schema.default)}, which is not one of '${schema.type}' [${formatChoices(choices)}] values`, option, "type", schema, {
1278
+ code: ArgsValidationErrorKeys.invalidDefault,
1279
+ values: {
1280
+ displayName,
1281
+ name: rawArg,
1282
+ expected: schema.type,
1283
+ choices: formatChoices(choices),
1284
+ choiceValues: [...choices],
1285
+ actual: schema.default
1286
+ }
1287
+ });
1288
+ }
1289
+ function createCustomParseError(error, rawArg, option, schema, value) {
1290
+ const reused = reuseValidationError(error, rawArg, option, schema, value);
1291
+ if (reused) return reused;
1292
+ const reason = getErrorReason(error);
1293
+ return new ArgsValidationError(reason, {
1294
+ code: ArgsValidationErrorKeys.customParse,
1295
+ values: {
1296
+ displayName: createArgumentDisplayName(option, schema),
1297
+ name: rawArg,
1298
+ reason
1299
+ },
1300
+ cause: error
1301
+ });
1302
+ }
1303
+ /**
1304
+ * Reuse an {@link ArgsValidationError} thrown from a custom `parse` function, filling in missing values.
1305
+ *
1306
+ * @param error - The value thrown from `parse`
1307
+ * @param rawArg - The argument key in the schema
1308
+ * @param option - The option name used on the command line
1309
+ * @param schema - The argument schema
1310
+ * @param value - The raw input value
1311
+ * @returns The same error when it can be reused, otherwise `undefined` so the caller wraps it.
1312
+ * Inspecting or updating the thrown value can throw, for example when its `values` object is frozen
1313
+ * or an accessor throws; such values are not reused, so a custom `parse` cannot make `resolveArgs` throw this way.
1314
+ */
1315
+ function reuseValidationError(error, rawArg, option, schema, value) {
1316
+ try {
1317
+ if (isArgsValidationError$1(error)) {
1318
+ augmentValidationError(error, rawArg, option, schema, value);
1319
+ return error;
1320
+ }
1321
+ } catch {}
1322
+ }
1323
+ function augmentValidationError(error, rawArg, option, schema, value) {
1324
+ const values = error.values;
1325
+ values.name ??= rawArg;
1326
+ values.displayName ??= createArgumentDisplayName(option, schema);
1327
+ if ((error.code === ArgsValidationErrorKeys.invalidType || error.code === ArgsValidationErrorKeys.invalidChoice) && values.actual == null) values.actual = value;
1328
+ }
1329
+ function getErrorReason(error) {
1330
+ return error instanceof Error ? error.message : String(error);
1331
+ }
1332
+ function createArgumentDisplayName(option, schema) {
1333
+ return schema.type === "positional" ? `'${option}'` : createOptionDisplayName(option, schema);
1334
+ }
1335
+ function createOptionDisplayName(option, schema) {
1336
+ return `'--${option}'${schema.short ? ` or '-${schema.short}'` : ""}`;
1337
+ }
1338
+ /**
1339
+ * Create the error for two arguments that conflict.
1340
+ *
1341
+ * An option is shown as it was written, such as `'-p'` or `'--no-color'`, and a positional argument
1342
+ * by its name, such as `'file'`, as in the message. The message starts with "Positional argument"
1343
+ * when `schema` is a positional argument, and with "Optional argument" otherwise.
1344
+ *
1345
+ * @param rawArg - The argument key of the argument whose `conflicts` names the other one
1346
+ * @param option - The name of that argument used on the command line
1347
+ * @param schema - The argument schema of that argument
1348
+ * @param actualName - That option as it was written, or the name of that positional argument
1349
+ * @param conflictingArg - The argument key of the other argument
1350
+ * @param conflictingActualName - The other option as it was written, or the name of the other
1351
+ * positional argument
1352
+ * @returns The validation error
1353
+ */
1354
+ function createConflictError(rawArg, option, schema, actualName, conflictingArg, conflictingActualName) {
1355
+ const displayName = `'${actualName}'`;
1356
+ const conflictDisplayName = `'${conflictingActualName}'`;
1357
+ return new ArgResolveError(`${schema.type === "positional" ? "Positional" : "Optional"} argument ${displayName} conflicts with ${conflictDisplayName}`, option, "conflict", schema, {
1358
+ code: ArgsValidationErrorKeys.conflict,
1359
+ values: {
1360
+ displayName,
1361
+ name: rawArg,
1362
+ conflictDisplayName,
1363
+ conflictName: conflictingArg
1364
+ }
1365
+ });
1366
+ }
1367
+ function checkConflicts(args, explicit, toKebab, actualInputNames) {
1368
+ for (const rawArg in args) {
1369
+ const schema = args[rawArg];
1370
+ if (!explicit[rawArg]) continue;
1371
+ if (!schema.conflicts) continue;
1372
+ const conflicts = Array.isArray(schema.conflicts) ? schema.conflicts : [schema.conflicts];
1373
+ for (let i = 0; i < conflicts.length; i++) {
1374
+ const conflictingArg = conflicts[i];
1375
+ if (!explicit[conflictingArg]) continue;
1376
+ const arg = toKebab || schema.toKebab ? kebabnize(rawArg) : rawArg;
1377
+ const conflictingArgKebab = toKebab || args[conflictingArg]?.toKebab ? kebabnize(conflictingArg) : conflictingArg;
1378
+ return [createConflictError(rawArg, arg, schema, schema.type === "positional" ? arg : actualInputNames.get(rawArg) || `--${arg}`, conflictingArg, args[conflictingArg]?.type === "positional" ? conflictingArgKebab : actualInputNames.get(conflictingArg) || `--${conflictingArgKebab}`)];
1379
+ }
1380
+ }
1381
+ return [];
1382
+ }
1383
+ //#endregion
1384
+ //#region node_modules/.bun/gunshi@1.0.0-rc.1/node_modules/gunshi/lib/error-pbHb3QAL.js
1385
+ /**
1386
+ * @author kazuya kawaguchi (a.k.a. kazupon)
1387
+ * @license MIT
1388
+ */
1389
+ /**
1390
+ * @author kazuya kawaguchi (a.k.a. kazupon)
1391
+ * @license MIT
1392
+ */
1393
+ /**
1394
+ * @author kazuya kawaguchi (a.k.a. kazupon)
1395
+ * @license MIT
1396
+ */
1397
+ /**
1398
+ * Command not found error resource keys.
1399
+ */
1400
+ const CommandNotFoundErrorKeys = { notFound: "err:cmd:not-found" };
1401
+ /**
1402
+ * Command resolution error resource keys.
1403
+ *
1404
+ * These errors describe an ambiguity or inconsistency while choosing a command from arguments.
1405
+ * They are kept separate from {@link CommandNotFoundError} so consumers can distinguish a typo
1406
+ * from an input whose command interpretation is not unique.
1407
+ */
1408
+ const CommandResolutionErrorKeys = {
1409
+ ambiguous: "err:cmd:ambiguous",
1410
+ inconsistentOptions: "err:cmd:inconsistent-options",
1411
+ lazySchemaMismatch: "err:cmd:lazy-schema-mismatch"
1412
+ };
1413
+ /**
1414
+ * Brand that marks {@link CommandNotFoundError} instances.
1415
+ *
1416
+ * The brand is looked up in the global symbol registry with `Symbol.for`, so it stays
1417
+ * identical across bundled copies of gunshi (`gunshi`, `@gunshi/plugin`, `@gunshi/bone`)
1418
+ * and across realms. It lets {@link isCommandNotFoundError} recognize errors created by
1419
+ * another copy, where `instanceof` cannot match.
1420
+ */
1421
+ const COMMAND_NOT_FOUND_ERROR_BRAND = Symbol.for("gunshi.CommandNotFoundError");
1422
+ const COMMAND_RESOLUTION_ERROR_BRAND = Symbol.for("gunshi.CommandResolutionError");
1423
+ /**
1424
+ * Error raised when a command cannot be resolved.
1425
+ *
1426
+ * Each instance carries a non-enumerable brand keyed by
1427
+ * `Symbol.for('gunshi.CommandNotFoundError')`, so that {@link isCommandNotFoundError}
1428
+ * recognizes it even when it was created by another bundled copy of gunshi.
1429
+ */
1430
+ var CommandNotFoundError = class extends Error {
1431
+ code;
1432
+ values;
1433
+ commandName;
1434
+ candidates;
1435
+ commandPath;
1436
+ /**
1437
+ * Create a command-not-found error.
1438
+ *
1439
+ * @param message - Fallback error message
1440
+ * @param options - Command-not-found metadata
1441
+ */
1442
+ constructor(message, options) {
1443
+ super(message, { cause: options.cause });
1444
+ this.name = "CommandNotFoundError";
1445
+ this.code = options.code;
1446
+ this.values = options.values || {};
1447
+ this.commandName = options.commandName;
1448
+ this.candidates = options.candidates || [];
1449
+ this.commandPath = options.commandPath || [];
1450
+ Object.defineProperty(this, COMMAND_NOT_FOUND_ERROR_BRAND, {
1451
+ value: true,
1452
+ enumerable: false,
1453
+ writable: false,
1454
+ configurable: false
1455
+ });
1456
+ }
1457
+ };
1458
+ /**
1459
+ * Error raised when command routing cannot produce one consistent command.
1460
+ *
1461
+ * The own registry brand is the cross-bundle contract. Unlike the legacy command-not-found
1462
+ * guard, the new guard deliberately has no name-based fallback because this error type is new and
1463
+ * must not classify arbitrary errors from older versions.
1464
+ */
1465
+ var CommandResolutionError = class extends Error {
1466
+ code;
1467
+ values;
1468
+ commandPath;
1469
+ candidatePaths;
1470
+ /**
1471
+ * Create a command resolution error with structured routing metadata.
1472
+ *
1473
+ * @param message - Human-readable fallback message
1474
+ * @param options - Error code and command-routing metadata
1475
+ */
1476
+ constructor(message, options = {}) {
1477
+ super(message, { cause: options.cause });
1478
+ this.name = "CommandResolutionError";
1479
+ this.code = options.code;
1480
+ this.values = options.values || {};
1481
+ this.commandPath = options.commandPath || [];
1482
+ this.candidatePaths = options.candidatePaths || [];
1483
+ Object.defineProperty(this, COMMAND_RESOLUTION_ERROR_BRAND, {
1484
+ value: true,
1485
+ enumerable: false,
1486
+ writable: false,
1487
+ configurable: false
1488
+ });
1489
+ }
1490
+ };
1491
+ /**
1492
+ * Check whether an error is a {@link CommandNotFoundError}.
1493
+ *
1494
+ * `instanceof` alone is not enough: `@gunshi/plugin` is bundled with its own copy of this
1495
+ * class (`noExternal: ['gunshi/plugin']`), so an error thrown by `gunshi` is never an instance
1496
+ * of the class a plugin imports. Errors from another copy are recognized through the
1497
+ * `Symbol.for('gunshi.CommandNotFoundError')` brand, which does not depend on `error.name`.
1498
+ *
1499
+ * @param error - An unknown error
1500
+ * @returns `true` if the error is a {@link CommandNotFoundError}
1501
+ */
1502
+ function isCommandNotFoundError(error) {
1503
+ if (error instanceof CommandNotFoundError) return true;
1504
+ if (!isRecord(error) || !hasCommandNotFoundErrorShape(error)) return false;
1505
+ if (Object.hasOwn(error, COMMAND_NOT_FOUND_ERROR_BRAND) && error[COMMAND_NOT_FOUND_ERROR_BRAND] === true) return true;
1506
+ return error instanceof Error && error.name === "CommandNotFoundError";
1507
+ }
1508
+ /**
1509
+ * Check whether an error is a {@link CommandResolutionError}.
1510
+ *
1511
+ * @param error - An unknown error
1512
+ * @returns `true` when the error has the command-resolution brand and shape
1513
+ */
1514
+ function isCommandResolutionError(error) {
1515
+ if (error instanceof CommandResolutionError) return true;
1516
+ if (!isRecord(error) || !hasCommandResolutionErrorShape(error)) return false;
1517
+ return Object.hasOwn(error, COMMAND_RESOLUTION_ERROR_BRAND) && error[COMMAND_RESOLUTION_ERROR_BRAND] === true;
1518
+ }
1519
+ /**
1520
+ * Check whether an error is an {@link ArgsValidationError}.
1521
+ *
1522
+ * Prefer this over the `args-tokens` guard of the same name. Both recognize errors from another
1523
+ * bundled copy through the `Symbol.for('args-tokens.ArgsValidationError')` brand that
1524
+ * `args-tokens` 0.29.0 or later sets, including subclasses such as `ArgResolveError` that
1525
+ * override `name` with the argument name. This guard additionally:
1526
+ *
1527
+ * - recognizes direct `ArgsValidationError` instances from copies bundling `args-tokens`
1528
+ * older than 0.29.0, which do not set the brand
1529
+ * - checks that `code` and `values` of an error from another copy have the expected types
1530
+ *
1531
+ * The guard narrows only to {@link ArgsValidationError}: across copies,
1532
+ * `instanceof ArgResolveError` still fails, so do not rely on `type` or `schema` for such errors.
1533
+ *
1534
+ * @param error - An unknown error
1535
+ * @returns `true` if the error is an {@link ArgsValidationError}
1536
+ */
1537
+ function isArgsValidationError(error) {
1538
+ if (error instanceof ArgsValidationError) return true;
1539
+ if (!isRecord(error) || !hasArgsValidationErrorShape(error)) return false;
1540
+ if (isArgsValidationError$1(error)) return true;
1541
+ return error instanceof Error && error.name === "ArgsValidationError";
1542
+ }
1543
+ function isRecord(value) {
1544
+ return typeof value === "object" && value !== null;
1545
+ }
1546
+ function isStringArray(value) {
1547
+ return Array.isArray(value) && value.every((item) => typeof item === "string");
1548
+ }
1549
+ /**
1550
+ * Check whether `code` is an own or inherited property that is a string or `undefined`.
1551
+ *
1552
+ * Constructors always assign `code`, even when the option is omitted.
1553
+ *
1554
+ * @param error - An error from another copy
1555
+ * @returns `true` if `code` has the expected type
1556
+ */
1557
+ function hasOptionalStringCode(error) {
1558
+ return "code" in error && (error.code === void 0 || typeof error.code === "string");
1559
+ }
1560
+ function hasCommandNotFoundErrorShape(error) {
1561
+ return hasOptionalStringCode(error) && isRecord(error.values) && typeof error.commandName === "string" && isStringArray(error.candidates) && isStringArray(error.commandPath);
1562
+ }
1563
+ function hasCommandResolutionErrorShape(error) {
1564
+ return hasOptionalStringCode(error) && isRecord(error.values) && isStringArray(error.commandPath) && Array.isArray(error.candidatePaths) && error.candidatePaths.every((path) => isStringArray(path));
1565
+ }
1566
+ function hasArgsValidationErrorShape(error) {
1567
+ return hasOptionalStringCode(error) && isRecord(error.values);
1568
+ }
1569
+ /**
1570
+ * Check whether validation errors should be handled before version, help, or command execution.
1571
+ *
1572
+ * @param error - An aggregate validation error
1573
+ * @returns `true` if the validation error must be handled with priority
1574
+ */
1575
+ function hasPriorityValidationError(error) {
1576
+ return error?.errors.some((error) => isCommandNotFoundError(error) || isCommandResolutionError(error) || isArgsValidationError(error) && error.code === ArgsValidationErrorKeys.unknownOption) ?? false;
1577
+ }
1578
+ //#endregion
1579
+ //#region node_modules/.bun/gunshi@1.0.0-rc.1/node_modules/gunshi/lib/core-EDPnjwxe.js
1580
+ /**
1581
+ * @author kazuya kawaguchi (a.k.a. kazupon)
1582
+ * @license MIT
1583
+ */
1584
+ const EMPTY_RENDERER = () => Promise.resolve("");
1585
+ /**
1586
+ * Factory function for creating a decorators manager.
1587
+ *
1588
+ * @returns A new decorators manager instance
1589
+ */
1590
+ function createDecorators() {
1591
+ /**
1592
+ * private states
1593
+ */
1594
+ const headerDecorators = [];
1595
+ const usageDecorators = [];
1596
+ const validationDecorators = [];
1597
+ const commandDecorators = [];
1598
+ /**
1599
+ * helper function for building renderers
1600
+ */
1601
+ function buildRenderer(decorators, defaultRenderer) {
1602
+ if (decorators.length === 0) return defaultRenderer;
1603
+ let renderer = defaultRenderer;
1604
+ for (const decorator of decorators) {
1605
+ const previousRenderer = renderer;
1606
+ renderer = (ctx) => decorator(previousRenderer, ctx);
1607
+ }
1608
+ return renderer;
1609
+ }
1610
+ /**
1611
+ * public interfaces
1612
+ */
1613
+ return Object.freeze({
1614
+ addHeaderDecorator(decorator) {
1615
+ headerDecorators.push(decorator);
1616
+ },
1617
+ addUsageDecorator(decorator) {
1618
+ usageDecorators.push(decorator);
1619
+ },
1620
+ addValidationErrorsDecorator(decorator) {
1621
+ validationDecorators.push(decorator);
1622
+ },
1623
+ addCommandDecorator(decorator) {
1624
+ commandDecorators.push(decorator);
1625
+ },
1626
+ get commandDecorators() {
1627
+ return [...commandDecorators];
1628
+ },
1629
+ getHeaderRenderer() {
1630
+ return buildRenderer(headerDecorators, EMPTY_RENDERER);
1631
+ },
1632
+ getUsageRenderer() {
1633
+ return buildRenderer(usageDecorators, EMPTY_RENDERER);
1634
+ },
1635
+ getValidationErrorsRenderer() {
1636
+ if (validationDecorators.length === 0) return EMPTY_RENDERER;
1637
+ let renderer = EMPTY_RENDERER;
1638
+ for (const decorator of validationDecorators) {
1639
+ const previousRenderer = renderer;
1640
+ renderer = (ctx, error) => decorator(previousRenderer, ctx, error);
1641
+ }
1642
+ return renderer;
1643
+ }
1644
+ });
1645
+ }
1646
+ /**
1647
+ * @author kazuya kawaguchi (a.k.a. kazupon)
1648
+ * @license MIT
1649
+ */
1650
+ /**
1651
+ * Factory function for creating a plugin context.
1652
+ *
1653
+ * @typeParam G - A type extending {@linkcode GunshiParams} to specify the shape of command parameters.
1654
+ *
1655
+ * @param decorators - A {@linkcode Decorators} instance.
1656
+ * @param initialSubCommands - Initial sub commands map.
1657
+ * @returns A new {@linkcode PluginContext} instance.
1658
+ */
1659
+ function createPluginContext(decorators, initialSubCommands) {
1660
+ /**
1661
+ * private states
1662
+ */
1663
+ const globalOptions = /* @__PURE__ */ new Map();
1664
+ const subCommands = new Map(initialSubCommands || []);
1665
+ /**
1666
+ * public interfaces
1667
+ */
1668
+ return Object.freeze({
1669
+ get globalOptions() {
1670
+ return new Map(globalOptions);
1671
+ },
1672
+ addGlobalOption(name, schema) {
1673
+ if (!name) throw new Error("Option name must be a non-empty string");
1674
+ if (globalOptions.has(name)) throw new Error(`Global option '${name}' is already registered`);
1675
+ /**
1676
+ * NOTE(kazupon): a short name belongs to one option. The global options of a CLI come from
1677
+ * plugins that know nothing of each other, so two of them may reach for the same letter, and
1678
+ * the parser would then match both and give neither the value that was typed. The one that
1679
+ * asked first keeps the letter, and the other keeps its long name — the same way a global
1680
+ * option gives its short name up to an argument of the command that claims it.
1681
+ */
1682
+ const taken = schema.short && findGlobalOptionByShort(globalOptions, schema.short);
1683
+ if (taken) {
1684
+ console.warn(`Short name '-${schema.short}' of the global option '${name}' is already used by '${taken}'. Global option '${name}' is registered without it.`);
1685
+ globalOptions.set(name, {
1686
+ ...schema,
1687
+ short: void 0
1688
+ });
1689
+ return;
1690
+ }
1691
+ globalOptions.set(name, schema);
1692
+ },
1693
+ get subCommands() {
1694
+ return new Map(subCommands);
1695
+ },
1696
+ addCommand(name, command) {
1697
+ if (!name) throw new Error("Command name must be a non-empty string");
1698
+ if (subCommands.has(name)) throw new Error(`Command '${name}' is already registered`);
1699
+ subCommands.set(name, command);
1700
+ },
1701
+ hasCommand(name) {
1702
+ return subCommands.has(name);
1703
+ },
1704
+ decorateHeaderRenderer(decorator) {
1705
+ decorators.addHeaderDecorator(decorator);
1706
+ },
1707
+ decorateUsageRenderer(decorator) {
1708
+ decorators.addUsageDecorator(decorator);
1709
+ },
1710
+ decorateValidationErrorsRenderer(decorator) {
1711
+ decorators.addValidationErrorsDecorator(decorator);
1712
+ },
1713
+ decorateCommand(decorator) {
1714
+ decorators.addCommandDecorator(decorator);
1715
+ }
1716
+ });
1717
+ }
1718
+ /**
1719
+ * Find the global option that already uses a short name.
1720
+ *
1721
+ * @param globalOptions - The global options registered so far
1722
+ * @param short - A short name, without the leading dash
1723
+ * @returns The name of the global option that uses it, or `undefined`
1724
+ */
1725
+ function findGlobalOptionByShort(globalOptions, short) {
1726
+ for (const [name, schema] of globalOptions) if (schema.short === short) return name;
1727
+ }
1728
+ /**
1729
+ * @author kazuya kawaguchi (a.k.a. kazupon)
1730
+ * @license MIT
1731
+ */
1732
+ /**
1733
+ * Resolve plugin dependencies using topological sort
1734
+ *
1735
+ * @param plugins - Array of plugins to resolve
1736
+ * @returns Array of plugins sorted by dependencies
1737
+ */
1738
+ function resolveDependencies(plugins) {
1739
+ const sorted = [];
1740
+ const visited = /* @__PURE__ */ new Set();
1741
+ const visiting = /* @__PURE__ */ new Set();
1742
+ const pluginMap = /* @__PURE__ */ new Map();
1743
+ for (const plugin of plugins) {
1744
+ if (typeof plugin.id !== "string" || plugin.id.length === 0) throw new Error("Plugin id must be a non-empty string");
1745
+ if (pluginMap.has(plugin.id)) console.warn(`Duplicate plugin id detected: \`${plugin.id}\``);
1746
+ pluginMap.set(plugin.id, plugin);
1747
+ }
1748
+ function visit(plugin) {
1749
+ if (typeof plugin.id !== "string" || plugin.id.length === 0) throw new Error("Plugin id must be a non-empty string");
1750
+ if (visited.has(plugin.id)) return;
1751
+ if (visiting.has(plugin.id)) throw new Error(`Circular dependency detected: \`${[...visiting].join(` -> `) + " -> " + plugin.id}\``);
1752
+ visiting.add(plugin.id);
1753
+ const deps = plugin.dependencies || [];
1754
+ for (const dep of deps) {
1755
+ const depId = typeof dep === "string" ? dep : dep.id;
1756
+ const isOptional = typeof dep === "string" ? false : dep.optional || false;
1757
+ const depPlugin = pluginMap.get(depId);
1758
+ if (!depPlugin && !isOptional) throw new Error(`Missing required dependency: \`${depId}\` on \`${plugin.id}\``);
1759
+ if (depPlugin) visit(depPlugin);
1760
+ }
1761
+ visiting.delete(plugin.id);
1762
+ visited.add(plugin.id);
1763
+ sorted.push(plugin);
1764
+ }
1765
+ for (const plugin of plugins) visit(plugin);
1766
+ return sorted;
1767
+ }
1768
+ /**
1769
+ * @author kazuya kawaguchi (a.k.a. kazupon)
1770
+ * @license MIT
1771
+ */
1772
+ /**
1773
+ * Resolve the arguments of a command, the way gunshi parses and renders them.
1774
+ *
1775
+ * The global options belong to no command definition, so they are merged into the arguments of the
1776
+ * command that runs. An argument of the command shadows the global option of the same name, and it
1777
+ * shadows the same way by short name: a global option gives up its short name to an argument of the
1778
+ * command that claims the same letter, and keeps its long name.
1779
+ *
1780
+ * NOTE(kazupon): this is not exported from the entry points. `@gunshi/plugin-completion` completes
1781
+ * the arguments the same way with the copy in `@gunshi/shared`, and the tests of that copy pin it
1782
+ * to the results of this one, so a change here has to be made there too.
1783
+ *
1784
+ * @param globalOptions - The global options that plugins registered with `addGlobalOption`
1785
+ * @param args - The arguments that the command declares
1786
+ * @returns The merged arguments
1787
+ */
1788
+ function resolveCommandArgs(globalOptions, args) {
1789
+ return Object.assign(create(), resolveGlobalOptions(globalOptions, args), args);
1790
+ }
1791
+ function resolveGlobalOptions(globalOptions, args) {
1792
+ if (!globalOptions) return;
1793
+ const shortNames = /* @__PURE__ */ new Set();
1794
+ for (const schema of Object.values(args || {})) if (schema.type !== "positional" && schema.short) shortNames.add(schema.short);
1795
+ const resolved = create();
1796
+ for (const [name, schema] of globalOptions)
1797
+ /**
1798
+ * NOTE(kazupon): a copy, because the schema is the one that the plugin registered, which every
1799
+ * command of the CLI shares. Only this command gives up the short name.
1800
+ */
1801
+ resolved[name] = schema.short && shortNames.has(schema.short) ? {
1802
+ ...schema,
1803
+ short: void 0
1804
+ } : schema;
1805
+ return resolved;
1806
+ }
1807
+ /**
1808
+ * @author kazuya kawaguchi (a.k.a. kazupon)
1809
+ * @license MIT
1810
+ */
1811
+ /**
1812
+ * Run the command.
1813
+ *
1814
+ * @typeParam G - A type extending {@linkcode GunshiParams} to specify the shape of command and cli options.
1815
+ *
1816
+ * @param argv - Command line arguments
1817
+ * @param entry - A {@link Command | entry command}, an {@link CommandRunner | inline command runner}, or a {@link LazyCommand | lazily-loaded command}
1818
+ * @param options - A {@link CliOptions | CLI options}
1819
+ * @param plugins - An array of {@link Plugin | plugins} to be applied
1820
+ * @param usageOnly - Whether to render the usage of the command instead of running it, which is what `generate` of `gunshi/generator` asks for
1821
+ * @returns A rendered usage or undefined. if you will use {@link CliOptions.usageSilent} option, it will return rendered usage string.
1822
+ */
1823
+ async function cliCore(argv, entry, options, plugins, usageOnly = false) {
1824
+ const decorators = createDecorators();
1825
+ /**
1826
+ * NOTE(kazupon): the decorator goes on before any plugin, which makes it the outermost one, so
1827
+ * that the usage is rendered whatever the command declares and the runner is never reached.
1828
+ */
1829
+ if (usageOnly) decorators.addCommandDecorator(usageOnlyDecorator());
1830
+ const entryCommand = createEntryCommand(entry);
1831
+ const initialSubCommands = createInitialSubCommands(options, entryCommand);
1832
+ const pluginContext = createPluginContext(decorators, initialSubCommands);
1833
+ const resolvedPlugins = await applyPlugins(pluginContext, [...plugins, ...options.plugins || []]);
1834
+ const cliOptions = normalizeCliOptions(options, decorators, pluginContext, entryCommand);
1835
+ /**
1836
+ * NOTE(kazupon): a CLI whose user declares no sub-commands has no command tree of its own,
1837
+ * so a positional argument must not become a command name just because a plugin added a command.
1838
+ * The user can still opt out with an explicit `fallbackToEntry: false`.
1839
+ */
1840
+ if (initialSubCommands.size === 0 && cliOptions.subCommands.size > 0 && options.fallbackToEntry === void 0) cliOptions.fallbackToEntry = true;
1841
+ const tokens = parseArgs(argv);
1842
+ const selection = resolveCommandSelection(tokens, entry, cliOptions, pluginContext.globalOptions);
1843
+ const resolved = selection.context;
1844
+ const { commandName: name, command, callMode, commandPath, depth, levelSubCommands } = resolved;
1845
+ let targetCommand = command;
1846
+ let targetCommandName = name;
1847
+ let targetCallMode = callMode;
1848
+ let targetCommandPath = commandPath;
1849
+ let targetDepth = depth;
1850
+ let targetOmitted = resolved.omitted;
1851
+ let targetLevelSubCommands = levelSubCommands;
1852
+ const additionalValidationErrors = selection.error ? [selection.error] : [];
1853
+ if (!targetCommand) {
1854
+ if (!resolved.parentCommand || !resolved.unresolvedCommandName) throw new Error(`Command not found: ${name || ""}`);
1855
+ targetCommand = resolved.parentCommand;
1856
+ targetCommandName = resolved.parentCommandName;
1857
+ targetCommandPath = resolved.parentCommandPath || [];
1858
+ targetDepth = targetCommandPath.length;
1859
+ targetCallMode = targetDepth > 0 ? "subCommand" : "entry";
1860
+ targetOmitted = false;
1861
+ targetLevelSubCommands = resolved.parentSubCommands;
1862
+ additionalValidationErrors.push(createCommandNotFoundError(resolved));
1863
+ }
1864
+ const routingOptions = Object.assign(create(), cliOptions, { subCommands: new Map(cliOptions.subCommands) });
1865
+ if (targetLevelSubCommands) cliOptions.subCommands = targetLevelSubCommands;
1866
+ const resolvedCommand = isLazyCommand(targetCommand) ? await resolveLazyCommand(targetCommand, targetCommandName, true) : targetCommand;
1867
+ if (selection.error == null && isLazyCommand(targetCommand)) {
1868
+ const loaded = resolveCommandTreeFromPositionals(getRoutingPositionals(tokens, pluginContext.globalOptions, resolvedCommand), entry, routingOptions);
1869
+ if (!sameCommandPath(loaded.commandPath, targetCommandPath)) additionalValidationErrors.push(createLazySchemaMismatchError(targetCommandPath, loaded.commandPath));
1870
+ }
1871
+ const commandArgs = getCommandArgs(resolvedCommand);
1872
+ const args = resolveCommandArgs(pluginContext.globalOptions, commandArgs);
1873
+ /**
1874
+ * NOTE(kazupon): a plugin cannot tell on its own whether the global option it registered survived
1875
+ * the merge, so the core says which ones are in effect for this command (#745).
1876
+ */
1877
+ cliOptions.globalOptions = resolveEffectiveGlobalOptions(pluginContext.globalOptions, commandArgs, args);
1878
+ const skipPositional = resolveSkipPositional(tokens, pluginContext.globalOptions, resolvedCommand, targetDepth);
1879
+ const diagnostic = selection.diagnostic === true;
1880
+ const { explicit, values, positionals, rest, error } = diagnostic ? {
1881
+ explicit: create(),
1882
+ values: create(),
1883
+ positionals: [],
1884
+ rest: [],
1885
+ error: void 0
1886
+ } : resolveArgs(args, tokens, {
1887
+ shortGrouping: true,
1888
+ toKebab: resolvedCommand.toKebab,
1889
+ skipPositional
1890
+ });
1891
+ const validationError = mergeValidationErrors(error, [...additionalValidationErrors, ...cliOptions.strict && !diagnostic ? createUnknownOptionErrors(findUnknownOptions(args, tokens, { toKebab: resolvedCommand.toKebab })) : []]);
1892
+ return await executeCommand(resolvedCommand, await createCommandContext({
1893
+ args,
1894
+ explicit,
1895
+ values,
1896
+ positionals,
1897
+ rest,
1898
+ argv,
1899
+ tokens,
1900
+ omitted: targetOmitted,
1901
+ callMode: targetCallMode,
1902
+ commandPath: targetCommandPath,
1903
+ command: resolvedCommand,
1904
+ extensions: getPluginExtensions(resolvedPlugins),
1905
+ validationError,
1906
+ cliOptions
1907
+ }), decorators.commandDecorators);
1908
+ }
1909
+ /**
1910
+ * Create the decorator that renders the usage of the command instead of running it.
1911
+ *
1912
+ * NOTE(kazupon): `generate()` of `gunshi/generator` asks the core for a usage. It used to ask by
1913
+ * adding `-h` to the arguments, which made the answer depend on what the command calls its own
1914
+ * arguments: a command that declares one named `help` takes the schema of the global option, and
1915
+ * the usage was never rendered. A decorator is not an argument, so no command can take it away.
1916
+ *
1917
+ * @returns A {@linkcode CommandDecorator | command decorator} that renders the usage
1918
+ */
1919
+ function usageOnlyDecorator() {
1920
+ return () => async (ctx) => {
1921
+ if (hasPriorityValidationError(ctx.validationError)) throw ctx.validationError;
1922
+ const buf = [];
1923
+ if (ctx.env.renderHeader != null) {
1924
+ const header = await ctx.env.renderHeader(ctx);
1925
+ if (header) buf.push(header);
1926
+ }
1927
+ if (ctx.env.renderUsage == null) return;
1928
+ const usage = await ctx.env.renderUsage(ctx);
1929
+ if (!usage) return;
1930
+ buf.push(usage);
1931
+ return buf.join("\n");
1932
+ };
1933
+ }
1934
+ async function applyPlugins(pluginContext, plugins) {
1935
+ const sortedPlugins = resolveDependencies(plugins);
1936
+ for (const plugin of sortedPlugins) try {
1937
+ /**
1938
+ * NOTE(kazupon):
1939
+ * strictly `Args` are not required for plugin installation.
1940
+ * because the strictly `Args` required by each plugin are unknown,
1941
+ * and the plugin side can not know what the user will specify.
1942
+ */
1943
+ await plugin(pluginContext);
1944
+ } catch (error) {
1945
+ /**
1946
+ * NOTE(kazupon): a plugin that cannot be installed leaves the CLI without the options, the
1947
+ * commands and the decorators it was written to add, and the plugins behind it are not
1948
+ * installed either, while their context extensions are handed to the command all the same.
1949
+ * `resolveDependencies()` already ends the run for a circular or a missing dependency, so a
1950
+ * `setup` that throws ends it too, naming the plugin rather than leaving the failure to
1951
+ * surface somewhere else.
1952
+ */
1953
+ throw new Error(`Failed to install the plugin \`${plugin.id}\``, { cause: error });
1954
+ }
1955
+ return sortedPlugins;
1956
+ }
1957
+ /**
1958
+ * Resolve the global options that are in effect for the command being executed.
1959
+ *
1960
+ * A global option is in effect unless the command declares an argument of its own under the same
1961
+ * name, which replaces it. The schema is taken from the merged arguments, so it is the one in effect.
1962
+ *
1963
+ * @param globalOptions - The global options that plugins registered with `addGlobalOption`
1964
+ * @param commandArgs - The arguments that the command declares
1965
+ * @param args - The merged arguments
1966
+ * @returns The global options in effect, keyed by name
1967
+ */
1968
+ function resolveEffectiveGlobalOptions(globalOptions, commandArgs, args) {
1969
+ const effective = /* @__PURE__ */ new Map();
1970
+ for (const name of globalOptions.keys()) if (!Object.hasOwn(commandArgs, name)) effective.set(name, args[name]);
1971
+ return effective;
1972
+ }
1973
+ function getCommandArgs(cmd) {
1974
+ if (isLazyCommand(cmd)) return cmd.args || create();
1975
+ else if (typeof cmd === "object") return cmd.args || create();
1976
+ else return create();
1977
+ }
1978
+ const NEGATABLE_OPTION_PREFIX = "no-";
1979
+ function findUnknownOptions(args, tokens, options) {
1980
+ const knownLongOptions = /* @__PURE__ */ new Set();
1981
+ const knownShortOptions = /* @__PURE__ */ new Set();
1982
+ const knownNegatableOptions = /* @__PURE__ */ new Set();
1983
+ const knownLongOptionCandidates = /* @__PURE__ */ new Set();
1984
+ const longOptionCandidates = [];
1985
+ function addLongOptionCandidate(name) {
1986
+ const candidate = `--${name}`;
1987
+ if (knownLongOptionCandidates.has(candidate)) return;
1988
+ knownLongOptionCandidates.add(candidate);
1989
+ longOptionCandidates.push(candidate);
1990
+ }
1991
+ for (const [name, schema] of Object.entries(args)) {
1992
+ if (schema.type === "positional") continue;
1993
+ const optionName = resolveOptionName(name, schema, options);
1994
+ knownLongOptions.add(optionName);
1995
+ /**
1996
+ * NOTE(kazupon): a hidden option is still accepted, so it stays a known option. It is left out
1997
+ * of the candidates, which are what `@gunshi/plugin-suggestion` offers as "Did you mean".
1998
+ */
1999
+ if (!schema.hidden) addLongOptionCandidate(optionName);
2000
+ if (schema.short) knownShortOptions.add(schema.short);
2001
+ if (schema.type === "boolean" && schema.negatable) {
2002
+ const negatableOptionName = `${NEGATABLE_OPTION_PREFIX}${optionName}`;
2003
+ knownNegatableOptions.add(negatableOptionName);
2004
+ if (!schema.hidden) addLongOptionCandidate(negatableOptionName);
2005
+ }
2006
+ }
2007
+ const unknownOptions = [];
2008
+ for (const token of tokens) {
2009
+ if (token.kind === "option-terminator") break;
2010
+ if (token.kind !== "option" || !token.name || !token.rawName) continue;
2011
+ const isLongOption = token.rawName.startsWith("--");
2012
+ if (isLongOption) {
2013
+ if (knownLongOptions.has(token.name) || knownNegatableOptions.has(token.name)) continue;
2014
+ } else if (knownShortOptions.has(token.name)) continue;
2015
+ unknownOptions.push({
2016
+ rawName: token.rawName,
2017
+ name: token.name,
2018
+ candidates: isLongOption ? longOptionCandidates : []
2019
+ });
2020
+ }
2021
+ return unknownOptions;
2022
+ }
2023
+ function resolveOptionName(name, schema, options) {
2024
+ return options.toKebab || schema.toKebab ? kebabnize(name) : name;
2025
+ }
2026
+ function createUnknownOptionErrors(unknownOptions) {
2027
+ return unknownOptions.map(({ rawName, name, candidates }) => {
2028
+ return new ArgsValidationError(`Unknown option: ${rawName}`, {
2029
+ code: ArgsValidationErrorKeys.unknownOption,
2030
+ values: {
2031
+ rawName,
2032
+ name,
2033
+ candidates
2034
+ }
2035
+ });
2036
+ });
2037
+ }
2038
+ function mergeValidationErrors(error, additionalErrors) {
2039
+ if (additionalErrors.length === 0) return error;
2040
+ return new AggregateError(error ? [...error.errors, ...additionalErrors] : additionalErrors, error?.message || additionalErrors[0]?.message);
2041
+ }
2042
+ const isObject = (val) => val !== null && typeof val === "object";
2043
+ /**
2044
+ * Create the entry command that sub-commands and plugins can see.
2045
+ * The user-provided entry is copied, so that marking it with `entry: true` does not mutate it.
2046
+ *
2047
+ * @param entryCmd - The entry that is passed to `cli`
2048
+ * @returns The entry command marked with `entry: true`, or `undefined` if the entry is not a command
2049
+ */
2050
+ function createEntryCommand(entryCmd) {
2051
+ if (isLazyCommand(entryCmd)) return Object.assign((...args) => entryCmd(...args), entryCmd, { entry: true });
2052
+ else if (typeof entryCmd === "object") return Object.assign(create(), entryCmd, { entry: true });
2053
+ else if (typeof entryCmd === "function") return {
2054
+ run: entryCmd,
2055
+ name: entryCmd.name || "(anonymous)",
2056
+ entry: true
2057
+ };
2058
+ }
2059
+ function createInitialSubCommands(options, entryCommand) {
2060
+ const hasSubCommands = options.subCommands ? options.subCommands instanceof Map ? options.subCommands.size > 0 : isObject(options.subCommands) && Object.keys(options.subCommands).length > 0 : false;
2061
+ const subCommands = new Map(options.subCommands instanceof Map ? options.subCommands : []);
2062
+ if (!(options.subCommands instanceof Map) && isObject(options.subCommands)) for (const [name, cmd] of Object.entries(options.subCommands)) subCommands.set(name, cmd);
2063
+ if (hasSubCommands && entryCommand) subCommands.set(resolveEntryName(entryCommand), entryCommand);
2064
+ return subCommands;
2065
+ }
2066
+ function normalizeCliOptions(options, decorators, pluginContext, entryCommand) {
2067
+ const subCommands = new Map(pluginContext.subCommands);
2068
+ /**
2069
+ * NOTE(kazupon): the entry command is part of `subCommands` only when the user passes sub-commands,
2070
+ * so it is exposed on its own for the plugins that add commands to a CLI without sub-commands.
2071
+ */
2072
+ const resolvedOptions = Object.assign(create(), CLI_OPTIONS_DEFAULT, options, {
2073
+ subCommands,
2074
+ entryCommand
2075
+ });
2076
+ if (resolvedOptions.renderHeader === void 0) resolvedOptions.renderHeader = decorators.getHeaderRenderer();
2077
+ if (resolvedOptions.renderUsage === void 0) resolvedOptions.renderUsage = decorators.getUsageRenderer();
2078
+ if (resolvedOptions.renderValidationErrors === void 0) resolvedOptions.renderValidationErrors = decorators.getValidationErrorsRenderer();
2079
+ return resolvedOptions;
2080
+ }
2081
+ function getPositionalTokens(tokens) {
2082
+ const positionals = [];
2083
+ for (const token of tokens) {
2084
+ if (token.kind === "option-terminator") break;
2085
+ if (token.kind === "positional" && token.value) positionals.push(token.value);
2086
+ }
2087
+ return positionals;
2088
+ }
2089
+ function resolveCommandTree(tokens, entry, options) {
2090
+ return resolveCommandTreeFromPositionals(getPositionalTokens(tokens), entry, options);
2091
+ }
2092
+ function resolveCommandTreeFromPositionals(positionals, entry, options) {
2093
+ function resolveAsEntry() {
2094
+ if (typeof entry === "function") {
2095
+ if (isLazyCommand(entry)) return {
2096
+ commandName: resolveEntryName(entry),
2097
+ command: entry,
2098
+ callMode: "entry",
2099
+ commandPath: [],
2100
+ depth: 0,
2101
+ omitted: options.subCommands.size > 0 && !positionals[0],
2102
+ levelSubCommands: options.subCommands.size > 0 ? options.subCommands : void 0
2103
+ };
2104
+ else return {
2105
+ command: {
2106
+ run: entry,
2107
+ entry: true
2108
+ },
2109
+ callMode: "entry",
2110
+ commandPath: [],
2111
+ depth: 0,
2112
+ omitted: options.subCommands.size > 0 && !positionals[0],
2113
+ levelSubCommands: options.subCommands.size > 0 ? options.subCommands : void 0
2114
+ };
2115
+ } else if (typeof entry === "object") return {
2116
+ commandName: resolveEntryName(entry),
2117
+ command: entry,
2118
+ callMode: "entry",
2119
+ commandPath: [],
2120
+ depth: 0,
2121
+ omitted: options.subCommands.size > 0 && !positionals[0],
2122
+ levelSubCommands: options.subCommands.size > 0 ? options.subCommands : void 0
2123
+ };
2124
+ else return {
2125
+ callMode: "unexpected",
2126
+ commandPath: [],
2127
+ depth: 0,
2128
+ omitted: false,
2129
+ levelSubCommands: void 0
2130
+ };
2131
+ }
2132
+ if (positionals.length === 0 || options.subCommands.size === 0) return resolveAsEntry();
2133
+ let currentSubCommands = options.subCommands;
2134
+ let resolvedCommand;
2135
+ let resolvedName;
2136
+ const commandPath = [];
2137
+ let depth = 0;
2138
+ for (let i = 0; i < positionals.length; i++) {
2139
+ const token = positionals[i];
2140
+ const cmd = currentSubCommands.get(token);
2141
+ if (cmd == null) {
2142
+ if (depth === 0) {
2143
+ if (options.fallbackToEntry) return resolveAsEntry();
2144
+ const parent = resolveAsEntry();
2145
+ return {
2146
+ commandName: token,
2147
+ callMode: "unexpected",
2148
+ commandPath: [],
2149
+ depth: 0,
2150
+ omitted: false,
2151
+ levelSubCommands: void 0,
2152
+ unresolvedCommandName: token,
2153
+ parentCommand: parent.command,
2154
+ parentCommandName: parent.commandName,
2155
+ parentCommandPath: [],
2156
+ parentSubCommands: options.subCommands
2157
+ };
2158
+ }
2159
+ return {
2160
+ commandName: token,
2161
+ callMode: "unexpected",
2162
+ commandPath: [...commandPath],
2163
+ depth,
2164
+ omitted: false,
2165
+ levelSubCommands: void 0,
2166
+ unresolvedCommandName: token,
2167
+ parentCommand: resolvedCommand,
2168
+ parentCommandName: resolvedName,
2169
+ parentCommandPath: [...commandPath],
2170
+ parentSubCommands: currentSubCommands
2171
+ };
2172
+ }
2173
+ let resolved = cmd;
2174
+ if (typeof cmd === "function" && cmd.commandName == null) resolved = Object.assign((...args) => cmd(...args), cmd, { commandName: token });
2175
+ else if (typeof cmd === "object" && cmd.name == null) resolved = Object.assign(create(), cmd, { name: token });
2176
+ resolvedCommand = resolved;
2177
+ resolvedName = token;
2178
+ commandPath.push(token);
2179
+ depth++;
2180
+ const nestedSubCommands = getCommandSubCommands(cmd);
2181
+ if (nestedSubCommands && nestedSubCommands.size > 0) currentSubCommands = nestedSubCommands;
2182
+ else break;
2183
+ }
2184
+ if (!resolvedCommand) return resolveAsEntry();
2185
+ const resolvedSubCommands = getCommandSubCommands(resolvedCommand);
2186
+ const omitted = resolvedSubCommands != null && resolvedSubCommands.size > 0;
2187
+ let levelSubCommands;
2188
+ if (omitted && resolvedSubCommands) {
2189
+ levelSubCommands = new Map(resolvedSubCommands);
2190
+ let entryCopy;
2191
+ if (typeof resolvedCommand === "function") entryCopy = Object.assign((...args) => resolvedCommand(...args), resolvedCommand, { entry: true });
2192
+ else entryCopy = Object.assign(create(), resolvedCommand, { entry: true });
2193
+ levelSubCommands.set(resolvedName || resolveEntryName(entryCopy), entryCopy);
2194
+ }
2195
+ return {
2196
+ commandName: resolvedName,
2197
+ command: resolvedCommand,
2198
+ callMode: depth > 0 ? "subCommand" : "entry",
2199
+ commandPath,
2200
+ depth,
2201
+ omitted,
2202
+ levelSubCommands
2203
+ };
2204
+ }
2205
+ /**
2206
+ * Select a command while accounting for option values that args-tokens removes during resolution.
2207
+ *
2208
+ * The routing pass deliberately projects each candidate's schemas down to the metadata needed to
2209
+ * classify tokens. It never copies `parse`, defaults, required checks, or other user code. A
2210
+ * candidate is accepted only when routing its own declaration reaches the same Map-key path in the
2211
+ * declaration tree.
2212
+ *
2213
+ * @param tokens - Tokenized command-line arguments
2214
+ * @param entry - Entry command definition or runner
2215
+ * @param options - Internal CLI options with the declared sub-command tree
2216
+ * @param globalOptions - Global option schemas used during candidate classification
2217
+ * @returns The selected command context or a diagnostic resolution error
2218
+ */
2219
+ function resolveCommandSelection(tokens, entry, options, globalOptions) {
2220
+ const rawPositionals = getPositionalTokens(tokens);
2221
+ const legacy = resolveCommandTree(tokens, entry, options);
2222
+ if (!tokens.some((token) => token.kind === "option")) return { context: legacy };
2223
+ const candidates = collectRoutingCandidates(rawPositionals, options.subCommands);
2224
+ const evaluations = candidates.map((candidate) => evaluateRoutingCandidate(candidate));
2225
+ const validExplicit = evaluations.filter((evaluation) => evaluation.result.command != null && evaluation.result.unresolvedCommandName == null && sameCommandPath(evaluation.result.commandPath, evaluation.path) && evaluation.path.length > 0);
2226
+ if (legacy.command != null && legacy.unresolvedCommandName == null && legacy.commandPath.length > 0) {
2227
+ const legacyMatch = validExplicit.find((evaluation) => sameCommandPath(evaluation.path, legacy.commandPath));
2228
+ if (legacyMatch) return { context: legacyMatch.result };
2229
+ }
2230
+ if (validExplicit.length === 1) return { context: validExplicit[0].result };
2231
+ if (validExplicit.length > 1) return createCommandResolutionResult(options, entry, CommandResolutionErrorKeys.ambiguous, validExplicit.map((evaluation) => evaluation.path));
2232
+ const entryEvaluation = evaluateRoutingCandidate({
2233
+ path: [],
2234
+ command: getEntryRoutingCommand(entry, options)
2235
+ });
2236
+ if (entryEvaluation.result.command != null && entryEvaluation.result.unresolvedCommandName == null && entryEvaluation.result.commandPath.length === 0) return { context: entryEvaluation.result };
2237
+ const failures = evaluations.filter((evaluation) => {
2238
+ const { result } = evaluation;
2239
+ if (!result.unresolvedCommandName) return false;
2240
+ const parentPath = result.parentCommandPath || [];
2241
+ return isPathPrefix(evaluation.path, parentPath);
2242
+ }).map((evaluation) => evaluation.result);
2243
+ if (entryEvaluation.result.unresolvedCommandName) failures.push(entryEvaluation.result);
2244
+ const deepestFailures = selectDeepestFailures(failures);
2245
+ if (deepestFailures.length === 1) return { context: deepestFailures[0] };
2246
+ if (deepestFailures.length > 1) {
2247
+ const paths = deepestFailures.map((result) => result.parentCommandPath || []);
2248
+ return createCommandResolutionResult(options, entry, CommandResolutionErrorKeys.ambiguous, paths);
2249
+ }
2250
+ return createCommandResolutionResult(options, entry, CommandResolutionErrorKeys.inconsistentOptions, candidates.map((candidate) => candidate.path));
2251
+ function evaluateRoutingCandidate(candidate) {
2252
+ const positionals = getRoutingPositionals(tokens, globalOptions, candidate.command);
2253
+ return {
2254
+ ...candidate,
2255
+ positionals,
2256
+ result: resolveCommandTreeFromPositionals(positionals, entry, options)
2257
+ };
2258
+ }
2259
+ }
2260
+ function collectRoutingCandidates(rawPositionals, root) {
2261
+ const candidates = [];
2262
+ const seen = /* @__PURE__ */ new Set();
2263
+ function collect(commands, offset, parentPath) {
2264
+ for (let index = offset; index < rawPositionals.length; index++) {
2265
+ const name = rawPositionals[index];
2266
+ const command = commands.get(name);
2267
+ if (command == null) continue;
2268
+ const path = [...parentPath, name];
2269
+ const key = JSON.stringify(path);
2270
+ const normalized = normalizeCommandReference(command, name);
2271
+ if (!seen.has(key)) {
2272
+ seen.add(key);
2273
+ candidates.push({
2274
+ path,
2275
+ command: normalized
2276
+ });
2277
+ }
2278
+ const nested = getCommandSubCommands(normalized);
2279
+ if (nested && nested.size > 0) collect(nested, index + 1, path);
2280
+ }
2281
+ }
2282
+ collect(root, 0, []);
2283
+ return candidates;
2284
+ }
2285
+ function normalizeCommandReference(command, name) {
2286
+ if (typeof command === "function" && command.commandName == null) return Object.assign((...args) => command(...args), command, { commandName: name });
2287
+ if (typeof command === "object" && command.name == null) return Object.assign(create(), command, { name });
2288
+ return command;
2289
+ }
2290
+ function getEntryRoutingCommand(entry, options) {
2291
+ if (options.entryCommand) return options.entryCommand;
2292
+ if (typeof entry === "function" && !isLazyCommand(entry)) return {
2293
+ run: entry,
2294
+ entry: true
2295
+ };
2296
+ return entry;
2297
+ }
2298
+ function getRoutingPositionals(tokens, globalOptions, command) {
2299
+ /**
2300
+ * NOTE(kazupon): an empty argument is never a command name. `getPositionalTokens()` skips it when it
2301
+ * collects the candidates, and the routing of each candidate must skip it too; otherwise the routing
2302
+ * looks for a sub-command named `''`, and fails with `inconsistent-options` (#781).
2303
+ */
2304
+ return readPositionals(tokens, globalOptions, command).filter((value) => value !== "");
2305
+ }
2306
+ /**
2307
+ * Read the positional arguments as `resolveArgs()` reads them for a command, empty ones included.
2308
+ *
2309
+ * The schemas are projected down to the metadata that classifies the tokens, so no code of the user,
2310
+ * such as `parse`, runs.
2311
+ *
2312
+ * @param tokens - Tokenized command-line arguments
2313
+ * @param globalOptions - Global option schemas
2314
+ * @param command - The command whose arguments classify the tokens
2315
+ * @returns The positional arguments, in the order that `skipPositional` of args-tokens counts them
2316
+ */
2317
+ function readPositionals(tokens, globalOptions, command) {
2318
+ const effective = resolveCommandArgs(globalOptions, getCommandArgs(command));
2319
+ const routingArgs = create();
2320
+ for (const [name, schema] of Object.entries(effective)) {
2321
+ if (schema.type === "positional") continue;
2322
+ routingArgs[name] = {
2323
+ type: schema.type === "boolean" ? "boolean" : "string",
2324
+ short: schema.short,
2325
+ negatable: schema.negatable,
2326
+ toKebab: schema.toKebab
2327
+ };
2328
+ }
2329
+ return resolveArgs(routingArgs, tokens, {
2330
+ shortGrouping: true,
2331
+ toKebab: command.toKebab
2332
+ }).positionals;
2333
+ }
2334
+ /**
2335
+ * Resolve `skipPositional` of args-tokens: the index of the last positional argument to skip.
2336
+ *
2337
+ * NOTE(kazupon): the command names are the first positional arguments that are not empty, and the
2338
+ * last one is at `depth - 1` only when no empty argument comes before it. `skipPositional` counts every
2339
+ * positional argument, the empty ones too, so `app '' build x` gave `build` to the first positional
2340
+ * argument of `build` (#793). The index is found in the reading of `resolveArgs()`, in which the values
2341
+ * of the options are already taken out, so that an empty value of an option is not counted.
2342
+ *
2343
+ * @param tokens - Tokenized command-line arguments
2344
+ * @param globalOptions - Global option schemas
2345
+ * @param command - The command whose arguments are resolved
2346
+ * @param depth - The number of command names
2347
+ * @returns The index of the last command name among the positional arguments, or `-1` for the entry
2348
+ */
2349
+ function resolveSkipPositional(tokens, globalOptions, command, depth) {
2350
+ if (depth === 0) return -1;
2351
+ if (!tokens.some((token) => token.kind === "positional" && token.value === "")) return depth - 1;
2352
+ let names = 0;
2353
+ for (const [index, value] of readPositionals(tokens, globalOptions, command).entries()) {
2354
+ if (value === "") continue;
2355
+ names++;
2356
+ if (names === depth) return index;
2357
+ }
2358
+ return depth - 1;
2359
+ }
2360
+ function sameCommandPath(left, right) {
2361
+ return left.length === right.length && left.every((name, index) => name === right[index]);
2362
+ }
2363
+ function isPathPrefix(prefix, path) {
2364
+ return prefix.length <= path.length && prefix.every((name, index) => name === path[index]);
2365
+ }
2366
+ function selectDeepestFailures(failures) {
2367
+ const unique = /* @__PURE__ */ new Map();
2368
+ for (const failure of failures) {
2369
+ const path = failure.parentCommandPath || [];
2370
+ const key = JSON.stringify(path);
2371
+ unique.set(key, failure);
2372
+ }
2373
+ const deepest = Math.max(-1, ...[...unique.values()].map((failure) => (failure.parentCommandPath || []).length));
2374
+ return [...unique.values()].filter((failure) => (failure.parentCommandPath || []).length === deepest);
2375
+ }
2376
+ function createCommandResolutionResult(options, entry, code, candidatePaths) {
2377
+ const normalizedPaths = candidatePaths.map((path) => [...path]);
2378
+ const commandPath = commonCommandPath(normalizedPaths);
2379
+ const parent = resolveCommandTreeFromPositionals(commandPath, entry, options);
2380
+ const command = createDiagnosticCommand(parent.command, commandPath.at(-1));
2381
+ const context = {
2382
+ ...parent,
2383
+ command,
2384
+ commandPath,
2385
+ depth: commandPath.length,
2386
+ commandName: parent.commandName || commandPath.at(-1),
2387
+ callMode: commandPath.length > 0 ? "subCommand" : "entry",
2388
+ omitted: false
2389
+ };
2390
+ const formattedPaths = normalizedPaths.map((path) => path.join(" ")).join(", ");
2391
+ const formattedPath = commandPath.join(" ");
2392
+ const values = {
2393
+ commandPath: formattedPath,
2394
+ candidatePaths: formattedPaths,
2395
+ candidates: formattedPaths
2396
+ };
2397
+ return {
2398
+ context,
2399
+ error: new CommandResolutionError(createCommandResolutionMessage(code, formattedPath, formattedPaths), {
2400
+ code,
2401
+ values,
2402
+ commandPath,
2403
+ candidatePaths: normalizedPaths
2404
+ }),
2405
+ diagnostic: true
2406
+ };
2407
+ }
2408
+ function commonCommandPath(paths) {
2409
+ if (paths.length === 0) return [];
2410
+ const common = [...paths[0]];
2411
+ for (const path of paths.slice(1)) {
2412
+ let length = 0;
2413
+ while (length < common.length && length < path.length && common[length] === path[length]) length++;
2414
+ common.length = length;
2415
+ }
2416
+ return common;
2417
+ }
2418
+ function createDiagnosticCommand(command, name) {
2419
+ if (typeof command === "function") return Object.assign(create(), command, {
2420
+ name: command.commandName || name,
2421
+ run: void 0
2422
+ });
2423
+ return Object.assign(create(), command || {}, {
2424
+ name: command?.name || name,
2425
+ run: void 0
2426
+ });
2427
+ }
2428
+ function createCommandResolutionMessage(code, commandPath, candidatePaths) {
2429
+ switch (code) {
2430
+ case CommandResolutionErrorKeys.ambiguous: return `Ambiguous command resolution. Move options after the command name: ${candidatePaths}`;
2431
+ case CommandResolutionErrorKeys.lazySchemaMismatch: return `Lazy command schema mismatch at ${commandPath}. Declare leading options in the lazy definition or move options after the command name.`;
2432
+ default: return "The options do not identify a consistent command. Move options after the command name.";
2433
+ }
2434
+ }
2435
+ function createLazySchemaMismatchError(commandPath, loadedPath) {
2436
+ const expected = [...commandPath];
2437
+ const actual = [...loadedPath];
2438
+ return new CommandResolutionError(`Lazy command schema mismatch at ${expected.join(" ")}. Declare leading options in the lazy definition or move options after the command name.`, {
2439
+ code: CommandResolutionErrorKeys.lazySchemaMismatch,
2440
+ values: {
2441
+ commandPath: expected.join(" "),
2442
+ loadedCommandPath: actual.join(" ")
2443
+ },
2444
+ commandPath: expected,
2445
+ candidatePaths: [expected, actual]
2446
+ });
2447
+ }
2448
+ function createCommandNotFoundError(resolved) {
2449
+ const commandName = resolved.unresolvedCommandName || resolved.commandName || "";
2450
+ return new CommandNotFoundError(`Command not found: ${commandName}`, {
2451
+ code: CommandNotFoundErrorKeys.notFound,
2452
+ values: { commandName },
2453
+ commandName,
2454
+ candidates: [...resolved.parentSubCommands?.keys() || []],
2455
+ commandPath: resolved.parentCommandPath || []
2456
+ });
2457
+ }
2458
+ function resolveEntryName(entry) {
2459
+ return isLazyCommand(entry) ? entry.commandName || "(anonymous)" : entry.name || "(anonymous)";
2460
+ }
2461
+ function getPluginExtensions(plugins) {
2462
+ const extensions = create();
2463
+ for (const plugin of plugins) if (plugin.extension) {
2464
+ const key = plugin.id;
2465
+ if (extensions[key]) console.warn(`Plugin "${key}" is already installed. Ignore it for command context extending.`);
2466
+ else extensions[key] = plugin.extension;
2467
+ }
2468
+ return extensions;
2469
+ }
2470
+ async function executeCommand(cmd, ctx, decorators) {
2471
+ const commandRunner = cmd.run || NOOP;
2472
+ const baseRunner = (ctx) => {
2473
+ if (hasPriorityValidationError(ctx.validationError)) throw ctx.validationError;
2474
+ return commandRunner(ctx);
2475
+ };
2476
+ const decoratedRunner = decorators.reduceRight((runner, decorator) => decorator(runner), baseRunner);
2477
+ try {
2478
+ if (ctx.env.onBeforeCommand) await ctx.env.onBeforeCommand(ctx);
2479
+ const result = await decoratedRunner(ctx);
2480
+ if (ctx.env.onAfterCommand) await ctx.env.onAfterCommand(ctx, result);
2481
+ return typeof result === "string" ? result : void 0;
2482
+ } catch (error) {
2483
+ if (ctx.env.onErrorCommand) try {
2484
+ await ctx.env.onErrorCommand(ctx, error);
2485
+ } catch (hookError) {
2486
+ console.error("Error in onErrorCommand hook:", hookError);
2487
+ }
2488
+ throw error;
2489
+ }
2490
+ }
2491
+ //#endregion
2492
+ //#region node_modules/.bun/gunshi@1.0.0-rc.1/node_modules/gunshi/lib/bone.js
2493
+ /**
2494
+ * @author kazuya kawaguchi (a.k.a. kazupon)
2495
+ * @license MIT
2496
+ */
2497
+ /**
2498
+ * Run the command.
2499
+ *
2500
+ * @typeParam G - A type extending {@linkcode GunshiParams} to specify the shape of command and cli options.
2501
+ *
2502
+ * @param args - Command line arguments
2503
+ * @param entry - A {@link Command | entry command}, an {@link CommandRunner | inline command runner}, or a {@link LazyCommand | lazily-loaded command}
2504
+ * @param options - A {@link CliOptions | CLI options}
2505
+ * @returns A rendered usage or undefined. if you will use {@linkcode CliOptions.usageSilent} option, it will return rendered usage string.
2506
+ */
2507
+ async function cli(args, entry, options = {}) {
2508
+ return cliCore(args, entry, options, []);
2509
+ }
2510
+ /**
2511
+ * @author kazuya kawaguchi (a.k.a. kazupon)
2512
+ * @license MIT
2513
+ */
2514
+ //#endregion
2515
+ //#region node_modules/.bun/gunshi@1.0.0-rc.1/node_modules/gunshi/lib/definition.js
2516
+ /**
2517
+ * @author kazuya kawaguchi (a.k.a. kazupon)
2518
+ * @license MIT
2519
+ */
2520
+ /**
2521
+ * Define a {@link Command | command}.
2522
+ *
2523
+ * @typeParam G - A {@link GunshiParamsConstraint} type
2524
+ *
2525
+ * @param definition - A {@link Command | command} definition
2526
+ * @returns A defined {@link Command | command}
2527
+ */
2528
+ function define(definition) {
2529
+ return definition;
2530
+ }
2531
+ /**
2532
+ * Define a {@link LazyCommand | lazy command} with or without definition.
2533
+ *
2534
+ * @param loader - A {@link CommandLoader | command loader} function that returns a command definition
2535
+ * @param definition - An optional {@link Command | command} definition. Its `name` may be omitted,
2536
+ * including when the lazy command is used as the CLI entry command.
2537
+ * @returns A {@link LazyCommand | lazy command} that can be executed later
2538
+ */
2539
+ function lazy(loader, definition) {
2540
+ let lazyCommand = loader;
2541
+ if ((definition != null || !("commandName" in lazyCommand)) && !Object.isExtensible(lazyCommand)) lazyCommand = Object.assign(() => loader(), loader);
2542
+ if (definition == null && !("commandName" in lazyCommand)) lazyCommand.commandName = void 0;
2543
+ if (definition != null) {
2544
+ lazyCommand.commandName = definition.name;
2545
+ lazyCommand.description = definition.description;
2546
+ lazyCommand.args = definition.args;
2547
+ lazyCommand.examples = definition.examples;
2548
+ lazyCommand.internal = definition.internal;
2549
+ lazyCommand.entry = definition.entry;
2550
+ lazyCommand.toKebab = definition.toKebab;
2551
+ lazyCommand.rendering = definition.rendering;
2552
+ if (definition.subCommands) lazyCommand.subCommands = definition.subCommands;
2553
+ if ("resource" in definition) lazyCommand.resource = definition.resource;
2554
+ }
2555
+ return lazyCommand;
2556
+ }
2557
+ //#endregion
2558
+ //#region node_modules/.bun/gunshi@1.0.0-rc.1/node_modules/gunshi/lib/plugin-Fea3gCnT.js
2559
+ /**
2560
+ * @author kazuya kawaguchi (a.k.a. kazupon)
2561
+ * @license MIT
2562
+ */
2563
+ /**
2564
+ * @author kazuya kawaguchi (a.k.a. kazupon)
2565
+ * @license MIT
2566
+ */
2567
+ //#endregion
9
2568
  //#region src/capture/resolve-capture-dir.ts
10
2569
  function resolveCaptureDir(capture, host) {
11
2570
  return capture.dir ?? join(resolveXDGDir(host, "state"), "captures");
@@ -73,7 +2632,6 @@ async function writeOwnerFile(path, text, flag) {
73
2632
  //#endregion
74
2633
  //#region src/config/build-jev-only-config.ts
75
2634
  function buildJevOnlyConfig(config) {
76
- if (config.provider.protocol !== "system-one") return null;
77
2635
  const judge = config.judge === void 0 || config.judge === null ? config.judge : {
78
2636
  ...config.judge,
79
2637
  timeoutMs: Math.min(config.judge.timeoutMs, CLI_LIMITS.judgeMs)
@@ -95,6 +2653,117 @@ function resolveShippedModDir(startDir = import.meta.dirname) {
95
2653
  return modDir;
96
2654
  }
97
2655
  //#endregion
2656
+ //#region src/process/start-detached-process.ts
2657
+ function startDetachedProcess(file, args, env) {
2658
+ const child = spawn(file, args, {
2659
+ detached: true,
2660
+ stdio: "ignore",
2661
+ env
2662
+ });
2663
+ child.on("error", () => {});
2664
+ child.unref();
2665
+ }
2666
+ //#endregion
2667
+ //#region src/judge/judge-server-response-schema.ts
2668
+ const judgeServerResponseSchema = discriminatedUnion("kind", [strictObject({
2669
+ kind: literal("reply"),
2670
+ text: string(),
2671
+ model: string(),
2672
+ safetyStops: number().nullable(),
2673
+ fallback: boolean(),
2674
+ warm: boolean().nullable()
2675
+ }), strictObject({
2676
+ kind: literal("failure"),
2677
+ aborted: boolean(),
2678
+ message: string()
2679
+ })]);
2680
+ //#endregion
2681
+ //#region src/judge/make-judge-server-session.ts
2682
+ function makeJudgeServerSession(target) {
2683
+ return {
2684
+ review: async (model, request, signal) => {
2685
+ const answer = await sendLine(await tryConnectOrStartServer(target, signal), `${JSON.stringify({
2686
+ model,
2687
+ timeoutMs: target.timeoutMs,
2688
+ ...request
2689
+ })}\n`, signal);
2690
+ const response = judgeServerResponseSchema.parse(JSON.parse(answer));
2691
+ if (response.kind === "failure") throw response.aborted ? new DOMException(response.message, "AbortError") : new Error(response.message);
2692
+ const { kind: _kind, ...reply } = response;
2693
+ return reply;
2694
+ },
2695
+ stop: () => {}
2696
+ };
2697
+ }
2698
+ const START_WAIT_MS = 1e4;
2699
+ const START_POLL_MS = 25;
2700
+ async function tryConnectOrStartServer(target, signal) {
2701
+ const existing = await tryConnect(target.socketPath);
2702
+ if (existing !== null) return existing;
2703
+ const [file, ...args] = target.command;
2704
+ startDetachedProcess(file, [
2705
+ ...args,
2706
+ "judge-server",
2707
+ target.socketPath
2708
+ ], target.env);
2709
+ const deadline = Date.now() + START_WAIT_MS;
2710
+ while (Date.now() < deadline) {
2711
+ await setTimeout(START_POLL_MS, void 0, { signal });
2712
+ const socket = await tryConnect(target.socketPath);
2713
+ if (socket !== null) return socket;
2714
+ }
2715
+ throw new Error("the judge server did not start");
2716
+ }
2717
+ function tryConnect(socketPath) {
2718
+ return new Promise((resolve) => {
2719
+ const socket = connect(socketPath);
2720
+ socket.once("connect", () => {
2721
+ socket.off("error", onError);
2722
+ resolve(socket);
2723
+ });
2724
+ const onError = () => {
2725
+ resolve(null);
2726
+ };
2727
+ socket.once("error", onError);
2728
+ });
2729
+ }
2730
+ function sendLine(socket, line, signal) {
2731
+ return new Promise((resolve, reject) => {
2732
+ const chunks = [];
2733
+ const onAbort = () => {
2734
+ socket.destroy();
2735
+ reject(new DOMException("Judge review aborted", "AbortError"));
2736
+ };
2737
+ if (signal.aborted) {
2738
+ onAbort();
2739
+ return;
2740
+ }
2741
+ signal.addEventListener("abort", onAbort, { once: true });
2742
+ socket.on("data", (chunk) => {
2743
+ chunks.push(chunk);
2744
+ });
2745
+ socket.once("error", (error) => {
2746
+ signal.removeEventListener("abort", onAbort);
2747
+ reject(error);
2748
+ });
2749
+ socket.once("end", () => {
2750
+ signal.removeEventListener("abort", onAbort);
2751
+ socket.destroy();
2752
+ resolve(Buffer.concat(chunks).toString("utf8").trim());
2753
+ });
2754
+ socket.write(line);
2755
+ });
2756
+ }
2757
+ //#endregion
2758
+ //#region src/judge/resolve-judge-socket-path.ts
2759
+ function resolveJudgeSocketPath(host, sessionID, entry) {
2760
+ const runtime = host.env["XDG_RUNTIME_DIR"];
2761
+ const dir = runtime === void 0 || runtime === "" ? join(resolveXDGDir(host, "state"), "judge") : join(runtime, "auto-mode");
2762
+ const build = statSync(entry, { throwIfNoEntry: false });
2763
+ const name = createHash("sha256").update(`${sessionID}\0${entry}\0${String(build?.mtimeMs ?? 0)}`).digest("hex").slice(0, 24);
2764
+ return join(dir, `judge-${name}.sock`);
2765
+ }
2766
+ //#endregion
98
2767
  //#region src/scope/read-pull-request.ts
99
2768
  const LOOKUP_TIMEOUT_MS = 5e3;
100
2769
  const MAX_LOOKUP_OUTPUT_BYTES = 65536;
@@ -345,11 +3014,11 @@ async function isBranchCreatedSince(commonDir, branch, since) {
345
3014
  }
346
3015
  //#endregion
347
3016
  //#region src/record-scope.ts
348
- async function recordScope(request, config, options = {}) {
349
- const host = options.host ?? readHostEnvironment();
3017
+ async function recordScope(request, config, runtime) {
3018
+ const host = runtime.host;
350
3019
  if (!Object.values(config.scopeSources ?? DEFAULT_SCOPE_SOURCES).some((source) => source.kind === "session")) return EMPTY_SESSION_SCOPE;
351
3020
  return await updateSessionScope(request, {
352
- now: options.now ?? Date.now(),
3021
+ now: runtime.now(),
353
3022
  stateDir: resolveXDGDir(host, "state"),
354
3023
  home: host.home,
355
3024
  env: host.env,
@@ -419,6 +3088,7 @@ Usage:
419
3088
  auto-mode print-prompt Print the system prompt the classifier receives
420
3089
  auto-mode record Read a finished Bash call on stdin, add what it created to the session's scope
421
3090
  auto-mode mod-path Print the directory of the Claude Code mod this package ships
3091
+ auto-mode judge-server <socket> Serve one agent session's judge reviews on a unix socket
422
3092
 
423
3093
  Options:
424
3094
  --classifier <path> Use this framework file instead of the shipped one
@@ -428,78 +3098,147 @@ Options:
428
3098
  --jev-only With run: require Jev and cap its API timeout at 5 seconds
429
3099
  --evaluation-deadline <unix-ms> With --jev-only: share the helper and API deadline
430
3100
  `;
3101
+ const CLI_ARGS = {
3102
+ classifier: { type: "string" },
3103
+ rules: { type: "string" },
3104
+ explain: { type: "boolean" },
3105
+ "local-only": { type: "boolean" },
3106
+ "jev-only": { type: "boolean" },
3107
+ "evaluation-deadline": { type: "string" },
3108
+ help: {
3109
+ type: "boolean",
3110
+ short: "h"
3111
+ }
3112
+ };
3113
+ const COMMANDS = /* @__PURE__ */ new Map([
3114
+ ["run", (io, values) => runClassification(io, values)],
3115
+ ["print-prompt", (io, values) => printPrompt(io, values)],
3116
+ ["record", (io) => runRecord(io)],
3117
+ ["mod-path", (io) => printModPath(io)],
3118
+ ["judge-server", (io, _values, positionals) => runJudgeServer(io, positionals[0])]
3119
+ ]);
431
3120
  async function runCLI(argv, io) {
432
- const args = tryParseCLIArgs(argv);
433
- if (args instanceof Error) {
434
- io.stderr.write(`auto-mode: ${args.message}\n\n${USAGE}`);
3121
+ let exitCode = 0;
3122
+ const subCommands = Object.fromEntries([...COMMANDS].map(([name, runCommand]) => [name, lazy(() => async (ctx) => {
3123
+ exitCode = ctx.values.help === true ? printUsage(io.stdout) : await runCommand(io, ctx.values, [...ctx.positionals.slice(ctx.commandPath.length), ...ctx.rest]);
3124
+ }, {
3125
+ name,
3126
+ args: CLI_ARGS
3127
+ })]));
3128
+ const entry = define({
3129
+ name: "auto-mode",
3130
+ args: CLI_ARGS,
3131
+ run: async (ctx) => {
3132
+ exitCode = await runCommandAfterTerminator(io, ctx.values, ctx.rest);
3133
+ }
3134
+ });
3135
+ try {
3136
+ await cli([...argv], entry, {
3137
+ subCommands,
3138
+ strict: true,
3139
+ onBeforeCommand: requireValidCommandLine
3140
+ });
3141
+ } catch (error) {
3142
+ if (!isUsageError(error)) throw error;
3143
+ io.stderr.write(`auto-mode: ${formatUsageError(error)}\n\n${USAGE}`);
435
3144
  return 2;
436
3145
  }
437
- const [command] = args.positionals;
438
- if (args.values.help === true || command === void 0) {
439
- io.stdout.write(USAGE);
440
- return 0;
3146
+ return exitCode;
3147
+ }
3148
+ function runCommandAfterTerminator(io, values, rest) {
3149
+ const [command, ...positionals] = rest;
3150
+ if (values.help === true || command === void 0) return Promise.resolve(printUsage(io.stdout));
3151
+ const runCommand = COMMANDS.get(command);
3152
+ if (runCommand === void 0) {
3153
+ io.stderr.write(`auto-mode: unknown command '${command}'\n\n${USAGE}`);
3154
+ return Promise.resolve(2);
441
3155
  }
442
- if (command === "run") try {
443
- return await run(io, args.values.explain === true, args.values["local-only"] === true, args.values["jev-only"] === true, args.values["evaluation-deadline"]);
3156
+ return runCommand(io, values, positionals);
3157
+ }
3158
+ function printUsage(stdout) {
3159
+ stdout.write(USAGE);
3160
+ return 0;
3161
+ }
3162
+ async function runClassification(io, values) {
3163
+ try {
3164
+ return await run(io, {
3165
+ explain: values.explain === true,
3166
+ localOnly: values["local-only"] === true,
3167
+ jevOnly: values["jev-only"] === true,
3168
+ deadline: values["evaluation-deadline"]
3169
+ });
444
3170
  } catch {
445
3171
  io.stderr.write("auto-mode: configuration unreadable; no verdict\n");
446
3172
  return 0;
447
3173
  }
448
- if (command === "record") return runRecord(io);
449
- if (command === "print-prompt") {
450
- const config = await loadConfig(void 0, io.host);
451
- printWarnings(io.stderr, config.warnings);
452
- const framework = config.provider.protocol === "system-one" ? "decision.md" : "classifier.md";
453
- const prompt = await loadPolicy({
454
- classifierPath: args.values.classifier ?? config.classifierPath,
455
- rulesPath: args.values.rules ?? config.rulesPath
456
- }, framework);
457
- io.stdout.write(`${prompt}\n`);
458
- return 0;
459
- }
460
- if (command === "mod-path") try {
3174
+ }
3175
+ async function printPrompt(io, values) {
3176
+ const config = await loadConfig(void 0, io.runtime.host);
3177
+ printWarnings(io.stderr, config.warnings);
3178
+ const prompt = await loadPolicy({
3179
+ classifierPath: values.classifier ?? config.classifierPath,
3180
+ rulesPath: values.rules ?? config.rulesPath
3181
+ }, "decision.md");
3182
+ io.stdout.write(`${prompt}\n`);
3183
+ return 0;
3184
+ }
3185
+ function printModPath(io) {
3186
+ try {
461
3187
  io.stdout.write(`${resolveShippedModDir()}\n`);
462
- return 0;
3188
+ return Promise.resolve(0);
463
3189
  } catch (error) {
464
3190
  io.stderr.write(`auto-mode: ${error instanceof Error ? error.message : String(error)}\n`);
465
- return 1;
3191
+ return Promise.resolve(1);
466
3192
  }
467
- io.stderr.write(`auto-mode: unknown command '${command}'\n\n${USAGE}`);
468
- return 2;
469
3193
  }
470
- function tryParseCLIArgs(argv) {
471
- try {
472
- return parseArgs({
473
- args: [...argv],
474
- allowPositionals: true,
475
- options: {
476
- classifier: { type: "string" },
477
- rules: { type: "string" },
478
- explain: { type: "boolean" },
479
- "local-only": { type: "boolean" },
480
- "jev-only": { type: "boolean" },
481
- "evaluation-deadline": { type: "string" },
482
- help: {
483
- type: "boolean",
484
- short: "h"
485
- }
486
- }
487
- });
488
- } catch (error) {
489
- return error instanceof Error ? error : new Error(String(error));
3194
+ function requireValidCommandLine(ctx) {
3195
+ if (ctx.validationError !== void 0) throw ctx.validationError;
3196
+ }
3197
+ function isUsageError(error) {
3198
+ return error instanceof AggregateError && error.errors.every((reason) => isArgsValidationError(reason) || isCommandNotFoundError(reason) || isCommandResolutionError(reason));
3199
+ }
3200
+ function formatUsageError(error) {
3201
+ return error.errors.map((reason) => {
3202
+ if (isCommandNotFoundError(reason)) return `unknown command '${reason.commandName}'`;
3203
+ return reason instanceof Error ? reason.message : String(reason);
3204
+ }).join("\n");
3205
+ }
3206
+ function buildJudgeServerSession(io, config, sessionID) {
3207
+ const judge = config.judge ?? null;
3208
+ if (io.judgeServerCommand === void 0 || judge === null || pickJudgeLane(judge).transport !== "agent-sdk") return;
3209
+ const command = io.judgeServerCommand;
3210
+ const entry = command[1] ?? command[0];
3211
+ return makeJudgeServerSession({
3212
+ socketPath: resolveJudgeSocketPath(io.runtime.host, sessionID, entry),
3213
+ command: io.judgeServerCommand,
3214
+ env: io.runtime.host.env,
3215
+ timeoutMs: judge.timeoutMs
3216
+ });
3217
+ }
3218
+ async function runJudgeServer(io, socketPath) {
3219
+ if (socketPath === void 0) {
3220
+ io.stderr.write(`auto-mode: judge-server needs a socket path\n\n${USAGE}`);
3221
+ return 2;
490
3222
  }
3223
+ await (await (await import("./start-judge-server-CCSZbTwM.js")).startJudgeServer({
3224
+ socketPath,
3225
+ env: io.runtime.host.env,
3226
+ idleMs: JUDGE_IDLE_MS
3227
+ }))?.closed;
3228
+ return 0;
491
3229
  }
492
- async function run(io, explain, localOnly, jevOnly, deadline) {
3230
+ const JUDGE_IDLE_MS = 9e5;
3231
+ async function run(io, options) {
493
3232
  const raw = await io.stdin();
494
3233
  let body;
495
3234
  try {
496
3235
  body = JSON.parse(raw);
497
3236
  } catch {
498
- return printNote(io.stderr, explain, "stdin is not JSON, so no verdict");
3237
+ return printNote(io.stderr, options.explain, "stdin is not JSON, so no verdict");
499
3238
  }
500
3239
  const request = parseActionRequest(body);
501
- if (request === null) return printNote(io.stderr, explain, "not an action request this classifier judges, so no verdict");
502
- const host = io.host;
3240
+ if (request === null) return printNote(io.stderr, options.explain, "not an action request this classifier judges, so no verdict");
3241
+ const host = io.runtime.host;
503
3242
  let loaded;
504
3243
  try {
505
3244
  loaded = await loadConfig(void 0, host);
@@ -508,29 +3247,26 @@ async function run(io, explain, localOnly, jevOnly, deadline) {
508
3247
  return printNote(io.stderr, true, "configuration unreadable; no verdict");
509
3248
  }
510
3249
  printWarnings(io.stderr, loaded.warnings);
511
- const config = jevOnly ? buildJevOnlyConfig(loaded) : loaded;
512
- if (config === null) {
513
- await writeActionFailure(request, host, io.stderr);
514
- return printNote(io.stderr, true, "Jev-only evaluation requires system-one; no verdict");
515
- }
516
- const deadlineAt = deadline === void 0 ? void 0 : Number(deadline);
517
- if (deadlineAt !== void 0 && (!jevOnly || !Number.isSafeInteger(deadlineAt) || deadlineAt <= 0)) {
3250
+ const config = options.jevOnly ? buildJevOnlyConfig(loaded) : loaded;
3251
+ const deadlineAt = options.deadline === void 0 ? void 0 : Number(options.deadline);
3252
+ if (deadlineAt !== void 0 && (!options.jevOnly || !Number.isSafeInteger(deadlineAt) || deadlineAt <= 0)) {
518
3253
  await writeActionFailure(request, host, io.stderr);
519
3254
  return printNote(io.stderr, true, "invalid Jev evaluation deadline; no verdict");
520
3255
  }
521
3256
  const controller = new AbortController();
522
- const unsubscribe = jevOnly ? io.subscribeToStopSignals(() => {
3257
+ const unsubscribe = options.jevOnly ? io.subscribeToStopSignals(() => {
523
3258
  controller.abort();
524
3259
  }) : null;
525
3260
  try {
526
3261
  const outcome = await classifyAction(request, config, {
527
- localOnly,
3262
+ localOnly: options.localOnly,
528
3263
  deadlineAt,
529
3264
  signal: controller.signal,
530
- host,
3265
+ runtime: io.runtime,
531
3266
  stderr: io.stderr,
532
3267
  budget: true,
533
- actionLog: true
3268
+ actionLog: true,
3269
+ judgeSession: buildJudgeServerSession(io, config, request.sessionID)
534
3270
  });
535
3271
  if (outcome.verdict !== null) printVerdict(io.stdout, outcome.verdict);
536
3272
  if (config.capture?.enabled === true) {
@@ -544,7 +3280,7 @@ async function run(io, explain, localOnly, jevOnly, deadline) {
544
3280
  });
545
3281
  printCaptureNote(io.stderr, captured);
546
3282
  }
547
- return printNote(io.stderr, explain || outcome.unavailable === true, outcome.note);
3283
+ return printNote(io.stderr, options.explain || outcome.unavailable === true, outcome.note);
548
3284
  } finally {
549
3285
  unsubscribe?.();
550
3286
  }
@@ -574,7 +3310,7 @@ async function runRecord(io) {
574
3310
  const request = parseScopeRecordRequest(body);
575
3311
  if (request === null) return 0;
576
3312
  try {
577
- await recordScope(request, await loadConfig(void 0, io.host), { host: io.host });
3313
+ await recordScope(request, await loadConfig(void 0, io.runtime.host), io.runtime);
578
3314
  } catch {
579
3315
  io.stderr.write("auto-mode: session scope unavailable\n");
580
3316
  }
@@ -586,7 +3322,7 @@ process.exitCode = await runCLI(process.argv.slice(2), {
586
3322
  stdin: () => text(process.stdin),
587
3323
  stdout: process.stdout,
588
3324
  stderr: process.stderr,
589
- host: readHostEnvironment(),
3325
+ runtime: readRuntime(),
590
3326
  subscribeToStopSignals: (onStop) => {
591
3327
  process.on("SIGTERM", onStop);
592
3328
  process.on("SIGINT", onStop);
@@ -594,7 +3330,8 @@ process.exitCode = await runCLI(process.argv.slice(2), {
594
3330
  process.off("SIGTERM", onStop);
595
3331
  process.off("SIGINT", onStop);
596
3332
  };
597
- }
3333
+ },
3334
+ judgeServerCommand: [process.execPath, import.meta.filename]
598
3335
  });
599
3336
  //#endregion
600
3337
  export {};