/** * Public interactive-extension contract for one mounted TUI front door. * * Plugins receive terminal-specific rendering primitives without access to * the live pi-tui tree, focus controller, overlay handles, or terminal * lifecycle. Registrations and open overlays remain owned by the calling * Cordis fiber. * @module @deepseek-ai/dsh-tui/extension */ /** Terminal component shape accepted from a trusted TUI extension. */ export interface TuiComponent { /** * Render this component for the supplied viewport width. * @param width - Available terminal columns. * @returns terminal lines owned by this component. */ render(width: number): string[] /** * Handle one terminal input sequence while this component owns focus. * @param data - Raw terminal input sequence. */ handleInput?(data: string): void /** Receive key-release events instead of having them filtered by the host. */ wantsKeyRelease?: boolean /** Drop cached rendering derived from theme, size, or component state. */ invalidate(): void } /** Optional focus state forwarded by the host to a component. */ export interface TuiFocusable { /** Whether the component currently owns terminal focus. */ focused: boolean } /** Read-only semantic color roles supplied by the mounted TUI. */ export interface TuiTheme { /** Render ordinary foreground text. */ readonly text: (value: string) => string /** Render secondary information. */ readonly muted: (value: string) => string /** Render low-emphasis hints. */ readonly dim: (value: string) => string /** Render the active accent role. */ readonly accent: (value: string) => string /** Render a successful outcome. */ readonly success: (value: string) => string /** Render a warning. */ readonly warning: (value: string) => string /** Render an error. */ readonly error: (value: string) => string /** Apply the host's bold role. */ readonly bold: (value: string) => string } /** Current terminal viewport exposed without the mutable Terminal object. */ export interface TuiViewport { /** Terminal columns. */ readonly columns: number /** Terminal rows. */ readonly rows: number } /** Supported overlay anchor points. */ export type TuiOverlayAnchor = | 'center' | 'top-left' | 'top-right' | 'bottom-left' | 'bottom-right' | 'top-center' | 'bottom-center' | 'left-center' | 'right-center' /** Terminal-edge spacing for an overlay. */ export interface TuiOverlayMargin { /** Rows reserved above the overlay. */ readonly top?: number /** Columns reserved to the right of the overlay. */ readonly right?: number /** Rows reserved below the overlay. */ readonly bottom?: number /** Columns reserved to the left of the overlay. */ readonly left?: number } /** Position and size constraints retained under TUI host ownership. */ export interface TuiOverlayOptions { /** Width in columns or as a percentage of terminal width. */ readonly width?: number | `${number}%` /** Minimum width in columns. */ readonly minWidth?: number /** Maximum height in rows or as a percentage of terminal height. */ readonly maxHeight?: number | `${number}%` /** Overlay anchor; defaults to the terminal center. */ readonly anchor?: TuiOverlayAnchor /** Terminal-edge spacing. */ readonly margin?: number | TuiOverlayMargin } /** Capabilities available while an overlay component is queued or visible. */ export interface TuiOverlayHost { /** * Aborts when the request, caller fiber, overlay session, or TUI closes. * Extension work started for the overlay must cooperate with this signal. */ readonly signal: AbortSignal /** Current viewport; a fresh immutable value is returned on every read. */ readonly viewport: TuiViewport /** Semantic styles that follow terminal color-scheme changes. */ readonly theme: TuiTheme /** * Escape control characters in untrusted display text. * @param value - text crossing into terminal presentation. * @returns a printable representation that cannot emit terminal controls. */ display(value: string): string /** Invalidate the component and schedule one contained terminal redraw. */ invalidate(): void /** Close this overlay normally; repeated calls are no-ops. */ close(): void } /** One effect-owned request to create an interactive overlay. */ export interface TuiOverlayRequest { /** * Construct the component when this request reaches the front of the modal * queue. A throw closes the session with `reason: "error"`. */ readonly create: (host: TuiOverlayHost) => TuiComponent & Partial /** Host-owned position and size constraints. */ readonly options?: TuiOverlayOptions /** Optional request cancellation in addition to caller and TUI ownership. */ readonly signal?: AbortSignal } /** Stable reason an overlay stopped being queued or visible. */ export type TuiOverlayCloseReason = | 'closed' | 'aborted' | 'owner-disposed' | 'tui-disposed' | 'error' /** Settled overlay outcome; component failures retain their original value. */ export type TuiOverlayOutcome = | { readonly reason: Exclude } | { readonly reason: 'error'; readonly error: unknown } /** Live state of an overlay operation. */ export type TuiOverlayState = 'queued' | 'active' | 'closed' /** Handle returned to the extension that opened an overlay. */ export interface TuiOverlaySession { /** Current queue/display state. */ readonly state: TuiOverlayState /** Settles exactly once after the overlay leaves the queue or display. */ readonly closed: Promise /** * Close the overlay normally and await its settled outcome. * @returns the same immutable value exposed through {@link closed}. */ close(): Promise }