Архитектура
Общая схема работы
По умолчанию (локальная 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 для WebSocketGET /__tb/api/config— получение конфигурации (proxyPort, devProxyUrl)POST /__tb/api/terminals— создание нового сеанса tmuxGET /__tb/app/*— резервный маршрут SPAWS /__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 попыток)
- Индикатор состояния соединения