@optique/core 1.1.0-dev.2087 → 1.1.0-dev.2146

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 (74) hide show
  1. package/dist/annotation-state.cjs +26 -26
  2. package/dist/annotation-state.d.cts +133 -1
  3. package/dist/annotation-state.d.ts +133 -1
  4. package/dist/annotations.cjs +2 -2
  5. package/dist/constructs.cjs +873 -73
  6. package/dist/constructs.d.cts +72 -1
  7. package/dist/constructs.d.ts +72 -1
  8. package/dist/constructs.js +808 -9
  9. package/dist/dependency-metadata.cjs +12 -12
  10. package/dist/dependency-metadata.d.cts +34 -3
  11. package/dist/dependency-metadata.d.ts +34 -3
  12. package/dist/dependency-runtime.cjs +37 -13
  13. package/dist/dependency-runtime.d.cts +197 -2
  14. package/dist/dependency-runtime.d.ts +197 -2
  15. package/dist/dependency-runtime.js +22 -1
  16. package/dist/dependency.cjs +7 -7
  17. package/dist/displaywidth.d.cts +12 -0
  18. package/dist/displaywidth.d.ts +12 -0
  19. package/dist/doc.cjs +3 -0
  20. package/dist/doc.js +3 -0
  21. package/dist/execution-context.d.cts +23 -0
  22. package/dist/execution-context.d.ts +23 -0
  23. package/dist/extension.cjs +14 -14
  24. package/dist/facade.cjs +49 -37
  25. package/dist/facade.js +34 -22
  26. package/dist/index.cjs +23 -21
  27. package/dist/index.d.cts +3 -3
  28. package/dist/index.d.ts +3 -3
  29. package/dist/index.js +4 -4
  30. package/dist/input-trace.d.cts +2 -1
  31. package/dist/input-trace.d.ts +2 -1
  32. package/dist/internal/annotations.cjs +3 -0
  33. package/dist/internal/annotations.d.cts +47 -5
  34. package/dist/internal/annotations.d.ts +47 -5
  35. package/dist/internal/annotations.js +1 -1
  36. package/dist/internal/command-alias.cjs +16 -0
  37. package/dist/internal/command-alias.js +14 -0
  38. package/dist/internal/dependency.cjs +131 -0
  39. package/dist/internal/dependency.d.cts +311 -2
  40. package/dist/internal/dependency.d.ts +311 -2
  41. package/dist/internal/dependency.js +119 -1
  42. package/dist/internal/parser.cjs +108 -23
  43. package/dist/internal/parser.d.cts +58 -3
  44. package/dist/internal/parser.d.ts +58 -3
  45. package/dist/internal/parser.js +101 -16
  46. package/dist/modifiers.cjs +74 -44
  47. package/dist/modifiers.js +34 -4
  48. package/dist/parser.cjs +11 -11
  49. package/dist/phase2-seed.cjs +2 -2
  50. package/dist/phase2-seed.d.cts +50 -0
  51. package/dist/phase2-seed.d.ts +50 -0
  52. package/dist/primitives.cjs +104 -33
  53. package/dist/primitives.d.cts +10 -0
  54. package/dist/primitives.d.ts +10 -0
  55. package/dist/primitives.js +84 -13
  56. package/dist/suggestion.cjs +72 -2
  57. package/dist/suggestion.d.cts +188 -0
  58. package/dist/suggestion.d.ts +188 -0
  59. package/dist/suggestion.js +71 -3
  60. package/dist/usage-internals.cjs +14 -6
  61. package/dist/usage-internals.js +14 -6
  62. package/dist/usage.cjs +33 -8
  63. package/dist/usage.d.cts +31 -0
  64. package/dist/usage.d.ts +31 -0
  65. package/dist/usage.js +33 -8
  66. package/dist/validate.cjs +1 -0
  67. package/dist/validate.d.cts +99 -0
  68. package/dist/validate.d.ts +99 -0
  69. package/dist/validate.js +1 -1
  70. package/dist/valueparser.cjs +333 -79
  71. package/dist/valueparser.d.cts +197 -1
  72. package/dist/valueparser.d.ts +197 -1
  73. package/dist/valueparser.js +334 -81
  74. package/package.json +19 -4
@@ -123,6 +123,7 @@ function parseSync(parser, args, options) {
123
123
  phase: "complete",
124
124
  dependencyRuntime: runtime,
125
125
  dependencyRegistry: runtime.registry,
126
+ commandPath: context.exec?.commandPath ?? exec.commandPath,
126
127
  trace: context.exec?.trace ?? context.trace ?? exec.trace
127
128
  };
128
129
  const endResult = parser.complete(context.state, completeExec);
@@ -195,6 +196,7 @@ async function parseAsync(parser, args, options) {
195
196
  phase: "complete",
196
197
  dependencyRuntime: runtime,
197
198
  dependencyRegistry: runtime.registry,
199
+ commandPath: context.exec?.commandPath ?? exec.commandPath,
198
200
  trace: context.exec?.trace ?? context.trace ?? exec.trace
199
201
  };
200
202
  const endResult = await parser.complete(context.state, completeExec);
@@ -501,14 +503,83 @@ function findCommandInExclusive(term, commandName) {
501
503
  if (term.type !== "exclusive") return null;
502
504
  for (const termGroup of term.terms) {
503
505
  const firstTerm = termGroup[0];
504
- if (firstTerm?.type === "command" && firstTerm.name === commandName) return termGroup;
505
- if (firstTerm?.type === "exclusive") {
506
- const found = findCommandInExclusive(firstTerm, commandName);
507
- if (found) return [...found, ...termGroup.slice(1)];
508
- }
506
+ if (firstTerm == null) continue;
507
+ const found = findCommandInCurrentUsageTerm(firstTerm, commandName, termGroup.slice(1));
508
+ if (found) return found;
509
+ }
510
+ return null;
511
+ }
512
+ /**
513
+ * Searches for a command inside an ordered usage sequence and returns the
514
+ * usage from the matched command onward. This lets contextual command
515
+ * documentation enter sequence terms while dropping sequence prefixes that
516
+ * were skipped by parsing, such as optional positionals before a subcommand.
517
+ *
518
+ * @param usage The usage terms to search.
519
+ * @param commandName The command name to find.
520
+ * @returns The contextual usage terms if found, null otherwise.
521
+ */
522
+ function findCommandInUsageSequence(usage, commandName) {
523
+ for (let index = 0; index < usage.length; index++) {
524
+ const found = findCommandInCurrentUsageTerm(usage[index], commandName, usage.slice(index + 1));
525
+ if (found) return found;
526
+ }
527
+ return null;
528
+ }
529
+ /**
530
+ * Searches the current usage term for a command and appends the trailing
531
+ * usage terms that remain valid after that current term.
532
+ *
533
+ * @param term The current usage term to search.
534
+ * @param commandName The command name to find.
535
+ * @param trailingUsage Usage terms that follow the current term.
536
+ * @returns The contextual usage terms if found, null otherwise.
537
+ */
538
+ function findCommandInCurrentUsageTerm(term, commandName, trailingUsage) {
539
+ if (term.type === "command" && commandTermMatches(term, commandName)) return [term, ...trailingUsage];
540
+ if (term.type === "exclusive") {
541
+ const found = findCommandInExclusive(term, commandName);
542
+ if (found) return [...found, ...trailingUsage];
543
+ } else if (term.type === "sequence") {
544
+ const found = findCommandInUsageSequence(term.terms, commandName);
545
+ if (found) return [...found, ...trailingUsage];
509
546
  }
510
547
  return null;
511
548
  }
549
+ function commandTermMatches(term, commandName) {
550
+ return term?.type === "command" && (term.name === commandName || term.aliases?.includes(commandName) === true || term.hiddenAliases?.includes(commandName) === true);
551
+ }
552
+ function collectCommandInputNames(usage, commandName, names) {
553
+ for (const term of usage) if (term.type === "command") {
554
+ if (commandTermMatches(term, commandName)) {
555
+ names.add(term.name);
556
+ for (const alias of term.aliases ?? []) names.add(alias);
557
+ for (const alias of term.hiddenAliases ?? []) names.add(alias);
558
+ }
559
+ } else if (term.type === "exclusive") for (const branch of term.terms) collectCommandInputNames(branch, commandName, names);
560
+ else if (term.type === "sequence") collectCommandInputNames(term.terms, commandName, names);
561
+ else if (term.type === "optional" || term.type === "multiple") collectCommandInputNames(term.terms, commandName, names);
562
+ }
563
+ function findLastCommandInputIndex(consumed, commandName, usage, searchEnd) {
564
+ const names = new Set([commandName]);
565
+ collectCommandInputNames(usage, commandName, names);
566
+ for (let index = searchEnd - 1; index >= 0; index--) if (names.has(consumed[index])) return index;
567
+ return -1;
568
+ }
569
+ function recordMatchedCommandArgIndices(usage, consumed, previousCommandPath, nextCommandPath, consumedOffset, indices) {
570
+ const previousLength = previousCommandPath?.length ?? 0;
571
+ const next = nextCommandPath ?? [];
572
+ if (next.length <= previousLength || consumed.length < 1) return;
573
+ let searchEnd = consumed.length;
574
+ for (let index = next.length - 1; index >= previousLength; index--) {
575
+ if (searchEnd <= 0) break;
576
+ const commandName = next[index];
577
+ const localIndex = findLastCommandInputIndex(consumed, commandName, usage, searchEnd);
578
+ if (localIndex < 0) continue;
579
+ indices.add(consumedOffset + localIndex);
580
+ searchEnd = localIndex;
581
+ }
582
+ }
512
583
  /**
513
584
  * Generates a documentation page for a synchronous parser.
514
585
  *
@@ -579,14 +650,18 @@ function getDocPageSyncImpl(parser, args, options) {
579
650
  state: initialState,
580
651
  optionsTerminated: false
581
652
  }, exec);
653
+ const matchedCommandArgIndices = /* @__PURE__ */ new Set();
582
654
  while (context.buffer.length > 0) {
583
655
  const result = parser.parse(context);
584
656
  if (!result.success) break;
657
+ const previousCommandPath = context.exec?.commandPath;
585
658
  const previousBuffer = context.buffer;
586
659
  context = result.next;
660
+ const consumedCount = previousBuffer.length - context.buffer.length;
661
+ recordMatchedCommandArgIndices(parser.usage, previousBuffer.slice(0, consumedCount), previousCommandPath, context.exec?.commandPath, args.length - previousBuffer.length, matchedCommandArgIndices);
587
662
  if (isBufferUnchanged(previousBuffer, context.buffer)) break;
588
663
  }
589
- return buildDocPage(parser, context, args);
664
+ return buildDocPage(parser, context, args, matchedCommandArgIndices);
590
665
  }
591
666
  /**
592
667
  * Internal async implementation of getDocPage.
@@ -604,20 +679,24 @@ async function getDocPageAsyncImpl(parser, args, options) {
604
679
  state: initialState,
605
680
  optionsTerminated: false
606
681
  }, exec);
682
+ const matchedCommandArgIndices = /* @__PURE__ */ new Set();
607
683
  while (context.buffer.length > 0) {
608
684
  const result = await parser.parse(context);
609
685
  if (!result.success) break;
686
+ const previousCommandPath = context.exec?.commandPath;
610
687
  const previousBuffer = context.buffer;
611
688
  context = result.next;
689
+ const consumedCount = previousBuffer.length - context.buffer.length;
690
+ recordMatchedCommandArgIndices(parser.usage, previousBuffer.slice(0, consumedCount), previousCommandPath, context.exec?.commandPath, args.length - previousBuffer.length, matchedCommandArgIndices);
612
691
  if (isBufferUnchanged(previousBuffer, context.buffer)) break;
613
692
  }
614
- return buildDocPage(parser, context, args);
693
+ return buildDocPage(parser, context, args, matchedCommandArgIndices);
615
694
  }
616
695
  /**
617
696
  * Builds a DocPage from the parser and context.
618
697
  * Shared by both sync and async implementations.
619
698
  */
620
- function buildDocPage(parser, context, args) {
699
+ function buildDocPage(parser, context, args, matchedCommandArgIndices) {
621
700
  let effectiveArgs = args;
622
701
  let { brief, description, fragments, footer } = parser.getDocFragments({
623
702
  kind: "available",
@@ -668,26 +747,32 @@ function buildDocPage(parser, context, args) {
668
747
  const sections = buildingSections;
669
748
  const usage = [...normalizeUsage(parser.usage)];
670
749
  const maybeApplyCommandUsageLine = (term, arg, isLastArg, usageIndex) => {
671
- if (term?.type !== "command" || term.name !== arg || !isLastArg || term.usageLine == null) return;
750
+ if (term?.type !== "command" || !commandTermMatches(term, arg) || !isLastArg || term.usageLine == null) return;
672
751
  const defaultUsageLine = cloneUsage(usage.slice(usageIndex + 1));
673
752
  const customUsageLine = typeof term.usageLine === "function" ? term.usageLine(defaultUsageLine) : term.usageLine;
674
753
  const normalizedCustomUsageLine = normalizeUsage(customUsageLine);
675
754
  usage.splice(usageIndex + 1, usage.length - (usageIndex + 1), ...normalizedCustomUsageLine);
676
755
  };
677
756
  let i = 0;
757
+ const consumedArgsCount = Math.max(0, effectiveArgs.length - context.buffer.length);
758
+ const commandArgIndices = args.length > 0 ? matchedCommandArgIndices : null;
678
759
  for (let argIndex = 0; argIndex < effectiveArgs.length; argIndex++) {
679
760
  const arg = effectiveArgs[argIndex];
680
761
  if (i >= usage.length) break;
681
762
  let term = usage[i];
682
- if (term.type === "exclusive") {
683
- const found = findCommandInExclusive(term, arg);
684
- if (found) {
685
- usage.splice(i, 1, ...found);
686
- term = usage[i];
687
- }
763
+ const canSearchCommand = commandArgIndices == null || commandArgIndices.has(argIndex);
764
+ if (!canSearchCommand) continue;
765
+ let found = null;
766
+ for (let searchIndex = i; searchIndex < usage.length; searchIndex++) {
767
+ found = findCommandInCurrentUsageTerm(usage[searchIndex], arg, usage.slice(searchIndex + 1));
768
+ if (found != null) break;
769
+ }
770
+ if (found) {
771
+ usage.splice(i, usage.length - i, ...found);
772
+ term = usage[i];
688
773
  }
689
774
  maybeApplyCommandUsageLine(term, arg, argIndex === effectiveArgs.length - 1, i);
690
- i++;
775
+ if (found != null || term.type !== "sequence" || argIndex >= consumedArgsCount) i++;
691
776
  }
692
777
  if (effectiveArgs.length === 0 && usage.length > 0) {
693
778
  const first = usage[0];
@@ -1,7 +1,7 @@
1
- const require_annotations = require('./internal/annotations.cjs');
1
+ const require_internal_annotations = require('./internal/annotations.cjs');
2
2
  const require_message = require('./message.cjs');
3
3
  const require_mode_dispatch = require('./internal/mode-dispatch.cjs');
4
- const require_parser = require('./internal/parser.cjs');
4
+ const require_internal_parser = require('./internal/parser.cjs');
5
5
  const require_annotation_state = require('./annotation-state.cjs');
6
6
  const require_execution_context = require('./execution-context.cjs');
7
7
  const require_phase2_seed = require('./phase2-seed.cjs');
@@ -12,6 +12,11 @@ function isTerminalMultipleItemState(state) {
12
12
  const unwrapped = unwrapMultipleItemState(state).value;
13
13
  return unwrapped != null && typeof unwrapped === "object" && Object.hasOwn(unwrapped, "success") && typeof unwrapped.success === "boolean";
14
14
  }
15
+ function isMatchedCommandParserState(parser, state) {
16
+ if (Reflect.get(parser, Symbol.for("@optique/core/commandParser")) !== true) return false;
17
+ const unwrapped = unwrapMultipleItemState(state).value;
18
+ return Array.isArray(unwrapped) && unwrapped.length === 2 && unwrapped[0] === "matched" && typeof unwrapped[1] === "string";
19
+ }
15
20
  function isUnstartedMultipleItemState(state, originalState) {
16
21
  const unwrappedState = unwrapMultipleItemState(state);
17
22
  if (unwrappedState.value == null) return true;
@@ -26,8 +31,8 @@ function unwrapMultipleItemState(state) {
26
31
  let unwrapped = state;
27
32
  let viaBoundCliWrapper = false;
28
33
  while (true) {
29
- if (require_annotations.isInjectedAnnotationWrapper(unwrapped)) {
30
- unwrapped = require_annotations.unwrapInjectedAnnotationWrapper(unwrapped);
34
+ if (require_internal_annotations.isInjectedAnnotationWrapper(unwrapped)) {
35
+ unwrapped = require_internal_annotations.unwrapInjectedAnnotationWrapper(unwrapped);
31
36
  continue;
32
37
  }
33
38
  if (Array.isArray(unwrapped) && unwrapped.length === 1) {
@@ -55,7 +60,7 @@ function normalizeOptionalLikeCompleteResult(result, shouldNormalize) {
55
60
  } : result;
56
61
  }
57
62
  function shouldRetryOptionalLikeCompatibilityError(error, state) {
58
- return error instanceof TypeError && state != null && typeof state === "object" && require_annotations.isInjectedAnnotationWrapper(state);
63
+ return error instanceof TypeError && state != null && typeof state === "object" && require_internal_annotations.isInjectedAnnotationWrapper(state);
59
64
  }
60
65
  function completeOptionalLikeSync(parser, state, exec) {
61
66
  const hasCarrier = require_annotation_state.hasDelegatedAnnotationCarrier(state);
@@ -156,12 +161,12 @@ function extractOptionalLikePhase2Seed(parser, state, exec) {
156
161
  function deriveOptionalInnerParseState(outerState, parser) {
157
162
  if (Array.isArray(outerState)) {
158
163
  const innerState = outerState[0];
159
- if (require_annotations.getAnnotations(outerState) != null && innerState != null && typeof innerState === "object") return require_annotation_state.getDelegatedAnnotationState(outerState, innerState);
164
+ if (require_internal_annotations.getAnnotations(outerState) != null && innerState != null && typeof innerState === "object") return require_annotation_state.getDelegatedAnnotationState(outerState, innerState);
160
165
  return innerState;
161
166
  }
162
167
  const initial = parser.initialState;
163
168
  if (initial != null && typeof initial !== "object") return initial;
164
- return initial != null && typeof initial === "object" ? require_annotation_state.getDelegatedAnnotationState(outerState, initial) : require_annotations.inheritAnnotations(outerState, initial);
169
+ return initial != null && typeof initial === "object" ? require_annotation_state.getDelegatedAnnotationState(outerState, initial) : require_internal_annotations.inheritAnnotations(outerState, initial);
165
170
  }
166
171
  /**
167
172
  * Internal helper for optional-style parsing logic shared by optional()
@@ -257,9 +262,9 @@ function adaptShouldDeferCompletion(innerCheck, parser) {
257
262
  };
258
263
  }
259
264
  function isAnnotationOnlyObjectState(state) {
260
- if (state == null || typeof state !== "object" || Array.isArray(state) || require_annotations.isInjectedAnnotationWrapper(state)) return false;
265
+ if (state == null || typeof state !== "object" || Array.isArray(state) || require_internal_annotations.isInjectedAnnotationWrapper(state)) return false;
261
266
  const keys = Reflect.ownKeys(state);
262
- return require_annotations.getAnnotations(state) != null && keys.length === 1 && keys[0] === require_annotations.annotationKey;
267
+ return require_internal_annotations.getAnnotations(state) != null && keys.length === 1 && keys[0] === require_internal_annotations.annotationKey;
263
268
  }
264
269
  function normalizeOptionalLikeInnerState(state, initialState, parser) {
265
270
  if (Array.isArray(state)) return require_annotation_state.getDelegatedAnnotationState(state, state[0]);
@@ -310,7 +315,7 @@ function optional(parser) {
310
315
  mode: parser.mode,
311
316
  $valueType: [],
312
317
  $stateType: [],
313
- ...parser[require_parser.unmatchedNonCliDependencySourceStateMarker] === true ? { [require_parser.unmatchedNonCliDependencySourceStateMarker]: true } : {},
318
+ ...parser[require_internal_parser.unmatchedNonCliDependencySourceStateMarker] === true ? { [require_internal_parser.unmatchedNonCliDependencySourceStateMarker]: true } : {},
314
319
  placeholder: void 0,
315
320
  priority: parser.priority,
316
321
  usage: [{
@@ -320,6 +325,11 @@ function optional(parser) {
320
325
  leadingNames: parser.leadingNames,
321
326
  acceptingAnyToken: false,
322
327
  initialState: void 0,
328
+ canSkip(state, exec) {
329
+ if (!Array.isArray(state)) return true;
330
+ const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
331
+ return parser.canSkip?.(innerState, exec) === true;
332
+ },
323
333
  ...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: adaptShouldDeferCompletion(parser.shouldDeferCompletion.bind(parser), parser) } : {},
324
334
  getSuggestRuntimeNodes(state, path) {
325
335
  if (optionalParser.dependencyMetadata?.source != null) return [{
@@ -358,7 +368,7 @@ function optional(parser) {
358
368
  const delegatedState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
359
369
  return require_mode_dispatch.dispatchByMode(parser.mode, () => completeOptionalLikeSync(syncParser, delegatedState, exec), async () => await completeOptionalLikeAsync(parser, delegatedState, exec));
360
370
  }
361
- if (parser[require_parser.unmatchedNonCliDependencySourceStateMarker] === true && state != null && typeof state === "object") {
371
+ if (parser[require_internal_parser.unmatchedNonCliDependencySourceStateMarker] === true && state != null && typeof state === "object") {
362
372
  const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
363
373
  return delegateToInner(innerState);
364
374
  }
@@ -410,8 +420,8 @@ function optional(parser) {
410
420
  const composed = require_dependency_metadata.composeDependencyMetadata(parser.dependencyMetadata, "optional");
411
421
  if (composed != null) optionalParser.dependencyMetadata = composed;
412
422
  }
413
- require_parser.defineInheritedAnnotationParser(optionalParser);
414
- require_parser.defineSourceBindingOnlyAnnotationCompletionParser(optionalParser);
423
+ require_internal_parser.defineInheritedAnnotationParser(optionalParser);
424
+ require_internal_parser.defineSourceBindingOnlyAnnotationCompletionParser(optionalParser);
415
425
  return optionalParser;
416
426
  }
417
427
  /**
@@ -479,7 +489,7 @@ function withDefault(parser, defaultValue, options) {
479
489
  mode: parser.mode,
480
490
  $valueType: [],
481
491
  $stateType: [],
482
- ...parser[require_parser.unmatchedNonCliDependencySourceStateMarker] === true ? { [require_parser.unmatchedNonCliDependencySourceStateMarker]: true } : {},
492
+ ...parser[require_internal_parser.unmatchedNonCliDependencySourceStateMarker] === true ? { [require_internal_parser.unmatchedNonCliDependencySourceStateMarker]: true } : {},
483
493
  priority: parser.priority,
484
494
  usage: [{
485
495
  type: "optional",
@@ -488,6 +498,11 @@ function withDefault(parser, defaultValue, options) {
488
498
  leadingNames: parser.leadingNames,
489
499
  acceptingAnyToken: false,
490
500
  initialState: void 0,
501
+ canSkip(state, exec) {
502
+ if (!Array.isArray(state)) return true;
503
+ const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
504
+ return parser.canSkip?.(innerState, exec) === true;
505
+ },
491
506
  ...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: adaptShouldDeferCompletion(parser.shouldDeferCompletion.bind(parser), parser) } : {},
492
507
  getSuggestRuntimeNodes(state, path) {
493
508
  if (withDefaultParser.dependencyMetadata?.source != null) return [{
@@ -522,7 +537,7 @@ function withDefault(parser, defaultValue, options) {
522
537
  const innerResult = require_mode_dispatch.dispatchByMode(parser.mode, () => completeOptionalLikeSync(syncParser, innerState, exec), async () => await completeOptionalLikeAsync(parser, innerState, exec));
523
538
  return innerResult;
524
539
  }
525
- if (parser[require_parser.unmatchedNonCliDependencySourceStateMarker] === true && state != null && typeof state === "object") {
540
+ if (parser[require_internal_parser.unmatchedNonCliDependencySourceStateMarker] === true && state != null && typeof state === "object") {
526
541
  const innerState = normalizeOptionalLikeInnerState(state, parser.initialState, parser);
527
542
  const innerResult = require_mode_dispatch.dispatchByMode(parser.mode, () => completeOptionalLikeSync(syncParser, innerState, exec), async () => await completeOptionalLikeAsync(parser, innerState, exec));
528
543
  const handleInnerResult = (result) => {
@@ -639,8 +654,8 @@ function withDefault(parser, defaultValue, options) {
639
654
  } });
640
655
  if (composed != null) withDefaultParser.dependencyMetadata = composed;
641
656
  }
642
- require_parser.defineInheritedAnnotationParser(withDefaultParser);
643
- require_parser.defineSourceBindingOnlyAnnotationCompletionParser(withDefaultParser);
657
+ require_internal_parser.defineInheritedAnnotationParser(withDefaultParser);
658
+ require_internal_parser.defineSourceBindingOnlyAnnotationCompletionParser(withDefaultParser);
644
659
  return withDefaultParser;
645
660
  }
646
661
  /**
@@ -848,27 +863,27 @@ function map(parser, transform) {
848
863
  function multiple(parser, options = {}) {
849
864
  const syncParser = parser;
850
865
  const { min = 0, max = Infinity } = options;
851
- const unwrapInjectedWrapper = require_annotations.unwrapInjectedAnnotationWrapper;
866
+ const unwrapInjectedWrapper = require_internal_annotations.unwrapInjectedAnnotationWrapper;
852
867
  const completeSyncWithUnwrappedFallback = (state, exec) => {
853
868
  try {
854
869
  const result = syncParser.complete(state, exec);
855
- if (!result.success && require_annotations.isInjectedAnnotationWrapper(state)) return syncParser.complete(unwrapInjectedWrapper(state), exec);
870
+ if (!result.success && require_internal_annotations.isInjectedAnnotationWrapper(state)) return syncParser.complete(unwrapInjectedWrapper(state), exec);
856
871
  return result;
857
872
  } catch (error) {
858
- if (!require_annotations.isInjectedAnnotationWrapper(state)) throw error;
873
+ if (!require_internal_annotations.isInjectedAnnotationWrapper(state)) throw error;
859
874
  return syncParser.complete(unwrapInjectedWrapper(state), exec);
860
875
  }
861
876
  };
862
877
  const parseSyncWithUnwrappedFallback = (context) => {
863
878
  try {
864
879
  const result = syncParser.parse(context);
865
- if (result.success || result.consumed !== 0 || !require_annotations.isInjectedAnnotationWrapper(context.state)) return result;
880
+ if (result.success || result.consumed !== 0 || !require_internal_annotations.isInjectedAnnotationWrapper(context.state)) return result;
866
881
  return syncParser.parse({
867
882
  ...context,
868
883
  state: unwrapInjectedWrapper(context.state)
869
884
  });
870
885
  } catch (error) {
871
- if (!require_annotations.isInjectedAnnotationWrapper(context.state)) throw error;
886
+ if (!require_internal_annotations.isInjectedAnnotationWrapper(context.state)) throw error;
872
887
  return syncParser.parse({
873
888
  ...context,
874
889
  state: unwrapInjectedWrapper(context.state)
@@ -878,23 +893,23 @@ function multiple(parser, options = {}) {
878
893
  const completeAsyncWithUnwrappedFallback = async (state, exec) => {
879
894
  try {
880
895
  const result = await parser.complete(state, exec);
881
- if (!result.success && require_annotations.isInjectedAnnotationWrapper(state)) return await parser.complete(unwrapInjectedWrapper(state), exec);
896
+ if (!result.success && require_internal_annotations.isInjectedAnnotationWrapper(state)) return await parser.complete(unwrapInjectedWrapper(state), exec);
882
897
  return result;
883
898
  } catch (error) {
884
- if (!require_annotations.isInjectedAnnotationWrapper(state)) throw error;
899
+ if (!require_internal_annotations.isInjectedAnnotationWrapper(state)) throw error;
885
900
  return await parser.complete(unwrapInjectedWrapper(state), exec);
886
901
  }
887
902
  };
888
903
  const parseAsyncWithUnwrappedFallback = async (context) => {
889
904
  try {
890
905
  const result = await parser.parse(context);
891
- if (result.success || result.consumed !== 0 || !require_annotations.isInjectedAnnotationWrapper(context.state)) return result;
906
+ if (result.success || result.consumed !== 0 || !require_internal_annotations.isInjectedAnnotationWrapper(context.state)) return result;
892
907
  return await parser.parse({
893
908
  ...context,
894
909
  state: unwrapInjectedWrapper(context.state)
895
910
  });
896
911
  } catch (error) {
897
- if (!require_annotations.isInjectedAnnotationWrapper(context.state)) throw error;
912
+ if (!require_internal_annotations.isInjectedAnnotationWrapper(context.state)) throw error;
898
913
  return await parser.parse({
899
914
  ...context,
900
915
  state: unwrapInjectedWrapper(context.state)
@@ -904,20 +919,20 @@ function multiple(parser, options = {}) {
904
919
  const extractPhase2SeedSyncWithUnwrappedFallback = (state, exec) => {
905
920
  try {
906
921
  const seed = require_phase2_seed.completeOrExtractPhase2Seed(syncParser, state, exec);
907
- if (seed == null && require_annotations.isInjectedAnnotationWrapper(state)) return require_phase2_seed.completeOrExtractPhase2Seed(syncParser, unwrapInjectedWrapper(state), exec);
922
+ if (seed == null && require_internal_annotations.isInjectedAnnotationWrapper(state)) return require_phase2_seed.completeOrExtractPhase2Seed(syncParser, unwrapInjectedWrapper(state), exec);
908
923
  return seed;
909
924
  } catch (error) {
910
- if (!require_annotations.isInjectedAnnotationWrapper(state)) throw error;
925
+ if (!require_internal_annotations.isInjectedAnnotationWrapper(state)) throw error;
911
926
  return require_phase2_seed.completeOrExtractPhase2Seed(syncParser, unwrapInjectedWrapper(state), exec);
912
927
  }
913
928
  };
914
929
  const extractPhase2SeedAsyncWithUnwrappedFallback = async (state, exec) => {
915
930
  try {
916
931
  const seed = await require_phase2_seed.completeOrExtractPhase2Seed(parser, state, exec);
917
- if (seed == null && require_annotations.isInjectedAnnotationWrapper(state)) return await require_phase2_seed.completeOrExtractPhase2Seed(parser, unwrapInjectedWrapper(state), exec);
932
+ if (seed == null && require_internal_annotations.isInjectedAnnotationWrapper(state)) return await require_phase2_seed.completeOrExtractPhase2Seed(parser, unwrapInjectedWrapper(state), exec);
918
933
  return seed;
919
934
  } catch (error) {
920
- if (!require_annotations.isInjectedAnnotationWrapper(state)) throw error;
935
+ if (!require_internal_annotations.isInjectedAnnotationWrapper(state)) throw error;
921
936
  return await require_phase2_seed.completeOrExtractPhase2Seed(parser, unwrapInjectedWrapper(state), exec);
922
937
  }
923
938
  };
@@ -926,9 +941,11 @@ function multiple(parser, options = {}) {
926
941
  parser,
927
942
  state
928
943
  }] : []);
944
+ const canExtendMultipleItem = (state, itemIndex, exec) => state != null && !isTerminalMultipleItemState(state) && (isMatchedCommandParserState(parser, state) || parser.canSkip?.(state, require_execution_context.withChildExecPath(exec, itemIndex)) !== true);
929
945
  const parseSync = (context) => {
930
946
  const currentItemState = context.state.at(-1);
931
- const canExtendCurrent = currentItemState != null && !isTerminalMultipleItemState(currentItemState);
947
+ const currentItemIndex = context.state.length - 1;
948
+ const canExtendCurrent = canExtendMultipleItem(currentItemState, currentItemIndex, context.exec);
932
949
  const canOpenFreshItem = context.state.length < max;
933
950
  if (!canExtendCurrent && !canOpenFreshItem) return {
934
951
  success: true,
@@ -937,12 +954,12 @@ function multiple(parser, options = {}) {
937
954
  };
938
955
  let added = !canExtendCurrent;
939
956
  let itemIndex = canExtendCurrent ? context.state.length - 1 : context.state.length;
940
- const currentItemStateWithAnnotations = canExtendCurrent ? currentItemState : require_annotations.inheritAnnotations(context.state, syncParser.initialState);
957
+ const currentItemStateWithAnnotations = canExtendCurrent ? currentItemState : require_internal_annotations.inheritAnnotations(context.state, syncParser.initialState);
941
958
  let result = parseSyncWithUnwrappedFallback(require_execution_context.withChildContext(context, itemIndex, currentItemStateWithAnnotations));
942
959
  if (!result.success) {
943
960
  if (result.consumed !== 0) return result;
944
961
  if (!added && canOpenFreshItem) {
945
- const nextInitialState = require_annotations.inheritAnnotations(context.state, syncParser.initialState);
962
+ const nextInitialState = require_internal_annotations.inheritAnnotations(context.state, syncParser.initialState);
946
963
  itemIndex = context.state.length;
947
964
  result = parseSyncWithUnwrappedFallback(require_execution_context.withChildContext(context, itemIndex, nextInitialState));
948
965
  if (!result.success) {
@@ -990,13 +1007,13 @@ function multiple(parser, options = {}) {
990
1007
  },
991
1008
  consumed: result.consumed
992
1009
  };
993
- const nextItemState = require_annotations.inheritAnnotations(itemAnnotationSource, result.next.state);
1010
+ const nextItemState = require_internal_annotations.inheritAnnotations(itemAnnotationSource, result.next.state);
994
1011
  return {
995
1012
  success: true,
996
1013
  ...result.provisional ? { provisional: true } : {},
997
1014
  next: {
998
1015
  ...result.next,
999
- state: require_annotations.annotateFreshArray(context.state, [...added ? context.state : context.state.slice(0, -1), nextItemState]),
1016
+ state: require_internal_annotations.annotateFreshArray(context.state, [...added ? context.state : context.state.slice(0, -1), nextItemState]),
1000
1017
  ...mergedExec != null ? {
1001
1018
  trace: mergedExec.trace,
1002
1019
  exec: mergedExec,
@@ -1008,7 +1025,8 @@ function multiple(parser, options = {}) {
1008
1025
  };
1009
1026
  const parseAsync = async (context) => {
1010
1027
  const currentItemState = context.state.at(-1);
1011
- const canExtendCurrent = currentItemState != null && !isTerminalMultipleItemState(currentItemState);
1028
+ const currentItemIndex = context.state.length - 1;
1029
+ const canExtendCurrent = canExtendMultipleItem(currentItemState, currentItemIndex, context.exec);
1012
1030
  const canOpenFreshItem = context.state.length < max;
1013
1031
  if (!canExtendCurrent && !canOpenFreshItem) return {
1014
1032
  success: true,
@@ -1017,12 +1035,12 @@ function multiple(parser, options = {}) {
1017
1035
  };
1018
1036
  let added = !canExtendCurrent;
1019
1037
  let itemIndex = canExtendCurrent ? context.state.length - 1 : context.state.length;
1020
- const currentItemStateWithAnnotations = canExtendCurrent ? currentItemState : require_annotations.inheritAnnotations(context.state, parser.initialState);
1038
+ const currentItemStateWithAnnotations = canExtendCurrent ? currentItemState : require_internal_annotations.inheritAnnotations(context.state, parser.initialState);
1021
1039
  let result = await parseAsyncWithUnwrappedFallback(require_execution_context.withChildContext(context, itemIndex, currentItemStateWithAnnotations));
1022
1040
  if (!result.success) {
1023
1041
  if (result.consumed !== 0) return result;
1024
1042
  if (!added && canOpenFreshItem) {
1025
- const nextInitialState = require_annotations.inheritAnnotations(context.state, parser.initialState);
1043
+ const nextInitialState = require_internal_annotations.inheritAnnotations(context.state, parser.initialState);
1026
1044
  itemIndex = context.state.length;
1027
1045
  result = await parseAsyncWithUnwrappedFallback(require_execution_context.withChildContext(context, itemIndex, nextInitialState));
1028
1046
  if (!result.success) {
@@ -1070,13 +1088,13 @@ function multiple(parser, options = {}) {
1070
1088
  },
1071
1089
  consumed: result.consumed
1072
1090
  };
1073
- const nextItemState = require_annotations.inheritAnnotations(itemAnnotationSource, result.next.state);
1091
+ const nextItemState = require_internal_annotations.inheritAnnotations(itemAnnotationSource, result.next.state);
1074
1092
  return {
1075
1093
  success: true,
1076
1094
  ...result.provisional ? { provisional: true } : {},
1077
1095
  next: {
1078
1096
  ...result.next,
1079
- state: require_annotations.annotateFreshArray(context.state, [...added ? context.state : context.state.slice(0, -1), nextItemState]),
1097
+ state: require_internal_annotations.annotateFreshArray(context.state, [...added ? context.state : context.state.slice(0, -1), nextItemState]),
1080
1098
  ...mergedExec != null ? {
1081
1099
  trace: mergedExec.trace,
1082
1100
  exec: mergedExec,
@@ -1099,6 +1117,11 @@ function multiple(parser, options = {}) {
1099
1117
  leadingNames: parser.leadingNames,
1100
1118
  acceptingAnyToken: min > 0 && (parser.acceptingAnyToken ?? false),
1101
1119
  initialState: [],
1120
+ canSkip(state, exec) {
1121
+ if (state.length < min) return false;
1122
+ const currentItemState = state.at(-1);
1123
+ return !canExtendMultipleItem(currentItemState, state.length - 1, exec);
1124
+ },
1102
1125
  getSuggestRuntimeNodes(state, path) {
1103
1126
  const innerNodes = state.flatMap((item, i) => [...getInnerSuggestRuntimeNodes(item, [...path, i])]);
1104
1127
  return resultParser.dependencyMetadata?.source != null ? [{
@@ -1198,11 +1221,12 @@ function multiple(parser, options = {}) {
1198
1221
  },
1199
1222
  suggest(context, prefix) {
1200
1223
  const currentItemState = context.state.at(-1);
1201
- const canExtendCurrent = currentItemState != null && !isTerminalMultipleItemState(currentItemState);
1224
+ const currentItemIndex = context.state.length - 1;
1225
+ const canExtendCurrent = canExtendMultipleItem(currentItemState, currentItemIndex, context.exec);
1202
1226
  const canOpenNew = context.state.length < max;
1203
1227
  if (!canExtendCurrent && !canOpenNew) return require_mode_dispatch.dispatchIterableByMode(parser.mode, function* () {}, async function* () {});
1204
1228
  const itemIndex = canExtendCurrent ? context.state.length - 1 : context.state.length;
1205
- const suggestInitialState = canExtendCurrent ? currentItemState : require_annotations.inheritAnnotations(context.state, parser.initialState);
1229
+ const suggestInitialState = canExtendCurrent ? currentItemState : require_internal_annotations.inheritAnnotations(context.state, parser.initialState);
1206
1230
  const suggestFallbackState = unwrapInjectedWrapper(suggestInitialState);
1207
1231
  const hasSuggestFallbackState = suggestFallbackState !== suggestInitialState;
1208
1232
  const collectSelectedValuesSync = () => {
@@ -1287,7 +1311,7 @@ function multiple(parser, options = {}) {
1287
1311
  },
1288
1312
  getDocFragments(state, defaultValue) {
1289
1313
  const latestState = state.kind === "available" && state.state.length > 0 ? state.state.at(-1) : void 0;
1290
- const latestInnerState = latestState != null && require_annotations.isInjectedAnnotationWrapper(latestState) ? unwrapInjectedWrapper(latestState) : latestState;
1314
+ const latestInnerState = latestState != null && require_internal_annotations.isInjectedAnnotationWrapper(latestState) ? unwrapInjectedWrapper(latestState) : latestState;
1291
1315
  const innerState = state.kind === "unavailable" ? { kind: "unavailable" } : latestInnerState !== void 0 ? {
1292
1316
  kind: "available",
1293
1317
  state: latestInnerState
@@ -1484,6 +1508,7 @@ function multiple(parser, options = {}) {
1484
1508
  */
1485
1509
  function nonEmpty(parser) {
1486
1510
  const syncParser = parser;
1511
+ const initialState = parser.initialState;
1487
1512
  const processNonEmptyResult = (result) => {
1488
1513
  if (!result.success) return result;
1489
1514
  if (result.consumed.length === 0) return {
@@ -1509,7 +1534,12 @@ function nonEmpty(parser) {
1509
1534
  usage: parser.usage,
1510
1535
  leadingNames: parser.leadingNames,
1511
1536
  acceptingAnyToken: parser.acceptingAnyToken,
1512
- initialState: parser.initialState,
1537
+ initialState,
1538
+ ...typeof parser.canSkip === "function" ? { canSkip(state, exec) {
1539
+ const unwrappedState = require_internal_annotations.unwrapInjectedAnnotationWrapper(state);
1540
+ if (unwrappedState === initialState) return false;
1541
+ return parser.canSkip?.(unwrappedState, exec) === true;
1542
+ } } : {},
1513
1543
  ...typeof parser.shouldDeferCompletion === "function" ? { shouldDeferCompletion: parser.shouldDeferCompletion.bind(parser) } : {},
1514
1544
  getSuggestRuntimeNodes(state, path) {
1515
1545
  return parser.getSuggestRuntimeNodes?.(state, path) ?? (parser.dependencyMetadata?.source != null ? [{