# Gadget Code Socket Protocol Reference

This document serves as a "Cheat Sheet" for AI agents and developers working on the Gadget Code real-time messaging system.

## 1. Components & Connections

| Component | Role | Protocol | Auth Method |
|-----------|------|----------|-------------|
| `gadget-code:web` | Hub / Router / Server | Socket.IO Server | N/A |
| `gadget-code:ide` | Frontend Control Surface | Socket.IO Client | JWT Token |
| `gadget-drone` | Worker / AWL Runner | Socket.IO Client | Drone Registration ID |

---

## 2. Event Map Overview

Defined in `packages/api/src/messages/socket.ts`.

### IDE -> Web (Client to Server)
*   `requestSessionLock`: Request to exclusive-lock a drone for a project session.
*   `requestWorkspaceMode`: Request a mode change (Idle, User, Agent).
*   `submitPrompt`: Submit a user prompt for agent processing.

### Drone -> Web (Client to Server)
*   `thinking`: Stream reasoning/thought process text.
*   `response`: Stream natural language response text.
*   `toolCall`: Emit a specific tool execution event with result.
*   `workOrderComplete`: Signal that a prompt processing turn is finished.
*   `requestCrashRecovery`: Inbound from drone on restart if it finds a stalled work order.
*   `requestTermination`: Acknowledgment from drone that termination request was received.

### Web -> Drone (Server to Client)
*   `processWorkOrder`: Command to start processing a specific prompt/turn.
*   `crashRecoveryResponse`: Command to `discard` or `retry` a stalled work order.
*   `requestTermination`: Command to immediately terminate the drone process.

---

## 3. Core Sequences & Routing

### 3.1 Prompt Submission Flow
1.  **IDE** emits `submitPrompt(content)`.
2.  **Web (`CodeSession.ts`)**:
    *   Creates a `ChatTurn` document (status: `processing`).
    *   Finds the target `DroneSession`.
    *   Emits `processWorkOrder` to the **Drone**.
3.  **Drone (`gadget-drone.ts`)**:
    *   Writes a local `.gadget/work-order.json` cache (for crash recovery).
    *   Calls `AgentService.process()`.
    *   Emits streaming events back to **Web**.

### 3.2 Result Streaming Flow
1.  **Drone** emits `thinking(text)`, `response(text)`, or `toolCall(id, name, args, result)`.
2.  **Web (`DroneSession.ts`)**:
    *   Locates the associated `CodeSession` via `SocketService.getCodeSessionByChatSessionId()`.
    *   Updates the `ChatTurn` document in MongoDB incrementally.
    *   Forwards the event to the **IDE**.
3.  **IDE**: Updates the UI in real-time.

### 3.3 Session Termination
1.  **Drone** emits `workOrderComplete(turnId, success, message)`.
2.  **Web (`DroneSession.ts`)**:
    *   Sets `ChatTurn` status to `finished` or `error`.
    *   Forwards event to **IDE**.
    *   Clears `currentTurnId` from the drone session.

### 3.4 Drone Termination Flow
1.  **User** clicks "Terminate" button in Drone Manager UI.
2.  **IDE** calls `POST /api/v1/drone/registration/:id/terminate`.
3.  **Web (`DroneService.ts`)**:
    *   Checks if drone is already offline → returns error if so.
    *   Looks up `DroneSession` via `SocketService.getDroneSession()`.
    *   If drone not connected → marks as offline immediately, returns success.
    *   Emits `requestTermination` to drone socket with callback.
    *   Starts 10-second timeout.
4.  **Web (`DroneSession.ts`)**:
    *   Receives `requestTermination` event.
    *   Logs the termination request.
    *   Forwards `requestTermination` to drone socket (passthrough).
5.  **Drone (`gadget-drone.ts`)**:
    *   Receives `requestTermination` from platform.
    *   Calls callback with `success: true`.
    *   Sends `SIGINT` to self, triggering graceful shutdown.
    *   Updates status to `Offline` during shutdown.
6.  **Web (`DroneService.ts`)**:
    *   Drone accepts termination → polls DB every 500ms waiting for `Offline` status.
    *   Drone goes offline → resolves with success.
    *   Timeout expires (10s) → forces status to `Offline`, resolves with success.

---

## 4. Message Signatures (TS Reference)

### IDE -> Web
```typescript
type RequestSessionLockMessage = (
  registration: IDroneRegistration,
  project: IProject,
  chatSession: IChatSession,
  cb: (success: boolean, chatSessionId: string) => void
) => void;

type SubmitPromptMessage = (prompt: string) => void;
```

### Web -> Drone
```typescript
type ProcessWorkOrderMessage = (
  registration: IDroneRegistration,
  project: IProject,
  chatSession: IChatSession,
  turn: IChatTurn,
  cb: (success: boolean, message?: string) => void
) => void;
type RequestTerminationMessage = (
  cb: (success: boolean) => void
) => void;
```

### Drone -> Web (Streaming)
```typescript
type ThinkingMessage = (content: string) => void;
type ResponseMessage = (content: string) => void;
type ToolCallMessage = (
  callId: string,
  name: string,
  params: string,   // JSON.stringify
  response: string  // JSON.stringify
) => void;
type WorkOrderCompleteMessage = (
  workOrderId: string,
  success: boolean,
  message?: string
) => void;
type RequestTerminationMessage = (
  cb: (success: boolean) => void
) => void;
```

---

## 5. Session Implementation Guide (Web Server)

The web server (`gadget-code:web`) implements two wrapper classes in `src/lib/`:

### `CodeSession.ts`
Manages the IDE socket.
*   **Logic**: Maps User ID -> Socket ID.
*   **Routing**: When an IDE sends a message, `CodeSession` finds the selected drone's `DroneSession` and forwards the command.

### `DroneSession.ts`
Manages the Drone socket.
*   **Logic**: Maps Drone Registration ID -> Socket ID.
*   **Routing**: When a drone streams, `DroneSession` looks up the `chatSessionId` in the `SocketService` index to find the return path to the IDE.
*   **Session Lookup**: `SocketService` maintains a `droneRegistrationIndex` Map that maps `registration._id` → `DroneSession` for efficient lookup by registration ID.

### Session Indexing Architecture

The `SocketService` maintains multiple indexes for efficient session lookup:

1.  **`droneSessions`**: Map<socket.id, DroneSession> - Primary storage by socket ID
2.  **`droneRegistrationIndex`**: Map<registration._id, DroneSession> - Lookup by drone registration
3.  **`codeSessions`**: Map<socket.id, CodeSession> - Primary storage by socket ID
4.  **`codeSessionUserIndex`**: Map<user._id, CodeSession> - Lookup by user ID
5.  **`chatSessionIndex`**: Map<chatSessionId, CodeSession> - Reverse lookup from chat session to IDE

All indexes are kept in sync during connection and disconnection.

---

## 6. Workspace Crash Recovery

1.  **Drone** starts -> checks for `.gadget/work-order.json`.
2.  If found, emits `requestCrashRecovery({ workspaceId, turnId, chatSessionId })`.
3.  **Web (`DroneSession.ts`)**:
    *   Checks DB for `ChatTurn` status.
    *   If turn is already `finished`, responds with `{ action: "discard" }`.
    *   If turn is `processing`, responds with `{ action: "retry" }` and schedules a new `processWorkOrder` after a delay.
4.  **Drone**: Deletes local cache upon receiving any `crashRecoveryResponse`.

---

## 7. Extending the Protocol

To add a new message:
1.  Add the message type to `packages/api/src/messages/ide.ts` or `drone.ts`.
2.  Register it in `ClientToServerEvents` or `ServerToClientEvents` in `packages/api/src/messages/socket.ts`.
3.  Implement the sender (emit) in the Client (`ide` or `drone`).
4.  Implement the handler in the corresponding `CodeSession` or `DroneSession` on the Web server.
5.  Implement the forward-path routing if needed.
