
# Architektura

## Przebieg działania

Domyślnie (lokalne tmux + tunel):

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

Tryb bezpośredni sandboxa (Daytona, bez tunelu):

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

Gdy ustawiono `--no-tunnel`, Termbridge pomija Cloudflare i używa podanego przez Ciebie publicznego URL.

## Komponenty

### Proces CLI

- Uruchamia serwer HTTP, który udostępnia zasoby UI.
- Uruchamia serwer WebSocket do komunikacji z terminalem.
- Tworzy jedną lub więcej sesji tmux (lub PTY Daytona).
- Wydaje jednorazowe tokeny dostępu.
- Uruchamia tunel i monitoruje go, gdy jest włączony (obecnie Cloudflare).
- W trybie bezpośrednim sandboxa uruchamia Termbridge wewnątrz sandboxa i czeka na link URL.

### Backend terminala

- **Backend tmux**: używa `node-pty`, aby połączyć się z tmux i obsługiwać rzeczywiste naciśnięcia klawiszy oraz wyjście.
- **Backend Daytona**: używa PTY Daytona wewnątrz sandboxa.
- Ustawia `TERM=xterm-256color` i `COLORTERM=truecolor`, aby zapewnić pełną obsługę kolorów.
- W przypadku tmux wyłącza pasek stanu tmux, aby zachować przejrzystość UI.

### Rejestr terminali

- Śledzi dostępne sesje terminala.
- Udostępnia listę dla UI i sprawdza poprawność wybranych identyfikatorów terminali.

### Uwierzytelnianie i sesja

- Jednorazowy token jest wyświetlany jako URL i zakodowany w kodzie QR.
- `GET /__tb/s/:token` wykorzystuje token i ustawia sesję cookie.
- Połączenia WebSocket wymagają prawidłowego pliku cookie sesji i tokena CSRF.
- Token CSRF jest pobierany przez `GET /__tb/api/csrf` i przekazywany w parametrze zapytania WebSocket.

### Tryb proxy

Po przekazaniu `--proxy <port>`:
- Wszystkie trasy termbridge są dostępne pod prefiksem `/__tb/`
- Żądania niezwiązane z `/__tb/` są przekazywane do aplikacji docelowej przez proxy
- UI udostępnia widoki Terminal/Preview za pomocą przełącznika widoków
- Widok Preview ładuje element iframe wskazujący na `/`
- Połączenia WebSocket HMR są przekazywane do aplikacji docelowej

### Bezpieczeństwo

- **Ochrona CSRF**: aktualizacje połączenia WebSocket wymagają tokena CSRF, aby zapobiec przejęciu połączenia z innej witryny.
- **Limity danych wejściowych**: treść żądania HTTP do 64 KB, wiadomość WebSocket do 1 MB, dane wejściowe terminala do 64 KB na wiadomość.
- **Ograniczanie liczby żądań**: limity na wykorzystanie tokena i połączenia WebSocket dla każdego IP.

## Punkty końcowe API

Wszystkie trasy znajdują się pod prefiksem `/__tb/`, aby uniknąć konfliktów z aplikacjami obsługiwanymi przez proxy:

- `GET /__tb/healthz` — kontrola stanu
- `GET /__tb/s/:token` — wykorzystanie tokena → cookie → przekierowanie
- `GET /__tb/api/terminals` — lista terminali
- `GET /__tb/api/csrf` — pobranie tokena CSRF dla WebSocket
- `GET /__tb/api/config` — pobranie konfiguracji (proxyPort, devProxyUrl)
- `POST /__tb/api/terminals` — utworzenie nowej sesji tmux
- `GET /__tb/app/*` — zapasowa obsługa SPA
- `WS /__tb/ws/terminal/:terminalId?csrf=<token>` — strumieniowanie komunikacji z terminalem

Gdy tryb proxy jest włączony:
- `GET /` — przekierowuje do aplikacji obsługiwanej przez proxy (lub `/__tb/app`, jeśli jest wyłączony)
- `* /*` — przekazywany przez proxy do aplikacji docelowej

## Protokół WebSocket

Klient -> serwer:

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

Serwer -> klient:

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

## Stos UI

- Vite + TanStack Router
- xterm.js + dodatek Fit + renderer WebGL
- Układ z myślą przede wszystkim o urządzeniach mobilnych i ze stałym paskiem wprowadzania
- Automatyczne ponowne łączenie z rosnącymi przerwami (do 10 prób)
- Wskaźnik stanu połączenia
