
# Architecture

## Vue d’ensemble du flux

Par défaut (local tmux + tunnel) :

```
Browser (phone)
  |
  | HTTPS
  v
Cloudflare Quick Tunnel
  |
  | HTTP/WS
  v
Local Termbridge server
  |
  | PTY
  v
Tmux session
```

Mode bac à sable direct (Daytona, sans tunnel) :

```
Browser (phone)
  |
  | HTTPS
  v
Daytona preview link
  |
  | HTTP/WS
  v
Termbridge server (sandbox)
  |
  | PTY
  v
Tmux session (sandbox)
```

Lorsque `--no-tunnel` est défini, Termbridge ignore Cloudflare et utilise le URL public que vous avez fourni.

## Composants

### Processus CLI

- Démarre le serveur HTTP qui sert les ressources UI.
- Démarre le serveur WebSocket pour les entrées-sorties du terminal.
- Crée une ou plusieurs sessions tmux (ou des pseudo-terminaux Daytona).
- Émet des jetons à usage unique.
- Démarre et surveille le tunnel lorsqu’il est activé (Cloudflare actuellement).
- En mode bac à sable direct, lance Termbridge dans le bac à sable et attend le URL de partage.

### Backend du terminal

- **Backend tmux** : utilise `node-pty` pour se connecter à tmux et gérer les frappes réelles et la sortie.
- **Backend Daytona** : utilise les pseudo-terminaux Daytona dans un bac à sable.
- Définit `TERM=xterm-256color` et `COLORTERM=truecolor` pour la prise en charge complète des couleurs.
- Pour tmux, désactive la barre d’état tmux afin de garder UI propre.

### Registre des terminaux

- Suit les sessions de terminal disponibles.
- Fournit une liste pour UI et valide les identifiants des terminaux sélectionnés.

### Authentification et session

- Le jeton à usage unique est affiché sous forme de URL et encodé dans un code QR.
- `GET /__tb/s/:token` échange le jeton et crée une session par cookie.
- Les connexions WebSocket nécessitent un cookie de session valide et un jeton CSRF.
- Le jeton CSRF est récupéré via `GET /__tb/api/csrf` et transmis dans le paramètre de requête WebSocket.

### Mode proxy

Lorsque `--proxy <port>` est transmis :
- Toutes les routes termbridge sont sous le préfixe `/__tb/`.
- Les requêtes autres que `/__tb/` sont transmises au proxy de l’application cible.
- UI expose les vues Terminal/Aperçu via le sélecteur de vues.
- La vue Aperçu charge un iframe pointant vers `/`.
- Les connexions WebSocket pour HMR sont transmises à la cible.

### Sécurité

- **Protection CSRF** : les mises à niveau WebSocket exigent un jeton CSRF pour prévenir le détournement intersites.
- **Limites d’entrée** : corps HTTP de 64KB, message WebSocket de 1MB, entrée du terminal de 64KB par message.
- **Limitation du débit** : limites par IP pour l’échange des jetons et les connexions WebSocket.

## Points de terminaison API

Toutes les routes sont sous le préfixe `/__tb/` pour éviter les conflits avec les applications utilisant le proxy :

- `GET /__tb/healthz` - vérification de l’état
- `GET /__tb/s/:token` - échange du jeton → cookie → redirection
- `GET /__tb/api/terminals` - lister les terminaux
- `GET /__tb/api/csrf` - obtenir le jeton CSRF pour WebSocket
- `GET /__tb/api/config` - obtenir la configuration (proxyPort, devProxyUrl)
- `POST /__tb/api/terminals` - créer une nouvelle session tmux
- `GET /__tb/app/*` - solution de repli pour SPA
- `WS /__tb/ws/terminal/:terminalId?csrf=<token>` - flux des entrées-sorties du terminal

Lorsque le mode proxy est activé :
- `GET /` - redirige vers l’application utilisant le proxy (ou `/__tb/app` si désactivé)
- `* /*` - transmis au proxy de l’application cible

## Protocole WebSocket

Client → serveur :

```json
{ "type": "input", "data": "ls -la" }
{ "type": "resize", "cols": 120, "rows": 32 }
{ "type": "control", "key": "ctrl_c" }
```

Serveur → client :

```json
{ "type": "output", "data": "..." }
{ "type": "status", "state": "connected" }
```

## Pile UI

- Vite + TanStack Router
- xterm.js + extension Fit + moteur de rendu WebGL
- Mise en page conçue d’abord pour les mobiles, avec une barre de saisie fixe
- Reconnexion automatique avec délai exponentiel (jusqu’à 10 tentatives)
- Indicateur d’état de connexion
