import type { CallbackActivity } from "../../core/callback-activity.ts"; import type { UIPromptEndEvent, UIPromptStartEvent } from "../../core/extensions/agent-events.ts"; import type { HostInputFormField, HostSessionPickerRow, WidgetScrollRequest, WidgetScrollState } from "../../core/extensions/ui-types.js"; import type { WorkflowActivityFrame } from "../../core/extensions/workflow-events.js"; import type { KeyId } from "../../core/keybindings.ts"; /** * Version 4 separates minimal session binding from optional resource readiness. * A host must not submit a prompt until the matching engine generation reports * `engine_resources_ready`. */ export declare const INTERACTIVE_ENGINE_PROTOCOL_VERSION = 4; export interface JsonObject { [key: string]: JsonValue; } export type JsonValue = boolean | JsonObject | JsonValue[] | null | number | string; export interface SerializableOverlayOptions { anchor?: string; col?: number | string; margin?: number | { top?: number; right?: number; bottom?: number; left?: number; }; maxHeight?: number | string; maxWidth?: number | string; minHeight?: number; minWidth?: number; offsetX?: number; offsetY?: number; row?: number | string; width?: number | string; } /** * Allowlisted terminal-mode control a remote custom component may ask the host * to apply to the real host TTY. Deliberately NOT a raw byte channel: the child * names an intent and the host owns the concrete escape sequence, so a buggy or * compromised child can only toggle this documented mode. */ export type EngineTerminalControl = { kind: "autowrap"; enabled: boolean; }; export interface EngineExtensionShortcut { key: string; description?: string; /** Editor-owned input exclusions resolved in the engine and matched by the host. */ editorKeys?: KeyId[]; } export type SerializableKeybindingsConfig = Record; export interface EngineKeybindingState { userBindings: SerializableKeybindingsConfig; effectiveBindings: SerializableKeybindingsConfig; shortcuts: EngineExtensionShortcut[]; } export type InteractiveEngineMessage = { type: "engine_ready"; protocolVersion: typeof INTERACTIVE_ENGINE_PROTOCOL_VERSION; pid: number; } | { type: "engine_bound"; } | { type: "engine_project_trust_resolved"; } /** The child recorded `engine_explicit_quit`; it is safe for the host to stop it. */ | { type: "engine_explicit_quit_ack"; } | { type: "engine_resources_ready"; } | { type: "engine_resources_failed"; message: string; } | { type: "engine_keybindings_reloaded"; state: EngineKeybindingState; } /** * The engine retired the session whose extension UI the host mirrors. Sent by the child before the * replacement session binds, on the stream that carries the replacement's `session_start` UI requests, * so the host resets the old UI first and never clears what the new session just set. */ | { type: "engine_extension_ui_reset"; } | { type: "engine_heartbeat"; at: number; } | { type: "engine_activity_started"; activity: CallbackActivity; } | { type: "engine_activity_finished"; activityId: string; } /** Workflow activity the host reports as terminal program status. Roots carry no graph. */ | { type: "engine_workflow_activity"; frame: WorkflowActivityFrame; } | { type: "engine_ui_prompt"; event: UIPromptStartEvent | UIPromptEndEvent; } /** * The child took ownership of a correlated RPC request: it has parsed the * command and is about to run it. Emitted and flushed BEFORE any handler * work, so a later transport failure can be told apart from a send that * never landed. Output is not a substitute: a command can run to completion * with side effects and produce nothing. */ | { type: "engine_request_accepted"; requestId: string; command: string; } | { type: "engine_custom_open"; componentId: string; overlay: boolean; purpose?: "prompt" | "navigation"; deferInlineCustomUiFocus?: boolean; handlesCtrlC?: boolean; handlesInternalUiAction?: boolean; reserveTranscriptRows?: boolean; overlayOptions?: SerializableOverlayOptions; widgetKey?: string; widgetPlacement?: "aboveEditor" | "belowEditor"; widgetScroll?: { maxHeight: number; maxHeightFraction?: number; }; } | { type: "engine_custom_close"; componentId: string; } | { type: "engine_custom_frame"; componentId: string; requestId: number; lines: string[]; scrollRequest?: WidgetScrollRequest; } | { type: "engine_custom_input_result"; componentId: string; requestId: number; handled: boolean; } | { type: "engine_custom_invalidate"; componentId: string; } | { type: "engine_custom_done"; componentId: string; result?: JsonValue; } | { type: "engine_custom_terminal"; componentId: string; control: EngineTerminalControl; } | { type: "engine_custom_copy"; componentId: string; requestId: number; text: string; } | { type: "engine_custom_control"; componentId: string; action: "focus" | "hide" | "show" | "unfocus"; } | { type: "engine_session_picker_open"; componentId: string; sessions: HostSessionPickerRow[]; showRenameHint?: boolean; } | { type: "engine_session_picker_update"; componentId: string; sessions: HostSessionPickerRow[]; } | { type: "engine_session_picker_error"; componentId: string; message: string; } | { type: "engine_session_picker_close"; componentId: string; } | { type: "engine_input_form_open"; componentId: string; title: string; fields: HostInputFormField[]; heading?: string; submitLabel?: string; } | { type: "engine_input_form_close"; componentId: string; }; /** * The host is quitting because the user asked to, not because a signal ended the * process. The child must acknowledge it (`engine_explicit_quit_ack`) before the host * stops it, because stopping closes stdin and sends SIGTERM, which alone cannot tell * an explicit quit from a host shutdown caused by a signal. Kept apart from * `InteractiveEngineCommand` because it addresses the process, not a UI component. */ export interface EngineExplicitQuitCommand { type: "engine_explicit_quit"; } export type InteractiveEngineCommand = { type: "engine_project_trust_start"; componentId: string; kind: "select" | "confirm" | "input"; title: string; } | { type: "engine_project_trust_end"; componentId: string; } | { type: "engine_custom_render"; componentId: string; requestId: number; width: number; rows: number; } | { type: "engine_custom_input"; componentId: string; requestId: number; data: string; } | { type: "engine_custom_copy_result"; componentId: string; requestId: number; error?: string; } | { type: "engine_custom_scroll"; componentId: string; state: WidgetScrollState; } | { type: "engine_custom_dispose"; componentId: string; } | { type: "engine_tool_render"; componentId: string; requestId: number; width: number; toolName: string; toolCallId: string; args: JsonValue; result?: JsonObject; executionStarted: boolean; argsComplete: boolean; isPartial: boolean; expanded: boolean; showImages: boolean; imageWidthCells: number; outputPad?: number; } | { type: "engine_message_render"; componentId: string; requestId: number; width: number; message: JsonObject; expanded: boolean; outputPad: number; } | { type: "engine_render_dispose"; componentId: string; } | { type: "engine_session_picker_select"; componentId: string; path: string; } | { type: "engine_session_picker_cancel"; componentId: string; } | { type: "engine_session_picker_delete"; componentId: string; path: string; } | { type: "engine_input_form_submit"; componentId: string; values: Record; } | { type: "engine_input_form_cancel"; componentId: string; }; export declare function isJsonValue(value: object | boolean | null | number | string): value is JsonValue; export declare function parseInteractiveEngineMessage(line: string): InteractiveEngineMessage | undefined; export declare function parseEngineExplicitQuitCommand(line: string): EngineExplicitQuitCommand | undefined; export declare function parseInteractiveEngineCommand(line: string): InteractiveEngineCommand | undefined; export declare function serializeInteractiveEngineFrame(message: InteractiveEngineMessage | InteractiveEngineCommand | EngineExplicitQuitCommand): string; export declare const serializeInteractiveEngineMessage: typeof serializeInteractiveEngineFrame; //# sourceMappingURL=protocol.d.ts.map