@optique/core 1.1.0-dev.2006 → 1.1.0-dev.2053

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/facade.js CHANGED
@@ -2,12 +2,12 @@ import { injectAnnotations, isInjectedAnnotationWrapper, unwrapInjectedAnnotatio
2
2
  import { commandLine, formatMessage, lineBreak, message, optionName, text, value } from "./message.js";
3
3
  import { bash, fish, nu, pwsh, zsh } from "./completion.js";
4
4
  import { validateCommandNames, validateContextIds, validateMetaNameCollisions, validateOptionNames, validateProgramName } from "./validate.js";
5
- import { formatUsage } from "./usage.js";
5
+ import { formatUsage, isSuggestionHidden } from "./usage.js";
6
6
  import { formatDocPage } from "./doc.js";
7
7
  import { dispatchByMode } from "./internal/mode-dispatch.js";
8
- import { createDependencyRuntimeContext } from "./dependency-runtime.js";
8
+ import { collectExplicitSourceValues, collectExplicitSourceValuesAsync, createDependencyRuntimeContext } from "./dependency-runtime.js";
9
9
  import { createInputTrace } from "./input-trace.js";
10
- import { createParserContext, getDocPage, suggest, suggestAsync } from "./internal/parser.js";
10
+ import { createParserContext, getDocPage } from "./internal/parser.js";
11
11
  import { completeOrExtractPhase2Seed } from "./phase2-seed.js";
12
12
  import { group, longestMatch, object } from "./constructs.js";
13
13
  import { multiple, optional, withDefault } from "./modifiers.js";
@@ -384,162 +384,42 @@ function createCompletionParser(programName, availableShells, commandConfig, opt
384
384
  completionOption
385
385
  };
386
386
  }
387
- function combineWithHelpVersion(originalParser, helpParsers, versionParsers, completionParsers, groups, helpOptionNames, versionOptionNames) {
387
+ function createMetaOptionDocParser(source) {
388
+ return {
389
+ mode: "sync",
390
+ $valueType: [],
391
+ $stateType: [],
392
+ priority: 200,
393
+ usage: source.usage,
394
+ leadingNames: source.leadingNames,
395
+ acceptingAnyToken: false,
396
+ initialState: null,
397
+ parse: () => ({
398
+ success: false,
399
+ error: message`Documentation-only meta option.`,
400
+ consumed: 0
401
+ }),
402
+ complete: (state) => ({
403
+ success: true,
404
+ value: state
405
+ }),
406
+ suggest: function* () {},
407
+ getDocFragments: (_state, defaultValue) => source.getDocFragments({
408
+ kind: "available",
409
+ state: source.initialState
410
+ }, defaultValue)
411
+ };
412
+ }
413
+ function combineWithHelpVersion(originalParser, helpParsers, versionParsers, completionParsers, groups) {
388
414
  const parsers = [];
389
- const effectiveHelpOptionNames = helpOptionNames ?? ["--help"];
390
- const effectiveVersionOptionNames = versionOptionNames ?? ["--version"];
391
415
  if (helpParsers.helpOption) {
392
- const lenientHelpParser = {
393
- mode: "sync",
394
- $valueType: [],
395
- $stateType: [],
396
- priority: 200,
397
- usage: helpParsers.helpOption.usage,
398
- leadingNames: helpParsers.helpOption.leadingNames,
399
- acceptingAnyToken: false,
400
- initialState: null,
401
- parse(context) {
402
- const { buffer, optionsTerminated } = context;
403
- if (optionsTerminated) return {
404
- success: false,
405
- error: message`Options terminated.`,
406
- consumed: 0
407
- };
408
- let helpFound = false;
409
- let helpIndex = -1;
410
- let versionIndex = -1;
411
- for (let i = 0; i < buffer.length; i++) {
412
- if (buffer[i] === "--") break;
413
- if (effectiveHelpOptionNames.includes(buffer[i])) {
414
- helpFound = true;
415
- helpIndex = i;
416
- }
417
- if (effectiveVersionOptionNames.includes(buffer[i])) versionIndex = i;
418
- }
419
- if (helpFound && versionIndex > helpIndex) return {
420
- success: false,
421
- error: message`Version option wins.`,
422
- consumed: 0
423
- };
424
- if (helpFound) {
425
- const commands = [];
426
- for (let i = 0; i < helpIndex; i++) {
427
- const arg = buffer[i];
428
- if (!arg.startsWith("-")) commands.push(arg);
429
- }
430
- return {
431
- success: true,
432
- next: {
433
- ...context,
434
- buffer: [],
435
- state: {
436
- [metaResultBrand]: true,
437
- help: true,
438
- version: false,
439
- completion: false,
440
- commands,
441
- helpFlag: true
442
- }
443
- },
444
- consumed: buffer.slice(0)
445
- };
446
- }
447
- return {
448
- success: false,
449
- error: message`Flag ${optionName(effectiveHelpOptionNames[0])} not found.`,
450
- consumed: 0
451
- };
452
- },
453
- complete(state) {
454
- return {
455
- success: true,
456
- value: state
457
- };
458
- },
459
- *suggest(_context, prefix) {
460
- for (const name of effectiveHelpOptionNames) if (name.startsWith(prefix)) yield {
461
- kind: "literal",
462
- text: name
463
- };
464
- },
465
- getDocFragments(state) {
466
- return helpParsers.helpOption?.getDocFragments(state) ?? { fragments: [] };
467
- }
468
- };
469
- const wrappedHelp = groups?.helpOptionGroup ? group(groups.helpOptionGroup, lenientHelpParser) : lenientHelpParser;
416
+ const helpOptionDocParser = createMetaOptionDocParser(helpParsers.helpOption);
417
+ const wrappedHelp = groups?.helpOptionGroup ? group(groups.helpOptionGroup, helpOptionDocParser) : helpOptionDocParser;
470
418
  parsers.push(wrappedHelp);
471
419
  }
472
420
  if (versionParsers.versionOption) {
473
- const lenientVersionParser = {
474
- mode: "sync",
475
- $valueType: [],
476
- $stateType: [],
477
- priority: 200,
478
- usage: versionParsers.versionOption.usage,
479
- leadingNames: versionParsers.versionOption.leadingNames,
480
- acceptingAnyToken: false,
481
- initialState: null,
482
- parse(context) {
483
- const { buffer, optionsTerminated } = context;
484
- if (optionsTerminated) return {
485
- success: false,
486
- error: message`Options terminated.`,
487
- consumed: 0
488
- };
489
- let versionFound = false;
490
- let versionIndex = -1;
491
- let helpIndex = -1;
492
- for (let i = 0; i < buffer.length; i++) {
493
- if (buffer[i] === "--") break;
494
- if (effectiveVersionOptionNames.includes(buffer[i])) {
495
- versionFound = true;
496
- versionIndex = i;
497
- }
498
- if (effectiveHelpOptionNames.includes(buffer[i])) helpIndex = i;
499
- }
500
- if (versionFound && helpIndex > versionIndex) return {
501
- success: false,
502
- error: message`Help option wins.`,
503
- consumed: 0
504
- };
505
- if (versionFound) return {
506
- success: true,
507
- next: {
508
- ...context,
509
- buffer: [],
510
- state: {
511
- [metaResultBrand]: true,
512
- help: false,
513
- version: true,
514
- completion: false,
515
- versionFlag: true
516
- }
517
- },
518
- consumed: buffer.slice(0)
519
- };
520
- return {
521
- success: false,
522
- error: message`Flag ${optionName(effectiveVersionOptionNames[0])} not found.`,
523
- consumed: 0
524
- };
525
- },
526
- complete(state) {
527
- return {
528
- success: true,
529
- value: state
530
- };
531
- },
532
- *suggest(_context, prefix) {
533
- for (const name of effectiveVersionOptionNames) if (name.startsWith(prefix)) yield {
534
- kind: "literal",
535
- text: name
536
- };
537
- },
538
- getDocFragments(state) {
539
- return versionParsers.versionOption?.getDocFragments(state) ?? { fragments: [] };
540
- }
541
- };
542
- const wrappedVersion = groups?.versionOptionGroup ? group(groups.versionOptionGroup, lenientVersionParser) : lenientVersionParser;
421
+ const versionOptionDocParser = createMetaOptionDocParser(versionParsers.versionOption);
422
+ const wrappedVersion = groups?.versionOptionGroup ? group(groups.versionOptionGroup, versionOptionDocParser) : versionOptionDocParser;
543
423
  parsers.push(wrappedVersion);
544
424
  }
545
425
  if (versionParsers.versionCommand) {
@@ -717,7 +597,7 @@ function classifyParseFailure(failure, helpOptionNames, helpCommandNames, versio
717
597
  * Handles shell completion requests.
718
598
  * @since 0.6.0
719
599
  */
720
- function handleCompletion(completionArgs, programName, parser, completionParser, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth, completionCommandDisplayName, completionOptionDisplayName, isOptionMode, sectionOrder) {
600
+ function handleCompletion(completionArgs, programName, parser, completionParser, stdout, stderr, onCompletion, onError, availableShells, colors, maxWidth, completionCommandDisplayName, completionOptionDisplayName, isOptionMode, sectionOrder, rootOptionSuggestions = []) {
721
601
  const shellName = completionArgs[0] || "";
722
602
  const args = completionArgs.slice(1);
723
603
  const callOnError = (code) => onError(code);
@@ -768,17 +648,248 @@ function handleCompletion(completionArgs, programName, parser, completionParser,
768
648
  }
769
649
  return dispatchByMode(parser.mode, () => {
770
650
  const syncParser = parser;
771
- const suggestions = suggest(syncParser, args);
651
+ const completionSuggestions = getSyncCompletionSuggestions(syncParser, args, rootOptionSuggestions);
652
+ const suggestions = withRootOptionSuggestions(completionSuggestions.suggestions, args, rootOptionSuggestions, completionSuggestions.argumentContext);
772
653
  for (const chunk of shell.encodeSuggestions(suggestions)) stdout(chunk);
773
654
  const result = callOnCompletion(0);
774
655
  if (result instanceof Promise) throw new RunParserError("Synchronous parser returned async result.");
775
656
  return result;
776
657
  }, async () => {
777
- const suggestions = await suggestAsync(parser, args);
778
- for (const chunk of shell.encodeSuggestions(suggestions)) stdout(chunk);
658
+ const asyncParser = parser;
659
+ const completionSuggestions = await getAsyncCompletionSuggestions(asyncParser, args, rootOptionSuggestions);
660
+ for (const chunk of shell.encodeSuggestions(withRootOptionSuggestions(completionSuggestions.suggestions, args, rootOptionSuggestions, completionSuggestions.argumentContext))) stdout(chunk);
779
661
  return callOnCompletion(0);
780
662
  });
781
663
  }
664
+ function withRootOptionSuggestions(suggestions, args, extraSuggestions, argumentContext) {
665
+ if (extraSuggestions.length === 0) return suggestions;
666
+ const prefix = args.at(-1) ?? "";
667
+ if (argumentContext.optionsTerminated) return suggestions;
668
+ if (argumentContext.completingOptionValue) return suggestions;
669
+ if (argumentContext.completedRootOption) return suggestions;
670
+ if (!(prefix === "" || prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/") || prefix.startsWith("+"))) return suggestions;
671
+ const seen = new Set(suggestions.flatMap((suggestion) => suggestion.kind === "literal" ? [suggestion.text] : []));
672
+ const combined = [...suggestions];
673
+ for (const suggestion of extraSuggestions) {
674
+ if (prefix === "-" && suggestion.text.startsWith("--")) continue;
675
+ if (prefix !== "" && !suggestion.text.startsWith(prefix)) continue;
676
+ if (seen.has(suggestion.text)) continue;
677
+ combined.push(suggestion);
678
+ seen.add(suggestion.text);
679
+ }
680
+ return combined;
681
+ }
682
+ function getSyncCompletionSuggestions(parser, args, rootOptionSuggestions) {
683
+ const prefix = args.at(-1) ?? "";
684
+ let context = createCompletionArgumentParserContext(parser, args.slice(0, -1));
685
+ while (context.buffer.length > 0) {
686
+ const result = parser.parse(context);
687
+ if (result instanceof Promise) throw new RunParserError("Synchronous parser returned async result.");
688
+ if (!result.success) {
689
+ const argumentContext = getFailedCompletionArgumentContext(result, context, parser, rootOptionSuggestions);
690
+ return {
691
+ suggestions: Array.from(parser.suggest(withCompletionSuggestRuntime(parser, context), prefix)),
692
+ argumentContext
693
+ };
694
+ }
695
+ const previousBuffer = context.buffer;
696
+ context = result.next;
697
+ if (isCompletionBufferUnchanged(previousBuffer, context.buffer)) return {
698
+ suggestions: [],
699
+ argumentContext: getCompletedCompletionArgumentContext(context)
700
+ };
701
+ }
702
+ return {
703
+ suggestions: Array.from(parser.suggest(withCompletionSuggestRuntime(parser, context), prefix)),
704
+ argumentContext: getCompletedCompletionArgumentContext(context)
705
+ };
706
+ }
707
+ async function getAsyncCompletionSuggestions(parser, args, rootOptionSuggestions) {
708
+ const prefix = args.at(-1) ?? "";
709
+ let context = createCompletionArgumentParserContext(parser, args.slice(0, -1));
710
+ while (context.buffer.length > 0) {
711
+ const result = await parser.parse(context);
712
+ if (!result.success) {
713
+ const argumentContext = getFailedCompletionArgumentContext(result, context, parser, rootOptionSuggestions);
714
+ const suggestions$1 = [];
715
+ const suggestContext$1 = await withCompletionSuggestRuntimeAsync(parser, context);
716
+ for await (const suggestion of parser.suggest(suggestContext$1, prefix)) suggestions$1.push(suggestion);
717
+ return {
718
+ suggestions: suggestions$1,
719
+ argumentContext
720
+ };
721
+ }
722
+ const previousBuffer = context.buffer;
723
+ context = result.next;
724
+ if (isCompletionBufferUnchanged(previousBuffer, context.buffer)) return {
725
+ suggestions: [],
726
+ argumentContext: getCompletedCompletionArgumentContext(context)
727
+ };
728
+ }
729
+ const suggestions = [];
730
+ const suggestContext = await withCompletionSuggestRuntimeAsync(parser, context);
731
+ for await (const suggestion of parser.suggest(suggestContext, prefix)) suggestions.push(suggestion);
732
+ return {
733
+ suggestions,
734
+ argumentContext: getCompletedCompletionArgumentContext(context)
735
+ };
736
+ }
737
+ function getCompletedCompletionArgumentContext(context) {
738
+ return {
739
+ completingOptionValue: false,
740
+ completedRootOption: false,
741
+ optionsTerminated: context.optionsTerminated
742
+ };
743
+ }
744
+ function withCompletionSuggestRuntime(parser, context) {
745
+ const runtime = createDependencyRuntimeContext();
746
+ const nodes = getCompletionSuggestRuntimeNodes(parser, context.state, context.exec?.path ?? []);
747
+ if (nodes.length > 0) collectExplicitSourceValues(nodes, runtime);
748
+ return addCompletionSuggestRuntime(context, runtime);
749
+ }
750
+ async function withCompletionSuggestRuntimeAsync(parser, context) {
751
+ const runtime = createDependencyRuntimeContext();
752
+ const nodes = getCompletionSuggestRuntimeNodes(parser, context.state, context.exec?.path ?? []);
753
+ if (nodes.length > 0) await collectExplicitSourceValuesAsync(nodes, runtime);
754
+ return addCompletionSuggestRuntime(context, runtime);
755
+ }
756
+ function addCompletionSuggestRuntime(context, runtime) {
757
+ return {
758
+ ...context,
759
+ dependencyRegistry: runtime.registry,
760
+ exec: context.exec ? {
761
+ ...context.exec,
762
+ dependencyRuntime: runtime,
763
+ dependencyRegistry: runtime.registry
764
+ } : void 0
765
+ };
766
+ }
767
+ function getCompletionSuggestRuntimeNodes(parser, state, path) {
768
+ if (typeof parser.getSuggestRuntimeNodes === "function") return parser.getSuggestRuntimeNodes(state, path);
769
+ if (parser.dependencyMetadata?.source == null) return [];
770
+ return [{
771
+ path,
772
+ parser,
773
+ state
774
+ }];
775
+ }
776
+ function createCompletionArgumentParserContext(parser, args) {
777
+ return createParserContext({
778
+ buffer: args,
779
+ state: parser.initialState,
780
+ optionsTerminated: false
781
+ }, {
782
+ usage: parser.usage,
783
+ phase: "suggest",
784
+ path: [],
785
+ trace: createInputTrace()
786
+ });
787
+ }
788
+ function getFailedCompletionArgumentContext(result, context, parser, rootOptionSuggestions) {
789
+ const activeValueOptionNames = collectActiveValueOptionNames(parser.usage, context.exec?.commandPath ?? [], result.consumed > 0, parser.leadingNames);
790
+ const token = context.buffer[0];
791
+ return {
792
+ completingOptionValue: (result.consumed === 0 || result.consumed === 1) && activeValueOptionNames.has(token),
793
+ completedRootOption: result.consumed === 0 && isRootOptionToken(token, rootOptionSuggestions),
794
+ optionsTerminated: context.optionsTerminated
795
+ };
796
+ }
797
+ function isCompletionBufferUnchanged(before, after) {
798
+ return before.length === after.length && before.every((arg, index) => arg === after[index]);
799
+ }
800
+ function collectActiveValueOptionNames(usage, commandPath, includeDirectAfterCommandOptions, rootLeadingNames) {
801
+ const optionNames = {
802
+ value: /* @__PURE__ */ new Set(),
803
+ flag: /* @__PURE__ */ new Set()
804
+ };
805
+ if (commandPath.length === 0) {
806
+ collectRootOptionNames(usage, optionNames, rootLeadingNames);
807
+ return optionNames.value;
808
+ } else collectActiveOptionNames(usage, commandPath, optionNames, false, includeDirectAfterCommandOptions);
809
+ const names = new Set(optionNames.value);
810
+ for (const name of optionNames.flag) names.delete(name);
811
+ return names;
812
+ }
813
+ function collectRootOptionNames(usage, names, rootLeadingNames) {
814
+ for (const term of usage) collectRootOptionNamesFromTerm(term, names, rootLeadingNames);
815
+ }
816
+ function collectRootOptionNamesFromTerm(term, names, rootLeadingNames) {
817
+ switch (term.type) {
818
+ case "option":
819
+ for (const name of term.names) {
820
+ if (!rootLeadingNames.has(name)) continue;
821
+ if (term.metavar != null) names.value.add(name);
822
+ else names.flag.add(name);
823
+ }
824
+ return;
825
+ case "optional":
826
+ case "multiple":
827
+ collectRootOptionNames(term.terms, names, rootLeadingNames);
828
+ return;
829
+ case "exclusive":
830
+ for (const branch of term.terms) collectRootOptionNames(branch, names, rootLeadingNames);
831
+ return;
832
+ case "argument":
833
+ case "command":
834
+ case "literal":
835
+ case "passthrough":
836
+ case "ellipsis": return;
837
+ }
838
+ }
839
+ function collectActiveOptionNames(usage, commandPath, names, fromExclusive, includeDirectAfterCommandOptions) {
840
+ if (commandPath.length === 0) {
841
+ collectOptionNamesAtCurrentCommandDepth(usage, names, false);
842
+ return;
843
+ }
844
+ const [commandName, ...rest] = commandPath;
845
+ for (let i = 0; i < usage.length; i++) {
846
+ const term = usage[i];
847
+ if (term.type === "command" && term.name === commandName) {
848
+ const remainingUsage = usage.slice(i + 1);
849
+ if (rest.length === 0) collectOptionNamesAtCurrentCommandDepth(remainingUsage, names, !fromExclusive && includeDirectAfterCommandOptions);
850
+ else collectActiveOptionNames(remainingUsage, rest, names, fromExclusive, includeDirectAfterCommandOptions);
851
+ } else if (term.type === "exclusive") for (const branch of term.terms) collectActiveOptionNames(branch, commandPath, names, true, includeDirectAfterCommandOptions);
852
+ else if (term.type === "optional" || term.type === "multiple") collectActiveOptionNames(term.terms, commandPath, names, fromExclusive, includeDirectAfterCommandOptions);
853
+ }
854
+ }
855
+ function isRootOptionToken(token, rootOptionSuggestions) {
856
+ return token != null && rootOptionSuggestions.some((suggestion) => token === suggestion.text || token.startsWith(`${suggestion.text}=`));
857
+ }
858
+ function collectOptionNamesAtCurrentCommandDepth(usage, names, afterMatchedCommand) {
859
+ for (const term of usage) if (collectOptionNamesAtCurrentCommandDepthFromTerm(term, names, afterMatchedCommand)) return;
860
+ }
861
+ function collectOptionNamesAtCurrentCommandDepthFromTerm(term, names, afterMatchedCommand) {
862
+ switch (term.type) {
863
+ case "command": return !afterMatchedCommand;
864
+ case "option":
865
+ if (term.metavar != null) for (const name of term.names) names.value.add(name);
866
+ else for (const name of term.names) names.flag.add(name);
867
+ return false;
868
+ case "optional":
869
+ case "multiple":
870
+ collectOptionNamesAtCurrentCommandDepth(term.terms, names, afterMatchedCommand);
871
+ return false;
872
+ case "exclusive":
873
+ for (const branch of term.terms) collectOptionNamesAtCurrentCommandDepth(branch, names, false);
874
+ return false;
875
+ case "argument":
876
+ case "literal":
877
+ case "passthrough":
878
+ case "ellipsis": return false;
879
+ }
880
+ }
881
+ function getRootMetaOptionSuggestions(helpOptionConfig, helpOptionNames, versionOptionConfig, versionOptionNames) {
882
+ const suggestions = [];
883
+ if (helpOptionConfig != null && !isSuggestionHidden(helpOptionConfig.hidden)) suggestions.push(...helpOptionNames.map((name) => ({
884
+ kind: "literal",
885
+ text: name
886
+ })));
887
+ if (versionOptionConfig != null && !isSuggestionHidden(versionOptionConfig.hidden)) suggestions.push(...versionOptionNames.map((name) => ({
888
+ kind: "literal",
889
+ text: name
890
+ })));
891
+ return suggestions;
892
+ }
782
893
  /**
783
894
  * Validates the configured version value.
784
895
  *
@@ -852,6 +963,7 @@ function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsPar
852
963
  const versionCommandNames = versionCommandConfig?.names ?? ["version"];
853
964
  const completionCommandNames = completionCommandConfig?.names ?? ["completion"];
854
965
  const completionOptionNames = completionOptionConfig?.names ?? ["--completion"];
966
+ const rootOptionSuggestions = getRootMetaOptionSuggestions(helpOptionConfig, helpOptionNames, versionOptionConfig, versionOptionNames);
855
967
  const activeMetaEntries = [];
856
968
  if (options.help && helpOptionConfig) activeMetaEntries.push([
857
969
  "option",
@@ -915,7 +1027,7 @@ function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsPar
915
1027
  versionOptionGroup: versionOptionConfig?.group,
916
1028
  completionCommandGroup: completionCommandConfig?.group,
917
1029
  completionOptionGroup: completionOptionConfig?.group
918
- }, helpOptionConfig ? [...helpOptionNames] : void 0, versionOptionConfig ? [...versionOptionNames] : void 0);
1030
+ });
919
1031
  const handleResult = (classified) => {
920
1032
  switch (classified.type) {
921
1033
  case "success": return classified.value;
@@ -926,7 +1038,7 @@ function runParser(parserOrProgram, programNameOrArgs, argsOrOptions, optionsPar
926
1038
  classified.shell,
927
1039
  ...classified.commandPath ?? [],
928
1040
  ...classified.args
929
- ], programName, parser, classified.source === "command" ? completionParsers.completionCommand : completionParsers.completionOption, stdout, stderr, onCompletionResult, onErrorResult, availableShells, colors, maxWidth, completionCommandNames[0], completionOptionNames[0], classified.source === "option", sectionOrder);
1041
+ ], programName, parser, classified.source === "command" ? completionParsers.completionCommand : completionParsers.completionOption, stdout, stderr, onCompletionResult, onErrorResult, availableShells, colors, maxWidth, completionCommandNames[0], completionOptionNames[0], classified.source === "option", sectionOrder, rootOptionSuggestions);
930
1042
  case "help": {
931
1043
  let helpGeneratorParser;
932
1044
  const helpAsCommand = helpCommandConfig != null;
@@ -260,7 +260,7 @@ function* suggestOptionSync(optionNames$1, valueParser, hidden, context, prefix)
260
260
  }
261
261
  } else {
262
262
  const expectingValue = context.buffer.length > 0 && optionNames$1.includes(context.buffer[context.buffer.length - 1]);
263
- if (!expectingValue && (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/"))) {
263
+ if (!expectingValue && (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/") || prefix.startsWith("+"))) {
264
264
  for (const optionName$1 of optionNames$1) if (optionName$1.startsWith(prefix)) {
265
265
  if (prefix === "-" && optionName$1.length !== 2) continue;
266
266
  yield {
@@ -274,7 +274,7 @@ function* suggestOptionSync(optionNames$1, valueParser, hidden, context, prefix)
274
274
  if (context.buffer.length > 0) {
275
275
  const lastToken = context.buffer[context.buffer.length - 1];
276
276
  if (optionNames$1.includes(lastToken)) shouldSuggestValues = true;
277
- } else if (require_annotation_state.isAnnotationWrappedInitialState(context.state) && context.buffer.length === 0 && (context.exec?.path?.length ?? 0) === 0 && !(prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/"))) shouldSuggestValues = true;
277
+ } else if (require_annotation_state.isAnnotationWrappedInitialState(context.state) && context.buffer.length === 0 && (context.exec?.path?.length ?? 0) === 0 && !(prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/") || prefix.startsWith("+"))) shouldSuggestValues = true;
278
278
  if (shouldSuggestValues) yield* getSuggestionsWithDependency(valueParser, prefix, context.dependencyRegistry, context.exec);
279
279
  }
280
280
  }
@@ -344,7 +344,7 @@ async function* suggestOptionAsync(optionNames$1, valueParser, hidden, context,
344
344
  }
345
345
  } else {
346
346
  const expectingValue = context.buffer.length > 0 && optionNames$1.includes(context.buffer[context.buffer.length - 1]);
347
- if (!expectingValue && (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/"))) {
347
+ if (!expectingValue && (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/") || prefix.startsWith("+"))) {
348
348
  for (const optionName$1 of optionNames$1) if (optionName$1.startsWith(prefix)) {
349
349
  if (prefix === "-" && optionName$1.length !== 2) continue;
350
350
  yield {
@@ -358,7 +358,7 @@ async function* suggestOptionAsync(optionNames$1, valueParser, hidden, context,
358
358
  if (context.buffer.length > 0) {
359
359
  const lastToken = context.buffer[context.buffer.length - 1];
360
360
  if (optionNames$1.includes(lastToken)) shouldSuggestValues = true;
361
- } else if (require_annotation_state.isAnnotationWrappedInitialState(context.state) && context.buffer.length === 0 && (context.exec?.path?.length ?? 0) === 0 && !(prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/"))) shouldSuggestValues = true;
361
+ } else if (require_annotation_state.isAnnotationWrappedInitialState(context.state) && context.buffer.length === 0 && (context.exec?.path?.length ?? 0) === 0 && !(prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/") || prefix.startsWith("+"))) shouldSuggestValues = true;
362
362
  if (shouldSuggestValues) for await (const suggestion of getSuggestionsWithDependencyAsync(valueParser, prefix, context.dependencyRegistry, context.exec)) yield suggestion;
363
363
  }
364
364
  }
@@ -888,7 +888,7 @@ function flag(...args) {
888
888
  suggest(_context, prefix) {
889
889
  if (require_usage.isSuggestionHidden(options.hidden)) return [];
890
890
  const suggestions = [];
891
- if (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/")) {
891
+ if (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/") || prefix.startsWith("+")) {
892
892
  for (const optionName$1 of optionNames$1) if (optionName$1.startsWith(prefix)) {
893
893
  if (prefix === "-" && optionName$1.length !== 2) continue;
894
894
  suggestions.push({
@@ -260,7 +260,7 @@ function* suggestOptionSync(optionNames$1, valueParser, hidden, context, prefix)
260
260
  }
261
261
  } else {
262
262
  const expectingValue = context.buffer.length > 0 && optionNames$1.includes(context.buffer[context.buffer.length - 1]);
263
- if (!expectingValue && (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/"))) {
263
+ if (!expectingValue && (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/") || prefix.startsWith("+"))) {
264
264
  for (const optionName$1 of optionNames$1) if (optionName$1.startsWith(prefix)) {
265
265
  if (prefix === "-" && optionName$1.length !== 2) continue;
266
266
  yield {
@@ -274,7 +274,7 @@ function* suggestOptionSync(optionNames$1, valueParser, hidden, context, prefix)
274
274
  if (context.buffer.length > 0) {
275
275
  const lastToken = context.buffer[context.buffer.length - 1];
276
276
  if (optionNames$1.includes(lastToken)) shouldSuggestValues = true;
277
- } else if (isAnnotationWrappedInitialState(context.state) && context.buffer.length === 0 && (context.exec?.path?.length ?? 0) === 0 && !(prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/"))) shouldSuggestValues = true;
277
+ } else if (isAnnotationWrappedInitialState(context.state) && context.buffer.length === 0 && (context.exec?.path?.length ?? 0) === 0 && !(prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/") || prefix.startsWith("+"))) shouldSuggestValues = true;
278
278
  if (shouldSuggestValues) yield* getSuggestionsWithDependency(valueParser, prefix, context.dependencyRegistry, context.exec);
279
279
  }
280
280
  }
@@ -344,7 +344,7 @@ async function* suggestOptionAsync(optionNames$1, valueParser, hidden, context,
344
344
  }
345
345
  } else {
346
346
  const expectingValue = context.buffer.length > 0 && optionNames$1.includes(context.buffer[context.buffer.length - 1]);
347
- if (!expectingValue && (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/"))) {
347
+ if (!expectingValue && (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/") || prefix.startsWith("+"))) {
348
348
  for (const optionName$1 of optionNames$1) if (optionName$1.startsWith(prefix)) {
349
349
  if (prefix === "-" && optionName$1.length !== 2) continue;
350
350
  yield {
@@ -358,7 +358,7 @@ async function* suggestOptionAsync(optionNames$1, valueParser, hidden, context,
358
358
  if (context.buffer.length > 0) {
359
359
  const lastToken = context.buffer[context.buffer.length - 1];
360
360
  if (optionNames$1.includes(lastToken)) shouldSuggestValues = true;
361
- } else if (isAnnotationWrappedInitialState(context.state) && context.buffer.length === 0 && (context.exec?.path?.length ?? 0) === 0 && !(prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/"))) shouldSuggestValues = true;
361
+ } else if (isAnnotationWrappedInitialState(context.state) && context.buffer.length === 0 && (context.exec?.path?.length ?? 0) === 0 && !(prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/") || prefix.startsWith("+"))) shouldSuggestValues = true;
362
362
  if (shouldSuggestValues) for await (const suggestion of getSuggestionsWithDependencyAsync(valueParser, prefix, context.dependencyRegistry, context.exec)) yield suggestion;
363
363
  }
364
364
  }
@@ -888,7 +888,7 @@ function flag(...args) {
888
888
  suggest(_context, prefix) {
889
889
  if (isSuggestionHidden(options.hidden)) return [];
890
890
  const suggestions = [];
891
- if (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/")) {
891
+ if (prefix.startsWith("--") || prefix.startsWith("-") || prefix.startsWith("/") || prefix.startsWith("+")) {
892
892
  for (const optionName$1 of optionNames$1) if (optionName$1.startsWith(prefix)) {
893
893
  if (prefix === "-" && optionName$1.length !== 2) continue;
894
894
  suggestions.push({