import { API_URL } from '@@/officer-url.mjs'; import { createSidecarConnector } from '@@/sidecar/connect'; import { startBrowserRelay, stopBrowserRelay, getUserRelayStatus, getUserTargets, getRelayPort } from './relay'; import { registerUserToken, unregisterUserToken, deriveRelayToken } from './relay-auth'; import { BROWSER_SIDECAR_KIND, RELAY_PORT, type BrowserCommand, type BrowserEvent } from './protocol'; // The browser relay, as its own process. // // It was a second `Bun.serve` inside the platform, on its own port, and that is exactly why it was // switched off on 2026-08-13 — "the platform serves one port". A sidecar is the shape that objection // asks for, and it is what this is now. // // Two listeners live here: the extension's WebSocket (RELAY_PORT, fixed — see protocol.ts) and the // registration socket back to the platform, which is how `api/router.ts` asks it anything. type ReplyFn = (msg: BrowserEvent) => void; async function handleCommand(cmd: BrowserCommand, reply: ReplyFn): Promise { try { switch (cmd.type) { case 'ping': return reply({ type: 'pong', id: cmd.id }); case 'relay:status': { const status = getUserRelayStatus(cmd.userId); return reply({ type: 'relay:status', id: cmd.id, ...status }); } case 'relay:targets': return reply({ type: 'relay:targets', id: cmd.id, targets: getUserTargets(cmd.userId) }); case 'relay:token-add': { // Derived here rather than sent over the wire: the key lives in this process, and a token that // crossed the boundary would be a credential in a log the moment anything traced these messages. const token = registerUserToken(cmd.userId, getRelayPort(), cmd.salt); return reply({ type: 'relay:token', id: cmd.id, token, port: getRelayPort() }); } case 'relay:token-remove': { unregisterUserToken(deriveRelayToken(cmd.userId, getRelayPort(), cmd.salt)); return reply({ type: 'relay:ok', id: cmd.id }); } default: return reply({ type: 'error', id: (cmd as { id: string }).id, error: `unknown command` }); } } catch (err) { reply({ type: 'error', id: cmd.id, error: err instanceof Error ? err.message : String(err) }); } } await startBrowserRelay(RELAY_PORT); console.log(`[browser-relay] listening for extensions on ${RELAY_PORT}`); const connection = createSidecarConnector({ apiUrl: `${API_URL}/api/sidecar/register`, name: 'browser-relay', handles: [BROWSER_SIDECAR_KIND], onCommand(cmd, reply) { void handleCommand(cmd as BrowserCommand, reply as ReplyFn); }, }); function shutdown(signal: string) { console.log(`[browser-relay] ${signal} received, closing`); stopBrowserRelay(); connection.destroy(); process.exit(0); } process.on('SIGTERM', () => shutdown('SIGTERM')); process.on('SIGINT', () => shutdown('SIGINT'));