/** * The chrome every surface that asks the user for something draws. * * All of them — the pickers, the `ask_options` pane, the extension input and * editor, the login dialog — take the prompt editor's place in * `editorContainer`. They used to draw two bare `DynamicBorder` rules instead * of the prompt's box, each with its own idea of whether the title went inside, * whether the hints got a blank line above them, and whether content was inset * at all. So the one surface the eye returns to changed shape whenever the * agent needed an answer, and the `editorBorder` setting moved the prompt * without moving anything that stands in for it. * * One frame, one border style, one place the title goes (into the top border, * flush right, the slot the session chip rides on the prompt) and one place the * hints go (the last row inside, flush above the bottom rule — a blank line * next to a rule is a blank line wasted). */ import { type Component, Frame, type FrameBorderStyle } from "@kolisachint/hoocode-tui"; /** * Not exported from the package: this follows the user's `editorBorder` * setting, and an extension does not get to overrule it. `interactive-mode` is * the one caller. */ export declare function setInputFrameBorder(style: FrameBorderStyle): void; export declare function getInputFrameBorder(): FrameBorderStyle; export interface InputFrameOptions { /** The surface's name. Laid into the top border when it fits there. */ title?: string; /** Columns of gutter inside the side borders. One, as the prompt's is. */ paddingX?: number; } /** * A `Frame` wearing the app's border colour and the current border style. * * The colour is the plain `border` token, not the prompt's: the prompt's border * carries the thinking level and bash mode, and a picker has neither to report. * * The colour, the style and the title are all resolved per frame, so a theme * switch or a `/settings` edit repaints a pane that is already open — a `Text` * holds its string with the escapes already in it, so a title decided once * would keep the colours of the theme it was built under. Re-resolving is * cheap: `setBorder` and `setLabel` both compare before they take, so an * unchanged frame still returns the same array and the renderer goes on * diffing whole regions by identity. */ export declare class InputFrame extends Frame { private hintRow?; /** The title as one line, or "" for none. Where it is drawn is a render-time call. */ private titleText; /** Holds the title when it will not fit in the border. */ private titleRow?; constructor(options?: InputFrameOptions); /** * Name this surface. An empty title draws a plain edge. * * Collapsed to one line first, because the border *is* one line: an * extension's `confirm` passes its question and its detail as one * newline-joined string, and a newline inside a rendered row splits the * border open and throws the renderer's row count out with it. * * Where it ends up is decided per frame in `layOutTitle`, not here — it * depends on the width, which a caller does not know. */ setTitle(title: string): void; /** * Put the title where it fits: in the top border, or — when the border has * no room for a run of rule beside it — on the frame's first row. * * The fallback is what stops a title being lost. `renderFrameEdge` drops a * label it cannot draw, which is right for the session chip (the footer also * names the session) and wrong for a question the user is about to answer * yes or no to. * * Rebuilt every frame rather than at `setTitle`, so a theme switch under an * open pane repaints the title along with everything else: a `Text` holds * its string with the escapes already in it. */ private layOutTitle; /** * The key hints, as the last row inside the frame. * * Owned here rather than added as a child by each caller so it always ends * up in the same place: callers that added it themselves put it above their * own `Spacer(1)` about half the time, which is the wasted row the vertical * rhythm rules name. */ setHint(hint: string): void; /** * Add a row above the hints. * * The hints are the frame's last row by construction, so a pane that sets * them before it finishes building its body still gets them at the bottom — * which is the ordering half the panes got wrong when each added its own. */ addChild(component: Component): void; /** The title row, when there is one, is the frame's first row. */ private unshiftTitleRow; render(width: number): string[]; } //# sourceMappingURL=input-frame.d.ts.map