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:
- Browser -- the overlay connects via WebSocket to receive annotation updates and respond to context requests.
- Agent -- your coding agent connects via MCP (stdio), which the relay translates to REST API calls internally.
- 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 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
- Connect. The browser overlay opens a WebSocket connection to the relay. The server confirms with a
connectevent containing the timestamp and client count. - Listen. The overlay listens for
annotation:created,annotation:updated, andmanifest:updatedevents to keep its UI in sync. - Respond. When a
context:requestarrives, the overlay's runtime service looks up the element by itsdata-dsID, captures its context, and sends acontext:responseback. - 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:updatedwith 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.
Related
- Code to UI -- uses
context:request/context:responseto let agents query live state - UI to Code -- uses
annotation:created/annotation:updatedfor the full annotation workflow - Overlay and Picker -- the consumer of all WebSocket events