| 96 | } |
| 97 | |
| 98 | const onMessage = (raw: unknown): void => { |
| 99 | const msg = raw && typeof raw === 'object' ? raw as BridgeMessage : null |
| 100 | if (!msg || typeof msg.type !== 'string') return |
| 101 | |
| 102 | if (msg.type === MSG_CONNECT) { |
| 103 | const connectionId = typeof msg.connectionId === 'string' ? msg.connectionId : '' |
| 104 | const sessionId = typeof msg.sessionId === 'string' ? msg.sessionId.slice(0, 64) : '' |
| 105 | if (!connectionId || !sessionId) { |
| 106 | if (connectionId) close(connectionId, 4000, 'session id required') |
| 107 | return |
| 108 | } |
| 109 | if (!svc.pool.get(sessionId)) { |
| 110 | close(connectionId, 4404, 'session not found') |
| 111 | return |
| 112 | } |
| 113 | const socket = new IpcPtySocket(connectionId) |
| 114 | sockets.set(connectionId, socket) |
| 115 | socket.once('close', () => sockets.delete(connectionId)) |
| 116 | const cols = clamp(msg.cols, 80, 1, 1000) |
| 117 | const rows = clamp(msg.rows, 24, 1, 1000) |
| 118 | const since = typeof msg.since === 'number' && Number.isFinite(msg.since) && msg.since >= 0 ? msg.since : undefined |
| 119 | const controllerId = typeof msg.controllerId === 'string' ? msg.controllerId.slice(0, 128) : '' |
| 120 | const controllerKind = typeof msg.controllerKind === 'string' ? msg.controllerKind.slice(0, 32) : 'electron' |
| 121 | const result = svc.pool.attachById( |
| 122 | sessionId, |
| 123 | socket as unknown as WebSocket, |
| 124 | cols, |
| 125 | rows, |
| 126 | since, |
| 127 | controllerId ? { controllerId, controllerKind, takeover: msg.takeover === true } : undefined, |
| 128 | ) |
| 129 | if (!result.ok && result.reason === 'missing') socket.close(4404, 'session not found') |
| 130 | launcherLogger.event('ipc_pty.attached', { connectionId, sessionId, cols, rows }) |
| 131 | console.log(`ipc pty attached: session=${sessionId} connection=${connectionId} size=${cols}x${rows}`) |
| 132 | return |
| 133 | } |
| 134 | |
| 135 | if (msg.type === MSG_CLIENT) { |
| 136 | const socket = sockets.get(typeof msg.connectionId === 'string' ? msg.connectionId : '') |
| 137 | if (!socket) return |
| 138 | socket.receive(msg.data, msg.binary === true) |
| 139 | return |
| 140 | } |
| 141 | |
| 142 | if (msg.type === MSG_CLIENT_CLOSE) { |
| 143 | const socket = sockets.get(typeof msg.connectionId === 'string' ? msg.connectionId : '') |
| 144 | socket?.clientClosed() |
| 145 | } |
| 146 | } |
| 147 | |
| 148 | process.on('message', onMessage) |
| 149 | return { |