Arquitectura
Flujo general
Predeterminado (tmux local + túnel):
Código
Browser (phone)
|
| HTTPS
v
Cloudflare Quick Tunnel
|
| HTTP/WS
v
Local Termbridge server
|
| PTY
v
Tmux session
Modo de entorno aislado directo (Daytona, sin túnel):
Código
Browser (phone)
|
| HTTPS
v
Daytona preview link
|
| HTTP/WS
v
Termbridge server (sandbox)
|
| PTY
v
Tmux session (sandbox)
Cuando se establece --no-tunnel, Termbridge omite Cloudflare y usa su URL público proporcionado.
Componentes
Proceso CLI
- Inicia el servidor HTTP que sirve los recursos UI.
- Inicia el servidor WebSocket para la entrada y salida de la terminal.
- Crea una o varias sesiones tmux (o PTY Daytona).
- Emite tokens de canje de un solo uso.
- Inicia y supervisa el túnel cuando está habilitado (actualmente Cloudflare).
- En el modo de entorno aislado directo, inicia Termbridge dentro del entorno aislado y espera el URL compartido.
Backend de terminal
- Backend tmux: Usa
node-ptypara conectarse a tmux y gestionar la entrada real del teclado y la salida. - Backend Daytona: Usa PTY Daytona dentro de un entorno aislado.
- Establece
TERM=xterm-256coloryCOLORTERM=truecolorpara ofrecer compatibilidad completa con colores. - Para tmux, desactiva la barra de estado de tmux para mantener limpia la UI.
Registro de terminales
- Hace seguimiento de las sesiones de terminal disponibles.
- Proporciona una lista para UI y valida los ID de terminal seleccionados.
Autenticación y sesión
- El token de un solo uso se imprime como URL y se codifica en un código QR.
GET /__tb/s/:tokencanjea el token e inicia una sesión con cookie.- Las conexiones WebSocket requieren una cookie de sesión válida y un token CSRF.
- El token CSRF se obtiene mediante
GET /__tb/api/csrfy se pasa como parámetro de consulta de WebSocket.
Modo proxy
Cuando se pasa --proxy <port>:
- Todas las rutas de termbridge están bajo el prefijo
/__tb/ - Las solicitudes que no sean
/__tb/se redirigen mediante proxy a la aplicación de destino - UI muestra las vistas Terminal/Preview mediante el selector Views
- La vista Preview carga un iframe que apunta a
/ - Las conexiones WebSocket para HMR se reenvían al destino
Seguridad
- Protección CSRF: las actualizaciones de WebSocket requieren un token CSRF para evitar el secuestro entre sitios.
- Límites de entrada: cuerpo HTTP de 64KB, mensaje WebSocket de 1MB y entrada de terminal de 64KB por mensaje.
- Limitación de frecuencia: límites por IP para el canje de tokens y las conexiones WebSocket.
Endpoints API
Todas las rutas están bajo el prefijo /__tb/ para evitar conflictos con las aplicaciones a las que se accede mediante proxy:
GET /__tb/healthz: comprobación del estadoGET /__tb/s/:token: canje del token → cookie → redirecciónGET /__tb/api/terminals: listar terminalesGET /__tb/api/csrf: obtener el token CSRF para WebSocketGET /__tb/api/config: obtener la configuración (proxyPort, devProxyUrl)POST /__tb/api/terminals: crear una nueva sesión tmuxGET /__tb/app/*: alternativa de SPAWS /__tb/ws/terminal/:terminalId?csrf=<token>: transmitir la entrada y salida de la terminal
Cuando el modo proxy está habilitado:
GET /: redirige a la aplicación con proxy (o a/__tb/appsi está deshabilitado)* /*: se redirige mediante proxy a la aplicación de destino
Protocolo WebSocket
Cliente -> servidor:
JSON
{ "type": "input", "data": "ls -la" }
{ "type": "resize", "cols": 120, "rows": 32 }
{ "type": "control", "key": "ctrl_c" }
Servidor -> cliente:
JSON
{ "type": "output", "data": "..." }
{ "type": "status", "state": "connected" }
Pila UI
- Vite + TanStack Router
- xterm.js + complemento Fit + renderizador WebGL
- Diseño para móviles con barra de entrada fija
- Reconexión automática con espera exponencial (hasta 10 reintentos)
- Indicador del estado de la conexión