Saltar al contenido

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-pty para 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-256color y COLORTERM=truecolor para 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/:token canjea 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/csrf y 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 estado
  • GET /__tb/s/:token: canje del token → cookie → redirección
  • GET /__tb/api/terminals: listar terminales
  • GET /__tb/api/csrf: obtener el token CSRF para WebSocket
  • GET /__tb/api/config: obtener la configuración (proxyPort, devProxyUrl)
  • POST /__tb/api/terminals: crear una nueva sesión tmux
  • GET /__tb/app/*: alternativa de SPA
  • WS /__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/app si 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