import { type ChannelSetupAwaitChoice } from "#setup/cli/index.js";
import { type RailSpinner } from "#setup/cli/index.js";
/**
 * Clack constrains option values to readonly primitives. Our scaffold flow
 * only ever uses string-valued options (`ChannelKind`, `SetupMode`,
 * `ProviderConnection`, model id), so the tightened bound matches usage.
 */
export type PrompterValue = string | number | boolean;
export interface SelectOption<T extends PrompterValue> {
    value: T;
    label: string;
    hint?: string;
    /** Short inline annotation shown dimmed only while the cursor is on this row. */
    focusHint?: string;
    /**
     * Longer, display-only explanation shown dimmed alongside the option while it
     * is highlighted during navigation. Hidden once a choice is submitted.
     */
    description?: string;
    /** Cursor-pointer/active-label accent; "warning" turns them yellow for an attention row. */
    accent?: "warning";
    disabled?: boolean;
    /** Parenthetical shown after a disabled option's label explaining why. */
    disabledReason?: string;
    /**
     * "warning" renders the disabled reason in yellow with a dimmed (not struck)
     * label: the row is unavailable here but actionable elsewhere (e.g. a channel
     * that needs a Vercel account points at /model), unlike the default disabled
     * styling, which marks a hard conflict.
     */
    disabledReasonTone?: "warning";
    /**
     * Completed work: renders with a check and remains cursor-addressable for
     * contextual feedback, but cannot be selected or toggled.
     */
    completed?: boolean;
    /**
     * Marks a mandatory row that is always selected and cannot be toggled off; the
     * cursor skips it and it renders a dimmed check. Mutually exclusive with
     * `disabled`.
     */
    locked?: boolean;
    /** Parenthetical shown after a locked option's label, e.g. "always available". */
    lockedReason?: string;
    /**
     * A leading run of featured options forms a searchable picker's default
     * viewport: with no filter typed, only they are in view, and scrolling or
     * filtering reaches the rest of the list. Featured options must be sorted
     * to the front. Meaningless without `search`.
     */
    featured?: boolean;
}
/**
 * An outcome line from an earlier lap of a looping menu, shown with the
 * repainted question: the TUI panel renders it beneath the options, the CLI
 * prints it to scrollback before the prompt.
 */
export interface SelectNotice {
    tone: "success" | "info" | "warning" | "error";
    text: string;
}
/** Options common to every {@link Prompter.select} call. */
export interface SelectCommonOptions<T extends PrompterValue> {
    message: string;
    options: SelectOption<T>[];
    /**
     * Add a type-ahead filter line. The filter is a case-insensitive substring
     * match against each option's label, value, and hint.
     */
    search?: boolean;
    /** Placeholder shown in the filter line while it is empty (with `search`). */
    placeholder?: string;
    /**
     * Require a selection before enter can confirm. For multi-select this blocks
     * an empty submission; single-select always resolves to the highlighted row,
     * so it is inherently satisfied.
     */
    required?: boolean;
    /**
     * How option hints are laid out in the dev TUI panel (the CLI prompter ignores
     * it and keeps its default inline, unnumbered rendering). "stacked" renders
     * each hint on its own line below the label with a blank line between options —
     * for small action menus whose hints carry current values. "inline" keeps hints
     * on the label row, suppresses numeric shortcuts, and separates the trailing
     * completion action (e.g. the `/channels` task list).
     */
    hintLayout?: "stacked" | "inline";
    /** Outcome lines from earlier laps of a looping menu. */
    notices?: readonly SelectNotice[];
}
/** Single-select form: navigate, then enter picks the highlighted option. */
export interface SingleSelectOptions<T extends PrompterValue> extends SelectCommonOptions<T> {
    multiple?: false;
    /** Pre-position the cursor on the option whose value matches. */
    initialValue?: T;
}
/** Multi-select form: space or enter toggles rows; enter on the trailing Submit row confirms the marked set. */
export interface MultiSelectOptions<T extends PrompterValue> extends SelectCommonOptions<T> {
    multiple: true;
    /** Pre-mark these values as selected. */
    initialValues?: T[];
}
/** Result of a single-select whose one row can be edited inline. */
export type EditableSelectResult<T extends PrompterValue> = {
    kind: "selected";
    value: T;
} | {
    kind: "edited";
    value: T;
    text: string;
};
/** Inline-edit behavior for one row in an otherwise ordinary single-select. */
export interface EditableSelectOptions<T extends PrompterValue> extends SingleSelectOptions<T> {
    editable: {
        value: T;
        defaultValue: string;
        formatHint: (value: string) => string;
        validate?: (value: string) => string | undefined;
    };
}
/** Color intent for {@link Prompter.note}: red warning (default) or green success. */
export type NoteTone = "warning" | "success";
/** Input for {@link Prompter.acknowledge}: a heading plus optional body lines. */
export interface AcknowledgeOptions {
    message: string;
    lines?: readonly string[];
}
export interface Prompter {
    text(opts: {
        message: string;
        placeholder?: string;
        defaultValue?: string;
        validate?: (value: string) => string | undefined;
        /**
         * Context lines shown with the question (e.g. why it is being re-asked).
         * They live and die with the question: the TUI paints them inside the
         * question panel so they vanish on submit, the CLI prints them to
         * scrollback above the prompt.
         */
        notices?: readonly SelectNotice[];
    }): Promise<string>;
    password(opts: {
        message: string;
        validate?: (value: string) => string | undefined;
    }): Promise<string>;
    /**
     * Unified picker. Defaults to single-select (enter picks the highlighted row);
     * pass `multiple: true` for a checklist (space or enter toggles, enter on
     * the trailing Submit row confirms). Add
     * `search: true` for a type-ahead filter. `required` gates an empty
     * multi-select submission.
     */
    select<T extends PrompterValue>(opts: SingleSelectOptions<T>): Promise<T>;
    select<T extends PrompterValue>(opts: MultiSelectOptions<T>): Promise<T[]>;
    /**
     * TUI enhancement for a select row whose secondary value becomes an inline
     * editor while focused. Typing and editing keys update it directly. Optional
     * so non-repainting prompt implementations can keep the ordinary
     * select-then-text fallback.
     */
    selectEditable?<T extends PrompterValue>(opts: EditableSelectOptions<T>): Promise<EditableSelectResult<T>>;
    /**
     * Static instructions the user dismisses before the flow moves on. The TUI
     * renders them in the question slot of the flow panel (the text takes the
     * place of option rows) until enter; the CLI prints them to scrollback and
     * resolves immediately, since printed text persists there. Optional so
     * lightweight test fakes can omit it — flows fall back to {@link note}.
     */
    acknowledge?(opts: AcknowledgeOptions): Promise<void>;
    /**
     * Presents actions while a setup operation continues in the background.
     * The TUI implements it; plain and headless prompters omit it, so callers
     * fall back to waiting without concurrent controls.
     */
    awaitChoice?: ChannelSetupAwaitChoice;
    /**
     * Rail-attached notice, no bullet — reads as a follow-up to the previous
     * step. Red by default (warnings, collisions); pass `tone: "success"` for a
     * green closing note like the one-shot next steps.
     */
    note(message: string, title?: string, options?: {
        tone?: NoteTone;
    }): void;
    /** Prints the Vercel ▲ logo + title + subtitle banner. */
    intro(title: string, subtitle?: string): void;
    /** Prints a final green ● end-cap with the message. */
    outro(message: string): void;
    log: {
        message(text: string): void;
        info(text: string): void;
        success(text: string): void;
        warning(text: string): void;
        error(text: string): void;
        commandOutput(text: string): void;
        section?(title: string, lines: readonly string[]): void;
        /**
         * Starts a section-like braille spinner for a network or other async wait,
         * returning a handle whose `stop()` clears it. Present on the real prompter;
         * optional so lightweight test fakes can omit it.
         */
        spinner?(message: string): RailSpinner;
    };
}
/**
 * Builds a prompter with Vercel-branded styling — white-then-green vertical
 * rails, open/filled triangle bullets per step, and a colored corner
 * below the active prompt. Built on `@clack/core` so we own every glyph.
 *
 * The resolved-prompt count is scoped to the returned prompter so the
 * first prompt's leader rail is white and subsequent ones are green.
 */
export declare function createPrompter(): Prompter;
