Pular para o conteúdo

Arquitetura

Fluxo geral

Padrão (tmux local + túnel):

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

Modo sandbox direto (Daytona, sem túnel):

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

Quando --no-tunnel está definido, Termbridge ignora Cloudflare e usa o URL público fornecido por você.

Componentes

Processo CLI

  • Inicia o servidor HTTP que serve os recursos UI.
  • Inicia o servidor WebSocket para a entrada e saída do terminal.
  • Cria uma ou mais sessões tmux (ou PTYs Daytona).
  • Emite tokens de resgate de uso único.
  • Inicia e monitora o túnel quando habilitado (Cloudflare atualmente).
  • No modo sandbox direto, inicia Termbridge dentro do sandbox e aguarda o URL de compartilhamento.

Backend do terminal

  • Backend tmux: usa node-pty para se conectar a tmux e receber teclas pressionadas e saída.
  • Backend Daytona: usa PTYs Daytona dentro de um sandbox.
  • Define TERM=xterm-256color e COLORTERM=truecolor para dar suporte total a cores.
  • Para tmux, desativa a barra de status tmux para manter o UI limpo.

Registro do terminal

  • Acompanha as sessões de terminal disponíveis.
  • Fornece uma lista para o UI e valida os IDs de terminal selecionados.

Autenticação e sessão

  • O token de uso único é exibido como URL e codificado em um código QR.
  • GET /__tb/s/:token resgata o token e define uma sessão de cookie.
  • As conexões WebSocket exigem um cookie de sessão válido e um token CSRF.
  • O token CSRF é obtido por GET /__tb/api/csrf e enviado como parâmetro de consulta do WebSocket.

Modo proxy

Quando --proxy <port> é passado:

  • Todas as rotas do termbridge ficam sob o prefixo /__tb/
  • As solicitações que não sejam /__tb/ são encaminhadas por proxy ao aplicativo de destino
  • UI expõe as visualizações Terminal/Preview pelo seletor Views
  • A visualização Preview carrega um iframe apontando para /
  • As conexões WebSocket para HMR são encaminhadas ao destino

Segurança

  • Proteção contra CSRF: as atualizações WebSocket exigem um token CSRF para evitar sequestros entre sites.
  • Limites de entrada: corpo HTTP de 64KB, mensagem WebSocket de 1MB e entrada do terminal de 64KB por mensagem.
  • Limitação de taxa: limites por IP para resgate de tokens e conexões WebSocket.

Endpoints API

Todas as rotas ficam sob o prefixo /__tb/ para evitar conflitos com aplicativos encaminhados por proxy:

  • GET /__tb/healthz - verificação de integridade
  • GET /__tb/s/:token - resgate do token → cookie → redirecionamento
  • GET /__tb/api/terminals - listar terminais
  • GET /__tb/api/csrf - obter token CSRF para WebSocket
  • GET /__tb/api/config - obter configuração (proxyPort, devProxyUrl)
  • POST /__tb/api/terminals - criar uma nova sessão tmux
  • GET /__tb/app/* - fallback da SPA
  • WS /__tb/ws/terminal/:terminalId?csrf=<token> - transmitir entrada e saída do terminal

Quando o modo proxy está habilitado:

  • GET / - redireciona para o aplicativo encaminhado por proxy (ou /__tb/app se desabilitado)
  • * /* - encaminhado por proxy ao aplicativo de destino

Protocolo WebSocket

Cliente -> servidor:

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

Servidor -> cliente:

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

Pilha UI

  • Vite + TanStack Router
  • xterm.js + complemento Fit + renderizador WebGL
  • Layout pensado primeiro para dispositivos móveis, com barra de entrada fixa
  • Reconexão automática com espera exponencial (até 10 tentativas)
  • Indicador de status da conexão