@optique/core 1.0.0-dev.1611 → 1.0.0-dev.1658

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/parser.cjs CHANGED
@@ -1,14 +1,29 @@
1
1
  const require_annotations = require('./annotations.cjs');
2
2
  const require_message = require('./message.cjs');
3
- const require_mode_dispatch = require('./mode-dispatch.cjs');
4
3
  const require_usage = require('./usage.cjs');
5
4
  const require_doc = require('./doc.cjs');
6
- const require_constructs = require('./constructs.cjs');
5
+ const require_mode_dispatch = require('./mode-dispatch.cjs');
6
+ const require_input_trace = require('./input-trace.cjs');
7
7
  const require_modifiers = require('./modifiers.cjs');
8
8
  const require_primitives = require('./primitives.cjs');
9
+ const require_dependency_runtime = require('./dependency-runtime.cjs');
10
+ const require_constructs = require('./constructs.cjs');
9
11
 
10
12
  //#region src/parser.ts
11
13
  /**
14
+ * Internal marker for wrappers whose `{ hasCliValue: false }` states should
15
+ * be treated as unmatched dependency-source states during completion-time
16
+ * Phase 1.
17
+ *
18
+ * Wrappers like `bindEnv()` and `bindConfig()` opt in because their missing
19
+ * CLI states still carry enough fallback context to pre-complete exactly
20
+ * once. Wrappers like `prompt()` intentionally do not opt in because
21
+ * prompted values are not yet registered as dependency sources.
22
+ *
23
+ * @internal
24
+ */
25
+ const unmatchedNonCliDependencySourceStateMarker = Symbol.for("@optique/core/parser/unmatchedNonCliDependencySourceStateMarker");
26
+ /**
12
27
  * Creates a {@link ParserContext} from a {@link ParseFrame} and an
13
28
  * {@link ExecutionContext}. The returned object provides both structured
14
29
  * access (`frame`, `exec`) and flat access (`buffer`, `state`, etc.)
@@ -23,6 +38,7 @@ const require_primitives = require('./primitives.cjs');
23
38
  function createParserContext(frame, exec) {
24
39
  return {
25
40
  exec,
41
+ trace: exec.trace,
26
42
  buffer: frame.buffer,
27
43
  state: frame.state,
28
44
  optionsTerminated: frame.optionsTerminated,
@@ -53,6 +69,8 @@ function injectAnnotationsIntoState(state, options) {
53
69
  * successful or not. If successful, it contains the parsed value of
54
70
  * type `T`. If not, it contains an error message describing the
55
71
  * failure.
72
+ * @throws {TypeError} When a synchronous dependency source extractor returns a
73
+ * thenable during completion-time dependency seeding.
56
74
  * @since 0.9.0 Renamed from the original `parse` function which now delegates
57
75
  * to this for sync parsers.
58
76
  * @since 0.10.0 Added optional `options` parameter for annotations support.
@@ -63,7 +81,8 @@ function parseSync(parser, args, options) {
63
81
  const exec = {
64
82
  usage: parser.usage,
65
83
  phase: "parse",
66
- path: []
84
+ path: [],
85
+ trace: require_input_trace.createInputTrace()
67
86
  };
68
87
  let context = createParserContext({
69
88
  buffer: args,
@@ -83,9 +102,13 @@ function parseSync(parser, args, options) {
83
102
  error: require_message.message`Unexpected option or argument: ${context.buffer[0]}.`
84
103
  };
85
104
  } while (context.buffer.length > 0);
105
+ const runtime = require_dependency_runtime.createDependencyRuntimeContext();
86
106
  const completeExec = {
87
107
  ...exec,
88
- phase: "complete"
108
+ phase: "complete",
109
+ dependencyRuntime: runtime,
110
+ dependencyRegistry: runtime.registry,
111
+ trace: context.exec?.trace ?? context.trace ?? exec.trace
89
112
  };
90
113
  const endResult = parser.complete(context.state, completeExec);
91
114
  return endResult.success ? {
@@ -130,7 +153,8 @@ async function parseAsync(parser, args, options) {
130
153
  const exec = {
131
154
  usage: parser.usage,
132
155
  phase: "parse",
133
- path: []
156
+ path: [],
157
+ trace: require_input_trace.createInputTrace()
134
158
  };
135
159
  let context = createParserContext({
136
160
  buffer: args,
@@ -150,9 +174,13 @@ async function parseAsync(parser, args, options) {
150
174
  error: require_message.message`Unexpected option or argument: ${context.buffer[0]}.`
151
175
  };
152
176
  } while (context.buffer.length > 0);
177
+ const runtime = require_dependency_runtime.createDependencyRuntimeContext();
153
178
  const completeExec = {
154
179
  ...exec,
155
- phase: "complete"
180
+ phase: "complete",
181
+ dependencyRuntime: runtime,
182
+ dependencyRegistry: runtime.registry,
183
+ trace: context.exec?.trace ?? context.trace ?? exec.trace
156
184
  };
157
185
  const endResult = await parser.complete(context.state, completeExec);
158
186
  return endResult.success ? {
@@ -185,6 +213,8 @@ async function parseAsync(parser, args, options) {
185
213
  * @param options Optional {@link ParseOptions} for customizing parsing behavior.
186
214
  * @returns A {@link Result} object (for sync) or Promise thereof (for async)
187
215
  * indicating whether the parsing was successful or not.
216
+ * @throws {TypeError} When a synchronous dependency source extractor returns a
217
+ * thenable during completion-time dependency seeding.
188
218
  * @since 0.10.0 Added optional `options` parameter for annotations support.
189
219
  */
190
220
  function parse(parser, args, options) {
@@ -222,6 +252,8 @@ function parse(parser, args, options) {
222
252
  * const suggestions2 = suggestSync(parser, ["-v", "--format="]);
223
253
  * // Returns: [{ text: "--format=json" }, { text: "--format=yaml" }]
224
254
  * ```
255
+ * @throws {TypeError} When a synchronous dependency source extractor returns a
256
+ * thenable during suggestion seeding.
225
257
  * @since 0.6.0
226
258
  * @since 0.9.0 Renamed from the original `suggest` function.
227
259
  * @since 0.10.0 Added optional `options` parameter for annotations support.
@@ -237,16 +269,71 @@ function suggestSync(parser, args, options) {
237
269
  }, {
238
270
  usage: parser.usage,
239
271
  phase: "suggest",
240
- path: []
272
+ path: [],
273
+ trace: require_input_trace.createInputTrace()
241
274
  });
242
275
  while (context.buffer.length > 0) {
243
276
  const result = parser.parse(context);
244
- if (!result.success) return Array.from(parser.suggest(context, prefix));
277
+ if (!result.success) return Array.from(parser.suggest(withSuggestRuntime(parser, context), prefix));
245
278
  const previousBuffer = context.buffer;
246
279
  context = result.next;
247
280
  if (isBufferUnchanged(previousBuffer, context.buffer)) return [];
248
281
  }
249
- return Array.from(parser.suggest(context, prefix));
282
+ return Array.from(parser.suggest(withSuggestRuntime(parser, context), prefix));
283
+ }
284
+ /**
285
+ * Creates a dependency runtime from the current parser state and returns
286
+ * a context with the populated registry. Used by top-level suggest
287
+ * functions to mirror the construct-owned model where suggest() receives
288
+ * a context with a dependency registry.
289
+ * @internal
290
+ */
291
+ function withSuggestRuntime(parser, context) {
292
+ const runtime = require_dependency_runtime.createDependencyRuntimeContext();
293
+ const nodes = getParserSuggestRuntimeNodes(parser, context.state, context.exec?.path ?? []);
294
+ if (nodes.length > 0) require_dependency_runtime.collectExplicitSourceValues(nodes, runtime);
295
+ return {
296
+ ...context,
297
+ dependencyRegistry: runtime.registry,
298
+ exec: context.exec ? {
299
+ ...context.exec,
300
+ dependencyRuntime: runtime,
301
+ dependencyRegistry: runtime.registry
302
+ } : void 0
303
+ };
304
+ }
305
+ async function withSuggestRuntimeAsync(parser, context) {
306
+ const runtime = require_dependency_runtime.createDependencyRuntimeContext();
307
+ const nodes = getParserSuggestRuntimeNodes(parser, context.state, context.exec?.path ?? []);
308
+ if (nodes.length > 0) await require_dependency_runtime.collectExplicitSourceValuesAsync(nodes, runtime);
309
+ return {
310
+ ...context,
311
+ dependencyRegistry: runtime.registry,
312
+ exec: context.exec ? {
313
+ ...context.exec,
314
+ dependencyRuntime: runtime,
315
+ dependencyRegistry: runtime.registry
316
+ } : void 0
317
+ };
318
+ }
319
+ /**
320
+ * Returns suggest-time runtime nodes for a parser, falling back to the
321
+ * parser's own source metadata when it does not expose a custom hook.
322
+ *
323
+ * @param parser The parser whose suggest-time runtime nodes should be resolved.
324
+ * @param state The current parser state.
325
+ * @param path The path to this parser within the parse tree.
326
+ * @returns The runtime nodes used to seed suggest-time dependency resolution.
327
+ * @internal
328
+ */
329
+ function getParserSuggestRuntimeNodes(parser, state, path) {
330
+ if (typeof parser.getSuggestRuntimeNodes === "function") return parser.getSuggestRuntimeNodes(state, path);
331
+ if (parser.dependencyMetadata?.source == null) return [];
332
+ return [{
333
+ path,
334
+ parser,
335
+ state
336
+ }];
250
337
  }
251
338
  /**
252
339
  * Generates command-line suggestions based on current parsing state.
@@ -279,21 +366,24 @@ async function suggestAsync(parser, args, options) {
279
366
  }, {
280
367
  usage: parser.usage,
281
368
  phase: "suggest",
282
- path: []
369
+ path: [],
370
+ trace: require_input_trace.createInputTrace()
283
371
  });
284
372
  while (context.buffer.length > 0) {
285
373
  const result = await parser.parse(context);
286
374
  if (!result.success) {
375
+ const ctx$1 = await withSuggestRuntimeAsync(parser, context);
287
376
  const suggestions$1 = [];
288
- for await (const suggestion of parser.suggest(context, prefix)) suggestions$1.push(suggestion);
377
+ for await (const suggestion of parser.suggest(ctx$1, prefix)) suggestions$1.push(suggestion);
289
378
  return suggestions$1;
290
379
  }
291
380
  const previousBuffer = context.buffer;
292
381
  context = result.next;
293
382
  if (isBufferUnchanged(previousBuffer, context.buffer)) return [];
294
383
  }
384
+ const ctx = await withSuggestRuntimeAsync(parser, context);
295
385
  const suggestions = [];
296
- for await (const suggestion of parser.suggest(context, prefix)) suggestions.push(suggestion);
386
+ for await (const suggestion of parser.suggest(ctx, prefix)) suggestions.push(suggestion);
297
387
  return suggestions;
298
388
  }
299
389
  /**
@@ -316,6 +406,8 @@ async function suggestAsync(parser, args, options) {
316
406
  * @param options Optional {@link ParseOptions} for customizing parsing behavior.
317
407
  * @returns An array of {@link Suggestion} objects (for sync) or Promise thereof
318
408
  * (for async) containing completion candidates.
409
+ * @throws {TypeError} When a synchronous dependency source extractor returns a
410
+ * thenable during suggestion seeding.
319
411
  * @since 0.6.0
320
412
  * @since 0.10.0 Added optional `options` parameter for annotations support.
321
413
  */
@@ -543,6 +635,7 @@ exports.flag = require_primitives.flag;
543
635
  exports.getDocPage = getDocPage;
544
636
  exports.getDocPageAsync = getDocPageAsync;
545
637
  exports.getDocPageSync = getDocPageSync;
638
+ exports.getParserSuggestRuntimeNodes = getParserSuggestRuntimeNodes;
546
639
  exports.group = require_constructs.group;
547
640
  exports.longestMatch = require_constructs.longestMatch;
548
641
  exports.map = require_modifiers.map;
@@ -561,4 +654,5 @@ exports.suggest = suggest;
561
654
  exports.suggestAsync = suggestAsync;
562
655
  exports.suggestSync = suggestSync;
563
656
  exports.tuple = require_constructs.tuple;
657
+ exports.unmatchedNonCliDependencySourceStateMarker = unmatchedNonCliDependencySourceStateMarker;
564
658
  exports.withDefault = require_modifiers.withDefault;
package/dist/parser.d.cts CHANGED
@@ -5,7 +5,8 @@ import { DocFragments, DocPage } from "./doc.cjs";
5
5
  import { DependencyRegistryLike } from "./registry-types.cjs";
6
6
  import { DeferredMap, ValueParserResult } from "./valueparser.cjs";
7
7
  import { ParserDependencyMetadata } from "./dependency-metadata.cjs";
8
- import { DependencyRuntimeContext } from "./dependency-runtime.cjs";
8
+ import { DependencyRuntimeContext, RuntimeNode } from "./dependency-runtime.cjs";
9
+ import { InputTrace } from "./input-trace.cjs";
9
10
  import { ConditionalErrorOptions, ConditionalOptions, DuplicateOptionError, GroupOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.cjs";
10
11
  import { MultipleErrorOptions, MultipleOptions, WithDefaultError, WithDefaultOptions, map, multiple, nonEmpty, optional, withDefault } from "./modifiers.cjs";
11
12
  import { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, FlagErrorOptions, FlagOptions, OptionErrorOptions, OptionOptions, OptionState, PassThroughFormat, PassThroughOptions, argument, command, constant, fail, flag, option, passThrough } from "./primitives.cjs";
@@ -150,6 +151,14 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
150
151
  * state when parsing starts.
151
152
  */
152
153
  readonly initialState: TState;
154
+ /**
155
+ * Internal marker for wrappers whose `{ hasCliValue: false }` states should
156
+ * be treated as unmatched dependency-source states during completion-time
157
+ * Phase 1.
158
+ *
159
+ * @internal
160
+ */
161
+ readonly [unmatchedNonCliDependencySourceStateMarker]?: true;
153
162
  /**
154
163
  * Parses the input context and returns a result indicating
155
164
  * whether the parsing was successful or not.
@@ -258,9 +267,22 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
258
267
  * capabilities. Used by the dependency runtime to resolve dependencies
259
268
  * without relying on state-shape protocols.
260
269
  * @internal
261
- * @since 1.0.0
262
270
  */
263
271
  readonly dependencyMetadata?: ParserDependencyMetadata;
272
+ /**
273
+ * Internal hook for top-level suggest-time dependency seeding.
274
+ *
275
+ * Wrapper parsers can expose the active parser/state pairs that should be
276
+ * scanned when `suggestSync()` or `suggestAsync()` builds a fresh dependency
277
+ * runtime. When omitted, only this parser's own dependency source metadata
278
+ * is considered.
279
+ *
280
+ * @param state The current parser state.
281
+ * @param path The path to this parser within the parse tree.
282
+ * @returns Runtime nodes to seed into the suggestion-time dependency runtime.
283
+ * @internal
284
+ */
285
+ getSuggestRuntimeNodes?(state: TState, path: readonly PropertyKey[]): readonly RuntimeNode[];
264
286
  }
265
287
  /**
266
288
  * Parser-local frame data containing the input buffer and parser state.
@@ -312,6 +334,16 @@ interface ExecutionContext {
312
334
  * resolution and completion.
313
335
  */
314
336
  readonly path: readonly PropertyKey[];
337
+ /**
338
+ * Immutable trace of raw primitive inputs recorded during parsing.
339
+ *
340
+ * Primitives append trace entries keyed by {@link path}, allowing later
341
+ * completion phases to replay derived parsers with the resolved
342
+ * dependency values.
343
+ *
344
+ * @internal
345
+ */
346
+ readonly trace?: InputTrace;
315
347
  /**
316
348
  * A registry containing resolved dependency values from DependencySource
317
349
  * parsers.
@@ -322,7 +354,6 @@ interface ExecutionContext {
322
354
  * The dependency runtime context for dependency resolution.
323
355
  * Coexists with `dependencyRegistry` during the transition period.
324
356
  * @internal
325
- * @since 1.0.0
326
357
  */
327
358
  readonly dependencyRuntime?: DependencyRuntimeContext;
328
359
  /**
@@ -341,10 +372,33 @@ interface ExecutionContext {
341
372
  *
342
373
  * @see https://github.com/dahlia/optique/issues/762
343
374
  * @internal
344
- * @since 1.0.0
345
375
  */
346
376
  readonly preCompletedByParser?: ReadonlyMap<string | symbol, unknown>;
377
+ /**
378
+ * Field names that should be ignored when a construct seeds dependency
379
+ * sources from child state during completion.
380
+ *
381
+ * Used by outer `merge()` completions to suppress ambiguous duplicate
382
+ * keys while still allowing the child parser to finish its own value
383
+ * completion.
384
+ *
385
+ * @internal
386
+ */
387
+ readonly excludedSourceFields?: ReadonlySet<string | symbol>;
347
388
  }
389
+ /**
390
+ * Internal marker for wrappers whose `{ hasCliValue: false }` states should
391
+ * be treated as unmatched dependency-source states during completion-time
392
+ * Phase 1.
393
+ *
394
+ * Wrappers like `bindEnv()` and `bindConfig()` opt in because their missing
395
+ * CLI states still carry enough fallback context to pre-complete exactly
396
+ * once. Wrappers like `prompt()` intentionally do not opt in because
397
+ * prompted values are not yet registered as dependency sources.
398
+ *
399
+ * @internal
400
+ */
401
+ declare const unmatchedNonCliDependencySourceStateMarker: unique symbol;
348
402
  /**
349
403
  * The context of the parser, which includes the input buffer and the state.
350
404
  *
@@ -364,6 +418,15 @@ interface ParserContext<TState> {
364
418
  * @since 1.0.0
365
419
  */
366
420
  readonly exec?: ExecutionContext;
421
+ /**
422
+ * Immutable trace of raw primitive inputs recorded during parsing.
423
+ *
424
+ * Preserved as a flat compatibility field so wrapper parsers can forward
425
+ * trace data even when they rebuild the parser context without {@link exec}.
426
+ *
427
+ * @since 1.0.0
428
+ */
429
+ readonly trace?: InputTrace;
367
430
  /**
368
431
  * The array of input strings that the parser is currently processing.
369
432
  */
@@ -557,6 +620,8 @@ type Result<T> = {
557
620
  * successful or not. If successful, it contains the parsed value of
558
621
  * type `T`. If not, it contains an error message describing the
559
622
  * failure.
623
+ * @throws {TypeError} When a synchronous dependency source extractor returns a
624
+ * thenable during completion-time dependency seeding.
560
625
  * @since 0.9.0 Renamed from the original `parse` function which now delegates
561
626
  * to this for sync parsers.
562
627
  * @since 0.10.0 Added optional `options` parameter for annotations support.
@@ -602,6 +667,8 @@ declare function parseAsync<T>(parser: Parser<Mode, T, unknown>, args: readonly
602
667
  * @param options Optional {@link ParseOptions} for customizing parsing behavior.
603
668
  * @returns A {@link Result} object (for sync) or Promise thereof (for async)
604
669
  * indicating whether the parsing was successful or not.
670
+ * @throws {TypeError} When a synchronous dependency source extractor returns a
671
+ * thenable during completion-time dependency seeding.
605
672
  * @since 0.10.0 Added optional `options` parameter for annotations support.
606
673
  */
607
674
  declare function parse<M extends Mode, T>(parser: Parser<M, T, unknown>, args: readonly string[], options?: ParseOptions): ModeValue<M, Result<T>>;
@@ -637,11 +704,24 @@ declare function parse<M extends Mode, T>(parser: Parser<M, T, unknown>, args: r
637
704
  * const suggestions2 = suggestSync(parser, ["-v", "--format="]);
638
705
  * // Returns: [{ text: "--format=json" }, { text: "--format=yaml" }]
639
706
  * ```
707
+ * @throws {TypeError} When a synchronous dependency source extractor returns a
708
+ * thenable during suggestion seeding.
640
709
  * @since 0.6.0
641
710
  * @since 0.9.0 Renamed from the original `suggest` function.
642
711
  * @since 0.10.0 Added optional `options` parameter for annotations support.
643
712
  */
644
713
  declare function suggestSync<T>(parser: Parser<"sync", T, unknown>, args: readonly [string, ...readonly string[]], options?: ParseOptions): readonly Suggestion[];
714
+ /**
715
+ * Returns suggest-time runtime nodes for a parser, falling back to the
716
+ * parser's own source metadata when it does not expose a custom hook.
717
+ *
718
+ * @param parser The parser whose suggest-time runtime nodes should be resolved.
719
+ * @param state The current parser state.
720
+ * @param path The path to this parser within the parse tree.
721
+ * @returns The runtime nodes used to seed suggest-time dependency resolution.
722
+ * @internal
723
+ */
724
+ declare function getParserSuggestRuntimeNodes<TState>(parser: Parser<Mode, unknown, TState>, state: TState, path: readonly PropertyKey[]): readonly RuntimeNode[];
645
725
  /**
646
726
  * Generates command-line suggestions based on current parsing state.
647
727
  * This function processes the input arguments up to the last argument,
@@ -683,6 +763,8 @@ declare function suggestAsync<T>(parser: Parser<Mode, T, unknown>, args: readonl
683
763
  * @param options Optional {@link ParseOptions} for customizing parsing behavior.
684
764
  * @returns An array of {@link Suggestion} objects (for sync) or Promise thereof
685
765
  * (for async) containing completion candidates.
766
+ * @throws {TypeError} When a synchronous dependency source extractor returns a
767
+ * thenable during suggestion seeding.
686
768
  * @since 0.6.0
687
769
  * @since 0.10.0 Added optional `options` parameter for annotations support.
688
770
  */
@@ -774,4 +856,4 @@ declare function getDocPage(parser: Parser<"sync", unknown, unknown>, argsOrOpti
774
856
  declare function getDocPage(parser: Parser<"async", unknown, unknown>, argsOrOptions?: readonly string[] | ParseOptions, options?: ParseOptions): Promise<DocPage | undefined>;
775
857
  declare function getDocPage<M extends Mode>(parser: Parser<M, unknown, unknown>, argsOrOptions?: readonly string[] | ParseOptions, options?: ParseOptions): ModeValue<M, DocPage | undefined>;
776
858
  //#endregion
777
- export { ArgumentErrorOptions, ArgumentOptions, CombineModes, CommandErrorOptions, CommandOptions, ConditionalErrorOptions, ConditionalOptions, DocState, DuplicateOptionError, ExecutionContext, ExecutionPhase, FlagErrorOptions, FlagOptions, GroupOptions, InferMode, InferValue, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionOptions, OptionState, OrErrorOptions, OrOptions, ParseFrame, type ParseOptions, Parser, ParserContext, ParserResult, PassThroughFormat, PassThroughOptions, Result, Suggestion, TupleOptions, WithDefaultError, WithDefaultOptions, argument, command, concat, conditional, constant, createParserContext, fail, flag, getDocPage, getDocPageAsync, getDocPageSync, group, longestMatch, map, merge, multiple, nonEmpty, object, option, optional, or, parse, parseAsync, parseSync, passThrough, suggest, suggestAsync, suggestSync, tuple, withDefault };
859
+ export { ArgumentErrorOptions, ArgumentOptions, CombineModes, CommandErrorOptions, CommandOptions, ConditionalErrorOptions, ConditionalOptions, DocState, DuplicateOptionError, ExecutionContext, ExecutionPhase, FlagErrorOptions, FlagOptions, GroupOptions, InferMode, InferValue, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionOptions, OptionState, OrErrorOptions, OrOptions, ParseFrame, type ParseOptions, Parser, ParserContext, ParserResult, PassThroughFormat, PassThroughOptions, Result, Suggestion, TupleOptions, WithDefaultError, WithDefaultOptions, argument, command, concat, conditional, constant, createParserContext, fail, flag, getDocPage, getDocPageAsync, getDocPageSync, getParserSuggestRuntimeNodes, group, longestMatch, map, merge, multiple, nonEmpty, object, option, optional, or, parse, parseAsync, parseSync, passThrough, suggest, suggestAsync, suggestSync, tuple, unmatchedNonCliDependencySourceStateMarker, withDefault };
package/dist/parser.d.ts CHANGED
@@ -5,7 +5,8 @@ import { DocFragments, DocPage } from "./doc.js";
5
5
  import { DependencyRegistryLike } from "./registry-types.js";
6
6
  import { DeferredMap, ValueParserResult } from "./valueparser.js";
7
7
  import { ParserDependencyMetadata } from "./dependency-metadata.js";
8
- import { DependencyRuntimeContext } from "./dependency-runtime.js";
8
+ import { DependencyRuntimeContext, RuntimeNode } from "./dependency-runtime.js";
9
+ import { InputTrace } from "./input-trace.js";
9
10
  import { ConditionalErrorOptions, ConditionalOptions, DuplicateOptionError, GroupOptions, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OrErrorOptions, OrOptions, TupleOptions, concat, conditional, group, longestMatch, merge, object, or, tuple } from "./constructs.js";
10
11
  import { MultipleErrorOptions, MultipleOptions, WithDefaultError, WithDefaultOptions, map, multiple, nonEmpty, optional, withDefault } from "./modifiers.js";
11
12
  import { ArgumentErrorOptions, ArgumentOptions, CommandErrorOptions, CommandOptions, FlagErrorOptions, FlagOptions, OptionErrorOptions, OptionOptions, OptionState, PassThroughFormat, PassThroughOptions, argument, command, constant, fail, flag, option, passThrough } from "./primitives.js";
@@ -150,6 +151,14 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
150
151
  * state when parsing starts.
151
152
  */
152
153
  readonly initialState: TState;
154
+ /**
155
+ * Internal marker for wrappers whose `{ hasCliValue: false }` states should
156
+ * be treated as unmatched dependency-source states during completion-time
157
+ * Phase 1.
158
+ *
159
+ * @internal
160
+ */
161
+ readonly [unmatchedNonCliDependencySourceStateMarker]?: true;
153
162
  /**
154
163
  * Parses the input context and returns a result indicating
155
164
  * whether the parsing was successful or not.
@@ -258,9 +267,22 @@ interface Parser<M extends Mode = "sync", TValue = unknown, TState = unknown> {
258
267
  * capabilities. Used by the dependency runtime to resolve dependencies
259
268
  * without relying on state-shape protocols.
260
269
  * @internal
261
- * @since 1.0.0
262
270
  */
263
271
  readonly dependencyMetadata?: ParserDependencyMetadata;
272
+ /**
273
+ * Internal hook for top-level suggest-time dependency seeding.
274
+ *
275
+ * Wrapper parsers can expose the active parser/state pairs that should be
276
+ * scanned when `suggestSync()` or `suggestAsync()` builds a fresh dependency
277
+ * runtime. When omitted, only this parser's own dependency source metadata
278
+ * is considered.
279
+ *
280
+ * @param state The current parser state.
281
+ * @param path The path to this parser within the parse tree.
282
+ * @returns Runtime nodes to seed into the suggestion-time dependency runtime.
283
+ * @internal
284
+ */
285
+ getSuggestRuntimeNodes?(state: TState, path: readonly PropertyKey[]): readonly RuntimeNode[];
264
286
  }
265
287
  /**
266
288
  * Parser-local frame data containing the input buffer and parser state.
@@ -312,6 +334,16 @@ interface ExecutionContext {
312
334
  * resolution and completion.
313
335
  */
314
336
  readonly path: readonly PropertyKey[];
337
+ /**
338
+ * Immutable trace of raw primitive inputs recorded during parsing.
339
+ *
340
+ * Primitives append trace entries keyed by {@link path}, allowing later
341
+ * completion phases to replay derived parsers with the resolved
342
+ * dependency values.
343
+ *
344
+ * @internal
345
+ */
346
+ readonly trace?: InputTrace;
315
347
  /**
316
348
  * A registry containing resolved dependency values from DependencySource
317
349
  * parsers.
@@ -322,7 +354,6 @@ interface ExecutionContext {
322
354
  * The dependency runtime context for dependency resolution.
323
355
  * Coexists with `dependencyRegistry` during the transition period.
324
356
  * @internal
325
- * @since 1.0.0
326
357
  */
327
358
  readonly dependencyRuntime?: DependencyRuntimeContext;
328
359
  /**
@@ -341,10 +372,33 @@ interface ExecutionContext {
341
372
  *
342
373
  * @see https://github.com/dahlia/optique/issues/762
343
374
  * @internal
344
- * @since 1.0.0
345
375
  */
346
376
  readonly preCompletedByParser?: ReadonlyMap<string | symbol, unknown>;
377
+ /**
378
+ * Field names that should be ignored when a construct seeds dependency
379
+ * sources from child state during completion.
380
+ *
381
+ * Used by outer `merge()` completions to suppress ambiguous duplicate
382
+ * keys while still allowing the child parser to finish its own value
383
+ * completion.
384
+ *
385
+ * @internal
386
+ */
387
+ readonly excludedSourceFields?: ReadonlySet<string | symbol>;
347
388
  }
389
+ /**
390
+ * Internal marker for wrappers whose `{ hasCliValue: false }` states should
391
+ * be treated as unmatched dependency-source states during completion-time
392
+ * Phase 1.
393
+ *
394
+ * Wrappers like `bindEnv()` and `bindConfig()` opt in because their missing
395
+ * CLI states still carry enough fallback context to pre-complete exactly
396
+ * once. Wrappers like `prompt()` intentionally do not opt in because
397
+ * prompted values are not yet registered as dependency sources.
398
+ *
399
+ * @internal
400
+ */
401
+ declare const unmatchedNonCliDependencySourceStateMarker: unique symbol;
348
402
  /**
349
403
  * The context of the parser, which includes the input buffer and the state.
350
404
  *
@@ -364,6 +418,15 @@ interface ParserContext<TState> {
364
418
  * @since 1.0.0
365
419
  */
366
420
  readonly exec?: ExecutionContext;
421
+ /**
422
+ * Immutable trace of raw primitive inputs recorded during parsing.
423
+ *
424
+ * Preserved as a flat compatibility field so wrapper parsers can forward
425
+ * trace data even when they rebuild the parser context without {@link exec}.
426
+ *
427
+ * @since 1.0.0
428
+ */
429
+ readonly trace?: InputTrace;
367
430
  /**
368
431
  * The array of input strings that the parser is currently processing.
369
432
  */
@@ -557,6 +620,8 @@ type Result<T> = {
557
620
  * successful or not. If successful, it contains the parsed value of
558
621
  * type `T`. If not, it contains an error message describing the
559
622
  * failure.
623
+ * @throws {TypeError} When a synchronous dependency source extractor returns a
624
+ * thenable during completion-time dependency seeding.
560
625
  * @since 0.9.0 Renamed from the original `parse` function which now delegates
561
626
  * to this for sync parsers.
562
627
  * @since 0.10.0 Added optional `options` parameter for annotations support.
@@ -602,6 +667,8 @@ declare function parseAsync<T>(parser: Parser<Mode, T, unknown>, args: readonly
602
667
  * @param options Optional {@link ParseOptions} for customizing parsing behavior.
603
668
  * @returns A {@link Result} object (for sync) or Promise thereof (for async)
604
669
  * indicating whether the parsing was successful or not.
670
+ * @throws {TypeError} When a synchronous dependency source extractor returns a
671
+ * thenable during completion-time dependency seeding.
605
672
  * @since 0.10.0 Added optional `options` parameter for annotations support.
606
673
  */
607
674
  declare function parse<M extends Mode, T>(parser: Parser<M, T, unknown>, args: readonly string[], options?: ParseOptions): ModeValue<M, Result<T>>;
@@ -637,11 +704,24 @@ declare function parse<M extends Mode, T>(parser: Parser<M, T, unknown>, args: r
637
704
  * const suggestions2 = suggestSync(parser, ["-v", "--format="]);
638
705
  * // Returns: [{ text: "--format=json" }, { text: "--format=yaml" }]
639
706
  * ```
707
+ * @throws {TypeError} When a synchronous dependency source extractor returns a
708
+ * thenable during suggestion seeding.
640
709
  * @since 0.6.0
641
710
  * @since 0.9.0 Renamed from the original `suggest` function.
642
711
  * @since 0.10.0 Added optional `options` parameter for annotations support.
643
712
  */
644
713
  declare function suggestSync<T>(parser: Parser<"sync", T, unknown>, args: readonly [string, ...readonly string[]], options?: ParseOptions): readonly Suggestion[];
714
+ /**
715
+ * Returns suggest-time runtime nodes for a parser, falling back to the
716
+ * parser's own source metadata when it does not expose a custom hook.
717
+ *
718
+ * @param parser The parser whose suggest-time runtime nodes should be resolved.
719
+ * @param state The current parser state.
720
+ * @param path The path to this parser within the parse tree.
721
+ * @returns The runtime nodes used to seed suggest-time dependency resolution.
722
+ * @internal
723
+ */
724
+ declare function getParserSuggestRuntimeNodes<TState>(parser: Parser<Mode, unknown, TState>, state: TState, path: readonly PropertyKey[]): readonly RuntimeNode[];
645
725
  /**
646
726
  * Generates command-line suggestions based on current parsing state.
647
727
  * This function processes the input arguments up to the last argument,
@@ -683,6 +763,8 @@ declare function suggestAsync<T>(parser: Parser<Mode, T, unknown>, args: readonl
683
763
  * @param options Optional {@link ParseOptions} for customizing parsing behavior.
684
764
  * @returns An array of {@link Suggestion} objects (for sync) or Promise thereof
685
765
  * (for async) containing completion candidates.
766
+ * @throws {TypeError} When a synchronous dependency source extractor returns a
767
+ * thenable during suggestion seeding.
686
768
  * @since 0.6.0
687
769
  * @since 0.10.0 Added optional `options` parameter for annotations support.
688
770
  */
@@ -774,4 +856,4 @@ declare function getDocPage(parser: Parser<"sync", unknown, unknown>, argsOrOpti
774
856
  declare function getDocPage(parser: Parser<"async", unknown, unknown>, argsOrOptions?: readonly string[] | ParseOptions, options?: ParseOptions): Promise<DocPage | undefined>;
775
857
  declare function getDocPage<M extends Mode>(parser: Parser<M, unknown, unknown>, argsOrOptions?: readonly string[] | ParseOptions, options?: ParseOptions): ModeValue<M, DocPage | undefined>;
776
858
  //#endregion
777
- export { ArgumentErrorOptions, ArgumentOptions, CombineModes, CommandErrorOptions, CommandOptions, ConditionalErrorOptions, ConditionalOptions, DocState, DuplicateOptionError, ExecutionContext, ExecutionPhase, FlagErrorOptions, FlagOptions, GroupOptions, InferMode, InferValue, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionOptions, OptionState, OrErrorOptions, OrOptions, ParseFrame, type ParseOptions, Parser, ParserContext, ParserResult, PassThroughFormat, PassThroughOptions, Result, Suggestion, TupleOptions, WithDefaultError, WithDefaultOptions, argument, command, concat, conditional, constant, createParserContext, fail, flag, getDocPage, getDocPageAsync, getDocPageSync, group, longestMatch, map, merge, multiple, nonEmpty, object, option, optional, or, parse, parseAsync, parseSync, passThrough, suggest, suggestAsync, suggestSync, tuple, withDefault };
859
+ export { ArgumentErrorOptions, ArgumentOptions, CombineModes, CommandErrorOptions, CommandOptions, ConditionalErrorOptions, ConditionalOptions, DocState, DuplicateOptionError, ExecutionContext, ExecutionPhase, FlagErrorOptions, FlagOptions, GroupOptions, InferMode, InferValue, LongestMatchErrorOptions, LongestMatchOptions, MergeOptions, Mode, ModeIterable, ModeValue, MultipleErrorOptions, MultipleOptions, NoMatchContext, ObjectErrorOptions, ObjectOptions, OptionErrorOptions, OptionOptions, OptionState, OrErrorOptions, OrOptions, ParseFrame, type ParseOptions, Parser, ParserContext, ParserResult, PassThroughFormat, PassThroughOptions, Result, Suggestion, TupleOptions, WithDefaultError, WithDefaultOptions, argument, command, concat, conditional, constant, createParserContext, fail, flag, getDocPage, getDocPageAsync, getDocPageSync, getParserSuggestRuntimeNodes, group, longestMatch, map, merge, multiple, nonEmpty, object, option, optional, or, parse, parseAsync, parseSync, passThrough, suggest, suggestAsync, suggestSync, tuple, unmatchedNonCliDependencySourceStateMarker, withDefault };