import { stripAnsi, visualWidth } from "../../stdlib/layout/ansi.js"; import type { Element } from "../../tui/elements.js"; import type { KeyEvent } from "../../tui/input/types.js"; import type { Screen } from "../../tui/screen.js"; import type { LabelingSessionController } from "./controller.js"; import type { SessionAction, SessionSnapshot } from "./session.js"; import type { Fields } from "./types.js"; export { stripAnsi, visualWidth }; /** * Highlight markdown, but fall back to plain text if the render lost content. * * A renderer that silently drops most of a document still produces a screen * that looks plausible, which is the worst possible failure for a tool whose * whole job is showing you what to judge. */ export declare function renderMarkdownSafely(source: string): string; export type ChecklistRender = { lines: string[]; focusLine: number; }; /** The right pane's lines, plus which line the focused question starts on so * the viewport can keep it visible. */ export declare function renderChecklist(snapshot: SessionSnapshot, width: number): ChecklistRender; export type RenderArgs = { snapshot: SessionSnapshot; title: string; width: number; height: number; /** Left-pane scroll position, owned by the loop. */ scroll: number; /** The output body, already highlighted and wrapped to the left pane. */ body: string[]; }; export declare function paneHeightFor(height: number): number; export declare function leftPaneWidthFor(width: number): number; /** * Build the frame as an Element tree. * * Pure, and laid out by the same engine the terminal uses — so a test asserts * on the real frame rather than on a string this module assembled by hand. */ export declare function labelScreen(args: RenderArgs): Element; /** * Translate a keystroke into a domain action. * * Returns null for keys the loop handles itself (scrolling, quitting) or * ignores. Events arrive already parsed by the TUI input layer, which owns * escape-sequence reassembly and bracketed paste. */ export declare function actionForKey(event: KeyEvent, editing: boolean): SessionAction | null; /** Vim-style paging. Cmd+arrow is not bindable — terminals do not transmit the * Cmd modifier. */ export declare function scrollDelta(event: KeyEvent, paneHeight: number): number; export declare function isQuitKey(event: KeyEvent): boolean; export declare function orderFieldNames(fields: Fields): string[]; /** * Every field as one scrollable block: a dim header, then the value. * * Field names come from a charset that cannot express a control character or a * style tag, but the values are arbitrary text from a model, so they go through * `sanitizeUntrusted` before anything else touches them. */ export declare function renderFields(fields: Fields, width: number): string[]; export type RunLabelTuiArgs = { controller: LabelingSessionController; screen: Screen; title?: string; /** Current terminal size, read before every draw. Screen stores its * dimensions, so without this a resize leaves stale pane widths, wrapping * and scroll bounds until restart. */ currentSize?: () => { width: number; height: number; }; }; export declare function runLabelTui(args: RunLabelTuiArgs): Promise;