Match the bot-side hardening
(serge/messenger-bot feat/webchat-auth-hardening): credentials no longer
leak via URL query strings.
* WebSocket handshake uses Sec-WebSocket-Protocol subprotocols
(messenzy.v1, messenzy-bot.<id>, messenzy-visitor.<id>,
messenzy-key.<key>) — the browser WebSocket ctor doesn't accept
custom headers, so subprotocols are the standard pattern.
* HTTP fallback (/webchat/msg, /webchat/history) uses
`Authorization: Bearer <apiKey>` — fetch supports custom headers.
* botId/visitorId stay in body/query as public identifiers; only the
apiKey moves off the URL.
No public API change — `createTransport(opts)` takes the same
TransportOpts as before.