@optique/core 1.4.0-dev.2638 → 1.4.0-dev.2662

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.
@@ -3,6 +3,7 @@ const require_mode_dispatch = require('./internal/mode-dispatch.cjs');
3
3
  const require_internal_parser = require('./internal/parser.cjs');
4
4
  const require_annotation_state = require('./annotation-state.cjs');
5
5
  const require_short_option = require('./short-option.cjs');
6
+ const require_passthrough = require('./internal/passthrough.cjs');
6
7
  const require_phase2_seed = require('./phase2-seed.cjs');
7
8
 
8
9
  //#region src/extension.ts
@@ -86,9 +87,27 @@ function delegateSuggestNodes(innerParser, outerParser, state, path, innerState,
86
87
  function mapSourceMetadata(parser, mapSource) {
87
88
  return require_internal_parser.composeWrappedSourceMetadata(parser.dependencyMetadata, mapSource);
88
89
  }
90
+ /**
91
+ * Delegates CLI option matching and capture priority through a parser wrapper.
92
+ * Use the same child-state projection as the wrapper's parse method. This
93
+ * preserves selected command options without changing public leading names.
94
+ *
95
+ * @param wrapper The parser being constructed.
96
+ * @param inner Its wrapped CLI parser.
97
+ * @param getInnerState Projects the wrapper state to the CLI parser state.
98
+ * @throws {TypeError} If metadata cannot be defined on the wrapper.
99
+ * @since 1.0.11
100
+ */
101
+ function delegateOptionParsing(wrapper, inner, getInnerState) {
102
+ require_passthrough.defineReachableChildren(wrapper, [inner], (state) => [{
103
+ parser: inner,
104
+ state: getInnerState(state)
105
+ }]);
106
+ }
89
107
 
90
108
  //#endregion
91
109
  exports.defineTraits = defineTraits;
110
+ exports.delegateOptionParsing = delegateOptionParsing;
92
111
  exports.delegateSuggestNodes = delegateSuggestNodes;
93
112
  exports.dispatchByMode = require_mode_dispatch.dispatchByMode;
94
113
  exports.extractPhase2SeedKey = require_phase2_seed.extractPhase2SeedKey;
@@ -105,5 +105,17 @@ declare function delegateSuggestNodes<TInnerState>(innerParser: Parser<Mode, unk
105
105
  * @since 1.0.0
106
106
  */
107
107
  declare function mapSourceMetadata<M extends Mode, TValue, TState>(parser: Pick<Parser<M, TValue, TState>, "dependencyMetadata">, mapSource: (source: ParserSourceMetadata<M, TValue, TState>) => ParserSourceMetadata<M, TValue, TState>): Parser<M, TValue, TState>["dependencyMetadata"] | undefined;
108
+ /**
109
+ * Delegates CLI option matching and capture priority through a parser wrapper.
110
+ * Use the same child-state projection as the wrapper's parse method. This
111
+ * preserves selected command options without changing public leading names.
112
+ *
113
+ * @param wrapper The parser being constructed.
114
+ * @param inner Its wrapped CLI parser.
115
+ * @param getInnerState Projects the wrapper state to the CLI parser state.
116
+ * @throws {TypeError} If metadata cannot be defined on the wrapper.
117
+ * @since 1.0.11
118
+ */
119
+ declare function delegateOptionParsing<TOuterState, TInnerState>(wrapper: Parser<Mode, unknown, TOuterState>, inner: Parser<Mode, unknown, TInnerState>, getInnerState: (state: TOuterState) => TInnerState): void;
108
120
  //#endregion
109
- export { ParserSourceMetadata, ParserTraits, SuggestNode, defineTraits, delegateSuggestNodes, dispatchByMode, extractPhase2SeedKey, getTraits, inheritAnnotations, inheritOptionScope, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
121
+ export { ParserSourceMetadata, ParserTraits, SuggestNode, defineTraits, delegateOptionParsing, delegateSuggestNodes, dispatchByMode, extractPhase2SeedKey, getTraits, inheritAnnotations, inheritOptionScope, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
@@ -105,5 +105,17 @@ declare function delegateSuggestNodes<TInnerState>(innerParser: Parser<Mode, unk
105
105
  * @since 1.0.0
106
106
  */
107
107
  declare function mapSourceMetadata<M extends Mode, TValue, TState>(parser: Pick<Parser<M, TValue, TState>, "dependencyMetadata">, mapSource: (source: ParserSourceMetadata<M, TValue, TState>) => ParserSourceMetadata<M, TValue, TState>): Parser<M, TValue, TState>["dependencyMetadata"] | undefined;
108
+ /**
109
+ * Delegates CLI option matching and capture priority through a parser wrapper.
110
+ * Use the same child-state projection as the wrapper's parse method. This
111
+ * preserves selected command options without changing public leading names.
112
+ *
113
+ * @param wrapper The parser being constructed.
114
+ * @param inner Its wrapped CLI parser.
115
+ * @param getInnerState Projects the wrapper state to the CLI parser state.
116
+ * @throws {TypeError} If metadata cannot be defined on the wrapper.
117
+ * @since 1.0.11
118
+ */
119
+ declare function delegateOptionParsing<TOuterState, TInnerState>(wrapper: Parser<Mode, unknown, TOuterState>, inner: Parser<Mode, unknown, TInnerState>, getInnerState: (state: TOuterState) => TInnerState): void;
108
120
  //#endregion
109
- export { ParserSourceMetadata, ParserTraits, SuggestNode, defineTraits, delegateSuggestNodes, dispatchByMode, extractPhase2SeedKey, getTraits, inheritAnnotations, inheritOptionScope, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
121
+ export { ParserSourceMetadata, ParserTraits, SuggestNode, defineTraits, delegateOptionParsing, delegateSuggestNodes, dispatchByMode, extractPhase2SeedKey, getTraits, inheritAnnotations, inheritOptionScope, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
package/dist/extension.js CHANGED
@@ -3,6 +3,7 @@ import { dispatchByMode, mapModeValue, wrapForMode } from "./internal/mode-dispa
3
3
  import { annotationWrapperRequiresSourceBindingKey, composeWrappedSourceMetadata, defineInheritedAnnotationParser, getDelegatingSuggestRuntimeNodes, inheritParentAnnotationsKey, unmatchedNonCliDependencySourceStateMarker } from "./internal/parser.js";
4
4
  import { withAnnotationView } from "./annotation-state.js";
5
5
  import { inheritOptionScope } from "./short-option.js";
6
+ import { defineReachableChildren } from "./internal/passthrough.js";
6
7
  import { extractPhase2SeedKey } from "./phase2-seed.js";
7
8
 
8
9
  //#region src/extension.ts
@@ -86,6 +87,23 @@ function delegateSuggestNodes(innerParser, outerParser, state, path, innerState,
86
87
  function mapSourceMetadata(parser, mapSource) {
87
88
  return composeWrappedSourceMetadata(parser.dependencyMetadata, mapSource);
88
89
  }
90
+ /**
91
+ * Delegates CLI option matching and capture priority through a parser wrapper.
92
+ * Use the same child-state projection as the wrapper's parse method. This
93
+ * preserves selected command options without changing public leading names.
94
+ *
95
+ * @param wrapper The parser being constructed.
96
+ * @param inner Its wrapped CLI parser.
97
+ * @param getInnerState Projects the wrapper state to the CLI parser state.
98
+ * @throws {TypeError} If metadata cannot be defined on the wrapper.
99
+ * @since 1.0.11
100
+ */
101
+ function delegateOptionParsing(wrapper, inner, getInnerState) {
102
+ defineReachableChildren(wrapper, [inner], (state) => [{
103
+ parser: inner,
104
+ state: getInnerState(state)
105
+ }]);
106
+ }
89
107
 
90
108
  //#endregion
91
- export { defineTraits, delegateSuggestNodes, dispatchByMode, extractPhase2SeedKey, getTraits, inheritAnnotations, inheritOptionScope$1 as inheritOptionScope, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
109
+ export { defineTraits, delegateOptionParsing, delegateSuggestNodes, dispatchByMode, extractPhase2SeedKey, getTraits, inheritAnnotations, inheritOptionScope$1 as inheritOptionScope, injectAnnotations, isInjectedAnnotationState, mapModeValue, mapSourceMetadata, unwrapInjectedAnnotationState, withAnnotationView, wrapForMode };
@@ -0,0 +1,284 @@
1
+
2
+ //#region src/internal/passthrough.ts
3
+ /** Retains the deepest diagnostic and highest matching lane priority. @internal */
4
+ function retainConsumingFailure(current, failure, priority) {
5
+ return {
6
+ failure: current != null && current.failure.consumed >= failure.consumed ? current.failure : failure,
7
+ priority: Math.max(current?.priority ?? -Infinity, priority)
8
+ };
9
+ }
10
+ const passThroughFailure = Symbol("passThroughFailure");
11
+ /**
12
+ * Gets the sibling failure that prevents pass-through capture at this cursor.
13
+ * Stale hints inherited through a successful child do not block later input.
14
+ * @param context The pass-through parser's context.
15
+ * @returns The failure at this cursor, or undefined if capture is allowed.
16
+ * @internal
17
+ */
18
+ function getPassThroughFailure(context, capturePriority$1 = -Infinity) {
19
+ const hinted = context;
20
+ const hint = hinted[passThroughFailure];
21
+ return hint?.buffer === context.buffer && hint.optionsTerminated === context.optionsTerminated && hint.failure.priority >= capturePriority$1 ? hint.failure : void 0;
22
+ }
23
+ /**
24
+ * Carries a sibling's consuming failure into a child parse call. Only
25
+ * passThrough consults the hint; ordinary alternatives may still recover.
26
+ * @param context The child context, without modifying the parent's context.
27
+ * @param failure The deepest matching consuming failure at this input position.
28
+ * @returns A context with a hint for active option-like input, or the original.
29
+ * @internal
30
+ */
31
+ function withPassThroughFailure(context, failure, capturePriority$1 = -Infinity) {
32
+ const incoming = context;
33
+ if (incoming[passThroughFailure]?.own != null) {
34
+ const { own: _own,...hint } = incoming[passThroughFailure];
35
+ const stripped = {
36
+ ...context,
37
+ [passThroughFailure]: hint
38
+ };
39
+ context = stripped;
40
+ }
41
+ const token = context.buffer[0];
42
+ const existing = getPassThroughFailure(context);
43
+ if (existing != null && existing.priority < capturePriority$1) {
44
+ const hinted$1 = context;
45
+ const { [passThroughFailure]: _discarded,...rest } = hinted$1;
46
+ context = rest;
47
+ }
48
+ if (failure == null || failure.failure.consumed < 1 || failure.priority < capturePriority$1 || context.optionsTerminated || token == null || token === "--" || !/^[-/+]/.test(token)) return context;
49
+ const retained = getPassThroughFailure(context);
50
+ const combined = retainConsumingFailure(retained, failure.failure, failure.priority);
51
+ const hinted = {
52
+ ...context,
53
+ [passThroughFailure]: {
54
+ buffer: context.buffer,
55
+ optionsTerminated: context.optionsTerminated,
56
+ failure: combined
57
+ }
58
+ };
59
+ return hinted;
60
+ }
61
+ /** Reads locally originated diagnostics at the same cursor. @internal */
62
+ function getOwnConsumingFailure(context) {
63
+ const hinted = context;
64
+ const hint = hinted[passThroughFailure];
65
+ return hint?.buffer === context.buffer && hint.optionsTerminated === context.optionsTerminated ? hint.own : void 0;
66
+ }
67
+ /**
68
+ * Returns a successful child's local diagnostic to its parent without merging
69
+ * its provenance with an inherited sibling diagnostic. Both share a cursor.
70
+ * @internal
71
+ */
72
+ function withReturnedConsumingFailure(context, failure) {
73
+ const next = withPassThroughFailure(context, failure);
74
+ if (failure == null || getPassThroughFailure(next) == null) return next;
75
+ const token = next.buffer[0];
76
+ if (next.optionsTerminated || token == null || token === "--" || !/^[-/+]/.test(token) || failure.failure.consumed < 1) return next;
77
+ const hinted = next;
78
+ const hint = hinted[passThroughFailure];
79
+ if (hint == null) return next;
80
+ const returned = {
81
+ ...next,
82
+ [passThroughFailure]: {
83
+ ...hint,
84
+ own: failure
85
+ }
86
+ };
87
+ return returned;
88
+ }
89
+ /** Retains a child's own rejected option failure at the parent's cursor. @internal */
90
+ function retainConsumingFailureHint(current, context, next) {
91
+ if (next.buffer !== context.buffer || next.optionsTerminated !== context.optionsTerminated) return current;
92
+ const own = getOwnConsumingFailure(next);
93
+ return own == null || own === getOwnConsumingFailure(context) ? current : retainConsumingFailure(current, own.failure, own.priority);
94
+ }
95
+ const capturePriority = Symbol("capturePriority");
96
+ /** Checks for capture through usage-preserving wrappers. @internal */
97
+ function hasPassThroughUsage(usage) {
98
+ return usage.some((term) => term.type === "passthrough" || (term.type === "optional" || term.type === "multiple") && hasPassThroughUsage(term.terms) || term.type === "exclusive" && term.terms.some(hasPassThroughUsage));
99
+ }
100
+ /**
101
+ * Gets the priority of reachable capture, respecting an explicit override.
102
+ * @param parser The parser whose capture priority is needed.
103
+ * @param state The current parser state.
104
+ * @param token The current token, omitted for an unfiltered priority lookup.
105
+ * @returns The capture priority, or undefined when capture is absent.
106
+ * @internal
107
+ */
108
+ function getPassThroughPriority(parser, state = parser.initialState, token) {
109
+ if (!hasPassThroughUsage(parser.usage)) return void 0;
110
+ const annotated = parser;
111
+ const hint = annotated[capturePriority];
112
+ if (hint == null) return parser.priority;
113
+ const priority = hint.getPriority == null ? hint.priority : hint.getPriority(state, token);
114
+ return priority == null ? void 0 : hint.ownerPriority === parser.priority ? priority : parser.priority;
115
+ }
116
+ /**
117
+ * Records capture priority separately from unrelated children's priorities.
118
+ * @param parser The newly constructed parser.
119
+ * @param children Its transparent children.
120
+ * @param getPriority Optional state-aware capture priority lookup.
121
+ * @internal
122
+ */
123
+ function definePassThroughPriority(parser, children, getPriority) {
124
+ const priorities = children.filter((child) => hasPassThroughUsage(child.usage)).map((child) => getPassThroughPriority(child) ?? child.priority);
125
+ if (priorities.length === 0) return;
126
+ Object.defineProperty(parser, capturePriority, {
127
+ value: {
128
+ ownerPriority: parser.priority,
129
+ priority: Math.max(...priorities),
130
+ getPriority
131
+ },
132
+ enumerable: true
133
+ });
134
+ }
135
+ /**
136
+ * Copies only a cursor-valid hint when rebuilding a child context.
137
+ * @param context The successful child's context.
138
+ * @returns Private hint properties, or an empty object for stale hints.
139
+ * @internal
140
+ */
141
+ function getPassThroughFailureHint(context) {
142
+ const hinted = context;
143
+ const hint = hinted[passThroughFailure];
144
+ return hint != null && getPassThroughFailure(context) != null ? { [passThroughFailure]: hint } : {};
145
+ }
146
+ /** Finds a Boolean option through usage-preserving wrappers. */
147
+ function hasFlagUsage(usage, name) {
148
+ return usage.some((term) => term.type === "option" && term.metavar == null && term.names.some((optionName) => optionName === name) || (term.type === "optional" || term.type === "multiple") && hasFlagUsage(term.terms, name) || term.type === "exclusive" && term.terms.some((terms) => hasFlagUsage(terms, name)));
149
+ }
150
+ /** Matches exact options, attached values, and leading bundled flags. */
151
+ function matchesOptionToken(parser, token) {
152
+ if (token == null || token === "--" || !/^[-/+]/.test(token)) return false;
153
+ if (parser.leadingNames.has(token)) return true;
154
+ const slashOption = token.startsWith("/");
155
+ const separator = slashOption ? token.indexOf(":") : token.startsWith("-") ? token.indexOf("=") : -1;
156
+ if (separator > (slashOption ? 0 : 2) && parser.leadingNames.has(token.slice(0, separator))) return true;
157
+ const shortName = token.slice(0, 2);
158
+ return token.length > 2 && /^-[^-]$/.test(shortName) && parser.leadingNames.has(shortName) && hasFlagUsage(parser.usage, shortName);
159
+ }
160
+ const optionMatchKey = Symbol("optionMatch");
161
+ /**
162
+ * Records state-aware option matching without changing public leading names.
163
+ * @param parser The newly constructed transparent parser.
164
+ * @param match Finds a reachable known-option lane.
165
+ * @internal
166
+ */
167
+ function defineOptionMatch(parser, match) {
168
+ Object.defineProperty(parser, optionMatchKey, {
169
+ value: {
170
+ ownerPriority: parser.priority,
171
+ match
172
+ },
173
+ enumerable: true
174
+ });
175
+ }
176
+ /**
177
+ * Finds a matching option's actual priority, including selected command children.
178
+ * @param parser The parser to inspect.
179
+ * @param state Its current state.
180
+ * @param token The current token.
181
+ * @returns A reachable option match, or undefined.
182
+ * @internal
183
+ */
184
+ function getOptionMatch(parser, state, token) {
185
+ if (token == null || token === "--" || !/^[-/+]/.test(token)) return void 0;
186
+ const annotated = parser;
187
+ const matcher = annotated[optionMatchKey];
188
+ if (matcher != null) {
189
+ const match = matcher.match(state, token);
190
+ return match == null || matcher.ownerPriority === parser.priority ? match : {
191
+ ...match,
192
+ priority: parser.priority
193
+ };
194
+ }
195
+ return matchesOptionToken(parser, token) ? {
196
+ priority: parser.priority,
197
+ continuesCommand: false
198
+ } : void 0;
199
+ }
200
+ /**
201
+ * Combines option matches while retaining active command continuation.
202
+ * @param matches Matches from transparent children.
203
+ * @returns Their highest priority and whether any matching command continues.
204
+ * @internal
205
+ */
206
+ function combineOptionMatches(matches) {
207
+ const found = matches.filter((match) => match != null);
208
+ return found.length === 0 ? void 0 : {
209
+ priority: Math.max(...found.map((match) => match.priority)),
210
+ continuesCommand: found.some((match) => match.continuesCommand)
211
+ };
212
+ }
213
+ const knownCompletionKey = Symbol("knownCompletion");
214
+ /** Marks a completion value that can be inspected without running user code. @internal */
215
+ function defineKnownCompletion(parser, value) {
216
+ defineKnownCompletionLookup(parser, (state) => ({ value: value(state) }));
217
+ }
218
+ /** Registers a known-value lookup that may decline unknown completion. @internal */
219
+ function defineKnownCompletionLookup(parser, value) {
220
+ Object.defineProperty(parser, knownCompletionKey, {
221
+ value: {
222
+ complete: parser.complete,
223
+ value
224
+ },
225
+ enumerable: true
226
+ });
227
+ }
228
+ /** Looks up a known value only while the original completion is intact. @internal */
229
+ function getKnownCompletion(parser, state) {
230
+ const annotated = parser;
231
+ const hint = annotated[knownCompletionKey];
232
+ return hint != null && hint.complete === parser.complete ? hint.value(state) : void 0;
233
+ }
234
+ /** Combines the priorities of currently reachable capture lanes. @internal */
235
+ function combinePassThroughPriorities(priorities) {
236
+ const found = priorities.filter((priority) => priority != null);
237
+ return found.length === 0 ? void 0 : Math.max(...found);
238
+ }
239
+ /** Forwards known completion through a state-preserving wrapper. @internal */
240
+ function delegateKnownCompletion(wrapper, inner) {
241
+ Object.defineProperty(wrapper, knownCompletionKey, {
242
+ value: {
243
+ complete: wrapper.complete,
244
+ value: (state) => getKnownCompletion(inner, state)
245
+ },
246
+ enumerable: true
247
+ });
248
+ }
249
+ /**
250
+ * Installs option and capture inspection from one pure child-state selector.
251
+ * Static children retain capture metadata even when no child is selected yet.
252
+ * Selection must not execute parsing, completion, or user callbacks. Potential
253
+ * alternatives remain candidates until parse-time replay or canSkip resolves
254
+ * them; inspection cannot safely predict opaque custom parser callbacks.
255
+ * @internal
256
+ */
257
+ function defineReachableChildren(parser, children, select) {
258
+ defineOptionMatch(parser, (state, token) => combineOptionMatches(select(state).map((child) => {
259
+ const match = getOptionMatch(child.parser, child.state, token);
260
+ return match == null || !child.continuesCommand ? match : {
261
+ ...match,
262
+ continuesCommand: true
263
+ };
264
+ })));
265
+ definePassThroughPriority(parser, children, (state, token) => combinePassThroughPriorities(select(state).map((child) => getPassThroughPriority(child.parser, child.state, token))));
266
+ }
267
+
268
+ //#endregion
269
+ exports.defineKnownCompletion = defineKnownCompletion;
270
+ exports.defineKnownCompletionLookup = defineKnownCompletionLookup;
271
+ exports.definePassThroughPriority = definePassThroughPriority;
272
+ exports.defineReachableChildren = defineReachableChildren;
273
+ exports.delegateKnownCompletion = delegateKnownCompletion;
274
+ exports.getKnownCompletion = getKnownCompletion;
275
+ exports.getOptionMatch = getOptionMatch;
276
+ exports.getPassThroughFailure = getPassThroughFailure;
277
+ exports.getPassThroughFailureHint = getPassThroughFailureHint;
278
+ exports.getPassThroughPriority = getPassThroughPriority;
279
+ exports.hasPassThroughUsage = hasPassThroughUsage;
280
+ exports.matchesOptionToken = matchesOptionToken;
281
+ exports.retainConsumingFailure = retainConsumingFailure;
282
+ exports.retainConsumingFailureHint = retainConsumingFailureHint;
283
+ exports.withPassThroughFailure = withPassThroughFailure;
284
+ exports.withReturnedConsumingFailure = withReturnedConsumingFailure;
@@ -0,0 +1,268 @@
1
+ //#region src/internal/passthrough.ts
2
+ /** Retains the deepest diagnostic and highest matching lane priority. @internal */
3
+ function retainConsumingFailure(current, failure, priority) {
4
+ return {
5
+ failure: current != null && current.failure.consumed >= failure.consumed ? current.failure : failure,
6
+ priority: Math.max(current?.priority ?? -Infinity, priority)
7
+ };
8
+ }
9
+ const passThroughFailure = Symbol("passThroughFailure");
10
+ /**
11
+ * Gets the sibling failure that prevents pass-through capture at this cursor.
12
+ * Stale hints inherited through a successful child do not block later input.
13
+ * @param context The pass-through parser's context.
14
+ * @returns The failure at this cursor, or undefined if capture is allowed.
15
+ * @internal
16
+ */
17
+ function getPassThroughFailure(context, capturePriority$1 = -Infinity) {
18
+ const hinted = context;
19
+ const hint = hinted[passThroughFailure];
20
+ return hint?.buffer === context.buffer && hint.optionsTerminated === context.optionsTerminated && hint.failure.priority >= capturePriority$1 ? hint.failure : void 0;
21
+ }
22
+ /**
23
+ * Carries a sibling's consuming failure into a child parse call. Only
24
+ * passThrough consults the hint; ordinary alternatives may still recover.
25
+ * @param context The child context, without modifying the parent's context.
26
+ * @param failure The deepest matching consuming failure at this input position.
27
+ * @returns A context with a hint for active option-like input, or the original.
28
+ * @internal
29
+ */
30
+ function withPassThroughFailure(context, failure, capturePriority$1 = -Infinity) {
31
+ const incoming = context;
32
+ if (incoming[passThroughFailure]?.own != null) {
33
+ const { own: _own,...hint } = incoming[passThroughFailure];
34
+ const stripped = {
35
+ ...context,
36
+ [passThroughFailure]: hint
37
+ };
38
+ context = stripped;
39
+ }
40
+ const token = context.buffer[0];
41
+ const existing = getPassThroughFailure(context);
42
+ if (existing != null && existing.priority < capturePriority$1) {
43
+ const hinted$1 = context;
44
+ const { [passThroughFailure]: _discarded,...rest } = hinted$1;
45
+ context = rest;
46
+ }
47
+ if (failure == null || failure.failure.consumed < 1 || failure.priority < capturePriority$1 || context.optionsTerminated || token == null || token === "--" || !/^[-/+]/.test(token)) return context;
48
+ const retained = getPassThroughFailure(context);
49
+ const combined = retainConsumingFailure(retained, failure.failure, failure.priority);
50
+ const hinted = {
51
+ ...context,
52
+ [passThroughFailure]: {
53
+ buffer: context.buffer,
54
+ optionsTerminated: context.optionsTerminated,
55
+ failure: combined
56
+ }
57
+ };
58
+ return hinted;
59
+ }
60
+ /** Reads locally originated diagnostics at the same cursor. @internal */
61
+ function getOwnConsumingFailure(context) {
62
+ const hinted = context;
63
+ const hint = hinted[passThroughFailure];
64
+ return hint?.buffer === context.buffer && hint.optionsTerminated === context.optionsTerminated ? hint.own : void 0;
65
+ }
66
+ /**
67
+ * Returns a successful child's local diagnostic to its parent without merging
68
+ * its provenance with an inherited sibling diagnostic. Both share a cursor.
69
+ * @internal
70
+ */
71
+ function withReturnedConsumingFailure(context, failure) {
72
+ const next = withPassThroughFailure(context, failure);
73
+ if (failure == null || getPassThroughFailure(next) == null) return next;
74
+ const token = next.buffer[0];
75
+ if (next.optionsTerminated || token == null || token === "--" || !/^[-/+]/.test(token) || failure.failure.consumed < 1) return next;
76
+ const hinted = next;
77
+ const hint = hinted[passThroughFailure];
78
+ if (hint == null) return next;
79
+ const returned = {
80
+ ...next,
81
+ [passThroughFailure]: {
82
+ ...hint,
83
+ own: failure
84
+ }
85
+ };
86
+ return returned;
87
+ }
88
+ /** Retains a child's own rejected option failure at the parent's cursor. @internal */
89
+ function retainConsumingFailureHint(current, context, next) {
90
+ if (next.buffer !== context.buffer || next.optionsTerminated !== context.optionsTerminated) return current;
91
+ const own = getOwnConsumingFailure(next);
92
+ return own == null || own === getOwnConsumingFailure(context) ? current : retainConsumingFailure(current, own.failure, own.priority);
93
+ }
94
+ const capturePriority = Symbol("capturePriority");
95
+ /** Checks for capture through usage-preserving wrappers. @internal */
96
+ function hasPassThroughUsage(usage) {
97
+ return usage.some((term) => term.type === "passthrough" || (term.type === "optional" || term.type === "multiple") && hasPassThroughUsage(term.terms) || term.type === "exclusive" && term.terms.some(hasPassThroughUsage));
98
+ }
99
+ /**
100
+ * Gets the priority of reachable capture, respecting an explicit override.
101
+ * @param parser The parser whose capture priority is needed.
102
+ * @param state The current parser state.
103
+ * @param token The current token, omitted for an unfiltered priority lookup.
104
+ * @returns The capture priority, or undefined when capture is absent.
105
+ * @internal
106
+ */
107
+ function getPassThroughPriority(parser, state = parser.initialState, token) {
108
+ if (!hasPassThroughUsage(parser.usage)) return void 0;
109
+ const annotated = parser;
110
+ const hint = annotated[capturePriority];
111
+ if (hint == null) return parser.priority;
112
+ const priority = hint.getPriority == null ? hint.priority : hint.getPriority(state, token);
113
+ return priority == null ? void 0 : hint.ownerPriority === parser.priority ? priority : parser.priority;
114
+ }
115
+ /**
116
+ * Records capture priority separately from unrelated children's priorities.
117
+ * @param parser The newly constructed parser.
118
+ * @param children Its transparent children.
119
+ * @param getPriority Optional state-aware capture priority lookup.
120
+ * @internal
121
+ */
122
+ function definePassThroughPriority(parser, children, getPriority) {
123
+ const priorities = children.filter((child) => hasPassThroughUsage(child.usage)).map((child) => getPassThroughPriority(child) ?? child.priority);
124
+ if (priorities.length === 0) return;
125
+ Object.defineProperty(parser, capturePriority, {
126
+ value: {
127
+ ownerPriority: parser.priority,
128
+ priority: Math.max(...priorities),
129
+ getPriority
130
+ },
131
+ enumerable: true
132
+ });
133
+ }
134
+ /**
135
+ * Copies only a cursor-valid hint when rebuilding a child context.
136
+ * @param context The successful child's context.
137
+ * @returns Private hint properties, or an empty object for stale hints.
138
+ * @internal
139
+ */
140
+ function getPassThroughFailureHint(context) {
141
+ const hinted = context;
142
+ const hint = hinted[passThroughFailure];
143
+ return hint != null && getPassThroughFailure(context) != null ? { [passThroughFailure]: hint } : {};
144
+ }
145
+ /** Finds a Boolean option through usage-preserving wrappers. */
146
+ function hasFlagUsage(usage, name) {
147
+ return usage.some((term) => term.type === "option" && term.metavar == null && term.names.some((optionName) => optionName === name) || (term.type === "optional" || term.type === "multiple") && hasFlagUsage(term.terms, name) || term.type === "exclusive" && term.terms.some((terms) => hasFlagUsage(terms, name)));
148
+ }
149
+ /** Matches exact options, attached values, and leading bundled flags. */
150
+ function matchesOptionToken(parser, token) {
151
+ if (token == null || token === "--" || !/^[-/+]/.test(token)) return false;
152
+ if (parser.leadingNames.has(token)) return true;
153
+ const slashOption = token.startsWith("/");
154
+ const separator = slashOption ? token.indexOf(":") : token.startsWith("-") ? token.indexOf("=") : -1;
155
+ if (separator > (slashOption ? 0 : 2) && parser.leadingNames.has(token.slice(0, separator))) return true;
156
+ const shortName = token.slice(0, 2);
157
+ return token.length > 2 && /^-[^-]$/.test(shortName) && parser.leadingNames.has(shortName) && hasFlagUsage(parser.usage, shortName);
158
+ }
159
+ const optionMatchKey = Symbol("optionMatch");
160
+ /**
161
+ * Records state-aware option matching without changing public leading names.
162
+ * @param parser The newly constructed transparent parser.
163
+ * @param match Finds a reachable known-option lane.
164
+ * @internal
165
+ */
166
+ function defineOptionMatch(parser, match) {
167
+ Object.defineProperty(parser, optionMatchKey, {
168
+ value: {
169
+ ownerPriority: parser.priority,
170
+ match
171
+ },
172
+ enumerable: true
173
+ });
174
+ }
175
+ /**
176
+ * Finds a matching option's actual priority, including selected command children.
177
+ * @param parser The parser to inspect.
178
+ * @param state Its current state.
179
+ * @param token The current token.
180
+ * @returns A reachable option match, or undefined.
181
+ * @internal
182
+ */
183
+ function getOptionMatch(parser, state, token) {
184
+ if (token == null || token === "--" || !/^[-/+]/.test(token)) return void 0;
185
+ const annotated = parser;
186
+ const matcher = annotated[optionMatchKey];
187
+ if (matcher != null) {
188
+ const match = matcher.match(state, token);
189
+ return match == null || matcher.ownerPriority === parser.priority ? match : {
190
+ ...match,
191
+ priority: parser.priority
192
+ };
193
+ }
194
+ return matchesOptionToken(parser, token) ? {
195
+ priority: parser.priority,
196
+ continuesCommand: false
197
+ } : void 0;
198
+ }
199
+ /**
200
+ * Combines option matches while retaining active command continuation.
201
+ * @param matches Matches from transparent children.
202
+ * @returns Their highest priority and whether any matching command continues.
203
+ * @internal
204
+ */
205
+ function combineOptionMatches(matches) {
206
+ const found = matches.filter((match) => match != null);
207
+ return found.length === 0 ? void 0 : {
208
+ priority: Math.max(...found.map((match) => match.priority)),
209
+ continuesCommand: found.some((match) => match.continuesCommand)
210
+ };
211
+ }
212
+ const knownCompletionKey = Symbol("knownCompletion");
213
+ /** Marks a completion value that can be inspected without running user code. @internal */
214
+ function defineKnownCompletion(parser, value) {
215
+ defineKnownCompletionLookup(parser, (state) => ({ value: value(state) }));
216
+ }
217
+ /** Registers a known-value lookup that may decline unknown completion. @internal */
218
+ function defineKnownCompletionLookup(parser, value) {
219
+ Object.defineProperty(parser, knownCompletionKey, {
220
+ value: {
221
+ complete: parser.complete,
222
+ value
223
+ },
224
+ enumerable: true
225
+ });
226
+ }
227
+ /** Looks up a known value only while the original completion is intact. @internal */
228
+ function getKnownCompletion(parser, state) {
229
+ const annotated = parser;
230
+ const hint = annotated[knownCompletionKey];
231
+ return hint != null && hint.complete === parser.complete ? hint.value(state) : void 0;
232
+ }
233
+ /** Combines the priorities of currently reachable capture lanes. @internal */
234
+ function combinePassThroughPriorities(priorities) {
235
+ const found = priorities.filter((priority) => priority != null);
236
+ return found.length === 0 ? void 0 : Math.max(...found);
237
+ }
238
+ /** Forwards known completion through a state-preserving wrapper. @internal */
239
+ function delegateKnownCompletion(wrapper, inner) {
240
+ Object.defineProperty(wrapper, knownCompletionKey, {
241
+ value: {
242
+ complete: wrapper.complete,
243
+ value: (state) => getKnownCompletion(inner, state)
244
+ },
245
+ enumerable: true
246
+ });
247
+ }
248
+ /**
249
+ * Installs option and capture inspection from one pure child-state selector.
250
+ * Static children retain capture metadata even when no child is selected yet.
251
+ * Selection must not execute parsing, completion, or user callbacks. Potential
252
+ * alternatives remain candidates until parse-time replay or canSkip resolves
253
+ * them; inspection cannot safely predict opaque custom parser callbacks.
254
+ * @internal
255
+ */
256
+ function defineReachableChildren(parser, children, select) {
257
+ defineOptionMatch(parser, (state, token) => combineOptionMatches(select(state).map((child) => {
258
+ const match = getOptionMatch(child.parser, child.state, token);
259
+ return match == null || !child.continuesCommand ? match : {
260
+ ...match,
261
+ continuesCommand: true
262
+ };
263
+ })));
264
+ definePassThroughPriority(parser, children, (state, token) => combinePassThroughPriorities(select(state).map((child) => getPassThroughPriority(child.parser, child.state, token))));
265
+ }
266
+
267
+ //#endregion
268
+ export { defineKnownCompletion, defineKnownCompletionLookup, definePassThroughPriority, defineReachableChildren, delegateKnownCompletion, getKnownCompletion, getOptionMatch, getPassThroughFailure, getPassThroughFailureHint, getPassThroughPriority, hasPassThroughUsage, matchesOptionToken, retainConsumingFailure, retainConsumingFailureHint, withPassThroughFailure, withReturnedConsumingFailure };