/** * Runner — the bridge between the engine's frame loop and the CLI's async flow. * * Commands are sequential (`const config = await promptForConfig(...)`), while * the engine is an event-driven render loop. The runner reconciles the two: it * mounts the screen, hands control to `onKey`/`run`, and resolves a Promise when * the flow calls `done()`. * * Three invariants hold for every wizard: * 1. the terminal is restored on every exit path — errors, SIGINT and a * process crash included; * 2. with no TTY the screen is never mounted: the caller gets a * NonInteractiveError and follows the headless path; * 3. whatever the logger would write during the mount is held in the sink and * re-emitted afterwards, so the frame is not torn. */ import { type KeyEvent, type Node, type Screen, type TerminalStreams } from './engine/index.js'; import { type LogRecord } from './log-sink.js'; /** Signals that the command has to carry on without an interactive UI (CI, pipe, --yes). */ export declare class NonInteractiveError extends Error { constructor(message?: string); } /** The user abandoned the wizard (Ctrl+C, or a step that cancels the flow). */ export declare class WizardCancelledError extends Error { constructor(message?: string); } export interface WizardContext { /** Encerra a tela e resolve o wizard com este valor. */ done(value: T): void; /** Encerra a tela e rejeita com WizardCancelledError. */ cancel(message?: string): void; /** Agenda um novo frame depois de alterar o estado. */ refresh(): void; /** Access to the screen, for cases that need the scheduler or the capabilities. */ readonly screen: Screen; } export interface WizardOptions { /** Pure view, rebuilt every frame. */ view: () => Node; /** Keys the view handles on its own. */ onKey?: (event: KeyEvent, ctx: WizardContext) => void; /** * Async work run with the screen alive — installing packages, writing files. * The UI keeps animating until the promise resolves. */ run?: (ctx: WizardContext) => Promise | void; fps?: number; /** How to find the terminal. Injectable for tests; the default resolves it itself. */ resolveStreams?: () => TerminalStreams | null; } export interface WizardResult { readonly value: T; /** Mensagens que o logger reteve enquanto a tela estava montada. */ readonly logs: readonly LogRecord[]; } /** * True when there is a terminal to mount the screen on. * * Looking at `process.stdout.isTTY && process.stdin.isTTY` is not enough: that * is what made `npx zard-cli init` fall back to text mode on macOS and Linux, * where npm runs the binary through a shell and hands over stdin as a pipe. The * controlling terminal is still reachable, and it is what decides. */ export declare function isInteractive(resolve?: () => TerminalStreams | null): boolean; export declare function runWizard(options: WizardOptions): Promise>; //# sourceMappingURL=runner.d.ts.map