{"version":3,"file":"index.mjs","names":[],"sources":["../../src/browser/async-context.ts","../../src/lib/context.ts","../../src/lib/cli-option-groups.ts","../../src/lib/format-help.ts","../../src/lib/resolve-prompts.ts","../../src/lib/utils.ts","../../src/lib/internal-cli.ts","../../src/lib/test-harness.ts","../../src/lib/public-api.ts","../../src/lib/composable-builder.ts","../../src/lib/completion-types.ts","../../src/lib/configuration-providers.ts"],"sourcesContent":["/**\n * Browser-safe fallback for AsyncLocalStorage.\n *\n * Uses a simple last-set-wins store. This is correct for browser usage\n * where CLI execution is single-threaded/sequential.\n *\n * Swapped in via browserAlias in tsdown.config.mjs.\n */\n\nexport interface ForgeContextData {\n  args: Record<string, unknown>;\n  commandChain: string[];\n  commandIdChain: string[];\n  providers: Map<string, unknown>;\n  providerFactories: Map<string, { factory: Function; lifetime: string }>;\n  handlerPhase: boolean;\n  /** Keys whose factories are currently being resolved — used for cycle detection */\n  resolving: Set<string>;\n}\n\nlet currentStore: ForgeContextData | undefined;\nlet activeRuns = 0;\nlet warnedAboutConcurrency = false;\n\n/**\n * Emit a one-shot warning when a second `forge()`/`sdk()` call starts while\n * another is still on the stack. Real async-boundary isolation needs\n * `AsyncLocalStorage`, which browsers don't provide — this store is just a\n * last-set-wins global. The warning exists so misuse fails loudly instead of\n * silently leaking providers between concurrent executions.\n */\nfunction warnOnceAboutConcurrency(): void {\n  if (warnedAboutConcurrency) return;\n  warnedAboutConcurrency = true;\n  // eslint-disable-next-line no-console\n  console.warn(\n    '[cli-forge] Concurrent forge()/sdk() execution detected in the browser. ' +\n      'The browser build uses a last-set-wins context store because ' +\n      'AsyncLocalStorage is unavailable, so DI providers may leak between ' +\n      'overlapping executions. See docs: \"DI and the browser runtime\".'\n  );\n}\n\nexport const contextStorage = {\n  run<T>(\n    store: ForgeContextData,\n    fn: (...args: unknown[]) => T,\n    ...args: unknown[]\n  ): T {\n    if (activeRuns > 0) {\n      warnOnceAboutConcurrency();\n    }\n    const prev = currentStore;\n    currentStore = store;\n    activeRuns++;\n    try {\n      return fn(...args);\n    } finally {\n      currentStore = prev;\n      activeRuns--;\n    }\n  },\n  getStore(): ForgeContextData | undefined {\n    return currentStore;\n  },\n  enterWith(store: ForgeContextData | undefined): void {\n    currentStore = store;\n  },\n};\n","import type { CLI, AnyCLI, ProviderConfig, GlobalProviderConfig } from './public-api';\nimport { contextStorage, ForgeContextData } from './async-context';\n\n// ─── Type Helpers ─────────────────────────────────────────────────────────────\n\n/**\n * Recursively gathers all providers from a CLI and its ancestors.\n *\n * When a child command re-provides a key that its parent also provides, the\n * child's type shadows the parent's — matching the runtime override semantics\n * in `collectProviders()`. This is why the parent's providers are wrapped in\n * `Omit<..., keyof TProviders>` before being intersected with the child's.\n */\nexport type ProvidersOf<T> = T extends CLI<any, any, any, infer TParent, infer TProviders>\n  ? TProviders &\n      (TParent extends AnyCLI\n        ? Omit<ProvidersOf<TParent>, keyof TProviders>\n        : Record<never, never>)\n  : Record<never, never>;\n\n/**\n * Same chain-walking semantics as {@link ProvidersOf}, but takes\n * `TProviders` and `TParent` directly instead of a `CLI<...>` instance type.\n *\n * This exists so the `CLI` interface can declare\n * `getContext(): CommandContext<TArgs, ProvidersFromChain<TProviders, TParent>, TChildren>`\n * without re-wrapping its own type parameters in a `CLI<...>`. Writing\n * `ProvidersOf<CLI<TArgs, ..., TParent, TProviders>>` inside `CLI` would\n * reference `CLI` while the interface is still being constructed, which\n * has caused TypeScript cycle / constraint-solver headaches in the past.\n * Passing the raw parameters through a non-CLI helper keeps the\n * recursion purely in conditional-type space.\n */\nexport type ProvidersFromChain<TProviders, TParent> =\n  TParent extends CLI<any, any, any, infer TGrandParent, infer TParentProviders>\n    ? TProviders &\n        Omit<ProvidersFromChain<TParentProviders, TGrandParent>, keyof TProviders>\n    : TProviders;\n\n/**\n * Infers the full CommandContext type from a CLI type.\n */\nexport type InferContextOfCommand<T extends AnyCLI> = T extends CLI<\n  infer TArgs,\n  any,\n  infer TChildren,\n  any,\n  any\n>\n  ? CommandContext<TArgs, ProvidersOf<T>, TChildren>\n  : never;\n\n/**\n * The context object available inside a command handler via {@link getCommandContext}.\n */\nexport interface CommandContext<TArgs, TProviders, TChildren = {}> {\n  /** The parsed arguments for the current command. */\n  readonly args: TArgs;\n\n  /**\n   * The chain of command names from root to the currently executing command.\n   * e.g. `['my-app', 'serve']`\n   */\n  readonly commandChain: string[];\n\n  /**\n   * Resolves a provider by its key.\n   *\n   * @param key The provider key (must be a key of TProviders)\n   * @param defaultValue Optional fallback if the provider has no registered factory\n   */\n  inject<K extends keyof TProviders>(key: K): TProviders[K];\n  inject<K extends keyof TProviders>(key: K, defaultValue: TProviders[K]): TProviders[K];\n\n  /**\n   * Returns a CommandContext scoped to a child command that was already executed.\n   * The child command must appear in the current commandChain.\n   */\n  getChildContext<K extends keyof TChildren>(\n    command: K & string\n  ): TChildren[K] extends AnyCLI ? InferContextOfCommand<TChildren[K]> : never;\n}\n\n// ─── Module-level state ───────────────────────────────────────────────────────\n\n/**\n * Permanent cache for global-lifetime providers. Survives across executions.\n *\n * Keyed by the factory function identity rather than the provider name, so\n * two unrelated CLI apps (or two registrations of the same name with\n * different factories) cannot collide on a shared cached value. Each\n * distinct factory function gets its own slot; calling `.provide()` twice\n * with the same factory reference (e.g. across clones) correctly shares.\n */\nconst globalProviderCache = new Map<Function, unknown>();\n\n/**\n * Clears the module-level cache for `lifetime: 'global'` providers.\n *\n * Global provider factories normally run once per Node process and their\n * result is memoized forever. That's the desired behavior in production —\n * it's also what makes them leak between tests. Call this from test setup\n * (or automatically via `TestHarness.clearMockedContexts()`) to get a clean\n * slate between specs that exercise global-lifetime providers.\n */\nexport function resetGlobalProviders(): void {\n  globalProviderCache.clear();\n}\n\n// ─── Internal helpers ─────────────────────────────────────────────────────────\n\nfunction readStore(): ForgeContextData {\n  const store = contextStorage.getStore();\n  if (!store) {\n    throw new Error(\n      'No CLI context found. getCommandContext() must be called from within a command handler.'\n    );\n  }\n  if (!store.handlerPhase) {\n    throw new Error(\n      'inject() can only be called during the handler phase. ' +\n        'Do not call getCommandContext() during option builders or middleware.'\n    );\n  }\n  return store;\n}\n\nconst NOT_FOUND = Symbol('NOT_FOUND');\n\nfunction resolveProvider(store: ForgeContextData, key: string): unknown | typeof NOT_FOUND {\n  // 1. Check pre-cached/pre-resolved providers (use .has() to handle undefined values)\n  if (store.providers.has(key)) {\n    return store.providers.get(key);\n  }\n\n  // 2. Lazy-resolve from factories\n  const registration = store.providerFactories.get(key);\n  if (!registration) {\n    return NOT_FOUND;\n  }\n\n  // 3. Cycle detection — a factory that inject()s a provider whose own\n  //    factory inject()s back into this key would otherwise blow the stack.\n  if (store.resolving.has(key)) {\n    const cycle = [...store.resolving, key].join(' -> ');\n    throw new Error(\n      `Circular provider dependency detected while resolving \"${key}\": ${cycle}`\n    );\n  }\n\n  const { factory, lifetime } = registration;\n  store.resolving.add(key);\n  try {\n    if (lifetime === 'global') {\n      // Global: permanent module-level cache keyed by factory identity\n      // (not by key name) so unrelated registrations can't collide.\n      const globalFactory = factory as GlobalProviderConfig<unknown>['factory'];\n      if (!globalProviderCache.has(globalFactory)) {\n        globalProviderCache.set(globalFactory, globalFactory());\n      }\n      const value = globalProviderCache.get(globalFactory);\n      // Also cache in the store so subsequent inject() calls skip factory lookup\n      store.providers.set(key, value);\n      return value;\n    } else {\n      // executionScope: scoped to this execution, keyed by args identity\n      const value = (factory as ProviderConfig<unknown>['factory'])(store.args);\n      store.providers.set(key, value);\n      return value;\n    }\n  } finally {\n    store.resolving.delete(key);\n  }\n}\n\nfunction createCommandContext(store: ForgeContextData): CommandContext<any, any, any> {\n  return {\n    get args() {\n      return store.args;\n    },\n\n    get commandChain() {\n      return store.commandChain;\n    },\n\n    inject(key: string, defaultValue?: unknown): unknown {\n      const resolved = resolveProvider(store, key);\n      if (resolved === NOT_FOUND) {\n        if (arguments.length >= 2) {\n          return defaultValue;\n        }\n        throw new Error(\n          `No provider registered for key \"${key}\". ` +\n            `Register it with .provide(\"${key}\", { factory: ... }) on the CLI.`\n        );\n      }\n      return resolved;\n    },\n\n    getChildContext(command: string): any {\n      if (!store.commandChain.includes(command)) {\n        throw new Error(\n          `Command \"${command}\" is not in the current command chain: [${store.commandChain.join(', ')}]. ` +\n            `getChildContext() can only be used with commands that have already executed.`\n        );\n      }\n      return createCommandContext(store);\n    },\n  };\n}\n\n// ─── Public API ───────────────────────────────────────────────────────────────\n\n/**\n * Returns the {@link CommandContext} for the currently executing command.\n *\n * Must be called from within a command handler (not during builders or middleware).\n *\n * ## Runtime safety\n *\n * When called with a CLI instance, `getCommandContext` validates at runtime\n * that the instance is part of the active command chain — the root app,\n * any ancestor on the chain, or the currently-running subcommand. If you\n * pass a CLI that isn't in the chain (a sibling command, an unrelated app,\n * a descendant that didn't run), it throws with a descriptive error. This\n * catches the common bug where the wrong instance is passed as a type\n * witness and `inject()` silently returns the wrong providers.\n *\n * ## Two ways to reach subcommand-typed access\n *\n * **Option 1** — from the root, walk by name:\n * ```ts\n * const ctx = getCommandContext(app);\n * const buildCtx = ctx.getChildContext('build');\n * console.log(buildCtx.args.target);\n * ```\n *\n * **Option 2** — pass a composed subcommand reference directly, skipping\n * the `getChildContext` hop:\n * ```ts\n * import { build } from './build'; // standalone CLI composed into app\n * const ctx = getCommandContext(build);\n * console.log(ctx.args.target);\n * ```\n *\n * Both forms are runtime-safe. Option 2 is only typed if the subcommand\n * reference carries the full `TProviders` — i.e. the subcommand is declared\n * inside the parent's `.command('name', { builder, handler })` call, where\n * TypeScript can thread parent providers into the builder's `cmd`. A\n * standalone `cli('build', ...)` reference doesn't see inherited providers\n * in its type; use Option 1 for that shape.\n *\n * ## Type witness (no instance)\n *\n * The parameterless overload returns a context typed by an explicit generic\n * — useful when you can't get a live reference to the CLI from where the\n * handler is written. **This form has no runtime safety**: the `T` type\n * parameter is trusted as-is, so a mismatched generic silently returns a\n * context typed for a CLI that isn't running. Prefer passing the CLI\n * instance whenever feasible.\n *\n * @param cli CLI instance used as both a type witness for inference and\n *            a runtime identity check. Required for runtime-safe usage.\n *\n * @example\n * ```ts\n * import { getCommandContext } from 'cli-forge/context';\n * import { app } from './cli';\n *\n * const ctx = getCommandContext(app);\n * const db = ctx.inject('db');\n * ```\n */\nexport function getCommandContext<T extends AnyCLI>(cli: T): InferContextOfCommand<T>;\n/**\n * Type-only overload: trusts `T` without runtime validation. Prefer the\n * instance-based overload whenever you can import the CLI that owns the\n * handler — this form exists as an escape hatch for cases where no live\n * CLI reference is reachable from the handler's module.\n */\nexport function getCommandContext<T extends AnyCLI>(): InferContextOfCommand<T>;\nexport function getCommandContext<T extends AnyCLI>(cli?: T): InferContextOfCommand<T> {\n  const store = readStore();\n  if (cli && typeof (cli as { commandId?: unknown }).commandId === 'string') {\n    const { commandId } = cli as unknown as { commandId: string; name?: string };\n    if (!store.commandIdChain.includes(commandId)) {\n      const name = (cli as unknown as { name?: string }).name ?? commandId;\n      throw new Error(\n        `getCommandContext() was called with a CLI instance (\"${name}\", id=${commandId}) ` +\n          `that is not part of the active command chain. ` +\n          `Active chain ids: [${store.commandIdChain.join(', ')}]. ` +\n          `Pass the root app, an ancestor on the chain, or the currently-running subcommand.`\n      );\n    }\n  }\n  return createCommandContext(store) as InferContextOfCommand<T>;\n}\n","import { InternalOptionConfig } from '@cli-forge/parser';\nimport { AnyInternalCLI } from './internal-cli';\n\nexport function readOptionGroupsForCLI(parentCLI: AnyInternalCLI) {\n  function registerGroupsFromCLI(cli: AnyInternalCLI) {\n    for (const { label, keys, sortOrder } of cli.registeredOptionGroups) {\n      groups[label] ??= {\n        keys: new Set(),\n        sortOrder: Number.MAX_SAFE_INTEGER,\n      };\n      if (sortOrder) {\n        groups[label].sortOrder = sortOrder;\n      }\n      for (const key of keys) {\n        groups[label].keys.add(key);\n      }\n    }\n  }\n\n  const groups: Record<string, { keys: Set<string>; sortOrder: number }> = {};\n   \n  let command: AnyInternalCLI = parentCLI;\n  registerGroupsFromCLI(command);\n  for (const subcommand of parentCLI.commandChain) {\n    command = command?.registeredCommands[subcommand];\n    registerGroupsFromCLI(command);\n  }\n  const parserOptions: Record<string, InternalOptionConfig> =\n    parentCLI.parser.configuredOptions;\n\n  for (const key in parserOptions) {\n    const option = parserOptions[key];\n    if (option.group) {\n      groups[option.group] ??= {\n        keys: new Set(),\n        sortOrder: Number.MAX_SAFE_INTEGER,\n      };\n      groups[option.group].keys.add(key);\n    }\n  }\n\n  const groupedOptions: Array<{\n    label: string;\n    sortOrder: number;\n    keys: Array<InternalOptionConfig>;\n  }> = [];\n\n  for (const label in groups) {\n    const entry = {\n      sortOrder: groups[label].sortOrder,\n      keys: [] as InternalOptionConfig[],\n      label,\n    };\n    for (const key of groups[label].keys) {\n      const option = parserOptions[key];\n      entry.keys.push(option);\n      delete parserOptions[key];\n    }\n    groupedOptions.push(entry);\n  }\n  groupedOptions.sort((a, b) => {\n    if (a.sortOrder === b.sortOrder) {\n      return a.label.localeCompare(b.label);\n    } else {\n      return a.sortOrder - b.sortOrder;\n    }\n  });\n  return groupedOptions;\n}\n","import {\n  InternalOptionConfig,\n  UnknownOptionConfig,\n  readDefaultValue,\n  isOneOfOptionConfig,\n  isObjectOptionConfig,\n} from '@cli-forge/parser';\nimport { AnyInternalCLI } from './internal-cli';\n\nexport function formatHelp(parentCLI: AnyInternalCLI): string {\n  const help: string[] = [];\n  let command = parentCLI;\n  let epilogue = parentCLI.configuration?.epilogue;\n  for (const key of parentCLI.commandChain) {\n    command = command.registeredCommands[key] as typeof parentCLI;\n\n    // Properties that are ineherited from the parent command should be copied over\n    if (command.configuration?.epilogue) {\n      epilogue = command.configuration.epilogue;\n    }\n  }\n  help.push(\n    `Usage: ${\n      command.configuration?.usage\n        ? command.configuration.usage\n        : [\n            parentCLI.name,\n            ...parentCLI.commandChain,\n            ...command.parser.configuredPositionals.map((p) => {\n              const displayKey = command.parser.getDisplayKey(p.key);\n              return p.required ? `<${displayKey}>` : `[${displayKey}]`;\n            }),\n          ].join(' ')\n    }`\n  );\n  if (command.configuration?.description) {\n    help.push(command.configuration.description);\n  }\n  // Track displayed commands by their actual CLI instance to avoid duplicates\n  const displayedCommands = new Set<AnyInternalCLI>();\n  const visibleSubcommands: AnyInternalCLI[] = [];\n  for (const key in command.registeredCommands) {\n    const subcommand = command.registeredCommands[key];\n    // Skip if we've already displayed this command instance\n    if (displayedCommands.has(subcommand)) {\n      continue;\n    }\n    displayedCommands.add(subcommand);\n    if (subcommand.configuration?.hidden) {\n      continue;\n    }\n    visibleSubcommands.push(subcommand);\n  }\n  if (visibleSubcommands.length > 0) {\n    help.push('');\n    help.push('Commands:');\n  }\n  for (const subcommand of visibleSubcommands) {\n    // Use the localized command name for display based on the command's default name\n    const displayKey = command.getLocalizedCommandName(subcommand.name);\n    help.push(\n      `  ${displayKey}${\n        subcommand.configuration?.description\n          ? ' - ' + subcommand.configuration.description\n          : ''\n      }`\n    );\n  }\n  const groupedOptions = parentCLI.getGroupedOptions();\n  const nonpositionalOptions = Object.values(\n    command.parser.configuredOptions\n  ).filter((c) => !c.positional && !c.hidden);\n\n  help.push(...getOptionBlock('Options', nonpositionalOptions, command.parser));\n\n  for (const { label, keys } of groupedOptions) {\n    help.push(...getOptionBlock(label, keys, command.parser));\n  }\n\n  if (command.configuration?.examples?.length) {\n    help.push('');\n    help.push('Examples:');\n    for (const example of command.configuration.examples) {\n      help.push(`  \\`${example}\\``);\n    }\n  }\n\n  const configDocs = command.parser.getConfigurationDocs();\n  if (configDocs.length > 0) {\n    help.push('');\n    help.push('Configuration:');\n    for (const section of configDocs) {\n      help.push(`  ${section.heading}`);\n      help.push(`    ${section.body}`);\n    }\n  }\n\n  if (visibleSubcommands.length > 0) {\n    help.push(' ');\n    help.push(\n      `Run \\`${[parentCLI.name, ...parentCLI.commandChain].join(\n        ' '\n      )} [command] --help\\` for more information on a command`\n    );\n  }\n\n  if (epilogue) {\n    help.push('');\n    help.push(epilogue);\n  }\n\n  return help.join('\\n');\n}\n\nfunction getOptionParts(option: UnknownOptionConfig) {\n  const parts = [];\n  if (option.description) {\n    parts.push(option.description);\n  }\n  if (isOneOfOptionConfig(option)) {\n    const { valueTypes } = option;\n    const typeNames = valueTypes.map((vt) => vt.type).join('|');\n    parts.push(`[${typeNames}]`);\n    for (const vt of valueTypes) {\n      const subParts: string[] = [];\n      if (vt.description) {\n        subParts.push(vt.description);\n      }\n      if (vt.choices) {\n        const choices =\n          typeof vt.choices === 'function' ? vt.choices() : vt.choices;\n        subParts.push(`(${choices.join(', ')})`);\n      }\n      if (subParts.length > 0) {\n        parts.push(`${vt.type}: ${subParts.join(' ')}`);\n      }\n    }\n  } else if ('choices' in option && option.choices) {\n    const choices =\n      typeof option.choices === 'function' ? option.choices() : option.choices;\n    parts.push(`(${choices.join(', ')})`);\n  }\n  if (option.default) {\n    parts.push(\n      '[default: ' + formatDefaultValue(readDefaultValue(option)) + ']'\n    );\n  } else if (option.required) {\n    parts.push('[required]');\n  }\n  if (option.deprecated) {\n    parts.push('[deprecated: ' + option.deprecated + ']');\n  }\n  return parts;\n}\n\nfunction formatDefaultValue([value, description]: [any, string | undefined]) {\n  if (description) {\n    return description;\n  }\n  return removeTrailingAndLeadingQuotes(JSON.stringify(value));\n}\n\nfunction removeTrailingAndLeadingQuotes(str: string) {\n  return str.replace(/^['\"]/, '').replace(/['\"]$/, '');\n}\n\n/**\n * Extract the merged properties from a oneOf config's object valueTypes.\n * When a oneOf has object branches, their properties can be set via dot notation,\n * so we merge them for display in help output.\n */\nfunction getOneOfObjectProperties(\n  config: UnknownOptionConfig\n): Record<string, UnknownOptionConfig> | undefined {\n  if (!isOneOfOptionConfig(config)) return undefined;\n  const merged: Record<string, UnknownOptionConfig> = {};\n  let found = false;\n  for (const vt of config.valueTypes) {\n    if (\n      vt.type === 'object' &&\n      'properties' in vt &&\n      vt.properties &&\n      typeof vt.properties === 'object'\n    ) {\n      found = true;\n      for (const [k, v] of Object.entries(\n        vt.properties as Record<string, UnknownOptionConfig>\n      )) {\n        // First object branch wins for any given key\n        if (!(k in merged)) {\n          merged[k] = v;\n        }\n      }\n    }\n  }\n  return found ? merged : undefined;\n}\n\nfunction collectObjectProperties(\n  parentKey: string,\n  properties: Record<string, UnknownOptionConfig>\n): Array<{ key: string; config: UnknownOptionConfig }> {\n  const result: Array<{ key: string; config: UnknownOptionConfig }> = [];\n  for (const [name, config] of Object.entries(properties)) {\n    if (config.hidden) continue;\n    const fullKey = `${parentKey}.${name}`;\n    result.push({ key: fullKey, config });\n    if (isObjectOptionConfig(config) && config.properties) {\n      result.push(\n        ...collectObjectProperties(\n          fullKey,\n          config.properties as Record<string, UnknownOptionConfig>\n        )\n      );\n    } else {\n      const oneOfProps = getOneOfObjectProperties(config);\n      if (oneOfProps) {\n        result.push(...collectObjectProperties(fullKey, oneOfProps));\n      }\n    }\n  }\n  return result;\n}\n\nfunction getPropertyEntries(\n  option: UnknownOptionConfig\n): Array<{ key: string; config: UnknownOptionConfig }> {\n  let properties: Record<string, UnknownOptionConfig> | undefined;\n  if (isObjectOptionConfig(option) && option.properties) {\n    properties = option.properties as Record<string, UnknownOptionConfig>;\n  } else {\n    properties = getOneOfObjectProperties(option);\n  }\n  if (!properties) return [];\n  return collectObjectProperties(\n    (option as InternalOptionConfig).key,\n    properties\n  );\n}\n\nfunction formatFlag(name: string): string {\n  return name.length === 1 ? `-${name}` : `--${name}`;\n}\n\nfunction getDisplayAliases(\n  option: InternalOptionConfig,\n  displayKey: string\n): string[] {\n  const aliases = option.alias ?? [];\n  if (aliases.length === 0) return [];\n  const hiddenAliases = option.hiddenAliases ?? [];\n  return aliases.filter(\n    (alias) => alias !== displayKey && !hiddenAliases.includes(alias)\n  );\n}\n\nfunction buildFlagColumn(displayKey: string, aliases: string[]): string {\n  return [formatFlag(displayKey), ...aliases.map(formatFlag)].join(', ');\n}\n\nfunction getOptionBlock(\n  label: string,\n  options: InternalOptionConfig[],\n  parser: import('@cli-forge/parser').ReadonlyArgvParser<any>\n) {\n  const lines: string[] = [];\n\n  if (options.length > 0) {\n    lines.push('');\n    lines.push(label + ':');\n  }\n\n  // Collect all entries (options + their property sub-entries) into a flat list\n  const entries: Array<{\n    flagColumn: string;\n    parts: string[];\n    indent: number;\n  }> = [];\n\n  for (const option of options) {\n    const displayKey = parser.getDisplayKey(option.key);\n    const aliases = getDisplayAliases(option, displayKey);\n    entries.push({\n      flagColumn: buildFlagColumn(displayKey, aliases),\n      parts: getOptionParts(option),\n      indent: 0,\n    });\n    for (const { key, config } of getPropertyEntries(option)) {\n      entries.push({\n        flagColumn: `--${key}`,\n        parts: getOptionParts(config),\n        indent: 2,\n      });\n    }\n  }\n\n  // Compute flag column width accounting for indent so all `-` separators align\n  let flagColumnWidth = 0;\n  for (const entry of entries) {\n    flagColumnWidth = Math.max(\n      flagColumnWidth,\n      entry.indent + entry.flagColumn.length\n    );\n  }\n\n  // Compute padding for each part column across all entries\n  const partPadding: number[] = [];\n  for (const entry of entries) {\n    for (let j = 0; j < entry.parts.length; j++) {\n      if (!partPadding[j]) {\n        partPadding[j] = 0;\n      }\n      partPadding[j] = Math.max(partPadding[j], entry.parts[j].length);\n    }\n  }\n\n  for (const { flagColumn, parts, indent } of entries) {\n    const paddedFlagColumn = flagColumn.padEnd(flagColumnWidth - indent);\n    lines.push(\n      `${' '.repeat(2 + indent)}${paddedFlagColumn}${\n        parts.length ? ' - ' : ''\n      }${parts.map((part, i) => part.padEnd(partPadding[i])).join(' ')}`\n    );\n  }\n  return lines;\n}\n","import type { InternalOptionConfig } from '@cli-forge/parser';\nimport type {\n  PromptConfig,\n  PromptOption,\n  PromptOptionConfig,\n  PromptProvider,\n} from './prompt-types';\n\n/**\n * Collects options that need prompting, matches them to providers,\n * executes prompts, and returns the prompted values.\n */\nexport async function resolvePrompts(opts: {\n  configuredOptions: Record<string, InternalOptionConfig>;\n  configuredImplies: Record<string, Set<string>>;\n  promptConfigs: Map<string, PromptOptionConfig<any>>;\n  providers: PromptProvider[];\n  currentArgs: Record<string, unknown>;\n}): Promise<Record<string, unknown>> {\n  const {\n    configuredOptions,\n    configuredImplies,\n    promptConfigs,\n    providers,\n    currentArgs,\n  } = opts;\n\n  // Step 1: Collect promptable options\n  const promptableOptions: PromptOption[] = [];\n\n  for (const [name, config] of Object.entries(configuredOptions)) {\n    // Skip internal options\n    if (\n      name === 'help' ||\n      name === 'version' ||\n      name === 'unmatched' ||\n      name === '--'\n    ) {\n      continue;\n    }\n\n    // Already has a value — skip unless prompt is explicitly true/string\n    const hasValue = currentArgs[name] !== undefined;\n\n    const promptSetting = promptConfigs.get(name);\n    let resolved: PromptConfig | null | undefined;\n\n    if (typeof promptSetting === 'function') {\n      resolved = promptSetting(currentArgs);\n      // Callback: null/undefined treated as false\n      if (resolved === null || resolved === undefined) {\n        continue;\n      }\n    } else if (promptSetting !== undefined) {\n      // Static value\n      resolved = promptSetting;\n    } else {\n      // Not specified: prompt only if required and missing value\n      if (hasValue) continue;\n\n      const isRequired = config.required === true;\n      const isImplied = isOptionImplied(name, configuredImplies, currentArgs);\n\n      if (!isRequired && !isImplied) continue;\n      if (providers.length === 0) continue; // No providers, let validation handle it\n\n      resolved = true; // Will prompt\n    }\n\n    if (resolved === false) continue;\n    if (hasValue && resolved !== true && typeof resolved !== 'string') continue;\n\n    promptableOptions.push({\n      name,\n      config: {\n        ...config,\n        prompt: resolved === true ? true : resolved ?? undefined,\n      },\n    });\n  }\n\n  if (promptableOptions.length === 0) {\n    return {};\n  }\n\n  // Step 2: Match options to providers\n  const filteredProviders = providers.filter((p) => p.filter);\n  const fallbackProviders = providers.filter((p) => !p.filter);\n\n  const providerGroups = new Map<PromptProvider, PromptOption[]>();\n  const unmatchedOptions: PromptOption[] = [];\n\n  for (const option of promptableOptions) {\n    let matched = false;\n    for (const provider of filteredProviders) {\n      if (provider.filter!(option.name, option.config)) {\n        if (!providerGroups.has(provider)) {\n          providerGroups.set(provider, []);\n        }\n        providerGroups.get(provider)!.push(option);\n        matched = true;\n        break;\n      }\n    }\n    if (!matched) {\n      unmatchedOptions.push(option);\n    }\n  }\n\n  // Assign unmatched options to first fallback provider\n  if (unmatchedOptions.length > 0) {\n    if (fallbackProviders.length === 0) {\n      const names = unmatchedOptions.map((o) => `'${o.name}'`).join(', ');\n      throw new Error(\n        `Option(s) ${names} require prompting but no prompt provider is available`\n      );\n    }\n    const fallback = fallbackProviders[0];\n    if (!providerGroups.has(fallback)) {\n      providerGroups.set(fallback, []);\n    }\n    providerGroups.get(fallback)!.push(...unmatchedOptions);\n  }\n\n  // Step 3: Execute prompts\n  const results: Record<string, unknown> = {};\n\n  for (const [provider, options] of providerGroups) {\n    if (provider.promptBatch) {\n      const batchResults = await provider.promptBatch(options);\n      Object.assign(results, batchResults);\n    } else if (provider.prompt) {\n      for (const option of options) {\n        results[option.name] = await provider.prompt(option);\n      }\n    }\n  }\n\n  return results;\n}\n\n/**\n * Check if an option is implied by another option that has been set.\n */\nfunction isOptionImplied(\n  name: string,\n  configuredImplies: Record<string, Set<string>>,\n  currentArgs: Record<string, unknown>\n): boolean {\n  for (const [trigger, implied] of Object.entries(configuredImplies)) {\n    if (implied.has(name) && currentArgs[trigger] !== undefined) {\n      return true;\n    }\n  }\n  return false;\n}\n","import { type Expand, getFileSystemProvider } from '@cli-forge/parser';\nimport { CLI } from './public-api';\n\nexport function getCallingFile() {\n  // Since this function lives in a utility file, the parent file\n  // would just be the file that invokes getCallingFile... We actually\n  // want the parent of the file that calls this, which is this file's\n  // grandparent.\n  let grandparentFile: string | undefined;\n\n  // Overrides prepare stack trace to be an identity fn, to get the callsites\n  // associated with the current error.\n  const _pst = Error.prepareStackTrace;\n  Error.prepareStackTrace = function (err, stack) {\n    return stack;\n  };\n\n  try {\n    const err = new Error();\n    const callsites = err.stack as any as NodeJS.CallSite[];\n\n    // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n    const currentfile = callsites.shift()!.getFileName();\n    let parentfile: string | undefined;\n\n    while (callsites.length) {\n      // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n      const callerfile = callsites.shift()!.getFileName();\n\n      // We've reached the parent file\n      if (currentfile !== callerfile) {\n        // We've reached the grandparent file\n        if (parentfile && parentfile !== callerfile) {\n          grandparentFile = parentfile;\n          break;\n        }\n        parentfile = callerfile;\n      }\n    }\n  } finally {\n    Error.prepareStackTrace = _pst;\n  }\n\n  return grandparentFile;\n}\n\nexport function getParentPackageJson(searchPath: string) {\n  const fs = getFileSystemProvider();\n\n  let currentPath = searchPath;\n  let packageJsonPath: string | undefined;\n\n   \n  while (true) {\n    const packagePath = fs.join(currentPath, 'package.json');\n\n    if (fs.existsSync(packagePath)) {\n      packageJsonPath = packagePath;\n      break;\n    }\n\n    const nextPath = fs.resolve(currentPath, '..');\n\n    if (nextPath === currentPath) {\n      break;\n    }\n\n    currentPath = nextPath;\n  }\n\n  if (!packageJsonPath) {\n    throw new Error('Could not find package.json');\n  }\n\n  return JSON.parse(fs.readFileSync(packageJsonPath)) as {\n    name: string;\n    version: string;\n    bin?: {\n      [cmd: string]: string;\n    };\n    dependencies?: Record<string, string>;\n  };\n}\n\nexport function stringToArgs(str: string) {\n  const quotePairs = new Map<string, string>([\n    ['\"', '\"'],\n    [\"'\", \"'\"],\n    ['`', '`'],\n  ]);\n  const escapeChars = new Set(['\\\\']);\n\n  let activeQuote: string | undefined;\n\n  const args = [];\n  let currentArg = '';\n\n  let prev: string | undefined;\n  for (let i = 0; i < str.length; i++) {\n    const char = str[i];\n    if (activeQuote) {\n       \n      while (true) {\n        if (i >= str.length) {\n          break;\n        } else if (\n          str[i] === quotePairs.get(activeQuote) &&\n          !(prev && escapeChars.has(prev))\n        ) {\n          break;\n        }\n        if (!escapeChars.has(str[i])) {\n          currentArg += str[i];\n        }\n        prev = str[i];\n        i++;\n      }\n      activeQuote = undefined;\n    } else if (quotePairs.has(char) && !(prev && escapeChars.has(prev))) {\n      activeQuote = char;\n    } else if (\n      char === ' ' &&\n      prev !== ' ' &&\n      !(prev && escapeChars.has(prev))\n    ) {\n      args.push(currentArg);\n      currentArg = '';\n    } else if (!escapeChars.has(char) || (prev && escapeChars.has(prev))) {\n      currentArg += char;\n    }\n    prev = char;\n  }\n  args.push(currentArg);\n  return args;\n}\n\n/**\n * Resolves the arguments added to a CLI instance by a builder function. Useful\n * for typing the arguments of a command handler when using composable builders.\n *\n * @typeParam T - A function that takes a CLI instance and returns a new CLI instance with additional options, commands etc.\n */\nexport type ArgumentsOf<T> = T extends (...args: any[]) => CLI<infer TArgs>\n  ? Expand<TArgs>\n  : never;\n"," \nimport {\n  ArgvParser,\n  EnvOptionConfig,\n  LocalizationDictionary,\n  LocalizationFunction,\n  OptionConfig,\n  ParsedArgs,\n  ValidationFailedError,\n  fromCamelOrDashedCaseToConstCase,\n  hideBin,\n  type ConfigurationFiles,\n} from '@cli-forge/parser';\nimport { readOptionGroupsForCLI } from './cli-option-groups';\nimport { contextStorage, ForgeContextData } from './async-context';\nimport { getCommandContext } from './context';\nimport type { CommandContext, ProvidersFromChain } from './context';\nimport { formatHelp } from './format-help';\n// Lazy-imported to avoid pulling Node-only modules (readline, child_process)\n// into the module graph when bundled for the browser.\ntype InteractiveShellModule = typeof import('./interactive-shell.js');\nlet _shellModule: InteractiveShellModule | null = null;\nasync function getInteractiveShellModule(): Promise<InteractiveShellModule> {\n  if (!_shellModule) {\n    _shellModule = await import('./interactive-shell.js');\n  }\n  return _shellModule;\n}\nimport {\n  AnyCLI,\n  CLI,\n  CLICommandOptions,\n  CLIHandlerContext,\n  Command,\n  ErrorHandler,\n  SDKCommand,\n} from './public-api';\nimport type {\n  CompletionCallback,\n  OptionCompletionCallback,\n} from './completion-types';\nimport type { PromptProvider, PromptOptionConfig } from './prompt-types';\nimport { resolvePrompts } from './resolve-prompts';\nimport { getCallingFile, getParentPackageJson } from './utils';\n\n/** Type alias for an InternalCLI instance with any type parameters. */\nexport type AnyInternalCLI = InternalCLI<any, any, any, any, any>;\n\ntype ProviderRegistration =\n  | { type: 'eager'; value: unknown }\n  | { type: 'factory'; factory: Function; lifetime: 'global' | 'executionScope' };\n\n/**\n * Monotonic counter used to stamp every `InternalCLI` instance with a\n * process-unique `commandId` at construction time. Used by\n * {@link getCommandContext} to verify at runtime that a CLI instance passed\n * as a type witness actually belongs to the currently-executing command\n * chain — which catches the class of bug where the user passes the wrong\n * CLI (a sibling, an unrelated app) as the type witness and silently gets\n * incorrect `inject()` types.\n */\nlet _internalCliIdCounter = 0;\n\n/**\n * The base class for a CLI application. This class is used to define the structure of the CLI.\n *\n * {@link cli} is provided as a small helper function to create a new CLI instance.\n *\n * @example\n * ```ts\n * import { cli } from 'cli-forge';\n *\n * cli('basic-cli').command('hello', {\n *   builder: (args) =>\n *    args.option('name', {\n *      type: 'string',\n *    }),\n *   handler: (args) => {\n *     console.log(`Hello, ${args.name}!`);\n *   }).forge();\n * ```\n */\n/**\n * Cross-realm brand symbol used to identify InternalCLI instances across\n * different copies of the cli-forge package (e.g. when pnpm resolves\n * multiple copies due to differing peer dependencies). `Symbol.for()`\n * returns the same symbol globally, so the brand check works even when\n * `instanceof` would fail.\n */\nconst CLI_FORGE_BRAND = Symbol.for('cli-forge:InternalCLI');\n\nexport class InternalCLI<\n  TArgs extends ParsedArgs = ParsedArgs,\n  THandlerReturn = void,\n\n  TChildren = {},\n  TParent = undefined,\n  TProviders = {}\n> implements CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>\n{\n  /**\n   * Cross-realm brand for identifying InternalCLI instances across\n   * different package copies. See {@link CLI_FORGE_BRAND}.\n   */\n  readonly [CLI_FORGE_BRAND] = true;\n\n  /**\n   * Check whether `obj` is an InternalCLI instance, even when it was\n   * created by a different copy of the cli-forge package.\n   */\n  static isInternalCLI(\n    obj: unknown\n  ): obj is AnyInternalCLI {\n    return (\n      obj != null &&\n      typeof obj === 'object' &&\n      CLI_FORGE_BRAND in obj\n    );\n  }\n\n  /**\n   * For internal use only. Stick to properties available on {@link CLI}.\n   */\n  registeredCommands: Record<string, AnyInternalCLI> = {};\n\n  /**\n   * Process-unique identifier stamped at construction time. Used to\n   * validate at runtime that a CLI instance passed to `getCommandContext`\n   * actually belongs to the active command chain. Never mutated once set —\n   * builders, handlers, and middleware see the same value for the lifetime\n   * of the instance, even across clones.\n   *\n   * For internal use only.\n   */\n  readonly commandId: string;\n\n  /**\n   * Registered DI providers keyed by name.\n   * For internal use only.\n   */\n  registeredProviders: Map<string, ProviderRegistration> = new Map();\n\n  /**\n   * For internal use only. Stick to properties available on {@link CLI}.\n   */\n  commandChain: string[] = [];\n\n  /**\n   * Reference to the parent CLI instance, if this command was registered as a subcommand.\n   * For internal use only. Use `getParent()` instead.\n   */\n  private _parent?: AnyInternalCLI;\n\n  private requiresCommand: 'IMPLICIT' | 'EXPLICIT' | false = 'IMPLICIT';\n\n  private _configuration?: CLICommandOptions<any, any>;\n\n  private _versionOverride?: string;\n\n  private registeredErrorHandlers: Array<ErrorHandler> = [\n    (e: unknown, actions) => {\n      if (e instanceof ValidationFailedError) {\n        this.printHelp();\n        console.log();\n        console.log(e.message);\n        console.log(e.errors.map((e) => `  - ${e.message}`).join('\\n'));\n        actions.exit(1);\n      }\n    },\n  ];\n\n  private registeredMiddleware = new Set<\n    (args: TArgs) => void | unknown | Promise<void> | Promise<unknown>\n  >();\n\n  private registeredInitHooks: Array<\n    (cli: any, args: TArgs) => Promise<void> | void\n  > = [];\n\n  registeredPromptProviders: PromptProvider[] = [];\n\n  /**\n   * Stores prompt config for each option, keyed by option name.\n   * Set when .option() is called with a `prompt` property.\n   */\n  promptConfigs: Map<string, PromptOptionConfig<any>> = new Map();\n\n  /**\n   * Custom completion callback for this command level.\n   * Set when .completion() is called with a callback argument.\n   */\n  completionCallback?: CompletionCallback<any>;\n\n  /**\n   * Per-option completion callbacks, keyed by option name.\n   * Set when .option() is called with a `completion` property.\n   */\n  completionConfigs: Map<string, OptionCompletionCallback<any>> = new Map();\n\n  /**\n   * Whether .completion() has been called on this CLI instance.\n   */\n  private _completionEnabled = false;\n\n  /**\n   * Set when a `$0` alias replaces the root builder via `.command()`.\n   * The $0 builder should only run if no explicit subcommand is given,\n   * so `forge()` defers it until the discovery loop confirms no match.\n   */\n  private builderIsFrom$0Alias = false;\n\n  /**\n   * A list of option groups that have been registered with the CLI. Grouped Options are displayed together in the help text.\n   *\n   * For internal use only. Stick to properties available on {@link CLI}.\n   */\n  registeredOptionGroups: Array<{\n    label: string;\n    sortOrder: number;\n    keys: Array<keyof TArgs>;\n  }> = [];\n\n  getGroupedOptions() {\n    return readOptionGroupsForCLI(this);\n  }\n\n  get configuration() {\n    return this._configuration;\n  }\n\n  private set configuration(value: CLICommandOptions<any, any> | undefined) {\n    this._configuration = value;\n  }\n\n  /**\n   * The parser used to parse the arguments for the current command.\n   *\n   * Meant for internal use only. Stick to properties available on {@link CLI}.\n   *\n   * If you need this kind of info, please open an issue on the GitHub repo with\n   * your use case.\n   */\n  parser = new ArgvParser<TArgs>({\n    unmatchedParser: (arg) => {\n      // eslint-disable-next-line @typescript-eslint/no-this-alias\n      let currentCommand: AnyInternalCLI = this;\n      for (const command of this.commandChain) {\n        currentCommand = currentCommand.registeredCommands[command];\n      }\n      const command = currentCommand.registeredCommands[arg];\n      if (command && command.configuration) {\n        command.parser = this.parser;\n        command.configuration.builder?.(command as any);\n        this.commandChain.push(arg);\n        return true;\n      }\n      return false;\n    },\n  })\n    .option('help', {\n      type: 'boolean',\n      alias: ['h'],\n      description: 'Show help for the current command',\n    })\n    .option('version', {\n      type: 'boolean',\n      description: 'Show the version number for the CLI',\n    });\n\n  /**\n   * @param name What should the name of the cli command be?\n   * @param configuration Configuration for the current CLI command.\n   */\n  constructor(\n    public name: string,\n    rootCommandConfiguration?: CLICommandOptions<\n      TArgs,\n      any,\n      THandlerReturn,\n      TChildren\n    >\n  ) {\n    // Stamp a stable, immutable identifier so `getCommandContext(cli)` can\n    // verify at runtime that this instance is part of the active command\n    // chain. The format is `${name}#${counter}` for debuggability — the\n    // counter guarantees uniqueness even when two commands share a name.\n    this.commandId = `${name}#${++_internalCliIdCounter}`;\n    if (rootCommandConfiguration) {\n      this.withRootCommandConfiguration(rootCommandConfiguration as any);\n    } else {\n      this.requiresCommand = 'IMPLICIT';\n    }\n  }\n\n  withRootCommandConfiguration<TRootCommandArgs extends TArgs>(\n    configuration: CLICommandOptions<TArgs, TRootCommandArgs>\n  ): InternalCLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    this.configuration = configuration;\n    this.requiresCommand = configuration.handler ? false : 'IMPLICIT';\n    return this;\n  }\n\n  command<\n    TCommand extends Command<TArgs, any, any, any>\n  >(\n    cmd: TCommand\n  ): CLI<\n    TArgs,\n    THandlerReturn,\n    TChildren & import('./public-api').CommandToChildEntry<\n      TCommand,\n      CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>\n    >,\n    TParent,\n    TProviders\n  >;\n  command<\n    TCommandArgs extends TArgs,\n    TChildHandlerReturn = void,\n    TCommandName extends string = string,\n    TChildChildren = {},\n    TChildProviders = {}\n  >(\n    key: TCommandName,\n    options: CLICommandOptions<\n      TArgs,\n      TCommandArgs,\n      TChildHandlerReturn,\n      TChildren,\n      CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>,\n      TChildChildren,\n      TChildProviders\n    >\n  ): CLI<\n    TArgs,\n    THandlerReturn,\n    TChildren & {\n      [key in TCommandName]: CLI<\n        TCommandArgs,\n        TChildHandlerReturn,\n        TChildChildren,\n        CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>,\n        TChildProviders\n      >;\n    },\n    TParent,\n    TProviders\n  >;\n  command(\n    keyOrCommand: string | Command<any, any, any, any>,\n    options?: CLICommandOptions<any, any, any, any, any, any, any>\n  ): any {\n    if (typeof keyOrCommand === 'string') {\n      const key = keyOrCommand;\n      if (!options) {\n        throw new Error(\n          'options must be provided when calling `command` with a string'\n        );\n      }\n      if (key === '$0' || options.alias?.includes('$0')) {\n        this.withRootCommandConfiguration({\n          ...this._configuration,\n          builder: options.builder as any,\n          handler: options.handler as any,\n          description: options.description,\n        });\n        // Only defer the builder when it came from an alias (e.g.,\n        // command('search', { alias: ['$0'] })). When key === '$0',\n        // the command IS the root and its builder should run normally.\n        if (key !== '$0' && options.alias?.includes('$0')) {\n          this.builderIsFrom$0Alias = true;\n        }\n      }\n      const cmd = new InternalCLI<TArgs, TChildHandlerReturn>(\n        key\n      ).withRootCommandConfiguration(options as any);\n      cmd._parent = this;\n\n      // Get localized command name\n      const localizedKey = this.getLocalizedCommandName(key);\n\n      // Register under the default key\n      this.registeredCommands[key] = cmd;\n\n      // If localized name is different, also register under localized name as an alias\n      if (localizedKey !== key) {\n        this.registeredCommands[localizedKey] = cmd;\n      }\n\n      if (options.alias) {\n        for (const alias of options.alias) {\n          this.registeredCommands[alias] = cmd;\n        }\n      }\n    } else if (InternalCLI.isInternalCLI(keyOrCommand)) {\n      const cmd = keyOrCommand as AnyInternalCLI;\n      if (cmd.name === '$0') {\n        this.withRootCommandConfiguration(cmd.configuration as any);\n        // Copy any commands registered on the $0 instance (e.g. subcommands\n        // added via `.commands()` after the $0 CLI was created).\n        for (const [key, subcmd] of Object.entries(cmd.registeredCommands)) {\n          subcmd._parent = this;\n          this.registeredCommands[key] = subcmd;\n        }\n        return this as any;\n      }\n      cmd._parent = this;\n      this.registeredCommands[cmd.name] = cmd;\n      if (cmd.configuration?.alias) {\n        for (const alias of cmd.configuration.alias) {\n          this.registeredCommands[alias] = cmd;\n        }\n      }\n    } else {\n      const { name, ...configuration } = keyOrCommand as {\n        name: string;\n      } & CLICommandOptions<TArgs, TCommandArgs>;\n      this.command<TCommandArgs>(name, configuration);\n    }\n    return this as any;\n  }\n\n  commands(...a0: Command[] | Command[][]): any {\n    const commands = a0.flat();\n    for (const val of commands) {\n      this.command(val);\n    }\n    return this;\n  }\n\n  option<\n    TOption extends string,\n    const TOptionConfig extends OptionConfig<any, any, any>\n  >(\n    name: TOption,\n    config: TOptionConfig & {\n      prompt?: PromptOptionConfig<TArgs>;\n      completion?: OptionCompletionCallback<TArgs>;\n    }\n  ) {\n    const { prompt, completion: completionCb, ...parserConfig } = config;\n    if (prompt !== undefined) {\n      this.promptConfigs.set(name, prompt);\n    }\n    if (completionCb !== undefined) {\n      this.completionConfigs.set(name, completionCb);\n    }\n    this.parser.option(name, parserConfig as TOptionConfig);\n    // Interface modifies the return type to reflect new params, cast is necessay.... I think 🤔\n    return this as any;\n  }\n\n  positional<\n    TOption extends string,\n    const TOptionConfig extends OptionConfig<any, any, any>\n  >(\n    name: TOption,\n    config: TOptionConfig & {\n      prompt?: PromptOptionConfig<TArgs>;\n      completion?: OptionCompletionCallback<TArgs>;\n    }\n  ) {\n    const { prompt, completion: completionCb, ...parserConfig } = config;\n    if (prompt !== undefined) {\n      this.promptConfigs.set(name, prompt);\n    }\n    if (completionCb !== undefined) {\n      this.completionConfigs.set(name, completionCb);\n    }\n    this.parser.positional(name, parserConfig as TOptionConfig);\n    // Interface modifies the return type to reflect new params, cast is necessay.... I think 🤔\n    return this as any;\n  }\n\n  conflicts(\n    ...args: [string, string, ...string[]]\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    this.parser.conflicts(...args);\n    return this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  }\n\n  implies(\n    option: string,\n    ...impliedOptions: string[]\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    this.parser.implies(option, ...impliedOptions);\n    return this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  }\n\n  env(\n    a0: string | EnvOptionConfig | undefined = fromCamelOrDashedCaseToConstCase(\n      this.name\n    )\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    if (typeof a0 === 'string') {\n      this.parser.env(a0);\n    } else {\n      a0.prefix ??= fromCamelOrDashedCaseToConstCase(this.name);\n      this.parser.env(a0);\n    }\n    return this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  }\n\n  localize(\n    dictionaryOrFn: LocalizationDictionary | LocalizationFunction,\n    locale?: string\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    if (typeof dictionaryOrFn === 'function') {\n      this.parser.localize(dictionaryOrFn);\n    } else {\n      this.parser.localize(dictionaryOrFn, locale);\n    }\n    return this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  }\n\n  /**\n   * Gets the localized display name for a command key.\n   * @param key The command key\n   * @returns The localized command name, or the original key if not localized\n   */\n  getLocalizedCommandName(key: string): string {\n    return this.parser.getDisplayKey(key);\n  }\n\n  demandCommand(): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    this.requiresCommand = 'EXPLICIT';\n    return this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  }\n\n  strict(enable = true): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    this.parser.options.strict = enable;\n    return this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  }\n\n  usage(usageText: string): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    this.configuration ??= {};\n    this.configuration.usage = usageText;\n    return this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  }\n\n  hidden(hidden = true): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    this.configuration ??= {};\n    this.configuration.hidden = hidden;\n    return this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  }\n\n  examples(\n    ...examples: string[]\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    this.configuration ??= {};\n    this.configuration.examples ??= [];\n    this.configuration.examples.push(...examples);\n    return this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  }\n\n  version(version?: string): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    this._versionOverride = version;\n    return this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  }\n\n  /**\n   * Gets help text for the current command as a string.\n   * @returns Help text for the current command.\n   */\n  formatHelp() {\n    return formatHelp(this);\n  }\n\n  /**\n   * Prints help text for the current command to the console.\n   */\n  printHelp() {\n    console.log(this.formatHelp());\n  }\n\n  middleware<TArgs2>(\n    callback: (args: TArgs) => TArgs2 | Promise<TArgs2> | void | Promise<void>\n  ): CLI<\n    TArgs2 extends void ? TArgs : TArgs & TArgs2,\n    THandlerReturn,\n    TChildren,\n    TParent,\n    TProviders\n  > {\n    this.registeredMiddleware.add(callback);\n    // If middleware returns void, TArgs doesn't change...\n    // If it returns something, we need to merge it into TArgs...\n    // that's not here though, its where we apply the middleware results.\n    return this as any;\n  }\n\n  handler<R>(\n    fn: (args: TArgs, context: any) => R\n  ): CLI<TArgs, R, TChildren, TParent, TProviders> {\n    if (!this._configuration) {\n      this._configuration = {};\n    }\n    this._configuration.handler = fn as any;\n    this.requiresCommand = false;\n    return this as any;\n  }\n\n  provide(key: string, valueOrConfig: unknown): any {\n    if (this.registeredProviders.has(key)) {\n      throw new Error(`Provider '${key}' is already registered on this command.`);\n    }\n    if (\n      valueOrConfig !== null &&\n      typeof valueOrConfig === 'object' &&\n      'factory' in valueOrConfig &&\n      typeof (valueOrConfig as any).factory === 'function'\n    ) {\n      const config = valueOrConfig as { factory: Function; lifetime?: string };\n      this.registeredProviders.set(key, {\n        type: 'factory',\n        factory: config.factory,\n        lifetime: (config.lifetime as 'global' | 'executionScope') ?? 'executionScope',\n      });\n    } else {\n      this.registeredProviders.set(key, { type: 'eager', value: valueOrConfig });\n    }\n    return this;\n  }\n\n  init(\n    callback: (\n      cli: CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>,\n      args: TArgs\n    ) => Promise<void> | void\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    this.registeredInitHooks.push(callback);\n    return this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  }\n\n  completion(\n    callback?: CompletionCallback<any>\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    this._completionEnabled = true;\n    if (callback) {\n      this.completionCallback = callback;\n    }\n\n    // Only register completion infrastructure at root level (no parent)\n    if (!this._parent) {\n      this.parser.option('getCompletions', {\n        type: 'boolean',\n        hidden: true,\n        description: 'Output shell completion suggestions',\n      } as any);\n\n      this.command('completion', {\n        description: 'Install shell completion scripts',\n        handler: async () => {\n          const { installCompletionScripts } = await import(\n            './completion-scripts.js'\n          );\n          await installCompletionScripts(this.name);\n        },\n      });\n    }\n\n    return this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  }\n\n  /**\n   * Runs the current command.\n   * @param cmd The command to run.\n   * @param args The arguments to pass to the command.\n   */\n  async runCommand<T extends ParsedArgs>(\n    args: T,\n    originalArgV: string[],\n    executedMiddleware?: Set<(args: any) => void>\n  ): Promise<T> {\n    const middlewares = new Set<(args: any) => void>(this.registeredMiddleware);\n    // eslint-disable-next-line @typescript-eslint/no-this-alias\n    let cmd: AnyInternalCLI = this;\n    for (const command of this.commandChain) {\n      cmd = cmd.registeredCommands[command];\n      for (const mw of cmd.registeredMiddleware) {\n        middlewares.add(mw);\n      }\n    }\n    try {\n      if (cmd.requiresCommand) {\n        throw new Error(\n          `${[this.name, ...this.commandChain].join(' ')} requires a command`\n        );\n      }\n      if (cmd.configuration?.handler) {\n        for (const middleware of middlewares) {\n          if (executedMiddleware?.has(middleware)) continue;\n          const middlewareResult = await middleware(args as any);\n          if (\n            middlewareResult !== void 0 &&\n            typeof middlewareResult === 'object'\n          ) {\n            args = middlewareResult as T;\n          }\n        }\n        // Keep ALS context args in sync after middleware transformations\n        const store = contextStorage.getStore();\n        if (store) {\n          store.args = args as Record<string, unknown>;\n        }\n        await cmd.configuration.handler(args, {\n          command: cmd as any,\n        });\n        return args;\n      } else {\n        // We can treat a command as a subshell if it has subcommands\n        if (Object.keys(cmd.registeredCommands).length > 0) {\n          if (typeof process === 'undefined' || !process.stdout?.isTTY) {\n            // If we're not in a TTY (or in a browser), we can't run an interactive shell...\n            // Maybe we should warn here?\n          } else if (args.unmatched.length > 0) {\n            // If there are unmatched args, we don't run an interactive shell...\n            // this could represent a user misspelling a subcommand so it gets rather confusing.\n            console.warn(\n              `Warning: Unrecognized command or arguments: ${args.unmatched.join(\n                ' '\n              )}`\n            );\n            cmd.printHelp();\n          } else {\n            const shellMod = await getInteractiveShellModule();\n            if (!shellMod.INTERACTIVE_SHELL) {\n              const tui = new shellMod.InteractiveShell(\n                this as unknown as AnyInternalCLI,\n                {\n                  prependArgs: originalArgV,\n                }\n              );\n              await new Promise<void>((res) => {\n                ['SIGINT', 'SIGTERM', 'SIGQUIT'].forEach((s) =>\n                  process?.on(s, () => {\n                    tui.close();\n                    res();\n                  })\n                );\n              });\n            }\n          }\n        }\n        // No subcommands so subshell doesn't make sense\n        // No handler, so nothing to run\n        else {\n          throw new Error(\n            `${[this.name, ...this.commandChain].join(' ')} is not implemented.`\n          );\n        }\n      }\n    } catch (e) {\n      if (typeof process !== 'undefined') process.exitCode = 1;\n      console.error(e);\n      this.printHelp();\n    }\n    return args;\n  }\n\n  getChildren(): TChildren {\n    // Return a copy of registered commands, excluding aliases (same command registered under different keys)\n    const children: Record<string, AnyInternalCLI> = {};\n    const seen = new Set<AnyInternalCLI>();\n    for (const [key, cmd] of Object.entries(this.registeredCommands)) {\n      if (!seen.has(cmd)) {\n        seen.add(cmd);\n        children[key] = cmd;\n      }\n    }\n    return children as TChildren;\n  }\n\n  getParent(): TParent {\n    return this._parent as TParent;\n  }\n\n  getContext(): CommandContext<\n    TArgs,\n    ProvidersFromChain<TProviders, TParent>,\n    TChildren\n  > {\n    // Delegate to getCommandContext(this) so the runtime chain validation\n    // and error messaging stay in a single place.\n    return getCommandContext(\n      this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>\n    ) as CommandContext<\n      TArgs,\n      ProvidersFromChain<TProviders, TParent>,\n      TChildren\n    >;\n  }\n\n  getBuilder():\n    | (<\n        TInit extends ParsedArgs,\n        TInitHandlerReturn,\n        TInitChildren,\n        TInitParent,\n        TInitProviders\n      >(\n        parser: CLI<TInit, TInitHandlerReturn, TInitChildren, TInitParent, TInitProviders>\n      ) => CLI<\n        TInit & TArgs,\n        TInitHandlerReturn,\n        TInitChildren & TChildren,\n        TInitParent,\n        TInitProviders\n      >)\n    | undefined {\n    const builder = this.configuration?.builder;\n    if (!builder) return undefined;\n    // Return a composable builder that preserves input types\n    return ((parser: AnyCLI) => builder(parser)) as any;\n  }\n\n  getHandler():\n    | ((args: Omit<TArgs, keyof ParsedArgs>) => THandlerReturn)\n    | undefined {\n    const context: CLIHandlerContext<TChildren, TParent> = {\n      command: this as unknown as CLI<any, any, TChildren, TParent, any>,\n    };\n    const handler = this._configuration?.handler;\n    if (!handler) {\n      return undefined;\n    }\n    return (args: Omit<TArgs, keyof ParsedArgs>) =>\n      handler(\n        args as TArgs,\n        context as CLIHandlerContext<any, any>\n      ) as THandlerReturn;\n  }\n\n  sdk(): SDKCommand<TArgs, THandlerReturn, TChildren> {\n    return this.buildSDKProxy(this) as SDKCommand<\n      TArgs,\n      THandlerReturn,\n      TChildren\n    >;\n  }\n\n  private buildSDKProxy(targetCmd: AnyInternalCLI): unknown {\n    // eslint-disable-next-line @typescript-eslint/no-this-alias\n    const self = this;\n\n    const invoke = async (\n      argsOrArgv?: Record<string, unknown> | string[]\n    ): Promise<THandlerReturn & { $args?: TArgs }> => {\n      // Clone the target command to avoid mutating the original\n      const cmd = targetCmd.clone();\n\n      const handler = cmd._configuration?.handler;\n      if (!handler) {\n        throw new Error(`Command '${cmd.name}' has no handler`);\n      }\n\n      let parsedArgs: any;\n\n      if (Array.isArray(argsOrArgv)) {\n        // String array: full pipeline (parse → validate → middleware)\n        // Run the builder first if present\n        if (cmd._configuration?.builder) {\n          cmd._configuration.builder(cmd as any);\n        }\n        parsedArgs = cmd.parser.parse(argsOrArgv);\n      } else {\n        // Object args: skip validation, apply defaults, run middleware\n        // Run the builder first to register options and get defaults\n        if (cmd._configuration?.builder) {\n          cmd._configuration.builder(cmd as any);\n        }\n        // Build defaults from configured options\n        const defaults: Record<string, unknown> = {};\n        for (const [key, config] of Object.entries(\n          cmd.parser.configuredOptions\n        )) {\n          if (config.default !== undefined) {\n            defaults[key] = config.default;\n          }\n        }\n        parsedArgs = {\n          ...defaults,\n          ...argsOrArgv,\n          unmatched: [],\n        };\n      }\n\n      // Collect and run middleware from the command chain\n      const middlewares = self.collectMiddlewareChain(targetCmd);\n      for (const mw of middlewares) {\n        const middlewareResult = await mw(parsedArgs);\n        if (\n          middlewareResult !== void 0 &&\n          typeof middlewareResult === 'object'\n        ) {\n          parsedArgs = middlewareResult;\n        }\n      }\n\n      // Build context data for ALS — collect providers from root down to cmd.\n      // Use targetCmd (not the clone) because clone() does not copy _parent.\n      const providerChain: AnyInternalCLI[] = [];\n      let providerWalk: AnyInternalCLI | undefined = targetCmd;\n      while (providerWalk) {\n        providerChain.unshift(providerWalk);\n        providerWalk = providerWalk._parent;\n      }\n      const sdkContextData: ForgeContextData = {\n        args: parsedArgs as Record<string, unknown>,\n        commandChain: [],\n        // providerChain walks root -> ...ancestors -> targetCmd already,\n        // so we reuse it for the id chain that getCommandContext validates.\n        commandIdChain: providerChain.map((c) => c.commandId),\n        providers: new Map(),\n        providerFactories: new Map(),\n        handlerPhase: true,\n        resolving: new Set(),\n      };\n      for (const providerNode of providerChain) {\n        for (const [key, reg] of providerNode.registeredProviders) {\n          if (reg.type === 'eager') {\n            sdkContextData.providers.set(key, reg.value);\n          } else {\n            sdkContextData.providerFactories.set(key, {\n              factory: reg.factory,\n              lifetime: reg.lifetime,\n            });\n          }\n        }\n      }\n\n      // Execute handler inside ALS context\n      const context: CLIHandlerContext<any, any> = {\n        command: cmd as unknown as AnyCLI,\n      };\n      const result = await contextStorage.run(sdkContextData, async () => {\n        return handler(parsedArgs, context);\n      });\n\n      // Try to attach $args to the result (fails silently for primitives)\n      if (result !== null && typeof result === 'object') {\n        try {\n          (result as any).$args = parsedArgs;\n        } catch {\n          // Cannot attach to frozen objects or primitives, return as-is\n        }\n      }\n\n      return result as any as THandlerReturn & { $args?: TArgs };\n    };\n\n    // Ensure builder has run to register all subcommands\n    if (targetCmd._configuration?.builder) {\n      targetCmd._configuration.builder(targetCmd as any);\n    }\n\n    // Create proxy that is both callable and has child properties\n    return new Proxy(invoke, {\n      get(_, prop: string) {\n        // Handle special properties\n        if (prop === 'then' || prop === 'catch' || prop === 'finally') {\n          // Don't intercept Promise methods - this prevents issues with await\n          return undefined;\n        }\n\n        const child = targetCmd.registeredCommands[prop];\n        if (child) {\n          return self.buildSDKProxy(child);\n        }\n        return undefined;\n      },\n    });\n  }\n\n  private collectMiddlewareChain(\n    cmd: AnyInternalCLI\n  ): Array<(args: any) => unknown | Promise<unknown>> {\n    const chain: AnyInternalCLI[] = [];\n    let current: AnyInternalCLI | undefined = cmd;\n    while (current) {\n      chain.unshift(current);\n      current = current._parent;\n    }\n    const seen = new Set<(args: any) => unknown | Promise<unknown>>();\n    for (const c of chain) {\n      for (const mw of c.registeredMiddleware) {\n        seen.add(mw);\n      }\n    }\n    return [...seen];\n  }\n\n  enableInteractiveShell(): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    if (this.requiresCommand === 'EXPLICIT') {\n      throw new Error(\n        'Interactive shell is not supported for commands that require a command.'\n      );\n    } else if (typeof process !== 'undefined' && process.stdout?.isTTY) {\n      this.requiresCommand = false;\n    }\n    return this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  }\n\n  private versionHandler() {\n    if (this._versionOverride) {\n      console.log(this._versionOverride);\n      return;\n    }\n    let mainFile = typeof require !== 'undefined' ? require?.main?.filename : undefined;\n    mainFile ??= getCallingFile();\n    if (!mainFile) {\n      console.log('unknown');\n      return;\n    }\n    try {\n      const packageJson = getParentPackageJson(mainFile);\n      console.log(packageJson.version ?? 'unknown');\n    } catch {\n      console.log('unknown');\n    }\n  }\n\n  private async withErrorHandlers<T>(cb: () => T): Promise<Awaited<T>> {\n    try {\n      return await cb();\n    } catch (e) {\n      for (const handler of this.registeredErrorHandlers) {\n        try {\n          handler(e, {\n            exit: (c) => {\n              if (typeof process !== 'undefined') process.exit(c);\n            },\n          });\n          // Error was handled, no need to continue\n          break;\n        } catch {\n          // Error was not handled, continue to the next handler\n        }\n      }\n      throw e;\n    }\n  }\n\n  errorHandler(\n    handler: ErrorHandler\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    this.registeredErrorHandlers.unshift(handler);\n    return this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  }\n\n  withPromptProvider(\n    provider: PromptProvider\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    if (!provider.prompt && !provider.promptBatch) {\n      throw new Error(\n        \"Prompt provider must implement at least one of 'prompt' or 'promptBatch'\"\n      );\n    }\n    this.registeredPromptProviders.push(provider);\n    return this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  }\n\n  group(\n    labelOrConfigObject:\n      | string\n      | { label: string; keys: (keyof TArgs)[]; sortOrder?: number },\n    keys?: (keyof TArgs)[]\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    const config =\n      typeof labelOrConfigObject === 'object'\n        ? labelOrConfigObject\n        : {\n            label: labelOrConfigObject,\n            keys: keys as (keyof TArgs)[],\n          };\n\n    if (!config.keys) {\n      throw new Error('keys must be provided when calling `group`.');\n    }\n\n    this.registeredOptionGroups.push({\n      ...config,\n      sortOrder:\n        config.sortOrder ?? Object.keys(this.registeredOptionGroups).length,\n    });\n    return this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  }\n\n  config(\n    provider: ConfigurationFiles.AnyConfigProvider<TArgs>\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders> {\n    this.parser.config(\n      provider as ConfigurationFiles.AnyConfigProvider<any>\n    );\n    return this as unknown as CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  }\n\n  async updateConfig(values: Partial<TArgs>): Promise<void>;\n  async updateConfig(\n    updater: ConfigurationFiles.ConfigUpdater<TArgs>\n  ): Promise<void>;\n  async updateConfig(\n    valuesOrUpdater:\n      | Partial<TArgs>\n      | ConfigurationFiles.ConfigUpdater<TArgs>\n  ): Promise<void> {\n    return this.parser.updateConfig(valuesOrUpdater as any);\n  }\n\n  /**\n   * Parses argv and executes the CLI.\n   *\n   * Execution proceeds in two phases:\n   *\n   * **Discovery loop** (per command level): builder → parse (non-strict,\n   * no validation) → merge → middleware → init hooks → find next\n   * subcommand in unmatched tokens → repeat.\n   *\n   * **Final parse + execution**: parse (with validation, seeded with\n   * accumulated args) → help/version check → handler. Middleware that\n   * already ran during discovery is skipped.\n   *\n   * @param args argv. Defaults to process.argv.slice(2)\n   * @returns Promise that resolves when the handler completes.\n   */\n  forge = (args: string[] = typeof process !== 'undefined' ? hideBin(process.argv) : []) =>\n    this.withErrorHandlers(async () => {\n      let argv: TArgs & { help?: boolean; version?: boolean };\n      let validationFailedError: ValidationFailedError<TArgs> | undefined;\n\n      // Run root builder (may register options, init hooks, commands).\n      // If the builder came from a $0 alias, skip it here — we defer\n      // running it until the discovery loop confirms no explicit\n      // subcommand was given, so it doesn't double-run when the\n      // command is invoked by name.\n      if (!this.builderIsFrom$0Alias) {\n        this.configuration?.builder?.(this as any);\n      }\n\n      // Merge helper: accumulate defined values without overwriting\n      const mergeNew = (target: any, source: any) => {\n        for (const [key, value] of Object.entries(source)) {\n          if (\n            key !== 'unmatched' &&\n            value !== undefined &&\n            target[key] === undefined\n          ) {\n            target[key] = value;\n          }\n        }\n      };\n\n      // Check if this is a completion request — enable lenient parsing\n      // so incomplete argv (e.g. `--env \"\"`) doesn't throw.\n      const isCompletionRequest =\n        this._completionEnabled &&\n        args.some(\n          (a) => a === '--get-completions' || a === '--getCompletions'\n        );\n\n      // Iterative command discovery with init hooks.\n      // Each level: non-strict parse filtered args → run middleware\n      // → run init hooks → find next command in unmatched tokens\n      // → filter down. Builders stay lazy.\n      let currentArgs = [...args];\n      // eslint-disable-next-line @typescript-eslint/no-this-alias\n      let currentCmd: AnyInternalCLI = this;\n      const mergedArgs: any = {};\n      const executedMiddleware = new Set<(args: any) => void>();\n\n       \n      while (true) {\n        // Non-strict parse to get current arg values for init hooks.\n        // Seeded with mergedArgs so required options parsed at earlier\n        // levels satisfy validation.\n        // The unmatchedParser intercepts subcommand tokens before\n        // positional matching can greedily consume them.\n        let discoveredCommand: string | null = null;\n        const parsed = this.parser\n          .clone({\n            ...this.parser.options,\n            unmatchedParser: (arg) => {\n              if (!discoveredCommand && !arg.startsWith('-')) {\n                const cmd = currentCmd.registeredCommands[arg];\n                if (cmd && cmd.configuration) {\n                  discoveredCommand = arg;\n                  return true;\n                }\n              }\n              return false;\n            },\n            strict: false,\n            validate: false,\n            lenient: isCompletionRequest,\n          })\n          .parse(currentArgs, mergedArgs) as any;\n\n        mergeNew(mergedArgs, parsed);\n\n        // Run middleware for this command level before init hooks,\n        // so init hooks can see middleware-transformed args.\n        for (const mw of currentCmd.registeredMiddleware) {\n          if (!executedMiddleware.has(mw)) {\n            executedMiddleware.add(mw);\n            const result = await mw(mergedArgs);\n            if (result !== void 0 && typeof result === 'object') {\n              Object.assign(mergedArgs, result);\n            }\n          }\n        }\n\n        // Run init hooks with the full accumulated args\n        for (const hook of currentCmd.registeredInitHooks) {\n          await hook(currentCmd as any, mergedArgs);\n        }\n\n        // Build the next command if one was discovered during parsing\n        // (i.e., subcommand token intercepted before positional matching)\n        let nextCmd: AnyInternalCLI | null = null;\n        if (discoveredCommand) {\n          const cmd = currentCmd.registeredCommands[discoveredCommand];\n          cmd.parser = this.parser;\n          cmd.configuration?.builder?.(cmd as any);\n          this.commandChain.push(discoveredCommand);\n          nextCmd = cmd;\n          // An explicit subcommand was found — the $0 default path\n          // won't be taken, so clear the deferred builder flag.\n          this.builderIsFrom$0Alias = false;\n        }\n\n        // Scan unmatched tokens for commands that may have been registered\n        // dynamically by init hooks (these weren't in registeredCommands\n        // during parse, so the unmatchedParser couldn't intercept them).\n        const unmatched: string[] = parsed.unmatched ?? [];\n        const remainingArgs: string[] = [];\n\n        if (!nextCmd) {\n          for (const token of unmatched) {\n            if (!nextCmd && !token.startsWith('-')) {\n              const cmd = currentCmd.registeredCommands[token];\n              if (cmd && cmd.configuration) {\n                cmd.parser = this.parser;\n                cmd.configuration.builder?.(cmd as any);\n                this.commandChain.push(token);\n                nextCmd = cmd;\n                this.builderIsFrom$0Alias = false;\n                continue;\n              }\n            }\n            remainingArgs.push(token);\n          }\n        }\n\n        if (!nextCmd) {\n          // No explicit subcommand was found. If a $0 alias replaced\n          // the root builder, run it now so its options (e.g. positionals)\n          // get registered before the final parse.\n          if (this.builderIsFrom$0Alias) {\n            this.builderIsFrom$0Alias = false; // only run once\n            this.configuration?.builder?.(this as any);\n            // Re-run the loop iteration so the newly registered options\n            // participate in parsing.\n            currentArgs = unmatched;\n            continue;\n          }\n          currentArgs = unmatched;\n          break;\n        }\n        // If command found during parse, all unmatched are remaining args.\n        // If command found in post-init scan, use filtered remaining args.\n        currentArgs = discoveredCommand ? unmatched : remainingArgs;\n        currentCmd = nextCmd;\n      }\n\n      // All builders and init hooks have run. The parser now has\n      // all options registered.\n\n      // If this is a completion request, resolve completions now\n      // (after discovery so subcommand builders have run) but before\n      // the strict final parse.\n      if (isCompletionRequest) {\n        const completionArgv = args.filter(\n          (a) => a !== '--get-completions' && a !== '--getCompletions'\n        );\n        const { resolveCompletions } = await import(\n          './resolve-completions.js'\n        );\n        const completions = await resolveCompletions({\n          rootCLI: this,\n          argv: completionArgv,\n        });\n        for (const c of completions) {\n          console.log(c);\n        }\n        return mergedArgs as TArgs;\n      }\n\n      // Parse the remaining unmatched tokens\n      // seeded with the accumulated values from the discovery loop.\n      // The alreadyParsed values ensure proper required-option\n      // validation and prevent positional re-consumption.\n\n      // Prompt for missing option values before final validation.\n      // Collect prompt providers from the full command chain.\n      const allPromptProviders: PromptProvider[] = [\n        ...this.registeredPromptProviders,\n      ];\n      const allPromptConfigs = new Map(this.promptConfigs);\n      {\n        // eslint-disable-next-line @typescript-eslint/no-this-alias\n        let walkCmd: AnyInternalCLI = this;\n        for (const command of this.commandChain) {\n          walkCmd = walkCmd.registeredCommands[command];\n          for (const p of walkCmd.registeredPromptProviders) {\n            allPromptProviders.push(p);\n          }\n          for (const [k, v] of walkCmd.promptConfigs) {\n            allPromptConfigs.set(k, v);\n          }\n        }\n      }\n\n      if (allPromptProviders.length > 0 || allPromptConfigs.size > 0) {\n        const promptedValues = await resolvePrompts({\n          configuredOptions: this.parser.configuredOptions as Record<\n            string,\n            any\n          >,\n          configuredImplies: this.parser.configuredImplies,\n          promptConfigs: allPromptConfigs,\n          providers: allPromptProviders,\n          currentArgs: mergedArgs,\n        });\n\n        // Inject prompted values into accumulated args\n        for (const [key, value] of Object.entries(promptedValues)) {\n          if (value !== undefined) {\n            mergedArgs[key] = value;\n          }\n        }\n      }\n\n      try {\n        argv = this.parser\n          .clone({\n            ...this.parser.options,\n            unmatchedParser: () => false,\n          })\n          .parse(currentArgs, mergedArgs) as any;\n      } catch (e) {\n        if (e instanceof ValidationFailedError) {\n          argv = e.partialArgV as any;\n          validationFailedError = e;\n        } else {\n          throw e;\n        }\n      }\n\n      if (argv.version) {\n        this.versionHandler();\n        return argv;\n      }\n\n      if (argv.help) {\n        this.printHelp();\n        return argv;\n      } else if (validationFailedError) {\n        throw validationFailedError;\n      }\n\n      // Collect all providers from the command chain (root → subcommands)\n      const allProviders = this.collectProviders();\n      const contextData: ForgeContextData = {\n        args: argv as Record<string, unknown>,\n        commandChain: [...this.commandChain],\n        commandIdChain: this.collectCommandIdChain(),\n        providers: new Map(),\n        providerFactories: new Map(),\n        handlerPhase: false,\n        resolving: new Set(),\n      };\n\n      // Register providers into context\n      for (const [key, reg] of allProviders) {\n        if (reg.type === 'eager') {\n          contextData.providers.set(key, reg.value);\n        } else {\n          contextData.providerFactories.set(key, {\n            factory: reg.factory,\n            lifetime: reg.lifetime,\n          });\n        }\n      }\n\n      const finalArgV = await contextStorage.run(contextData, async () => {\n        contextData.handlerPhase = true;\n        return this.runCommand(argv, args, executedMiddleware);\n      });\n      return finalArgV as TArgs;\n    });\n\n  getParser() {\n    return this.parser.asReadonly();\n  }\n\n  getSubcommands() {\n    return this.registeredCommands as Readonly<Record<string, AnyInternalCLI>>;\n  }\n\n  private collectProviders(): Map<string, ProviderRegistration> {\n    const result = new Map<string, ProviderRegistration>();\n    // Start from root (this) and walk down the command chain\n    // eslint-disable-next-line @typescript-eslint/no-this-alias\n    let cmd: AnyInternalCLI = this;\n    for (const [key, reg] of cmd.registeredProviders) {\n      result.set(key, reg);\n    }\n    for (const name of this.commandChain) {\n      cmd = cmd.registeredCommands[name];\n      if (cmd) {\n        for (const [key, reg] of cmd.registeredProviders) {\n          result.set(key, reg); // child overrides parent\n        }\n      }\n    }\n    return result;\n  }\n\n  /**\n   * Walks the command chain from root (this) down to the running command\n   * and collects each instance's `commandId`. Populates\n   * `ForgeContextData.commandIdChain` so `getCommandContext(cli)` can\n   * validate at runtime that the CLI passed as a type witness is any\n   * command on the active chain.\n   */\n  private collectCommandIdChain(): string[] {\n    const ids: string[] = [this.commandId];\n    // eslint-disable-next-line @typescript-eslint/no-this-alias\n    let cmd: AnyInternalCLI = this;\n    for (const name of this.commandChain) {\n      const next = cmd.registeredCommands[name];\n      if (!next) break;\n      cmd = next;\n      ids.push(cmd.commandId);\n    }\n    return ids;\n  }\n\n  clone() {\n    const clone = new InternalCLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>(\n      this.name\n    );\n    // Propagate the commandId so the clone still validates against any\n    // original CLI reference the user passes to `getCommandContext()`.\n    // A clone conceptually represents the same command — just a private\n    // mutable copy — so it keeps the original's identity.\n    (clone as { commandId: string }).commandId = this.commandId;\n    clone.parser = this.parser.clone(clone.parser.options) as any;\n    if (this.configuration) {\n      clone.withRootCommandConfiguration(this.configuration);\n    }\n    clone.registeredCommands = {};\n    for (const command in this.registeredCommands ?? {}) {\n      clone.command(this.registeredCommands[command].clone() as any);\n    }\n    clone.registeredProviders = new Map(this.registeredProviders);\n    clone.commandChain = [...this.commandChain];\n    clone.requiresCommand = this.requiresCommand;\n    clone.registeredPromptProviders = [...this.registeredPromptProviders];\n    clone.promptConfigs = new Map(this.promptConfigs);\n    clone.completionCallback = this.completionCallback;\n    clone.completionConfigs = new Map(this.completionConfigs);\n    clone._completionEnabled = this._completionEnabled;\n    return clone;\n  }\n}\n","import { ParsedArgs } from '@cli-forge/parser';\nimport { contextStorage, ForgeContextData } from './async-context';\nimport { resetGlobalProviders } from './context';\nimport { AnyInternalCLI, InternalCLI } from './internal-cli';\nimport { CLI, GlobalProviderConfig, ProviderConfig } from './public-api';\n\nconst mockedDisposers: Array<() => void> = [];\n\nexport type TestHarnessParseResult<T extends ParsedArgs> = {\n  /**\n   * Parsed arguments. Note the the typing of this is based on the CLI typings,\n   * but no runtime validation outside of the configured validation checks on\n   * individual options will be performed. If you want to validate the arguments,\n   * you should do so in your test or configure a `validate` callback for the option.\n   */\n  args: T;\n\n  /**\n   * The command chain that was resolved during parsing. This is used for testing\n   * that the correct command is ran when resolving a subcommand. A test that checks\n   * this may look like:\n   *\n   * ```ts\n   * const harness = new TestHarness(cli);\n   * const { args, commandChain } = await harness.parse(['hello', '--name=sir']);\n   * expect(commandChain).toEqual(['hello']);\n   * ```\n   *\n   * The above test would check that the `hello` command was resolved when parsing\n   * the argstring, and since only one command's handler will ever be called, this\n   * can be used to ensure that the correct command is ran.\n   */\n  commandChain: string[];\n};\n\n/**\n * Options accepted by {@link TestHarness.mockContext} and\n * {@link TestHarness.runWithMockedContext}.\n *\n * `providers` mirrors the shape of `.provide()`: each entry is either an\n * eager value, an `executionScope` factory config, or a `global` factory\n * config. The runtime detection matches `InternalCLI.provide()` — any\n * object with a `factory` function is treated as a factory registration.\n */\nexport type MockContextProviders<TArgs, TProviders> = {\n  [K in keyof TProviders]?:\n    | TProviders[K]\n    | ProviderConfig<TProviders[K], TArgs>\n    | GlobalProviderConfig<TProviders[K]>;\n};\n\nexport interface MockContextOptions<TArgs extends ParsedArgs, TProviders> {\n  args?: Partial<TArgs>;\n  providers?: MockContextProviders<TArgs, TProviders>;\n  commandChain?: string[];\n}\n\nfunction buildMockContextData<TArgs extends ParsedArgs, TProviders>(\n  cli: CLI<TArgs, any, any, any, TProviders> | undefined,\n  options: MockContextOptions<TArgs, TProviders>\n): ForgeContextData {\n  // Walk from the mocked CLI up through its parents to build an id chain,\n  // so `getCommandContext(root)` / `getCommandContext(running)` / any\n  // ancestor on the chain all validate successfully inside the mock.\n  const commandIdChain: string[] = [];\n  if (cli && InternalCLI.isInternalCLI(cli)) {\n    let walk: AnyInternalCLI | undefined = cli;\n    while (walk) {\n      commandIdChain.unshift(walk.commandId);\n      walk = walk.getParent() as AnyInternalCLI | undefined;\n    }\n  }\n\n  const contextData: ForgeContextData = {\n    args: (options.args ?? {}) as Record<string, unknown>,\n    commandChain: options.commandChain ?? [],\n    commandIdChain,\n    providers: new Map(),\n    providerFactories: new Map(),\n    handlerPhase: true,\n    resolving: new Set(),\n  };\n\n  for (const [key, value] of Object.entries(options.providers ?? {})) {\n    if (\n      value !== null &&\n      typeof value === 'object' &&\n      'factory' in (value as object) &&\n      typeof (value as { factory: unknown }).factory === 'function'\n    ) {\n      const config = value as {\n        factory: Function;\n        lifetime?: 'global' | 'executionScope';\n      };\n      contextData.providerFactories.set(key, {\n        factory: config.factory,\n        lifetime: config.lifetime ?? 'executionScope',\n      });\n    } else {\n      contextData.providers.set(key, value);\n    }\n  }\n\n  return contextData;\n}\n\n/**\n * Utility for testing CLI instances. Can check argument parsing and validation, including\n * command chain resolution.\n */\nexport class TestHarness<T extends ParsedArgs> {\n  private cli: InternalCLI<T>;\n\n  constructor(cli: CLI<T, any, any, any, any>) {\n    if (InternalCLI.isInternalCLI(cli)) {\n      this.cli = cli;\n      mockHandler(cli);\n    } else {\n      throw new Error(\n        'TestHarness can only be used with CLI instances created by `cli`.'\n      );\n    }\n  }\n\n  /**\n   * Mocks the CLI context for testing DI providers and command context outside\n   * of a real `forge()` execution. Returns a cleanup function that removes the\n   * mocked context when called.\n   *\n   * `options.providers` accepts both eager values and the same\n   * `{ factory, lifetime }` configs that `.provide()` takes — factory mocks\n   * run lazily via `inject()` and receive the mocked `args`.\n   *\n   * This helper is best suited for simple synchronous tests. It does not\n   * maintain a stack of prior contexts: calling `mockContext()` while\n   * another mock is active overwrites the current store, and the returned\n   * cleanup function blanks the store rather than restoring whatever was\n   * there before.\n   *\n   * For tests that use `await` across the mocked block or need nested\n   * mocked contexts that unwind properly, prefer {@link runWithMockedContext},\n   * which uses `AsyncLocalStorage.run()` for proper scoping.\n   *\n   * @example\n   * ```ts\n   * afterEach(() => TestHarness.clearMockedContexts());\n   *\n   * it('resolves provider', () => {\n   *   const cleanup = TestHarness.mockContext(myApp, {\n   *     providers: {\n   *       db: mockDb,\n   *       logger: { factory: (args) => makeLogger(args.logLevel) },\n   *     },\n   *   });\n   *   const ctx = getCommandContext(myApp);\n   *   expect(ctx.inject('db')).toBe(mockDb);\n   *   cleanup();\n   * });\n   * ```\n   */\n  static mockContext<TArgs extends ParsedArgs, TProviders>(\n    _cli: CLI<TArgs, any, any, any, TProviders>,\n    options: MockContextOptions<TArgs, TProviders>\n  ): () => void {\n    const contextData = buildMockContextData(_cli, options);\n    contextStorage.enterWith(contextData);\n\n    const dispose = () => {\n      // Unconditionally blank the current store on dispose. Capturing the\n      // previous store and restoring it looks cleaner for nested mocks, but\n      // it misbehaves when `clearMockedContexts()` batch-disposes out of\n      // order. Callers that need proper nesting should use\n      // `runWithMockedContext`, which scopes via `AsyncLocalStorage.run()`.\n      contextStorage.enterWith(undefined);\n      const idx = mockedDisposers.indexOf(dispose);\n      if (idx !== -1) mockedDisposers.splice(idx, 1);\n    };\n\n    mockedDisposers.push(dispose);\n    return dispose;\n  }\n\n  /**\n   * Runs `fn` inside a mocked DI context using `AsyncLocalStorage.run()`.\n   *\n   * Unlike {@link mockContext}, this variant scopes the context properly\n   * across async boundaries — any `await` inside `fn` keeps seeing the\n   * mocked providers, and the context is automatically torn down when `fn`\n   * resolves (or throws). Prefer this for anything that isn't a trivial\n   * synchronous assertion.\n   *\n   * @example\n   * ```ts\n   * const result = await TestHarness.runWithMockedContext(\n   *   myApp,\n   *   { providers: { db: mockDb } },\n   *   async () => {\n   *     const ctx = getCommandContext(myApp);\n   *     return ctx.inject('db').query('select 1');\n   *   }\n   * );\n   * ```\n   */\n  static async runWithMockedContext<TArgs extends ParsedArgs, TProviders, R>(\n    _cli: CLI<TArgs, any, any, any, TProviders>,\n    options: MockContextOptions<TArgs, TProviders>,\n    fn: () => R | Promise<R>\n  ): Promise<R> {\n    const contextData = buildMockContextData(_cli, options);\n    // Wrap in an async function so synchronous throws from fn() are\n    // converted to rejected promises, and await inside fn sees the scoped\n    // context (AsyncLocalStorage.run propagates the store through awaits).\n    return await contextStorage.run(contextData, async () => fn());\n  }\n\n  /**\n   * Removes all mocked contexts registered via {@link mockContext} and\n   * clears the `lifetime: 'global'` provider cache so the next test starts\n   * with a fresh slate.\n   *\n   * Typically called from `afterEach`:\n   * ```ts\n   * afterEach(() => TestHarness.clearMockedContexts());\n   * ```\n   */\n  static clearMockedContexts(): void {\n    for (const dispose of [...mockedDisposers]) {\n      dispose();\n    }\n    // Belt-and-braces: even after all disposers ran, blank the store so any\n    // lingering reference from a test that forgot to capture its cleanup\n    // doesn't leak into the next test.\n    contextStorage.enterWith(undefined);\n    resetGlobalProviders();\n  }\n\n  /**\n   * Clears only the `lifetime: 'global'` provider cache without touching\n   * any active mocked contexts. Useful when a specific test needs to\n   * re-initialize global providers without discarding the surrounding mock.\n   */\n  static resetGlobalProviders(): void {\n    resetGlobalProviders();\n  }\n\n  async parse(args: string[]): Promise<TestHarnessParseResult<T>> {\n    const argv = await this.cli.forge(args);\n\n    return {\n      args: argv,\n      commandChain: this.cli.commandChain,\n    };\n  }\n}\n\nfunction mockHandler(cli: AnyInternalCLI) {\n  if (cli.configuration?.handler) {\n    cli.configuration.handler = () => {\n      // Mocked, should do nothing.\n    };\n  }\n  for (const command in cli.registeredCommands) {\n    mockHandler(cli.registeredCommands[command]);\n  }\n}\n"," \nimport {\n  ArrayOptionConfig,\n  BooleanOptionConfig,\n  type ConfigurationFiles,\n  EnvOptionConfig,\n  LocalizationDictionary,\n  LocalizationFunction,\n  Expand,\n  MakeUndefinedPropertiesOptional,\n  NumberOptionConfig,\n  ObjectOptionConfig,\n  OneOfOptionConfig,\n  OptionConfig,\n  OptionConfigToType,\n  ParsedArgs,\n  ResolveProperties,\n  StringOptionConfig,\n  WithOptional,\n} from '@cli-forge/parser';\n\nimport { InternalCLI } from './internal-cli';\nimport type { CompletionCallback, OptionCompletionCallback } from './completion-types';\nimport type { PromptOptionConfig, PromptProvider } from './prompt-types';\nimport type { CommandContext, ProvidersFromChain } from './context';\n\nexport interface ProviderConfig<T, TArgs = any> {\n  factory: (args: TArgs) => T;\n  lifetime?: 'executionScope';\n}\n\nexport interface GlobalProviderConfig<T> {\n  factory: () => T;\n  lifetime: 'global';\n}\n\n/**\n * Extracts the command name from a Command type.\n * Works with both CLI instances and command config objects.\n */\nexport type ExtractCommandName<T> = T extends CLI<any, any, any, any, any>\n  ? T extends InternalCLI<any, any, any, any, any>\n    ? string\n    : string\n  : T extends { name: infer N }\n  ? N extends string\n    ? N\n    : string\n  : string;\n\n/**\n * Extracts the args type from a Command.\n * Works with both CLI instances and command config objects.\n */\nexport type ExtractCommandArgs<T> = T extends CLI<infer A, any, any, any, any>\n  ? A\n  : T extends CLICommandOptions<any, infer A, any, any>\n  ? A\n  : ParsedArgs;\n\n/**\n * Extracts the handler return type from a Command.\n */\nexport type ExtractCommandHandlerReturn<T> = T extends CLI<any, infer R, any, any, any>\n  ? R\n  : T extends CLICommandOptions<any, any, infer R, any>\n  ? R\n  : void;\n\n/**\n * Extracts the registered providers from a Command.\n * Works with both CLI instances (uses the 5th generic directly) and command\n * config objects (infers the builder's return type's provider map).\n */\nexport type ExtractCommandProviders<T> = T extends CLI<any, any, any, any, infer P>\n  ? P\n  : T extends CLICommandOptions<any, any, any, any, any, any, infer P>\n  ? P\n  : {};\n\n/**\n * Converts a Command to its child CLI entry for TChildren tracking.\n * TParentCLI is the parent CLI type that will be set as the child's TParent.\n */\nexport type CommandToChildEntry<T, TParentCLI = undefined> = {\n  [K in ExtractCommandName<T>]: CLI<\n    ExtractCommandArgs<T>,\n    ExtractCommandHandlerReturn<T>,\n    {},\n    TParentCLI,\n    ExtractCommandProviders<T>\n  >;\n};\n\n/**\n * The interface for a CLI application or subcommands.\n *\n * {@link cli} is provided as a small helper function to create a new CLI instance.\n *\n * @example\n * ```ts\n * import { cli } from 'cli-forge';\n *\n * cli('basic-cli').command('hello', {\n *   builder: (args) =>\n *    args.option('name', {\n *      type: 'string',\n *    }),\n *   handler: (args) => {\n *     console.log(`Hello, ${args.name}!`);\n *   }).forge();\n * ```\n */\nexport interface CLI<\n  TArgs extends ParsedArgs = ParsedArgs,\n  THandlerReturn = void,\n\n  TChildren = {},\n  TParent = undefined,\n  TProviders = {}\n> {\n  command<\n    TCommand extends Command<TArgs, any, any, any>,\n    TCommandArgs extends TArgs = ExtractCommandArgs<TCommand> extends TArgs\n      ? ExtractCommandArgs<TCommand>\n      : TArgs,\n    TCmdName extends string = ExtractCommandName<TCommand>,\n    TChildHandlerReturn = ExtractCommandHandlerReturn<TCommand>\n  >(\n    cmd: TCommand\n  ): CLI<\n    TArgs,\n    THandlerReturn,\n    TChildren & {\n      [key in TCmdName]: CLI<\n        TCommandArgs,\n        TChildHandlerReturn,\n        {},\n        CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>,\n        ExtractCommandProviders<TCommand>\n      >;\n    },\n    TParent,\n    TProviders\n  >;\n\n  /**\n   * Registers a new command with the CLI.\n   * @param key What should the new command be called?\n   * @param options Settings for the new command. See {@link CLICommandOptions}.\n   * @returns Updated CLI instance with the new command registered.\n   */\n  command<\n    TCommandArgs extends TArgs,\n    TChildHandlerReturn,\n    TKey extends string,\n\n    TChildChildren = {},\n    TChildProviders = {}\n  >(\n    key: TKey,\n    options: CLICommandOptions<\n      TArgs,\n      TCommandArgs,\n      TChildHandlerReturn,\n      TChildren,\n      CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>,\n      TChildChildren,\n      TChildProviders\n    >\n  ): CLI<\n    TArgs,\n    THandlerReturn,\n    TChildren & {\n      [key in TKey]: CLI<\n        TCommandArgs,\n        TChildHandlerReturn,\n        TChildChildren,\n        CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>,\n        TChildProviders\n      >;\n    },\n    TParent,\n    TProviders\n  >;\n\n  /**\n   * Registers multiple subcommands with the CLI.\n   * @param commands Several commands to register. Can be the result of a call to {@link cli} or a configuration object.\n   * @returns Updated CLI instance with the commands registered and their types tracked in TChildren.\n   */\n  // Typed overloads for 1-10 commands to preserve individual command types\n  // Each child command gets this CLI as its TParent\n  commands<C1 extends Command>(\n    c1: C1\n  ): CLI<\n    TArgs,\n    THandlerReturn,\n    TChildren &\n      CommandToChildEntry<C1, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>>,\n    TParent,\n    TProviders\n  >;\n  commands<C1 extends Command, C2 extends Command>(\n    c1: C1,\n    c2: C2\n  ): CLI<\n    TArgs,\n    THandlerReturn,\n    TChildren &\n      CommandToChildEntry<C1, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C2, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>>,\n    TParent,\n    TProviders\n  >;\n  commands<C1 extends Command, C2 extends Command, C3 extends Command>(\n    c1: C1,\n    c2: C2,\n    c3: C3\n  ): CLI<\n    TArgs,\n    THandlerReturn,\n    TChildren &\n      CommandToChildEntry<C1, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C2, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C3, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>>,\n    TParent,\n    TProviders\n  >;\n  commands<\n    C1 extends Command,\n    C2 extends Command,\n    C3 extends Command,\n    C4 extends Command\n  >(\n    c1: C1,\n    c2: C2,\n    c3: C3,\n    c4: C4\n  ): CLI<\n    TArgs,\n    THandlerReturn,\n    TChildren &\n      CommandToChildEntry<C1, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C2, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C3, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C4, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>>,\n    TParent,\n    TProviders\n  >;\n  commands<\n    C1 extends Command,\n    C2 extends Command,\n    C3 extends Command,\n    C4 extends Command,\n    C5 extends Command\n  >(\n    c1: C1,\n    c2: C2,\n    c3: C3,\n    c4: C4,\n    c5: C5\n  ): CLI<\n    TArgs,\n    THandlerReturn,\n    TChildren &\n      CommandToChildEntry<C1, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C2, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C3, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C4, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C5, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>>,\n    TParent,\n    TProviders\n  >;\n  commands<\n    C1 extends Command,\n    C2 extends Command,\n    C3 extends Command,\n    C4 extends Command,\n    C5 extends Command,\n    C6 extends Command\n  >(\n    c1: C1,\n    c2: C2,\n    c3: C3,\n    c4: C4,\n    c5: C5,\n    c6: C6\n  ): CLI<\n    TArgs,\n    THandlerReturn,\n    TChildren &\n      CommandToChildEntry<C1, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C2, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C3, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C4, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C5, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C6, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>>,\n    TParent,\n    TProviders\n  >;\n  commands<\n    C1 extends Command,\n    C2 extends Command,\n    C3 extends Command,\n    C4 extends Command,\n    C5 extends Command,\n    C6 extends Command,\n    C7 extends Command\n  >(\n    c1: C1,\n    c2: C2,\n    c3: C3,\n    c4: C4,\n    c5: C5,\n    c6: C6,\n    c7: C7\n  ): CLI<\n    TArgs,\n    THandlerReturn,\n    TChildren &\n      CommandToChildEntry<C1, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C2, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C3, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C4, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C5, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C6, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C7, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>>,\n    TParent,\n    TProviders\n  >;\n  commands<\n    C1 extends Command,\n    C2 extends Command,\n    C3 extends Command,\n    C4 extends Command,\n    C5 extends Command,\n    C6 extends Command,\n    C7 extends Command,\n    C8 extends Command\n  >(\n    c1: C1,\n    c2: C2,\n    c3: C3,\n    c4: C4,\n    c5: C5,\n    c6: C6,\n    c7: C7,\n    c8: C8\n  ): CLI<\n    TArgs,\n    THandlerReturn,\n    TChildren &\n      CommandToChildEntry<C1, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C2, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C3, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C4, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C5, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C6, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C7, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C8, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>>,\n    TParent,\n    TProviders\n  >;\n  commands<\n    C1 extends Command,\n    C2 extends Command,\n    C3 extends Command,\n    C4 extends Command,\n    C5 extends Command,\n    C6 extends Command,\n    C7 extends Command,\n    C8 extends Command,\n    C9 extends Command\n  >(\n    c1: C1,\n    c2: C2,\n    c3: C3,\n    c4: C4,\n    c5: C5,\n    c6: C6,\n    c7: C7,\n    c8: C8,\n    c9: C9\n  ): CLI<\n    TArgs,\n    THandlerReturn,\n    TChildren &\n      CommandToChildEntry<C1, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C2, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C3, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C4, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C5, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C6, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C7, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C8, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C9, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>>,\n    TParent,\n    TProviders\n  >;\n  commands<\n    C1 extends Command,\n    C2 extends Command,\n    C3 extends Command,\n    C4 extends Command,\n    C5 extends Command,\n    C6 extends Command,\n    C7 extends Command,\n    C8 extends Command,\n    C9 extends Command,\n    C10 extends Command\n  >(\n    c1: C1,\n    c2: C2,\n    c3: C3,\n    c4: C4,\n    c5: C5,\n    c6: C6,\n    c7: C7,\n    c8: C8,\n    c9: C9,\n    c10: C10\n  ): CLI<\n    TArgs,\n    THandlerReturn,\n    TChildren &\n      CommandToChildEntry<C1, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C2, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C3, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C4, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C5, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C6, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C7, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C8, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C9, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>> &\n      CommandToChildEntry<C10, CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>>,\n    TParent,\n    TProviders\n  >;\n  // Fallback for arrays or more than 10 commands (loses individual type tracking)\n  commands(commands: Command[]): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  commands(\n    ...commands: Command[]\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  /**\n   * Register's a configuration provider for the CLI. See {@link ConfigurationProviders} for built-in providers.\n   *\n   * @param provider Provider to register.\n   */\n  config(\n    provider: ConfigurationFiles.AnyConfigProvider<TArgs>\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  /**\n   * Updates configuration by routing each key to its owning provider.\n   *\n   * @param values Partial configuration to write.\n   */\n  updateConfig(values: Partial<TArgs>): Promise<void>;\n  /**\n   * Updates configuration via an updater function. The current merged\n   * configuration is passed via a proxy that tracks which properties are set.\n   * Only properties set during the callback are written back.\n   *\n   * @param updater Function that receives the current config and mutates it.\n   */\n  updateConfig(\n    updater: ConfigurationFiles.ConfigUpdater<TArgs>\n  ): Promise<void>;\n\n  /**\n   * Enables the ability to run CLI commands that contain subcommands as an interactive shell.\n   * This presents as a small shell that only knows the current command and its subcommands.\n   * Any flags already consumed by the command will be passed to every subcommand invocation.\n   */\n  enableInteractiveShell(): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  /**\n   * Registers a custom global error handler for the CLI. This handler will be called when an error is thrown\n   * during the execution of the CLI and not otherwise handled. Error handlers should re-throw the error if they\n   * cannot handle it, s.t. the next error handler can attempt to handle it.\n   *\n   * @param handler Typically called with an Error object, but you should be prepared to handle any type of error.\n   * @param actions Actions that can be taken by the error handler. Prefer using these over process.exit for better support of interactive shells.\n   */\n  errorHandler(\n    handler: ErrorHandler\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  /**\n   * Registers a prompt provider for interactive option fulfillment.\n   * Multiple providers can be registered. Filtered providers are checked first\n   * (in registration order), then fallback providers (no filter).\n   *\n   * @param provider The prompt provider to register.\n   */\n  withPromptProvider(\n    provider: PromptProvider\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  /**\n   * Registers a new option for the CLI command. This option will be accessible\n   * within the command handler, as well as any subcommands.\n   *\n   * @param name The name of the option.\n   * @param config Configuration for the option. See {@link UnknownOptionConfig}.\n   * @returns Updated CLI instance with the new option registered.\n   */\n  // Object option overload - must come first for proper contextual typing\n  // Uses direct ObjectOptionConfig type (not `extends`) to ensure TypeScript\n  // infers TProps from `properties` BEFORE evaluating the coerce callback type\n  option<\n    TOption extends string,\n    TCoerce,\n    const TProps extends Record<string, { type: string }>\n  >(\n    name: TOption,\n    config: ObjectOptionConfig<TCoerce, TProps> & { prompt?: PromptOptionConfig<TArgs>; completion?: OptionCompletionCallback<TArgs> }\n  ): CLI<\n    Expand<TArgs &\n      MakeUndefinedPropertiesOptional<{\n        [key in TOption]: WithOptional<\n          unknown extends TCoerce ? ResolveProperties<TProps> : TCoerce,\n          ObjectOptionConfig<TCoerce, TProps>\n        >;\n      }>>,\n    THandlerReturn,\n    TChildren,\n    TParent,\n    TProviders\n  >;\n  // String option overload\n  option<\n    TOption extends string,\n    const TConfig extends StringOptionConfig<any, any>\n  >(\n    name: TOption,\n    config: TConfig & { prompt?: PromptOptionConfig<TArgs>; completion?: OptionCompletionCallback<TArgs> }\n  ): CLI<\n    Expand<TArgs &\n      MakeUndefinedPropertiesOptional<{\n        [key in TOption]: OptionConfigToType<TConfig>;\n      }>>,\n    THandlerReturn,\n    TChildren,\n    TParent,\n    TProviders\n  >;\n  // Number option overload\n  option<\n    TOption extends string,\n    const TConfig extends NumberOptionConfig<any, any>\n  >(\n    name: TOption,\n    config: TConfig & { prompt?: PromptOptionConfig<TArgs>; completion?: OptionCompletionCallback<TArgs> }\n  ): CLI<\n    Expand<TArgs &\n      MakeUndefinedPropertiesOptional<{\n        [key in TOption]: OptionConfigToType<TConfig>;\n      }>>,\n    THandlerReturn,\n    TChildren,\n    TParent,\n    TProviders\n  >;\n  // Boolean option overload\n  option<\n    TOption extends string,\n    const TConfig extends BooleanOptionConfig<any, any>\n  >(\n    name: TOption,\n    config: TConfig & { prompt?: PromptOptionConfig<TArgs>; completion?: OptionCompletionCallback<TArgs> }\n  ): CLI<\n    Expand<TArgs &\n      MakeUndefinedPropertiesOptional<{\n        [key in TOption]: OptionConfigToType<TConfig>;\n      }>>,\n    THandlerReturn,\n    TChildren,\n    TParent,\n    TProviders\n  >;\n  // Array option overload\n  option<\n    TOption extends string,\n    const TConfig extends ArrayOptionConfig<any, any>\n  >(\n    name: TOption,\n    config: TConfig & { prompt?: PromptOptionConfig<TArgs>; completion?: OptionCompletionCallback<TArgs> }\n  ): CLI<\n    Expand<TArgs &\n      MakeUndefinedPropertiesOptional<{\n        [key in TOption]: OptionConfigToType<TConfig>;\n      }>>,\n    THandlerReturn,\n    TChildren,\n    TParent,\n    TProviders\n  >;\n  // OneOf option overload\n  option<\n    TOption extends string,\n    const TConfig extends OneOfOptionConfig<any>\n  >(\n    name: TOption,\n    config: TConfig & { prompt?: PromptOptionConfig<TArgs>; completion?: OptionCompletionCallback<TArgs> }\n  ): CLI<\n    Expand<TArgs &\n      MakeUndefinedPropertiesOptional<{\n        [key in TOption]: OptionConfigToType<TConfig>;\n      }>>,\n    THandlerReturn,\n    TChildren,\n    TParent,\n    TProviders\n  >;\n  // Generic fallback overload\n  option<\n    TOption extends string,\n    const TOptionConfig extends OptionConfig<any, any, any>\n  >(\n    name: TOption,\n    config: TOptionConfig & { prompt?: PromptOptionConfig<TArgs>; completion?: OptionCompletionCallback<TArgs> }\n  ): CLI<\n    Expand<TArgs &\n      MakeUndefinedPropertiesOptional<{\n        [key in TOption]: OptionConfigToType<TOptionConfig>;\n      }>>,\n    THandlerReturn,\n    TChildren,\n    TParent,\n    TProviders\n  >;\n\n  /**\n   * Registers a new positional argument for the CLI command. This argument will be accessible\n   * within the command handler, as well as any subcommands.\n   * @param name The name of the positional argument.\n   * @param config Configuration for the positional argument. See {@link UnknownOptionConfig}.\n   * @returns Updated CLI instance with the new positional argument registered.\n   */\n  // Object option overload - must come first for proper contextual typing\n  // Uses direct ObjectOptionConfig type (not `extends`) to ensure TypeScript\n  // infers TProps from `properties` BEFORE evaluating the coerce callback type\n  positional<\n    TOption extends string,\n    TCoerce,\n    const TProps extends Record<string, { type: string }>\n  >(\n    name: TOption,\n    config: ObjectOptionConfig<TCoerce, TProps> & { prompt?: PromptOptionConfig<TArgs>; completion?: OptionCompletionCallback<TArgs> }\n  ): CLI<\n    Expand<TArgs &\n      MakeUndefinedPropertiesOptional<{\n        [key in TOption]: WithOptional<\n          unknown extends TCoerce ? ResolveProperties<TProps> : TCoerce,\n          ObjectOptionConfig<TCoerce, TProps>\n        >;\n      }>>,\n    THandlerReturn,\n    TChildren,\n    TParent,\n    TProviders\n  >;\n  // String option overload\n  positional<\n    TOption extends string,\n    const TConfig extends StringOptionConfig<any, any>\n  >(\n    name: TOption,\n    config: TConfig & { prompt?: PromptOptionConfig<TArgs>; completion?: OptionCompletionCallback<TArgs> }\n  ): CLI<\n    Expand<TArgs &\n      MakeUndefinedPropertiesOptional<{\n        [key in TOption]: OptionConfigToType<TConfig>;\n      }>>,\n    THandlerReturn,\n    TChildren,\n    TParent,\n    TProviders\n  >;\n  // Number option overload\n  positional<\n    TOption extends string,\n    const TConfig extends NumberOptionConfig<any, any>\n  >(\n    name: TOption,\n    config: TConfig & { prompt?: PromptOptionConfig<TArgs>; completion?: OptionCompletionCallback<TArgs> }\n  ): CLI<\n    Expand<TArgs &\n      MakeUndefinedPropertiesOptional<{\n        [key in TOption]: OptionConfigToType<TConfig>;\n      }>>,\n    THandlerReturn,\n    TChildren,\n    TParent,\n    TProviders\n  >;\n  // Boolean option overload\n  positional<\n    TOption extends string,\n    const TConfig extends BooleanOptionConfig<any, any>\n  >(\n    name: TOption,\n    config: TConfig & { prompt?: PromptOptionConfig<TArgs>; completion?: OptionCompletionCallback<TArgs> }\n  ): CLI<\n    Expand<TArgs &\n      MakeUndefinedPropertiesOptional<{\n        [key in TOption]: OptionConfigToType<TConfig>;\n      }>>,\n    THandlerReturn,\n    TChildren,\n    TParent,\n    TProviders\n  >;\n  // Array option overload\n  positional<\n    TOption extends string,\n    const TConfig extends ArrayOptionConfig<any, any>\n  >(\n    name: TOption,\n    config: TConfig & { prompt?: PromptOptionConfig<TArgs>; completion?: OptionCompletionCallback<TArgs> }\n  ): CLI<\n    Expand<TArgs &\n      MakeUndefinedPropertiesOptional<{\n        [key in TOption]: OptionConfigToType<TConfig>;\n      }>>,\n    THandlerReturn,\n    TChildren,\n    TParent,\n    TProviders\n  >;\n  // Generic fallback overload\n  positional<\n    TOption extends string,\n    const TOptionConfig extends OptionConfig<any, any, any>\n  >(\n    name: TOption,\n    config: TOptionConfig & { prompt?: PromptOptionConfig<TArgs>; completion?: OptionCompletionCallback<TArgs> }\n  ): CLI<\n    Expand<TArgs &\n      MakeUndefinedPropertiesOptional<{\n        [key in TOption]: OptionConfigToType<TOptionConfig>;\n      }>>,\n    THandlerReturn,\n    TChildren,\n    TParent,\n    TProviders\n  >;\n\n  /**\n   * Adds support for reading CLI options from environment variables.\n   * @param prefix The prefix to use when looking up environment variables. Defaults to the command name.\n   */\n  env(prefix?: string): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  env(options: EnvOptionConfig): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  /**\n   * Sets up localization for option keys and other text.\n   * When localization is enabled, option keys will be displayed in the specified locale in help text and documentation,\n   * and both the default and localized keys will be accepted when parsing arguments.\n   *\n   * @param dictionary The localization dictionary mapping keys to their translations\n   * @param locale The target locale (defaults to system locale if not provided)\n   * @returns Updated CLI instance for chaining\n   *\n   * @example\n   * ```ts\n   * cli('myapp')\n   *   .localize({\n   *     name: { default: 'name', 'es-ES': 'nombre' },\n   *     port: { default: 'port', 'es-ES': 'puerto' }\n   *   }, 'es-ES')\n   *   .option('name', { type: 'string' })\n   *   .option('port', { type: 'number' });\n   * ```\n   */\n  localize(\n    dictionary: LocalizationDictionary,\n    locale?: string\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  /**\n   * Sets up localization using a custom function for translating keys.\n   * This allows integration with existing localization libraries like i18next.\n   *\n   * @param fn A function that takes a key and returns its localized value\n   * @returns Updated CLI instance for chaining\n   *\n   * @example\n   * ```ts\n   * import i18next from 'i18next';\n   *\n   * cli('myapp')\n   *   .localize((key) => i18next.t(key))\n   *   .option('name', { type: 'string' })\n   *   .option('port', { type: 'number' });\n   * ```\n   */\n  localize(\n    fn: LocalizationFunction\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  /**\n   * Sets a group of options as mutually exclusive. If more than one option is provided, there will be a validation error.\n   * @param options The options that should be mutually exclusive.\n   */\n  conflicts(\n    ...options: [string, string, ...string[]]\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  /**\n   * Sets a group of options as mutually inclusive. If one option is provided, all other options must also be provided.\n   * @param option The option that implies the other options.\n   * @param impliedOptions The options which become required when the option is provided.\n   */\n  implies(\n    option: string,\n    ...impliedOptions: string[]\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  /**\n   * Requires a command to be provided when executing the CLI. Useful if your parent command\n   * cannot be executed on its own.\n   * @returns Updated CLI instance.\n   */\n  demandCommand(): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  /**\n   * Enables or disables strict mode. When strict mode is enabled, the parser throws a validation error\n   * when unmatched arguments are encountered. Unmatched arguments are those that don't match any\n   * configured option or positional argument.\n   * @param enable Whether to enable strict mode. Defaults to true.\n   * @returns Updated CLI instance.\n   */\n  strict(enable?: boolean): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  /**\n   * Sets the usage text for the CLI. This text will be displayed in place of the default usage text\n   * @param usageText Text displayed in place of the default usage text for `--help` and in generated docs.\n   */\n  usage(usageText: string): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  /**\n   * Marks this command as hidden so it is omitted from help output, generated documentation,\n   * and shell completion suggestions. Useful when composing reusable builders that need to\n   * register internal or experimental commands without exposing them to end users.\n   * @param hidden Whether the command should be hidden. Defaults to `true`.\n   */\n  hidden(hidden?: boolean): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  /**\n   * Sets the description for the CLI. This text will be displayed in the help text and generated docs.\n   * @param examples Examples to display in the help text and generated docs.\n   */\n  examples(\n    ...examples: string[]\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  /**\n   * Allows overriding the version displayed when passing `--version`. Defaults to crawling\n   * the file system to get the package.json of the currently executing command.\n   * @param override\n   */\n  version(override?: string): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  /**\n   * Prints help text to stdout.\n   */\n  printHelp(): void;\n\n  group({\n    label,\n    keys,\n    sortOrder,\n  }: {\n    label: string;\n    keys: (keyof TArgs)[];\n    sortOrder?: number;\n  }): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n  group(\n    label: string,\n    keys: (keyof TArgs)[]\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  middleware<TArgs2>(\n    callback: MiddlewareFunction<TArgs, TArgs2>\n  ): CLI<\n    TArgs2 extends void ? TArgs : Expand<TArgs & TArgs2>,\n    THandlerReturn,\n    TChildren,\n    TParent,\n    TProviders\n  >;\n\n  /**\n   * Registers a handler for this command. Fluent alternative to passing\n   * `handler` in the command configuration object.\n   *\n   * @param fn Handler function receiving parsed args and command context.\n   * @returns Updated CLI instance with the handler return type updated.\n   *\n   * @example\n   * ```ts\n   * cli('serve')\n   *   .option('port', { type: 'number', default: 3000 })\n   *   .handler((args) => {\n   *     console.log(`Listening on port ${args.port}`);\n   *   })\n   *   .forge();\n   * ```\n   */\n  handler<R>(\n    fn: (\n      args: TArgs,\n      context: CLIHandlerContext<TChildren, TParent>\n    ) => R\n  ): CLI<TArgs, R, TChildren, TParent, TProviders>;\n\n  /**\n   * Registers a dependency injection provider under a unique key.\n   * The value (or factory result) is accessible via `inject()` within command handlers.\n   *\n   * Three forms are supported:\n   * - **Eager value**: `provide('key', value)` — stored as-is.\n   * - **ExecutionScope factory**: `provide('key', { factory: (args) => value })` — called per invocation with parsed args.\n   * - **Global factory**: `provide('key', { factory: () => value, lifetime: 'global' })` — called once and cached.\n   *\n   * Duplicate keys on the same command instance throw an error.\n   */\n  // Global factory (no args, must specify lifetime: 'global')\n  provide<TName extends string, T>(\n    key: TName & (TName extends keyof TProviders ? never : TName),\n    config: GlobalProviderConfig<T>,\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders & { [K in TName]: T }>;\n\n  // ExecutionScope factory (receives args)\n  provide<TName extends string, T>(\n    key: TName & (TName extends keyof TProviders ? never : TName),\n    config: ProviderConfig<T, TArgs>,\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders & { [K in TName]: T }>;\n\n  // Eager value\n  provide<TName extends string, T>(\n    key: TName & (TName extends keyof TProviders ? never : TName),\n    value: T,\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders & { [K in TName]: T }>;\n\n  /**\n   * Registers an init hook that runs before command resolution.\n   * Init hooks receive partially-parsed args (from currently-registered options)\n   * and can modify the CLI (register commands, options, middleware) before the\n   * full parse runs. This enables plugin loading from config files.\n   *\n   * @param callback Async function receiving (args, cli). Mutate cli to add commands/options.\n   */\n  init(\n    callback: (\n      cli: CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>,\n      args: TArgs\n    ) => Promise<void> | void\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  /**\n   * Enables shell completion for this CLI.\n   * When called at the root level (no parent), also registers:\n   *   - A hidden `--get-completions` flag for runtime completion\n   *   - A `completion` subcommand for installing shell scripts\n   *\n   * At any level, stores the optional callback for custom completion suggestions.\n   *\n   * @param callback Optional custom completion callback for this command level.\n   */\n  completion(\n    callback?: CompletionCallback<TArgs>\n  ): CLI<TArgs, THandlerReturn, TChildren, TParent, TProviders>;\n\n  /**\n   * Parses argv and executes the CLI\n   * @param args argv. Defaults to process.argv.slice(2)\n   * @returns Promise that resolves when the handler completes.\n   */\n  forge(args?: string[]): Promise<TArgs>;\n\n  /**\n   * Returns the typed children commands registered with this CLI.\n   * The return type depends on the commands registered via `command()` or `commands()`.\n   *\n   * @example\n   * ```ts\n   * const app = cli('app')\n   *   .command('init', { ... })\n   *   .command('build', { ... });\n   *\n   * const children = app.getChildren();\n   * // children.init and children.build are typed CLI instances\n   * const initHandler = children.init.getHandler();\n   * ```\n   */\n  getChildren(): TChildren;\n\n  /**\n   * Returns the parent CLI instance, if this command was registered as a subcommand.\n   * Returns undefined for root-level CLI instances.\n   *\n   * @example\n   * ```ts\n   * const build = cli('build', {\n   *   handler: (args, ctx) => {\n   *     const parent = ctx.command.getParent();\n   *     const siblings = parent?.getChildren();\n   *     // Access sibling commands\n   *   }\n   * });\n   * ```\n   */\n  getParent(): TParent;\n\n  /**\n   * Returns the {@link CommandContext} for the currently executing command,\n   * inferred from this CLI instance.\n   *\n   * This is a shorthand for `getCommandContext(this)` — it avoids the\n   * separate `import { getCommandContext } from 'cli-forge'` when you\n   * already have a reference to the CLI. Both forms are equivalent in\n   * type inference and runtime safety: the CLI instance is validated\n   * against the active command chain, so passing a CLI that isn't\n   * running (a sibling, an unrelated app) throws.\n   *\n   * Must be called from within a command handler — not during builders\n   * or middleware.\n   *\n   * @example\n   * ```ts\n   * const app = cli('app')\n   *   .provide('db', { factory: () => connectDb() })\n   *   .command('migrate', {\n   *     handler: () => {\n   *       const db = app.getContext().inject('db');\n   *       return db.runMigrations();\n   *     },\n   *   });\n   * ```\n   */\n  // Uses `ProvidersFromChain<TProviders, TParent>` rather than\n  // `ProvidersOf<CLI<TArgs, ..., TParent, TProviders>>` so this signature\n  // doesn't re-wrap `CLI`'s own type parameters in a `CLI<...>` while\n  // the `CLI` interface is still being constructed. The chain-walk\n  // recursion then stays in conditional-type space, where TypeScript\n  // evaluates it lazily at call sites — no self-reference to trip.\n  getContext(): CommandContext<\n    TArgs,\n    ProvidersFromChain<TProviders, TParent>,\n    TChildren\n  >;\n\n  /**\n   * Returns a programmatic SDK for invoking this CLI and its subcommands.\n   * The SDK provides typed function calls instead of argv parsing.\n   *\n   * @example\n   * ```ts\n   * const myCLI = cli('my-app')\n   *   .option('verbose', { type: 'boolean' })\n   *   .command('build', {\n   *     builder: (cmd) => cmd.option('watch', { type: 'boolean' }),\n   *     handler: (args) => ({ success: true, files: ['a.js'] })\n   *   });\n   *\n   * const sdk = myCLI.sdk();\n   *\n   * // Invoke root command (if it has a handler)\n   * await sdk({ verbose: true });\n   *\n   * // Invoke subcommand with typed args\n   * const result = await sdk.build({ watch: true });\n   * console.log(result.files);       // ['a.js']\n   * console.log(result.$args.watch); // true\n   *\n   * // Use CLI-style args for -- support\n   * await sdk.build(['--watch', '--', 'extra-arg']);\n   * ```\n   *\n   * @returns An SDK object that is callable (if this command has a handler)\n   *          and has properties for each subcommand.\n   */\n  sdk(): SDKCommand<TArgs, THandlerReturn, TChildren>;\n\n  /**\n   * Returns the builder function for this command as a composable builder.\n   * The returned function can be used with `chain` to compose multiple builders.\n   *\n   * @example\n   * ```ts\n   * const siblings = args.getParent().getChildren();\n   * const withBuildArgs = siblings.build.getBuilder()!;\n   * const withServeArgs = siblings.serve.getBuilder()!;\n   * return chain(args, withBuildArgs, withServeArgs);\n   * ```\n   */\n  getBuilder():\n    | (<\n        TInit extends ParsedArgs,\n        TInitHandlerReturn,\n        TInitChildren,\n        TInitParent,\n        TInitProviders\n      >(\n        parser: CLI<TInit, TInitHandlerReturn, TInitChildren, TInitParent, TInitProviders>\n      ) => CLI<\n        TInit & TArgs,\n        TInitHandlerReturn,\n        TInitChildren & TChildren,\n        TInitParent,\n        TInitProviders\n      >)\n    | undefined;\n  getHandler():\n    | ((args: Omit<TArgs, keyof ParsedArgs>) => THandlerReturn)\n    | undefined;\n}\n\nexport interface CLIHandlerContext<TChildren = {}, TParent = any> {\n  command: CLI<any, any, TChildren, TParent, any>;\n}\n\n/**\n * Extracts the TChildren type parameter from a CLI type.\n */\nexport type ExtractCLIChildren<T> = T extends CLI<any, any, infer C, any, any>\n  ? C\n  : {};\n\n/**\n * Represents the configuration needed to create a CLI command.\n */\nexport interface CLICommandOptions<\n  /**\n   * The type of the arguments that are already registered before `builder` is invoked.\n   */\n  TInitial extends ParsedArgs,\n  /**\n   * The type of the arguments that are registered after `builder` is invoked, and the type that is passed to the handler.\n   */\n  TArgs extends TInitial = TInitial,\n  THandlerReturn = void | Promise<void>,\n  /**\n   * The children commands that exist before the builder runs.\n   */\n\n  TInitialChildren = {},\n  TParent = any,\n  /**\n   * The children commands after the builder runs (includes TInitialChildren plus any added by builder).\n   */\n\n  TChildren = {},\n  /**\n   * The providers registered inside the builder via `.provide()`. Inferred\n   * from the builder's return type so that child-overrides-parent semantics\n   * are visible in `getCommandContext(child).inject()`.\n   */\n  TChildProviders = {}\n> {\n  /**\n   * If set the command will be registered under the provided name and any aliases.\n   *\n   * This can be useful if a command should be executed under more than one name, e.g. `npx my-cli` and `npx my-cli hello`.\n   */\n  alias?: string[];\n\n  /**\n   * The command description. This will be displayed in the help text and generated docs.\n   */\n  description?: string;\n\n  /**\n   * The command builder. This function is called before the command is executed, and is used to register options and positional parameters.\n   * @param parser The parser instance to register options and positionals with.\n   */\n  // Note: Builder uses 'any' for THandlerReturn to avoid inference conflicts with the handler.\n  // The handler's return type is inferred independently from the handler function itself.\n  builder?: (\n    parser: CLI<TInitial, any, TInitialChildren, TParent, {}>\n  ) => CLI<TArgs, any, TChildren, any, TChildProviders>;\n\n  /**\n   * The command handler. This function is called when the command is executed.\n   * @param args The parsed arguments.\n   * @param context Context for the handler. Contains the command instance.\n   */\n  handler?: (\n    args: NoInfer<TArgs>,\n    context: CLIHandlerContext<NoInfer<TChildren>, TParent>\n  ) => THandlerReturn;\n\n  /**\n   * The usage text for the command. This text will be displayed in place of the default usage text in the help text and generated docs.\n   */\n  usage?: string;\n\n  /**\n   * Examples to display in the help text and generated docs.\n   */\n  examples?: string[];\n\n  /**\n   * Hides the command from the help text and generated docs. Useful primarily for experimental or internal commands.\n   */\n  hidden?: boolean;\n\n  /**\n   * The epilogue text for the command. This text will be displayed at the end of the help text and generated docs.\n   */\n  epilogue?: string;\n}\n\nexport type Command<\n  TInitial extends ParsedArgs = any,\n  TArgs extends TInitial = TInitial,\n  TCommandName extends string = string,\n  THandlerReturn = void\n> =\n  | ({\n      name: TCommandName;\n    } & CLICommandOptions<TInitial, TArgs, THandlerReturn>)\n  | CLI<TArgs, THandlerReturn>;\n\n/**\n * Error Handler for CLI applications. Error handlers should re-throw the error if they cannot handle it.\n *\n * @param e The error that was thrown.\n * @param actions Actions that can be taken by the error handler. Prefer using these over process.exit for better support of interactive shells.\n */\nexport type ErrorHandler = (\n  e: unknown,\n  actions: {\n    /**\n     * Exits the process immediately.\n     * @param code\n     */\n    exit: (code?: number) => void;\n  }\n) => void;\n\n/** Type alias for a CLI instance with any type parameters. Use in value positions where you need to accept any CLI. */\nexport type AnyCLI = CLI<any, any, any, any, any>;\n\n/**\n * Base CLI constraint for generic functions. Uses `ParsedArgs` instead of `any`\n * for `TArgs` so that method return types (like `.option()`) compute correctly\n * through `chain()`. Use this as the bound in `<T extends UnknownCLI>`.\n *\n * @example\n * ```ts\n * function withVerbose<T extends UnknownCLI>(cli: T) {\n *   return cli.option('verbose', { type: 'boolean' });\n * }\n * ```\n */\nexport type UnknownCLI = CLI<ParsedArgs, any, any, any, any>;\n\nexport type MiddlewareFunction<TArgs extends ParsedArgs, TArgs2> = (\n  args: TArgs\n) => TArgs2 | Promise<TArgs2>;\n\n// ============================================================================\n// SDK Types\n// ============================================================================\n\n/**\n * Result type that conditionally includes $args.\n * Only attaches $args when result is an object type.\n * Uses `Awaited<T>` to handle async handlers that return `Promise<U>`.\n */\nexport type SDKResult<TArgs, THandlerReturn> =\n  Awaited<THandlerReturn> extends object\n    ? Awaited<THandlerReturn> & { $args: TArgs }\n    : Awaited<THandlerReturn>;\n\n/**\n * The callable signature for a command with a handler.\n * Supports both object-style args (typed, skips validation) and\n * string array args (CLI-style, full validation pipeline).\n */\nexport type SDKInvokable<TArgs, THandlerReturn> = {\n  /**\n   * Invoke the command with typed object args.\n   * Skips validation (TypeScript handles it), applies defaults, runs middleware.\n   */\n  (args?: Partial<Omit<TArgs, 'unmatched' | '--'>>): Promise<\n    SDKResult<TArgs, THandlerReturn>\n  >;\n  /**\n   * Invoke the command with CLI-style string args.\n   * Runs full pipeline: parse → validate → middleware → handler.\n   * Use this when you need to pass `--` extra args.\n   */\n  (args: string[]): Promise<SDKResult<TArgs, THandlerReturn>>;\n};\n\n/**\n * Recursively builds SDK type from TChildren.\n * Each child command becomes a property on the SDK object.\n */\nexport type SDKChildren<TChildren> = {\n  [K in keyof TChildren]: TChildren[K] extends CLI<\n    infer A,\n    infer R,\n    infer C,\n\n    infer _P,\n    infer _Providers\n  >\n    ? SDKCommand<A, R, C>\n    : never;\n};\n\n/**\n * A single SDK command - callable if it has a handler, with nested children as properties.\n * Container commands (no handler) are not callable but still provide access to children.\n */\nexport type SDKCommand<TArgs, THandlerReturn, TChildren> =\n   \n  // THandlerReturn extends void | undefined\n  // ? SDKChildren<TChildren> // No handler = just children (not callable)\n  SDKInvokable<TArgs, THandlerReturn> & SDKChildren<TChildren>;\n\n/**\n * Constructs a CLI instance. See {@link CLI} for more information.\n * @param name Name for the top level CLI\n * @param rootCommandConfiguration Configuration used when running the bare CLI. e.g. npx my-cli, rather than npx my-cli [cmd]\n * @returns A {@link CLI} instance.\n */\nexport function cli<\n  TArgs extends ParsedArgs,\n  THandlerReturn = void,\n   \n  TChildren = {},\n  TName extends string = string\n>(\n  name: TName,\n  rootCommandConfiguration?: CLICommandOptions<\n    ParsedArgs,\n    TArgs,\n    THandlerReturn,\n    {},\n    any,\n    TChildren\n  >\n) {\n  return new InternalCLI(name, rootCommandConfiguration as any) as any as CLI<\n    TArgs,\n    THandlerReturn,\n    TChildren,\n    undefined,\n    {}\n  >;\n}\n\nexport default cli;\n","import type { Expand, ParsedArgs } from '@cli-forge/parser';\nimport { CLI } from './public-api';\n\n/**\n * Extracts the TChildren type parameter from a CLI type.\n */\nexport type ExtractChildren<T> = T extends CLI<any, any, infer C, any, any>\n  ? C\n  : never;\n\n/**\n * Extracts the TArgs type parameter from a CLI type.\n */\nexport type ExtractArgs<T> = T extends CLI<infer A, any, any, any, any> ? A : never;\n\n/**\n * Type for a composable builder function that transforms a CLI.\n * Used with `chain` to compose multiple builders.\n */\nexport type ComposableBuilder<\n  TArgs2 extends ParsedArgs,\n  TAddedChildren = {},\n  TAddedProviders = {}\n> = <TInit extends ParsedArgs, THandlerReturn, TChildren, TParent, TProviders>(\n  init: CLI<TInit, THandlerReturn, TChildren, TParent, TProviders>\n) => CLI<Expand<TInit & TArgs2>, THandlerReturn, TChildren & TAddedChildren, TParent, TProviders & TAddedProviders>;\n\n/**\n * Creates a composable builder function that can be used with `chain`.\n * Can be used to add options, commands, or any other CLI modifications.\n * Children added by the builder function are properly tracked in the type.\n *\n * The builder function runs once at creation time against a recording Proxy.\n * Subsequent applications replay the captured operations, ensuring inline\n * middleware closures have stable references for Set-based deduplication.\n *\n * @typeParam TArgs2 - The args type after the builder runs\n * @typeParam TChildren2 - The children type added by the builder\n * @typeParam TProviders2 - The providers type added by the builder\n */\nexport function makeComposableBuilder<\n  TArgs2 extends ParsedArgs,\n  TChildren2 = {},\n  TProviders2 = {}\n>(\n  fn: (\n    init: CLI<ParsedArgs, any, {}, any, {}>\n  ) => CLI<TArgs2, any, TChildren2, any, TProviders2>\n) {\n  // Run builder once against a recording proxy to capture operations.\n  // Replaying these ensures inline closures (e.g. middleware) keep stable\n  // references across applications, enabling Set-based deduplication.\n  const operations: { method: string; args: any[] }[] = [];\n  const proxy = new Proxy({} as CLI, {\n    get(_target, prop) {\n      return (...args: any[]) => {\n        operations.push({ method: prop as string, args });\n        return proxy;\n      };\n    },\n  });\n  fn(proxy);\n\n  return <TInit extends ParsedArgs, THandlerReturn, TChildren, TParent, TProviders>(\n    init: CLI<TInit, THandlerReturn, TChildren, TParent, TProviders>\n  ) => {\n    let current: any = init;\n    for (const op of operations) {\n      current = current[op.method](...op.args);\n    }\n    return current as unknown as CLI<\n      Expand<TInit & TArgs2>,\n      THandlerReturn,\n      TChildren & TChildren2,\n      TParent,\n      TProviders & TProviders2\n    >;\n  };\n}\n","import type { ParsedArgs } from '@cli-forge/parser';\nimport { getFileSystemProvider } from '@cli-forge/parser';\n\n/**\n * Context passed to completion callbacks.\n */\nexport interface CompletionContext<TArgs = ParsedArgs> {\n  /** Partially-parsed args available so far */\n  current: Partial<TArgs>;\n  /** The raw argv being completed */\n  argv: string[];\n  /** Default completions cli-forge would return (subcommands, flags, choices) */\n  defaultCompletions: string[];\n}\n\n/**\n * A completion callback that returns custom completion suggestions.\n * Used with `.completion()` on a CLI instance.\n */\nexport type CompletionCallback<TArgs = ParsedArgs> = (\n  context: CompletionContext<TArgs>\n) => string[] | Promise<string[]>;\n\n/**\n * Per-option completion callback, attached to option configs via the `completion` field.\n */\nexport type OptionCompletionCallback<TArgs = ParsedArgs> = (\n  context: CompletionContext<TArgs>\n) => string[] | Promise<string[]>;\n\n/**\n * Helpers for common completion scenarios.\n */\nexport const completionHelpers = {\n  /**\n   * Returns a completion callback that suggests filesystem paths.\n   * @param glob Optional glob pattern to filter results (e.g. '*.json')\n   */\n  files(glob?: string): OptionCompletionCallback {\n    return ({ argv }) => {\n      const fs = getFileSystemProvider();\n      const partial = argv[argv.length - 1] || '';\n      const dir = partial ? fs.dirname(partial) : '.';\n      const prefix = partial ? fs.basename(partial) : '';\n\n      try {\n        let entries: string[] = fs.readdirSync(dir === '' ? '.' : dir);\n\n        if (prefix) {\n          entries = entries.filter((e) => e.startsWith(prefix));\n        }\n\n        if (glob) {\n          // Simple extension filter for patterns like '*.json'\n          const ext = glob.startsWith('*.') ? glob.slice(1) : null;\n          if (ext) {\n            entries = entries.filter((e) => e.endsWith(ext));\n          }\n        }\n\n        return entries.map((e) => (dir === '.' ? e : fs.join(dir, e)));\n      } catch {\n        return [];\n      }\n    };\n  },\n};\n","import { ConfigurationFiles } from '@cli-forge/parser';\n\nlet md: typeof import('markdown-factory') | undefined;\ntry {\n  // markdown-factory is an optional peer dependency\n  md = require('markdown-factory');\n} catch {\n  // not available\n}\n\n/**\n * A collection of built-in configuration provider factories. These should be invoked and passed to\n * {@link CLI.config} to load configuration from various sources. For custom configuration providers, see\n * https://craigory.dev/cli-forge/api/parser/namespaces/ConfigurationFiles/type-aliases/ConfigurationProvider\n *\n * @example\n * ```typescript\n * import { cli, ConfigurationProviders } from 'cli-forge';\n *\n * cli(...).config(ConfigurationProviders.PackageJson('myConfig'));\n * ```\n */\nexport const ConfigurationProviders = {\n  /**\n   * Load configuration from a package.json file.\n   *\n   * @param key The key in the package.json file to load as configuration.\n   */\n  PackageJson<T>(key: string) {\n    return ConfigurationFiles.getPackageJsonConfigurationLoader<T>(key);\n  },\n\n  /**\n   * Load configuration from a JSON file (or files).\n   *\n   * @param filename The filename (or array of possible filenames) of the JSON file to load.\n   *   When an array is provided, each filename gets its own provider wrapped in an aggregate.\n   * @param key The key in the JSON file to load as configuration. By default, the entire JSON object is loaded.\n   */\n  JsonFile<T>(\n    filename: string | string[],\n    key?: string\n  ): ConfigurationFiles.AnyConfigProvider<T> {\n    const transform = key ? (json: any) => json[key] : undefined;\n    const writeTransform = key\n      ? (json: any, config: T) => ({ ...json, [key]: config })\n      : undefined;\n\n    if (Array.isArray(filename)) {\n      const aggregate = ConfigurationFiles.getJsonFileConfigLoader<T>(\n        filename,\n        transform,\n        writeTransform\n      );\n      if (key) {\n        for (let i = 0; i < aggregate.providers.length; i++) {\n          const provider = aggregate.providers[i];\n          if (!ConfigurationFiles.isAggregateConfigProvider(provider)) {\n            applyKeyDescribeConfig(provider, filename[i], key);\n          }\n        }\n      }\n      return aggregate;\n    }\n\n    const loader = ConfigurationFiles.getJsonFileConfigLoader<T>(\n      filename,\n      transform,\n      writeTransform\n    );\n    if (key) {\n      applyKeyDescribeConfig(loader, filename, key);\n    }\n    return loader;\n  },\n};\n\nfunction applyKeyDescribeConfig<T>(\n  loader: ConfigurationFiles.ConfigurationProvider<T>,\n  filename: string,\n  key: string\n) {\n  loader.describeConfig = () => {\n    const heading = `JSON File: ${filename} (key: \"${key}\")`;\n    if (md) {\n      return {\n        heading,\n        body: md.lines(\n          `Searches for ${md.code(filename)}`,\n          'Resolution walks up the directory tree from the working directory, using the nearest match.',\n          `Reads the ${md.code(`\"${key}\"`)} key from the JSON file.`,\n          `Supports ${md.code('\"extends\"')} for configuration inheritance.`,\n          '',\n          md.bold('Example:'),\n          md.codeBlock(\n            JSON.stringify({ [key]: { option: 'value' } }, null, 2),\n            'json'\n          )\n        ),\n      };\n    }\n    return {\n      heading,\n      body: [\n        `Searches for ${filename}`,\n        'Resolution walks up the directory tree from the working directory, using the nearest match.',\n        `Reads the \"${key}\" key from the JSON file.`,\n        'Supports \"extends\" for configuration inheritance.',\n      ].join('\\n\\n'),\n    };\n  };\n}\n"],"mappings":"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"}