
# Architectuur

## Stroom op hoofdlijnen

Standaard (lokale tmux + tunnel):

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

Directe sandboxmodus (Daytona, geen tunnel):

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

Wanneer `--no-tunnel` is ingesteld, slaat Termbridge Cloudflare over en gebruikt het de openbare URL die je hebt opgegeven.

## Componenten

### CLI-proces

- Start de HTTP-server die de assets van UI levert.
- Start de WebSocket-server voor terminal-I/O.
- Maakt een of meer tmux-sessies aan (of Daytona-PTY's).
- Geeft eenmalig inwisselbare tokens uit.
- Start en bewaakt de tunnel wanneer die is ingeschakeld (momenteel Cloudflare).
- In directe sandboxmodus start Termbridge binnen de sandbox en wacht op de share-URL.

### Terminalbackend

- **tmux-backend**: Gebruikt `node-pty` om verbinding te maken met tmux voor echte toetsaanslagen en uitvoer.
- **Daytona-backend**: Gebruikt Daytona-PTY's binnen een sandbox.
- Stelt `TERM=xterm-256color` en `COLORTERM=truecolor` in voor volledige kleurondersteuning.
- Schakelt voor tmux de statusbalk van tmux uit om UI schoon te houden.

### Terminalregister

- Houdt beschikbare terminalsessies bij.
- Biedt een lijst voor de UI en valideert geselecteerde terminal-ID's.

### Verificatie en sessie

- Eenmalige token wordt afgedrukt als URL en gecodeerd in een QR-code.
- `GET /__tb/s/:token` wisselt de token in en stelt een cook iesessie in.
- Voor WebSocket-verbindingen zijn een geldige sessiecookie en CSRF-token vereist.
- De CSRF-token wordt opgehaald via `GET /__tb/api/csrf` en meegegeven als queryparameter van de WebSocket.

### Proxy modus

Wanneer `--proxy <port>` wordt meegegeven:
- Vallen alle termbridge-routes onder de prefix `/__tb/`
- Worden niet-`/__tb/`-requests doorgestuurd naar de doelapp
- Toont UI de weergaven Terminal/Preview via de weergavekiezer
- Laadt de Preview-weergave een iframe dat verwijst naar `/`
- Worden WebSocket-verbindingen voor HMR doorgestuurd naar het doel

### Beveiliging

- **CSRF-bescherming**: Voor WebSocket-upgrades is een CSRF-token vereist om cross-site hijacking te voorkomen.
- **Invoerlimieten**: 64KB HTTP-body, WebSocket-bericht van 1MB, terminalinvoer van 64KB per bericht.
- **Snelheidslimieten**: Limieten per IP voor het inwisselen van tokens en WebSocket-verbindingen.

## API-eindpunten

Alle routes vallen onder de prefix `/__tb/` om conflicten met geproxiede apps te voorkomen:

- `GET /__tb/healthz` - statuscontrole
- `GET /__tb/s/:token` - token inwisselen → cookie → doorsturen
- `GET /__tb/api/terminals` - terminals weergeven
- `GET /__tb/api/csrf` - CSRF-token voor WebSocket ophalen
- `GET /__tb/api/config` - configuratie ophalen (proxyPort, devProxyUrl)
- `POST /__tb/api/terminals` - nieuwe tmux-sessie aanmaken
- `GET /__tb/app/*` - SPA-fallback
- `WS /__tb/ws/terminal/:terminalId?csrf=<token>` - terminal-I/O streamen

Wanneer de proxymodus is ingeschakeld:
- `GET /` - stuurt door naar de geproxiede app (of `/__tb/app` als uitgeschakeld)
- `* /*` - wordt doorgestuurd naar de doelapp

## WebSocket-protocol

Client -> server:

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

Server -> client:

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

## UI-stack

- Vite + TanStack Router
- xterm.js + Fit-addon + WebGL-renderer
- Mobielgerichte lay-out met een vaste invoerbalk
- Automatisch opnieuw verbinden met exponentiële wachttijd (maximaal 10 pogingen)
- Verbindingsstatusindicator
