/**
 * The interactive terminal UI of the one command and `submit`: a step
 * timeline on stderr with inputs for the email and the code, an account
 * picker, Yes/No questions, spinners and a live collection progress bar.
 *
 * It is used only on an interactive terminal (`terminalFeatures`: stdin and
 * stderr are TTYs, TERM is not dumb, CI is not set, no `--json`); everywhere
 * else the commands keep their plain lines and prompts. What it shows follows
 * the same rules as the plain output: the masked address from vigilbase.com,
 * never the address, the code, the token or the session code once entered;
 * account names only through `displayText`; counts, never values, from the
 * snapshot.
 *
 * Every label is built from the session's symbols (`ellipsis`, `join`), so an
 * ASCII-only console (the Linux console, legacy Windows consoles) gets no
 * character outside ASCII.
 */
import { type Writer } from '../../lib/format.js';
import { Tui, type SignalSource, type TtyInput, type TtyOutput } from '../../lib/tui.js';
import type { CollectProgress } from './collector.js';
import type { EmailVerificationView } from './email-verification.js';
/** Sign-in attempts offered after the first one fails. */
export declare const MAX_SIGN_IN_RETRIES = 2;
export type CollectionPlan = {
    zones: number;
    plannedReads: number;
    maxRequests: number;
};
export type CollectedSummary = {
    zones: number;
    total: number;
    ok: number;
    notCollectable: number;
    denied: number;
    /** Other HTTP errors and reads that could not be collected. */
    failed: number;
    path: string;
    bytes: number;
    /** `2 member emails`, `3 DNS names`, … (counts only). */
    contents: string[];
    inspect: string;
};
export type UploadSummary = {
    replayed: boolean;
    passed?: number;
    warnings?: number;
    failed?: number;
    notCollected: number;
    resultsUrl?: string;
    opening: boolean;
    requester: string;
};
export type CheckupTuiOptions = {
    mode: 'text' | 'json';
    stdin: TtyInput;
    stderr: TtyOutput;
    /** stdout; when it is not a terminal, the result lines are written there too (plain). */
    stdout?: {
        isTTY?: boolean;
    };
    env: NodeJS.ProcessEnv;
    /** The command's writer, for those plain result lines. */
    writer: Writer;
    platform?: NodeJS.Platform;
    signals?: SignalSource;
    exit?: (code: number) => void;
    frameMs?: number;
    now?: () => number;
};
export declare class CheckupTui {
    readonly tui: Tui;
    private readonly writer;
    private readonly now;
    private readonly echoResults;
    private constructor();
    /** The terminal UI, or null for the plain output. */
    static open(options: CheckupTuiOptions): CheckupTui | null;
    /** What Ctrl-C prints at this stage. */
    set cancelMessage(message: string);
    /**
     * A writer for the lines the commands print outside the steps below
     * (warnings, notes): `Warning: …` becomes `▲`, anything else a `│` line,
     * so nothing is written through the live frame.
     */
    get lines(): Writer;
    intro(): void;
    /** `…`, or `...` on an ASCII-only console: for masked IDs and cut text built outside this class. */
    get ellipsis(): string;
    /** `a · b · c`, or `a - b - c` on an ASCII-only console. */
    join(parts: readonly string[]): string;
    /** `label…` (`label...` in ASCII): an activity in progress, without its ellipsis. */
    private ongoing;
    /** `◒  label…` while `work` runs; `label` has no ellipsis. */
    busy<T>(label: string, work: () => Promise<T>): Promise<T>;
    /** `◒  label…` until stopped; `label` (also in `update`) has no ellipsis. */
    spinner(label: string): {
        update(label: string): void;
        stop(): void;
    };
    /** `◇  title  detail` */
    step(title: string, detail?: string): void;
    warning(text: string): void;
    /** A Yes/No question; the answer stays on screen (`◇  question › Yes`). Ctrl-D answers no. */
    confirm(question: string, options: {
        initial: boolean;
        detail?: string;
    }): Promise<boolean>;
    /** A question a flag answered: `◇  question › Yes (--yes)`. */
    answeredByFlag(question: string, flag: string): void;
    /**
     * The verification's inputs: the address is shown while it is typed and
     * sent, then replaced by the masked address vigilbase.com returns; the code
     * is shown while it is typed, then masked (●●●●●●). A notice (a refused
     * address, a wrong code) appears inside the next input, which is drawn in
     * the same place.
     */
    emailView(): EmailVerificationView;
    private retryClock;
    /**
     * cf's interactive sign-in with the terminal handed over (cf prints and
     * reads directly); after a failed or cancelled sign-in, "Try signing in
     * again?" up to MAX_SIGN_IN_RETRIES times. `check` is whoami afterwards.
     */
    signIn<T>(run: () => Promise<number>, check: () => Promise<T>): Promise<T>;
    signedIn(summary: string): void;
    /** The account picker; `label` is already safe (`displayText`). Null on Ctrl-D. */
    chooseAccount(accounts: ReadonlyArray<{
        id: string;
        label: string;
        detail: string;
    }>): Promise<string | null>;
    /** `◇  Account  Acme Corp  a1b2…8f90`, the last line before the collection. */
    account(label: string, detail: string): void;
    /**
     * `◒  Collecting  ████░░  zones 1/2 · 40/97 reads · ~20 s left`, redrawn on
     * every progress event. The estimate is the larger of what the request
     * budget allows for the reads left and the pace so far.
     */
    collecting(plan: CollectionPlan): {
        update(progress: CollectProgress): void;
        stop(): void;
    };
    /** `◇  84 reads · 72 ok · 10 not collectable · 2 refused`, the saved file and what it contains. */
    collected(summary: CollectedSummary): void;
    /** `◆  Upload 13 KB to vigilbase.com?  › Yes / No`; Enter on the initial state means No. */
    confirmUpload(input: {
        bytes: number;
        where: string;
        requester: string;
        flag: string | null;
    }): Promise<boolean>;
    /** The upload and the scoring, which happen in one request. */
    uploading<T>(bytes: number, work: () => Promise<T>): Promise<T>;
    /**
     * `└  ✓ Done. 10 passed · 2 failed`, the results link (underlined, an OSC 8
     * link where supported) and the email note. `plainLines` are the plain
     * result lines, also written to stdout when stdout is not a terminal.
     */
    uploaded(summary: UploadSummary, plainLines: readonly string[]): void;
    /** Dim lines under the end of the timeline (the logout hint), then the command on a line of its own. */
    footnote(text: string, command?: string): void;
    /** Before an upload error is shown: the `submit` command for the saved snapshot, on a line of its own. */
    uploadLater(command: string): void;
    /**
     * `■  message` with the hint under it, for an error that ends the command;
     * `runCli` then does not print it again. After Ctrl-C nothing more is shown.
     */
    fail(error: unknown): void;
    close(): void;
}
