
# Architektura

## Přehled toku

Výchozí režim (místní tmux + tunel):

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

Přímý režim sandboxu (Daytona, bez tunelu):

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

Když je nastaveno `--no-tunnel`, Termbridge přeskočí Cloudflare a použije zadané veřejné URL.

## Komponenty

### Proces CLI

- Spustí server HTTP, který poskytuje prostředky UI.
- Spustí server WebSocket pro vstup a výstup terminálu.
- Vytvoří jednu nebo více relací tmux (nebo PTY Daytona).
- Vydá jednorázové tokeny k uplatnění.
- Pokud je tunel povolen, spustí jej a sleduje (aktuálně Cloudflare).
- V přímém režimu sandboxu spustí uvnitř sandboxu Termbridge a čeká na sdílecí URL.

### Backend terminálu

- **Backend tmux**: Pomocí `node-pty` se připojí k tmux a zpracovává skutečné stisky kláves i výstup.
- **Backend Daytona**: Používá PTY Daytona uvnitř sandboxu.
- Nastaví `TERM=xterm-256color` a `COLORTERM=truecolor` pro plnou podporu barev.
- Pro tmux zakáže stavový řádek tmux, aby UI zůstal přehledný.

### Registr terminálů

- Eviduje dostupné relace terminálu.
- Poskytuje seznam pro UI a ověřuje vybraná ID terminálů.

### Ověřování a relace

- Jednorázový token se vypíše jako URL a zakóduje do kódu QR.
- `GET /__tb/s/:token` uplatní token a nastaví relaci pomocí cookie.
- Připojení WebSocket vyžadují platnou relační cookie a token CSRF.
- Token CSRF se načte přes `GET /__tb/api/csrf` a předá jako parametr dotazu WebSocket.

### Režim proxy

Při předání `--proxy <port>`:
- Všechny trasy termbridge jsou pod prefixem `/__tb/`
- Požadavky nesouvisející s `/__tb/` se předávají cílové aplikaci
- UI zpřístupňuje pohledy Terminál/Náhled pomocí přepínače Pohledy
- Pohled Náhled načítá iframe odkazující na `/`
- Připojení WebSocket pro HMR se předávají cílové aplikaci

### Zabezpečení

- **Ochrana CSRF**: Upgrady WebSocket vyžadují token CSRF, který brání únosům z jiných webů.
- **Omezení vstupu**: Tělo HTTP do 64KB, zpráva WebSocket do 1MB, vstup terminálu do 64KB na zprávu.
- **Omezení četnosti**: Limity pro uplatnění tokenu a připojení WebSocket pro každé IP.

## Koncové body API

Všechny trasy jsou pod prefixem `/__tb/`, aby nekolidovaly s aplikacemi obsluhovanými proxy:

- `GET /__tb/healthz` – kontrola stavu
- `GET /__tb/s/:token` – uplatnění tokenu → cookie → přesměrování
- `GET /__tb/api/terminals` – výpis terminálů
- `GET /__tb/api/csrf` – získání tokenu CSRF pro WebSocket
- `GET /__tb/api/config` – získání konfigurace (proxyPort, devProxyUrl)
- `POST /__tb/api/terminals` – vytvoření nové relace tmux
- `GET /__tb/app/*` – náhradní obsluha SPA
- `WS /__tb/ws/terminal/:terminalId?csrf=<token>` – streamování vstupu a výstupu terminálu

Když je režim proxy povolen:
- `GET /` – přesměruje do aplikace obsluhované proxy (nebo na `/__tb/app`, pokud je vypnutá)
- `* /*` – předává se cílové aplikaci

## Protokol WebSocket

Klient → server:

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

Server → klient:

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

## Zásobník UI

- Vite + TanStack Router
- xterm.js + doplněk Fit + vykreslovací modul WebGL
- Rozložení navržené nejprve pro mobily s pevnou lištou pro zadávání
- Automatické opětovné připojení s exponenciálním prodlužováním prodlevy (až 10 pokusů)
- Indikátor stavu připojení
