/** * @module tui/surfaces/surface-schema * * The declarative TUI surface language — the SAFE description agents emit to * mount workflow interfaces inside the running TUI shell. Agents never write * raw terminal UI code: they produce this schema, it is validated here (on * the gateway before publishing AND in the TUI before mounting), and the * surface renderer maps it onto the built-in component registry. * * Shared by the gateway `surface` tool and the TUI renderer. */ /** Built-in component registry. Generated surfaces may ONLY use these. */ export declare const PANE_TYPES: readonly ["checklist", "task_detail", "markdown", "log_stream", "diff", "text", "table", "sheet", "progress", "stat", "sparkline", "barchart", "steps", "tree", "art", "activity", "linechart", "scatter", "heatmap", "donut", "gauge", "candles", "gantt", "calendar", "timeline", "timer", "chat", "kv", "code", "flashcard", "quiz", "gameboard", "poll", "rating", "player", "pixelgrid", "wordgrid", "cards", "dice", "wheel", "scoreboard", "fireworks", "bigtext", "ticker", "breathing", "rings", "network", "funnel", "receipt", "feed", "contactcard", "keypad", "colorpicker"]; export type TuiPaneType = (typeof PANE_TYPES)[number]; /** * Design presets — the minimalism contract. Every surface declares ONE preset * and the renderer enforces its budgets (pane count, visible lines). Chosen * per workflow so different tasks LOOK different: */ export declare const SURFACE_PRESETS: { /** One centered checklist. Nothing else. Errands, plans, todo flows. */ readonly "zen-list": { readonly maxPanes: 1; readonly paneLines: 10; readonly layout: "single"; }; /** One generous reading panel. Essays, research summaries, briefs. */ readonly document: { readonly maxPanes: 1; readonly paneLines: 18; readonly layout: "single"; }; /** 2-3 slim columns, short lines — kanban feel. Pipelines, stages. */ readonly board: { readonly maxPanes: 3; readonly paneLines: 8; readonly layout: "columns"; }; /** Stat tiles on top + one table/progress body. Numbers-first views. */ readonly dashboard: { readonly maxPanes: 4; readonly paneLines: 8; readonly layout: "tiles"; }; /** One live log + a thin status pane. Deploys, builds, watching. */ readonly monitor: { readonly maxPanes: 2; readonly paneLines: 12; readonly layout: "stack"; }; /** A main diff/document + slim side checklist. Code review, editing. */ readonly review: { readonly maxPanes: 2; readonly paneLines: 14; readonly layout: "main+side"; }; /** Progress bars + a small table. Habits, learning, fitness, goals. */ readonly tracker: { readonly maxPanes: 2; readonly paneLines: 10; readonly layout: "stack"; }; /** ONE tiny pane — the pure-delegation view. The user glances, koi works. */ readonly glance: { readonly maxPanes: 1; readonly paneLines: 6; readonly layout: "single"; }; /** Message list (main) + reading pane (right) — a real mail client. */ readonly inbox: { readonly maxPanes: 3; readonly paneLines: 14; readonly layout: "main+side"; }; /** One conversation: transcript + slim context list. Deep-reading a thread. */ readonly thread: { readonly maxPanes: 2; readonly paneLines: 14; readonly layout: "main+side"; }; /** The draft verbatim + fact checklist. Approve/edit/discard — never auto-send. */ readonly "draft-approval": { readonly maxPanes: 2; readonly paneLines: 12; readonly layout: "main+side"; }; /** Stat tiles + mini-dossier + recent interactions. "Who is X", pre-meeting. */ readonly person: { readonly maxPanes: 3; readonly paneLines: 8; readonly layout: "tiles"; }; /** Stat + people/systems table with status. Team and org views. */ readonly roster: { readonly maxPanes: 2; readonly paneLines: 10; readonly layout: "stack"; }; /** Stat + time|what|where table + prep list. "What's my day". */ readonly day: { readonly maxPanes: 3; readonly paneLines: 8; readonly layout: "stack"; }; /** One checklist column per day. Short-horizon planning. */ readonly agenda: { readonly maxPanes: 3; readonly paneLines: 8; readonly layout: "columns"; }; /** Hero T-minus stat + progress to the date. Launches, deadlines. */ readonly countdown: { readonly maxPanes: 2; readonly paneLines: 6; readonly layout: "stack"; }; /** Milestone checklist + assumptions/risks note. Project kickoff. */ readonly plan: { readonly maxPanes: 2; readonly paneLines: 10; readonly layout: "main+side"; }; /** Plan checklist + live activity stream + log tail. Long-mission cockpit. */ readonly mission: { readonly maxPanes: 3; readonly paneLines: 10; readonly layout: "main+side"; }; /** Sub-koi table (id|task|state) + shared activity stream. Parallel workers. */ readonly "worker-fleet": { readonly maxPanes: 2; readonly paneLines: 10; readonly layout: "stack"; }; /** ONE live activity pane — "watch me do this" narration. */ readonly run: { readonly maxPanes: 1; readonly paneLines: 8; readonly layout: "single"; }; /** Steps gates + diff summary + log. Ship trains. */ readonly release: { readonly maxPanes: 3; readonly paneLines: 8; readonly layout: "stack"; }; /** Log (real err/warn washes) + recovery steps + impact stat. Something broke. */ readonly incident: { readonly maxPanes: 3; readonly paneLines: 8; readonly layout: "stack"; }; /** Stat (battery/disk/load) + progress + log. Device health. */ readonly system: { readonly maxPanes: 3; readonly paneLines: 8; readonly layout: "tiles"; }; /** Options × criteria table + verdict stat. "X vs Y vs Z". */ readonly compare: { readonly maxPanes: 3; readonly paneLines: 8; readonly layout: "stack"; }; /** Steps (process) or tree (structure) + key-insight note. Teach it. */ readonly explainer: { readonly maxPanes: 2; readonly paneLines: 12; readonly layout: "main+side"; }; /** Synthesis document + sources table. Deep research reports. */ readonly research: { readonly maxPanes: 3; readonly paneLines: 10; readonly layout: "stack"; }; /** Options table + score barchart + one numbered action per option. */ readonly decision: { readonly maxPanes: 3; readonly paneLines: 8; readonly layout: "stack"; }; /** One big sheet/table, nothing else. Spreadsheet/CSV answers. */ readonly data: { readonly maxPanes: 1; readonly paneLines: 22; readonly layout: "single"; }; /** Directory tree (main) + contents table (right). A real file browser. */ readonly files: { readonly maxPanes: 2; readonly paneLines: 16; readonly layout: "main+side"; }; /** Hero barchart/sparkline + one-line stat caption. Quantitative answers. */ readonly chart: { readonly maxPanes: 2; readonly paneLines: 8; readonly layout: "stack"; }; /** Balance stats + category barchart + transactions table. Spend questions. */ readonly money: { readonly maxPanes: 3; readonly paneLines: 8; readonly layout: "tiles"; }; /** Checklist with prices + running-total stat. Groceries, purchases. */ readonly shopping: { readonly maxPanes: 2; readonly paneLines: 10; readonly layout: "stack"; }; /** Itinerary steps + confirmations table + note. Travel. */ readonly trip: { readonly maxPanes: 3; readonly paneLines: 8; readonly layout: "stack"; }; /** Ingredients checklist + method steps. Cooking along. */ readonly recipe: { readonly maxPanes: 2; readonly paneLines: 12; readonly layout: "main+side"; }; /** Progress bars + trend sparkline. Long-horizon goals. */ readonly goal: { readonly maxPanes: 2; readonly paneLines: 10; readonly layout: "stack"; }; /** One table of knobs, rows match-clickable. Koi-rendered option pickers. */ readonly settings: { readonly maxPanes: 1; readonly paneLines: 14; readonly layout: "single"; }; /** Steps progress + one question with numbered choices. Onboarding flows. */ readonly wizard: { readonly maxPanes: 2; readonly paneLines: 10; readonly layout: "stack"; }; /** Saved surfaces/presets table + preview actions. Browsing the library. */ readonly library: { readonly maxPanes: 2; readonly paneLines: 12; readonly layout: "stack"; }; /** Art pane (ASCII QR) + steps. Channel logins and pairing. */ readonly connect: { readonly maxPanes: 2; readonly paneLines: 12; readonly layout: "main+side"; }; }; export type TuiSurfacePreset = keyof typeof SURFACE_PRESETS; export declare const PANE_REGIONS: readonly ["left", "main", "right", "bottom"]; export type TuiPaneRegion = (typeof PANE_REGIONS)[number]; export interface TuiPane { id: string; type: TuiPaneType; title: string; /** File path RELATIVE to the surface root (no absolute paths, no `..`). */ source?: string; /** Inline content for type "text". */ text?: string; region: TuiPaneRegion; /** Section icon glyph (emoji/unicode, ≤4 chars) shown before the title. */ icon?: string; /** Section color override — any hex ("#7ee787") or accent name. */ color?: string; /** Workers may live-update this pane (update_pane); others are controller-owned. */ workerWritable?: boolean; /** * LIVE pane: re-check the source this often (ms, 100-600000). A background * job appending/rewriting the source file becomes a living view — tickers, * progress, game frames — at up to ~10 updates a second. */ refreshMs?: number; } export interface TuiAction { id: string; label: string; /** Single key a-z0-9 (lowercase). Routed, never executed: pressing it injects * `message` into the chat session for the orchestrator koi to act on. */ shortcut: string; message: string; /** * Makes pane CONTENT interactive: any rendered line containing this text * (case-insensitive) becomes hoverable + clickable and fires this action. * This is how a surface turns list rows, menu entries, email subjects, * table rows, or "next page" markers into real clickable elements. */ match?: string; } export declare const NAMED_ACCENTS: Record; /** "#rgb"/"#rrggbb" or a named accent → normalized "#rrggbb"; null = invalid. */ export declare function normalizeColor(value: string | undefined): string | null; export declare const SURFACE_SIZES: readonly ["compact", "normal", "full", "fill"]; export type TuiSurfaceSize = (typeof SURFACE_SIZES)[number]; export interface TuiSurface { version: 1; surfaceId: string; title: string; /** Absolute directory pane sources resolve under (usually the mission project root). */ root: string; /** Ask the TUI to open the surface as soon as it arrives. */ autoMount?: boolean; /** * Screen appetite. "compact" = a few lines (user is mostly chatting), * "normal" = balanced (~40%), "full" = most of the screen (dense review * work), "fill" = the WHOLE terminal: chat steps aside, the surface becomes * the screen, only the text box (and its status line) stays put. * The panel always shrinks to fit content — size is the CEILING — except * "fill", which pads to claim the full height like a real app. */ size?: TuiSurfaceSize; /** Design preset (minimalism contract) — layout + hard budgets. */ preset?: TuiSurfacePreset; panes: TuiPane[]; actions: TuiAction[]; /** * Visual identity: the card's accent — ANY color. A name ("blue" "green" * "amber" "rose" "violet" "cyan" "teal" "orange" "lime" "magenta") or any * hex like "#ff6b35". Pick per SUBJECT so a transformers lesson, an inbox, * and a deploy monitor don't all look the same. Drives the title band, * edge, hairlines, bars, and buttons. */ accent?: string; /** Title-bar icon glyph (emoji or unicode, ≤4 chars). Default ⛩. */ icon?: string; /** * DEPTH ON CLICK: pre-loaded drill-downs. Key = text that appears in a * rendered row (matched case-insensitively, like action.match); value = * the detail shown INSTANTLY in a local panel when that row is clicked — * the full message behind a subject line, the numbers behind a stat, the * definition behind a term. No model round-trip, no waiting. */ details?: Record; } /** Keys the shell reserves for navigation — generated shortcuts may not take them. */ export declare const RESERVED_KEYS: Set; /** * Validate an untrusted surface description. Returns the list of problems — * empty means safe to publish/mount. Enforces: registry-only components, * relative traversal-free sources, single-key non-reserved non-conflicting * shortcuts, chat-routed actions only (no commands), sane sizes. */ export declare function surfaceProblems(raw: unknown): string[]; /** * AUTO-REPAIR before validation — the forgiving publisher. Validation * ping-pong was the #1 latency source for staged replies (a blocked `set` * costs a full extra model round-trip), so everything mechanically fixable * is fixed here and reported as warnings; only genuinely unsafe or * unrenderable input still reaches surfaceProblems and blocks. */ export declare function repairSurface(raw: TuiSurface): { surface: TuiSurface; warnings: string[]; }; /** Strip every control/escape character from untrusted pane content (§ terminal-safe sandboxing). */ export declare function sanitizeContent(text: string): string;