
# Arquitectura

## Flujo general

Predeterminado (tmux local + túnel):

```
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):

```
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
