// src/messages/socket.ts // Copyright (C) 2026 Rob Colbert // Licensed under the Apache License, Version 2.0 import { StatusMessage, ProcessWorkOrderMessage, ResponseMessage, ThinkingMessage, ToolCallMessage, WorkOrderCompleteMessage, RequestCrashRecoveryMessage, CrashRecoveryResponseMessage, RequestTerminationMessage, WorkspaceModeChangedMessage, LogMessage, } from "./drone.ts"; import { SessionUpdatedMessage } from "./web.ts"; import { AbortWorkOrderMessage, ReleaseSessionLockMessage, RequestSessionLockMessage, RequestWorkspaceModeMessage, SessionHeartbeatMessage, SubmitPromptMessage, } from "./ide.ts"; /* There are two different kinds of clients that connect to the gadget-code:web Socket.IO server: 1. The gadget-code:ide (ReactJS front-end) 2. The gadget-drone work order runner (NodeJS headless process) gadget-code:ide sends Socket.IO messages to gadget-code:web, which then routes them to the appropriate gadget-drone socket. gadget-drone sends messages to gadget-code:web intending for them to be routed to the appropriate gadget-code:ide socket. This architecture lets the IDE run under User control in any browser anywhere, and serve as a remote control surface for one or more gadget-drone processes running work orders on projects in chat sessions. */ export interface ClientToServerEvents { /* * gadget-code:ide => gadget-code:web */ requestSessionLock: RequestSessionLockMessage; requestWorkspaceMode: RequestWorkspaceModeMessage; submitPrompt: SubmitPromptMessage; abortWorkOrder: AbortWorkOrderMessage; releaseSessionLock: ReleaseSessionLockMessage; sessionHeartbeat: SessionHeartbeatMessage; /* * gadget-drone => gadget-code:web */ log: LogMessage; status: StatusMessage; thinking: ThinkingMessage; response: ResponseMessage; toolCall: ToolCallMessage; workOrderComplete: WorkOrderCompleteMessage; requestCrashRecovery: RequestCrashRecoveryMessage; requestTermination: RequestTerminationMessage; workspaceModeChanged: WorkspaceModeChangedMessage; "agent:thinking": AgentThinkingMessage; "agent:response": AgentResponseMessage; "agent:tool-call": AgentToolCallMessage; "agent:tool-result": AgentToolResultMessage; "agent:complete": AgentCompleteMessage; } export type AgentThinkingMessage = (data: { agentId: string; thinking: string; }) => void; export type AgentResponseMessage = (data: { agentId: string; chunk: string; }) => void; export type AgentToolCallMessage = (data: { agentId: string; tool: string; args: unknown; }) => void; export type AgentToolResultMessage = (data: { agentId: string; tool: string; result: unknown; }) => void; export type AgentCompleteMessage = (data: { agentId: string; response?: string; subagent?: Record; stats?: Record; }) => void; export interface ServerToClientEvents { /* * gadget-code:web => gadget-drone */ requestSessionLock: RequestSessionLockMessage; requestWorkspaceMode: RequestWorkspaceModeMessage; releaseSessionLock: ReleaseSessionLockMessage; sessionHeartbeat: SessionHeartbeatMessage; abortWorkOrder: AbortWorkOrderMessage; processWorkOrder: ProcessWorkOrderMessage; crashRecoveryResponse: CrashRecoveryResponseMessage; requestTermination: RequestTerminationMessage; /* * gadget-code:web => gadget-code:ide */ log: LogMessage; status: StatusMessage; thinking: ThinkingMessage; response: ResponseMessage; toolCall: ToolCallMessage; workOrderComplete: WorkOrderCompleteMessage; workspaceModeChanged: WorkspaceModeChangedMessage; sessionUpdated: SessionUpdatedMessage; tabLockDenied: (data: { message: string }) => void; "agent:thinking": AgentThinkingMessage; "agent:response": AgentResponseMessage; "agent:tool-call": AgentToolCallMessage; "agent:tool-result": AgentToolResultMessage; "agent:complete": AgentCompleteMessage; } export interface SocketData { /* no data defined */ }