import type { ExtensionContext } from "agent-sh/types"; import type { RenderNode, RenderNodes } from "./renderer.js"; import type { StatusSegment } from "./status-footer.js"; import type { SelectOpts, ConfirmOpts } from "./dialogs.js"; import type { InputOpts } from "./input-prompt.js"; export type { SelectChoice, SelectOpts, ConfirmOpts } from "./dialogs.js"; export type { InputOpts } from "./input-prompt.js"; export type { StatusSegment } from "./status-footer.js"; export type NoticeLevel = "info" | "warn" | "error" | "success"; export interface DiffOpts { before?: string | null; after?: string; filePath?: string; boxed?: boolean; } export interface Contribution { /** Re-pull this surface (call after the content it depends on changes). */ refresh(): void; remove(): void; } /** * Typed sugar over ashi's UI protocol. Wraps the bus events and named handlers so call * sites read like a UI object, with real types and no magic strings — without a `ui` field * on the kernel context. Request/response surfaces degrade when no frontend answers them * (select/input → undefined, confirm → false, getEditorText → ""). */ export interface Ui { notify(message: string, level?: NoticeLevel): void; select(opts: SelectOpts): Promise; confirm(opts: ConfirmOpts): Promise; diff(opts: DiffOpts): (width: number) => string[]; input(opts?: InputOpts): Promise; getEditorText(): string; setEditorText(text: string): void; /** Contribute a status-bar segment. `get` runs on each repaint; return null to show nothing. */ status(get: () => StatusSegment | null): Contribution; /** Contribute a pinned widget above the input, built from the renderer's node factory. */ dock(build: (nodes: RenderNodes) => RenderNode | null): Contribution; } export declare function createUi(ctx: ExtensionContext): Ui;