/** * Minimal in-house spinner — issue #97. * * Why in-house? `ora` / `nanospinner` / `cli-spinners` would each pull a small * dep tree we don't need. The full spec for an audit-time spinner is a redraw * loop + ANSI cursor codes — well under 100 LOC. The shared `ui/tokens` palette * (ansis) handles color. * * Design contract: * - Always writes to stderr by default. stdout is reserved for the audit * JSON / SARIF payload; the spinner must never contaminate it. * - No-op when `enabled` is false OR `isTTY` is false. Callers can pass the * spinner unconditionally; suppression logic lives here. * - On `start()` we hide the cursor and install signal handlers so a * ^C-killed audit doesn't leave the terminal in a cursor-hidden state. * - On `succeed()` / `fail()` / `stop()` we clear the spinner line first, * then optionally write the final state (succeed/fail). The final line * persists; the in-progress frame does not. */ export interface SpinnerOptions { /** Whether the destination stream is a TTY. */ isTTY: boolean; /** Master switch — false means no-op (used for --quiet, JSON/SARIF, etc.). */ enabled: boolean; /** Destination stream (default: process.stderr). */ stream?: NodeJS.WriteStream; /** * Whether to emit ANSI color codes. Cursor + clear-line codes are emitted * regardless because they're what makes the spinner visible. Default: * `isTTY && NO_COLOR` is unset. */ color?: boolean; } export interface Spinner { start(label: string): void; update(label: string): void; succeed(label: string): void; fail(label: string): void; stop(): void; } export declare function createSpinner(opts: SpinnerOptions): Spinner;