import { Colors, Formatter } from "ansispeck"; //#region src/core/schema/brand.d.ts /** * Type-only seal for framework-normalized schema values. * * The symbol has no runtime value: schema objects never carry the key, so * spreads, `structuredClone`, and JSON round-trips are unaffected. The brand * exists purely in the type system — consumers cannot spell the key, so a * structural literal is never assignable to a sealed schema type, and the * normalization factories are the only construction path. * * @module dreamcli/core/schema/brand */ declare const schemaBrand: unique symbol; //#endregion //#region src/core/schema/activity.d.ts /** * Activity types — spinner and progress bar handles, options, events. * * These types define the contract for `Out.spinner()` and `Out.progress()` * lifecycle management. Implementations live in `core/output/activity.ts`. * * @module dreamcli/core/schema/activity */ /** * Non-TTY fallback strategy for spinners and progress bars. * * - `'silent'` — no output at all (default). Ideal for CI where decorative * output is noise. * - `'static'` — emit plain text via `out.log()` / `out.error()` at * lifecycle boundaries (start, succeed, fail). No animation. */ type Fallback = 'silent' | 'static'; /** Options for {@link Out.spinner}. */ interface SpinnerOptions { /** * Fallback strategy when `!isTTY` or `jsonMode`. * @defaultValue `'silent'` */ readonly fallback?: Fallback; } /** * Handle returned by {@link Out.spinner} for lifecycle control. * * Terminal methods (`succeed`, `fail`, `stop`) are idempotent — calling any * of them after the handle is already stopped is a no-op, not an error. */ interface SpinnerHandle { /** Update the spinner text (no-op if stopped). */ update(text: string): void; /** Stop with a success symbol and optional final text. */ succeed(text?: string): void; /** Stop with a failure symbol and optional final text. */ fail(text?: string): void; /** Stop the spinner without a status symbol. */ stop(): void; /** * Wrap a promise: auto-succeed on resolve, auto-fail on reject. * * @returns The resolved value of the wrapped promise. */ wrap(promise: Promise, options?: { readonly succeed?: string; readonly fail?: string; }): Promise; } /** Options for {@link Out.progress}. */ interface ProgressOptions { /** * Total units of work. When provided, the bar shows a determinate * percentage. When omitted, the bar pulses in indeterminate mode. */ readonly total?: number; /** Label displayed alongside the progress bar. */ readonly label?: string; /** * Fallback strategy when `!isTTY` or `jsonMode`. * @defaultValue `'silent'` */ readonly fallback?: Fallback; } /** * Handle returned by {@link Out.progress} for lifecycle control. * * Terminal methods (`done`, `fail`) are idempotent — calling any * of them after the handle is already stopped is a no-op. */ interface ProgressHandle { /** Advance progress by `n` units (default 1). */ increment(n?: number): void; /** Set progress to an absolute value. */ update(value: number): void; /** Mark progress as complete with an optional final message. */ done(text?: string): void; /** Mark progress as failed with an optional final message. */ fail(text?: string): void; } /** * Discriminated union of spinner and progress lifecycle events. * * Captured by testkit in {@link RunResult.activity} for assertion * without polluting stdout/stderr arrays. */ type ActivityEvent = { /** Spinner created and started. */ readonly type: 'spinner:start'; /** Initial spinner text. */ readonly text: string; } | { /** Spinner text changed. */ readonly type: 'spinner:update'; /** Updated spinner text. */ readonly text: string; } | { /** Spinner completed successfully. */ readonly type: 'spinner:succeed'; /** Success message. */ readonly text: string; } | { /** Spinner stopped with an error. */ readonly type: 'spinner:fail'; /** Failure message. */ readonly text: string; } | { /** Spinner stopped without a final status. */ readonly type: 'spinner:stop'; } | { /** Progress bar created and started. */ readonly type: 'progress:start'; /** Bar label. */ readonly label: string; /** Known total, or `undefined` for indeterminate. */ readonly total: number | undefined; } | { /** Progress bar advanced. */ readonly type: 'progress:increment'; /** Amount advanced. */ readonly delta: number; } | { /** Progress bar set to an absolute value. */ readonly type: 'progress:update'; /** New absolute value. */ readonly value: number; } | { /** Progress bar completed. */ readonly type: 'progress:done'; /** Completion message, if any. */ readonly text: string | undefined; } | { /** Progress bar stopped with an error. */ readonly type: 'progress:fail'; /** Failure message, if any. */ readonly text: string | undefined; }; /** * Describes a single column in table output. * * @typeParam T - The row object type (inferred from the rows array). */ interface TableColumn> { /** Property key on the row objects to display in this column. */ readonly key: keyof T & string; /** * Header label for the column. * @defaultValue the {@link TableColumn.key | key} value */ readonly header?: string; } /** Render format override for {@link Out.table}. */ type TableFormat = 'auto' | 'text' | 'json'; /** Output stream override for text table rendering. */ type TableStream = 'stdout' | 'stderr'; /** * Per-call table output options. * * `format: 'auto'` preserves the current mode-dependent behavior. * `format: 'json'` always emits a JSON array to stdout. * `format: 'text'` always renders a human-readable table; when `stream` is * omitted, text defaults to stdout in normal mode and stderr in jsonMode. */ /** Preserve the mode-dependent default — text tables in normal mode, JSON in `jsonMode`. */ interface TableOptionsAuto { /** * Follow the current output mode (text in normal, JSON in jsonMode). * @defaultValue `'auto'` */ readonly format?: 'auto'; } /** Force JSON array output to stdout regardless of output mode. */ interface TableOptionsJson { /** Always emit a JSON array to stdout. */ readonly format: 'json'; } /** Force human-readable text table output, optionally routed to a specific {@link TableStream}. */ interface TableOptionsText { /** Always render a human-readable text table. */ readonly format: 'text'; /** Target stream for text output. Falls back to stdout (stderr in jsonMode). */ readonly stream?: TableStream; } /** Per-call rendering options for {@link Out.table}. */ type TableOptions = TableOptionsAuto | TableOptionsJson | TableOptionsText; //#endregion //#region src/core/help/theme.d.ts /** * Semantic styling roles for help output. * * Roles that appear inside wrap-eligible description text (`defaultValue`, * `annotation`, `deprecated`) should stick to foreground colors and `dim` — * a styled span may cross a soft-wrap boundary, and while color/dim carry * invisibly across the continuation indent, `underline`/`inverse`/background * styles would visibly paint it. */ interface HelpTheme { /** Section headings: `Usage:`, `Arguments:`, `Flags:`, `Commands:`, `Examples:`, `Global options:`. */ readonly sectionTitle: Formatter; /** Binary / command path in the usage line. */ readonly usageBin: Formatter; /** Flag forms in the flags table: `-f, --force`. */ readonly flag: Formatter; /** Grammar tokens: ``, ``, `[flags]`, value hints. */ readonly placeholder: Formatter; /** Command names in `Commands:` tables. */ readonly command: Formatter; /** Positional arg tokens: ``, `[out]...`. */ readonly arg: Formatter; /** Default-value annotations: `(default: 8080)`. */ readonly defaultValue: Formatter; /** Metadata annotations: `[env: X]`, `[config: a.b]`, `[prompt]`, `[required]`, ` (default)`. */ readonly annotation: Formatter; /** Deprecation labels: `[deprecated]`, `[deprecated: use --x]`. */ readonly deprecated: Formatter; /** Program name in the root-help header. */ readonly headerName: Formatter; /** Version (`vX.Y.Z`) in the root-help header. */ readonly headerVersion: Formatter; /** The `$` prompt marker in `Examples:`. */ readonly examplePrompt: Formatter; } /** * Help description text, either literal or resolved against the effective * description theme at render time. */ type HelpDescription = string | ((theme: HelpTheme) => string); /** * User theme customization: receives the gated palette and returns role * overrides merged over the default theme. * * The palette formatters are identity functions when color is disabled, and * the factory itself is only invoked when color is enabled — style * unconditionally, gating is the framework's job. */ type HelpThemeFactory = (colors: Colors) => Partial; //#endregion //#region src/core/schema/number-constraints.d.ts /** * Numeric constraints for number-valued flags and args. * * A single, shared representation and validator so the parse path * (`core/parse`) and the resolver coercion path (`core/resolve/coerce`) cannot * drift: both import {@link validateNumberConstraints} and apply the checks in * the same order (finite → int → min → max). * * @module dreamcli/core/schema/number-constraints */ /** * Runtime numeric constraints attached to a number flag/arg schema. * * Bounds are **inclusive**. All fields are optional; an absent field means "no * constraint" except for {@link NumberConstraints.finite | finite}, which * defaults to `true` (so `Infinity` / `-Infinity` are rejected unless opted * back in). */ interface NumberConstraints { /** * Inclusive lower bound. Values below this are rejected. * @defaultValue `undefined` (no lower bound) */ readonly min?: number; /** * Inclusive upper bound. Values above this are rejected. * @defaultValue `undefined` (no upper bound) */ readonly max?: number; /** * Require an integer value. Non-integers (e.g. `3.7`) are rejected. * @defaultValue `false` */ readonly int?: boolean; /** * Require a finite value. When `true`, `Infinity` / `-Infinity` are rejected. * @defaultValue `true` */ readonly finite?: boolean; } /** * A failed numeric constraint, discriminated by which rule was violated. * * `min` / `max` carry the offending bound so callers can render it. */ type NumberConstraintViolation = { readonly kind: 'finite'; } | { readonly kind: 'int'; } | { readonly kind: 'min'; readonly bound: number; } | { readonly kind: 'max'; readonly bound: number; }; //#endregion //#region src/core/schema/prompt.d.ts /** * Prompt type definitions for interactive flag resolution. * * Prompt configuration is stored on `FlagSchema.prompt` and consumed by the * resolution chain (v0.3+) when a flag value is missing after CLI/env/config * resolution. The prompt engine reads this config to present the appropriate * UI to the user. * * @module dreamcli/core/schema/prompt */ /** All prompt kind discriminators as a runtime array. */ declare const PROMPT_KINDS: readonly ["confirm", "input", "select", "multiselect"]; /** * The kind of interactive prompt to present. * * - `'confirm'` — yes/no boolean question * - `'input'` — free-text string input * - `'select'` — single selection from a list * - `'multiselect'` — multiple selections from a list */ type PromptKind = (typeof PROMPT_KINDS)[number]; /** Shared fields across all prompt kinds. */ interface PromptConfigBase { /** The question displayed to the user. */ readonly message: string; } /** Yes/no confirmation prompt — maps to `boolean` flags. Part of {@link PromptConfig}. */ interface ConfirmPromptConfig extends PromptConfigBase { /** Discriminator identifying this as a yes/no confirmation prompt. */ readonly kind: 'confirm'; /** * Value used when the user submits an empty line (presses Enter). Also * drives the displayed hint: `true` → `(Y/n)`, `false` → `(y/N)`. * @defaultValue `true` */ readonly default?: boolean; } /** Free-text input prompt — maps to `string` and `number` flags. Part of {@link PromptConfig}. */ interface InputPromptConfig extends PromptConfigBase { /** Discriminator identifying this as a free-text input prompt. */ readonly kind: 'input'; /** Placeholder text shown before user types (informational only). */ readonly placeholder?: string; /** * Value used when the user submits an empty line (presses Enter), shown in * the hint as `(default: )`. When set, an empty submission resolves * to this value without running {@link InputPromptConfig.validate | validate}. * When omitted, an empty submission is treated as "no answer" so resolution * falls through to the flag's `.default()`. * @defaultValue `undefined` */ readonly default?: string; /** * Inline validation function. Return `true` if valid, or a string * error message if invalid. Called before coercion to flag kind. */ readonly validate?: (value: string) => true | string; } /** Single-selection prompt — maps to `enum` flags or any flag with {@link SelectChoice choices}. Part of {@link PromptConfig}. */ interface SelectPromptConfig extends PromptConfigBase { /** Discriminator identifying this as a single-selection prompt. */ readonly kind: 'select'; /** * Available choices. When omitted for `enum` flags, the enum values * from the flag schema are used automatically. */ readonly choices?: readonly SelectChoice[]; } /** * Multi-selection prompt — maps to `array` flags. * Returns an array of selected {@link SelectChoice} values. Part of {@link PromptConfig}. */ interface MultiselectPromptConfig extends PromptConfigBase { /** Discriminator identifying this as a multi-selection prompt. */ readonly kind: 'multiselect'; /** * Available choices. When omitted for `array` flags with enum elements, * the enum values from the element schema are used automatically. */ readonly choices?: readonly SelectChoice[]; /** * Minimum number of selections required. * @defaultValue `0` */ readonly min?: number; /** * Maximum number of selections allowed. * @defaultValue `Infinity` */ readonly max?: number; } /** A selectable option for {@link SelectPromptConfig} and {@link MultiselectPromptConfig} prompts. */ interface SelectChoice { /** The value returned when this choice is selected. */ readonly value: string; /** * Display label shown to the user. * @defaultValue {@link SelectChoice.value | value} */ readonly label?: string; /** Optional description shown alongside the choice. */ readonly description?: string; } /** * Discriminated union of all prompt configurations. * * Use the `kind` field to narrow: * ```ts * if (config.kind === 'select') { * config.choices // readonly SelectChoice[] | undefined * } * ``` */ type PromptConfig = ConfirmPromptConfig | InputPromptConfig | SelectPromptConfig | MultiselectPromptConfig; /** * The raw result returned by a prompt engine for a single prompt. * * - `answered: true` — user provided a value * - `answered: false` — user cancelled/aborted (Ctrl+C, ESC, etc.) * * Coercion to the flag's kind is the resolver's responsibility, not the * prompt engine's. */ type PromptResult = { /** User provided a value. */ readonly answered: true; /** The raw value from the prompt engine (not yet coerced). */ readonly value: unknown; } | { /** User cancelled or aborted (Ctrl+C, ESC, etc.). */ readonly answered: false; }; //#endregion //#region src/core/schema/standard.d.ts /** * The Standard Schema v1 interface, vendored as types only. * * Mirrors the specification at https://standardschema.dev so validators from * zod, valibot, arktype, and any other conforming library can be passed to * `flag.custom()` / `arg.custom()` without adding a runtime dependency. * * @module */ /** A schema that conforms to the Standard Schema v1 specification. */ interface StandardSchemaV1 { /** The Standard Schema properties, namespaced under a well-known key. */ readonly '~standard': StandardSchemaV1.Props; } /** Types copied from the Standard Schema v1 specification. */ declare namespace StandardSchemaV1 { /** The properties exposed under a validator's `~standard` key. */ interface Props { /** The version number of the specification. */ readonly version: 1; /** The vendor name of the schema library. */ readonly vendor: string; /** Validate an unknown value, returning its output or the issues found. */ readonly validate: (value: unknown, options?: Options | undefined) => Result | Promise>; /** Inferred input and output types, present only at the type level. */ readonly types?: Types | undefined; } /** Optional parameters passed to a validator. */ interface Options { /** Explicit support for vendor-specific validation parameters. */ readonly libraryOptions?: Record | undefined; } /** The result of validating a value: either its output or a list of issues. */ type Result = SuccessResult | FailureResult; /** A successful validation carrying the parsed output value. */ interface SuccessResult { /** The validated (and possibly transformed) value. */ readonly value: Output; /** Absent on success. */ readonly issues?: undefined; } /** A failed validation carrying validation issues. */ interface FailureResult { /** The issues that caused validation to fail. */ readonly issues: ReadonlyArray; } /** A single validation issue. */ interface Issue { /** The human-readable error message. */ readonly message: string; /** The path to the offending value, when the validator reports one. */ readonly path?: ReadonlyArray | undefined; } /** One segment of an issue path. */ interface PathSegment { /** The key of this path segment. */ readonly key: PropertyKey; } /** The type-level input and output carried by a validator. */ interface Types { /** The input type accepted by the validator. */ readonly input: Input; /** The output type produced by the validator. */ readonly output: Output; } /** Infer the input type of a Standard Schema validator. */ type InferInput = NonNullable['input']; /** Infer the output type of a Standard Schema validator. */ type InferOutput = NonNullable['output']; } /** Backward-compatible flat alias for {@link StandardSchemaV1.Props}. */ type StandardSchemaV1Props = StandardSchemaV1.Props; /** Flat alias for {@link StandardSchemaV1.Options}. */ type StandardSchemaV1Options = StandardSchemaV1.Options; /** Flat alias for {@link StandardSchemaV1.Result}. */ type StandardSchemaV1Result = StandardSchemaV1.Result; /** Flat alias for {@link StandardSchemaV1.SuccessResult}. */ type StandardSchemaV1SuccessResult = StandardSchemaV1.SuccessResult; /** Flat alias for {@link StandardSchemaV1.FailureResult}. */ type StandardSchemaV1FailureResult = StandardSchemaV1.FailureResult; /** Flat alias for {@link StandardSchemaV1.Issue}. */ type StandardSchemaV1Issue = StandardSchemaV1.Issue; /** Flat alias for {@link StandardSchemaV1.PathSegment}. */ type StandardSchemaV1PathSegment = StandardSchemaV1.PathSegment; /** Backward-compatible flat alias for {@link StandardSchemaV1.Types}. */ type StandardSchemaV1Types = StandardSchemaV1.Types; /** Flat alias for {@link StandardSchemaV1.InferInput}. */ type InferStandardInput = StandardSchemaV1.InferInput; /** Flat alias for {@link StandardSchemaV1.InferOutput}. */ type InferStandardOutput = StandardSchemaV1.InferOutput; //#endregion //#region src/core/schema/stdin.d.ts /** * The stdin binding shared by the `flag` and `arg` factories. * * A {@link StdinBinding} says when an input reads the stdin stream, whether it * consumes the stream alone, and whether a single value drops the terminator a * pipe appends. Both factories store one of these under their `stdin` field, and * the parse, preflight, and resolve pipelines read the stdin axis through it. * * @module dreamcli/core/schema/stdin */ /** All stdin trigger modes as a runtime array. */ declare const STDIN_WHENS: readonly ["dash", "missing", "dash-or-missing"]; /** * When a stdin-enabled input reads the stdin stream. * * - `'dash'` — only an explicit `-` selects stdin; an absent input falls * through to the later sources * - `'missing'` — only an absent input selects stdin; a `-` stays the literal * string `'-'` * - `'dash-or-missing'` — both select stdin */ type StdinWhen = (typeof STDIN_WHENS)[number]; /** All stdin consumption modes as a runtime array. */ declare const STDIN_CONSUMES: readonly ["exclusive", "broadcast"]; /** * How a stdin-enabled input shares the stream with the command's other inputs. * * - `'exclusive'` — this input is the command's only stdin consumer, and a * second exclusive consumer is a schema error * - `'broadcast'` — every broadcast consumer on the command receives the same * buffer */ type StdinConsume = (typeof STDIN_CONSUMES)[number]; /** The normalized stdin axis of a flag or an arg. */ interface StdinBinding { /** When this input reads the stdin stream. */ readonly when: StdinWhen; /** Whether this input consumes the stream alone. */ readonly consume: StdinConsume; /** Whether one trailing line terminator is dropped from a single value. */ readonly trim: boolean; } /** Stdin settings accepted by `.stdin()` and by the schema definitions. */ interface StdinOptions { /** * When this input reads the stdin stream. * @defaultValue `'dash-or-missing'` */ readonly when?: StdinWhen | undefined; /** * Whether this input consumes the stream alone. * @defaultValue `'exclusive'` */ readonly consume?: StdinConsume | undefined; /** * Drop one trailing `\n`, `\r\n`, or `\r` from a single value read off the * stream, so `echo ./dir | mycli` delivers `'./dir'`. A string is the one * kind that still carries the terminator at that point; every other kind * drops it while decoding and is unaffected. * @defaultValue `false` */ readonly trim?: boolean | undefined; } //#endregion //#region src/core/schema/string-constraints.d.ts /** * String constraints for string-valued flags. * * A single, shared representation and validator so the parse path * (`core/parse`) and the resolver coercion path (`core/resolve/coerce`) cannot * drift: both import {@link validateStringConstraints} and apply the checks in * the same order (nonEmpty → minLength → maxLength → pattern). * * @module dreamcli/core/schema/string-constraints */ /** * Runtime string constraints attached to a string flag/arg schema. * * Length bounds are **inclusive** and measured in UTF-16 code units * (`String.prototype.length`). All fields are optional; an absent field means * "no constraint". */ interface StringConstraints { /** * Reject empty strings (`''`). Whitespace-only strings are still accepted; * combine with {@link StringConstraints.pattern | pattern} for stricter rules. * @defaultValue `false` */ readonly nonEmpty?: boolean; /** * Inclusive minimum length. Shorter values are rejected. * @defaultValue `undefined` (no minimum) */ readonly minLength?: number; /** * Inclusive maximum length. Longer values are rejected. * @defaultValue `undefined` (no maximum) */ readonly maxLength?: number; /** * Regular expression the value must match. Tested with * `RegExp.prototype.test`; anchor with `^`/`$` for full-string matching. * @defaultValue `undefined` (no pattern) */ readonly pattern?: RegExp; } /** * A failed string constraint, discriminated by which rule was violated. * * `minLength` / `maxLength` carry the offending bound and `pattern` carries * the source so callers can render them. */ type StringConstraintViolation = { readonly kind: 'nonEmpty'; } | { readonly kind: 'minLength'; readonly bound: number; } | { readonly kind: 'maxLength'; readonly bound: number; } | { readonly kind: 'pattern'; readonly pattern: string; }; //#endregion //#region src/core/schema/value-parsers.d.ts /** * Value-level machinery behind the sugar factories on both `flag` and `arg` * (`url()`, `path()`, `date()`, `duration()`, `bytes()`). * * Each parser converts a raw CLI/env/config/stdin value into a typed value and * throws a plain `Error` with a raw-free reason on invalid input. The parse and * resolve pipelines own value display and redaction, then add the subject's * context. Developer-authored custom parser messages remain verbatim. * * The option types keep their `Flag` prefix from the release that introduced * them on the flag factory alone. They describe the value, not flag syntax, * and the arg factory takes the same objects. * * @module dreamcli/core/schema/value-parsers */ /** Options accepted by `flag.url()` and `arg.url()`. */ interface UrlFlagOptions { /** * Allowed URL protocols, without the trailing colon (e.g. `['https']`). * @defaultValue `undefined` (any protocol) */ readonly protocols?: readonly string[]; } /** Options accepted by `flag.date()` and `arg.date()`. */ interface DateFlagOptions { /** * Inclusive earliest allowed date. * @defaultValue `undefined` (no lower bound) */ readonly min?: Date; /** * Inclusive latest allowed date. * @defaultValue `undefined` (no upper bound) */ readonly max?: Date; } /** Options accepted by `flag.path()` and `arg.path()` for any-kind or file paths. */ interface FilePathFlagOptions { /** * Reject the value if nothing exists at the path. * @defaultValue `false` (`true` when `type` is set) */ readonly mustExist?: boolean; /** * Require the path to be a file or a directory. Implies existence * unless `mustExist` is explicitly `false`, in which case a missing * path passes and only an existing path is type-checked. * @defaultValue `undefined` (any kind) */ readonly type?: 'file'; /** Directory creation is only available with `type: 'directory'`. */ readonly create?: never; } /** Options accepted by `flag.path()` and `arg.path()` for directory paths. */ interface DirectoryPathFlagOptions { /** * Reject the value if nothing exists at the path. * @defaultValue `false` (`true` when `type` is set) */ readonly mustExist?: boolean; /** * Require the path to be a directory. Implies existence unless * `mustExist` is explicitly `false`, in which case a missing path * passes and only an existing path is type-checked. */ readonly type: 'directory'; /** * Create the directory (recursively) when nothing exists at the path. * An existing non-directory path still fails the type check. * @defaultValue `false` */ readonly create?: boolean; } /** Options accepted by `flag.path()` and `arg.path()`. */ type PathFlagOptions = FilePathFlagOptions | DirectoryPathFlagOptions; /** * Filesystem expectations attached by `flag.path()` and `arg.path()`. * * Checked after resolution (not during parse) via the runtime adapter, so * `src/core` stays free of platform I/O and every resolved value is validated * whichever source produced it, defaults included. */ interface PathChecks { /** Reject the value if nothing exists at the path. */ readonly mustExist: boolean; /** * Require the existing path to be a file or a directory. Implies * existence when set, unless `mustExist` is `false`. */ readonly type: 'file' | 'directory' | undefined; /** Create the directory (recursively) when nothing exists at the path. */ readonly create: boolean; } //#endregion //#region src/core/schema/flag.d.ts /** All flag presence states as a runtime array. */ declare const FLAG_PRESENCES: readonly ["optional", "required", "defaulted"]; /** * Presence describes whether a flag value is guaranteed to exist when the * action handler runs: * * - `'optional'` — not required; unresolved value follows the kind-specific * optional fallback (`undefined` for most flags, `[]` for arrays) * - `'required'` — must be supplied; error if missing * - `'defaulted'` — always present (falls back to default value) */ type FlagPresence = (typeof FLAG_PRESENCES)[number]; /** * Fallback behavior when an optional flag resolves no value from any source. * * Most optional flags resolve to `undefined`; array flags instead resolve to * an empty array `[]`, and key-value flags to an empty object `{}`. */ type OptionalFallback = 'undefined' | 'empty-array' | 'empty-object'; /** * Compile-time state carried through the builder chain. * * Adding new tracked properties only requires extending this interface — no * builder signature changes. */ interface FlagConfig { /** The resolved value type (e.g. `string`, `number`, `'us' | 'eu'`). */ readonly valueType: unknown; /** Whether the flag is optional, required, or has a default. */ readonly presence: FlagPresence; /** What an unresolved optional flag becomes at the action boundary. */ readonly optionalFallback: OptionalFallback; /** The runtime kind discriminator, mirroring {@link FlagKind}. */ readonly flagKind: FlagKind; /** * Whether this builder may still be passed to `flag.array()` as the * element schema. * * Factories producing element-meaningful kinds start `true`. Flag-level * modifiers (`.alias()`, `.env()`, `.prompt()`, `.default()`, …) flip it * to `false` — those settings describe the *flag*, are never read from an * element schema, and would otherwise be silently ignored. */ readonly elementEligible: boolean; } /** * Advanced type helper used by {@linkcode FlagBuilder} modifiers to replace presence. * Most consumers rely on inference and never reference this directly. */ type WithPresence = { readonly valueType: C['valueType']; readonly presence: P; readonly optionalFallback: C['optionalFallback']; readonly flagKind: C['flagKind']; readonly elementEligible: false; }; /** * Advanced type helper: marks a builder as no longer usable as an array * element (returned by flag-level modifiers whose settings elements ignore). */ type WithoutElementEligibility = { readonly valueType: C['valueType']; readonly presence: C['presence']; readonly optionalFallback: C['optionalFallback']; readonly flagKind: C['flagKind']; readonly elementEligible: false; }; /** * Compute the final value type from config — this is what handlers receive. * * Advanced type helper: this powers {@link InferFlag} and action-handler * inference. Most apps do not need to mention it explicitly. * * - `'optional'` + `'undefined'` fallback → `T | undefined` * - `'optional'` + `'empty-array'` / `'empty-object'` fallback → `T` * - `'required'` → `T` * - `'defaulted'` → `T` */ type ResolvedValue = C['presence'] extends 'optional' ? C['optionalFallback'] extends 'undefined' ? C['valueType'] | undefined : C['valueType'] : C['valueType']; /** * The element config a collection factory assumes when given no element * builder: an unconstrained string. */ type StringElementConfig = { /** Element value type. */ readonly valueType: string; /** Elements carry no presence of their own. */ readonly presence: 'optional'; /** Elements carry no fallback of their own. */ readonly optionalFallback: 'undefined'; /** Element kind discriminator. */ readonly flagKind: 'string'; /** Elements are element-eligible by construction. */ readonly elementEligible: true; }; /** Extract the resolved value type from a {@linkcode FlagBuilder}. */ type InferFlag = B extends FlagBuilder ? ResolvedValue : never; /** Extract resolved value types from a record of builders. */ type InferFlags>> = { [K in keyof T]: InferFlag; }; /** * Maps a {@linkcode FlagConfig} to the prompt config types that are compatible * with the flag's kind. Prevents compile-time mismatches such as * `flag.enum([…]).prompt({ kind: 'multiselect' })`. * * - `'boolean'` → {@link ConfirmPromptConfig} * - `'string'` → {@link InputPromptConfig} | {@link SelectPromptConfig} * - `'number'` → {@link InputPromptConfig} * - `'enum'` → {@link SelectPromptConfig} | {@link InputPromptConfig} * - `'array'` → {@link MultiselectPromptConfig} * - `'custom'` → all prompt kinds ({@link PromptConfig}) * - `'count'` / `'keyValue'` → `never` (not promptable) */ type PromptConfigByFlagKind = { readonly string: InputPromptConfig | SelectPromptConfig; readonly number: InputPromptConfig; readonly boolean: ConfirmPromptConfig; readonly enum: SelectPromptConfig | InputPromptConfig; readonly array: MultiselectPromptConfig; readonly custom: PromptConfig; readonly count: never; readonly keyValue: never; }; /** Prompt configuration compatible with the kind carried by a {@link FlagConfig}. */ type AllowedPromptConfig = PromptConfigByFlagKind[C['flagKind']]; /** All flag kind discriminators as a runtime array. */ declare const FLAG_KINDS: readonly ["string", "number", "boolean", "enum", "array", "custom", "count", "keyValue"]; /** Discriminator for the kind of value a flag accepts. */ type FlagKind = (typeof FLAG_KINDS)[number]; /** * Custom parse function for `flag.custom()`. * * Receives `string` from CLI argv and env vars, or any JSON-representable * value from config files. Narrow inside the function as needed. */ type FlagParseFn = (raw: unknown) => T; /** Options controlling how a declared default appears in help output. */ interface DefaultValueOptions { /** * Human-readable default text, or `false` to hide the default from help. * `undefined` uses the default value's automatic rendering when it is safe. */ readonly description?: string | false; } /** Runtime descriptor for a flag alias. */ interface FlagAlias { /** Alias name without `-` / `--` prefix. */ readonly name: string; /** Whether the alias is parser-only and hidden from user-facing surfaces. */ readonly hidden: boolean; } /** * Negation settings for a boolean flag (set by `.negatable()`). * * The negated spelling and the positive form are two spellings of ONE * logical flag: they share duplicate policy, and the last CLI occurrence * wins across both. The negated spelling is presence-only — `--no-foo=x` * is rejected. */ interface FlagNegation { /** * Explicit negated spelling without the `--` prefix (e.g. `'no-sandbox'`). * `undefined` synthesizes `no-` wherever the flag name is known. */ readonly alias: string | undefined; /** Hide the negated spelling from help, completions, and suggestions. */ readonly hidden: boolean; } /** * How repeated CLI occurrences of a singleton flag combine. * * - `'last'` — last occurrence wins (matches historic behavior) * - `'first'` — first occurrence wins; later ones parse but are ignored * - `'error'` — a second occurrence is a `ParseError` (`DUPLICATE_FLAG`) * * Applies to CLI token occurrences only — env/config/prompt/default * resolution keeps its precedence semantics and never raises duplicates. * Occurrences are counted per *logical* flag: aliases and the negated * spelling all count toward the same flag. * * @defaultValue `'last'` */ type DuplicatePolicy = 'last' | 'first' | 'error'; /** * The runtime descriptor stored inside every {@linkcode FlagBuilder}. Consumers (parser, * help generator, resolution chain) read this to understand the flag's shape * without touching generics. */ interface FlagSchema { /** Type-only seal produced by {@link createFlagSchema}. */ readonly [schemaBrand]: 'flag'; /** What kind of value this flag accepts. */ readonly kind: K; /** Current presence state. */ readonly presence: FlagPresence; /** Runtime default value (if any). */ readonly defaultValue: unknown; /** * Human-readable replacement for the default value in help, or `false` to * omit the default annotation. */ readonly defaultDescription: string | false | undefined; /** Whether values from this input must be kept out of user-facing projections. */ readonly sensitive: boolean; /** Short/long aliases (e.g. `[{ name: 'f', hidden: false }]` for `--force`). */ readonly aliases: readonly FlagAlias[]; /** * Stdin binding set by `.stdin()` (`undefined` when the flag never reads * stdin). See {@link StdinBinding}. */ readonly stdin: StdinBinding | undefined; /** Environment variable name for v0.2+ resolution. */ readonly envVar: string | undefined; /** Dotted config path for v0.2+ resolution (e.g. `'deploy.region'`). */ readonly configPath: string | undefined; /** Human-readable description for help text. */ readonly description: HelpDescription | undefined; /** Allowed literal values when `kind === 'enum'`. */ readonly enumValues: readonly string[] | undefined; /** * Numeric constraints when `kind === 'number'` (`undefined` otherwise). * * Enforced at the parse and resolution boundaries. `finite` defaults to * `true`, so `Infinity` is rejected even when no constraints object is set. */ readonly numberConstraints: NumberConstraints | undefined; /** * String constraints when `kind === 'string'` (`undefined` otherwise). * * Enforced at the parse and resolution boundaries, in fixed order: * nonEmpty → minLength → maxLength → pattern. */ readonly stringConstraints: StringConstraints | undefined; /** Element schema when `kind === 'array'` or `kind === 'keyValue'`. */ readonly elementSchema: FlagSchema | undefined; /** * CLI value separator for a collection kind (`undefined` otherwise). * * When set, each CLI occurrence is split on this separator before element * coercion, so `--tag a,b --tag c` yields `['a', 'b', 'c']`. Other sources * decode through {@link FlagSchema.split}. */ readonly separator: string | undefined; /** * Env and stdin split policies for a collection kind (`undefined` otherwise). * * A source the binding leaves out takes its default: comma-delimited for env, * line-delimited for stdin. */ readonly split: SourceSplitBinding | undefined; /** * How a repeated key combines when `kind === 'keyValue'`. * * @defaultValue `'last'` */ readonly duplicateKeys: DuplicateKeys; /** * Deduplicate resolved array values when `kind === 'array'`. * * Applied after all sources resolve, preserving first-seen order. * Uses `SameValueZero` semantics (like `Set`). */ readonly unique: boolean; /** * Filesystem checks for path-valued flags (set by `flag.path()`). * * Validated after resolution through the runtime adapter. */ readonly pathChecks: PathChecks | undefined; /** * Help placeholder label (e.g. `'url'` renders as ``). * * Set by the sugar factories (`flag.url()`, `flag.date()`, …) so help * output names the expected value shape; `undefined` falls back to the * kind-derived hint. */ readonly valueHint: string | undefined; /** Interactive prompt configuration for v0.3+ resolution. */ readonly prompt: PromptConfig | undefined; /** Custom parse function (only when `kind === 'custom'`). */ readonly parseFn: FlagParseFn | undefined; /** * Standard Schema v1 validator applied to each resolved value. * * When set, the value from any source (CLI, env, config, prompt, default) * is validated after resolution via `~standard.validate`. Sync and async * validators are both awaited; issues surface as a `CONSTRAINT_VIOLATED` * {@link ValidationError}. On a collection this validates every element, * whether it rides here or on {@link FlagSchema.elementSchema}. */ readonly standard: StandardSchemaV1 | undefined; /** * Standard Schema v1 validator applied to the completed collection. * * Set by `.standard()` on a collection builder, so the array or record the * aggregation produced is validated as a whole after every element passed. */ readonly aggregateStandard: StandardSchemaV1 | undefined; /** * Deprecation marker. * * - `undefined` — not deprecated (default) * - `true` — deprecated with no migration message * - `string` — deprecated with a reason/migration message * * When a deprecated flag is used, a warning is emitted to stderr. * Help text shows `[deprecated]` or `[deprecated: ]`. */ readonly deprecated: string | true | undefined; /** * Whether this flag propagates to subcommands in nested command trees. * * When `true`, the flag is automatically available to all descendant * commands. A child command that defines a flag with the same name * shadows the propagated parent flag. * * @defaultValue `false` */ readonly propagate: boolean; /** * Negation settings when `kind === 'boolean'` and `.negatable()` was * called (`undefined` otherwise). See {@link FlagNegation}. */ readonly negation: FlagNegation | undefined; /** * Duplicate policy for repeated CLI occurrences. See {@link DuplicatePolicy}. * * @defaultValue `'last'` */ readonly duplicates: DuplicatePolicy; } /** Definition fields accepted by every flag kind. */ interface FlagDefinitionBase { /** * Presence state. * @defaultValue `'optional'` */ readonly presence?: FlagPresence | undefined; /** * Runtime default value. * @defaultValue `undefined` */ readonly defaultValue?: unknown; /** * Human-readable replacement for the default value in help, or `false` to * omit the default annotation. * @defaultValue `undefined` */ readonly defaultDescription?: string | false | undefined; /** * Whether values from this input must be kept out of user-facing projections. * @defaultValue `false` */ readonly sensitive?: boolean | undefined; /** * Short/long aliases as bare names or {@link FlagAlias} records. * @defaultValue `[]` */ readonly aliases?: readonly (string | FlagAlias)[] | undefined; /** * Stdin binding. See {@link StdinOptions}. * @defaultValue `undefined` */ readonly stdin?: StdinOptions | undefined; /** * Environment variable name for env resolution. * @defaultValue `undefined` */ readonly envVar?: string | undefined; /** * Dotted config path for config resolution (e.g. `'deploy.region'`). * @defaultValue `undefined` */ readonly configPath?: string | undefined; /** * Human-readable description for help text. * @defaultValue `undefined` */ readonly description?: HelpDescription | undefined; /** * Help placeholder label (`'url'` renders as ``). * @defaultValue `undefined` */ readonly valueHint?: string | undefined; /** * Interactive prompt configuration. * @defaultValue `undefined` */ readonly prompt?: PromptConfig | undefined; /** * Standard Schema v1 validator applied to each resolved value. * @defaultValue `undefined` */ readonly standard?: StandardSchemaV1 | undefined; /** * Standard Schema v1 validator applied to a completed collection. * @defaultValue `undefined` */ readonly aggregateStandard?: StandardSchemaV1 | undefined; /** * Deprecation marker. `true` deprecates without a message, a string carries * the migration guidance. * @defaultValue `undefined` */ readonly deprecated?: string | true | undefined; /** * Whether the flag propagates to descendant commands. * @defaultValue `false` */ readonly propagate?: boolean | undefined; /** * How repeated CLI occurrences combine. See {@link DuplicatePolicy}. * @defaultValue `'last'` */ readonly duplicates?: DuplicatePolicy | undefined; } /** Definition of a `string` flag. */ interface StringFlagDefinition extends FlagDefinitionBase { /** Kind discriminator. */ readonly kind: 'string'; /** * String constraints enforced at the parse and resolution boundaries. * @defaultValue `undefined` */ readonly stringConstraints?: StringConstraints | undefined; /** * Filesystem checks applied after resolution. * @defaultValue `undefined` */ readonly pathChecks?: PathChecks | undefined; } /** Definition of a `number` flag. */ interface NumberFlagDefinition extends FlagDefinitionBase { /** Kind discriminator. */ readonly kind: 'number'; /** * Numeric constraints enforced at the parse and resolution boundaries. * @defaultValue `undefined` */ readonly numberConstraints?: NumberConstraints | undefined; } /** Definition of a `boolean` flag. */ interface BooleanFlagDefinition extends FlagDefinitionBase { /** Kind discriminator. */ readonly kind: 'boolean'; /** * Negated-spelling settings. See {@link FlagNegation}. * @defaultValue `undefined` */ readonly negation?: FlagNegation | undefined; } /** Definition of an `enum` flag. */ interface EnumFlagDefinition extends FlagDefinitionBase { /** Kind discriminator. */ readonly kind: 'enum'; /** Allowed literal values. */ readonly enumValues: readonly string[]; } /** Definition of an `array` flag. */ interface ArrayFlagDefinition extends FlagDefinitionBase { /** Kind discriminator. */ readonly kind: 'array'; /** * Element definition or an already-built element schema. * @defaultValue `undefined` */ readonly elementSchema?: FlagDefinition | FlagSchema | undefined; /** * Value separator each CLI occurrence is split on. * @defaultValue `undefined` */ readonly separator?: string | undefined; /** * Env and stdin split policies. * @defaultValue `undefined` */ readonly split?: SourceSplitBinding | undefined; /** * Deduplicate the resolved array, preserving first-seen order. * @defaultValue `false` */ readonly unique?: boolean | undefined; } /** Definition of a `custom` flag. */ interface CustomFlagDefinition extends FlagDefinitionBase { /** Kind discriminator. */ readonly kind: 'custom'; /** * Parse function applied to the raw value. * @defaultValue `undefined` */ readonly parseFn?: FlagParseFn | undefined; } /** Definition of a `count` flag. */ interface CountFlagDefinition extends FlagDefinitionBase { /** Kind discriminator. */ readonly kind: 'count'; } /** Definition of a `keyValue` flag. */ interface KeyValueFlagDefinition extends FlagDefinitionBase { /** Kind discriminator. */ readonly kind: 'keyValue'; /** * Element definition or an already-built element schema for each entry value. * @defaultValue `undefined` */ readonly elementSchema?: FlagDefinition | FlagSchema | undefined; /** * Pair separator each CLI occurrence is split on. * @defaultValue `undefined` */ readonly separator?: string | undefined; /** * Env and stdin split policies. * @defaultValue `undefined` */ readonly split?: SourceSplitBinding | undefined; /** * How a repeated key combines. See {@link DuplicateKeys}. * @defaultValue `'last'` */ readonly duplicateKeys?: DuplicateKeys | undefined; } /** Maps each {@link FlagKind} to its definition shape. */ interface FlagDefinitionByKind { /** Definition shape for `string` flags. */ readonly string: StringFlagDefinition; /** Definition shape for `number` flags. */ readonly number: NumberFlagDefinition; /** Definition shape for `boolean` flags. */ readonly boolean: BooleanFlagDefinition; /** Definition shape for `enum` flags. */ readonly enum: EnumFlagDefinition; /** Definition shape for `array` flags. */ readonly array: ArrayFlagDefinition; /** Definition shape for `custom` flags. */ readonly custom: CustomFlagDefinition; /** Definition shape for `count` flags. */ readonly count: CountFlagDefinition; /** Definition shape for `keyValue` flags. */ readonly keyValue: KeyValueFlagDefinition; } /** Definition of a flag of kind `K`, including the kind discriminator. */ type FlagDefinition = FlagDefinitionByKind[K]; /** Definition of a flag of kind `K` with the kind discriminator removed. */ type FlagDefinitionOverrides = Omit; /** Positional factory arguments, requiring fields that the selected kind requires. */ type FlagDefinitionArguments = K extends 'enum' ? [overrides: FlagDefinitionOverrides] : [overrides?: FlagDefinitionOverrides]; /** * Effective negated spelling for a flag, or `undefined` when not negatable. * * The builder cannot know its flag name, so a default (`no-`) is * synthesized here — everywhere the canonical name is known (parser, help, * completions, collision validation). * * @param name - Canonical flag name. * @param schema - Flag schema (read for {@link FlagNegation}). * @returns The negated spelling without the `--` prefix. */ declare function getFlagNegatedName(name: string, schema: FlagSchema): string | undefined; /** Flag kinds that can read from stdin: every scalar, plus the collections. */ declare const STDIN_CAPABLE_FLAG_KINDS: readonly ['string', 'number', 'boolean', 'enum', 'custom', 'array', 'keyValue']; type StdinCapableFlagKind = (typeof STDIN_CAPABLE_FLAG_KINDS)[number]; /** * Create a raw {@link FlagSchema} object with sensible defaults. * * Most consumers should prefer the higher-level {@link flag} factory, which * returns an immutable {@link FlagBuilder} with type inference and safe * modifier chaining. `createFlagSchema()` is the low-level escape hatch for * advanced schema composition, tests, or custom factories that need the plain * runtime descriptor. * * Fields are shallow-merged on top of the default shape, so callers are * responsible for keeping the resulting schema internally consistent. * * @param kind - Discriminator for the value type this flag accepts. * @param overrides - Definition fields for `kind`, shallow-merged onto defaults. * @returns A fully populated {@link FlagSchema}. * @throws {CLIError} With code `'INVALID_SCHEMA'` when a field belongs to a * different {@link FlagKind}. * * @example * ```ts * const schema = createFlagSchema('enum', { * enumValues: ['us', 'eu', 'ap'], * description: 'Deployment region', * }); * ``` */ declare function createFlagSchema(kind: K, ...overrides: FlagDefinitionArguments): FlagSchema; /** * Create a raw {@link FlagSchema} object from a single definition object. * * An already-built {@link FlagSchema} is accepted and re-normalized into a * deep-equal schema. * * @param definition - Kind discriminator plus the fields valid for that kind. * @returns A fully populated {@link FlagSchema}. * @throws {CLIError} With code `'INVALID_SCHEMA'` when a field belongs to a * different {@link FlagKind}. * * @example * ```ts * const schema = createFlagSchema({ * kind: 'array', * elementSchema: { kind: 'string' }, * separator: ',', * }); * ``` */ declare function createFlagSchema(definition: FlagDefinition | FlagSchema): FlagSchema; /** * Immutable flag schema builder. * * The type parameter `C` is a phantom that tracks the value type and presence * through the fluent chain. Each modifier returns a **new** builder — the * original is never mutated. * * @example * ```ts * const port = flag.number().default(8080); * type Port = InferFlag; // number * * const region = flag.enum(['us', 'eu', 'ap']); * type Region = InferFlag; // 'us' | 'eu' | 'ap' | undefined * ``` */ declare class FlagBuilder { /** @internal Runtime schema descriptor. */ readonly schema: FlagSchema; /** * @internal Type brand — exists only in the type system (`declare` * produces no runtime property). Used by {@linkcode InferFlag} / {@linkcode InferFlags}. */ readonly _config: C; /** * Create a flag builder from a pre-built schema descriptor. * * @param schema - Runtime descriptor seeding this builder's state. */ constructor(schema: FlagSchema); /** * Provide a default value. The flag becomes "always present" — handlers * will never see `undefined`. * * The generic constraint `V extends C['valueType']` ensures the default * matches the flag's declared type. * * @param value - Fallback value used when no source provides one. * @param options - Optional help presentation for the default. * @returns The builder (for chaining). * * @example * ```ts * flag.number().default(8080).describe('Port to listen on') * * // $ mycli serve → port = 8080 * // $ mycli serve --port 443 → port = 443 * ``` */ default(value: V, options?: DefaultValueOptions): FlagBuilder>; /** * Mark the flag as required. If not resolved from any source the framework * will emit a `ValidationError` before the action handler runs. * * @returns The builder (for chaining). * * @example * ```ts * flag.string().required().describe('Deploy target') * * // $ mycli deploy * // # → Error: Missing required flag --target * // $ mycli deploy --target staging * // # → target = 'staging' * ``` */ required(): FlagBuilder>; /** * Mark this input's values as sensitive. * * Sensitive defaults are omitted from definition and input JSON Schemas and * from automatic help text. A custom default description remains safe to show. * * @param value - Whether this input is sensitive. * @defaultValue `true` * @returns The builder (for chaining). */ sensitive(value?: boolean): FlagBuilder>; /** * Add a short or long alias (e.g. `'f'` for `--force`, `'verbose'` as an * alternative long name). * * @param name - Single-char short alias or alternative long name. * @param options - Optional alias metadata. Hidden aliases remain parseable * but are omitted from help, completions, and suggestions. * @returns The builder (for chaining). * * @example * ```ts * flag.boolean().alias('v').describe('Enable verbose output') * * // $ mycli build -v → verbose = true * // $ mycli build --verbose → verbose = true * ``` */ alias(name: string, options?: { hidden?: boolean; }): FlagBuilder>; /** * Bind to an environment variable (resolved in v0.2+). * * The env value is read after CLI and stdin, and before config, the prompt, * and the default: CLI → stdin → **env** → config → prompt → default. * * @param varName - Environment variable name (e.g. `'PORT'`). * @returns The builder (for chaining). * * @example * ```ts * flag.string().env('API_KEY').describe('Service API key') * * // $ API_KEY=sk-123 mycli request → apiKey = 'sk-123' * // $ mycli request --api-key sk-456 → apiKey = 'sk-456' (CLI wins) * ``` */ env(varName: string): FlagBuilder>; /** * Let this flag read its value from piped stdin. * * An explicit `-- -` is CLI-sourced with bytes from stdin and keeps * CLI precedence. An absent flag takes the stdin fallback stage, which sits * between CLI and env, so a flag set in the environment still reads stdin * and stdin wins. The whole buffer becomes the value, byte for byte for a * string flag; every other kind drops the single line terminator a pipe * appends before decoding, and `{ trim: true }` drops it for a string flag * too. * * A collection reads the buffer as elements instead: `--tag -` splices what * stdin decodes into the position the `-` occupies, so * `--tag before --tag - --tag after` over `'a\nb\n'` resolves to * `['before', 'a', 'b', 'after']`. `.split({ stdin })` sets the decoding. * Each `-` stands for the whole source, so `--tag - --tag -` splices the * buffer twice. A `-` typed beside other occurrences with nothing piped fails * with `MISSING_STDIN`; occurrences of nothing but `-` fall through to the * later sources. * * A stdin-enabled flag cannot receive a literal `-` as its value, since the * token names the source. * * Available on every flag kind except `count`. One command may declare a * single exclusive stdin consumer; pass `{ consume: 'broadcast' }` on every * input that should share the buffer. * * @param options - When to read stdin, how to share it, and whether to trim. * @returns The builder (for chaining). * @throws {CLIError} With code `'INVALID_SCHEMA'` on a `count` flag. * * @example * ```ts * flag.string().stdin().describe('Message body') * // $ echo hi | mycli send → body = 'hi\n' * // $ mycli send --body - → body reads stdin * // $ mycli send --body hello → body = 'hello' * * flag.string().stdin({ when: 'dash' }) * // only `--body -` reads stdin * * flag.path({ mustExist: true }).stdin({ trim: true }) * // $ echo ./dist | mycli clean → path = './dist', checked on disk * ``` */ stdin(this: FlagBuilder, options?: StdinOptions): FlagBuilder>; /** * Bind to a dotted config path (resolved in v0.2+). * * The config value is read after CLI, stdin, and env, and before the prompt * and the default: CLI → stdin → env → **config** → prompt → default. * * @param path - Dotted config key (e.g. `'deploy.region'`). * @returns The builder (for chaining). * * @example * ```ts * flag.string().config('deploy.region').default('us-east-1') * // Config file: { "deploy": { "region": "eu-west-1" } } * // $ mycli deploy * // # → region = 'eu-west-1' (from config) * // $ mycli deploy --region ap-south-1 * // # → CLI flag wins * ``` */ config(path: string): FlagBuilder>; /** * Human-readable description shown in help output. * * @param description - Text displayed next to the flag in `--help`. * @returns The builder (for chaining). */ describe(description: HelpDescription): FlagBuilder>; /** * Attach interactive prompt configuration for v0.3+ resolution. * * When a flag value is not resolved from CLI, stdin, env, or config, the * prompt engine uses this config to interactively ask the user. * In non-interactive contexts (CI, piped stdin) prompts are skipped * and resolution falls through to default or required validation. * * @param config - {@link PromptConfig} describing the interactive prompt. * @returns The builder (for chaining). * * @example * ```ts * flag.string().prompt({ kind: 'input', message: 'Enter value:' }) * * // $ mycli init → prompts "Enter value:" interactively * // $ mycli init --name foo → skips prompt, uses CLI value * ``` */ prompt(config: AllowedPromptConfig): FlagBuilder>; /** * Mark this flag as deprecated. * * When used, a warning is emitted to stderr. Help text shows * `[deprecated]` or `[deprecated: ]`. * * Does not change the flag's type-level config — it's metadata only. * * @param message - Optional migration reason/guidance. * @returns The builder (for chaining). * * @example * ```ts * flag.string().deprecated('Use --target instead') * * // $ mycli deploy --dest staging * // ⚠ --dest is deprecated: Use --target instead * ``` */ deprecated(message?: string): FlagBuilder>; /** * Mark this flag as propagated to subcommands. * * Propagated flags are automatically available to all descendant * commands in a nested command tree. A child command that defines * a flag with the same name shadows the propagated parent flag. * * Does not change the flag's type-level config — it's metadata only. * * @returns The builder (for chaining). * * @example * ```ts * flag.boolean().alias('v').propagate().describe('Enable verbose output') * * // $ mycli --verbose deploy staging * // # → verbose = true in deploy handler * // $ mycli deploy --verbose staging * // # → same, inherited from parent * ``` */ propagate(): FlagBuilder>; /** * Require an integer value. Composes with other numeric constraints. * * @param value - Whether to require an integer. * @defaultValue `true` * @returns The builder (for chaining). * * @example * ```ts * flag.number().int() // rejects 3.7, accepts 3 * flag.number({ int: true }).int(false) // re-allows non-integers * ``` */ int(this: FlagBuilder, value?: boolean): FlagBuilder; /** * Set an inclusive lower bound. Composes with other numeric constraints; * a later call overrides an earlier `min` (including one from the options * object). * * @param value - Inclusive minimum. * @returns The builder (for chaining). * * @example * ```ts * flag.number().min(0) // rejects -1, accepts 0 * flag.number({ min: 0 }).min(5) // effective min is 5 * ``` */ min(this: FlagBuilder, value: number): FlagBuilder; /** * Set an inclusive upper bound. Composes with other numeric constraints; * a later call overrides an earlier `max`. * * @param value - Inclusive maximum. * @returns The builder (for chaining). * * @example * ```ts * flag.number().max(100) // rejects 101, accepts 100 * ``` */ max(this: FlagBuilder, value: number): FlagBuilder; /** * Require (or, with `false`, allow) a finite value. Finiteness is enforced * by default, so this is mainly used as `.finite(false)` to re-allow * `Infinity` / `-Infinity`. * * @param allow - Whether to require a finite value. * @defaultValue `true` * @returns The builder (for chaining). * * @example * ```ts * flag.number().finite(false) // accepts Infinity * ``` */ finite(this: FlagBuilder, allow?: boolean): FlagBuilder; /** * Reject empty strings. Composes with other string constraints. * * @param value - Whether to reject empty strings. * @defaultValue `true` * @returns The builder (for chaining). * * @example * ```ts * flag.string().nonEmpty() // rejects '', accepts 'x' * ``` */ nonEmpty(this: FlagBuilder, value?: boolean): FlagBuilder; /** * Set an inclusive minimum length (UTF-16 code units). Composes with other * string constraints; a later call overrides an earlier `minLength`. * * @param value - Inclusive minimum length. * @returns The builder (for chaining). * * @example * ```ts * flag.string().minLength(3) // rejects 'ab', accepts 'abc' * ``` */ minLength(this: FlagBuilder, value: number): FlagBuilder; /** * Set an inclusive maximum length (UTF-16 code units). Composes with other * string constraints; a later call overrides an earlier `maxLength`. * * @param value - Inclusive maximum length. * @returns The builder (for chaining). * * @example * ```ts * flag.string().maxLength(8) // rejects 9+ chars * ``` */ maxLength(this: FlagBuilder, value: number): FlagBuilder; /** * Require the value to match a regular expression. Anchor with `^`/`$` * for full-string matching. Composes with other string constraints. * * @param value - Pattern the value must match. * @returns The builder (for chaining). * * @example * ```ts * flag.string().pattern(/^ghp_/) // rejects 'abc', accepts 'ghp_x' * ``` */ pattern(this: FlagBuilder, value: RegExp): FlagBuilder; /** * Split each CLI occurrence on a separator before element coercion, so * `--tag a,b --tag c` resolves to `['a', 'b', 'c']`. Elements are coerced * (and rejected) individually with the element schema's own error format. * * The separator is the CLI policy alone. Env values split on `','` and the * stdin buffer on line terminators unless `.split()` says otherwise. * * @param value - Separator string (e.g. `','`). * @returns The builder (for chaining). * @throws {CLIError} With code `'INVALID_SCHEMA'` on a flag that carries a * single value. * * @example * ```ts * flag.array(flag.enum(['us', 'eu', 'ap'])).separator(',') * // --region us,eu --region ap → ['us', 'eu', 'ap'] * ``` */ separator(this: FlagBuilder, value: string): FlagBuilder; /** * Set how each source decodes into elements. * * CLI tokens accept `'whole'` and a delimiter; env values also accept * `'json'`; the stdin buffer accepts every format, including `'lines'`. The * strings `'whole'`, `'lines'`, and `'json'` name their format, and every * other string is the delimiter to split on. A source left out keeps what it * already had, or its default: whole CLI tokens (or the `.separator()` * delimiter), comma-delimited env values, line-delimited stdin. A config * value is a native array or object, and a config string decodes under the * env policy. For stdin, `'whole'` passes the complete buffer to a string * element, including its final line terminator. * * @param options - Per-source split settings. * @returns The builder (for chaining). * @throws {CLIError} With code `'INVALID_SCHEMA'` on a format the source does * not accept, an empty delimiter, or a flag that carries a single value. * * @example * ```ts * flag.array(flag.string()).split({ cli: ',', env: { format: 'json' } }).env('TAGS') * // --tag a,b → ['a', 'b'] * // TAGS='["a","b"]' → ['a', 'b'] * ``` */ split(this: FlagBuilder, options: SplitOptions): FlagBuilder; /** * Set how a repeated key combines. * * Applies to repeated CLI occurrences, delimited env pairs, and spliced stdin * reads in the same occurrence order. JSON decoding does not preserve * repeated object member names, so it cannot reliably expose them here. * * @param policy - `'last'` (default), `'first'`, or `'error'`. * @returns The builder (for chaining). * @throws {CLIError} With code `'INVALID_SCHEMA'` on a flag that is not * `keyValue`. * * @example * ```ts * flag.keyValue().duplicateKeys('error').env('VARS') * // $ VARS='A=1,A=2' mycli run * // # → Duplicate key '' from env VARS for flag --env (CONSTRAINT_VIOLATED) * ``` */ duplicateKeys(this: FlagBuilder, policy: DuplicateKeys): FlagBuilder; /** * Validate the resolved value with a Standard Schema v1 validator. * * On a scalar builder the validator sees each value; on a collection builder * it sees the completed array or record, after every element passed its own * validator. `flag.array(flag.string().standard(s))` validates elements, * `flag.array(flag.string()).standard(s)` validates the array. * * @param schema - A Standard Schema v1 validator. * @returns The builder (for chaining). * * @example * ```ts * import { z } from 'zod'; * flag.array(flag.string()).standard(z.array(z.string()).min(1)) * ``` */ standard(schema: StandardSchemaV1): FlagBuilder; /** * Deduplicate the resolved array, preserving first-seen order. Applied * after all sources resolve, using `SameValueZero` semantics (like `Set`). * * @param value - Whether to deduplicate. * @defaultValue `true` * @returns The builder (for chaining). * @throws {CLIError} With code `'INVALID_SCHEMA'` on a flag that is not * `array`. * * @example * ```ts * flag.array(flag.string()).separator(',').unique() * // --tag a,a --tag a → ['a'] * ``` */ unique(this: FlagBuilder, value?: boolean): FlagBuilder; /** * Accept a negated spelling (`--no-`) that sets the flag to `false`. * * Both spellings are ONE logical flag: the last CLI occurrence wins across * them, and they share the duplicate policy. The negated spelling is * presence-only — `--no-=true` is rejected. Help renders the flag as * `--[no-]` (or lists a custom alias); env/config/prompt/default * resolution is unaffected. * * @param options - Optional custom spelling (`alias`, without `--`) and * `hidden` to keep the negated spelling parseable but unadvertised. * @returns The builder (for chaining). * @throws {CLIError} With code `'INVALID_SCHEMA'` on a flag that is not * `boolean`. * * @example * ```ts * flag.boolean().default(true).negatable() * // $ mycli build --no-sandbox → sandbox = false * // $ mycli build --sandbox → sandbox = true * ``` */ negatable(this: FlagBuilder, options?: { alias?: string; hidden?: boolean; }): FlagBuilder>; /** * Set how repeated CLI occurrences of this flag combine. * * Counted per logical flag — aliases and the negated spelling all count * toward the same flag. CLI tokens only: env/config/prompt/default * resolution keeps its precedence semantics. Not available on `array`, * `count`, or `keyValue` flags, which inherently accumulate. * * @param policy - `'last'` (default), `'first'`, or `'error'`. * @returns The builder (for chaining). * * @example * ```ts * flag.enum(['session', 'same-dir', 'worktree']).duplicates('error') * // $ mycli run --spawn session --spawn worktree * // # → Error: Flag --spawn may only be specified once * ``` */ duplicates(this: FlagBuilder, policy: DuplicatePolicy): FlagBuilder>; } /** * Factory that creates {@link FlagBuilder} instances seeded with the correct * {@link FlagKind} and initial type-level config. */ interface FlagFactory { /** * String-valued flag, with optional string constraints. * * Constraints are enforced at the parse and resolution boundaries, in * fixed order: nonEmpty → minLength → maxLength → pattern. They also * compose via chained methods (`.nonEmpty()`, `.minLength()`, * `.maxLength()`, `.pattern()`), which override values set here. * * @param constraints - Optional string constraints. * @defaultValue `undefined` (no constraints) * @returns A {@link FlagBuilder} for `string` values. * * @example * ```ts * flag.string() // any string * flag.string({ nonEmpty: true }) // rejects '' * flag.string({ pattern: /^ghp_/ }) // token shapes * ``` */ string(constraints?: StringConstraints): FlagBuilder<{ readonly valueType: string; readonly presence: 'optional'; readonly optionalFallback: 'undefined'; readonly flagKind: 'string'; readonly elementEligible: true; }>; /** * Number-valued flag, with optional numeric constraints. * * Constraints are enforced at the parse and resolution boundaries. The * resolved value type stays `number` — constraints are runtime + schema, not * type-level. Bounds are inclusive. * * Constraints also compose via chained methods (`.int()`, `.min()`, * `.max()`, `.finite()`), which override values set here. * * @param constraints - Optional numeric constraints. `finite` defaults to * `true`, so `Infinity` / `-Infinity` are rejected unless `finite: false`. * @defaultValue `undefined` (finite-only, no bounds, non-integer allowed) * @returns A {@link FlagBuilder} for `number` values. * * @example * ```ts * flag.number() // finite numbers only * flag.number({ int: true, min: 0 }) // non-negative integers * flag.number({ finite: false }) // also accepts Infinity * ``` */ number(constraints?: NumberConstraints): FlagBuilder<{ readonly valueType: number; readonly presence: 'optional'; readonly optionalFallback: 'undefined'; readonly flagKind: 'number'; readonly elementEligible: true; }>; /** * Boolean flag. Implicitly defaults to `false` — the only flag kind where * the absence of a value is still meaningful (not `undefined`). * * @returns A {@link FlagBuilder} for `boolean` values (defaulted to `false`). */ boolean(): FlagBuilder<{ readonly valueType: boolean; readonly presence: 'defaulted'; readonly optionalFallback: 'undefined'; readonly flagKind: 'boolean'; readonly elementEligible: true; }>; /** * Enum flag with literal type inference. * * Requires a **non-empty** readonly tuple so that `T[number]` produces a * union of string literals rather than just `string`. * * @example * ```ts * flag.enum(['us', 'eu', 'ap']) * // inferred type: 'us' | 'eu' | 'ap' * ``` * * @param values - Non-empty tuple of allowed string literals. * @returns A {@link FlagBuilder} whose value type is the union of `values`. */ enum(values: T): FlagBuilder<{ readonly valueType: T[number]; readonly presence: 'optional'; readonly optionalFallback: 'undefined'; readonly flagKind: 'enum'; readonly elementEligible: true; }>; /** * Array flag — collects multiple values of the same element type. * * @example * ```ts * flag.array(flag.string()) * // inferred type: string[] * ``` * * @param element - {@link FlagBuilder} describing the element type. * @returns A {@link FlagBuilder} for arrays of the element type. */ array(element: FlagBuilder): FlagBuilder<{ readonly valueType: E['valueType'][]; readonly presence: 'optional'; readonly optionalFallback: 'empty-array'; readonly flagKind: 'array'; readonly elementEligible: false; }>; /** * Custom flag validated by a Standard Schema v1 validator (zod, valibot, * arktype, …). The resolved value from any source is validated after * resolution; the flag's value type is the validator's output type. * * Sync and async validators are both supported. Validation issues surface * as a `CONSTRAINT_VIOLATED` error naming the flag. * * @example * ```ts * import { z } from 'zod'; * flag.custom(z.string().url()) * // inferred type: string | undefined * ``` * * @param schema - A Standard Schema v1 validator. * @returns A {@link FlagBuilder} whose value type is the validator's output. */ custom(schema: S): FlagBuilder<{ readonly valueType: InferStandardOutput; readonly presence: 'optional'; readonly optionalFallback: 'undefined'; readonly flagKind: 'custom'; readonly elementEligible: true; }>; /** * Custom-parsed flag. The parse function receives the raw value and must * return a value of type `T`. The return type is inferred from `parseFn`. * * The input is `string` from CLI argv and env vars, or any JSON value * from config files. Narrow inside the function as needed: * * ```ts * flag.custom((raw: unknown): string[] => { * if (Array.isArray(raw)) return raw.map(String); * if (typeof raw === 'string') return raw.split(','); * throw new Error(`Expected string or array, got ${typeof raw}`); * }) * ``` * * Throw an `Error` (or `ParseError`) to signal invalid input — it will * be wrapped with context and re-thrown as a `ParseError`. * * @see `coerceConfigValue` `'custom'` case in `core/resolve/index.ts` * * @example * ```ts * flag.custom((raw) => new URL(String(raw))) * // inferred type: URL | undefined * ``` * * @param parseFn - Converts the raw input into a value of type `T`. * @returns A {@link FlagBuilder} whose value type is inferred from `parseFn`. */ custom(parseFn: FlagParseFn): FlagBuilder<{ readonly valueType: T; readonly presence: 'optional'; readonly optionalFallback: 'undefined'; readonly flagKind: 'custom'; readonly elementEligible: true; }>; /** * URL-valued flag. Parses into a `URL`; invalid URLs are rejected with an * `INVALID_VALUE` error naming the flag. * * @param options - Optional protocol allowlist (without trailing colon). * @returns A {@link FlagBuilder} for `URL` values. * * @example * ```ts * flag.url() // any URL * flag.url({ protocols: ['https'] }) // https only * ``` */ url(options?: UrlFlagOptions): FlagBuilder<{ readonly valueType: URL; readonly presence: 'optional'; readonly optionalFallback: 'undefined'; readonly flagKind: 'custom'; readonly elementEligible: true; }>; /** * Path-valued flag. The value stays a `string`; optional filesystem * checks run **after resolution** through the runtime adapter, so CLI, * env, config, prompted, and defaulted values are all validated. * * @param options - Optional existence/type checks. `type` implies * existence unless `mustExist` is explicitly `false`. * @returns A {@link FlagBuilder} for path strings. * * @example * ```ts * flag.path() // any string, help shows * flag.path({ mustExist: true }) // rejects missing paths * flag.path({ type: 'directory' }) // must exist and be a directory * flag.path({ type: 'directory', mustExist: false }) * // missing passes; existing must be a directory * flag.path({ type: 'directory', create: true }) * // created recursively when missing * ``` */ path(options?: PathFlagOptions): FlagBuilder<{ readonly valueType: string; readonly presence: 'optional'; readonly optionalFallback: 'undefined'; readonly flagKind: 'string'; readonly elementEligible: true; }>; /** * Date-valued flag. Accepts strict ISO-8601 (`2026-07-10`, * `2026-07-10T14:30:00Z`) and parses into a `Date`. Lenient `Date.parse` * inputs (`'0'`, `'March 5'`) and calendar-invalid dates (`2026-02-31`) * are rejected. * * Returns `Date` (not `Temporal`) because the supported runtimes do not * all ship Temporal yet; use `flag.custom()` with `Temporal.PlainDate.from` * where the target runtime has it. * * @param options - Optional inclusive `min`/`max` date bounds. * @returns A {@link FlagBuilder} for `Date` values. * * @example * ```ts * flag.date() * flag.date({ min: new Date('2020-01-01') }) * ``` */ date(options?: DateFlagOptions): FlagBuilder<{ readonly valueType: Date; readonly presence: 'optional'; readonly optionalFallback: 'undefined'; readonly flagKind: 'custom'; readonly elementEligible: true; }>; /** * Duration flag. Accepts `'30s'`, `'5m'`, `'1.5h'`, `'250ms'`, `'2d'`, * compounds like `'1h30m'`, or a bare millisecond count, and resolves to * **milliseconds**. * * @returns A {@link FlagBuilder} for duration values in milliseconds. * * @example * ```ts * flag.duration().default(30_000) // --timeout 45s → 45000 * ``` */ duration(): FlagBuilder<{ readonly valueType: number; readonly presence: 'optional'; readonly optionalFallback: 'undefined'; readonly flagKind: 'custom'; readonly elementEligible: true; }>; /** * Byte-size flag. Accepts `'512mb'`, `'1.5gb'`, `'64kb'`, `'100b'` or a * bare byte count, and resolves to **bytes**. Units are binary * (`1kb` = 1024) and case-insensitive. * * @returns A {@link FlagBuilder} for sizes in bytes. * * @example * ```ts * flag.bytes().default(10 * 1024 ** 2) // --max-size 512kb → 524288 * ``` */ bytes(): FlagBuilder<{ readonly valueType: number; readonly presence: 'optional'; readonly optionalFallback: 'undefined'; readonly flagKind: 'custom'; readonly elementEligible: true; }>; /** * Count flag — resolves to how many times the flag appears. `-vvv`, * `-v -v -v`, and `--verbose --verbose --verbose` all yield `3`; absent * yields `0`. An explicit value (`--verbose=2`, env, config) sets the * count directly. * * Not promptable. * * @returns A {@link FlagBuilder} for occurrence counts (defaulted to `0`). * * @example * ```ts * flag.count().alias('v').describe('Increase verbosity') * // $ mycli build -vv → verbose = 2 * ``` */ count(): FlagBuilder<{ readonly valueType: number; readonly presence: 'defaulted'; readonly optionalFallback: 'undefined'; readonly flagKind: 'count'; readonly elementEligible: false; }>; /** * Key-value flag — repeated `KEY=VALUE` occurrences merge into a * `Record` (docker/kubectl `--env` style). The value is * split at the **first** `=`, so `--env A=b=c` yields `{ A: 'b=c' }`. * Later occurrences of the same key win, which `.duplicateKeys()` changes. * Absent resolves to `{}`. * * Env vars accept comma-delimited pairs (`A=1,B=2`); config files accept a * plain object; `.split()` sets any of that per source. Not promptable. * * An element builder gives each entry value its own codec, constraints, and * checks, so `flag.keyValue(flag.path())` checks every value on disk. * * @param element - {@link FlagBuilder} describing the value of each entry. * @defaultValue an unconstrained string element * @returns A {@link FlagBuilder} for records of the element type. * * @example * ```ts * flag.keyValue().alias('e').describe('Environment variables') * // $ mycli run -e A=1 -e B=2 → env = { A: '1', B: '2' } * ``` */ keyValue(element?: FlagBuilder): FlagBuilder<{ readonly valueType: Record; readonly presence: 'optional'; readonly optionalFallback: 'empty-object'; readonly flagKind: 'keyValue'; readonly elementEligible: false; }>; } /** * Flag schema factory. Call `flag.()` to create an immutable * {@link FlagBuilder} with full type inference and safe modifier chaining. */ declare const flag: FlagFactory; //#endregion //#region src/core/schema/cardinality.d.ts /** All split formats as a runtime array. */ declare const SPLIT_FORMATS: readonly ["whole", "delimiter", "lines", "json"]; /** How one source's text decodes into collection elements. */ type SplitFormat = (typeof SPLIT_FORMATS)[number]; /** * How one source's text decodes into collection elements. * * - `'whole'`: the source value is a single element * - `'delimiter'`: split on a literal delimiter, dropping empty segments * - `'lines'`: split on `\n`, `\r\n`, or `\r` * - `'json'`: parse the text as JSON */ type SplitPolicy = { readonly format: 'whole'; } | { readonly format: 'delimiter'; readonly delimiter: string; } | { readonly format: 'lines'; } | { readonly format: 'json'; }; /** * A split policy, a format name, or a literal delimiter. * * The strings `'whole'`, `'lines'`, and `'json'` name their format; every other * string is the delimiter to split on, so `','` is the comma policy. */ type SplitSetting = string | SplitPolicy; /** * Per-source split settings accepted by `.split()`. * * Config values are native arrays and objects; a config string decodes under * the `env` policy. */ interface SplitOptions { /** * How each CLI token splits. Accepts `'whole'` and a delimiter. * @defaultValue `'whole'`, or the delimiter set by `.separator()` */ readonly cli?: SplitSetting | undefined; /** * How an environment value splits. Accepts `'whole'`, `'json'`, and a delimiter. * @defaultValue `{ format: 'delimiter', delimiter: ',' }` */ readonly env?: SplitSetting | undefined; /** * How the stdin buffer splits. Accepts every format. * @defaultValue `'lines'` */ readonly stdin?: SplitSetting | undefined; } /** * The non-CLI split policies a schema stores. * * The CLI delimiter lives on the `separator` field both schemas already carry, * so `.separator(',')` and `.split({ cli: ',' })` write the same place. */ interface SourceSplitBinding { /** Environment split policy, or `undefined` for the default. */ readonly env: SplitPolicy | undefined; /** Stdin split policy, or `undefined` for the default. */ readonly stdin: SplitPolicy | undefined; } /** The resolved split policy of every source. */ interface SplitBinding { /** How each CLI token splits. */ readonly cli: SplitPolicy; /** How an environment value splits. */ readonly env: SplitPolicy; /** How the stdin buffer splits. */ readonly stdin: SplitPolicy; } /** All duplicate-key policies as a runtime array. */ declare const DUPLICATE_KEYS: readonly ["first", "last", "error"]; /** * How a repeated key combines when entries aggregate. * * - `'last'`: the later occurrence wins * - `'first'`: the earlier occurrence wins * - `'error'`: a repeat is a validation failure * * @defaultValue `'last'` */ type DuplicateKeys = (typeof DUPLICATE_KEYS)[number]; //#endregion //#region src/core/schema/arg.d.ts /** All arg presence states as a runtime array. */ declare const ARG_PRESENCES: readonly ["required", "optional", "defaulted"]; /** * Presence describes whether a positional arg is guaranteed to exist when the * action handler runs: * * - `'required'` — must be supplied; error if missing (default) * - `'optional'` — may be `undefined` if not supplied * - `'defaulted'` — always present (falls back to default value) */ type ArgPresence = (typeof ARG_PRESENCES)[number]; /** * Compile-time state carried through the builder chain. */ interface ArgConfig { /** The resolved value type (e.g. `string`, `number`, custom). */ readonly valueType: unknown; /** Whether the arg is required, optional, or has a default. */ readonly presence: ArgPresence; /** Whether this arg consumes remaining positionals. */ readonly variadic: boolean; /** The runtime kind discriminator, mirroring {@link ArgKind}. */ readonly argKind: ArgKind; /** * Whether this builder may still be passed to `arg.keyValue()` as its entry * value. Factories start `true`; the modifiers that describe the positional * itself (`.env()`, `.prompt()`, `.optional()`, `.stdin()`, …) flip it to * `false`, since an entry value is never read for those settings. */ readonly elementEligible: boolean; } /** * Advanced type helper used by {@linkcode ArgBuilder} modifiers to replace presence. * Most consumers rely on inference and never reference this directly. */ type WithArgPresence = { readonly valueType: C['valueType']; readonly presence: P; readonly variadic: C['variadic']; readonly argKind: C['argKind']; readonly elementEligible: false; }; /** * Advanced type helper used by {@linkcode ArgBuilder.variadic | ArgBuilder.variadic()}. * Most consumers rely on inference and never reference this directly. */ type WithVariadic = { readonly valueType: C['valueType']; readonly presence: C['presence']; readonly variadic: true; readonly argKind: C['argKind']; readonly elementEligible: false; }; /** * Advanced type helper: marks a builder as no longer usable as an entry value * (returned by the modifiers whose settings an entry value ignores). */ type WithoutArgElementEligibility = { readonly valueType: C['valueType']; readonly presence: C['presence']; readonly variadic: C['variadic']; readonly argKind: C['argKind']; readonly elementEligible: false; }; /** * The element config `arg.keyValue()` assumes when given no element builder: an * unconstrained string. */ type StringArgElementConfig = { /** Element value type. */ readonly valueType: string; /** Elements carry no presence of their own. */ readonly presence: 'required'; /** Elements are never variadic on their own. */ readonly variadic: false; /** Element kind discriminator. */ readonly argKind: 'string'; /** Elements are element-eligible by construction. */ readonly elementEligible: true; }; /** * Compute the final value type from config — this is what handlers receive. * * Advanced type helper: this powers {@link InferArg} and action-handler * inference. Most apps do not need to mention it explicitly. * * A `keyValue` arg always produces a record, variadic or not, because it * aggregates entries rather than a list. Variadic args of every other kind * produce an array. Non-variadic: * - `'optional'` → `T | undefined` * - `'required'` → `T` * - `'defaulted'` → `T` */ type ResolvedArgValue = C['argKind'] extends 'keyValue' ? C['valueType'] : C['variadic'] extends true ? C['valueType'][] : C['presence'] extends 'optional' ? C['valueType'] | undefined : C['valueType']; /** * The value `.default()` accepts for an arg. * * A default stands in for what the arg resolves to, so an arg that aggregates * takes the completed array or record and every other arg takes one value. */ type ArgDefaultValue = C['argKind'] extends 'keyValue' ? C['valueType'] : C['variadic'] extends true ? readonly C['valueType'][] : C['valueType']; /** * Maps an {@linkcode ArgKind} to the prompt config types compatible with it, * mirroring the flag table for the kinds args have. * * - `'string'` → {@link InputPromptConfig} | {@link SelectPromptConfig} * - `'number'` → {@link InputPromptConfig} * - `'boolean'` → {@link ConfirmPromptConfig} * - `'enum'` → {@link SelectPromptConfig} | {@link InputPromptConfig} * - `'custom'` → all prompt kinds ({@link PromptConfig}) * - `'keyValue'` → `never` (not promptable) */ type PromptConfigByArgKind = { readonly string: InputPromptConfig | SelectPromptConfig; readonly number: InputPromptConfig; readonly boolean: ConfirmPromptConfig; readonly enum: SelectPromptConfig | InputPromptConfig; readonly custom: PromptConfig; readonly keyValue: never; }; /** * Prompt configuration compatible with an {@link ArgConfig}. * * A variadic arg collects several values, so it takes the multiselect a * `flag.array()` takes; every other arg takes what its kind takes. */ type AllowedArgPromptConfig = C['argKind'] extends 'keyValue' ? never : C['variadic'] extends true ? MultiselectPromptConfig : PromptConfigByArgKind[C['argKind']]; /** Extract the resolved value type from an {@linkcode ArgBuilder}. */ type InferArg = B extends ArgBuilder ? ResolvedArgValue : never; /** Extract resolved value types from a record of builders. */ type InferArgs>> = { [K in keyof T]: InferArg; }; /** All arg kind discriminators as a runtime array. */ declare const ARG_KINDS: readonly ["string", "number", "boolean", "enum", "custom", "keyValue"]; /** Discriminator for the kind of value an arg accepts. */ type ArgKind = (typeof ARG_KINDS)[number]; /** Arg kinds whose variadic form resolves to a list. @internal */ type ListArgKind = Exclude; /** Custom parse function for `arg.custom()`. */ type ArgParseFn = (raw: string) => T; /** * The runtime descriptor stored inside every {@linkcode ArgBuilder}. Consumers (parser, * help generator) read this to understand the arg's shape without touching * generics. */ interface ArgSchema { /** Type-only seal produced by {@link createArgSchema}. */ readonly [schemaBrand]: 'arg'; /** What kind of value this arg accepts. */ readonly kind: K; /** Current presence state. */ readonly presence: ArgPresence; /** Whether this arg consumes all remaining positionals. */ readonly variadic: boolean; /** * Stdin binding set by `.stdin()` (`undefined` when the arg never reads * stdin). See {@link StdinBinding}. */ readonly stdin: StdinBinding | undefined; /** Runtime default value (if any). */ readonly defaultValue: unknown; /** * Human-readable replacement for the default value in help, or `false` to * omit the default annotation. */ readonly defaultDescription: string | false | undefined; /** Whether values from this input must be kept out of user-facing projections. */ readonly sensitive: boolean; /** Human-readable description for help text. */ readonly description: HelpDescription | undefined; /** * Environment variable name for env resolution. * * When set and the CLI value is absent, the resolver reads this env var * and coerces the string to the arg's declared kind. * * @see {@link ArgBuilder.env} for the builder method. */ readonly envVar: string | undefined; /** * Dotted config path for config resolution (e.g. `'deploy.region'`). * * @see {@link ArgBuilder.config} for the builder method. */ readonly configPath: string | undefined; /** * Interactive prompt configuration. * * @see {@link ArgBuilder.prompt} for the builder method. */ readonly prompt: PromptConfig | undefined; /** Allowed literal values when `kind === 'enum'`. */ readonly enumValues: readonly string[] | undefined; /** * Element schema when `kind === 'keyValue'`. * * Describes the value of each entry, so `arg.keyValue(arg.number())` decodes * `A=1` to the number `1`. `undefined` leaves entry values as strings. */ readonly elementSchema: ArgSchema | undefined; /** * Numeric constraints when `kind === 'number'` (`undefined` otherwise). * * Enforced at the parse and resolution boundaries. `finite` defaults to * `true`, so `Infinity` is rejected even when no constraints object is set. */ readonly numberConstraints: NumberConstraints | undefined; /** * String constraints when `kind === 'string'` (`undefined` otherwise). * * Enforced at the parse and resolution boundaries, in fixed order: * nonEmpty → minLength → maxLength → pattern. A `defaultValue` is a typed * value, so it is validated against them when the schema is built. */ readonly stringConstraints: StringConstraints | undefined; /** * Filesystem checks for path-valued args (set by `arg.path()`). * * Validated after resolution through the runtime adapter, so CLI, stdin, * env, and defaulted values are all checked. Only meaningful when * `kind === 'string'`. */ readonly pathChecks: PathChecks | undefined; /** * Help placeholder label (e.g. `'url'`). * * Set by the sugar factories (`arg.url()`, `arg.date()`, …) so tooling * reading the schema knows the expected value shape. Help renders a * positional by its own name, so this does not change the usage line. */ readonly valueHint: string | undefined; /** Custom parse function (only when `kind === 'custom'`). */ readonly parseFn: ArgParseFn | undefined; /** * CLI value separator for a collection (`undefined` otherwise). * * When set, each positional token is split on this separator before element * coercion. Other sources decode through {@link ArgSchema.split}. */ readonly separator: string | undefined; /** * Env and stdin split policies for a collection (`undefined` otherwise). * * A source the binding leaves out takes its default: comma-delimited for env, * line-delimited for stdin. */ readonly split: SourceSplitBinding | undefined; /** * How a repeated key combines when `kind === 'keyValue'`. * * @defaultValue `'last'` */ readonly duplicateKeys: DuplicateKeys; /** * Deduplicate the resolved values of a variadic arg. * * Applied after all sources resolve, preserving first-seen order. Uses * `SameValueZero` semantics (like `Set`). */ readonly unique: boolean; /** * Standard Schema v1 validator applied to each resolved value. * * When set, the value from any source (CLI, env, stdin, default) is * validated after resolution via `~standard.validate`. Sync and async * validators are both awaited; issues surface as a `CONSTRAINT_VIOLATED` * {@link ValidationError}. A variadic arg validates every element with it. */ readonly standard: StandardSchemaV1 | undefined; /** * Standard Schema v1 validator applied to the completed collection. * * Set by `.standard()` on a builder that already aggregates, so the array or * record is validated as a whole after every element passed. */ readonly aggregateStandard: StandardSchemaV1 | undefined; /** * Deprecation marker. * * - `undefined` — not deprecated (default) * - `true` — deprecated with no migration message * - `string` — deprecated with a reason/migration message * * When a deprecated arg is used, a warning is emitted to stderr. * Help text shows `[deprecated]` or `[deprecated: ]`. */ readonly deprecated: string | true | undefined; } /** Definition fields accepted by every arg kind. */ interface ArgDefinitionBase { /** * Presence state. * @defaultValue `'required'` */ readonly presence?: ArgPresence | undefined; /** * Whether this arg consumes all remaining positionals. * @defaultValue `false` */ readonly variadic?: boolean | undefined; /** * Stdin binding. See {@link StdinOptions}. * @defaultValue `undefined` */ readonly stdin?: StdinOptions | undefined; /** * Runtime default value. * @defaultValue `undefined` */ readonly defaultValue?: unknown; /** * Human-readable replacement for the default value in help, or `false` to * omit the default annotation. * @defaultValue `undefined` */ readonly defaultDescription?: string | false | undefined; /** * Whether values from this input must be kept out of user-facing projections. * @defaultValue `false` */ readonly sensitive?: boolean | undefined; /** * Human-readable description for help text. * @defaultValue `undefined` */ readonly description?: HelpDescription | undefined; /** * Environment variable name for env resolution. * @defaultValue `undefined` */ readonly envVar?: string | undefined; /** * Dotted config path for config resolution (e.g. `'deploy.region'`). * @defaultValue `undefined` */ readonly configPath?: string | undefined; /** * Interactive prompt configuration. * @defaultValue `undefined` */ readonly prompt?: PromptConfig | undefined; /** * Help placeholder label (`'url'`, `'path'`, …). * @defaultValue `undefined` */ readonly valueHint?: string | undefined; /** * CLI value separator each positional token is split on. * @defaultValue `undefined` */ readonly separator?: string | undefined; /** * Env and stdin split policies. * @defaultValue `undefined` */ readonly split?: SourceSplitBinding | undefined; /** * Deduplicate the resolved values of a variadic arg. * @defaultValue `false` */ readonly unique?: boolean | undefined; /** * Standard Schema v1 validator applied to each resolved value. * @defaultValue `undefined` */ readonly standard?: StandardSchemaV1 | undefined; /** * Standard Schema v1 validator applied to a completed collection. * @defaultValue `undefined` */ readonly aggregateStandard?: StandardSchemaV1 | undefined; /** * Deprecation marker. `true` deprecates without a message, a string carries * the migration guidance. * @defaultValue `undefined` */ readonly deprecated?: string | true | undefined; } /** Definition of a `string` arg. */ interface StringArgDefinition extends ArgDefinitionBase { /** Kind discriminator. */ readonly kind: 'string'; /** * String constraints enforced at the parse and resolution boundaries. * @defaultValue `undefined` */ readonly stringConstraints?: StringConstraints | undefined; /** * Filesystem checks applied after resolution. * @defaultValue `undefined` */ readonly pathChecks?: PathChecks | undefined; } /** Definition of a `number` arg. */ interface NumberArgDefinition extends ArgDefinitionBase { /** Kind discriminator. */ readonly kind: 'number'; /** * Numeric constraints enforced at the parse and resolution boundaries. * @defaultValue `undefined` */ readonly numberConstraints?: NumberConstraints | undefined; } /** Definition of an `enum` arg. */ interface EnumArgDefinition extends ArgDefinitionBase { /** Kind discriminator. */ readonly kind: 'enum'; /** Allowed literal values. */ readonly enumValues: readonly string[]; } /** Definition of a `custom` arg. */ interface CustomArgDefinition extends ArgDefinitionBase { /** Kind discriminator. */ readonly kind: 'custom'; /** * Parse function applied to the raw value. * @defaultValue `undefined` */ readonly parseFn?: ArgParseFn | undefined; } /** Definition of a `boolean` arg. */ interface BooleanArgDefinition extends ArgDefinitionBase { /** Kind discriminator. */ readonly kind: 'boolean'; } /** Definition of a `keyValue` arg. */ interface KeyValueArgDefinition extends ArgDefinitionBase { /** Kind discriminator. */ readonly kind: 'keyValue'; /** * How a repeated key combines. See {@link DuplicateKeys}. * @defaultValue `'last'` */ readonly duplicateKeys?: DuplicateKeys | undefined; /** * Schema describing the value of each entry, as a definition or an already * built {@link ArgSchema}. * @defaultValue `undefined`, which leaves entry values as strings */ readonly elementSchema?: ArgDefinition | ArgSchema | undefined; } /** Maps each {@link ArgKind} to its definition shape. */ interface ArgDefinitionByKind { /** Definition shape for `string` args. */ readonly string: StringArgDefinition; /** Definition shape for `number` args. */ readonly number: NumberArgDefinition; /** Definition shape for `boolean` args. */ readonly boolean: BooleanArgDefinition; /** Definition shape for `enum` args. */ readonly enum: EnumArgDefinition; /** Definition shape for `custom` args. */ readonly custom: CustomArgDefinition; /** Definition shape for `keyValue` args. */ readonly keyValue: KeyValueArgDefinition; } /** Definition of an arg of kind `K`, including the kind discriminator. */ type ArgDefinition = ArgDefinitionByKind[K]; /** Definition of an arg of kind `K` with the kind discriminator removed. */ type ArgDefinitionOverrides = Omit; /** Positional factory arguments, requiring fields that the selected kind requires. */ type ArgDefinitionArguments = K extends 'enum' ? [overrides: ArgDefinitionOverrides] : [overrides?: ArgDefinitionOverrides]; /** * Create a raw {@link ArgSchema} object with sensible defaults. * * Most consumers should prefer the higher-level {@link arg} factory, which * returns an immutable {@link ArgBuilder} with type inference and fluent * modifiers. `createArgSchema()` exists for advanced schema composition, * targeted tests, or custom builders that need the plain runtime descriptor. * * Fields are shallow-merged on top of the default shape, so callers are * responsible for preserving invariants such as variadic ordering. * * @param kind - Discriminator for the value type this arg accepts. * @param overrides - Definition fields for `kind`, shallow-merged onto defaults. * @returns A fully populated {@link ArgSchema}. * @throws {CLIError} With code `'INVALID_SCHEMA'` when a field belongs to a * different {@link ArgKind}. * * @example * ```ts * const schema = createArgSchema('custom', { * description: 'Hex color', * parseFn: (raw) => `#${raw}`, * }); * ``` */ declare function createArgSchema(kind: K, ...overrides: ArgDefinitionArguments): ArgSchema; /** * Create a raw {@link ArgSchema} object from a single definition object. * * An already-built {@link ArgSchema} is accepted and re-normalized into a * deep-equal schema. * * @param definition - Kind discriminator plus the fields valid for that kind. * @returns A fully populated {@link ArgSchema}. * @throws {CLIError} With code `'INVALID_SCHEMA'` when a field belongs to a * different {@link ArgKind}. * * @example * ```ts * const schema = createArgSchema({ * kind: 'enum', * enumValues: ['us', 'eu', 'ap'], * description: 'Target region', * }); * ``` */ declare function createArgSchema(definition: ArgDefinition | ArgSchema): ArgSchema; /** * Immutable positional argument schema builder. * * The type parameter `C` is a phantom that tracks the value type, presence, * and variadic state through the fluent chain. Each modifier returns a **new** * builder — the original is never mutated. * * @example * ```ts * // Full command with multiple args and modifiers * import { command, arg } from '@kjanat/dreamcli'; * * command('deploy') * .arg('target', arg.string() * .env('DEPLOY_TARGET') * .describe('Deploy target')) * .arg('port', arg.number() * .env('PORT') * .default(3000) * .describe('Port number')) * .arg('files', arg.string() * .variadic() * .optional() * .describe('Extra config files')) * .action(({ args }) => { * args.target; // string (required, from CLI or $DEPLOY_TARGET) * args.port; // number (defaulted, from CLI, $PORT, or 3000) * args.files; // string[] (optional variadic) * }); * ``` * * @example * ```ts * // Type inference * const target = arg.string(); * type T = InferArg; // string * * const opt = arg.string().optional(); * type O = InferArg; // string | undefined * * const files = arg.string().variadic(); * type F = InferArg; // string[] * ``` */ declare class ArgBuilder { /** @internal Runtime schema descriptor. */ readonly schema: ArgSchema; /** * @internal Type brand — exists only in the type system (`declare` * produces no runtime property). Used by {@linkcode InferArg} / {@linkcode InferArgs}. */ readonly _config: C; /** * Create an arg builder from a pre-built schema descriptor. * * @param schema - Runtime descriptor for this positional argument. */ constructor(schema: ArgSchema); /** * Mark the arg as required (this is the default for positional args). * Produces an error if no value resolves from any configured source * (CLI → stdin → env → config → prompt → default). * * @example * ```ts * arg.string().required() // explicit, same as default * * // In a command — omitting causes a ValidationError: * command('deploy') * .arg('target', arg.string().required().describe('Deploy target')) * // $ mycli deploy * // Error: Missing required argument * ``` * * @returns The builder (for chaining). */ required(): ArgBuilder>; /** * Mark the arg as optional. Handlers receive `undefined` when absent. * * @example * ```ts * arg.string().optional() * * // In a command — handler receives `undefined` when omitted: * command('greet') * .arg('name', arg.string().optional().describe('Who to greet')) * .action(({ args }) => { * args.name; // string | undefined * }); * // $ mycli greet → args.name is undefined * // $ mycli greet Alice → args.name is 'Alice' * ``` * * @returns The builder (for chaining). */ optional(): ArgBuilder>; /** * Provide a default value. The arg becomes "always present" — handlers * will never see `undefined`. * * The generic constraint {@link ArgDefaultValue} ensures the default matches * what the arg resolves to: an array for a variadic arg, a record for a * `keyValue` one, and a single value otherwise. * * Resolution order when extra sources are configured: * CLI → stdin → env → config → prompt → **default**. * * @param value - Fallback used when no CLI value or env var resolves. * @param options - Optional help presentation for the default. * @returns The builder (for chaining). * @throws {CLIError} With code `'INVALID_DEFAULT'` when the value is one the * arg could never hold. * * @example * ```ts * arg.string().default('production') * arg.number().default(3000) * arg.string().variadic().default(['a', 'b']) * * // In a command — default kicks in when CLI and env are both absent: * command('deploy') * .arg('env', arg.string() * .env('DEPLOY_ENV') * .default('staging') * .describe('Target environment')) * .action(({ args }) => { * args.env; // string (never undefined) * }); * // $ mycli deploy → 'staging' (default) * // $ DEPLOY_ENV=prod mycli deploy → 'prod' (env) * // $ mycli deploy production → 'production' (CLI) * ``` */ default>(value: V, options?: DefaultValueOptions): ArgBuilder>; /** * Mark this arg as variadic — it consumes all remaining positional * arguments. The inferred type becomes `T[]`. * * A variadic arg is the last positional a command can declare. Registering * another positional after it throws `INVALID_BUILDER_STATE` from `.arg()` * and from `createCommandSchema()`. * * @example * ```ts * arg.string().variadic() * * // In a command — collects all remaining positionals: * command('build') * .arg('entry', arg.string().describe('Main entry')) * .arg('extras', arg.string().variadic().optional().describe('Extra files')) * .action(({ args }) => { * args.entry; // string * args.extras; // string[] * }); * // $ mycli build main.ts a.ts b.ts * // → entry = 'main.ts', extras = ['a.ts', 'b.ts'] * ``` * * @returns The builder (for chaining). */ variadic(): ArgBuilder>; /** * Split each positional token on a separator before element coercion, so * `mycli build a,b c` collects `['a', 'b', 'c']` into a variadic arg. * * The separator is the CLI policy alone. Env values split on `','` and the * stdin buffer on line terminators unless `.split()` says otherwise. * * Available on an arg that aggregates, so call it after `.variadic()` or on * `arg.keyValue()`. * * @param value - Separator string (e.g. `','`). * @returns The builder (for chaining). * @throws {CLIError} With code `'INVALID_SCHEMA'` on an arg carrying a single * value. */ separator(this: ArgBuilder | ArgBuilder, value: string): ArgBuilder; /** * Set how each source decodes into elements. * * CLI tokens accept `'whole'` and a delimiter; env values also accept * `'json'`; the stdin buffer accepts every format, including `'lines'`. The * strings `'whole'`, `'lines'`, and `'json'` name their format, and every * other string is the delimiter to split on. A source left out keeps what it * already had, or its default: whole CLI tokens, comma-delimited env values, * line-delimited stdin. For stdin, `'whole'` passes the complete buffer to a * string element, including its final line terminator. * * Available on an arg that aggregates, so call it after `.variadic()` or on * `arg.keyValue()`. * * @param options - Per-source split settings. * @returns The builder (for chaining). * @throws {CLIError} With code `'INVALID_SCHEMA'` on a format the source does * not accept, an empty delimiter, or an arg carrying a single value. * * @example * ```ts * arg.string().variadic().split({ env: { format: 'json' } }) * // FILES='["a.ts","b.ts"]' → ['a.ts', 'b.ts'] * ``` */ split(this: ArgBuilder | ArgBuilder, options: SplitOptions): ArgBuilder; /** * Deduplicate the resolved values of a variadic arg, preserving first-seen * order. Applied after all sources resolve, using `SameValueZero` semantics. * * Available on a variadic arg of a list kind, so call it after `.variadic()`. * * @param value - Whether to deduplicate. * @defaultValue `true` * @returns The builder (for chaining). * @throws {CLIError} With code `'INVALID_SCHEMA'` on an arg that resolves to * one value or to a record. */ unique(this: ArgBuilder, value?: boolean): ArgBuilder; /** * Set how a repeated key combines. * * @param policy - `'last'` (default), `'first'`, or `'error'`. * @returns The builder (for chaining). * @throws {CLIError} With code `'INVALID_SCHEMA'` on an arg that is not * `arg.keyValue()`. * * @example * ```ts * arg.keyValue().variadic().duplicateKeys('error').env('VARS') * // $ VARS='A=1,A=2' mycli run * // # → Duplicate key '' from env VARS for argument (CONSTRAINT_VIOLATED) * ``` */ duplicateKeys(this: ArgBuilder, policy: DuplicateKeys): ArgBuilder; /** * Validate the resolved value with a Standard Schema v1 validator. * * On a single-value builder the validator sees each value; on a builder that * already aggregates (`.variadic()` or `arg.keyValue()`) it sees the * completed array or record, after every element passed its own validator. * * The builder this is called on is what decides, so where the call sits * relative to `.variadic()` chooses between the two. * * @param schema - A Standard Schema v1 validator. * @returns The builder (for chaining). * * @example * ```ts * import { z } from 'zod'; * arg.string().standard(z.string().min(1)).variadic() // each element * arg.string().variadic().standard(z.array(z.string())) // the whole array * ``` */ standard(schema: StandardSchemaV1): ArgBuilder; /** * Let this arg read its value from piped stdin. * * An explicit `-` in the arg's slot is CLI-sourced with bytes from stdin and * keeps CLI precedence. An absent positional takes the stdin fallback stage, * which sits between CLI and env, so an arg set in the environment still * reads stdin and stdin wins. The whole buffer becomes the value, byte for * byte for a string arg; every other kind drops the single line terminator a * pipe appends before decoding, and `{ trim: true }` drops it for a string * arg too. * * On an arg that aggregates, a `-` among the tail tokens splices what the * buffer decodes to into that position, so `mycli build a - b` over * `'x\ny\n'` collects `['a', 'x', 'y', 'b']`. Each `-` stands for the whole * source, so two of them splice the buffer twice. A `-` typed beside other * tokens with nothing piped fails with `MISSING_STDIN`; a tail of nothing but * `-` falls through to the later sources. * * A stdin-enabled arg cannot receive a literal `-` as its value, since the * token names the source. * * One command may declare a single exclusive stdin consumer; pass * `{ consume: 'broadcast' }` on every input that should share the buffer. * * @param options - When to read stdin, how to share it, and whether to trim. * @returns The builder (for chaining). * * @example * ```ts * arg.string().describe('Input text').stdin() * // $ echo "hello" | mycli transform → input = 'hello\n' (from stdin) * // $ mycli transform - → input reads stdin * // $ mycli transform "hello" → input = 'hello' (from CLI) * * arg.string().stdin({ when: 'dash' }) * // only an explicit `-` reads stdin * * arg.path({ mustExist: true }).stdin({ trim: true }) * // $ echo ./dist | mycli clean → path = './dist', checked on disk * ``` */ stdin(options?: StdinOptions): ArgBuilder>; /** * Bind to an environment variable. * * When the arg is not provided on the CLI or by stdin, the resolver checks * this env var before config, prompt, and the default value. The env string * is coerced to the arg's declared kind (passthrough for strings, parsed * for numbers, run through `parseFn` for custom args). * * Resolution order when extra sources are configured: * **CLI → stdin → env → config → prompt → default**. * * Help output shows `[env: VAR]` next to the arg description. * * @param varName - Environment variable name (e.g. `'DEPLOY_TARGET'`). * @returns The builder (for chaining). * * @example * ```ts * command('deploy') * .arg('target', arg.string().env('DEPLOY_TARGET').describe('Deploy target')) * .arg('port', arg.number().env('PORT').default(3000)) * .action(({ args }) => { * console.log(args.target); // from CLI, $DEPLOY_TARGET, or error * console.log(args.port); // from CLI, $PORT, or 3000 * }); * ``` */ env(varName: string): ArgBuilder>; /** * Bind to a dotted config path. * * The config value is read after CLI, stdin, and env, and is coerced to the * arg's declared kind the same way a flag's config value is. * * @param path - Dotted config key (e.g. `'deploy.region'`). * @returns The builder (for chaining). * * @example * ```ts * arg.string().config('deploy.region').default('us-east-1') * // Config file: { "deploy": { "region": "eu-west-1" } } * // $ mycli deploy → region = 'eu-west-1' * // $ mycli deploy ap-south-1 → CLI positional wins * ``` */ config(path: string): ArgBuilder>; /** * Attach interactive prompt configuration. * * When CLI, stdin, env, and config all produce nothing, the prompt engine * uses this config to ask the user. In non-interactive contexts the prompt * is skipped and resolution falls through to the default or the missing-arg * error. * * The compatible kinds follow the value and the cardinality: a variadic arg * takes the `multiselect` a `flag.array()` takes, and every other arg takes * what its kind takes on the flag surface. * * @param config - {@link PromptConfig} describing the interactive prompt. * @returns The builder (for chaining). * * @example * ```ts * arg.string().prompt({ kind: 'input', message: 'Target:' }) * // $ mycli deploy → prompts "Target:" * // $ mycli deploy production → skips the prompt * * arg.string().variadic().prompt({ kind: 'multiselect', message: 'Targets:' }) * ``` */ prompt(config: AllowedArgPromptConfig): ArgBuilder>; /** * Mark this input's values as sensitive. * * Sensitive defaults are omitted from definition and input JSON Schemas and * from automatic help text. A custom default description remains safe to show. * * @param value - Whether this input is sensitive. * @defaultValue `true` * @returns The builder (for chaining). */ sensitive(value?: boolean): ArgBuilder>; /** * Human-readable description shown in help output. * * @param description - Text displayed next to the arg in `--help`. * @returns The builder (for chaining). * * @example * ```ts * arg.string().describe('Deploy target') * * // Help output: * // Arguments: * // Deploy target * ``` */ describe(description: HelpDescription): ArgBuilder>; /** * Mark this arg as deprecated. * * When used, a warning is emitted to stderr. Help text shows * `[deprecated]` or `[deprecated: ]`. * * Does not change the arg's type-level config — it's metadata only. * * @param message - Optional migration reason/guidance. * @returns The builder (for chaining). * * @example * ```ts * arg.string().deprecated() // generic * arg.string().deprecated('use --target flag instead') // with guidance * * // Help output: * // Arguments: * // Deploy target [deprecated: use --target flag instead] * ``` */ deprecated(message?: string): ArgBuilder>; /** * Require an integer value. Composes with other numeric constraints. * * @param value - Whether to require an integer. * @defaultValue `true` * @returns The builder (for chaining). * * @example * ```ts * arg.number().int() // rejects 3.7, accepts 3 * arg.number({ int: true }).int(false) // re-allows non-integers * ``` */ int(this: ArgBuilder, value?: boolean): ArgBuilder; /** * Set an inclusive lower bound. Composes with other numeric constraints; * a later call overrides an earlier `min` (including one from the options * object). * * @param value - Inclusive minimum. * @returns The builder (for chaining). * * @example * ```ts * arg.number().min(0) // rejects -1, accepts 0 * arg.number({ min: 0 }).min(5) // effective min is 5 * ``` */ min(this: ArgBuilder, value: number): ArgBuilder; /** * Set an inclusive upper bound. Composes with other numeric constraints; * a later call overrides an earlier `max`. * * @param value - Inclusive maximum. * @returns The builder (for chaining). * * @example * ```ts * arg.number().max(100) // rejects 101, accepts 100 * ``` */ max(this: ArgBuilder, value: number): ArgBuilder; /** * Require (or, with `false`, allow) a finite value. Finiteness is enforced * by default, so this is mainly used as `.finite(false)` to re-allow * `Infinity` / `-Infinity`. * * @param allow - Whether to require a finite value. * @defaultValue `true` * @returns The builder (for chaining). * * @example * ```ts * arg.number().finite(false) // accepts Infinity * ``` */ finite(this: ArgBuilder, allow?: boolean): ArgBuilder; /** * Reject empty strings. Composes with other string constraints. * * @param value - Whether to reject empty strings. * @defaultValue `true` * @returns The builder (for chaining). * * @example * ```ts * arg.string().nonEmpty() // rejects '', accepts 'x' * ``` */ nonEmpty(this: ArgBuilder, value?: boolean): ArgBuilder; /** * Set an inclusive minimum length (UTF-16 code units). Composes with other * string constraints; a later call overrides an earlier `minLength`. * * @param value - Inclusive minimum length. * @returns The builder (for chaining). * * @example * ```ts * arg.string().minLength(3) // rejects 'ab', accepts 'abc' * ``` */ minLength(this: ArgBuilder, value: number): ArgBuilder; /** * Set an inclusive maximum length (UTF-16 code units). Composes with other * string constraints; a later call overrides an earlier `maxLength`. * * @param value - Inclusive maximum length. * @returns The builder (for chaining). * * @example * ```ts * arg.string().maxLength(8) // rejects 9+ chars * ``` */ maxLength(this: ArgBuilder, value: number): ArgBuilder; /** * Require the value to match a regular expression. Anchor with `^`/`$` * for full-string matching. Composes with other string constraints. * * @param value - Pattern the value must match. * @returns The builder (for chaining). * * @example * ```ts * arg.string().pattern(/^ghp_/) // rejects 'abc', accepts 'ghp_x' * ``` */ pattern(this: ArgBuilder, value: RegExp): ArgBuilder; } /** * Arg factory functions — the public API for creating positional arguments. * * Each method returns an {@linkcode ArgBuilder} seeded with the correct {@linkcode ArgKind} * and initial type-level config. Chain modifiers (`.optional()`, `.env()`, * `.config()`, `.prompt()`, `.default()`, `.variadic()`, `.stdin()`, * `.describe()`, `.deprecated()`) to refine. * * All args are **required** by default. Resolution order when extra * sources are configured: **CLI → stdin → env → config → prompt → default**. * * @example Overview of common kinds with common modifier patterns * ```ts * command('process') * // String arg with env fallback * .arg('input', arg.string() * .env('INPUT_FILE') * .describe('Input file path')) * * // Number arg with env + default * .arg('concurrency', arg.number() * .env('CONCURRENCY') * .default(4) * .describe('Worker threads')) * * // Custom arg — hex color parser with env * .arg('color', arg.custom((raw) => { * if (!/^#?[0-9a-f]{6}$/i.test(raw)) throw new Error('bad hex'); * return raw.startsWith('#') ? raw : `#${raw}`; * }) * .env('THEME_COLOR') * .optional() * .describe('Theme color (hex)')) * * .action(({ args }) => { * args.input; // string (required) * args.concurrency; // number (defaulted) * args.color; // string | undefined (optional custom) * }); * ``` */ interface ArgFactory { /** * String-valued positional argument, with optional string constraints. * Required by default. * * Constraints are enforced at the parse and resolution boundaries, in * fixed order: nonEmpty → minLength → maxLength → pattern. A `.default()` * value is validated against them where the chain declares it. They also * compose via chained methods (`.nonEmpty()`, `.minLength()`, * `.maxLength()`, `.pattern()`), which override values set here. * * @param constraints - Optional string constraints. * @defaultValue `undefined` (no constraints) * @returns A required string {@link ArgBuilder}. * * @example * ```ts * arg.string() // required string * arg.string().optional() // string | undefined * arg.string().env('TARGET') // falls back to $TARGET * arg.string().default('production') // always present * arg.string({ nonEmpty: true }) // rejects '' * arg.string({ pattern: /^ghp_/ }) // token shapes * * // In a command: * command('deploy') * .arg('target', arg.string().env('DEPLOY_TARGET').describe('Deploy target')) * ``` */ string(constraints?: StringConstraints): ArgBuilder<{ readonly valueType: string; readonly presence: 'required'; readonly variadic: false; readonly argKind: 'string'; readonly elementEligible: true; }>; /** * Number-valued positional argument. Required by default. * * The parser coerces the raw CLI string to a number and emits a * `ParseError` if conversion fails. Env values are coerced the same way. * * @example * ```ts * arg.number() // required number * arg.number().default(8080) // defaults to 8080 * arg.number().env('PORT') // falls back to $PORT (coerced) * * // In a command: * command('serve') * .arg('port', arg.number().env('PORT').default(3000).describe('Port')) * // $ mycli serve 8080 → 8080 * // $ PORT=9090 mycli serve → 9090 * // $ mycli serve → 3000 * ``` * * Constraints are enforced at the parse and resolution boundaries and also * compose via chained methods (`.int()`, `.min()`, `.max()`, `.finite()`), * which override values set here. The resolved value type stays `number`. * * @param constraints - Optional numeric constraints. `finite` defaults to * `true`, so `Infinity` / `-Infinity` are rejected unless `finite: false`. * @defaultValue `undefined` (finite-only, no bounds, non-integer allowed) * @returns A required number {@link ArgBuilder}. */ number(constraints?: NumberConstraints): ArgBuilder<{ readonly valueType: number; readonly presence: 'required'; readonly variadic: false; readonly argKind: 'number'; readonly elementEligible: true; }>; /** * Boolean positional argument. Required by default. * * A positional carries no presence semantics, so the token spells the value * out: `true`/`false` or `1`/`0` from argv, and also `yes`/`no` or an empty * string from env, config, stdin, and a prompt. * * @returns A required boolean {@link ArgBuilder}. * * @example * ```ts * command('feature') * .arg('enabled', arg.boolean().describe('Whether the feature is on')) * // $ mycli feature true → enabled = true * // $ mycli feature nope → ParseError: Invalid boolean value 'nope' * ``` */ boolean(): ArgBuilder<{ readonly valueType: boolean; readonly presence: 'required'; readonly variadic: false; readonly argKind: 'boolean'; readonly elementEligible: true; }>; /** * Key-value positional argument. Required by default. * * Consumes `KEY=VALUE` tokens and resolves to a record, split at the * **first** `=`. The non-variadic form reads one token, the variadic form * aggregates the whole tail. Later occurrences of the same key win, which * `.duplicateKeys()` changes. Not promptable. * * An element builder gives each entry value its own codec, constraints, and * checks, so `arg.keyValue(arg.path())` checks every value on disk. * * @param element - {@link ArgBuilder} describing the value of each entry. * @defaultValue an unconstrained string element * @returns A required key-value {@link ArgBuilder} for records of the element type. * * @example * ```ts * command('run') * .arg('vars', arg.keyValue().variadic().describe('Template variables')) * // $ mycli run A=1 B=2 → vars = { A: '1', B: '2' } * * command('scale') * .arg('replicas', arg.keyValue(arg.number().int().min(0)).variadic()) * // $ mycli scale web=3 api=2 → replicas = { web: 3, api: 2 } * ``` */ keyValue(element?: ArgBuilder): ArgBuilder<{ readonly valueType: Record; readonly presence: 'required'; readonly variadic: false; readonly argKind: 'keyValue'; readonly elementEligible: false; }>; /** * Enum-valued positional argument. Required by default. * * Accepts only the listed string literals. The inferred type is the * union of those literals (e.g. `'us' | 'eu' | 'ap'`), not `string`. * Invalid values produce a `ParseError` listing allowed options. * * @param values - Non-empty tuple of allowed string values. * @returns A required enum {@link ArgBuilder} typed to the union of `values`. * * @example * ```ts * arg.enum(['us', 'eu', 'ap']) // required, 'us' | 'eu' | 'ap' * arg.enum(['dev', 'prod']).default('dev') // defaulted * arg.enum(['json', 'csv']).optional() // 'json' | 'csv' | undefined * * // In a command: * command('deploy') * .arg('region', arg.enum(['us', 'eu', 'ap']).env('REGION').describe('Target region')) * // $ mycli deploy us → 'us' * // $ mycli deploy invalid → ParseError: Allowed: us, eu, ap * ``` */ enum(values: T): ArgBuilder<{ readonly valueType: T[number]; readonly presence: 'required'; readonly variadic: false; readonly argKind: 'enum'; readonly elementEligible: true; }>; /** * Custom positional argument validated by a Standard Schema v1 validator * (zod, valibot, arktype, …). The resolved value from any source is * validated after resolution; the arg's value type is the validator's * output type. * * Sync and async validators are both supported. Validation issues surface * as a `CONSTRAINT_VIOLATED` error naming the argument. * * @example * ```ts * import { z } from 'zod'; * arg.custom(z.string().uuid()) * // inferred type: string * ``` * * @param schema - A Standard Schema v1 validator. * @returns A required custom {@link ArgBuilder} typed to the validator's output. */ custom(schema: S): ArgBuilder<{ readonly valueType: InferStandardOutput; readonly presence: 'required'; readonly variadic: false; readonly argKind: 'custom'; readonly elementEligible: true; }>; /** * Custom-parsed positional argument. Required by default. * * The parse function receives the raw string and must return a value of * type `T`. Throw an `Error` (or `ParseError`) to signal invalid input. * The same parse function is used for both CLI and env values. * * @param parseFn - Converts the raw CLI string to `T`. * @returns A required custom {@link ArgBuilder} typed to the return of `parseFn`. * * @example * ```ts * arg.custom((raw) => Number.parseInt(raw, 16)) * // inferred type: number * * // In a command — parse hex color from CLI or $COLOR: * command('theme') * .arg('color', arg.custom((raw) => { * if (!/^[0-9a-f]{6}$/i.test(raw)) throw new Error('Expected 6-digit hex'); * return `#${raw}`; * }).env('COLOR').describe('Hex color code')) * // $ mycli theme ff6600 → '#ff6600' * // $ COLOR=aabbcc mycli theme → '#aabbcc' * ``` */ custom(parseFn: ArgParseFn): ArgBuilder<{ readonly valueType: T; readonly presence: 'required'; readonly variadic: false; readonly argKind: 'custom'; readonly elementEligible: true; }>; /** * URL-valued positional argument. Parses into a `URL`; invalid URLs are * rejected with an `INVALID_VALUE` error naming the argument. * * @param options - Optional protocol allowlist (without trailing colon). * @returns A required `URL` {@link ArgBuilder}. * * @example * ```ts * arg.url() // any URL * arg.url({ protocols: ['https'] }) // https only * * // In a command: * command('fetch') * .arg('endpoint', arg.url().env('API_URL').describe('Service endpoint')) * ``` */ url(options?: UrlFlagOptions): ArgBuilder<{ readonly valueType: URL; readonly presence: 'required'; readonly variadic: false; readonly argKind: 'custom'; readonly elementEligible: true; }>; /** * Path-valued positional argument. The value stays a `string`; optional * filesystem checks run **after resolution** through the runtime adapter, * so CLI, stdin, env, and defaulted values are all validated. * * A variadic path arg checks every value it collects. Help renders a * positional by its own name, so the `'path'` value hint on the schema does * not reach the usage line. * * @param options - Optional existence/type checks. `type` implies * existence unless `mustExist` is explicitly `false`. * @returns A required path-string {@link ArgBuilder}. * * @example * ```ts * arg.path() // any string * arg.path({ mustExist: true }) // rejects missing paths * arg.path({ type: 'directory' }) // must exist and be a directory * arg.path({ type: 'directory', create: true }) * // created recursively when missing * ``` */ path(options?: PathFlagOptions): ArgBuilder<{ readonly valueType: string; readonly presence: 'required'; readonly variadic: false; readonly argKind: 'string'; readonly elementEligible: true; }>; /** * Date-valued positional argument. Accepts strict ISO-8601 (`2026-07-10`, * `2026-07-10T14:30:00Z`) and parses into a `Date`. Lenient `Date.parse` * inputs (`'0'`, `'March 5'`) and calendar-invalid dates (`2026-02-31`) * are rejected. * * Returns `Date` (not `Temporal`) because the supported runtimes do not * all ship Temporal yet; use `arg.custom()` with `Temporal.PlainDate.from` * where the target runtime has it. * * @param options - Optional inclusive `min`/`max` date bounds. * @returns A required `Date` {@link ArgBuilder}. * * @example * ```ts * arg.date() * arg.date({ min: new Date('2020-01-01') }) * ``` */ date(options?: DateFlagOptions): ArgBuilder<{ readonly valueType: Date; readonly presence: 'required'; readonly variadic: false; readonly argKind: 'custom'; readonly elementEligible: true; }>; /** * Duration positional argument. Accepts `'30s'`, `'5m'`, `'1.5h'`, * `'250ms'`, `'2d'`, compounds like `'1h30m'`, or a bare millisecond * count, and resolves to **milliseconds**. * * @returns A required duration {@link ArgBuilder} in milliseconds. * * @example * ```ts * arg.duration().default(30_000) // `mycli wait 45s` → 45000 * ``` */ duration(): ArgBuilder<{ readonly valueType: number; readonly presence: 'required'; readonly variadic: false; readonly argKind: 'custom'; readonly elementEligible: true; }>; /** * Byte-size positional argument. Accepts `'512mb'`, `'1.5gb'`, `'64kb'`, * `'100b'` or a bare byte count, and resolves to **bytes**. Units are * binary (`1kb` = 1024) and case-insensitive. * * @returns A required size {@link ArgBuilder} in bytes. * * @example * ```ts * arg.bytes().default(10 * 1024 ** 2) // `mycli split 512kb` → 524288 * ``` */ bytes(): ArgBuilder<{ readonly valueType: number; readonly presence: 'required'; readonly variadic: false; readonly argKind: 'custom'; readonly elementEligible: true; }>; } /** * Positional argument schema factory. * * Entry point for defining args on a command. Use `arg.()` to create * an {@linkcode ArgBuilder}, then chain modifiers and pass the result to * `command().arg(name, builder)`. * * Six base kinds are available: * - `arg.string()` — raw string (most common) * - `arg.number()` — parsed to number, errors on NaN * - `arg.boolean()` reads an explicit true/false token * - `arg.enum(values)` — constrained to listed literals * - `arg.keyValue()` merges `KEY=VALUE` tokens into a record * - `arg.custom(fn)` — arbitrary parse function, infers return type * * Five sugar factories build on them, mirroring their flag counterparts: * - `arg.url()` parses to `URL`, with an optional protocol allowlist * - `arg.path()` keeps the string and adds optional filesystem checks * - `arg.date()` parses strict ISO-8601 to `Date` * - `arg.duration()` resolves `'1h30m'` and friends to milliseconds * - `arg.bytes()` resolves `'512mb'` and friends to bytes * * @example * ```ts * import { command, arg } from '@kjanat/dreamcli'; * * command('deploy') * .arg('target', arg.string().env('DEPLOY_TARGET').describe('Where to deploy')) * .arg('port', arg.number().env('PORT').default(3000)) * .action(({ args }) => { * console.log(`Deploying to ${args.target} on port ${args.port}`); * }); * * // $ mycli deploy production 8080 → target='production', port=8080 * // $ DEPLOY_TARGET=staging mycli deploy → target='staging', port=3000 * ``` */ declare const arg: ArgFactory; //#endregion //#region src/core/output/contracts.d.ts /** Ordered output verbosity levels owned by the output policy layer. */ declare const OUTPUT_VERBOSITY_LEVELS: readonly ["normal", "quiet"]; /** Stable text verbosity labels. */ type Verbosity = (typeof OUTPUT_VERBOSITY_LEVELS)[number]; //#endregion //#region src/core/schema/middleware.d.ts /** * Parameters received by a middleware function at runtime. * * Middleware receives erased args, flags, and provenance (since it's defined * independently of commands) plus the accumulated context from prior middleware * and a `next` function to continue the chain. */ interface MiddlewareParams { /** Fully resolved positional arguments (type-erased). */ readonly args: Readonly>; /** Fully resolved flags (type-erased). */ readonly flags: Readonly>; /** * Where each resolved value came from, keyed like `flags` and `args`. * * Erased alongside them, so any key reads as `ResolutionProvenance | * undefined`. A key the bound command never declared, and one an input * resolved no value for, both read `undefined`. */ readonly sources: ErasedInputSources; /** Context accumulated from previous middleware in the chain. */ readonly ctx: Readonly>; /** Output channel. */ readonly out: Out; /** CLI program metadata (name, bin, version, command). */ readonly meta: CommandMeta; /** * Continue to the next middleware or action handler. * * Call with context additions that merge into `ctx` for downstream. * Returns when the entire downstream chain completes — enabling * wrap-around patterns (timing, try/catch, cleanup). */ readonly next: (additions: Record) => Promise; } /** * Type-erased middleware handler stored on the command builder. * * At runtime, all middleware handlers have this signature. The phantom * `Output` type on {@linkcode Middleware} is erased. */ type ErasedMiddlewareHandler = (params: MiddlewareParams) => void | Promise; /** * Middleware handler function with typed `next()` parameter. * * The `Output` generic constrains what properties must be passed to * {@linkcode MiddlewareParams.next | next()}, ensuring type-safe context additions at the call site. */ type MiddlewareHandler> = (params: { readonly args: Readonly>; readonly flags: Readonly>; readonly sources: ErasedInputSources; readonly ctx: Readonly>; readonly out: Out; readonly meta: CommandMeta; /** Pass context additions downstream. Must include all `Output` properties. */ readonly next: (additions: Output) => Promise; }) => void | Promise; /** * Internal runtime representation of middleware. */ interface MiddlewareImpl { readonly _handler: ErasedMiddlewareHandler; } /** * Middleware with phantom output type. * * The `Output` parameter tracks what this middleware adds to context at * compile time. The `_output` brand is phantom — it exists only in the * type system for inference, not at runtime. * * Created via the {@linkcode middleware} factory. Attached to commands via * `CommandBuilder.middleware()`. * * @example * ```ts * interface User { id: string; name: string } * * const auth = middleware<{ user: User }>(async ({ next }) => { * const user = await getUser(); * if (!user) throw new CLIError('Not authenticated', { code: 'AUTH_REQUIRED' }); * return next({ user }); * }); * ``` */ type Middleware> = MiddlewareImpl & { /** @internal Phantom type brand — compile-time only. */ readonly _output: Output; }; /** * Create a middleware definition. * * Middleware runs before the action handler and can add typed context, * short-circuit execution, or wrap downstream processing. * * @param handler - Function receiving `{ args, flags, ctx, out, meta, next }`. * Call `next(additions)` to continue the chain with added context. * Omitting the `next()` call short-circuits (e.g., for auth guards). * @returns {@linkcode Middleware} to attach via `CommandBuilder.middleware()`. * * @example * ```ts * // Auth guard — adds user to context or throws * const auth = middleware(async ({ next }) => { * const user = await getUser(); * if (!user) throw new CLIError('Not authenticated', { code: 'AUTH_REQUIRED' }); * return next({ user }); * }); * * // Timing wrapper — measures downstream execution * const timing = middleware(async ({ out, next }) => { * const start = Date.now(); * await next({}); * out.info(`Done in ${Date.now() - start}ms`); * }); * * command('deploy') * .middleware(timing) * .middleware(auth) * .action(({ ctx }) => { * console.log(ctx.user.name); // typed! * }); * ``` */ declare function middleware>(handler: MiddlewareHandler): Middleware; //#endregion //#region src/core/schema/provenance.d.ts /** * Where a resolved value came from. * * Resolution records one {@link ResolutionProvenance} per input that produced a * value, and the same record reaches a handler through `sources` and a * `resolve()` caller through `ResolveResult.provenance`. {@link wasExplicit} * derives the explicit-versus-defaulted question from it. * * @module dreamcli/core/schema/provenance */ /** * Which stage produced a resolved value, and how. * * `via` and `trigger` distinguish the two ways stdin delivers bytes. An explicit * `-` keeps CLI precedence and reports `{ stage: 'cli', via: 'stdin', trigger: * 'dash' }`; an absent input takes the fallback stage between CLI and env and * reports `{ stage: 'stdin', via: 'stdin', trigger: 'fallback' }`. * * @example * ```ts * command('deploy') * .flag('region', flag.string().env('REGION').default('us')) * .action(({ sources }) => { * const region = sources.flags.region; * if (region?.stage === 'env') console.log(`from ${region.envVar}`); * }); * ``` */ type ResolutionProvenance = { readonly stage: 'cli'; } | { readonly stage: 'cli'; readonly via: 'stdin'; readonly trigger: 'dash'; } | { readonly stage: 'stdin'; readonly via: 'stdin'; readonly trigger: 'fallback'; } | { readonly stage: 'env'; readonly envVar: string; } | { readonly stage: 'config'; readonly configPath: string; } | { readonly stage: 'prompt'; } | { readonly stage: 'default'; }; /** * Provenance of every input of one surface, keyed by input name. * * An input that resolved no value has no record, so every member is optional in * value even though the key set is the surface's own. * * @typeParam T - The record of flag or arg builders whose keys this mirrors. */ type SourcesOf = { readonly [K in keyof T]: ResolutionProvenance | undefined; }; /** * Where each of a command's resolved values came from. * * Handed to an action, derive, or middleware handler as `sources`, keyed by the * same names as `flags` and `args`. * * @typeParam F - The command's flag builders. * @typeParam A - The command's arg builders. */ interface InputSources { /** Provenance of every declared flag, keyed by flag name. */ readonly flags: SourcesOf; /** Provenance of every declared arg, keyed by arg name. */ readonly args: SourcesOf; } /** * Whether a value came from somewhere other than its declared default. * * Every stage but `'default'` means the value was supplied: typed on the command * line, piped, exported, written in a config file, or answered at a prompt. An * input that resolved no value at all has no record and is not explicit. * * Read `stage` directly for a narrower question, such as `stage === 'cli'` for * "the user typed it on this command line". * * @param source - The provenance record of one input, or `undefined`. * @returns `true` when a source other than the default produced the value. * * @example * ```ts * command('build') * .flag('out', flag.string().default('dist')) * .action(({ sources, out }) => { * if (wasExplicit(sources.flags.out)) out.info('using an overridden output'); * }); * ``` */ declare function wasExplicit(source: ResolutionProvenance | undefined): boolean; //#endregion //#region src/core/schema/command.d.ts /** * Widen the context type when adding middleware. * * The default `C = Record` uses an index signature where * every key maps to `never` — making property access a type error until * middleware extends it. Naive intersection (`Record & { user: string }`) * collapses all properties to `never` because `never & T = never`. * * This utility replaces `Record` entirely on the first * `.middleware()` call. Subsequent calls use plain intersection. */ type WidenContext, Output extends Record> = C extends Record ? Output : C & Output; /** * Widen the context type when adding command-scoped derived context. * * Validation-only derive handlers return `undefined` (or nothing), preserving `C`. * Context-producing derive handlers return an object that merges into `C` * using the same first-call replacement rules as middleware. */ type WidenDerivedContext, Output> = Awaited extends Record ? WidenContext> : C; /** * Parameters received by the interactive resolver function. * * `flags` contains partially resolved values — present for flags resolved * via CLI, env, or config, `undefined` for unresolved flags. The resolver * uses this to decide which prompts to show based on current state. */ interface InteractiveParams>> { /** Partially resolved flag values (after CLI/env/config, before prompts). */ readonly flags: Readonly>>; } /** * A record mapping flag names to prompt configs or falsy values. * * - `PromptConfig` — show this prompt for the flag * - `false | undefined | null | 0 | ''` — skip prompting for this flag * * Only flag names that need prompting should have truthy values. * Flags not mentioned are handled by their per-flag `.prompt()` config. */ type InteractiveResult = Readonly>; /** * Interactive resolver function for command-level prompt control. * * Called after CLI/env/config resolution but before per-flag prompts fire. * Receives partially resolved values and returns a prompt schema for * flags that should be prompted. Commands without `.interactive()` use * per-flag prompt configs directly. * * @example * ```ts * import { command, flag } from '@kjanat/dreamcli'; * * const deploy = command('deploy') * .flag('region', flag.enum(['us', 'eu', 'ap'])) * .interactive(({ flags }) => ({ * region: !flags.region && { * kind: 'select', * message: 'Select region', * }, * })) * .action(({ flags, out }) => { * out.log(`Deploying to ${flags.region}`); * }); * ``` */ type InteractiveResolver>> = (params: InteractiveParams) => InteractiveResult; /** * Type-erased interactive resolver stored on {@linkcode CommandSchema}. * * Advanced bridge type: most consumers should use {@link InteractiveResolver} * via {@linkcode command | command().interactive()} and never reference this alias directly. * * At runtime, the resolver receives `{ flags: Record }` * and returns `Record`. The phantom types * from `CommandBuilder` are erased. */ type ErasedInteractiveResolver = (params: { readonly flags: Readonly>; }) => InteractiveResult; /** * Seals {@linkcode Out} against structural construction outside the framework. * * @internal */ declare const outBrand: unique symbol; /** * Output channel available inside action handlers. * * Provides structured methods for stdout/stderr, JSON output, * spinners, progress bars, and tables. The real implementation lives in * `src/core/output/`; this interface defines the shape that handlers consume. * * `Out` is a framework-created, non-exhaustive value: obtain instances from * action parameters, `createOutput()`, or `createCaptureOutput()` — do not * implement it. New readonly members may be added in minor releases. */ interface Out { /** Framework-construction seal. Obtain `Out` values from DreamCLI; do not implement this interface. */ readonly [outBrand]: never; /** Write to stdout (normal output). */ log(message: string): void; /** Informational (may be suppressed in quiet mode). */ info(message: string): void; /** * Status line to stderr, suppressed in quiet mode. * * Keeps stdout clean for piping; for success and progress notes like * `Wrote ` that scripts silence with `--quiet`. */ status(message: string): void; /** Warning to stderr. */ warn(message: string): void; /** Error to stderr. */ error(message: string): void; /** * Request a process exit code without emitting error-shaped output. * * Use this for check/status commands that should print normal output but * still signal a non-zero status to scripts. This does not stop execution; * later calls overwrite earlier calls, and thrown errors still win. */ setExitCode(code: number): void; /** * Emit a structured JSON value to stdout. * * Always serialises `value` as JSON to stdout regardless of output * mode. Prefer this over `log(JSON.stringify(...))` so the output * channel can enforce consistent formatting and future features * (pretty-print in TTY, streaming JSON, etc.). */ json(value: unknown): void; /** * Whether the output channel is in JSON mode (`--json` flag active). * * Handlers can check this to skip decorative output (spinners, * progress bars, ANSI formatting) when machine-readable output is * expected. */ readonly jsonMode: boolean; /** * Active output verbosity for this command execution. * * Root `--quiet`/`-q` resolves to `'quiet'`. Most handlers should emit * informational output through {@linkcode Out.info | info()}, * {@linkcode Out.status | status()}, {@linkcode Out.spinner | spinner()}, * or {@linkcode Out.progress | progress()} and let the channel suppress it * automatically. Read this property only when custom rendering or expensive * optional work genuinely depends on the active verbosity. */ readonly verbosity: Verbosity; /** * Whether stdout is connected to a TTY (terminal). * * Handlers can check this to decide whether to emit decorative output * (spinners, progress bars, ANSI color codes). When `false`, the output * is being piped or redirected — skip interactive decorations. * * Note: `jsonMode` takes precedence — when `jsonMode` is `true`, * decorative output should be suppressed regardless of `isTTY`. */ readonly isTTY: boolean; /** * Context-aware ANSI color palette (powered by `ansispeck`). * * Colors are enabled only when stdout is a TTY, JSON mode is off, and the * environment supports color (`NO_COLOR`, `FORCE_COLOR`, `--no-color`, * `--color`, `CI` are respected). When disabled, every formatter is an * identity function — `out.color.red('x')` returns `'x'` — so handlers can * style unconditionally without gating on `isTTY`/`jsonMode` themselves. * * @example * ```ts * .action(({ out }) => { * out.log(`${out.color.green('✔')} deployed ${out.color.bold('api')}`); * }); * ``` */ readonly color: Colors; /** * Whether OSC 8 terminal hyperlinks should be emitted. * * Honors explicit `--no-hyperlinks`/`--hyperlinks` argv flags first, then * `NO_HYPERLINKS`, then `FORCE_HYPERLINKS`, falling back to `isTTY`. * Handlers rendering their own `out.color.link(...)` output can gate on * this to keep OSC 8 escapes out of piped or opted-out contexts. */ readonly isHyperlinkSupported: boolean; /** * Render tabular data. * * - **TTY mode** (non-JSON): Pretty-print aligned columns with headers. * - **JSON mode** (`--json`): Emit the rows as a JSON array to stdout. * - **Piped** (non-TTY, non-JSON): Same aligned text output as TTY * (useful for `grep`, `awk`, etc.). * - Pass `{ format: 'text', stream: 'stderr' }` to keep a human-readable * side channel while `json()` writes machine output to stdout. * * When `columns` is omitted, columns are auto-inferred from the keys * of the first row. Column headers default to the key name. * * When `columns` is provided, both text and JSON output are projected to * only the listed keys. * * @param rows - Array of row objects. */ table>(rows: readonly T[], options: TableOptions): void; /** * Render tabular data with explicit column selection. * * @param rows - Array of row objects. * @param columns - Column descriptors controlling which keys are shown and header labels. * @param options - Per-call rendering options (format, stream). */ table>(rows: readonly T[], columns?: readonly TableColumn[], options?: TableOptions): void; /** * Create a spinner for indeterminate progress feedback. * * Returns a no-op handle in quiet or JSON mode. Otherwise, non-TTY output * uses a no-op handle or the configured static fallback. * * @param text - Initial spinner text. * @param options - Fallback strategy for non-TTY environments. * @returns A {@link SpinnerHandle} for lifecycle control. */ spinner(text: string, options?: SpinnerOptions): SpinnerHandle; /** * Create a progress bar for measured work. * * Returns a no-op handle in quiet or JSON mode. Otherwise, pass `total` for * determinate mode (percentage bar); omit for indeterminate (pulsing). * * @param options - Progress configuration (total, label, fallback). * @returns A {@link ProgressHandle} for updating progress. */ progress(options: ProgressOptions): ProgressHandle; /** * Stop the currently active spinner or progress handle, if any. * * TTY spinner and progress handles start `setInterval` timers that * prevent the process from exiting until a terminal method (`stop`, * `succeed`, `fail`, `done`) is called. If a handler throws before * reaching that call, the timer leaks and the process hangs. * * Call `stopActive()` in a `finally` block after handler execution * to guarantee cleanup. It is idempotent — safe to call when no * handle is active, or when the handle was already stopped. * * The framework calls this automatically in `runCommand()` and * `cli().run()`. Direct users of `createOutput()` should call it * themselves after the handler returns or throws. * * @example * ```ts * const out = createOutput({ isTTY: true }); * try { * await handler({ out }); * } finally { * out.stopActive(); * } * ``` */ stopActive(): void; } /** * Runtime metadata about the CLI program and current command execution. * * Available to action handlers and middleware. * * Populated by the CLI dispatch layer from {@link CLISchema} and * {@link CommandSchema}. For standalone `runCommand()` calls without * a CLI wrapper, a minimal meta is constructed from the command's own schema. */ interface CommandMeta { /** CLI program name (from `cli('name')` or package.json inference). */ readonly name: string; /** Binary display name used in help/usage (may differ from `name`). */ readonly bin: string; /** Program version, if set via `.version()` or discovered from package.json. */ readonly version: string | undefined; /** The leaf command name currently being executed. */ readonly command: string; } /** * The bag of values received by an action handler. * * - `args`: fully resolved positional arguments * - `flags`: fully resolved flags * - `sources`: which stage produced each of those values * - `ctx`: derive/middleware-provided context * - `out`: output channel * - `meta`: CLI program metadata (name, bin, version, command) * * The `C` parameter defaults to `Record`, making `ctx` * property access a type error until derive or middleware extends it. */ interface ActionParams>, A extends Record>, C extends Record = Record> { /** Fully resolved positional argument values, typed from `.arg()` definitions. */ readonly args: Readonly>; /** Fully resolved flag values, typed from `.flag()` definitions. */ readonly flags: Readonly>; /** * Where each resolved value came from, keyed like `flags` and `args`. * * An input that resolved no value has no record. {@link wasExplicit} answers * the explicit-versus-defaulted question; read `stage` for the rest. */ readonly sources: InputSources; /** Middleware/derive-provided context, typed from `.middleware()` and `.derive()` chains. */ readonly ctx: Readonly; /** Structured output channel for stdout, stderr, JSON, tables, and spinners. */ readonly out: Out; /** Runtime metadata about the CLI program and current command. */ readonly meta: CommandMeta; } /** * Action handler function signature. * * May be sync or async — the framework will `await` the return value * regardless. The `C` parameter carries the accumulated middleware * context type (defaults to empty). */ type ActionHandler>, A extends Record>, C extends Record = Record> = (params: ActionParams) => void | Promise; /** * Type-erased action handler stored on {@linkcode CommandBuilder}. * * The typed {@linkcode ActionHandler} from `.action()` is cast to this * erased form at the type-erasure boundary, keeping {@linkcode CommandBuilder} * covariant in its generic parameters. This enables structural * compatibility across TypeScript declaration-file boundaries where * generic inference may fall back to constraint types. * * Follows the same erasure pattern as {@link ErasedDeriveHandler} and * {@link ErasedMiddlewareHandler}. */ type ErasedActionHandler = (params: { readonly args: Readonly>; readonly flags: Readonly>; readonly sources: ErasedInputSources; readonly ctx: Readonly>; readonly out: Out; readonly meta: CommandMeta; }) => void | Promise; /** * The provenance bag as the execution seam carries it, before a handler's own * flag and arg names type it. */ type ErasedInputSources = InputSources>, Readonly>>; /** * The bag of values received by a derive handler. * * Identical to {@link ActionParams}: derives run after full resolution and * before the action handler, with typed args, flags, provenance, and current * context plus `out` and `meta`. */ type DeriveParams>, A extends Record>, C extends Record = Record> = ActionParams; /** * Command-scoped typed pre-action handler. * * Derive handlers may: * - validate resolved input and throw {@linkcode CLIError} * - return nothing (or `undefined`) to continue without changing context * - return an object whose properties merge into `ctx` downstream * * Handlers may be async; the resolved value follows the same rules. * They cannot wrap downstream execution; use {@linkcode middleware} for that. */ type DeriveHandler>, A extends Record>, C extends Record = Record, Output extends Record | undefined = undefined> = (params: DeriveParams) => Output | Promise | void | Promise; /** * Type-erased derive handler stored on the command builder. */ type ErasedDeriveHandler = (params: { readonly args: Readonly>; readonly flags: Readonly>; readonly sources: ErasedInputSources; readonly ctx: Readonly>; readonly out: Out; readonly meta: CommandMeta; }) => undefined | Readonly> | Promise>>; /** * Internal execution step union preserving registration order across * {@linkcode CommandBuilder.derive | derive()} and {@linkcode CommandBuilder.middleware | middleware()}. */ type ExecutionStep = { readonly kind: 'derive'; readonly handler: ErasedDeriveHandler; } | { readonly kind: 'middleware'; readonly handler: ErasedMiddlewareHandler; }; /** * Program metadata passed to a function-form example, resolved at render time. * * `name` is the actually-invoked program name (`options.help.binName`, falling * back to the command name) so examples stay truthful under symlinks, * `inheritName`, and `npx x` vs a global install. `version` is the program * version, or `undefined` when none is configured. */ interface ExampleMeta { readonly name: string; readonly version: string | undefined; } /** * An example command line: a literal string, or a function resolved at render * time with the program {@link ExampleMeta} (so the program name need not be * hardcoded). */ type ExampleCommand = string | ((meta: ExampleMeta) => string); /** A single usage example shown in help text. */ interface CommandExample { /** The command invocation (e.g. `'deploy production --force'`). */ readonly command: ExampleCommand; /** Optional description of what this example does. */ readonly description?: string; } /** Resolve an {@link ExampleCommand} to its string form for the given meta. */ declare function resolveExampleCommand(command: ExampleCommand, meta: ExampleMeta): string; /** * Runtime descriptor produced by {@link CommandBuilder}. * * Consumers (parser, help generator, CLI dispatcher) read this to * understand the command's shape — flags, args, aliases, subcommands, * and interactive resolver. */ interface CommandSchema { /** Type-only seal produced by {@link createCommandSchema}. */ readonly [schemaBrand]: 'command'; /** The command name (used for dispatch, e.g. `'deploy'`). */ readonly name: string; /** Human-readable description for help text. */ readonly description: string | undefined; /** Alternative names for this command. */ readonly aliases: readonly string[]; /** Whether this command is hidden from help listings. */ readonly hidden: boolean; /** Usage examples for help text. */ readonly examples: readonly CommandExample[]; /** Named flag schemas, keyed by flag name. */ readonly flags: Readonly>; /** Ordered positional arg entries (name + schema). */ readonly args: readonly CommandArgEntry[]; /** Whether an action handler has been registered. */ readonly hasAction: boolean; /** * Command-level interactive resolver for schema-driven prompt control. * * When set, called after CLI/env/config resolution with partially resolved * flag values. Returns prompt configs for flags that need interactive input. * Takes precedence over per-flag `.prompt()` configs for flags it returns * configs for; flags not mentioned fall back to their per-flag configs. * * @see InteractiveResolver */ readonly interactive: ErasedInteractiveResolver | undefined; /** * Nested subcommand schemas (for help rendering and completion). * * Pure data — no execution closures. Populated by `.command()` on * `CommandBuilder`. Empty for leaf commands. */ readonly commands: readonly CommandSchema[]; } /** * A named positional argument entry in the command schema. * * Pairs a user-facing arg name with its {@link ArgSchema} descriptor. * The array ordering in {@link CommandSchema.args} determines CLI position. */ interface CommandArgEntry { /** User-facing argument name (shown in help as ``). */ readonly name: string; /** Runtime descriptor controlling parsing, presence, and coercion. */ readonly schema: ArgSchema; } /** * A named positional argument entry accepted by {@link createCommandSchema}. * * The schema may be an {@link ArgDefinition} or an already-built {@link ArgSchema}. */ interface CommandArgEntryDefinition { /** User-facing argument name (shown in help as ``). */ readonly name: string; /** Arg definition or an already-built schema. */ readonly schema: ArgDefinition | ArgSchema; } /** * Input shape accepted by {@link createCommandSchema}. * * Every field except `name` is optional. Flags, args, and subcommands accept * either definitions or already-built schemas. */ interface CommandDefinition { /** The command name used for dispatch. */ readonly name: string; /** * Human-readable description for help text. * @defaultValue `undefined` */ readonly description?: string | undefined; /** * Alternative names for this command. * @defaultValue `[]` */ readonly aliases?: readonly string[] | undefined; /** * Whether this command is hidden from help listings. * @defaultValue `false` */ readonly hidden?: boolean | undefined; /** * Usage examples for help text. * @defaultValue `[]` */ readonly examples?: readonly CommandExample[] | undefined; /** * Flag definitions or built schemas, keyed by flag name. * @defaultValue `{}` */ readonly flags?: Readonly> | undefined; /** * Ordered positional arg entries. * @defaultValue `[]` */ readonly args?: readonly CommandArgEntryDefinition[] | undefined; /** * Whether an action handler has been registered. * @defaultValue `false` */ readonly hasAction?: boolean | undefined; /** * Command-level interactive resolver. * @defaultValue `undefined` */ readonly interactive?: ErasedInteractiveResolver | undefined; /** * Nested subcommand definitions or built schemas. * @defaultValue `[]` */ readonly commands?: readonly (CommandDefinition | CommandSchema)[] | undefined; } /** * Create a {@link CommandSchema} from a plain definition object. * * Most consumers should prefer {@link command | command()}, which returns a * {@link CommandBuilder} with type inference. `createCommandSchema()` is the * low-level escape hatch for tooling that composes schemas as data. * * Flags, args, and subcommands are normalized recursively, so an already-built * schema fed back in produces a deep-equal schema. * * Flag spellings are checked across the whole tree, so a definition whose names, * aliases, or negated spellings collide with each other or with a propagated * ancestor flag is rejected here. Both flags still parse under their canonical * names, so what a collision costs is the shared spelling. Help advertises it on * both flags and the parser answers it with one of them. * Args go through the same invariants {@link CommandBuilder.arg} enforces. * These are the checks the {@link CommandBuilder} applies as flags, args, and * subcommands are registered. * * @param definition - Command name plus optional flags, args, and subcommands. * @returns A fully populated {@link CommandSchema}. * @throws {CLIError} With code `'INVALID_SCHEMA'` when a name at any depth is * empty or contains whitespace, a flag or arg at any depth is named * `__proto__`, which JavaScript cannot carry as a plain record key, or a flag * record at any depth has a * replaced prototype, which hides the entries a name check would read. * @throws {CLIError} With code `'FLAG_NAME_COLLISION'` when two flags on one * command share a spelling. * @throws {CLIError} With code `'PROPAGATED_FLAG_COLLISION'` when a flag shadows * a spelling propagated from an ancestor command. * @throws {CLIError} With code `'INVALID_BUILDER_STATE'` when a positional comes * after a variadic one, or `'DUPLICATE_STDIN_INPUT'` when two inputs on one * command consume stdin and either is exclusive. * * @example * ```ts * const schema = createCommandSchema({ * name: 'deploy', * description: 'Ship the build', * flags: { force: { kind: 'boolean' } }, * args: [{ name: 'target', schema: { kind: 'string' } }], * }); * ``` */ declare function createCommandSchema(definition: CommandDefinition): CommandSchema; /** * Type-erased {@link CommandBuilder} for heterogeneous subcommand storage. * * Advanced helper alias: useful only when working on DreamCLI internals or * custom tooling that mirrors the framework's type-erasure boundary. * * Uses widest possible generic bounds so any `CommandBuilder` is * assignable. The CLI layer's `compileCommand()` traverses these to build * the execution graph. * */ type AnyCommandBuilder = CommandBuilder>, Record>, Record>; /** * Immutable command schema builder. * * The type parameters `F` (flags), `A` (args), and `C` (context) are * phantom types that accumulate builder types as `.flag()`, `.arg()`, * `.derive()`, and `.middleware()` are chained. The `.action()` handler receives * fully typed `ActionParams`. * * `C` defaults to `Record`, making `ctx` property * access a type error until derive or middleware extends it. * * @example * ```ts * const deploy = command('deploy') * .description('Deploy to an environment') * .arg('target', arg.string().describe('Deploy target')) * .flag('force', flag.boolean().alias('f')) * .flag('region', flag.enum(['us', 'eu', 'ap'])) * .action(async ({ args, flags, out }) => { * // args.target: string * // flags.force: boolean * // flags.region: 'us' | 'eu' | 'ap' | undefined * out.log(`Deploying ${args.target}...`); * }); * ``` */ declare class CommandBuilder> = {}, A extends Record> = {}, C extends Record = Record> { /** @internal Runtime schema descriptor. */ readonly schema: CommandSchema; /** @internal The action handler, if registered (type-erased for covariance). */ readonly handler: ErasedActionHandler | undefined; /** * @internal Nested sub-command builders (type-erased for heterogeneous storage). * * Stored separately from `schema.commands` because builders carry action * handlers and phantom types needed by `compileCommand()` in the CLI layer. * `schema.commands` holds pure `CommandSchema[]` for help/completion. */ readonly _subcommands: readonly AnyCommandBuilder[]; /** * @internal Derive and middleware steps in registration order. * * The executor builds the handler chain from this list. */ readonly _executionSteps: readonly ExecutionStep[]; /** @internal Phantom brand for accumulated flag builder types. No runtime value. */ readonly _flags: F; /** @internal Phantom brand for accumulated arg builder types. No runtime value. */ readonly _args: A; /** @internal Phantom brand for accumulated context type. No runtime value. */ readonly _ctx: C; /** * Create a command builder from a pre-built schema descriptor. * * @param schema - Runtime command descriptor. * @param handler - Action handler, if registered. * @param subcommands - Nested sub-command builders (type-erased). * @param executionSteps - Derive/middleware steps in registration order. */ constructor(schema: CommandSchema, handler?: ErasedActionHandler, subcommands?: readonly AnyCommandBuilder[], executionSteps?: readonly ExecutionStep[]); /** * Register a command-level interactive resolver for schema-driven prompts. * * The resolver is called after CLI/env/config resolution with partially * resolved flag values. It returns a prompt schema for flags that need * interactive input based on the current state. * * For flags the resolver returns a {@linkcode PromptConfig}, that config is used * instead of any per-flag `.prompt()` config. For flags returned as falsy * (or not mentioned), per-flag `.prompt()` configs are used as fallback. * * Commands without `.interactive()` use per-flag prompt configs directly. * * @example * ```ts * const deploy = command('deploy') * .flag('region', flag.enum(['us', 'eu', 'ap'])) * .flag('force', flag.boolean()) * .interactive(({ flags }) => ({ * region: !flags.region && { * kind: 'select', * message: 'Select region', * }, * })) * .action(({ flags }) => { ... }); * ``` * * @param resolver - Function receiving partially resolved flags and returning prompt configs. * @returns The builder (for chaining). */ interactive(resolver: InteractiveResolver): CommandBuilder; /** * Register a command-scoped typed pre-action handler. * * Derive runs after full resolution and before the action handler. * It receives typed `{ args, flags, ctx, out, meta }` and may either: * * - return nothing (or `undefined`) for validation-only behavior * - return an object to merge additional properties into `ctx` * * Handlers may be async — the runtime awaits them before continuing. * * Unlike middleware, derive cannot wrap downstream execution and does not * use `next()`. Use {@linkcode middleware} for timing, logging, retries, cleanup, * or error-boundary patterns. * * Adding derive drops the current handler (like `.flag()`, `.arg()`, and * `.middleware()`) because the action handler's `ctx` type may change. * * @example * ```ts * command('deploy') * .flag('token', flag.string().env('AUTH_TOKEN')) * .derive(({ flags }) => { * if (!flags.token) { * throw new CLIError('Not authenticated', { * code: 'AUTH_REQUIRED', * suggest: 'Run `mycli login` or set AUTH_TOKEN', * }); * } * return { token: flags.token }; * }) * .action(({ ctx }) => { * ctx.token; // string * }); * ``` * * @param handler - Derive function receiving typed args/flags/ctx. * @returns The builder (for chaining). */ derive | undefined = undefined>(handler: DeriveHandler): CommandBuilder>; /** * Register middleware to run before the action handler. * * Middleware executes in registration order. Each middleware receives * `{ args, flags, ctx, out, meta, next }` and must call `next(additions)` * to continue the chain. Context additions are merged and become * typed downstream. * * Adding middleware widens `C` via intersection and drops the current * handler (like `.flag()` / `.arg()` — the handler's type signature * changes when context changes). * * @example * ```ts * import { CLIError, command, middleware } from '@kjanat/dreamcli'; * * interface User { * id: string; * email: string; * } * * async function getCurrentUser(): Promise { * return { id: 'u_123', email: 'dev@example.com' }; * } * * function startTrace(name: string): string { * return `trace:${name}`; * } * * // Resolve the current user and expose it as `ctx.user` downstream. * const auth = middleware<{ user: User }>(async ({ next }) => { * const user = await getCurrentUser(); * if (!user) { * throw new CLIError('Not authenticated', { code: 'AUTH_REQUIRED' }); * } * await next({ user }); * }); * * // Create a trace id for this command run and expose it as `ctx.traceId`. * const telemetry = middleware<{ traceId: string }>(async ({ meta, next }) => { * const traceId = startTrace(`${meta.name}.${meta.command}`); * await next({ traceId }); * }); * * command('deploy') * .middleware(auth) // C becomes { user: User } * .middleware(telemetry) // C becomes { user: User } & { traceId: string } * .action(({ ctx }) => { * ctx.user; // User — typed * ctx.traceId; // string — typed * }); * ``` * * @param m - {@link Middleware} instance created via {@linkcode middleware | middleware()}. * Middleware handlers receive `{ args, flags, ctx, out, meta, next }`. * @returns The builder (for chaining). */ middleware>(m: Middleware): CommandBuilder>; /** * Set the command's description for help text. * * Displayed below the usage line in `--help` output and next to the * command name in parent command/group help listings. * * @param text - One-line description of what the command does. * * @example * ```ts * command('deploy') * .description('Deploy the application to a target environment') * .action(({ out }) => { out.log('deploying...'); }); * * // $ mycli deploy --help * // Usage: deploy [flags] * // * // Deploy the application to a target environment * ``` * * @returns The builder (for chaining). */ description(text: string): CommandBuilder; /** * Add an alternative name for this command. * * Aliases are accepted during dispatch alongside the primary name. * Multiple aliases can be chained. Aliases are shown in help output. * * @param name - Alternative command name (e.g. `'d'` for `deploy`). * * @example * ```ts * command('deploy') * .alias('d') * .alias('push') * .action(({ out }) => { out.log('deploying...'); }); * * // All equivalent: * // $ mycli deploy * // $ mycli d * // $ mycli push * ``` * * @returns The builder (for chaining). */ alias(name: string): CommandBuilder; /** * Hide this command from help listings. * * The command remains fully functional and dispatchable — it just * won't appear in `--help` output or shell completions. Useful for * internal/debug commands. * * @example * ```ts * command('debug-dump') * .hidden() * .action(({ out }) => { out.log(JSON.stringify(internalState)); }); * * // $ mycli --help → 'debug-dump' is not listed * // $ mycli debug-dump → still works * ``` * * @returns The builder (for chaining). */ hidden(): CommandBuilder; /** * Add a usage example to help text. * * Examples are rendered in the "Examples:" section of `--help` output. * Call multiple times to add several examples. Each example shows a * shell invocation, optionally with a description. * * `cmd` may be a literal string or a function receiving the program * {@link ExampleMeta} (`name`, `version`), resolved at render time. Use the * function form to reference the invoked program name instead of hardcoding * it, so examples stay truthful under symlinks, `inheritName`, and * `npx x` vs a global install. * * @param cmd - The example command line, or a `(meta) => string` builder. * @param description - Optional one-line explanation of what the example does. * * @example * ```ts * command('deploy') * .arg('target', arg.string()) * .flag('force', flag.boolean().alias('f')) * .example('deploy production', 'Deploy to production') * .example((m) => `${m.name} deploy staging -f`, 'Force deploy to staging') * .action(({ args, flags }) => { ... }); * * // $ mycli deploy --help * // ... * // Examples: * // deploy production Deploy to production * // mycli deploy staging -f Force deploy to staging * ``` * * @returns The builder (for chaining). */ example(cmd: ExampleCommand, description?: string): CommandBuilder; /** * Register a named flag on this command. * * The flag name is added to the type-level `F` map. Duplicate flag names * are prevented at the type level via the `Exclude` constraint. * * The builder controls the flag's type, presence, aliases, env/config * bindings, and description. See {@link FlagBuilder} for available modifiers. * * @param name - Flag name: the `--name` CLI token and the matching key on `flags` * in the handler. The name is preserved as-is (no camelCasing); read non-identifier * names such as `'dry-run'` with bracket access (`flags['dry-run']`). * @param builder - Configured {@linkcode FlagBuilder} from {@linkcode flag | flag.string()}, * `flag.boolean()`, `flag.number()`, `flag.enum()`, `flag.array()`, or `flag.custom()`. * * @example * ```ts * command('serve') * .flag('port', flag.number() * .alias('p') * .env('PORT') * .default(3000) * .describe('Port to listen on')) * .flag('host', flag.string() * .env('HOST') * .default('localhost') * .describe('Bind address')) * .flag('verbose', flag.boolean() * .alias('v') * .describe('Enable verbose logging')) * .action(({ flags, out }) => { * flags.port; // number * flags.host; // string * flags.verbose; // boolean * out.log(`Listening on ${flags.host}:${flags.port}`); * }); * * // $ mycli serve --port 8080 -v * // $ PORT=9090 mycli serve * ``` * * @returns The builder (for chaining). * @throws {@link CLIError} `INVALID_SCHEMA` when the name is `__proto__`, * which a plain record cannot carry. * @throws {@link CLIError} `FLAG_NAME_COLLISION` when the command already * declares this name, or the new flag's spellings collide with another * flag's. * @throws {@link CLIError} `PROPAGATED_FLAG_COLLISION` when a spelling * collides with one propagated to a registered subcommand. */ flag>(name: N & Exclude, builder: B): CommandBuilder, A, C>; /** * Register a named positional argument on this command. * * Args are ordered by registration — position on the CLI matches the * order of `.arg()` calls. The arg name is added to the type-level `A` * map. Duplicate arg names are prevented at the type level via the * `Exclude` constraint. * * The builder controls the arg's type, presence, env binding, and * description. See {@link ArgBuilder} for available modifiers. * * @param name - Positional arg name (used in help text and `args.*`). * @param builder - Configured {@linkcode ArgBuilder} from `arg.string()`, `arg.number()`, * or `arg.custom()`. * * @example * ```ts * command('deploy') * // Required string arg — first positional * .arg('target', arg.string() * .env('DEPLOY_TARGET') * .describe('Deploy target')) * // Optional number arg — second positional * .arg('port', arg.number() * .env('PORT') * .default(3000) * .describe('Port number')) * .action(({ args }) => { * args.target; // string * args.port; // number * }); * * // Usage: deploy [flags] [port] * // $ mycli deploy production 8080 * // $ DEPLOY_TARGET=staging mycli deploy * ``` * * @returns The builder (for chaining). * @throws {@link CLIError} `INVALID_SCHEMA` when the name is `__proto__`, * which a plain record cannot carry. * @throws {@link CLIError} `INVALID_BUILDER_STATE` when an earlier arg on this * command is variadic, so this one could never be filled. * @throws {@link CLIError} `DUPLICATE_STDIN_INPUT` when another input on this * command already consumes stdin exclusively. */ arg>(name: N & Exclude, builder: B): CommandBuilder, C>; /** * Register a nested subcommand on this command. * * The subcommand's builder is stored in `_subcommands` for the CLI layer's * `compileCommand()` to traverse when building the execution graph. The * subcommand's `CommandSchema` is also appended to `schema.commands` for * help rendering and completion generation. * * Does not change `F`, `A`, or `C` — subcommands are type-erased at the * parent level (same semantics as `CLIBuilder.command()`). The handler is * preserved. * * @example * ```ts * const db = group('db') * .description('Database operations') * .command(migrateCmd) * .command(seedCmd); * ``` * * @param sub - Child {@link CommandBuilder} to nest under this command. * @returns The builder (for chaining). * @throws {@link CLIError} `PROPAGATED_FLAG_COLLISION` when a spelling this * command propagates collides with one the subcommand, or any of its own * descendants, declares. */ command>, A2 extends Record>, C2 extends Record>(sub: CommandBuilder): CommandBuilder; /** * Register the action handler for this command. * * The handler receives fully typed `{ args, flags, ctx, out, meta }` derived * from the accumulated `.flag()`, `.arg()`, `.derive()`, and `.middleware()` * definitions. * * May be synchronous or async. Return values are ignored; command handlers * communicate through `out`, thrown errors, and side effects. * * @param handler - Function receiving `ActionParams`. * * @example * ```ts * // Minimal * command('greet') * .arg('name', arg.string()) * .action(({ args, out }) => { * out.log(`Hello, ${args.name}!`); * }); * ``` * * @example * ```ts * // Full params — flags, args, context, output, metadata * command('deploy') * .arg('target', arg.string().env('DEPLOY_TARGET')) * .flag('force', flag.boolean().alias('f')) * .flag('region', flag.enum(['us', 'eu', 'ap']).env('REGION')) * .middleware(auth) * .action(async ({ args, flags, ctx, out, meta }) => { * args.target; // string * flags.force; // boolean * flags.region; // 'us' | 'eu' | 'ap' | undefined * ctx.user; // User (from auth middleware) * meta.command; // string * * const spinner = out.spinner('Deploying...'); * await deploy(args.target, { force: flags.force }); * spinner.stop(); * out.log('Done'); * }); * ``` * * @returns The builder (for chaining). */ action(handler: ActionHandler): CommandBuilder; } /** * Create a new command builder. * * @param name - The command name used for dispatch (e.g. `'deploy'`). * * @example * ```ts * import { arg, command, flag } from '@kjanat/dreamcli'; * * const greet = command('greet') * .arg('name', arg.string()) * .flag('loud', flag.boolean()) * .action(({ args, flags, out }) => { * const msg = `Hello, ${args.name}!`; * out.log(flags.loud ? msg.toUpperCase() : msg); * }); * ``` * * @returns A fresh {@link CommandBuilder} with empty flags, args, and context. */ declare function command(name: string): CommandBuilder; /** * Create a command builder intended for use as a command group. * * Semantically identical to {@linkcode command | command()} — a group is simply a command that * has subcommands registered via `.command()`. The separate factory * communicates intent: groups organise subcommands, leaf commands have actions. * * A group may also have its own `.action()` (e.g. `git remote` lists remotes * when invoked without a subcommand, but dispatches to `git remote add`, etc.). * * @param name - The group name used for dispatch (e.g. `'db'`). * * @example * ```ts * const db = group('db') * .description('Database operations') * .command(migrateCmd) * .command(seedCmd); * ``` * * @returns A fresh {@link CommandBuilder} with empty flags, args, and context. */ declare function group(name: string): CommandBuilder; //#endregion //#region src/core/prompt/index.d.ts /** * A select prompt config with choices guaranteed non-empty. * * The resolution chain populates choices from `FlagSchema.enumValues` * when the user's {@linkcode PromptConfig} omits them. */ interface ResolvedSelectPromptConfig { /** Discriminant — single-choice selection prompt. */ readonly kind: 'select'; /** User-facing question text. */ readonly message: string; /** Non-empty list of selectable options (populated from flag enum values when omitted). */ readonly choices: readonly [SelectChoice, ...SelectChoice[]]; } /** * A multiselect prompt config with choices guaranteed non-empty. * * Same guarantee as {@linkcode ResolvedSelectPromptConfig} — choices are always * present and non-empty. */ interface ResolvedMultiselectPromptConfig { /** Discriminant — multiple-choice selection prompt. */ readonly kind: 'multiselect'; /** User-facing question text. */ readonly message: string; /** Non-empty list of selectable options (populated from flag enum values when omitted). */ readonly choices: readonly [SelectChoice, ...SelectChoice[]]; /** Minimum number of selections required (validated after input). */ readonly min?: number; /** Maximum number of selections allowed (validated after input). */ readonly max?: number; } /** * Prompt config variant where select/multiselect choices are guaranteed * present. The prompt engine receives this (not raw {@linkcode PromptConfig}), * so it never needs to merge enum values from `FlagSchema`. * * confirm and input configs pass through unchanged. */ type ResolvedPromptConfig = ConfirmPromptConfig | InputPromptConfig | ResolvedSelectPromptConfig | ResolvedMultiselectPromptConfig; /** * Prompt engine interface. * * Implementations present one prompt per `promptOne()` call and return * the result. Engines may retain state across calls, such as an answer queue. * * The resolution chain calls `promptOne` for each flag that needs * interactive input. Engines do not need schema knowledge — all * relevant context (message, choices, validation) is in the config. * * @example * ```ts * // Custom engine (e.g. wrapping @clack/prompts) * const engine: PromptEngine = { * async promptOne(config) { * // ... render with your library * return { answered: true, value: userInput }; * } * }; * ``` */ interface PromptEngine { /** * Present a single prompt and return the user's response. * * @param config - The resolved prompt configuration (choices guaranteed * for select/multiselect). * @returns The user's answer, or `{ answered: false }` if cancelled. */ promptOne(config: ResolvedPromptConfig): Promise; } /** * A function that reads a single line of user input. * * Returns `null` on EOF (Ctrl+D on Unix, Ctrl+Z on Windows), * indicating the user closed the input stream (treated as cancel). * * The terminal prompter uses this as its sole input seam. The * resolution chain (prompt-adapter-1) will wire this to the * runtime adapter's stdin. */ type ReadFn = () => Promise; /** * Prepare a {@linkcode ResolvedPromptConfig} from a raw {@linkcode PromptConfig} and optional * enum values from the flag schema. * * For select/multiselect prompts without explicit choices, this merges * the flag's enum values into the choices list. Throws if no choices * are available. * * This function is called by the resolution chain (prompt-resolve-1), * not by the engine itself — keeping the engine free of schema knowledge. * * @param config - Raw prompt config from `FlagSchema.prompt` * @param enumValues - Optional enum values from `FlagSchema.enumValues` * @returns Resolved config with choices guaranteed for select kinds * @throws Error if select/multiselect has no choices and no enum values */ declare function resolvePromptConfig(config: PromptConfig, enumValues: readonly string[] | undefined): ResolvedPromptConfig; //#endregion //#region src/core/output/writer.d.ts /** * Minimal I/O seam — the only write primitive the output module depends on. * * Extracted to its own file so that both `index.ts` (OutputChannel) and * `activity.ts` (handle classes) can import it without a circular dependency. * * @module dreamcli/core/output/writer */ /** * A function that writes a string somewhere. * * This is the only write primitive the output layer depends on. * In production it usually wraps `process.stdout.write` or * `process.stderr.write`; in tests it is often a simple string accumulator. * * The contract is intentionally tiny: * - writes are synchronous fire-and-forget * - callers decide whether to append a trailing newline * - there is no backpressure or flush signal * * @example * ```ts * const lines: string[] = []; * const write: WriteFn = (data) => { * lines.push(data); * }; * ``` */ type WriteFn = (data: string) => void; //#endregion //#region src/core/output/index.d.ts /** * Configuration for creating an output channel. * * Every field is optional — sensible defaults are applied when omitted. */ interface OutputOptions { /** * Writer for stdout-bound messages (`log`, `info`, `json`). * Defaults to `process.stdout.write` when running in Node/Bun. */ readonly stdout?: WriteFn; /** * Writer for stderr-bound messages (`warn`, `error`). * In JSON mode, `log` and `info` are also redirected here so that * stdout contains only structured JSON output. * Defaults to `process.stderr.write` when running in Node/Bun. */ readonly stderr?: WriteFn; /** * Whether stdout is connected to a TTY. * When `false`, output may omit ANSI codes and decorations. * Defaults to `false` (safe default — non-TTY until proven otherwise). */ readonly isTTY?: boolean; /** * Verbosity level. * - `'normal'` (default) — emit all messages * - `'quiet'` — suppress `info` messages */ readonly verbosity?: Verbosity; /** * Enable JSON output mode. * * When `true`, `log` and `info` messages are redirected to stderr * so that stdout is reserved exclusively for structured `json()` output. * `warn` and `error` continue to write to stderr as normal. * * @defaultValue `false` */ readonly jsonMode?: boolean; /** * Explicitly enable or disable ANSI colors on `out.color`. * * When set, this wins over the auto-gate — use it to force colors in * captured test output or when embedding into a host that manages its * own color policy. * * @defaultValue auto — enabled when `isTTY` is `true`, `jsonMode` is * `false`, and the environment supports color (`NO_COLOR`, * `FORCE_COLOR`, `--no-color`, `--color`, `CI` are respected). */ readonly color?: boolean; /** * Resolved OSC 8 hyperlink support for `out.isHyperlinkSupported`. * * When set, this wins over the `isTTY` fallback. Callers pass the * `NO_HYPERLINKS`/`FORCE_HYPERLINKS` (and `--no-hyperlinks`/`--hyperlinks`) * decision here via {@linkcode resolveHyperlinkOverride}, keeping `process` * access out of the output layer. * * @defaultValue `isTTY` */ readonly hyperlinks?: boolean; } /** * Create an output channel. * * Low-level factory: action handlers already receive `out` automatically from * `cli()`, `.execute()`, and `runCommand()`. Call `createOutput()` when you * are embedding DreamCLI primitives into a custom runtime or need a standalone * output implementation outside the normal command pipeline. * * @param options - Optional configuration. When omitted, output is * discarded (useful for silent test runs). Pass `stdout`/`stderr` * writers to direct output somewhere useful. * * @returns An {@link Out} instance backed by an {@link OutputChannel}. * * @example * ```ts * // Production (wired by the runtime adapter) * const out = createOutput({ * stdout: (s) => process.stdout.write(s), * stderr: (s) => process.stderr.write(s), * isTTY: process.stdout.isTTY === true, * }); * * // Test (capture output) * const lines: string[] = []; * const out = createOutput({ * stdout: (s) => lines.push(s), * stderr: (s) => lines.push(s), * }); * ``` */ declare function createOutput(options?: OutputOptions): Out; /** Captured output from a `createCaptureOutput` instance. */ interface CapturedOutput { /** * Lines written to stdout. * * In normal mode: `log`, `info`, and `json` output. * In JSON mode: only `json` output (log/info redirected to stderr). */ readonly stdout: string[]; /** * Lines written to stderr. * * In normal mode: `warn` and `error` output. * In JSON mode: `warn`, `error`, `log`, and `info` output. */ readonly stderr: string[]; /** * Activity events from spinner and progress handles. * * Captured separately from stdout/stderr to allow targeted assertions * on activity lifecycle without parsing text output. Events are * recorded in chronological order. */ readonly activity: ActivityEvent[]; } /** * Create an output channel that captures all output into arrays. * * Useful in tests to assert on what a handler wrote without touching * real I/O. * * @param options - Optional {@link OutputOptions} (minus `stdout`/`stderr`, * which are wired to the capture buffers automatically). * * @returns A tuple of `[out, captured]` — the {@link Out} channel and the * {@link CapturedOutput} buffers. * * @example * ```ts * const [out, captured] = createCaptureOutput(); * out.log('hello'); * out.warn('danger'); * expect(captured.stdout).toEqual(['hello\n']); * expect(captured.stderr).toEqual(['danger\n']); * ``` */ declare function createCaptureOutput(options?: Omit): [out: Out, captured: CapturedOutput]; //#endregion export { ArgParseFn as $, WithoutElementEligibility as $t, Out as A, PromptResult as An, DefaultValueOptions as At, MiddlewareHandler as B, ProgressHandle as Bn, FlagKind as Bt, ErasedActionHandler as C, StandardSchemaV1Types as Cn, SplitOptions as Ct, InteractiveParams as D, PromptConfig as Dn, BooleanFlagDefinition as Dt, ExecutionStep as E, MultiselectPromptConfig as En, ArrayFlagDefinition as Et, InputSources as F, HelpDescription as Fn, FlagDefinition as Ft, ArgConfig as G, TableFormat as Gn, InferFlag as Gt, middleware as H, SpinnerHandle as Hn, FlagParseFn as Ht, ResolutionProvenance as I, HelpTheme as In, FlagDefinitionBase as It, ArgDefinitionBase as J, schemaBrand as Jn, NumberFlagDefinition as Jt, ArgDefaultValue as K, TableOptions as Kn, InferFlags as Kt, SourcesOf as L, HelpThemeFactory as Ln, FlagDefinitionByKind as Lt, createCommandSchema as M, SelectPromptConfig as Mn, EnumFlagDefinition as Mt, group as N, NumberConstraintViolation as Nn, FlagBuilder as Nt, InteractiveResolver as O, PromptConfigBase as On, CountFlagDefinition as Ot, resolveExampleCommand as P, NumberConstraints as Pn, FlagConfig as Pt, ArgKind as Q, WithPresence as Qt, wasExplicit as R, ActivityEvent as Rn, FlagDefinitionOverrides as Rt, DeriveParams as S, StandardSchemaV1SuccessResult as Sn, SplitFormat as St, ExampleMeta as T, InputPromptConfig as Tn, SplitSetting as Tt, Verbosity as U, SpinnerOptions as Un, FlagPresence as Ut, MiddlewareParams as V, ProgressOptions as Vn, FlagNegation as Vt, ArgBuilder as W, TableColumn as Wn, FlagSchema as Wt, ArgDefinitionOverrides as X, StringElementConfig as Xt, ArgDefinitionByKind as Y, ResolvedValue as Yt, ArgFactory as Z, StringFlagDefinition as Zt, CommandDefinition as _, StandardSchemaV1Issue as _n, DUPLICATE_KEYS as _t, WriteFn as a, PathFlagOptions as an, InferArg as at, CommandSchema as b, StandardSchemaV1Props as bn, SourceSplitBinding as bt, ResolvedMultiselectPromptConfig as c, StringConstraints as cn, NumberArgDefinition as ct, resolvePromptConfig as d, StdinOptions as dn, StringArgElementConfig as dt, createFlagSchema as en, ArgPresence as et, ActionHandler as f, StdinWhen as fn, WithArgPresence as ft, CommandBuilder as g, StandardSchemaV1FailureResult as gn, createArgSchema as gt, CommandArgEntryDefinition as h, StandardSchemaV1 as hn, arg as ht, createOutput as i, PathChecks as in, EnumArgDefinition as it, command as j, SelectChoice as jn, DuplicatePolicy as jt, InteractiveResult as k, PromptKind as kn, CustomFlagDefinition as kt, ResolvedPromptConfig as l, StdinBinding as ln, ResolvedArgValue as lt, CommandArgEntry as m, InferStandardOutput as mn, WithoutArgElementEligibility as mt, OutputOptions as n, getFlagNegatedName as nn, BooleanArgDefinition as nt, PromptEngine as o, UrlFlagOptions as on, InferArgs as ot, ActionParams as p, InferStandardInput as pn, WithVariadic as pt, ArgDefinition as q, TableStream as qn, KeyValueFlagDefinition as qt, createCaptureOutput as r, DateFlagOptions as rn, CustomArgDefinition as rt, ReadFn as s, StringConstraintViolation as sn, KeyValueArgDefinition as st, CapturedOutput as t, flag as tn, ArgSchema as tt, ResolvedSelectPromptConfig as u, StdinConsume as un, StringArgDefinition as ut, CommandExample as v, StandardSchemaV1Options as vn, DuplicateKeys as vt, ExampleCommand as w, ConfirmPromptConfig as wn, SplitPolicy as wt, DeriveHandler as x, StandardSchemaV1Result as xn, SplitBinding as xt, CommandMeta as y, StandardSchemaV1PathSegment as yn, SPLIT_FORMATS as yt, Middleware as z, Fallback as zn, FlagFactory as zt };