// Based on OpenClaw Browser Extension Relay (MIT License) // https://github.com/nicepkg/openclaw function hasCdpVersionShape(data) { return !!data && typeof data === 'object' && 'Browser' in data && 'Protocol-Version' in data } export function classifyRelayCheckResponse(res, host, port) { if (!res) { return { action: 'throw', error: 'No response from service worker' } } if (res.status === 401) { return { action: 'status', kind: 'error', message: 'Relay token rejected. Check token and save again.' } } if (res.error) { return { action: 'throw', error: res.error } } if (!res.ok) { return { action: 'throw', error: `HTTP ${res.status}` } } const contentType = String(res.contentType || '') if (!contentType.includes('application/json')) { return { action: 'status', kind: 'error', message: `Wrong endpoint: expected Officer browser relay at this address.`, } } if (!hasCdpVersionShape(res.json)) { const browser = res.json?.Browser ?? '' if (browser && !browser.startsWith('Officer/')) { return { action: 'status', kind: 'error', message: `Wrong relay: found "${browser}" instead of Officer/browser-relay.`, } } return { action: 'status', kind: 'error', message: `Wrong endpoint: expected relay /json/version response.`, } } return { action: 'status', kind: 'ok', message: `Relay reachable and authenticated at http://${host}:${port}/` } } export function classifyRelayCheckException(err, host, port) { const message = String(err || '').toLowerCase() if (message.includes('json') || message.includes('syntax')) { return { kind: 'error', message: `Wrong endpoint: this is not a relay endpoint.`, } } return { kind: 'error', message: `Relay not reachable at http://${host}:${port}/. Verify the server address and relay token.`, } }