mirror of
https://github.com/siteboon/claudecodeui.git
synced 2026-06-02 18:45:34 +08:00
* fix: preserve WebSocket frame type in plugin proxy The plugin WebSocket proxy relays all messages as binary frames regardless of the original frame type. This causes text-based ready messages to be forwarded as binary, so the browser never processes them and plugin UIs (like web-terminal) show a spinner indefinitely. Pass the isBinary flag through in both relay directions so the original frame type is preserved. Fixes CoderLuii/HolyClaude#11 * fix(plugins): preserve websocket frame type in proxy Ultraworked with [Sisyphus](https://github.com/code-yeongyu/oh-my-openagent) Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai> --------- Co-authored-by: Sisyphus <clio-agent@sisyphuslabs.ai>
66 lines
1.6 KiB
TypeScript
66 lines
1.6 KiB
TypeScript
import { WebSocket } from 'ws';
|
|
|
|
/**
|
|
* Proxies an authenticated client websocket to a plugin websocket endpoint.
|
|
*/
|
|
export function handlePluginWsProxy(
|
|
clientWs: WebSocket,
|
|
pathname: string,
|
|
getPluginPort: (pluginName: string) => number | null
|
|
): void {
|
|
const pluginName = pathname.replace('/plugin-ws/', '');
|
|
if (!pluginName || /[^a-zA-Z0-9_-]/.test(pluginName)) {
|
|
clientWs.close(4400, 'Invalid plugin name');
|
|
return;
|
|
}
|
|
|
|
const port = getPluginPort(pluginName);
|
|
if (!port) {
|
|
clientWs.close(4404, 'Plugin not running');
|
|
return;
|
|
}
|
|
|
|
const upstream = new WebSocket(`ws://127.0.0.1:${port}/ws`);
|
|
|
|
upstream.on('open', () => {
|
|
console.log(`[Plugins] WS proxy connected to "${pluginName}" on port ${port}`);
|
|
});
|
|
|
|
upstream.on('message', (data, isBinary) => {
|
|
if (clientWs.readyState === WebSocket.OPEN) {
|
|
clientWs.send(data, { binary: isBinary });
|
|
}
|
|
});
|
|
|
|
clientWs.on('message', (data, isBinary) => {
|
|
if (upstream.readyState === WebSocket.OPEN) {
|
|
upstream.send(data, { binary: isBinary });
|
|
}
|
|
});
|
|
|
|
upstream.on('close', () => {
|
|
if (clientWs.readyState === WebSocket.OPEN) {
|
|
clientWs.close();
|
|
}
|
|
});
|
|
|
|
clientWs.on('close', () => {
|
|
if (upstream.readyState === WebSocket.OPEN) {
|
|
upstream.close();
|
|
}
|
|
});
|
|
|
|
upstream.on('error', (error) => {
|
|
console.error(`[Plugins] WS proxy error for "${pluginName}":`, error.message);
|
|
if (clientWs.readyState === WebSocket.OPEN) {
|
|
clientWs.close(4502, 'Upstream error');
|
|
}
|
|
});
|
|
|
|
clientWs.on('error', () => {
|
|
if (upstream.readyState === WebSocket.OPEN) {
|
|
upstream.close();
|
|
}
|
|
});
|
|
}
|