/** * terminal — the ONE low-level I/O boundary (ADR-0007). Nothing else touches * process.stdout/stdin. Detects capabilities and handles raw mode and the * alternate screen. */ import type { ColorLevel } from '../ansi/index.js'; import type { Disposable } from '../events/index.js'; import type { Size } from '../frame/index.js'; export type { ColorLevel } from '../ansi/index.js'; /** The pair of streams the UI will live on, and how to give them back. */ export interface TerminalStreams { readonly input: NodeJS.ReadStream; readonly output: NodeJS.WriteStream; /** True when the terminal had to be opened outside the inherited fds. */ readonly fromControllingTerminal: boolean; /** Closes whatever we opened; a no-op when these are the standard fds. */ close(): void; } /** * Opens the process's controlling terminal, ignoring the inherited fds. * * `/dev/tty` is the terminal the process is attached to, whatever the caller did * with stdin and stdout. It is the mechanism `fzf`, `less` and `git rebase -i` * use to stay interactive inside a pipe; on Windows, `CONIN$`/`CONOUT$` are the * equivalent. * * Returns null when there is no terminal at all — real CI, a cron job, a * container with no tty — and that is what keeps the headless path working * where it should. */ export declare function openControllingTerminal(): TerminalStreams | null; /** * Where the UI should be drawn. * * The inherited fds come first: when both are already a terminal, there is * nothing to resolve. The rest exists because of `npx` — on POSIX it runs the * binary through a shell and the process's stdin arrives as a pipe, which made * the CLI conclude nobody could answer and fall back to text mode. The terminal * was there the whole time; it was the route to it that had gone missing. */ export declare function resolveTerminalStreams(stdin?: NodeJS.ReadStream, stdout?: NodeJS.WriteStream, openTerminal?: () => TerminalStreams | null): TerminalStreams | null; export interface TerminalCapabilities { readonly colors: ColorLevel; readonly unicode: boolean; readonly mouse: boolean; readonly synchronizedOutput: boolean; readonly isTTY: boolean; } export interface Terminal { readonly caps: TerminalCapabilities; size(): Size; write(bytes: string): void; writeError(bytes: string): void; enterRawMode(): void; exitRawMode(): void; enterAltScreen(): void; exitAltScreen(): void; showCursor(visible: boolean): void; enableMouse(enabled: boolean): void; onResize(cb: (size: Size) => void): Disposable; onData(cb: (bytes: Buffer) => void): Disposable; restore(): void; } export interface TerminalOptions { readonly forceColor?: ColorLevel; readonly stdout?: NodeJS.WriteStream; readonly stdin?: NodeJS.ReadStream; } /** * How many colours this terminal accepts. * * This decides whether the banner's gradient comes out in the theme's exact * tones or quantized — and the answer has to be the same on all three platforms, * or the same CLI has three appearances. `COLORTERM` alone does not give that: * Windows Terminal, VS Code and iTerm all do 24-bit and none of them set it, so * falling through to the `ansi16` at the end would treat them as 1990 terminals. * * The order runs from the most explicit to the most assumed: what the user asked * for (NO_COLOR/FORCE_COLOR), what the terminal declares, who it says it is, and * only then a guess from the platform. */ export declare function detectColorLevel(env: NodeJS.ProcessEnv, isTTY: boolean, force?: ColorLevel, platform?: NodeJS.Platform): ColorLevel; export declare function createTerminal(options?: TerminalOptions): Terminal; //# sourceMappingURL=index.d.ts.map