import type { Component, Focusable, TuiMouseEvent, TuiMouseEventResult } from "@earendil-works/pi-tui"; import type { Theme } from "@earendil-works/pi-coding-agent"; import type { FabricUiWidgetMode } from "../config.js"; import { FabricWidgetRetention } from "./retention.js"; import { type FabricDashboardSnapshot } from "./types.js"; /** A widget row that can be selected and opened. */ export interface FabricWidgetRow { /** * Agent id, actor id for an actor's worker row, the main session's id, a * or the exact shell task id. */ id: string; kind: "main" | "agent" | "actor" | "shell"; name: string; model?: string; } /** Optional interaction wiring; without it the widget stays a passive status box. */ export interface FabricWidgetInteraction { /** Open the participant's full conversation, where it can be read and steered. */ open?: (row: FabricWidgetRow) => void; /** * Return focus to the editor. `forward` is a key the widget does not use; the * editor receives it, because Pi handles Ctrl+C and extension shortcuts there. */ release: (forward?: string) => void; /** Ask the host to redraw (selection changes without a snapshot change). */ requestRender: () => void; /** Called after each render, so the host can check where the widget sits. */ rendered?: () => void; /** Space left after native UI and other extensions; zero temporarily hides the list. */ availableRows?: (width: number) => number | undefined; /** The participant on screen; its row keeps the filled circle. Undefined means the main session. */ viewing?: () => string | undefined; /** The main session's id, which makes the header a row to select, for windows Main is a place to return to. */ mainId?: string; /** False drops the key hints, where the list is the window's only navigation. */ hints?: boolean; /** * With no row to select (no agent, actor worker, or shell task), the widget * draws no lines while this is true: the host shows any session label * elsewhere, on the editor border. */ collapseIdle?: () => boolean; } export declare const shouldShowFabricWidget: (snapshot: FabricDashboardSnapshot, mode: FabricUiWidgetMode, retention?: FabricWidgetRetention) => boolean; /** * Share of the terminal height the animated box may claim. pi's main-screen * renderer scrolls the pane once the rendered content is taller than the * terminal, so a box that fills the viewport keeps that scroll region moving on * every animation frame — which reads as flicker inside tmux. Half the pane * keeps the transcript and editor visible and bounds the box on short panes. */ export declare const WIDGET_TERMINAL_ROW_SHARE = 0.5; /** Effective row budget: the configured maximum, bounded by the live pane. */ export declare const widgetRowLimit: (maxRows: number, terminalRows?: number) => number; /** Keyboard focus must not resize the footer or move the transcript. */ export declare const widgetFocusedRowLimit: (maxRows: number, terminalRows?: number) => number; /** Keep the viewport height fixed, replacing the overflow cue with content at the bottom. */ export declare const widgetViewport: (contentRows: number, budget: number, offset: number) => { windowRows: number; hasCue: boolean; maxOffset: number; offset: number; }; /** Shared by the native footer and participant windows so opening one never resets the list. */ export interface FabricWidgetViewportState { offset: number; } export declare class FabricWidget implements Component, Focusable { #private; readonly theme: Theme; readonly snapshot: () => FabricDashboardSnapshot; readonly maxRows: number; readonly terminalRows?: (() => number | undefined) | undefined; readonly retention: FabricWidgetRetention; readonly interaction?: FabricWidgetInteraction | undefined; readonly viewport: FabricWidgetViewportState; constructor(theme: Theme, snapshot: () => FabricDashboardSnapshot, maxRows: number, terminalRows?: (() => number | undefined) | undefined, retention?: FabricWidgetRetention, interaction?: FabricWidgetInteraction | undefined, viewport?: FabricWidgetViewportState); /** Set by the TUI when the widget gains or loses keyboard focus. */ focused: boolean; /** Select the row on screen, or the first row; used when focus arrives from the keyboard. */ selectDefault(): void; /** Select the top row; ↓ from the editor lands on the row next to it. */ selectFirst(): void; /** True while at least one row can take focus. */ hasRows(): boolean; handleInput(data: string): void; handleMouse(event: TuiMouseEvent): TuiMouseEventResult | undefined; render(width: number): string[]; hasChanged(): boolean; invalidate(): void; } //# sourceMappingURL=widget.d.ts.map