# Real-time Feedback

Domscribe uses a WebSocket relay to push live updates between the browser overlay and the agent. When an agent processes an annotation, creates a response, or requests context, the overlay reflects the change immediately -- no polling required.

## Architecture

The Domscribe relay is a localhost Fastify server that bridges three participants:

1. **Browser** -- the overlay connects via WebSocket to receive annotation updates and respond to context requests.
2. **Agent** -- your coding agent connects via MCP (stdio), which the relay translates to REST API calls internally.
3. **Manifest watcher** -- the relay monitors the manifest file for changes and broadcasts updates.

The WebSocket endpoint is available at `/ws` on the relay server.

## WebSocket Events

The relay uses the following event types:

### Connection Events

| Event | Direction | Description |
| --- | --- | --- |
| `connect` | Server to Client | Sent immediately when a client connects. Includes a timestamp and the current client count. |

### Annotation Events

| Event | Direction | Description |
| --- | --- | --- |
| `annotation:created` | Server to Client | A new annotation has been created (e.g., the user submitted a change request from the overlay). |
| `annotation:updated` | Server to Client | An annotation's status or content has changed (e.g., the agent claimed it, responded, or it failed). |

These events are emitted by the annotation service whenever an annotation transitions between statuses (`QUEUED`, `PROCESSING`, `PROCESSED`, `FAILED`, `ARCHIVED`).

### Context Events

| Event | Direction | Description |
| --- | --- | --- |
| `context:request` | Server to Client | The relay needs runtime context from the browser for a specific `data-ds` element ID. Includes a `requestId` and `entryId`. |
| `context:response` | Client to Server | The browser responds with the captured runtime context (props, state, DOM snapshot) for the requested element. Includes the matching `requestId`. |

Context events power the [Code to UI](/content/docs/features/code-to-ui/index.html) feature. When an agent calls `domscribe.query.bySource`, the relay broadcasts a `context:request` to all connected browser clients. The first client that responds with a `context:response` containing the matching `requestId` wins. If no response arrives within the timeout (default 3 seconds), the tool returns the manifest entry without runtime context.

### Manifest Events

| Event | Direction | Description |
| --- | --- | --- |
| `manifest:updated` | Server to Client | The manifest file has been updated (e.g., after an HMR rebuild). The overlay can use this to refresh its knowledge of available elements. |

## Connection Lifecycle

1. **Connect.** The browser overlay opens a WebSocket connection to the relay. The server confirms with a `connect` event containing the timestamp and client count.
2. **Listen.** The overlay listens for `annotation:created`, `annotation:updated`, and `manifest:updated` events to keep its UI in sync.
3. **Respond.** When a `context:request` arrives, the overlay's runtime service looks up the element by its `data-ds` ID, captures its context, and sends a `context:response` back.
4. **Disconnect.** When the browser tab closes or navigates away, the WebSocket connection closes. The relay removes the client from its set. If all clients disconnect, context requests return `null`.

## How the Overlay Uses This

The overlay listens for WebSocket events to provide a live experience:

- **New annotations** (`annotation:created`) appear in the annotation list immediately.
- **Status transitions** (`annotation:updated`) update the annotation's status badge in real time -- you can watch it move from QUEUED to PROCESSING to PROCESSED as the agent works.
- **Agent responses** (`annotation:updated` with response content) are displayed inline in the annotation panel, so you see the agent's output without leaving the browser.
- **Manifest updates** (`manifest:updated`) signal that the element map has changed, allowing the overlay to refresh.
