
# Arsitektur

## Alur tingkat tinggi

Default (lokal tmux + tunnel):

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

Mode sandbox langsung (Daytona, tanpa tunnel):

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

Saat `--no-tunnel` diatur, Termbridge melewati Cloudflare dan menggunakan URL publik yang Anda berikan.

## Komponen

### Proses CLI

- Menjalankan server HTTP yang menyajikan aset UI.
- Menjalankan server WebSocket untuk I/O terminal.
- Membuat satu atau beberapa sesi tmux (atau PTY Daytona).
- Menerbitkan token penukaran sekali pakai.
- Menjalankan dan memantau tunnel jika diaktifkan (saat ini Cloudflare).
- Dalam mode sandbox langsung, meluncurkan Termbridge di dalam sandbox dan menunggu URL berbagi.

### Backend terminal

- **Backend tmux**: Menggunakan `node-pty` untuk terhubung ke tmux demi input tombol dan output nyata.
- **Backend Daytona**: Menggunakan PTY Daytona di dalam sandbox.
- Mengatur `TERM=xterm-256color` dan `COLORTERM=truecolor` untuk dukungan warna penuh.
- Untuk tmux, menonaktifkan bilah status tmux agar UI tetap bersih.

### Registri terminal

- Melacak sesi terminal yang tersedia.
- Menyediakan daftar untuk UI dan memvalidasi ID terminal yang dipilih.

### Autentikasi dan sesi

- Token sekali pakai dicetak sebagai URL dan dikodekan dalam kode QR.
- `GET /__tb/s/:token` menukar token dan mengatur sesi cookie.
- Koneksi WebSocket memerlukan cookie sesi yang valid dan token CSRF.
- Token CSRF diambil melalui `GET /__tb/api/csrf` dan diteruskan dalam parameter kueri WebSocket.

### Mode proxy

Saat `--proxy <port>` diberikan:
- Semua rute termbridge berada di bawah prefiks `/__tb/`
- Permintaan non-`/__tb/` diteruskan ke aplikasi target melalui proxy
- UI menampilkan tampilan Terminal/Preview melalui pemilih Views
- Tampilan Preview memuat iframe yang mengarah ke `/`
- Koneksi WebSocket untuk HMR diteruskan ke target

### Keamanan

- **Perlindungan CSRF**: Upgrade WebSocket memerlukan token CSRF untuk mencegah pembajakan lintas situs.
- **Batas input**: body HTTP 64KB, pesan WebSocket 1MB, input terminal 64KB per pesan.
- **Pembatasan laju**: Batas per-IP pada penukaran token dan koneksi WebSocket.

## Endpoint API

Semua rute berada di bawah prefiks `/__tb/` untuk menghindari konflik dengan aplikasi yang diproksikan:

- `GET /__tb/healthz` - pemeriksaan kesehatan
- `GET /__tb/s/:token` - penukaran token → cookie → pengalihan
- `GET /__tb/api/terminals` - daftar terminal
- `GET /__tb/api/csrf` - mengambil token CSRF untuk WebSocket
- `GET /__tb/api/config` - mengambil konfigurasi (proxyPort, devProxyUrl)
- `POST /__tb/api/terminals` - membuat sesi tmux baru
- `GET /__tb/app/*` - fallback SPA
- `WS /__tb/ws/terminal/:terminalId?csrf=<token>` - streaming I/O terminal

Saat mode proxy diaktifkan:
- `GET /` - mengalihkan ke aplikasi yang diproksikan (atau `/__tb/app` jika dinonaktifkan)
- `* /*` - diteruskan ke aplikasi target melalui proxy

## Protokol WebSocket

Klien -> server:

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

Server -> klien:

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

## Stack UI

- Vite + TanStack Router
- xterm.js + add-on Fit + renderer WebGL
- Tata letak mobile-first dengan bilah input tetap
- Sambung ulang otomatis dengan jeda eksponensial (hingga 10 percobaan ulang)
- Indikator status koneksi
