Vai al contenuto

Architettura

Flusso generale

Predefinito (locale tmux + tunnel):

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

Modalità sandbox diretta (Daytona, senza tunnel):

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

Quando è impostato --no-tunnel, Termbridge salta Cloudflare e usa il tuo URL pubblico.

Componenti

Processo CLI

  • Avvia il server HTTP che serve le risorse UI.
  • Avvia il server WebSocket per l'I/O del terminale.
  • Crea una o più sessioni tmux (o PTY Daytona).
  • Emette token monouso per il riscatto.
  • Avvia e monitora il tunnel, se abilitato (Cloudflare oggi).
  • In modalità sandbox diretta, avvia Termbridge nella sandbox e attende lo URL di condivisione.

Backend del terminale

  • Backend tmux: usa node-pty per collegarsi a tmux e gestire input da tastiera e output effettivi.
  • Backend Daytona: usa PTY Daytona all'interno di una sandbox.
  • Imposta TERM=xterm-256color e COLORTERM=truecolor per il supporto completo ai colori.
  • Per tmux, disabilita la barra di stato tmux per mantenere pulito UI.

Registro dei terminali

  • Tiene traccia delle sessioni di terminale disponibili.
  • Fornisce un elenco per UI e convalida gli ID dei terminali selezionati.

Autenticazione e sessione

  • Il token monouso viene stampato come URL e codificato in un codice QR.
  • GET /__tb/s/:token riscatta il token e imposta una sessione tramite cookie.
  • Le connessioni WebSocket richiedono un cookie di sessione valido e un token CSRF.
  • Il token CSRF viene recuperato tramite GET /__tb/api/csrf e passato come parametro di query WebSocket.

Modalità proxy

Quando viene passato --proxy <port>:

  • Tutte le route di termbridge si trovano sotto il prefisso /__tb/
  • Le richieste non-/__tb/ vengono inoltrate all'app di destinazione
  • UI mostra le viste Terminale/Anteprima tramite il selettore Viste
  • La vista Anteprima carica un iframe che punta a /
  • Le connessioni WebSocket per HMR vengono inoltrate alla destinazione

Sicurezza

  • Protezione CSRF: gli upgrade WebSocket richiedono un token CSRF per prevenire dirottamenti tra siti.
  • Limiti di input: corpo HTTP da 64KB, messaggi WebSocket da 1MB, input del terminale da 64KB per messaggio.
  • Limitazione della frequenza: limiti per-IP sul riscatto dei token e sulle connessioni WebSocket.

Endpoint API

Tutte le route si trovano sotto il prefisso /__tb/ per evitare conflitti con le app inoltrate:

  • GET /__tb/healthz - controllo dello stato
  • GET /__tb/s/:token - riscatto del token → cookie → reindirizzamento
  • GET /__tb/api/terminals - elenco dei terminali
  • GET /__tb/api/csrf - recupero del token CSRF per WebSocket
  • GET /__tb/api/config - recupero della configurazione (proxyPort, devProxyUrl)
  • POST /__tb/api/terminals - creazione di una nuova sessione tmux
  • GET /__tb/app/* - fallback della SPA
  • WS /__tb/ws/terminal/:terminalId?csrf=<token> - streaming dell'I/O del terminale

Quando la modalità proxy è abilitata:

  • GET / - reindirizza all'app inoltrata (o a /__tb/app se è disabilitata)
  • * /* - inoltrata all'app di destinazione

Protocollo WebSocket

Client -> server:

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

Server -> client:

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

Stack UI

  • Vite + TanStack Router
  • xterm.js + componente aggiuntivo Fit + renderer WebGL
  • Layout pensato prima per i dispositivi mobili, con barra di input fissa
  • Riconnessione automatica con attesa esponenziale (fino a 10 tentativi)
  • Indicatore dello stato della connessione