/** * Self-contained progress reporting for the role download/install pipeline. * * Wraps a fetch ReadableStream byte counter (the consumer passes per-chunk * `update({ received, total })`) and renders either an animated determinate * bar (when `total` is known) or an indeterminate spinner (when it is not). * * The output sink (`write`) and the clock (`now`) are injected so the module * can be unit-tested without a real TTY. Rendering degrades to plain, * throttled line-based logging when the destination is not interactive * (no TTY, CI, TERM=dumb) or `noProgress` is passed, and ANSI color is * suppressed whenever `NO_COLOR` is set. * * No new dependency — reuses `format.ts` bar/ANSI helpers and * `display-helpers.ts` `formatDuration`. * * @module */ /** Named phases of the download → install pipeline. */ export type Phase = "resolving" | "downloading" | "verifying" | "extracting" | "installing" | "done"; /** Progress state consumed by {@link DownloadProgress.update}. */ export interface ProgressState { /** Bytes read so far. */ received: number; /** Total bytes expected; 0 (or absent) means unknown → indeterminate. */ total: number; } /** Failure payload for {@link DownloadProgress.phaseFail}. */ export interface FailureInfo { /** The asset that failed, e.g. `acme/architect@2.0.0`. */ asset: string; /** Human-readable reason for the failure. */ reason: string; /** Current retry attempt (1-based). */ attempt: number; /** Total number of retry attempts. */ maxAttempts: number; } export interface DownloadProgressOptions { /** Output sink. Defaults to `process.stdout.write`. */ write?: (chunk: string) => void; /** Clock in ms. Defaults to `Date.now`. */ now?: () => number; /** Whether stdout is a TTY. Defaults to `process.stdout.isTTY`. */ isTTY?: boolean; /** Environment snapshot. Defaults to `process.env`. */ env?: Record; /** Force plain-line degraded mode even on a TTY. */ noProgress?: boolean; /** Suppress all non-error output. */ quiet?: boolean; /** Emit additional per-phase detail. */ verbose?: boolean; } /** Spinner frames for indeterminate mode (audit-suggested `│/─\`). */ export declare const SPINNER_FRAMES: readonly ["│", "/", "─", "\\"]; /** * Format a byte count with binary units, e.g. `1.2MB`, `850KB`, `512B`. * * One-line delegation to the canonical `formatBytes`. Every finite, * non-negative value renders exactly as before; non-finite input now renders * the invalid sentinel `?` instead of `NaNB` / `InfinityB`. */ export declare function formatBytes(n: number): string; /** Format a transfer rate in bytes/second, e.g. `850KB/s`. */ export declare function formatRate(bytesPerSec: number): string; export declare class DownloadProgress { private readonly write; private readonly now; private readonly isTTY; private readonly env; private readonly noProgress; private readonly quiet; private readonly verbose; private readonly degraded; private readonly useColor; private startMs; private downloadStartMs; private lastReceived; private lastLogMs; private lastMilestone; private spinnerIndex; private progressActive; private progressPhase; private progressDetail; constructor(opts?: DownloadProgressOptions); /** Emit the start line for a phase. */ phaseStart(phase: Phase, detail?: string): void; /** Emit the completion status line for a phase. */ phaseComplete(phase: Phase, detail?: string): void; /** * Emit failure rendering for a phase: the failed asset, the reason, and * (when retrying) the attempt N/M. Always shown, even in quiet mode. */ phaseFail(phase: Phase, failure: FailureInfo): void; /** * Consume a byte-count progress sample. In interactive determinate mode * this redraws a single line in place; in indeterminate mode it advances * the spinner. In degraded mode it throttles to plain periodic lines. */ update(state: ProgressState): void; private phaseLine; private renderInteractive; private updateDegraded; private crossedMilestone; private averageRate; private arrow; private writeLine; private verboseLine; /** Terminate an in-flight `\r`-redrawn progress line with a newline. */ private endProgressLine; } //# sourceMappingURL=download-progress.d.ts.map