/** * Reusable TUI utilities — stolen from a Pi dashboard extension and * generalized just enough to drop into other TUI surfaces. * * Six patterns, each self-contained: * 1. gradientText() — per-character truecolor gradient text * 2. hideThemesSection() — find/splice a labeled node from a renderable tree * 3. columns() — two-column layout that gracefully overflows * 4. sanitizeTerminalLabel() — strip OSC/CSI/control escapes from labels * 5. renderedText() — render a child to a throwaway buffer + strip ANSI * 6. createRenderDispatcher()— reassignable render thunk for event-driven redraws * * Pi types are kept honestly; `visibleWidth` / `truncateToWidth` come from * @earendil-works/pi-tui, and the tree-walkers expect a RenderableNode shape * compatible with @earendil-works/pi-coding-agent. */ export interface RenderableNode { children?: RenderableNode[]; invalidate(): void; render(width: number): string[]; } export interface RequestRenderable extends RenderableNode { requestRender(force?: boolean): void; } type Rgb = [number, number, number]; export declare const RESET = "\u001B[0m"; /** Default blue-leaning palette; override per call for a different feel. */ export declare const DEFAULT_PALETTE: Rgb[]; /** * Sample a wrapping gradient at `position` (0..1, wraps modulo 1) across * `palette`. Adjacent stops are linearly interpolated. */ export declare function sampleGradient(position: number, palette?: Rgb[]): Rgb; /** * Render `text` with a per-character gradient. `phase` shifts the gradient * (use a row index * small constant to stagger multi-line art). Spaces are * passed through uncolored so the gradient doesn't waste hues on whitespace. */ export declare function gradientText(text: string, phase: number, palette?: Rgb[]): string; /** Render a node to a throwaway buffer and strip ANSI — see pattern 5. */ export declare function renderedText(node: RenderableNode, width?: number): string; /** * Find the first node whose first non-empty rendered line equals `label` * and splice it out (plus one trailing blank-line sibling if present). * Returns true if something was removed. */ export declare function hideLabeledSection(root: RenderableNode, label: string): boolean; /** * Progressive-poll helper: try removal at [0, 50, 250, 1000] ms. Useful when * the target node is injected asynchronously and you don't control when. * Returns an array of timers (pass to clearHideTimers on teardown). */ export declare function scheduleHideLabeledSection(root: RequestRenderable, label: string, delays?: number[]): Array>; export declare function clearHideTimers(timers: Array>): void; /** * Place `left` and `right` on one line of `width`. If they fit naturally, * pad the gap; if they don't, shrink left to ~45% and right to the * remainder, keeping at least a 1-space gap, and truncate both. */ export declare function columns(left: string, right: string, width: number): string; /** * Strip OSC, CSI, other escape sequences, and C0/C1 control chars from a * label before display. Use on any user-controllable or external string * before rendering it into a TUI — prevents escape injection and layout * breakage. */ export declare function sanitizeTerminalLabel(text: string): string; /** Collapse $HOME to ~ for display. Combined with sanitizeTerminalLabel. */ export declare function formatDirectory(cwd: string): string; /** * Manages a reassignable render thunk so event sources can trigger a * redraw without knowing which surface (header/footer) is currently bound. * * Usage: * const disp = createRenderDispatcher(); * const off = someEvent((v) => { update(v); disp.requestRender(); }); * disp.bind(tui); // point requestRender at tui.requestRender() * disp.unbind(); // tear down (also stops listener if provided) */ export interface RenderDispatcher { requestRender(): void; bind(tui: { requestRender(force?: boolean): void; }): void; unbind(): void; } export declare function createRenderDispatcher(): RenderDispatcher; export {};