@optique/core 1.0.0-dev.908 → 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (109) hide show
  1. package/dist/annotation-state.cjs +425 -0
  2. package/dist/annotation-state.d.cts +24 -0
  3. package/dist/annotation-state.d.ts +24 -0
  4. package/dist/annotation-state.js +414 -0
  5. package/dist/annotations.cjs +2 -248
  6. package/dist/annotations.d.cts +2 -137
  7. package/dist/annotations.d.ts +2 -137
  8. package/dist/annotations.js +2 -238
  9. package/dist/completion.cjs +611 -100
  10. package/dist/completion.d.cts +1 -1
  11. package/dist/completion.d.ts +1 -1
  12. package/dist/completion.js +611 -100
  13. package/dist/constructs.cjs +3338 -827
  14. package/dist/constructs.d.cts +48 -7
  15. package/dist/constructs.d.ts +48 -7
  16. package/dist/constructs.js +3338 -827
  17. package/dist/context.cjs +0 -23
  18. package/dist/context.d.cts +119 -53
  19. package/dist/context.d.ts +119 -53
  20. package/dist/context.js +0 -22
  21. package/dist/dependency-metadata.cjs +139 -0
  22. package/dist/dependency-metadata.d.cts +112 -0
  23. package/dist/dependency-metadata.d.ts +112 -0
  24. package/dist/dependency-metadata.js +138 -0
  25. package/dist/dependency-runtime.cjs +698 -0
  26. package/dist/dependency-runtime.d.cts +149 -0
  27. package/dist/dependency-runtime.d.ts +149 -0
  28. package/dist/dependency-runtime.js +687 -0
  29. package/dist/dependency.cjs +7 -928
  30. package/dist/dependency.d.cts +2 -794
  31. package/dist/dependency.d.ts +2 -794
  32. package/dist/dependency.js +2 -899
  33. package/dist/displaywidth.cjs +44 -0
  34. package/dist/displaywidth.js +43 -0
  35. package/dist/doc.cjs +285 -23
  36. package/dist/doc.d.cts +57 -2
  37. package/dist/doc.d.ts +57 -2
  38. package/dist/doc.js +283 -25
  39. package/dist/execution-context.cjs +56 -0
  40. package/dist/execution-context.js +53 -0
  41. package/dist/extension.cjs +87 -0
  42. package/dist/extension.d.cts +97 -0
  43. package/dist/extension.d.ts +97 -0
  44. package/dist/extension.js +76 -0
  45. package/dist/facade.cjs +718 -523
  46. package/dist/facade.d.cts +87 -18
  47. package/dist/facade.d.ts +87 -18
  48. package/dist/facade.js +718 -523
  49. package/dist/index.cjs +14 -29
  50. package/dist/index.d.cts +10 -10
  51. package/dist/index.d.ts +10 -10
  52. package/dist/index.js +7 -7
  53. package/dist/input-trace.cjs +56 -0
  54. package/dist/input-trace.d.cts +77 -0
  55. package/dist/input-trace.d.ts +77 -0
  56. package/dist/input-trace.js +55 -0
  57. package/dist/internal/annotations.cjs +316 -0
  58. package/dist/internal/annotations.d.cts +140 -0
  59. package/dist/internal/annotations.d.ts +140 -0
  60. package/dist/internal/annotations.js +306 -0
  61. package/dist/internal/dependency.cjs +984 -0
  62. package/dist/internal/dependency.d.cts +539 -0
  63. package/dist/internal/dependency.d.ts +539 -0
  64. package/dist/internal/dependency.js +964 -0
  65. package/dist/{mode-dispatch.cjs → internal/mode-dispatch.cjs} +1 -3
  66. package/dist/{mode-dispatch.d.cts → internal/mode-dispatch.d.cts} +3 -7
  67. package/dist/{mode-dispatch.d.ts → internal/mode-dispatch.d.ts} +3 -7
  68. package/dist/{mode-dispatch.js → internal/mode-dispatch.js} +1 -3
  69. package/dist/internal/parser.cjs +728 -0
  70. package/dist/internal/parser.d.cts +947 -0
  71. package/dist/internal/parser.d.ts +947 -0
  72. package/dist/internal/parser.js +711 -0
  73. package/dist/message.cjs +84 -26
  74. package/dist/message.d.cts +49 -9
  75. package/dist/message.d.ts +49 -9
  76. package/dist/message.js +84 -27
  77. package/dist/modifiers.cjs +1023 -240
  78. package/dist/modifiers.d.cts +42 -1
  79. package/dist/modifiers.d.ts +42 -1
  80. package/dist/modifiers.js +1023 -240
  81. package/dist/parser.cjs +11 -463
  82. package/dist/parser.d.cts +3 -537
  83. package/dist/parser.d.ts +3 -537
  84. package/dist/parser.js +2 -433
  85. package/dist/phase2-seed.cjs +59 -0
  86. package/dist/phase2-seed.js +56 -0
  87. package/dist/primitives.cjs +557 -208
  88. package/dist/primitives.d.cts +10 -14
  89. package/dist/primitives.d.ts +10 -14
  90. package/dist/primitives.js +557 -208
  91. package/dist/program.cjs +5 -1
  92. package/dist/program.d.cts +5 -3
  93. package/dist/program.d.ts +5 -3
  94. package/dist/program.js +6 -1
  95. package/dist/suggestion.cjs +22 -8
  96. package/dist/suggestion.js +22 -8
  97. package/dist/usage-internals.cjs +3 -2
  98. package/dist/usage-internals.js +4 -2
  99. package/dist/usage.cjs +195 -40
  100. package/dist/usage.d.cts +92 -11
  101. package/dist/usage.d.ts +92 -11
  102. package/dist/usage.js +194 -41
  103. package/dist/validate.cjs +170 -0
  104. package/dist/validate.js +164 -0
  105. package/dist/valueparser.cjs +1278 -191
  106. package/dist/valueparser.d.cts +330 -20
  107. package/dist/valueparser.d.ts +330 -20
  108. package/dist/valueparser.js +1277 -192
  109. package/package.json +9 -9
@@ -1,42 +1,121 @@
1
- const require_annotations = require('./annotations.cjs');
1
+ const require_annotations = require('./internal/annotations.cjs');
2
2
  const require_message = require('./message.cjs');
3
- const require_dependency = require('./dependency.cjs');
4
- const require_mode_dispatch = require('./mode-dispatch.cjs');
3
+ const require_validate = require('./validate.cjs');
5
4
  const require_usage = require('./usage.cjs');
5
+ const require_mode_dispatch = require('./internal/mode-dispatch.cjs');
6
+ const require_dependency = require('./internal/dependency.cjs');
7
+ const require_dependency_runtime = require('./dependency-runtime.cjs');
8
+ const require_annotation_state = require('./annotation-state.cjs');
9
+ const require_execution_context = require('./execution-context.cjs');
10
+ const require_phase2_seed = require('./phase2-seed.cjs');
6
11
  const require_suggestion = require('./suggestion.cjs');
7
12
  const require_usage_internals = require('./usage-internals.cjs');
13
+ const require_dependency_metadata = require('./dependency-metadata.cjs');
8
14
  const require_valueparser = require('./valueparser.cjs');
9
15
 
10
16
  //#region src/primitives.ts
17
+ /**
18
+ * A shared empty set used as the `leadingNames` value for parsers that
19
+ * do not match any specific name at the first buffer position.
20
+ */
21
+ const EMPTY_LEADING_NAMES = /* @__PURE__ */ new Set();
11
22
  function hasParsedOptionValue(state, valueParser) {
12
- if (valueParser != null) return require_dependency.isDeferredParseState(state) || require_dependency.isDependencySourceState(state) || state != null && "success" in state && state.success;
23
+ if (valueParser != null) return state != null && typeof state === "object" && "success" in state && typeof state.success === "boolean";
13
24
  return state != null && "success" in state && state.success && state.value === true;
14
25
  }
15
26
  /**
16
- * Helper function to create the appropriate state for an option value.
17
- * - If the value parser is a DerivedValueParser, wraps the result in a DeferredParseState
18
- * to allow later resolution with actual dependency values.
19
- * - If the value parser is a DependencySource, wraps the result in a DependencySourceState
20
- * so that it can be matched with DeferredParseState during resolution.
27
+ * Helper function to create the stored state for an option or argument value.
28
+ *
29
+ * Primitive parsers now keep only the plain parse result as their local state.
30
+ * Any dependency-aware replay information is recorded separately in the
31
+ * execution trace.
21
32
  * @internal
22
33
  */
23
- function createOptionParseState(rawInput, valueParser, parseResult) {
24
- if (require_dependency.isDerivedValueParser(valueParser)) return require_dependency.createDeferredParseState(rawInput, valueParser, parseResult);
25
- if (require_dependency.isDependencySource(valueParser)) return require_dependency.createDependencySourceState(parseResult, valueParser[require_dependency.dependencyId]);
34
+ function createOptionParseState(parseResult) {
26
35
  return parseResult;
27
36
  }
37
+ function buildTraceEntry(kind, rawInput, consumed, valueParser, parseResult, optionNames$1) {
38
+ const entry = {
39
+ kind,
40
+ rawInput,
41
+ consumed,
42
+ preliminaryResult: parseResult,
43
+ ...optionNames$1 != null ? { optionNames: optionNames$1 } : {},
44
+ metavar: valueParser.metavar
45
+ };
46
+ if (require_dependency.isDerivedValueParser(valueParser)) {
47
+ const defaults = require_dependency.getSnapshottedDefaultDependencyValues(parseResult);
48
+ if (defaults != null) return {
49
+ ...entry,
50
+ defaultDependencyValues: defaults
51
+ };
52
+ }
53
+ return entry;
54
+ }
55
+ function recordTrace(context, entry) {
56
+ if (context.exec?.trace == null) return context;
57
+ const trace = context.exec.trace.set(context.exec.path, entry);
58
+ return {
59
+ ...context,
60
+ trace,
61
+ exec: {
62
+ ...context.exec,
63
+ trace
64
+ }
65
+ };
66
+ }
67
+ function resolveDerivedCompletionSync(derivedMetadata, state, exec) {
68
+ if (derivedMetadata?.derived == null || exec?.dependencyRuntime == null) return state;
69
+ const traceEntry = exec.trace?.get(exec.path);
70
+ if (traceEntry?.rawInput == null) return traceEntry?.preliminaryResult ?? state;
71
+ if (traceEntry.preliminaryResult != null) {
72
+ const resolution = exec.dependencyRuntime.resolveDependencies({
73
+ dependencyIds: derivedMetadata.derived.dependencyIds,
74
+ defaultValues: traceEntry.defaultDependencyValues
75
+ });
76
+ if (resolution.kind === "resolved" && resolution.usedDefaults.length > 0 && resolution.usedDefaults.every((used) => used)) return traceEntry.preliminaryResult;
77
+ }
78
+ const replayed = require_dependency_runtime.replayDerivedParser({
79
+ path: exec.path,
80
+ parser: { dependencyMetadata: { derived: derivedMetadata.derived } },
81
+ state,
82
+ defaultDependencyValues: traceEntry.defaultDependencyValues
83
+ }, traceEntry.rawInput, exec.dependencyRuntime);
84
+ return replayed ?? traceEntry.preliminaryResult ?? state;
85
+ }
86
+ async function resolveDerivedCompletionAsync(derivedMetadata, state, exec) {
87
+ if (derivedMetadata?.derived == null || exec?.dependencyRuntime == null) return state;
88
+ const traceEntry = exec.trace?.get(exec.path);
89
+ if (traceEntry?.rawInput == null) return traceEntry?.preliminaryResult ?? state;
90
+ if (traceEntry.preliminaryResult != null) {
91
+ const resolution = exec.dependencyRuntime.resolveDependencies({
92
+ dependencyIds: derivedMetadata.derived.dependencyIds,
93
+ defaultValues: traceEntry.defaultDependencyValues
94
+ });
95
+ if (resolution.kind === "resolved" && resolution.usedDefaults.length > 0 && resolution.usedDefaults.every((used) => used)) return traceEntry.preliminaryResult;
96
+ }
97
+ const replayed = await require_dependency_runtime.replayDerivedParserAsync({
98
+ path: exec.path,
99
+ parser: { dependencyMetadata: { derived: derivedMetadata.derived } },
100
+ state,
101
+ defaultDependencyValues: traceEntry.defaultDependencyValues
102
+ }, traceEntry.rawInput, exec.dependencyRuntime);
103
+ return replayed ?? traceEntry.preliminaryResult ?? state;
104
+ }
28
105
  /**
29
106
  * Creates a parser that always succeeds without consuming any input and
30
107
  * produces a constant value of the type {@link T}.
31
108
  * @template T The type of the constant value produced by the parser.
32
109
  */
33
110
  function constant(value) {
34
- return {
111
+ const result = {
35
112
  $valueType: [],
36
113
  $stateType: [],
37
- $mode: "sync",
114
+ mode: "sync",
38
115
  priority: 0,
39
116
  usage: [],
117
+ leadingNames: EMPTY_LEADING_NAMES,
118
+ acceptingAnyToken: false,
40
119
  initialState: value,
41
120
  parse(context) {
42
121
  return {
@@ -45,7 +124,7 @@ function constant(value) {
45
124
  consumed: []
46
125
  };
47
126
  },
48
- complete(state) {
127
+ complete(state, _exec) {
49
128
  return {
50
129
  success: true,
51
130
  value: state
@@ -58,6 +137,13 @@ function constant(value) {
58
137
  return { fragments: [] };
59
138
  }
60
139
  };
140
+ Object.defineProperty(result, "placeholder", {
141
+ value,
142
+ configurable: true,
143
+ enumerable: false,
144
+ writable: false
145
+ });
146
+ return result;
61
147
  }
62
148
  /**
63
149
  * Creates a parser that always fails without consuming any input.
@@ -82,9 +168,11 @@ function fail() {
82
168
  return {
83
169
  $valueType: [],
84
170
  $stateType: [],
85
- $mode: "sync",
171
+ mode: "sync",
86
172
  priority: 0,
87
173
  usage: [],
174
+ leadingNames: EMPTY_LEADING_NAMES,
175
+ acceptingAnyToken: false,
88
176
  initialState: void 0,
89
177
  parse(_context) {
90
178
  return {
@@ -93,7 +181,7 @@ function fail() {
93
181
  error: require_message.message`No value provided.`
94
182
  };
95
183
  },
96
- complete(_state) {
184
+ complete(_state, _exec) {
97
185
  return {
98
186
  success: false,
99
187
  error: require_message.message`No value provided.`
@@ -112,12 +200,13 @@ function fail() {
112
200
  * if the parser is a derived parser and dependency values are available.
113
201
  * @internal
114
202
  */
115
- function* getSuggestionsWithDependency(valueParser, prefix, dependencyRegistry) {
203
+ function* getSuggestionsWithDependency(valueParser, prefix, dependencyRegistry, exec) {
116
204
  if (!valueParser.suggest) return;
117
205
  if (require_dependency.isDerivedValueParser(valueParser) && require_dependency.suggestWithDependency in valueParser) {
118
206
  const derived = valueParser;
119
207
  const suggestWithDep = derived[require_dependency.suggestWithDependency];
120
208
  if (suggestWithDep && dependencyRegistry) {
209
+ const dependencyRuntime = exec?.dependencyRuntime;
121
210
  const depIds = require_dependency.getDependencyIds(derived);
122
211
  const defaultsFn = require_dependency.getDefaultValuesFunction(derived);
123
212
  const defaults = defaultsFn?.();
@@ -128,7 +217,8 @@ function* getSuggestionsWithDependency(valueParser, prefix, dependencyRegistry)
128
217
  if (dependencyRegistry.has(depId)) {
129
218
  dependencyValues.push(dependencyRegistry.get(depId));
130
219
  hasAnyValue = true;
131
- } else if (defaults && i < defaults.length) dependencyValues.push(defaults[i]);
220
+ } else if (dependencyRuntime?.isSourceFailed(depId)) return;
221
+ else if (defaults && i < defaults.length) dependencyValues.push(defaults[i]);
132
222
  else {
133
223
  yield* valueParser.suggest(prefix);
134
224
  return;
@@ -155,7 +245,7 @@ function* suggestOptionSync(optionNames$1, valueParser, hidden, context, prefix)
155
245
  const valuePart = prefix.slice(equalsIndex + 1);
156
246
  if (optionNames$1.includes(optionPart)) {
157
247
  if (valueParser && valueParser.suggest) {
158
- const valueSuggestions = getSuggestionsWithDependency(valueParser, valuePart, context.dependencyRegistry);
248
+ const valueSuggestions = getSuggestionsWithDependency(valueParser, valuePart, context.dependencyRegistry, context.exec);
159
249
  for (const suggestion of valueSuggestions) if (suggestion.kind === "literal") yield {
160
250
  kind: "literal",
161
251
  text: `${optionPart}=${suggestion.text}`,
@@ -184,8 +274,8 @@ function* suggestOptionSync(optionNames$1, valueParser, hidden, context, prefix)
184
274
  if (context.buffer.length > 0) {
185
275
  const lastToken = context.buffer[context.buffer.length - 1];
186
276
  if (optionNames$1.includes(lastToken)) shouldSuggestValues = true;
187
- } else if (context.state === void 0 && context.buffer.length === 0) shouldSuggestValues = true;
188
- if (shouldSuggestValues) yield* getSuggestionsWithDependency(valueParser, prefix, context.dependencyRegistry);
277
+ } else if (require_annotation_state.isAnnotationWrappedInitialState(context.state) && context.buffer.length === 0 && (context.exec?.path?.length ?? 0) === 0 && !(prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/"))) shouldSuggestValues = true;
278
+ if (shouldSuggestValues) yield* getSuggestionsWithDependency(valueParser, prefix, context.dependencyRegistry, context.exec);
189
279
  }
190
280
  }
191
281
  }
@@ -194,12 +284,13 @@ function* suggestOptionSync(optionNames$1, valueParser, hidden, context, prefix)
194
284
  * if the parser is a derived parser and dependency values are available.
195
285
  * @internal
196
286
  */
197
- async function* getSuggestionsWithDependencyAsync(valueParser, prefix, dependencyRegistry) {
287
+ async function* getSuggestionsWithDependencyAsync(valueParser, prefix, dependencyRegistry, exec) {
198
288
  if (!valueParser.suggest) return;
199
289
  if (require_dependency.isDerivedValueParser(valueParser) && require_dependency.suggestWithDependency in valueParser) {
200
290
  const derived = valueParser;
201
291
  const suggestWithDep = derived[require_dependency.suggestWithDependency];
202
292
  if (suggestWithDep && dependencyRegistry) {
293
+ const dependencyRuntime = exec?.dependencyRuntime;
203
294
  const depIds = require_dependency.getDependencyIds(derived);
204
295
  const defaultsFn = require_dependency.getDefaultValuesFunction(derived);
205
296
  const defaults = defaultsFn?.();
@@ -210,7 +301,8 @@ async function* getSuggestionsWithDependencyAsync(valueParser, prefix, dependenc
210
301
  if (dependencyRegistry.has(depId)) {
211
302
  dependencyValues.push(dependencyRegistry.get(depId));
212
303
  hasAnyValue = true;
213
- } else if (defaults && i < defaults.length) dependencyValues.push(defaults[i]);
304
+ } else if (dependencyRuntime?.isSourceFailed(depId)) return;
305
+ else if (defaults && i < defaults.length) dependencyValues.push(defaults[i]);
214
306
  else {
215
307
  for await (const suggestion of valueParser.suggest(prefix)) yield suggestion;
216
308
  return;
@@ -237,7 +329,7 @@ async function* suggestOptionAsync(optionNames$1, valueParser, hidden, context,
237
329
  const valuePart = prefix.slice(equalsIndex + 1);
238
330
  if (optionNames$1.includes(optionPart)) {
239
331
  if (valueParser && valueParser.suggest) {
240
- const valueSuggestions = getSuggestionsWithDependencyAsync(valueParser, valuePart, context.dependencyRegistry);
332
+ const valueSuggestions = getSuggestionsWithDependencyAsync(valueParser, valuePart, context.dependencyRegistry, context.exec);
241
333
  for await (const suggestion of valueSuggestions) if (suggestion.kind === "literal") yield {
242
334
  kind: "literal",
243
335
  text: `${optionPart}=${suggestion.text}`,
@@ -266,8 +358,8 @@ async function* suggestOptionAsync(optionNames$1, valueParser, hidden, context,
266
358
  if (context.buffer.length > 0) {
267
359
  const lastToken = context.buffer[context.buffer.length - 1];
268
360
  if (optionNames$1.includes(lastToken)) shouldSuggestValues = true;
269
- } else if (context.state === void 0 && context.buffer.length === 0) shouldSuggestValues = true;
270
- if (shouldSuggestValues) for await (const suggestion of getSuggestionsWithDependencyAsync(valueParser, prefix, context.dependencyRegistry)) yield suggestion;
361
+ } else if (require_annotation_state.isAnnotationWrappedInitialState(context.state) && context.buffer.length === 0 && (context.exec?.path?.length ?? 0) === 0 && !(prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/"))) shouldSuggestValues = true;
362
+ if (shouldSuggestValues) for await (const suggestion of getSuggestionsWithDependencyAsync(valueParser, prefix, context.dependencyRegistry, context.exec)) yield suggestion;
271
363
  }
272
364
  }
273
365
  }
@@ -275,17 +367,17 @@ async function* suggestOptionAsync(optionNames$1, valueParser, hidden, context,
275
367
  * Internal sync helper for argument suggest functionality.
276
368
  * @internal
277
369
  */
278
- function* suggestArgumentSync(valueParser, hidden, prefix, dependencyRegistry) {
370
+ function* suggestArgumentSync(valueParser, hidden, prefix, dependencyRegistry, exec) {
279
371
  if (hidden) return;
280
- if (valueParser.suggest) yield* getSuggestionsWithDependency(valueParser, prefix, dependencyRegistry);
372
+ if (valueParser.suggest) yield* getSuggestionsWithDependency(valueParser, prefix, dependencyRegistry, exec);
281
373
  }
282
374
  /**
283
375
  * Internal async helper for argument suggest functionality.
284
376
  * @internal
285
377
  */
286
- async function* suggestArgumentAsync(valueParser, hidden, prefix, dependencyRegistry) {
378
+ async function* suggestArgumentAsync(valueParser, hidden, prefix, dependencyRegistry, exec) {
287
379
  if (hidden) return;
288
- if (valueParser.suggest) yield* getSuggestionsWithDependencyAsync(valueParser, prefix, dependencyRegistry);
380
+ if (valueParser.suggest) yield* getSuggestionsWithDependencyAsync(valueParser, prefix, dependencyRegistry, exec);
289
381
  }
290
382
  function option(...args) {
291
383
  const lastArg = args.at(-1);
@@ -309,10 +401,14 @@ function option(...args) {
309
401
  optionNames$1 = args;
310
402
  valueParser = void 0;
311
403
  }
312
- const mode = valueParser?.$mode ?? "sync";
404
+ require_validate.validateOptionNames(optionNames$1, "Option");
405
+ const mode = valueParser?.mode ?? "sync";
313
406
  const isAsync = mode === "async";
407
+ const syncValueParser = valueParser;
408
+ const dependencyMetadata = valueParser != null ? require_dependency_metadata.extractDependencyMetadata(valueParser) : void 0;
409
+ const formatInvalidValueError = (error) => options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(error) : options.errors.invalidValue : require_message.message`${require_message.optionNames(optionNames$1)}: ${error}`;
314
410
  const result = {
315
- $mode: mode,
411
+ mode,
316
412
  $valueType: [],
317
413
  $stateType: [],
318
414
  priority: 10,
@@ -329,13 +425,12 @@ function option(...args) {
329
425
  metavar: valueParser.metavar,
330
426
  ...options.hidden != null && { hidden: options.hidden }
331
427
  }],
428
+ leadingNames: new Set(optionNames$1),
429
+ acceptingAnyToken: false,
332
430
  initialState: valueParser == null ? {
333
431
  success: true,
334
432
  value: false
335
- } : require_dependency.isDependencySource(valueParser) ? require_dependency.createPendingDependencySourceState(valueParser[require_dependency.dependencyId]) : {
336
- success: false,
337
- error: options.errors?.missing ? typeof options.errors.missing === "function" ? options.errors.missing(optionNames$1) : options.errors.missing : require_message.message`Missing option ${require_message.optionNames(optionNames$1)}.`
338
- },
433
+ } : void 0,
339
434
  parse(context) {
340
435
  if (context.optionsTerminated) return {
341
436
  success: false,
@@ -378,28 +473,34 @@ function option(...args) {
378
473
  if (context.buffer.length < 2) return {
379
474
  success: false,
380
475
  consumed: 1,
381
- error: require_message.message`Option ${require_message.optionName(context.buffer[0])} requires a value, but got no value.`
476
+ error: options.errors?.endOfInput ?? require_message.message`${require_message.optionName(context.buffer[0])} requires ${require_message.metavar(valueParser.metavar)}.`
382
477
  };
383
478
  const rawInput = context.buffer[1];
384
- const parseResultOrPromise = valueParser.parse(rawInput);
385
- if (isAsync) return parseResultOrPromise.then((parseResult) => ({
386
- success: true,
387
- next: {
388
- ...context,
389
- state: createOptionParseState(rawInput, valueParser, parseResult),
390
- buffer: context.buffer.slice(2)
391
- },
392
- consumed: context.buffer.slice(0, 2)
393
- }));
394
- return {
395
- success: true,
396
- next: {
397
- ...context,
398
- state: createOptionParseState(rawInput, valueParser, parseResultOrPromise),
399
- buffer: context.buffer.slice(2)
400
- },
401
- consumed: context.buffer.slice(0, 2)
402
- };
479
+ return require_mode_dispatch.dispatchByMode(mode, () => {
480
+ const parseResult = syncValueParser.parse(rawInput);
481
+ const next = recordTrace(context, buildTraceEntry("option-value", rawInput, context.buffer.slice(0, 2), syncValueParser, parseResult, optionNames$1));
482
+ return {
483
+ success: true,
484
+ next: {
485
+ ...next,
486
+ state: createOptionParseState(parseResult),
487
+ buffer: context.buffer.slice(2)
488
+ },
489
+ consumed: context.buffer.slice(0, 2)
490
+ };
491
+ }, async () => {
492
+ const parseResult = await valueParser.parse(rawInput);
493
+ const next = recordTrace(context, buildTraceEntry("option-value", rawInput, context.buffer.slice(0, 2), valueParser, parseResult, optionNames$1));
494
+ return {
495
+ success: true,
496
+ next: {
497
+ ...next,
498
+ state: createOptionParseState(parseResult),
499
+ buffer: context.buffer.slice(2)
500
+ },
501
+ consumed: context.buffer.slice(0, 2)
502
+ };
503
+ });
403
504
  }
404
505
  const prefixes = optionNames$1.filter((name) => name.startsWith("--") || name.startsWith("/") || name.startsWith("-") && name.length > 2).map((name) => name.startsWith("/") ? `${name}:` : `${name}=`);
405
506
  for (const prefix of prefixes) {
@@ -418,25 +519,31 @@ function option(...args) {
418
519
  consumed: 1,
419
520
  error: options.errors?.unexpectedValue ? typeof options.errors.unexpectedValue === "function" ? options.errors.unexpectedValue(rawInput) : options.errors.unexpectedValue : require_message.message`Option ${require_message.optionName(prefix)} is a Boolean flag, but got a value: ${rawInput}.`
420
521
  };
421
- const parseResultOrPromise = valueParser.parse(rawInput);
422
- if (isAsync) return parseResultOrPromise.then((parseResult) => ({
423
- success: true,
424
- next: {
425
- ...context,
426
- state: createOptionParseState(rawInput, valueParser, parseResult),
427
- buffer: context.buffer.slice(1)
428
- },
429
- consumed: context.buffer.slice(0, 1)
430
- }));
431
- return {
432
- success: true,
433
- next: {
434
- ...context,
435
- state: createOptionParseState(rawInput, valueParser, parseResultOrPromise),
436
- buffer: context.buffer.slice(1)
437
- },
438
- consumed: context.buffer.slice(0, 1)
439
- };
522
+ return require_mode_dispatch.dispatchByMode(mode, () => {
523
+ const parseResult = syncValueParser.parse(rawInput);
524
+ const next = recordTrace(context, buildTraceEntry("option-value", rawInput, context.buffer.slice(0, 1), syncValueParser, parseResult, optionNames$1));
525
+ return {
526
+ success: true,
527
+ next: {
528
+ ...next,
529
+ state: createOptionParseState(parseResult),
530
+ buffer: context.buffer.slice(1)
531
+ },
532
+ consumed: context.buffer.slice(0, 1)
533
+ };
534
+ }, async () => {
535
+ const parseResult = await valueParser.parse(rawInput);
536
+ const next = recordTrace(context, buildTraceEntry("option-value", rawInput, context.buffer.slice(0, 1), valueParser, parseResult, optionNames$1));
537
+ return {
538
+ success: true,
539
+ next: {
540
+ ...next,
541
+ state: createOptionParseState(parseResult),
542
+ buffer: context.buffer.slice(1)
543
+ },
544
+ consumed: context.buffer.slice(0, 1)
545
+ };
546
+ });
440
547
  }
441
548
  if (valueParser == null) {
442
549
  const shortOptions = optionNames$1.filter((name) => name.match(/^-[^-]$/));
@@ -480,39 +587,32 @@ function option(...args) {
480
587
  error: require_suggestion.createErrorWithSuggestions(baseError, invalidOption, context.usage, "option")
481
588
  };
482
589
  },
483
- complete(state) {
484
- if (state == null) return valueParser == null ? {
590
+ complete(state, exec) {
591
+ const missing = valueParser == null ? {
485
592
  success: true,
486
593
  value: false
487
594
  } : {
488
595
  success: false,
489
596
  error: options.errors?.missing ? typeof options.errors.missing === "function" ? options.errors.missing(optionNames$1) : options.errors.missing : require_message.message`Missing option ${require_message.optionNames(optionNames$1)}.`
490
597
  };
491
- if (require_dependency.isPendingDependencySourceState(state)) return {
492
- success: false,
493
- error: options.errors?.missing ? typeof options.errors.missing === "function" ? options.errors.missing(optionNames$1) : options.errors.missing : require_message.message`Missing option ${require_message.optionNames(optionNames$1)}.`
494
- };
495
- if (require_dependency.isDeferredParseState(state)) {
496
- const preliminaryResult = state.preliminaryResult;
497
- if (preliminaryResult.success) return preliminaryResult;
498
- return {
598
+ const completeSync = () => {
599
+ if (state == null) return missing;
600
+ const resolvedState = valueParser != null && dependencyMetadata?.derived != null ? resolveDerivedCompletionSync(dependencyMetadata, state, exec) : state;
601
+ return resolvedState.success ? resolvedState : {
499
602
  success: false,
500
- error: options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(preliminaryResult.error) : options.errors.invalidValue : require_message.message`${require_message.optionNames(optionNames$1)}: ${preliminaryResult.error}`
603
+ error: formatInvalidValueError(resolvedState.error)
501
604
  };
502
- }
503
- if (require_dependency.isDependencySourceState(state)) {
504
- const result$1 = state.result;
505
- if (result$1.success) return result$1;
506
- return {
605
+ };
606
+ const completeAsync = async () => {
607
+ if (state == null) return missing;
608
+ if (valueParser == null || dependencyMetadata?.derived == null) return completeSync();
609
+ const resolved = await resolveDerivedCompletionAsync(dependencyMetadata, state, exec);
610
+ return resolved.success ? resolved : {
507
611
  success: false,
508
- error: options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(result$1.error) : options.errors.invalidValue : require_message.message`${require_message.optionNames(optionNames$1)}: ${result$1.error}`
612
+ error: formatInvalidValueError(resolved.error)
509
613
  };
510
- }
511
- if (state.success) return state;
512
- return {
513
- success: false,
514
- error: options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(state.error) : options.errors.invalidValue : require_message.message`${require_message.optionNames(optionNames$1)}: ${state.error}`
515
614
  };
615
+ return require_mode_dispatch.dispatchByMode(mode, completeSync, completeAsync);
516
616
  },
517
617
  suggest(context, prefix) {
518
618
  if (isAsync) return suggestOptionAsync(optionNames$1, valueParser, require_usage.isSuggestionHidden(options.hidden), context, prefix);
@@ -523,7 +623,10 @@ function option(...args) {
523
623
  fragments: [],
524
624
  description: options.description
525
625
  };
526
- const choicesMessage = valueParser?.choices != null && valueParser.choices.length > 0 ? require_message.valueSet(valueParser.choices.map((c) => valueParser.format(c)), { type: "unit" }) : void 0;
626
+ const choicesMessage = valueParser?.choices != null && valueParser.choices.length > 0 ? require_message.valueSet(valueParser.choices.map((c) => valueParser.format(c)), {
627
+ fallback: "",
628
+ type: "unit"
629
+ }) : void 0;
527
630
  const fragments = [{
528
631
  type: "entry",
529
632
  term: {
@@ -544,6 +647,86 @@ function option(...args) {
544
647
  return `option(${optionNames$1.map((o) => JSON.stringify(o)).join(", ")})`;
545
648
  }
546
649
  };
650
+ if (valueParser != null && typeof valueParser.normalize === "function") {
651
+ const normalize = valueParser.normalize.bind(valueParser);
652
+ Object.defineProperty(result, "normalizeValue", {
653
+ value(v) {
654
+ try {
655
+ return normalize(v);
656
+ } catch {
657
+ return v;
658
+ }
659
+ },
660
+ configurable: true,
661
+ enumerable: false
662
+ });
663
+ }
664
+ if (valueParser == null) Object.defineProperty(result, "validateValue", {
665
+ value(v) {
666
+ if (typeof v !== "boolean") {
667
+ const actualType = v === null ? "null" : typeof v;
668
+ return require_mode_dispatch.wrapForMode(mode, {
669
+ success: false,
670
+ error: formatInvalidValueError(require_message.message`Expected a boolean value, but received ${actualType}.`)
671
+ });
672
+ }
673
+ return require_mode_dispatch.wrapForMode(mode, {
674
+ success: true,
675
+ value: v
676
+ });
677
+ },
678
+ configurable: true,
679
+ enumerable: false
680
+ });
681
+ else if (!require_dependency.isDerivedValueParser(valueParser)) {
682
+ const vp = valueParser;
683
+ const wrapParseResult = (parsed) => parsed.success ? parsed : {
684
+ success: false,
685
+ error: formatInvalidValueError(parsed.error)
686
+ };
687
+ Object.defineProperty(result, "validateValue", {
688
+ value(v) {
689
+ let stringified;
690
+ try {
691
+ stringified = vp.format(v);
692
+ } catch {
693
+ return require_mode_dispatch.wrapForMode(mode, {
694
+ success: true,
695
+ value: v
696
+ });
697
+ }
698
+ if (typeof stringified !== "string") return require_mode_dispatch.wrapForMode(mode, {
699
+ success: true,
700
+ value: v
701
+ });
702
+ return require_mode_dispatch.dispatchByMode(mode, () => wrapParseResult(vp.parse(stringified)), async () => wrapParseResult(await vp.parse(stringified)));
703
+ },
704
+ configurable: true,
705
+ enumerable: false
706
+ });
707
+ }
708
+ if (valueParser != null) Object.defineProperty(result, "placeholder", {
709
+ get() {
710
+ try {
711
+ return valueParser.placeholder;
712
+ } catch {
713
+ return void 0;
714
+ }
715
+ },
716
+ configurable: true,
717
+ enumerable: false
718
+ });
719
+ else Object.defineProperty(result, "placeholder", {
720
+ value: false,
721
+ configurable: true,
722
+ enumerable: false,
723
+ writable: false
724
+ });
725
+ if (dependencyMetadata != null) Object.defineProperty(result, "dependencyMetadata", {
726
+ value: dependencyMetadata,
727
+ configurable: true,
728
+ enumerable: false
729
+ });
547
730
  return result;
548
731
  }
549
732
  /**
@@ -585,16 +768,19 @@ function flag(...args) {
585
768
  options = lastArg;
586
769
  optionNames$1 = args.slice(0, -1);
587
770
  } else optionNames$1 = args;
588
- return {
771
+ require_validate.validateOptionNames(optionNames$1, "Flag");
772
+ const result = {
589
773
  $valueType: [],
590
774
  $stateType: [],
591
- $mode: "sync",
775
+ mode: "sync",
592
776
  priority: 10,
593
777
  usage: [{
594
778
  type: "option",
595
779
  names: optionNames$1,
596
780
  ...options.hidden != null && { hidden: options.hidden }
597
781
  }],
782
+ leadingNames: new Set(optionNames$1),
783
+ acceptingAnyToken: false,
598
784
  initialState: void 0,
599
785
  parse(context) {
600
786
  if (context.optionsTerminated) return {
@@ -685,7 +871,7 @@ function flag(...args) {
685
871
  error: require_suggestion.createErrorWithSuggestions(baseError, invalidOption, context.usage, "option")
686
872
  };
687
873
  },
688
- complete(state) {
874
+ complete(state, _exec) {
689
875
  if (state == null) return {
690
876
  success: false,
691
877
  error: options.errors?.missing ? typeof options.errors.missing === "function" ? options.errors.missing(optionNames$1) : options.errors.missing : require_message.message`Required flag ${require_message.optionNames(optionNames$1)} is missing.`
@@ -735,6 +921,13 @@ function flag(...args) {
735
921
  return `flag(${optionNames$1.map((o) => JSON.stringify(o)).join(", ")})`;
736
922
  }
737
923
  };
924
+ Object.defineProperty(result, "placeholder", {
925
+ value: true,
926
+ configurable: true,
927
+ enumerable: false,
928
+ writable: false
929
+ });
930
+ return result;
738
931
  }
739
932
  /**
740
933
  * Creates a parser that expects a single argument value.
@@ -750,7 +943,10 @@ function flag(...args) {
750
943
  * the parsed value of type {@link T}.
751
944
  */
752
945
  function argument(valueParser, options = {}) {
753
- const isAsync = valueParser.$mode === "async";
946
+ const isAsync = valueParser.mode === "async";
947
+ const syncValueParser = valueParser;
948
+ const dependencyMetadata = require_dependency_metadata.extractDependencyMetadata(valueParser);
949
+ const formatInvalidValueError = (error) => options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(error) : options.errors.invalidValue : require_message.message`${require_message.metavar(valueParser.metavar)}: ${error}`;
754
950
  const optionPattern = /^--?[a-z0-9-]+$/i;
755
951
  const term = {
756
952
  type: "argument",
@@ -758,13 +954,16 @@ function argument(valueParser, options = {}) {
758
954
  ...options.hidden != null && { hidden: options.hidden }
759
955
  };
760
956
  const result = {
761
- $mode: valueParser.$mode,
957
+ mode: valueParser.mode,
762
958
  $valueType: [],
763
959
  $stateType: [],
764
960
  priority: 5,
765
961
  usage: [term],
962
+ leadingNames: EMPTY_LEADING_NAMES,
963
+ acceptingAnyToken: true,
766
964
  initialState: void 0,
767
965
  parse(context) {
966
+ const localState = require_annotation_state.normalizeInjectedAnnotationState(context.state);
768
967
  if (context.buffer.length < 1) return {
769
968
  success: false,
770
969
  consumed: 0,
@@ -787,72 +986,78 @@ function argument(valueParser, options = {}) {
787
986
  consumed: i,
788
987
  error: require_message.message`Expected an argument, but got end of input.`
789
988
  };
790
- if (context.state != null) return {
989
+ if (localState != null) return {
791
990
  success: false,
792
991
  consumed: i,
793
992
  error: options.errors?.multiple ? typeof options.errors.multiple === "function" ? options.errors.multiple(valueParser.metavar) : options.errors.multiple : require_message.message`The argument ${require_message.metavar(valueParser.metavar)} cannot be used multiple times.`
794
993
  };
795
994
  const rawInput = context.buffer[i];
796
- const parseResultOrPromise = valueParser.parse(rawInput);
797
- if (isAsync) return parseResultOrPromise.then((parseResult) => ({
798
- success: true,
799
- next: {
800
- ...context,
801
- buffer: context.buffer.slice(i + 1),
802
- state: createOptionParseState(rawInput, valueParser, parseResult),
803
- optionsTerminated
804
- },
805
- consumed: context.buffer.slice(0, i + 1)
806
- }));
807
- return {
808
- success: true,
809
- next: {
810
- ...context,
811
- buffer: context.buffer.slice(i + 1),
812
- state: createOptionParseState(rawInput, valueParser, parseResultOrPromise),
813
- optionsTerminated
814
- },
815
- consumed: context.buffer.slice(0, i + 1)
816
- };
995
+ return require_mode_dispatch.dispatchByMode(valueParser.mode, () => {
996
+ const parseResult = syncValueParser.parse(rawInput);
997
+ const next = recordTrace(context, buildTraceEntry("argument-value", rawInput, context.buffer.slice(0, i + 1), syncValueParser, parseResult));
998
+ return {
999
+ success: true,
1000
+ next: {
1001
+ ...next,
1002
+ buffer: context.buffer.slice(i + 1),
1003
+ state: createOptionParseState(parseResult),
1004
+ optionsTerminated
1005
+ },
1006
+ consumed: context.buffer.slice(0, i + 1)
1007
+ };
1008
+ }, async () => {
1009
+ const parseResult = await valueParser.parse(rawInput);
1010
+ const next = recordTrace(context, buildTraceEntry("argument-value", rawInput, context.buffer.slice(0, i + 1), valueParser, parseResult));
1011
+ return {
1012
+ success: true,
1013
+ next: {
1014
+ ...next,
1015
+ buffer: context.buffer.slice(i + 1),
1016
+ state: createOptionParseState(parseResult),
1017
+ optionsTerminated
1018
+ },
1019
+ consumed: context.buffer.slice(0, i + 1)
1020
+ };
1021
+ });
817
1022
  },
818
- complete(state) {
819
- if (state == null) return {
1023
+ complete(state, exec) {
1024
+ const missing = {
820
1025
  success: false,
821
1026
  error: options.errors?.endOfInput ?? require_message.message`Expected a ${require_message.metavar(valueParser.metavar)}, but too few arguments.`
822
1027
  };
823
- if (require_dependency.isDeferredParseState(state)) {
824
- const preliminaryResult = state.preliminaryResult;
825
- if (preliminaryResult.success) return preliminaryResult;
826
- return {
1028
+ const completeSync = () => {
1029
+ if (state == null) return missing;
1030
+ const resolvedState = dependencyMetadata?.derived != null ? resolveDerivedCompletionSync(dependencyMetadata, state, exec) : state;
1031
+ return resolvedState.success ? resolvedState : {
827
1032
  success: false,
828
- error: options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(preliminaryResult.error) : options.errors.invalidValue : require_message.message`${require_message.metavar(valueParser.metavar)}: ${preliminaryResult.error}`
1033
+ error: formatInvalidValueError(resolvedState.error)
829
1034
  };
830
- }
831
- if (require_dependency.isDependencySourceState(state)) {
832
- const result$1 = state.result;
833
- if (result$1.success) return result$1;
834
- return {
1035
+ };
1036
+ const completeAsync = async () => {
1037
+ if (state == null) return missing;
1038
+ if (dependencyMetadata?.derived == null) return completeSync();
1039
+ const resolved = await resolveDerivedCompletionAsync(dependencyMetadata, state, exec);
1040
+ return resolved.success ? resolved : {
835
1041
  success: false,
836
- error: options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(result$1.error) : options.errors.invalidValue : require_message.message`${require_message.metavar(valueParser.metavar)}: ${result$1.error}`
1042
+ error: formatInvalidValueError(resolved.error)
837
1043
  };
838
- }
839
- if (state.success) return state;
840
- return {
841
- success: false,
842
- error: options.errors?.invalidValue ? typeof options.errors.invalidValue === "function" ? options.errors.invalidValue(state.error) : options.errors.invalidValue : require_message.message`${require_message.metavar(valueParser.metavar)}: ${state.error}`
843
1044
  };
1045
+ return require_mode_dispatch.dispatchByMode(valueParser.mode, completeSync, completeAsync);
844
1046
  },
845
1047
  suggest(context, prefix) {
846
- if (context.state != null) return require_mode_dispatch.dispatchIterableByMode(valueParser.$mode, function* () {}, async function* () {});
847
- if (isAsync) return suggestArgumentAsync(valueParser, require_usage.isSuggestionHidden(options.hidden), prefix, context.dependencyRegistry);
848
- return suggestArgumentSync(valueParser, require_usage.isSuggestionHidden(options.hidden), prefix, context.dependencyRegistry);
1048
+ if (require_annotation_state.normalizeInjectedAnnotationState(context.state) != null) return require_mode_dispatch.dispatchIterableByMode(valueParser.mode, function* () {}, async function* () {});
1049
+ if (isAsync) return suggestArgumentAsync(valueParser, require_usage.isSuggestionHidden(options.hidden), prefix, context.dependencyRegistry, context.exec);
1050
+ return suggestArgumentSync(valueParser, require_usage.isSuggestionHidden(options.hidden), prefix, context.dependencyRegistry, context.exec);
849
1051
  },
850
1052
  getDocFragments(_state, defaultValue) {
851
1053
  if (require_usage.isDocHidden(options.hidden)) return {
852
1054
  fragments: [],
853
1055
  description: options.description
854
1056
  };
855
- const choicesMessage = valueParser.choices != null && valueParser.choices.length > 0 ? require_message.valueSet(valueParser.choices.map((c) => valueParser.format(c)), { type: "unit" }) : void 0;
1057
+ const choicesMessage = valueParser.choices != null && valueParser.choices.length > 0 ? require_message.valueSet(valueParser.choices.map((c) => valueParser.format(c)), {
1058
+ fallback: "",
1059
+ type: "unit"
1060
+ }) : void 0;
856
1061
  const fragments = [{
857
1062
  type: "entry",
858
1063
  term,
@@ -869,44 +1074,111 @@ function argument(valueParser, options = {}) {
869
1074
  return `argument()`;
870
1075
  }
871
1076
  };
1077
+ if (typeof valueParser.normalize === "function") {
1078
+ const normalize = valueParser.normalize.bind(valueParser);
1079
+ Object.defineProperty(result, "normalizeValue", {
1080
+ value(v) {
1081
+ try {
1082
+ return normalize(v);
1083
+ } catch {
1084
+ return v;
1085
+ }
1086
+ },
1087
+ configurable: true,
1088
+ enumerable: false
1089
+ });
1090
+ }
1091
+ if (!require_dependency.isDerivedValueParser(valueParser)) {
1092
+ const vp = valueParser;
1093
+ const vpMode = valueParser.mode;
1094
+ const wrapParseResult = (parsed) => parsed.success ? parsed : {
1095
+ success: false,
1096
+ error: formatInvalidValueError(parsed.error)
1097
+ };
1098
+ Object.defineProperty(result, "validateValue", {
1099
+ value(v) {
1100
+ let stringified;
1101
+ try {
1102
+ stringified = vp.format(v);
1103
+ } catch {
1104
+ return require_mode_dispatch.wrapForMode(vpMode, {
1105
+ success: true,
1106
+ value: v
1107
+ });
1108
+ }
1109
+ if (typeof stringified !== "string") return require_mode_dispatch.wrapForMode(vpMode, {
1110
+ success: true,
1111
+ value: v
1112
+ });
1113
+ return require_mode_dispatch.dispatchByMode(vpMode, () => wrapParseResult(syncValueParser.parse(stringified)), async () => wrapParseResult(await vp.parse(stringified)));
1114
+ },
1115
+ configurable: true,
1116
+ enumerable: false
1117
+ });
1118
+ }
1119
+ Object.defineProperty(result, "placeholder", {
1120
+ get() {
1121
+ try {
1122
+ return valueParser.placeholder;
1123
+ } catch {
1124
+ return void 0;
1125
+ }
1126
+ },
1127
+ configurable: true,
1128
+ enumerable: false
1129
+ });
1130
+ if (dependencyMetadata != null) Object.defineProperty(result, "dependencyMetadata", {
1131
+ value: dependencyMetadata,
1132
+ configurable: true,
1133
+ enumerable: false
1134
+ });
872
1135
  return result;
873
1136
  }
1137
+ function normalizeCommandState(state) {
1138
+ return require_annotation_state.normalizeInjectedAnnotationState(state);
1139
+ }
1140
+ function getCommandParseChildState(commandState, childState, parser) {
1141
+ return require_annotation_state.getWrappedChildParseState(commandState, childState, parser);
1142
+ }
1143
+ function getCommandChildState(commandState, childState, parser) {
1144
+ return require_annotation_state.getWrappedChildState(commandState, childState, parser);
1145
+ }
1146
+ function createCommandState(sourceState, state) {
1147
+ return require_annotations.annotateFreshArray(sourceState, state);
1148
+ }
1149
+ function appendCommandPath(exec, name) {
1150
+ if (exec == null) return void 0;
1151
+ return {
1152
+ ...exec,
1153
+ commandPath: [...exec.commandPath ?? [], name]
1154
+ };
1155
+ }
874
1156
  function* suggestCommandSync(context, prefix, name, parser, options) {
875
1157
  if (require_usage.isSuggestionHidden(options.hidden)) return;
876
- if (context.state === void 0) {
1158
+ const state = normalizeCommandState(context.state);
1159
+ if (state === void 0) {
877
1160
  if (name.startsWith(prefix)) yield {
878
1161
  kind: "literal",
879
1162
  text: name,
880
1163
  ...options.description && { description: options.description }
881
1164
  };
882
- } else if (context.state[0] === "matched") yield* parser.suggest({
883
- ...context,
884
- state: parser.initialState
885
- }, prefix);
886
- else if (context.state[0] === "parsing") yield* parser.suggest({
887
- ...context,
888
- state: context.state[1]
889
- }, prefix);
1165
+ } else if (state[0] === "matched") yield* parser.suggest(require_execution_context.withChildContext(context, name, getCommandChildState(context.state, parser.initialState, parser), parser.usage), prefix);
1166
+ else if (state[0] === "parsing") yield* parser.suggest(require_execution_context.withChildContext(context, name, getCommandChildState(context.state, state[1], parser), parser.usage), prefix);
890
1167
  }
891
1168
  async function* suggestCommandAsync(context, prefix, name, parser, options) {
892
1169
  if (require_usage.isSuggestionHidden(options.hidden)) return;
893
- if (context.state === void 0) {
1170
+ const state = normalizeCommandState(context.state);
1171
+ if (state === void 0) {
894
1172
  if (name.startsWith(prefix)) yield {
895
1173
  kind: "literal",
896
1174
  text: name,
897
1175
  ...options.description && { description: options.description }
898
1176
  };
899
- } else if (context.state[0] === "matched") {
900
- const suggestions = parser.suggest({
901
- ...context,
902
- state: parser.initialState
903
- }, prefix);
1177
+ } else if (state[0] === "matched") {
1178
+ const suggestions = parser.suggest(require_execution_context.withChildContext(context, name, getCommandChildState(context.state, parser.initialState, parser), parser.usage), prefix);
904
1179
  for await (const s of suggestions) yield s;
905
- } else if (context.state[0] === "parsing") {
906
- const suggestions = parser.suggest({
907
- ...context,
908
- state: context.state[1]
909
- }, prefix);
1180
+ } else if (state[0] === "parsing") {
1181
+ const suggestions = parser.suggest(require_execution_context.withChildContext(context, name, getCommandChildState(context.state, state[1], parser), parser.usage), prefix);
910
1182
  for await (const s of suggestions) yield s;
911
1183
  }
912
1184
  }
@@ -923,11 +1195,17 @@ async function* suggestCommandAsync(context, prefix, name, parser, options) {
923
1195
  * a description for documentation.
924
1196
  * @returns A {@link Parser} that matches the command name and delegates
925
1197
  * to the inner parser for the remaining arguments.
1198
+ * @throws {TypeError} If `name` is empty, whitespace-only, contains
1199
+ * embedded whitespace, or contains control characters.
926
1200
  */
927
1201
  function command(name, parser, options = {}) {
928
- const isAsync = parser.$mode === "async";
1202
+ require_validate.validateCommandNames([name], "Command");
1203
+ const isAsync = parser.mode === "async";
1204
+ const syncInnerParser = parser;
1205
+ const asyncInnerParser = parser;
929
1206
  const result = {
930
- $mode: parser.$mode,
1207
+ [Symbol.for("@optique/core/commandParser")]: true,
1208
+ mode: parser.mode,
931
1209
  $valueType: [],
932
1210
  $stateType: [],
933
1211
  priority: 15,
@@ -937,9 +1215,23 @@ function command(name, parser, options = {}) {
937
1215
  ...options.usageLine != null && { usageLine: options.usageLine },
938
1216
  ...options.hidden != null && { hidden: options.hidden }
939
1217
  }, ...parser.usage],
1218
+ leadingNames: new Set([name]),
1219
+ acceptingAnyToken: false,
940
1220
  initialState: void 0,
1221
+ getSuggestRuntimeNodes(state, path) {
1222
+ const normalizedState = normalizeCommandState(state);
1223
+ if (normalizedState === void 0) return [];
1224
+ const childState = normalizedState[0] === "matched" ? getCommandChildState(state, parser.initialState, parser) : getCommandChildState(state, normalizedState[1], parser);
1225
+ const childPath = [...path, name];
1226
+ return parser.getSuggestRuntimeNodes?.(childState, childPath) ?? (parser.dependencyMetadata?.source != null ? [{
1227
+ path: childPath,
1228
+ parser,
1229
+ state: childState
1230
+ }] : []);
1231
+ },
941
1232
  parse(context) {
942
- if (context.state === void 0) {
1233
+ const state = normalizeCommandState(context.state);
1234
+ if (state === void 0) {
943
1235
  if (context.buffer.length < 1 || context.buffer[0] !== name) {
944
1236
  const actual = context.buffer.length > 0 ? context.buffer[0] : null;
945
1237
  const leadingCmds = require_usage_internals.extractLeadingCommandNames(context.usage);
@@ -974,29 +1266,32 @@ function command(name, parser, options = {}) {
974
1266
  next: {
975
1267
  ...context,
976
1268
  buffer: context.buffer.slice(1),
977
- state: ["matched", name]
1269
+ state: createCommandState(context.state, ["matched", name]),
1270
+ ...context.exec != null ? { exec: appendCommandPath(context.exec, name) } : {}
978
1271
  },
979
1272
  consumed: context.buffer.slice(0, 1)
980
1273
  };
981
- } else if (context.state[0] === "matched" || context.state[0] === "parsing") {
982
- const innerState = context.state[0] === "matched" ? parser.initialState : context.state[1];
983
- const parseResultOrPromise = parser.parse({
984
- ...context,
985
- state: innerState
986
- });
1274
+ } else if (state[0] === "matched" || state[0] === "parsing") {
1275
+ const innerState = state[0] === "matched" ? getCommandParseChildState(context.state, parser.initialState, parser) : getCommandParseChildState(context.state, state[1], parser);
987
1276
  const wrapState = (parseResult) => {
988
- if (parseResult.success) return {
989
- success: true,
990
- next: {
991
- ...parseResult.next,
992
- state: ["parsing", parseResult.next.state]
993
- },
994
- consumed: parseResult.consumed
995
- };
1277
+ if (parseResult.success) {
1278
+ const mergedExec = require_execution_context.mergeChildExec(context.exec, parseResult.next.exec);
1279
+ return {
1280
+ success: true,
1281
+ next: {
1282
+ ...parseResult.next,
1283
+ state: createCommandState(context.state, ["parsing", parseResult.next.state]),
1284
+ ...mergedExec != null ? {
1285
+ exec: mergedExec,
1286
+ dependencyRegistry: mergedExec.dependencyRegistry
1287
+ } : {}
1288
+ },
1289
+ consumed: parseResult.consumed
1290
+ };
1291
+ }
996
1292
  return parseResult;
997
1293
  };
998
- if (isAsync) return parseResultOrPromise.then(wrapState);
999
- return wrapState(parseResultOrPromise);
1294
+ return require_mode_dispatch.dispatchByMode(parser.mode, () => wrapState(syncInnerParser.parse(require_execution_context.withChildContext(context, name, innerState, parser.usage))), async () => wrapState(await parser.parse(require_execution_context.withChildContext(context, name, innerState, parser.usage))));
1000
1295
  }
1001
1296
  return {
1002
1297
  success: false,
@@ -1004,37 +1299,79 @@ function command(name, parser, options = {}) {
1004
1299
  error: options.errors?.invalidState ?? require_message.message`Invalid command state.`
1005
1300
  };
1006
1301
  },
1007
- complete(state) {
1008
- if (typeof state === "undefined") return {
1302
+ complete(state, exec) {
1303
+ const normalizedState = normalizeCommandState(state);
1304
+ if (typeof normalizedState === "undefined") return {
1009
1305
  success: false,
1010
1306
  error: options.errors?.notFound ?? require_message.message`Command ${require_message.optionName(name)} was not matched.`
1011
1307
  };
1012
- else if (state[0] === "matched") {
1013
- const parseResultOrPromise = parser.parse({
1308
+ else if (normalizedState[0] === "matched") {
1309
+ const childExec = require_execution_context.withChildExecPath(exec, name);
1310
+ const childContext = {
1014
1311
  buffer: [],
1015
1312
  optionsTerminated: false,
1016
- usage: [],
1017
- state: parser.initialState
1018
- });
1019
- if (isAsync) return parseResultOrPromise.then((parseResult$1) => {
1020
- if (parseResult$1.success) return parser.complete(parseResult$1.next.state);
1021
- return parser.complete(parser.initialState);
1313
+ usage: parser.usage,
1314
+ state: getCommandParseChildState(state, parser.initialState, parser),
1315
+ ...childExec != null ? {
1316
+ exec: childExec,
1317
+ trace: childExec.trace,
1318
+ dependencyRegistry: childExec.dependencyRegistry
1319
+ } : {}
1320
+ };
1321
+ return require_mode_dispatch.dispatchByMode(parser.mode, () => {
1322
+ const parseResult = syncInnerParser.parse(childContext);
1323
+ const nextExec = parseResult.success ? require_execution_context.mergeChildExec(childExec, parseResult.next.exec) : childExec;
1324
+ return syncInnerParser.complete(parseResult.success ? getCommandChildState(state, parseResult.next.state, parser) : getCommandChildState(state, syncInnerParser.initialState, parser), nextExec);
1325
+ }, async () => {
1326
+ const parseResult = await asyncInnerParser.parse(childContext);
1327
+ const nextExec = parseResult.success ? require_execution_context.mergeChildExec(childExec, parseResult.next.exec) : childExec;
1328
+ return asyncInnerParser.complete(parseResult.success ? getCommandChildState(state, parseResult.next.state, parser) : getCommandChildState(state, parser.initialState, parser), nextExec);
1022
1329
  });
1023
- const parseResult = parseResultOrPromise;
1024
- if (parseResult.success) return parser.complete(parseResult.next.state);
1025
- return parser.complete(parser.initialState);
1026
- } else if (state[0] === "parsing") return parser.complete(state[1]);
1330
+ } else if (normalizedState[0] === "parsing") {
1331
+ const childExec = require_execution_context.withChildExecPath(exec, name);
1332
+ return require_mode_dispatch.dispatchByMode(parser.mode, () => syncInnerParser.complete(getCommandChildState(state, normalizedState[1], parser), childExec), async () => await asyncInnerParser.complete(getCommandChildState(state, normalizedState[1], parser), childExec));
1333
+ }
1027
1334
  return {
1028
1335
  success: false,
1029
1336
  error: options.errors?.invalidState ?? require_message.message`Invalid command state during completion.`
1030
1337
  };
1031
1338
  },
1339
+ [require_phase2_seed.extractPhase2SeedKey](state, exec) {
1340
+ const normalizedState = normalizeCommandState(state);
1341
+ if (typeof normalizedState === "undefined") return require_mode_dispatch.wrapForMode(parser.mode, null);
1342
+ if (normalizedState[0] === "matched") {
1343
+ const childExec = require_execution_context.withChildExecPath(exec, name);
1344
+ const childContext = {
1345
+ buffer: [],
1346
+ optionsTerminated: false,
1347
+ usage: parser.usage,
1348
+ state: getCommandParseChildState(state, parser.initialState, parser),
1349
+ ...childExec != null ? {
1350
+ exec: childExec,
1351
+ trace: childExec.trace,
1352
+ dependencyRegistry: childExec.dependencyRegistry
1353
+ } : {}
1354
+ };
1355
+ return require_mode_dispatch.dispatchByMode(parser.mode, () => {
1356
+ const parseResult = syncInnerParser.parse(childContext);
1357
+ const nextExec = parseResult.success ? require_execution_context.mergeChildExec(childExec, parseResult.next.exec) : childExec;
1358
+ return require_phase2_seed.completeOrExtractPhase2Seed(syncInnerParser, parseResult.success ? getCommandChildState(state, parseResult.next.state, parser) : getCommandChildState(state, syncInnerParser.initialState, parser), nextExec);
1359
+ }, async () => {
1360
+ const parseResult = await asyncInnerParser.parse(childContext);
1361
+ const nextExec = parseResult.success ? require_execution_context.mergeChildExec(childExec, parseResult.next.exec) : childExec;
1362
+ return await require_phase2_seed.completeOrExtractPhase2Seed(asyncInnerParser, parseResult.success ? getCommandChildState(state, parseResult.next.state, parser) : getCommandChildState(state, parser.initialState, parser), nextExec);
1363
+ });
1364
+ }
1365
+ if (normalizedState[0] === "parsing") return require_phase2_seed.completeOrExtractPhase2Seed(parser, getCommandChildState(state, normalizedState[1], parser), require_execution_context.withChildExecPath(exec, name));
1366
+ return require_mode_dispatch.wrapForMode(parser.mode, null);
1367
+ },
1032
1368
  suggest(context, prefix) {
1033
1369
  if (isAsync) return suggestCommandAsync(context, prefix, name, parser, options);
1034
1370
  return suggestCommandSync(context, prefix, name, parser, options);
1035
1371
  },
1036
1372
  getDocFragments(state, defaultValue) {
1037
- if (state.kind === "unavailable" || typeof state.state === "undefined") {
1373
+ const commandState = state.kind === "available" ? normalizeCommandState(state.state) : void 0;
1374
+ if (state.kind === "unavailable" || typeof commandState === "undefined") {
1038
1375
  if (require_usage.isDocHidden(options.hidden)) return {
1039
1376
  fragments: [],
1040
1377
  description: options.description
@@ -1051,12 +1388,12 @@ function command(name, parser, options = {}) {
1051
1388
  }]
1052
1389
  };
1053
1390
  }
1054
- const innerState = state.state[0] === "parsing" ? {
1391
+ const innerState = commandState[0] === "parsing" ? {
1055
1392
  kind: "available",
1056
- state: state.state[1]
1393
+ state: getCommandChildState(state.state, commandState[1], parser)
1057
1394
  } : {
1058
1395
  kind: "available",
1059
- state: parser.initialState
1396
+ state: getCommandChildState(state.state, parser.initialState, parser)
1060
1397
  };
1061
1398
  const innerFragments = parser.getDocFragments(innerState, defaultValue);
1062
1399
  return {
@@ -1070,6 +1407,16 @@ function command(name, parser, options = {}) {
1070
1407
  return `command(${JSON.stringify(name)})`;
1071
1408
  }
1072
1409
  };
1410
+ if (typeof parser.normalizeValue === "function") Object.defineProperty(result, "normalizeValue", {
1411
+ value: parser.normalizeValue.bind(parser),
1412
+ configurable: true,
1413
+ enumerable: false
1414
+ });
1415
+ if (typeof parser.validateValue === "function") Object.defineProperty(result, "validateValue", {
1416
+ value: parser.validateValue.bind(parser),
1417
+ configurable: true,
1418
+ enumerable: false
1419
+ });
1073
1420
  return result;
1074
1421
  }
1075
1422
  /**
@@ -1125,12 +1472,14 @@ function passThrough(options = {}) {
1125
1472
  return {
1126
1473
  $valueType: [],
1127
1474
  $stateType: [],
1128
- $mode: "sync",
1475
+ mode: "sync",
1129
1476
  priority: -10,
1130
1477
  usage: [{
1131
1478
  type: "passthrough",
1132
1479
  ...options.hidden != null && { hidden: options.hidden }
1133
1480
  }],
1481
+ leadingNames: EMPTY_LEADING_NAMES,
1482
+ acceptingAnyToken: false,
1134
1483
  initialState: [],
1135
1484
  parse(context) {
1136
1485
  if (context.buffer.length < 1) return {
@@ -1217,7 +1566,7 @@ function passThrough(options = {}) {
1217
1566
  error: require_message.message`Unknown passThrough format: ${format}.`
1218
1567
  };
1219
1568
  },
1220
- complete(state) {
1569
+ complete(state, _exec) {
1221
1570
  if (require_annotations.getAnnotations(state) == null) return {
1222
1571
  success: true,
1223
1572
  value: state