/**
 * Progress routing for `agents run --lease`.
 *
 * The box-side bootstrap emits `LEASE_AGENT_MARKER` on its own line right before
 * `agents run`. Everything the crabbox run streams BEFORE that marker is setup
 * noise (sync bytes, node/agents install, `agents setup`) — shown as spinner
 * text and captured for a failure dump. Everything AFTER is the agent's own
 * output — printed through verbatim. The marker line itself is swallowed.
 */
/** Sentinel echoed on the box right before `agents run`. Distinctive + collision-proof. */
export declare const LEASE_AGENT_MARKER = "___AGENTS_LEASE_AGENT_OUTPUT_b1f4c2___";
/**
 * A structured setup step, parsed from a `___PHASE_<name>___` sentinel line the
 * bootstrap script echoes before each block (sync/install/runtime/creds/…). The
 * command layer renders these to drive a step-by-step progress UI; the lib never
 * prints (see `renderStepLine`).
 */
export type LeaseStep = {
    name: string;
    detail?: string;
    elapsedMs?: number;
};
/**
 * The sentinel line the bootstrap script echoes to announce phase `name`.
 * Kept distinct from `LEASE_AGENT_MARKER` (which does NOT start with `___PHASE_`).
 */
export declare function leasePhaseSentinel(name: string): string;
/**
 * Render one lease step as a single human line the command layer can print
 * (e.g. behind a spinner). Self-contained: the lib never writes to a stream.
 */
export declare function renderStepLine(step: LeaseStep): string;
export interface Spinner {
    /** Begin animating a phase (renders `frame text` on one line, TTY only). */
    start(text: string): void;
    /** Change the text shown; rendered on the next throttled tick (no write itself). */
    update(text: string): void;
    /** Finalize the current line with a symbol (e.g. ✔) and a newline. */
    stopAndPersist(symbol: string, text: string): void;
    /** Clear the current animated line without persisting anything. */
    stop(): void;
    /** True while a phase is active. */
    readonly active: boolean;
}
/**
 * A deliberately minimal, self-throttled spinner. Unlike `ora`, it does NOT hook
 * the stream's `write` to re-render on external output — it writes exactly one
 * short line per fixed tick and nowhere else, so it is structurally incapable of
 * a re-render feedback loop (the failure mode that made `ora` blow up when a
 * lease streamed output past a live spinner). On a non-TTY it prints each phase
 * label once and stays silent on `update`, so piped/CI output never floods.
 *
 * Only ever run ONE phase at a time, and never stream other output to the same
 * stream while a phase is active — stop it first.
 */
export declare function createSpinner(opts?: {
    stream?: {
        write(s: string): unknown;
        isTTY?: boolean;
    };
    enabled?: boolean;
    intervalMs?: number;
}): Spinner;
export interface LeaseOutputRouter {
    /** Feed a raw chunk of the crabbox run's combined stdout/stderr. */
    push(chunk: string): void;
    /** Flush any buffered partial line (call once the stream closes). */
    end(): void;
    /** True once the agent-output marker has been seen. */
    sawAgent(): boolean;
    /** The setup lines seen so far (for a failure dump). */
    setupLines(): string[];
    /** The structured steps parsed from phase sentinels so far. */
    steps(): LeaseStep[];
}
/**
 * Split the crabbox run stream at `LEASE_AGENT_MARKER`. `onSetupLine` fires for
 * each complete non-empty line before the marker; `onAgentChunk` fires with raw
 * text after it (streamed promptly, not line-buffered, so agent output is live).
 *
 * Setup lines matching a `___PHASE_<name>___` sentinel are swallowed (never shown
 * as setup noise) and surfaced through `onStep` instead — a structured step
 * stream the command layer can render via `renderStepLine`. When `now` is
 * provided, each step carries `elapsedMs` since the previous step (or router
 * start for the first); omit `now` for deterministic, timing-free output.
 */
export declare function createLeaseOutputRouter(cb: {
    onSetupLine: (line: string) => void;
    onAgentChunk: (chunk: string) => void;
    onStep?: (step: LeaseStep) => void;
    marker?: string;
    now?: () => number;
}): LeaseOutputRouter;
