@optique/core 1.4.0-dev.2636 → 1.4.0-dev.2661

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.
@@ -11,6 +11,7 @@ import { annotationViewTargets, getWrappedChildParseState, getWrappedChildState,
11
11
  import { mergeChildExec, withChildContext, withChildExecPath } from "./execution-context.js";
12
12
  import { collectLeadingCandidates } from "./usage-internals.js";
13
13
  import { adoptOptionScope, combinedOptionScope, conditionalOptionScope, forkOptionScope, restoreOptionScope, scopeParser, selectableOptionScope, withOptionScope, withParserOptionScope } from "./short-option.js";
14
+ import { combineOptionMatches, combinePassThroughPriorities, defineOptionMatch, definePassThroughPriority, delegateKnownCompletion, getKnownCompletion, getOptionMatch, getPassThroughFailureHint, getPassThroughPriority, hasPassThroughUsage, matchesOptionToken, retainConsumingFailure, retainConsumingFailureHint, withPassThroughFailure } from "./internal/passthrough.js";
14
15
  import { allowDuplicateLeadingCommandNamesKey } from "./internal/command-alias.js";
15
16
  import { completeOrExtractPhase2Seed, extractPhase2Seed, extractPhase2SeedKey, phase2SeedFromValueResult } from "./phase2-seed.js";
16
17
  import { fluent } from "./modifiers.js";
@@ -605,6 +606,63 @@ function sharedBufferLeadingNames(parsers) {
605
606
  return names.size === 0 ? EMPTY_LEADING_NAMES : names;
606
607
  }
607
608
  /**
609
+ * Defers capture until a known option at an equal or higher lane priority
610
+ * has been tried.
611
+ * Other siblings retain their relative order, and explicit priorities win.
612
+ */
613
+ function orderBeforePassThrough(pairs, context, getParser, getState, passThroughParsers) {
614
+ const token = context.buffer[0];
615
+ if (passThroughParsers.size === 0 || context.optionsTerminated || token == null || token === "--" || !/^[-/+]/.test(token)) return pairs;
616
+ const matches = new Map(pairs.map((pair) => [pair, getOptionMatch(getParser(pair), getState(pair), token)]));
617
+ const normalizedOptions = /* @__PURE__ */ new Map();
618
+ const captures = new Map(pairs.flatMap((pair) => {
619
+ if (!passThroughParsers.has(getParser(pair))) return [];
620
+ const priority = getPassThroughPriority(getParser(pair), getState(pair), token);
621
+ const match = matches.get(pair);
622
+ if (match != null && (priority == null || match.priority >= priority)) {
623
+ const unfiltered = getPassThroughPriority(getParser(pair), getState(pair));
624
+ if (priority == null || unfiltered != null && unfiltered > match.priority) normalizedOptions.set(pair, match.priority);
625
+ return [];
626
+ }
627
+ return priority == null ? [] : [[pair, priority]];
628
+ }));
629
+ const matching = pairs.filter((pair) => !captures.has(pair)).flatMap((pair) => {
630
+ const match = matches.get(pair);
631
+ return match == null ? [] : [match];
632
+ });
633
+ const orderedCaptures = [...captures].sort((a, b) => b[1] - a[1]);
634
+ if (matching.length === 0) {
635
+ let captureIndex = 0;
636
+ return pairs.map((pair) => captures.has(pair) ? orderedCaptures[captureIndex++][0] : pair);
637
+ }
638
+ const matchingPriority = Math.max(...matching.map((match) => match.priority));
639
+ const ordinary = pairs.filter((pair) => !captures.has(pair) && !normalizedOptions.has(pair));
640
+ const positions = new Map(pairs.map((pair, index) => [pair, index]));
641
+ for (const [pair, priority] of [...normalizedOptions].sort((a, b) => b[1] - a[1])) {
642
+ let insertion = ordinary.findIndex((candidate) => {
643
+ const match = matches.get(candidate);
644
+ return match != null && (match.priority < priority || match.priority === priority && positions.get(pair) < positions.get(candidate));
645
+ });
646
+ if (insertion < 0) {
647
+ const lastMatch = ordinary.findLastIndex((candidate) => matches.get(candidate) != null);
648
+ insertion = lastMatch >= 0 ? lastMatch + 1 : ordinary.findIndex((candidate) => positions.get(candidate) > positions.get(pair));
649
+ if (insertion < 0) insertion = ordinary.length;
650
+ }
651
+ ordinary.splice(insertion, 0, pair);
652
+ }
653
+ const first = ordinary.findIndex((pair) => matches.get(pair) != null);
654
+ const last = ordinary.findLastIndex((pair) => matches.get(pair) != null);
655
+ const before = orderedCaptures.filter(([, priority]) => priority > matchingPriority).map(([pair]) => pair);
656
+ const after = orderedCaptures.filter(([, priority]) => priority <= matchingPriority).map(([pair]) => pair);
657
+ return [
658
+ ...ordinary.slice(0, first),
659
+ ...before,
660
+ ...ordinary.slice(first, last + 1),
661
+ ...after,
662
+ ...ordinary.slice(last + 1)
663
+ ];
664
+ }
665
+ /**
608
666
  * Internal symbol for exposing field-level parser pairs from `object()`
609
667
  * and `merge()` parsers. This allows `merge()` to pre-complete dependency
610
668
  * source fields from child parsers before resolving deferred states.
@@ -1114,6 +1172,7 @@ function preserveExclusiveStateAfterOptionsTerminator(context, result) {
1114
1172
  success: true,
1115
1173
  next: {
1116
1174
  ...context,
1175
+ ...getPassThroughFailureHint(result.next),
1117
1176
  buffer: result.next.buffer,
1118
1177
  optionsTerminated: true,
1119
1178
  state: context.state,
@@ -1448,6 +1507,7 @@ function or(...args) {
1448
1507
  success: true,
1449
1508
  next: {
1450
1509
  ...adoptOptionScope(context, result.next),
1510
+ ...getPassThroughFailureHint(result.next),
1451
1511
  buffer: result.next.buffer,
1452
1512
  optionsTerminated: result.next.optionsTerminated,
1453
1513
  state: createExclusiveState(context.state, i, parser, result),
@@ -1484,6 +1544,7 @@ function or(...args) {
1484
1544
  success: true,
1485
1545
  next: {
1486
1546
  ...adoptOptionScope(context, replayedResult.next),
1547
+ ...getPassThroughFailureHint(replayedResult.next),
1487
1548
  buffer: replayedResult.next.buffer,
1488
1549
  optionsTerminated: replayedResult.next.optionsTerminated,
1489
1550
  state: createExclusiveState(context.state, i, parser, {
@@ -1503,6 +1564,7 @@ function or(...args) {
1503
1564
  success: true,
1504
1565
  next: {
1505
1566
  ...adoptOptionScope(context, result.next),
1567
+ ...getPassThroughFailureHint(result.next),
1506
1568
  buffer: result.next.buffer,
1507
1569
  optionsTerminated: result.next.optionsTerminated,
1508
1570
  state: createExclusiveState(context.state, i, parser, result),
@@ -1547,6 +1609,7 @@ function or(...args) {
1547
1609
  provisional: true,
1548
1610
  next: {
1549
1611
  ...adoptOptionScope(context, provisionalConsuming.result.next),
1612
+ ...getPassThroughFailureHint(provisionalConsuming.result.next),
1550
1613
  buffer: provisionalConsuming.result.next.buffer,
1551
1614
  optionsTerminated: provisionalConsuming.result.next.optionsTerminated,
1552
1615
  state: createExclusiveState(context.state, provisionalConsuming.index, provisionalConsuming.parser, provisionalConsuming.result),
@@ -1581,6 +1644,7 @@ function or(...args) {
1581
1644
  provisional: true,
1582
1645
  next: {
1583
1646
  ...adoptOptionScope(context, replayedResult.next),
1647
+ ...getPassThroughFailureHint(replayedResult.next),
1584
1648
  buffer: replayedResult.next.buffer,
1585
1649
  optionsTerminated: replayedResult.next.optionsTerminated,
1586
1650
  state: createExclusiveState(context.state, provisionalConsuming.index, provisionalConsuming.parser, {
@@ -1652,6 +1716,7 @@ function or(...args) {
1652
1716
  success: true,
1653
1717
  next: {
1654
1718
  ...adoptOptionScope(context, result.next),
1719
+ ...getPassThroughFailureHint(result.next),
1655
1720
  buffer: result.next.buffer,
1656
1721
  optionsTerminated: result.next.optionsTerminated,
1657
1722
  state: createExclusiveState(context.state, i, parser, result),
@@ -1690,6 +1755,7 @@ function or(...args) {
1690
1755
  success: true,
1691
1756
  next: {
1692
1757
  ...adoptOptionScope(context, replayedResult.next),
1758
+ ...getPassThroughFailureHint(replayedResult.next),
1693
1759
  buffer: replayedResult.next.buffer,
1694
1760
  optionsTerminated: replayedResult.next.optionsTerminated,
1695
1761
  state: createExclusiveState(context.state, i, parser, {
@@ -1709,6 +1775,7 @@ function or(...args) {
1709
1775
  success: true,
1710
1776
  next: {
1711
1777
  ...adoptOptionScope(context, result.next),
1778
+ ...getPassThroughFailureHint(result.next),
1712
1779
  buffer: result.next.buffer,
1713
1780
  optionsTerminated: result.next.optionsTerminated,
1714
1781
  state: createExclusiveState(context.state, i, parser, result),
@@ -1753,6 +1820,7 @@ function or(...args) {
1753
1820
  provisional: true,
1754
1821
  next: {
1755
1822
  ...adoptOptionScope(context, provisionalConsuming.result.next),
1823
+ ...getPassThroughFailureHint(provisionalConsuming.result.next),
1756
1824
  buffer: provisionalConsuming.result.next.buffer,
1757
1825
  optionsTerminated: provisionalConsuming.result.next.optionsTerminated,
1758
1826
  state: createExclusiveState(context.state, provisionalConsuming.index, provisionalConsuming.parser, provisionalConsuming.result),
@@ -1787,6 +1855,7 @@ function or(...args) {
1787
1855
  provisional: true,
1788
1856
  next: {
1789
1857
  ...adoptOptionScope(context, replayedResult.next),
1858
+ ...getPassThroughFailureHint(replayedResult.next),
1790
1859
  buffer: replayedResult.next.buffer,
1791
1860
  optionsTerminated: replayedResult.next.optionsTerminated,
1792
1861
  state: createExclusiveState(context.state, provisionalConsuming.index, provisionalConsuming.parser, {
@@ -1879,6 +1948,14 @@ function or(...args) {
1879
1948
  if (singleDependencyMetadata != null) singleResult.dependencyMetadata = singleDependencyMetadata;
1880
1949
  defineExclusiveSchedulingNodes(singleResult, parsers);
1881
1950
  defineInheritedAnnotationParser(singleResult);
1951
+ defineOptionMatch(singleResult, (state, token) => combineOptionMatches(parsers.map((parser, index) => {
1952
+ const active = normalizeExclusiveState(state);
1953
+ return getOptionMatch(parser, active?.[0] === index && active[1].success ? active[1].next.state : parser.initialState, token);
1954
+ })));
1955
+ definePassThroughPriority(singleResult, parsers, (state, token) => {
1956
+ const active = normalizeExclusiveState(state);
1957
+ return combinePassThroughPriorities(parsers.map((parser, index) => getPassThroughPriority(parser, active?.[0] === index && active[1].success ? active[1].next.state : parser.initialState, token)));
1958
+ });
1882
1959
  return fluent(scopeParser(singleResult, combinedOptionScope(parsers, parsers.map((_, index) => index))));
1883
1960
  }
1884
1961
  /**
@@ -1913,24 +1990,27 @@ function createLongestMatch(...args) {
1913
1990
  return createUnexpectedInputErrorWithScopedSuggestions(defaultMsg, token, parsers, options?.errors?.suggestions);
1914
1991
  })()
1915
1992
  });
1916
- const commitLongestMatch = (context, match, optionsTerminatorResult) => {
1993
+ const commitLongestMatch = (context, match, optionsTerminatorResult, consumingFailure) => {
1917
1994
  const selectedResult = optionsTerminatorResult == null ? match.result : {
1918
1995
  ...match.result,
1919
1996
  next: {
1920
1997
  ...match.result.next,
1998
+ ...getPassThroughFailureHint(optionsTerminatorResult.next),
1921
1999
  buffer: optionsTerminatorResult.next.buffer,
1922
2000
  optionsTerminated: true
1923
2001
  },
1924
2002
  consumed: [...optionsTerminatorResult.consumed, ...match.result.consumed]
1925
2003
  };
2004
+ const next = selectedResult.consumed.length === 0 ? withPassThroughFailure(selectedResult.next, consumingFailure) : selectedResult.next;
1926
2005
  const parser = parsers[match.index];
1927
- const mergedExec = mergeChildExec(context.exec, selectedResult.next.exec);
2006
+ const mergedExec = mergeChildExec(context.exec, next.exec);
1928
2007
  return {
1929
2008
  success: true,
1930
2009
  next: {
1931
- ...adoptOptionScope(context, selectedResult.next),
1932
- buffer: selectedResult.next.buffer,
1933
- optionsTerminated: selectedResult.next.optionsTerminated,
2010
+ ...adoptOptionScope(context, next),
2011
+ ...getPassThroughFailureHint(next),
2012
+ buffer: next.buffer,
2013
+ optionsTerminated: next.optionsTerminated,
1934
2014
  state: createExclusiveState(context.state, match.index, parser, selectedResult),
1935
2015
  ...mergedExec != null ? {
1936
2016
  exec: mergedExec,
@@ -1965,6 +2045,7 @@ function createLongestMatch(...args) {
1965
2045
  let bestMatch = null;
1966
2046
  const optionsTerminatorMatches = [];
1967
2047
  let error = getInitialError(context);
2048
+ let consumingFailure;
1968
2049
  const activeState = normalizeExclusiveState(context.state);
1969
2050
  for (let i = 0; i < syncParsers.length; i++) {
1970
2051
  const parser = syncParsers[i];
@@ -1980,6 +2061,7 @@ function createLongestMatch(...args) {
1980
2061
  continue;
1981
2062
  }
1982
2063
  if (result.success) {
2064
+ consumingFailure = retainConsumingFailureHint(consumingFailure, context, result.next);
1983
2065
  const consumed = context.buffer.length - result.next.buffer.length;
1984
2066
  const bestIsProvisional = bestMatch != null && bestMatch.result.success && !!bestMatch.result.provisional;
1985
2067
  if (bestMatch === null || consumed > bestMatch.consumed || consumed === bestMatch.consumed && bestIsProvisional && !result.provisional) bestMatch = {
@@ -1987,11 +2069,15 @@ function createLongestMatch(...args) {
1987
2069
  result,
1988
2070
  consumed
1989
2071
  };
1990
- } else if (error.consumed < result.consumed) error = result;
2072
+ } else {
2073
+ const match = getOptionMatch(parser, childContext.state, context.buffer[0]);
2074
+ if (result.consumed > 0 && match != null) consumingFailure = retainConsumingFailure(consumingFailure, result, match.priority);
2075
+ if (error.consumed < result.consumed) error = result;
2076
+ }
1991
2077
  }
1992
2078
  const optionsTerminatorResolution = resolveLongestMatchOptionsTerminator(context, bestMatch, optionsTerminatorMatches);
1993
2079
  if (optionsTerminatorResolution != null) return optionsTerminatorResolution;
1994
- if (bestMatch != null) return commitLongestMatch(context, bestMatch);
2080
+ if (bestMatch != null) return commitLongestMatch(context, bestMatch, void 0, consumingFailure);
1995
2081
  return {
1996
2082
  ...error,
1997
2083
  success: false
@@ -2001,6 +2087,7 @@ function createLongestMatch(...args) {
2001
2087
  let bestMatch = null;
2002
2088
  const optionsTerminatorMatches = [];
2003
2089
  let error = getInitialError(context);
2090
+ let consumingFailure;
2004
2091
  const activeState = normalizeExclusiveState(context.state);
2005
2092
  for (let i = 0; i < parsers.length; i++) {
2006
2093
  const parser = parsers[i];
@@ -2017,6 +2104,7 @@ function createLongestMatch(...args) {
2017
2104
  continue;
2018
2105
  }
2019
2106
  if (result.success) {
2107
+ consumingFailure = retainConsumingFailureHint(consumingFailure, context, result.next);
2020
2108
  const consumed = context.buffer.length - result.next.buffer.length;
2021
2109
  const bestIsProvisional = bestMatch != null && bestMatch.result.success && !!bestMatch.result.provisional;
2022
2110
  if (bestMatch === null || consumed > bestMatch.consumed || consumed === bestMatch.consumed && bestIsProvisional && !result.provisional) bestMatch = {
@@ -2024,11 +2112,15 @@ function createLongestMatch(...args) {
2024
2112
  result,
2025
2113
  consumed
2026
2114
  };
2027
- } else if (error.consumed < result.consumed) error = result;
2115
+ } else {
2116
+ const match = getOptionMatch(parser, childContext.state, context.buffer[0]);
2117
+ if (result.consumed > 0 && match != null) consumingFailure = retainConsumingFailure(consumingFailure, result, match.priority);
2118
+ if (error.consumed < result.consumed) error = result;
2119
+ }
2028
2120
  }
2029
2121
  const optionsTerminatorResolution = resolveLongestMatchOptionsTerminator(context, bestMatch, optionsTerminatorMatches);
2030
2122
  if (optionsTerminatorResolution != null) return optionsTerminatorResolution;
2031
- if (bestMatch != null) return commitLongestMatch(context, bestMatch);
2123
+ if (bestMatch != null) return commitLongestMatch(context, bestMatch, void 0, consumingFailure);
2032
2124
  return {
2033
2125
  ...error,
2034
2126
  success: false
@@ -2101,6 +2193,14 @@ function createLongestMatch(...args) {
2101
2193
  if (multiDependencyMetadata != null) multiResult.dependencyMetadata = multiDependencyMetadata;
2102
2194
  defineExclusiveSchedulingNodes(multiResult, parsers);
2103
2195
  defineInheritedAnnotationParser(multiResult);
2196
+ defineOptionMatch(multiResult, (state, token) => combineOptionMatches(parsers.map((parser, index) => {
2197
+ const active = normalizeExclusiveState(state);
2198
+ return getOptionMatch(parser, active?.[0] === index && active[1].success ? active[1].next.state : parser.initialState, token);
2199
+ })));
2200
+ definePassThroughPriority(multiResult, parsers, (state, token) => {
2201
+ const active = normalizeExclusiveState(state);
2202
+ return combinePassThroughPriorities(parsers.map((parser, index) => getPassThroughPriority(parser, active?.[0] === index && active[1].success ? active[1].next.state : parser.initialState, token)));
2203
+ });
2104
2204
  return fluent(scopeParser(multiResult, combinedOptionScope(parsers, parsers.map((_, index) => index))));
2105
2205
  }
2106
2206
  /**
@@ -2504,6 +2604,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2504
2604
  const parserKeys = Reflect.ownKeys(parsers);
2505
2605
  const parserPairs = parserKeys.map((k) => [k, parsers[k]]);
2506
2606
  parserPairs.sort(([_, parserA], [__, parserB]) => parserB.priority - parserA.priority);
2607
+ const passThroughParsers = new Set(parserPairs.map(([, parser]) => parser).filter((parser) => hasPassThroughUsage(parser.usage)));
2507
2608
  const createInitialState = () => {
2508
2609
  const state = {};
2509
2610
  for (const key of parserKeys) state[key] = parsers[key].initialState;
@@ -2554,6 +2655,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2554
2655
  success: true,
2555
2656
  next: {
2556
2657
  ...context,
2658
+ ...getPassThroughFailureHint(result.next),
2557
2659
  buffer: result.next.buffer,
2558
2660
  optionsTerminated: result.next.optionsTerminated,
2559
2661
  state: nextState,
@@ -2590,17 +2692,20 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2590
2692
  let anySuccess = false;
2591
2693
  const allConsumed = [];
2592
2694
  const consumedFields = /* @__PURE__ */ new Set();
2695
+ let consumingFailure;
2593
2696
  let madeProgress = true;
2594
2697
  while (madeProgress && currentContext.buffer.length > 0) {
2595
2698
  madeProgress = false;
2699
+ consumingFailure = void 0;
2596
2700
  const getFieldState = createFieldStateGetter(currentContext.state, getObjectParseChildState);
2597
- for (const [field, parser] of parserPairs) {
2598
- const result = parser.parse(withChildContext$1(forkOptionScope(currentContext), field, getFieldState(field, parser), parser));
2701
+ for (const [field, parser] of orderBeforePassThrough(parserPairs, currentContext, ([, parser$1]) => parser$1, ([field$1, parser$1]) => getFieldState(field$1, parser$1), passThroughParsers)) {
2702
+ const result = parser.parse(withPassThroughFailure(withChildContext$1(forkOptionScope(currentContext), field, getFieldState(field, parser), parser), consumingFailure, getPassThroughPriority(parser, getFieldState(field, parser), currentContext.buffer[0])));
2599
2703
  if (result.success && result.consumed.length > 0) {
2600
2704
  adoptOptionScope(currentContext, result.next);
2601
2705
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
2602
2706
  currentContext = {
2603
2707
  ...currentContext,
2708
+ ...getPassThroughFailureHint(result.next),
2604
2709
  buffer: result.next.buffer,
2605
2710
  optionsTerminated: result.next.optionsTerminated,
2606
2711
  state: {
@@ -2618,7 +2723,12 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2618
2723
  madeProgress = true;
2619
2724
  consumedFields.add(field);
2620
2725
  break;
2621
- } else if (!result.success && error.consumed < result.consumed) error = result;
2726
+ } else if (result.success) consumingFailure = retainConsumingFailureHint(consumingFailure, currentContext, result.next);
2727
+ else {
2728
+ const match = getOptionMatch(parser, getFieldState(field, parser), currentContext.buffer[0]);
2729
+ if (result.consumed > 0 && match != null) consumingFailure = retainConsumingFailure(consumingFailure, result, match.priority);
2730
+ if (error.consumed < result.consumed) error = result;
2731
+ }
2622
2732
  }
2623
2733
  }
2624
2734
  {
@@ -2628,7 +2738,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2628
2738
  const typedParser = parser;
2629
2739
  if (parser.leadingNames.size > 0 || typedParser.acceptingAnyToken) continue;
2630
2740
  const fieldState = getFieldState(field, parser);
2631
- const result = typedParser.parse(withChildContext$1(forkOptionScope(currentContext), field, fieldState, parser));
2741
+ const result = typedParser.parse(withPassThroughFailure(withChildContext$1(forkOptionScope(currentContext), field, fieldState, parser), consumingFailure, getPassThroughPriority(parser, getFieldState(field, parser), currentContext.buffer[0])));
2632
2742
  if (result.success && result.consumed.length === 0 && result.next.state !== fieldState) {
2633
2743
  adoptOptionScope(currentContext, result.next);
2634
2744
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
@@ -2649,7 +2759,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2649
2759
  }
2650
2760
  if (anySuccess) return {
2651
2761
  success: true,
2652
- next: currentContext,
2762
+ next: withPassThroughFailure(currentContext, consumingFailure),
2653
2763
  consumed: allConsumed
2654
2764
  };
2655
2765
  if (currentContext.buffer.length === 0) {
@@ -2698,18 +2808,21 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2698
2808
  let anySuccess = false;
2699
2809
  const allConsumed = [];
2700
2810
  const consumedFields = /* @__PURE__ */ new Set();
2811
+ let consumingFailure;
2701
2812
  let madeProgress = true;
2702
2813
  while (madeProgress && currentContext.buffer.length > 0) {
2703
2814
  madeProgress = false;
2815
+ consumingFailure = void 0;
2704
2816
  const getFieldState = createFieldStateGetter(currentContext.state, getObjectParseChildState);
2705
- for (const [field, parser] of parserPairs) {
2706
- const resultOrPromise = parser.parse(withChildContext$1(forkOptionScope(currentContext), field, getFieldState(field, parser), parser));
2817
+ for (const [field, parser] of orderBeforePassThrough(parserPairs, currentContext, ([, parser$1]) => parser$1, ([field$1, parser$1]) => getFieldState(field$1, parser$1), passThroughParsers)) {
2818
+ const resultOrPromise = parser.parse(withPassThroughFailure(withChildContext$1(forkOptionScope(currentContext), field, getFieldState(field, parser), parser), consumingFailure, getPassThroughPriority(parser, getFieldState(field, parser), currentContext.buffer[0])));
2707
2819
  const result = await resultOrPromise;
2708
2820
  if (result.success && result.consumed.length > 0) {
2709
2821
  adoptOptionScope(currentContext, result.next);
2710
2822
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
2711
2823
  currentContext = {
2712
2824
  ...currentContext,
2825
+ ...getPassThroughFailureHint(result.next),
2713
2826
  buffer: result.next.buffer,
2714
2827
  optionsTerminated: result.next.optionsTerminated,
2715
2828
  state: {
@@ -2727,7 +2840,12 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2727
2840
  madeProgress = true;
2728
2841
  consumedFields.add(field);
2729
2842
  break;
2730
- } else if (!result.success && error.consumed < result.consumed) error = result;
2843
+ } else if (result.success) consumingFailure = retainConsumingFailureHint(consumingFailure, currentContext, result.next);
2844
+ else {
2845
+ const match = getOptionMatch(parser, getFieldState(field, parser), currentContext.buffer[0]);
2846
+ if (result.consumed > 0 && match != null) consumingFailure = retainConsumingFailure(consumingFailure, result, match.priority);
2847
+ if (error.consumed < result.consumed) error = result;
2848
+ }
2731
2849
  }
2732
2850
  }
2733
2851
  {
@@ -2736,7 +2854,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2736
2854
  if (consumedFields.has(field)) continue;
2737
2855
  if (parser.leadingNames.size > 0 || parser.acceptingAnyToken) continue;
2738
2856
  const fieldState = getFieldState(field, parser);
2739
- const resultOrPromise = parser.parse(withChildContext$1(forkOptionScope(currentContext), field, fieldState, parser));
2857
+ const resultOrPromise = parser.parse(withPassThroughFailure(withChildContext$1(forkOptionScope(currentContext), field, fieldState, parser), consumingFailure, getPassThroughPriority(parser, getFieldState(field, parser), currentContext.buffer[0])));
2740
2858
  const result = await resultOrPromise;
2741
2859
  if (result.success && result.consumed.length === 0 && result.next.state !== fieldState) {
2742
2860
  adoptOptionScope(currentContext, result.next);
@@ -2758,7 +2876,7 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
2758
2876
  }
2759
2877
  if (anySuccess) return {
2760
2878
  success: true,
2761
- next: currentContext,
2879
+ next: withPassThroughFailure(currentContext, consumingFailure),
2762
2880
  consumed: allConsumed
2763
2881
  };
2764
2882
  if (currentContext.buffer.length === 0) {
@@ -3128,6 +3246,8 @@ function object(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
3128
3246
  });
3129
3247
  defineParseLanes(objectParser, objectParseLanes);
3130
3248
  defineInheritedAnnotationParser(objectParser);
3249
+ defineOptionMatch(objectParser, (state, token) => combineOptionMatches(parserPairs.map(([field, parser]) => getOptionMatch(parser, getAnnotatedFieldState(state, typeof field === "number" ? String(field) : field, parser), token))));
3250
+ definePassThroughPriority(objectParser, parserPairs.map(([, parser]) => parser), (state, token) => combinePassThroughPriorities(parserPairs.map(([field, parser]) => getPassThroughPriority(parser, getAnnotatedFieldState(state, typeof field === "number" ? String(field) : field, parser), token))));
3131
3251
  return fluent(scopeParser(objectParser, combinedOptionScope(parserPairs.map(([, p]) => p), parserPairs.map(([field]) => field)), void 0, true));
3132
3252
  }
3133
3253
  function isParserLike(value) {
@@ -3586,6 +3706,7 @@ function advanceTupleSuggestContextSync(context, parsers) {
3586
3706
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
3587
3707
  currentContext = {
3588
3708
  ...currentContext,
3709
+ ...getPassThroughFailureHint(result.next),
3589
3710
  buffer: result.next.buffer,
3590
3711
  optionsTerminated: result.next.optionsTerminated,
3591
3712
  state: newStateArray,
@@ -3652,6 +3773,7 @@ async function advanceTupleSuggestContextAsync(context, parsers) {
3652
3773
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
3653
3774
  currentContext = {
3654
3775
  ...currentContext,
3776
+ ...getPassThroughFailureHint(result.next),
3655
3777
  buffer: result.next.buffer,
3656
3778
  optionsTerminated: result.next.optionsTerminated,
3657
3779
  state: newStateArray,
@@ -3751,10 +3873,12 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
3751
3873
  const combinedMode = parsers.some((p) => p.mode === "async") ? "async" : "sync";
3752
3874
  const syncParsers = parsers;
3753
3875
  if (!options.allowDuplicates) checkDuplicateOptionNames(parsers.map((parser, index) => [String(index), parser.usage]));
3876
+ const passThroughParsers = new Set(parsers.filter((parser) => hasPassThroughUsage(parser.usage)));
3754
3877
  const parseSync = (context) => {
3755
3878
  let currentContext = context;
3756
3879
  const allConsumed = [];
3757
3880
  const matchedParsers = /* @__PURE__ */ new Set();
3881
+ let consumingFailure;
3758
3882
  while (matchedParsers.size < syncParsers.length) {
3759
3883
  let foundMatch = false;
3760
3884
  let error = {
@@ -3762,14 +3886,15 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
3762
3886
  error: message`No remaining parsers could match the input.`
3763
3887
  };
3764
3888
  const stateArray = currentContext.state;
3765
- const remainingParsers = syncParsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
3889
+ const remainingParsers = orderBeforePassThrough(syncParsers.map((parser, index) => [parser, index]).filter(([parser, index]) => !matchedParsers.has(index) || getOptionMatch(parser, stateArray[index], currentContext.buffer[0])?.continuesCommand === true || passThroughParsers.size > 0 && !currentContext.optionsTerminated && getOptionMatch(parser, stateArray[index], currentContext.buffer[0]) != null).sort(([parserA], [parserB]) => parserB.priority - parserA.priority), currentContext, ([parser]) => parser, ([, index]) => stateArray[index], passThroughParsers);
3766
3890
  for (const [parser, index] of remainingParsers) {
3767
- const result = parser.parse(withChildContext$1(currentContext, index, stateArray[index], parser));
3891
+ const result = parser.parse(withPassThroughFailure(withChildContext$1(currentContext, index, stateArray[index], parser), consumingFailure, getPassThroughPriority(parser, stateArray[index], currentContext.buffer[0])));
3768
3892
  if (result.success && result.consumed.length > 0) {
3769
3893
  const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((s, idx) => idx === index ? getWrappedChildState(currentContext.state, result.next.state, parser) : s));
3770
3894
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
3771
3895
  currentContext = {
3772
3896
  ...currentContext,
3897
+ ...getPassThroughFailureHint(result.next),
3773
3898
  buffer: result.next.buffer,
3774
3899
  optionsTerminated: result.next.optionsTerminated,
3775
3900
  state: newStateArray,
@@ -3778,14 +3903,21 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
3778
3903
  dependencyRegistry: mergedExec.dependencyRegistry
3779
3904
  } : {}
3780
3905
  };
3906
+ consumingFailure = void 0;
3781
3907
  allConsumed.push(...result.consumed);
3782
3908
  matchedParsers.add(index);
3783
3909
  foundMatch = true;
3784
3910
  break;
3785
- } else if (!result.success && error.consumed < result.consumed) error = result;
3911
+ } else if (result.success) consumingFailure = retainConsumingFailureHint(consumingFailure, currentContext, result.next);
3912
+ else {
3913
+ const match = getOptionMatch(parser, stateArray[index], currentContext.buffer[0]);
3914
+ if (result.consumed > 0 && match != null) consumingFailure = retainConsumingFailure(consumingFailure, result, match.priority);
3915
+ if (error.consumed < result.consumed) error = result;
3916
+ }
3786
3917
  }
3787
3918
  if (!foundMatch) for (const [parser, index] of remainingParsers) {
3788
- const result = parser.parse(withChildContext$1(currentContext, index, stateArray[index], parser));
3919
+ if (matchedParsers.has(index)) continue;
3920
+ const result = parser.parse(withPassThroughFailure(withChildContext$1(currentContext, index, stateArray[index], parser), consumingFailure, getPassThroughPriority(parser, stateArray[index], currentContext.buffer[0])));
3789
3921
  if (result.success && result.consumed.length < 1) {
3790
3922
  const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((s, idx) => idx === index ? getWrappedChildState(currentContext.state, result.next.state, parser) : s));
3791
3923
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
@@ -3813,7 +3945,7 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
3813
3945
  }
3814
3946
  return {
3815
3947
  success: true,
3816
- next: currentContext,
3948
+ next: withPassThroughFailure(currentContext, consumingFailure),
3817
3949
  consumed: allConsumed
3818
3950
  };
3819
3951
  };
@@ -3821,6 +3953,7 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
3821
3953
  let currentContext = context;
3822
3954
  const allConsumed = [];
3823
3955
  const matchedParsers = /* @__PURE__ */ new Set();
3956
+ let consumingFailure;
3824
3957
  while (matchedParsers.size < parsers.length) {
3825
3958
  let foundMatch = false;
3826
3959
  let error = {
@@ -3828,15 +3961,16 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
3828
3961
  error: message`No remaining parsers could match the input.`
3829
3962
  };
3830
3963
  const stateArray = currentContext.state;
3831
- const remainingParsers = parsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
3964
+ const remainingParsers = orderBeforePassThrough(parsers.map((parser, index) => [parser, index]).filter(([parser, index]) => !matchedParsers.has(index) || getOptionMatch(parser, stateArray[index], currentContext.buffer[0])?.continuesCommand === true || passThroughParsers.size > 0 && !currentContext.optionsTerminated && getOptionMatch(parser, stateArray[index], currentContext.buffer[0]) != null).sort(([parserA], [parserB]) => parserB.priority - parserA.priority), currentContext, ([parser]) => parser, ([, index]) => stateArray[index], passThroughParsers);
3832
3965
  for (const [parser, index] of remainingParsers) {
3833
- const resultOrPromise = parser.parse(withChildContext$1(currentContext, index, stateArray[index], parser));
3966
+ const resultOrPromise = parser.parse(withPassThroughFailure(withChildContext$1(currentContext, index, stateArray[index], parser), consumingFailure, getPassThroughPriority(parser, stateArray[index], currentContext.buffer[0])));
3834
3967
  const result = await resultOrPromise;
3835
3968
  if (result.success && result.consumed.length > 0) {
3836
3969
  const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((s, idx) => idx === index ? getWrappedChildState(currentContext.state, result.next.state, parser) : s));
3837
3970
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
3838
3971
  currentContext = {
3839
3972
  ...currentContext,
3973
+ ...getPassThroughFailureHint(result.next),
3840
3974
  buffer: result.next.buffer,
3841
3975
  optionsTerminated: result.next.optionsTerminated,
3842
3976
  state: newStateArray,
@@ -3845,14 +3979,21 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
3845
3979
  dependencyRegistry: mergedExec.dependencyRegistry
3846
3980
  } : {}
3847
3981
  };
3982
+ consumingFailure = void 0;
3848
3983
  allConsumed.push(...result.consumed);
3849
3984
  matchedParsers.add(index);
3850
3985
  foundMatch = true;
3851
3986
  break;
3852
- } else if (!result.success && error.consumed < result.consumed) error = result;
3987
+ } else if (result.success) consumingFailure = retainConsumingFailureHint(consumingFailure, currentContext, result.next);
3988
+ else {
3989
+ const match = getOptionMatch(parser, stateArray[index], currentContext.buffer[0]);
3990
+ if (result.consumed > 0 && match != null) consumingFailure = retainConsumingFailure(consumingFailure, result, match.priority);
3991
+ if (error.consumed < result.consumed) error = result;
3992
+ }
3853
3993
  }
3854
3994
  if (!foundMatch) for (const [parser, index] of remainingParsers) {
3855
- const resultOrPromise = parser.parse(withChildContext$1(currentContext, index, stateArray[index], parser));
3995
+ if (matchedParsers.has(index)) continue;
3996
+ const resultOrPromise = parser.parse(withPassThroughFailure(withChildContext$1(currentContext, index, stateArray[index], parser), consumingFailure, getPassThroughPriority(parser, stateArray[index], currentContext.buffer[0])));
3856
3997
  const result = await resultOrPromise;
3857
3998
  if (result.success && result.consumed.length < 1) {
3858
3999
  const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((s, idx) => idx === index ? getWrappedChildState(currentContext.state, result.next.state, parser) : s));
@@ -3881,7 +4022,7 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
3881
4022
  }
3882
4023
  return {
3883
4024
  success: true,
3884
- next: currentContext,
4025
+ next: withPassThroughFailure(currentContext, consumingFailure),
3885
4026
  consumed: allConsumed
3886
4027
  };
3887
4028
  };
@@ -4154,6 +4295,8 @@ function tuple(labelOrParsers, maybeParsersOrOptions, maybeOptions) {
4154
4295
  enumerable: false
4155
4296
  });
4156
4297
  defineInheritedAnnotationParser(tupleParser);
4298
+ defineOptionMatch(tupleParser, (state, token) => combineOptionMatches(parsers.map((parser, index) => getOptionMatch(parser, getWrappedChildState(state, state[index], parser), token))));
4299
+ definePassThroughPriority(tupleParser, parsers, (state, token) => combinePassThroughPriorities(parsers.map((parser, index) => getPassThroughPriority(parser, getWrappedChildState(state, state[index], parser), token))));
4157
4300
  return fluent(scopeParser(tupleParser, combinedOptionScope(parsers, parsers.map((_, index) => index))));
4158
4301
  }
4159
4302
  function seq(...rawArgs) {
@@ -4648,6 +4791,7 @@ function merge(...args) {
4648
4791
  success: true,
4649
4792
  next: {
4650
4793
  ...context,
4794
+ ...getPassThroughFailureHint(result.next),
4651
4795
  buffer: result.next.buffer,
4652
4796
  optionsTerminated: result.next.optionsTerminated,
4653
4797
  state: newState,
@@ -4753,6 +4897,7 @@ function merge(...args) {
4753
4897
  const mergedExec = mergeChildExec(settledContext.exec, result.next.exec);
4754
4898
  settledContext = {
4755
4899
  ...settledContext,
4900
+ ...getPassThroughFailureHint(result.next),
4756
4901
  buffer: result.next.buffer,
4757
4902
  optionsTerminated: result.next.optionsTerminated,
4758
4903
  state: nextState,
@@ -4785,6 +4930,7 @@ function merge(...args) {
4785
4930
  const newState = mergeResultState(parser, currentContext, parserState, result, i);
4786
4931
  const newContext = {
4787
4932
  ...currentContext,
4933
+ ...getPassThroughFailureHint(result.next),
4788
4934
  buffer: result.next.buffer,
4789
4935
  optionsTerminated: result.next.optionsTerminated,
4790
4936
  state: newState,
@@ -4830,6 +4976,7 @@ function merge(...args) {
4830
4976
  const newState = mergeResultState(parser, currentContext, parserState, result, i);
4831
4977
  const newContext = {
4832
4978
  ...currentContext,
4979
+ ...getPassThroughFailureHint(result.next),
4833
4980
  buffer: result.next.buffer,
4834
4981
  optionsTerminated: result.next.optionsTerminated,
4835
4982
  state: newState,
@@ -4869,10 +5016,12 @@ function merge(...args) {
4869
5016
  const consumedLanes = /* @__PURE__ */ new Set();
4870
5017
  const consumedGroups = /* @__PURE__ */ new Set();
4871
5018
  const laneResults = /* @__PURE__ */ new Map();
5019
+ let consumingFailure;
4872
5020
  let attemptedLane = false;
4873
5021
  let madeProgress = true;
4874
5022
  while (madeProgress && currentContext.buffer.length > 0) {
4875
5023
  madeProgress = false;
5024
+ consumingFailure = void 0;
4876
5025
  let consumingError = null;
4877
5026
  for (const lane of mergeParseLanes) {
4878
5027
  if (consumingError != null && lane.priority < consumingError.priority) {
@@ -4890,6 +5039,10 @@ function merge(...args) {
4890
5039
  break;
4891
5040
  }
4892
5041
  if (!result.success) {
5042
+ if (result.consumed > 0 && matchesOptionToken({
5043
+ leadingNames: lane.leadingNames,
5044
+ usage: parsers.flatMap((parser) => parser.usage)
5045
+ }, currentContext.buffer[0])) consumingFailure = retainConsumingFailure(consumingFailure, result, lane.priority);
4893
5046
  if (result.consumed > 0 && consumingError == null) consumingError = {
4894
5047
  priority: lane.priority,
4895
5048
  result
@@ -4921,7 +5074,7 @@ function merge(...args) {
4921
5074
  }
4922
5075
  return {
4923
5076
  success: true,
4924
- next: currentContext,
5077
+ next: withPassThroughFailure(currentContext, consumingFailure),
4925
5078
  consumed: allConsumed
4926
5079
  };
4927
5080
  };
@@ -4932,10 +5085,12 @@ function merge(...args) {
4932
5085
  const consumedLanes = /* @__PURE__ */ new Set();
4933
5086
  const consumedGroups = /* @__PURE__ */ new Set();
4934
5087
  const laneResults = /* @__PURE__ */ new Map();
5088
+ let consumingFailure;
4935
5089
  let attemptedLane = false;
4936
5090
  let madeProgress = true;
4937
5091
  while (madeProgress && currentContext.buffer.length > 0) {
4938
5092
  madeProgress = false;
5093
+ consumingFailure = void 0;
4939
5094
  let consumingError = null;
4940
5095
  for (const lane of mergeParseLanes) {
4941
5096
  if (consumingError != null && lane.priority < consumingError.priority) {
@@ -4953,6 +5108,10 @@ function merge(...args) {
4953
5108
  break;
4954
5109
  }
4955
5110
  if (!result.success) {
5111
+ if (result.consumed > 0 && matchesOptionToken({
5112
+ leadingNames: lane.leadingNames,
5113
+ usage: parsers.flatMap((parser) => parser.usage)
5114
+ }, currentContext.buffer[0])) consumingFailure = retainConsumingFailure(consumingFailure, result, lane.priority);
4956
5115
  if (result.consumed > 0 && consumingError == null) consumingError = {
4957
5116
  priority: lane.priority,
4958
5117
  result
@@ -4984,7 +5143,7 @@ function merge(...args) {
4984
5143
  }
4985
5144
  return {
4986
5145
  success: true,
4987
- next: currentContext,
5146
+ next: withPassThroughFailure(currentContext, consumingFailure),
4988
5147
  consumed: allConsumed
4989
5148
  };
4990
5149
  };
@@ -5527,6 +5686,8 @@ function merge(...args) {
5527
5686
  };
5528
5687
  defineParseLanes(mergeParser, mergeParseLanes);
5529
5688
  defineInheritedAnnotationParser(mergeParser);
5689
+ defineOptionMatch(mergeParser, (state, token) => combineOptionMatches(sorted.map(([parser], index) => getOptionMatch(parser, extractParserStateFromState(parser, state, index), token))));
5690
+ definePassThroughPriority(mergeParser, parsers, (state, token) => combinePassThroughPriorities(sorted.map(([parser], index) => getPassThroughPriority(parser, extractParserStateFromState(parser, state, index), token))));
5530
5691
  return fluent(scopeParser(mergeParser, combinedOptionScope(parsers, parsers.map((_, index) => index))));
5531
5692
  }
5532
5693
  /**
@@ -5717,6 +5878,7 @@ function tryParseSuggestList(context, stateArray, parsers, matchedParsers, remai
5717
5878
  const mergedExec = mergeChildExec(context.exec, result$1.next.exec);
5718
5879
  return preParseSuggestLoop({
5719
5880
  ...context,
5881
+ ...getPassThroughFailureHint(result$1.next),
5720
5882
  buffer: result$1.next.buffer,
5721
5883
  optionsTerminated: result$1.next.optionsTerminated,
5722
5884
  state: stateArray,
@@ -5744,6 +5906,7 @@ function tryParseSuggestList(context, stateArray, parsers, matchedParsers, remai
5744
5906
  const mergedExec = mergeChildExec(context.exec, result.next.exec);
5745
5907
  return {
5746
5908
  ...context,
5909
+ ...getPassThroughFailureHint(result.next),
5747
5910
  buffer: result.next.buffer,
5748
5911
  optionsTerminated: result.next.optionsTerminated,
5749
5912
  state: stateArray,
@@ -5763,10 +5926,12 @@ function concat(...parsers) {
5763
5926
  const isAsync = combinedMode === "async";
5764
5927
  const syncParsers = parsers;
5765
5928
  const initialState = parsers.map((parser) => parser.initialState);
5929
+ const passThroughParsers = new Set(parsers.filter((parser) => hasPassThroughUsage(parser.usage)));
5766
5930
  const parseSync = (context) => {
5767
5931
  let currentContext = context;
5768
5932
  const allConsumed = [];
5769
5933
  const matchedParsers = /* @__PURE__ */ new Set();
5934
+ let consumingFailure;
5770
5935
  while (matchedParsers.size < syncParsers.length) {
5771
5936
  let foundMatch = false;
5772
5937
  let error = {
@@ -5774,14 +5939,15 @@ function concat(...parsers) {
5774
5939
  error: message`No remaining parsers could match the input.`
5775
5940
  };
5776
5941
  const stateArray = currentContext.state;
5777
- const remainingParsers = syncParsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
5942
+ const remainingParsers = orderBeforePassThrough(syncParsers.map((parser, index) => [parser, index]).filter(([parser, index]) => !matchedParsers.has(index) || getOptionMatch(parser, stateArray[index], currentContext.buffer[0])?.continuesCommand === true || passThroughParsers.size > 0 && !currentContext.optionsTerminated && getOptionMatch(parser, stateArray[index], currentContext.buffer[0]) != null).sort(([parserA], [parserB]) => parserB.priority - parserA.priority), currentContext, ([parser]) => parser, ([, index]) => stateArray[index], passThroughParsers);
5778
5943
  for (const [parser, index] of remainingParsers) {
5779
- const result = parser.parse(withChildContext$1(currentContext, index, stateArray[index], parser));
5944
+ const result = parser.parse(withPassThroughFailure(withChildContext$1(currentContext, index, stateArray[index], parser), consumingFailure, getPassThroughPriority(parser, stateArray[index], currentContext.buffer[0])));
5780
5945
  if (result.success && result.consumed.length > 0) {
5781
5946
  const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((s, idx) => idx === index ? getWrappedChildState(currentContext.state, result.next.state, parser) : s));
5782
5947
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
5783
5948
  currentContext = {
5784
5949
  ...currentContext,
5950
+ ...getPassThroughFailureHint(result.next),
5785
5951
  buffer: result.next.buffer,
5786
5952
  optionsTerminated: result.next.optionsTerminated,
5787
5953
  state: newStateArray,
@@ -5790,14 +5956,21 @@ function concat(...parsers) {
5790
5956
  dependencyRegistry: mergedExec.dependencyRegistry
5791
5957
  } : {}
5792
5958
  };
5959
+ consumingFailure = void 0;
5793
5960
  allConsumed.push(...result.consumed);
5794
5961
  matchedParsers.add(index);
5795
5962
  foundMatch = true;
5796
5963
  break;
5797
- } else if (!result.success && error.consumed < result.consumed) error = result;
5964
+ } else if (result.success) consumingFailure = retainConsumingFailureHint(consumingFailure, currentContext, result.next);
5965
+ else {
5966
+ const match = getOptionMatch(parser, stateArray[index], currentContext.buffer[0]);
5967
+ if (result.consumed > 0 && match != null) consumingFailure = retainConsumingFailure(consumingFailure, result, match.priority);
5968
+ if (error.consumed < result.consumed) error = result;
5969
+ }
5798
5970
  }
5799
5971
  if (!foundMatch) for (const [parser, index] of remainingParsers) {
5800
- const result = parser.parse(withChildContext$1(currentContext, index, stateArray[index], parser));
5972
+ if (matchedParsers.has(index)) continue;
5973
+ const result = parser.parse(withPassThroughFailure(withChildContext$1(currentContext, index, stateArray[index], parser), consumingFailure, getPassThroughPriority(parser, stateArray[index], currentContext.buffer[0])));
5801
5974
  if (result.success && result.consumed.length < 1) {
5802
5975
  const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((s, idx) => idx === index ? getWrappedChildState(currentContext.state, result.next.state, parser) : s));
5803
5976
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
@@ -5825,7 +5998,7 @@ function concat(...parsers) {
5825
5998
  }
5826
5999
  return {
5827
6000
  success: true,
5828
- next: currentContext,
6001
+ next: withPassThroughFailure(currentContext, consumingFailure),
5829
6002
  consumed: allConsumed
5830
6003
  };
5831
6004
  };
@@ -5833,6 +6006,7 @@ function concat(...parsers) {
5833
6006
  let currentContext = context;
5834
6007
  const allConsumed = [];
5835
6008
  const matchedParsers = /* @__PURE__ */ new Set();
6009
+ let consumingFailure;
5836
6010
  while (matchedParsers.size < parsers.length) {
5837
6011
  let foundMatch = false;
5838
6012
  let error = {
@@ -5840,14 +6014,15 @@ function concat(...parsers) {
5840
6014
  error: message`No remaining parsers could match the input.`
5841
6015
  };
5842
6016
  const stateArray = currentContext.state;
5843
- const remainingParsers = parsers.map((parser, index) => [parser, index]).filter(([_, index]) => !matchedParsers.has(index)).sort(([parserA], [parserB]) => parserB.priority - parserA.priority);
6017
+ const remainingParsers = orderBeforePassThrough(parsers.map((parser, index) => [parser, index]).filter(([parser, index]) => !matchedParsers.has(index) || getOptionMatch(parser, stateArray[index], currentContext.buffer[0])?.continuesCommand === true || passThroughParsers.size > 0 && !currentContext.optionsTerminated && getOptionMatch(parser, stateArray[index], currentContext.buffer[0]) != null).sort(([parserA], [parserB]) => parserB.priority - parserA.priority), currentContext, ([parser]) => parser, ([, index]) => stateArray[index], passThroughParsers);
5844
6018
  for (const [parser, index] of remainingParsers) {
5845
- const result = await parser.parse(withChildContext$1(currentContext, index, stateArray[index], parser));
6019
+ const result = await parser.parse(withPassThroughFailure(withChildContext$1(currentContext, index, stateArray[index], parser), consumingFailure, getPassThroughPriority(parser, stateArray[index], currentContext.buffer[0])));
5846
6020
  if (result.success && result.consumed.length > 0) {
5847
6021
  const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((s, idx) => idx === index ? getWrappedChildState(currentContext.state, result.next.state, parser) : s));
5848
6022
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
5849
6023
  currentContext = {
5850
6024
  ...currentContext,
6025
+ ...getPassThroughFailureHint(result.next),
5851
6026
  buffer: result.next.buffer,
5852
6027
  optionsTerminated: result.next.optionsTerminated,
5853
6028
  state: newStateArray,
@@ -5856,14 +6031,21 @@ function concat(...parsers) {
5856
6031
  dependencyRegistry: mergedExec.dependencyRegistry
5857
6032
  } : {}
5858
6033
  };
6034
+ consumingFailure = void 0;
5859
6035
  allConsumed.push(...result.consumed);
5860
6036
  matchedParsers.add(index);
5861
6037
  foundMatch = true;
5862
6038
  break;
5863
- } else if (!result.success && error.consumed < result.consumed) error = result;
6039
+ } else if (result.success) consumingFailure = retainConsumingFailureHint(consumingFailure, currentContext, result.next);
6040
+ else {
6041
+ const match = getOptionMatch(parser, stateArray[index], currentContext.buffer[0]);
6042
+ if (result.consumed > 0 && match != null) consumingFailure = retainConsumingFailure(consumingFailure, result, match.priority);
6043
+ if (error.consumed < result.consumed) error = result;
6044
+ }
5864
6045
  }
5865
6046
  if (!foundMatch) for (const [parser, index] of remainingParsers) {
5866
- const result = await parser.parse(withChildContext$1(currentContext, index, stateArray[index], parser));
6047
+ if (matchedParsers.has(index)) continue;
6048
+ const result = await parser.parse(withPassThroughFailure(withChildContext$1(currentContext, index, stateArray[index], parser), consumingFailure, getPassThroughPriority(parser, stateArray[index], currentContext.buffer[0])));
5867
6049
  if (result.success && result.consumed.length < 1) {
5868
6050
  const newStateArray = annotateFreshArray(currentContext.state, stateArray.map((s, idx) => idx === index ? getWrappedChildState(currentContext.state, result.next.state, parser) : s));
5869
6051
  const mergedExec = mergeChildExec(currentContext.exec, result.next.exec);
@@ -5891,7 +6073,7 @@ function concat(...parsers) {
5891
6073
  }
5892
6074
  return {
5893
6075
  success: true,
5894
- next: currentContext,
6076
+ next: withPassThroughFailure(currentContext, consumingFailure),
5895
6077
  consumed: allConsumed
5896
6078
  };
5897
6079
  };
@@ -6162,6 +6344,8 @@ function concat(...parsers) {
6162
6344
  }
6163
6345
  };
6164
6346
  defineInheritedAnnotationParser(concatParser);
6347
+ defineOptionMatch(concatParser, (state, token) => combineOptionMatches(parsers.map((parser, index) => getOptionMatch(parser, getWrappedChildState(state, state[index], parser), token))));
6348
+ definePassThroughPriority(concatParser, parsers, (state, token) => combinePassThroughPriorities(parsers.map((parser, index) => getPassThroughPriority(parser, getWrappedChildState(state, state[index], parser), token))));
6165
6349
  return fluent(scopeParser(concatParser, combinedOptionScope(parsers, parsers.map((_, index) => index))));
6166
6350
  }
6167
6351
  function group(label, parser, options = {}) {
@@ -6280,6 +6464,9 @@ function group(label, parser, options = {}) {
6280
6464
  configurable: true,
6281
6465
  enumerable: false
6282
6466
  });
6467
+ delegateKnownCompletion(groupParser, parser);
6468
+ defineOptionMatch(groupParser, (state, token) => getOptionMatch(parser, state, token));
6469
+ definePassThroughPriority(groupParser, [parser], (state, token) => getPassThroughPriority(parser, state, token));
6283
6470
  return fluent(scopeParser(groupParser, combinedOptionScope([parser])));
6284
6471
  }
6285
6472
  /**
@@ -6437,6 +6624,7 @@ function conditional(discriminator, branches, defaultBranch, options) {
6437
6624
  dependencyRegistry: discriminatorExec.dependencyRegistry
6438
6625
  } : {}
6439
6626
  }, "_branch", branchParser.initialState, branchParser, branchParser.usage),
6627
+ ...getPassThroughFailureHint(discriminatorResult.next),
6440
6628
  buffer: discriminatorResult.next.buffer,
6441
6629
  optionsTerminated: discriminatorResult.next.optionsTerminated
6442
6630
  });
@@ -6565,6 +6753,7 @@ function conditional(discriminator, branches, defaultBranch, options) {
6565
6753
  const discriminatorExec = mergeChildExec(context.exec, discriminatorResult.next.exec);
6566
6754
  const speculationContext = {
6567
6755
  ...withOptionScope(context, unionLeadingNames([...branchParsers.map(([, p]) => p), ...defaultBranch ? [defaultBranch] : []])),
6756
+ ...getPassThroughFailureHint(discriminatorResult.next),
6568
6757
  buffer: discriminatorResult.next.buffer,
6569
6758
  optionsTerminated: discriminatorResult.next.optionsTerminated,
6570
6759
  ...discriminatorExec != null ? {
@@ -6696,6 +6885,7 @@ function conditional(discriminator, branches, defaultBranch, options) {
6696
6885
  dependencyRegistry: discriminatorExec.dependencyRegistry
6697
6886
  } : {}
6698
6887
  }, "_branch", branchParser.initialState, branchParser, branchParser.usage),
6888
+ ...getPassThroughFailureHint(discriminatorResult.next),
6699
6889
  buffer: discriminatorResult.next.buffer,
6700
6890
  optionsTerminated: discriminatorResult.next.optionsTerminated
6701
6891
  });
@@ -7650,6 +7840,36 @@ function conditional(discriminator, branches, defaultBranch, options) {
7650
7840
  configurable: true,
7651
7841
  enumerable: false
7652
7842
  });
7843
+ const reachableBranches = (state) => {
7844
+ if (state.selectedBranch != null) {
7845
+ const branch = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
7846
+ return branch == null ? [] : [{
7847
+ branch,
7848
+ state: state.branchState
7849
+ }];
7850
+ }
7851
+ const known = getKnownCompletion(discriminator, state.discriminatorState);
7852
+ if (known != null) {
7853
+ const branch = typeof known.value === "string" ? branches[known.value] : void 0;
7854
+ const reachable = branch ?? defaultBranch;
7855
+ return reachable == null ? [] : [{
7856
+ branch: reachable,
7857
+ state: reachable.initialState
7858
+ }];
7859
+ }
7860
+ return allBranchParsers.map((branch) => ({
7861
+ branch,
7862
+ state: branch.initialState
7863
+ }));
7864
+ };
7865
+ definePassThroughPriority(conditionalParser, [discriminator, ...allBranchParsers], (state, token) => combinePassThroughPriorities([...state.selectedBranch == null ? [getPassThroughPriority(discriminator, state.discriminatorState, token)] : [], ...reachableBranches(state).map(({ branch, state: state$1 }) => getPassThroughPriority(branch, state$1, token))]));
7866
+ defineOptionMatch(conditionalParser, (state, token) => {
7867
+ if (state.selectedBranch != null) {
7868
+ const branch = state.selectedBranch.kind === "default" ? defaultBranch : branches[state.selectedBranch.key];
7869
+ return branch == null ? void 0 : getOptionMatch(branch, state.branchState, token);
7870
+ }
7871
+ return combineOptionMatches([getOptionMatch(discriminator, state.discriminatorState, token), ...reachableBranches(state).map(({ branch, state: state$1 }) => getOptionMatch(branch, state$1, token))]);
7872
+ });
7653
7873
  return fluent(scopeParser(conditionalParser, optionScope.source, (context) => {
7654
7874
  const selected = context.state?.selectedBranch;
7655
7875
  if (selected != null) {