Zum Inhalt springen

Architektur

Überblick über den Ablauf

Standard (lokales tmux + Tunnel):

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

Direkter Sandbox-Modus (Daytona, ohne Tunnel):

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

Wenn --no-tunnel gesetzt ist, überspringt Termbridge Cloudflare und verwendet die von dir angegebene öffentliche URL.

Komponenten

CLI-Prozess

  • Startet den HTTP-Server, der die UI-Assets bereitstellt.
  • Startet den WebSocket-Server für die Terminal-Ein- und -Ausgabe.
  • Erstellt eine oder mehrere tmux-Sitzungen (oder Daytona-PTYs).
  • Stellt einmalig verwendbare Einlösetokens aus.
  • Startet und überwacht den Tunnel, sofern aktiviert (derzeit Cloudflare).
  • Startet im direkten Sandbox-Modus Termbridge innerhalb der Sandbox und wartet auf die Freigabe-URL.

Terminal-Backend

  • tmux-Backend: Verwendet node-pty, um sich für echte Tastatureingaben und Ausgaben mit tmux zu verbinden.
  • Daytona-Backend: Verwendet Daytona-PTYs in einer Sandbox.
  • Setzt TERM=xterm-256color und COLORTERM=truecolor für vollständige Farbunterstützung.
  • Deaktiviert für tmux die Statusleiste tmux, damit UI übersichtlich bleibt.

Terminal-Registry

  • Verfolgt verfügbare Terminalsitzungen.
  • Stellt eine Liste für UI bereit und validiert ausgewählte Terminal-IDs.

Authentifizierung und Sitzung

  • Ein einmaliges Token wird als URL ausgegeben und in einem QR-Code codiert.
  • GET /__tb/s/:token löst das Token ein, setzt eine Cookie-Sitzung und leitet weiter.
  • WebSocket-Verbindungen erfordern ein gültiges Sitzungscookie und CSRF-Token.
  • Das CSRF-Token wird über GET /__tb/api/csrf abgerufen und als Query-Parameter im WebSocket übergeben.

Proxy-Modus

Wenn --proxy <port> übergeben wird:

  • Alle termbridge-Routen liegen unter dem Präfix /__tb/.
  • Anfragen, die nicht an /__tb/ gerichtet sind, werden an die Ziel-App weitergeleitet.
  • UI stellt die Ansichten „Terminal“ und „Vorschau“ über die Ansichten-Auswahl bereit.
  • Die Vorschauansicht lädt ein iframe mit Verweis auf /.
  • WebSocket-Verbindungen für HMR werden an das Ziel weitergeleitet.

Sicherheit

  • CSRF-Schutz: Für WebSocket-Upgrades ist ein CSRF-Token erforderlich, um siteübergreifende Übernahmen zu verhindern.
  • Eingabelimits: 64 KB im HTTP-Body, 1 MB pro WebSocket-Nachricht und 64 KB Terminaleingabe pro Nachricht.
  • Ratenbegrenzung: Limits pro IP für das Einlösen von Tokens und WebSocket-Verbindungen.

API-Endpunkte

Alle Routen liegen unter dem Präfix /__tb/, um Konflikte mit weitergeleiteten Apps zu vermeiden:

  • GET /__tb/healthz – Zustandsprüfung
  • GET /__tb/s/:token – Token einlösen → Cookie → Weiterleitung
  • GET /__tb/api/terminals – Terminals auflisten
  • GET /__tb/api/csrf – CSRF-Token für WebSocket abrufen
  • GET /__tb/api/config – Konfiguration abrufen (proxyPort, devProxyUrl)
  • POST /__tb/api/terminals – Neue tmux-Sitzung erstellen
  • GET /__tb/app/* – SPA-Fallback
  • WS /__tb/ws/terminal/:terminalId?csrf=<token> – Terminal-Ein- und -Ausgabe streamen

Wenn der Proxy-Modus aktiviert ist:

  • GET / – Leitet zur weitergeleiteten App um (oder zu /__tb/app, falls deaktiviert).
  • * /* – Wird an die Ziel-App weitergeleitet.

WebSocket-Protokoll

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" }

UI-Stack

  • Vite + TanStack Router
  • xterm.js + Fit-Addon + WebGL-Renderer
  • Für Mobilgeräte optimiertes Layout mit fester Eingabeleiste
  • Automatische Wiederverbindung mit exponentiellem Backoff (bis zu 10 Versuche)
  • Verbindungsstatusanzeige