@@ -101,20 +101,20 @@ interface Message {
101101
102102#### Proxy → Device Messages
103103
104- | Event | Payload | Description |
105- | -------------- | ------------------------------------------ | --------------------------------------------- |
106- | ` getPages ` | _ (none)_ | Request current page list. Sent periodically. |
107- | ` connect ` | ` { pageId: string } ` | Prepare for debugger connection to page. |
108- | ` disconnect ` | ` { pageId: string } ` | Terminate debugger session for page. |
109- | ` wrappedEvent ` | ` { pageId: string, wrappedEvent: string } ` | Forward CDP message (JSON string) to page. |
104+ | Event | Payload | Description |
105+ | -------------- | ------------------------------------------------------------- | --------------------------------------------- |
106+ | ` getPages ` | _ (none)_ | Request current page list. Sent periodically. |
107+ | ` connect ` | ` { pageId: string, sessionId: string } ` | Prepare for debugger connection to page. |
108+ | ` disconnect ` | ` { pageId: string, sessionId: string } ` | Terminate debugger session for page. |
109+ | ` wrappedEvent ` | ` { pageId: string, sessionId: string, wrappedEvent: string } ` | Forward CDP message (JSON string) to page. |
110110
111111#### Device → Proxy Messages
112112
113- | Event | Payload | Description |
114- | -------------- | ------------------------------------------ | ----------------------------------------------------- |
115- | ` getPages ` | ` Page[] ` | Current list of inspectable pages. |
116- | ` disconnect ` | ` { pageId: string } ` | Notify that page disconnected or rejected connection. |
117- | ` wrappedEvent ` | ` { pageId: string, wrappedEvent: string } ` | Forward CDP message (JSON string) from page. |
113+ | Event | Payload | Description |
114+ | -------------- | -------------------------------------------------------------- | ----------------------------------------------------- |
115+ | ` getPages ` | ` Page[] ` | Current list of inspectable pages. |
116+ | ` disconnect ` | ` { pageId: string, sessionId?: string } ` | Notify that page disconnected or rejected connection. |
117+ | ` wrappedEvent ` | ` { pageId: string, sessionId?: string, wrappedEvent: string } ` | Forward CDP message (JSON string) from page. |
118118
119119#### Page Object
120120
@@ -128,10 +128,14 @@ interface Page {
128128 nativePageReloads? : boolean ; // Target keeps the socket open across reloads
129129 nativeSourceCodeFetching? : boolean ; // Target supports Network.loadNetworkResource
130130 prefersFuseboxFrontend? : boolean ; // Target is designed for React Native DevTools
131+ supportsMultipleDebuggers? : boolean ; // Supports concurrent debugger sessions
131132 };
132133}
133134```
134135
136+ ** Note** : The value of ` supportsMultipleDebuggers ` SHOULD be consistent across
137+ all pages for a given device.
138+
135139### Connection Lifecycle
136140
137141** Device Registration:**
@@ -155,16 +159,18 @@ Debugger Proxy Device
155159 │ │ │
156160 │── WS Connect ───▶│ │
157161 │ ?device&page │── connect ────────────────▶│
158- │ │ {pageId} │
162+ │ │ {pageId, sessionId} │
159163 │ │ │
160164 │── CDP Request ──▶│── wrappedEvent ───────────▶│
161- │ │ {pageId, wrappedEvent} │
165+ │ │ {pageId, sessionId, │
166+ │ │ wrappedEvent} │
162167 │ │ │
163168 │ │◀── wrappedEvent ───────────│
164- │◀── CDP Response ─│ {pageId, wrappedEvent} │
169+ │◀── CDP Response ─│ {pageId, sessionId, │
170+ │ │ wrappedEvent} │
165171 │ │ │
166172 │── WS Close ─────▶│── disconnect ─────────────▶│
167- │ │ {pageId} │
173+ │ │ {pageId, sessionId} │
168174```
169175
170176** Connection Rejection:**
@@ -174,12 +180,34 @@ a `disconnect` back to the proxy for that `pageId`.
174180
175181### Connection Semantics
176182
177- 1 . ** One Debugger Per Page** : New debugger connections to an already-connected
178- page disconnect the existing debugger.
183+ #### Multi-Debugger Support
184+
185+ Multiple debuggers can connect simultaneously to the same page when ** both** the
186+ proxy and device support session multiplexing:
187+
188+ 1 . ** Session IDs** : The proxy assigns a unique, non-empty ` sessionId ` to each
189+ debugger connection. All messages include this ` sessionId ` for routing. This
190+ SHOULD be a UUID or other suitably unique and ephemeral identifier.
191+
192+ 2 . ** Capability Detection** : Devices report ` supportsMultipleDebuggers: true ` in
193+ their page capabilities to indicate session support.
194+
195+ 3 . ** Backwards Compatibility** : Legacy devices ignore ` sessionId ` fields in
196+ incoming messages and don't include them in responses.
197+
198+ #### Connection Rules
199+
200+ 1 . ** Session-Capable Device** : Multiple debuggers can connect to the same page
201+ simultaneously. Each connection has an independent session.
202+
203+ 2 . ** Legacy Device (no ` supportsMultipleDebuggers ` )** : New debugger connections
204+ to an already-connected page disconnect the existing debugger. The proxy MUST
205+ NOT allow multiple debuggers to connect to the same page.
179206
180- 2 . ** Device Reconnection** : If a device reconnects with the same ` device ` ID,
207+ 3 . ** Device Reconnection** : If a device reconnects with the same ` device ` ID
208+ while debugger connections to the same logical device are open in the proxy,
181209 the proxy may attempt to preserve active debugger sessions by forwarding them
182- to the new device connection .
210+ to the new device.
183211
184212### WebSocket Close Reasons
185213
0 commit comments