
# Архитектура

## Общая схема работы

По умолчанию (локальная tmux + туннель):

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

Прямой режим песочницы (Daytona, без туннеля):

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

Если задана `--no-tunnel`, Termbridge пропускает Cloudflare и использует указанный вами публичный URL.

## Компоненты

### Процесс CLI

- Запускает сервер HTTP, который обслуживает ресурсы UI.
- Запускает сервер WebSocket для ввода-вывода терминала.
- Создает один или несколько сеансов tmux (или PTY Daytona).
- Выдает одноразовые токены для входа.
- Запускает туннель и следит за ним, если он включен (сейчас Cloudflare).
- В прямом режиме песочницы запускает Termbridge внутри песочницы и ожидает общий ресурс URL.

### Серверная часть терминала

- **Серверная часть tmux**: использует `node-pty` для подключения к tmux и передачи реального ввода с клавиатуры и вывода.
- **Серверная часть Daytona**: использует PTY Daytona внутри песочницы.
- Устанавливает `TERM=xterm-256color` и `COLORTERM=truecolor` для полной поддержки цвета.
- Для tmux отключает строку состояния tmux, чтобы интерфейс UI оставался чистым.

### Реестр терминалов

- Отслеживает доступные сеансы терминала.
- Предоставляет список для UI и проверяет выбранные идентификаторы терминалов.

### Аутентификация и сеанс

- Одноразовый токен выводится в виде URL и кодируется в коде QR.
- `GET /__tb/s/:token` принимает токен и устанавливает сеанс cookie.
- Для соединений WebSocket требуются действительные cookie сеанса и токен CSRF.
- Токен CSRF запрашивается через `GET /__tb/api/csrf` и передается в параметре запроса WebSocket.

### Режим прокси

При передаче `--proxy <port>`:
- Все маршруты termbridge находятся в префиксе `/__tb/`
- Запросы, не относящиеся к `/__tb/`, проксируются к целевому приложению
- UI открывает представления Terminal/Preview через переключатель Views
- В представлении Preview загружается iframe, указывающий на `/`
- Соединения WebSocket для HMR перенаправляются к целевому приложению

### Безопасность

- **Защита CSRF**: для обновления соединений WebSocket требуется токен CSRF, предотвращающий межсайтовый перехват.
- **Ограничения ввода**: тело HTTP размером 64KB, сообщение WebSocket размером 1MB, ввод в терминал размером 64KB на сообщение.
- **Ограничение частоты запросов**: лимиты для каждого IP при погашении токенов и подключении WebSocket.

## Конечные точки API

Все маршруты находятся в префиксе `/__tb/`, чтобы избежать конфликтов с проксируемыми приложениями:

- `GET /__tb/healthz` — проверка работоспособности
- `GET /__tb/s/:token` — погашение токена → cookie → перенаправление
- `GET /__tb/api/terminals` — список терминалов
- `GET /__tb/api/csrf` — получение токена CSRF для WebSocket
- `GET /__tb/api/config` — получение конфигурации (proxyPort, devProxyUrl)
- `POST /__tb/api/terminals` — создание нового сеанса tmux
- `GET /__tb/app/*` — резервный маршрут SPA
- `WS /__tb/ws/terminal/:terminalId?csrf=<token>` — потоковая передача ввода-вывода терминала

Когда включен режим прокси:
- `GET /` — перенаправляет в проксируемое приложение (или `/__tb/app`, если отключено)
- `* /*` — проксируется к целевому приложению

## Протокол WebSocket

Клиент → сервер:

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

Сервер → клиент:

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

## Стек UI

- Vite + TanStack Router
- xterm.js + дополнение Fit + рендерер WebGL
- Интерфейс с приоритетом для мобильных устройств и закрепленной панелью ввода
- Автоматическое переподключение с экспоненциальным увеличением интервала (до 10 попыток)
- Индикатор состояния соединения
