import type { AutocompleteItem, SlashCommand } from '@earendil-works/pi-tui'; import type { BrokerSnapshot, ClientToBroker } from '../../../core/runtime/broker-protocol.js'; /** Everything a slash handler needs: the frame sink, a notice sink, the latest * engine state (for read-only commands like `/session`), and the cwd (for the * default `/export` path). */ export interface SlashContext { /** Send a command frame to the broker (= InputController hooks.onCommand). */ send: (frame: ClientToBroker) => void; /** Surface a transient one-line notice in the viewer. */ notify: (message: string) => void; /** Latest `welcome`/`session_info_changed` state, if the controller fed it. */ state?: BrokerSnapshot['state']; /** cwd for the default `/export` path; defaults to `process.cwd()`. */ cwd?: string; /** True for a REMOTE attach (`crtr surface attach --canvas `). The * native canvas commands that shell a LOCAL `crtr` mutation/read against * `nodeId` (`/promote`, `/resume-node`, `/context`) are meaningless — or * worse, id-colliding — for a remote node id, so `dispatchCanvasCommand` * notifies + no-ops them instead of executing (see `REMOTE_UNSAFE_CANVAS_NAMES` * below). Defaults to `false` so every existing local caller is unaffected. */ remote?: boolean; /** The canvas node this viewer is attached to — used by `/promote` (passed * as `--node`). Falls back to `CRTR_NODE_ID` when absent; if neither is set * `/promote` notifies and no-ops. (Unit Q wires this from `runAttach`.) */ nodeId?: string; /** The attached node's selected profile. `/resume-node` passes it to canvas * browse so the resume page opens within this identity. */ profileId?: string; /** Toggle the in-process GRAPH overlay (the local subscription-tree view). * `/graph` is inherently an in-viewer overlay, not a tmux popup, so this unit * registers `/graph` as a stub that calls this hook. Unit C/Q owns the overlay * itself and populates this; when absent `/graph` notifies it isn't wired yet. */ onGraph?: () => void; /** Detach this viewer (`/quit`). A viewer quit DETACHES — it tears down the * local TUI/socket and leaves the shared engine running. Wired by viewer.ts to * `teardown('detach')`; without it `/quit` cannot actually exit (just sending * `bye` makes the broker drop the socket, which the viewer treats as a dropped * connection and reconnects). */ onQuit?: () => void; /** Copy the last assistant message to the clipboard (`/copy`). Wired by * viewer.ts (it owns the ChatView that holds the text + the clipboard writer). */ onCopy?: () => void; /** OPTIONAL native-picker openers — the InputController fills these from its * read-op request channel. When absent (channel unwired) the value-picker * builtins fall back to the text-arg notice. */ openModelPicker?: () => void; openSessionPicker?: () => void; openForkPicker?: () => void; openTreePicker?: () => void; openSettingsPicker?: () => void; openScopedModelsPicker?: () => void; /** Open the native /login provider selector. */ openLoginPicker?: () => void; /** Open the native /logout provider selector. */ openLogoutPicker?: () => void; /** Open the native /mcp server status panel (viewer-local reads of the * pi-mcp-adapter's config sources + tool cache; connect/auth-start bridge * to the engine). With a server name, act on that server directly instead * of opening the picker. Wired by InputController; absent → notice. */ openMcpPicker?: (serverName?: string) => void; /** `/color` — recolor the editor's name chip (the "bubble" /rename names). * `null` clears back to the default chip. Wired by viewer.ts (it owns the * TitledEditor); absent → only the tmux pane outline is painted. */ onColor?: (color: string | null) => void; /** Open the focused node's progressively disclosed metadata dossier. */ onNodeMetadata?: () => void; } /** Canvas slash-commands — implemented NATIVE in the viewer, the ONLY live host: * the broker binds mode:'rpc', so broker pi-extensions never run their * interactive (mode==='tui') paths. `/promote` triggers a turn after shelling * `crtr node promote`; `/resume-node`, `/view`, `/context` each shell a `crtr` * subcommand via `tmux display-popup` (the viewer runs inside a tmux pane); * `/graph` toggles the in-process overlay. Exported so the editor folds these * into the slash autocomplete list. */ export declare const CANVAS_SLASH_COMMANDS: ReadonlyArray<{ name: string; description: string; }>; /** Every leading-command name this viewer consumes ENTIRELY locally — the * message never reaches the engine as prose, whether dispatched or blocked * with a notice (a remote-unsafe canvas/builtin command still returns * `true` from `dispatchSlashCommand` — swallowed with a notice, never * forwarded as prose — so it counts as consumed here too, independent of * `remote`). Exactly BUILTIN_NAMES ∪ CANVAS_NAMES ∪ SCOPED_OUT — every name * `dispatchSlashCommand` returns `true` for (design: inline memory * references, review Major 6/terminal). Used ONLY for terminal * ref-decoration suppression (`input/titled-editor.ts`); never merged into * command completion, which is `slashCommandList` — a different, * remote-filtered, broker-augmented list. */ export declare function locallyConsumedCommandNames(): ReadonlySet; /** True if `text` is a leading-slash command (vs. a normal prompt). */ export declare function isSlashCommand(text: string): boolean; /** * Parse + dispatch a leading-slash command. Returns `true` if it was handled * (a recognized builtin or a scoped-out notice) — the caller then clears the * editor and sends nothing else. Returns `false` for an UNRECOGNIZED command, * which the caller forwards to the engine as a `prompt` (extension command). */ export declare function dispatchSlashCommand(text: string, ctx: SlashContext): boolean; /** Build slash-command autocomplete entries from the merged command list (the * broker's `get_commands` result, which T7 may inject) — defaults to the * vendored builtins. The native canvas commands are always appended (minus the * remote-unsafe ones when `remote`). Shaped for pi-tui's `CombinedAutocompleteProvider`. */ export declare function slashCommandList(commands?: ReadonlyArray<{ name: string; description?: string; }>, remote?: boolean): SlashCommand[]; /** Same list as flat autocomplete items (value/label/description). */ export declare function commandAutocompleteItems(commands?: ReadonlyArray<{ name: string; description?: string; }>, remote?: boolean): AutocompleteItem[];