
# Arhitektura

## Potek na visoki ravni

Privzeto (lokalni tmux + tunel):

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

Neposredni način peskovnika (Daytona, brez tunela):

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

Ko je nastavljena spremenljivka `--no-tunnel`, Termbridge preskoči Cloudflare in uporabi vaš javni URL.

## Komponente

### Proces CLI

- Zažene strežnik HTTP, ki streže sredstva UI.
- Zažene strežnik WebSocket za V/I terminala.
- Ustvari eno ali več sej tmux (ali PTY-jev Daytona).
- Izdaja enkratne žetone za dostop.
- Zažene in nadzira tunel, če je omogočen (trenutno Cloudflare).
- V neposrednem načinu peskovnika zažene Termbridge v peskovniku in počaka na deljeni URL.

### Zaledje terminala

- **Zaledje tmux**: Uporablja `node-pty` za povezavo s tmux, da omogoči prave pritiske tipk in izhod.
- **Zaledje Daytona**: Uporablja PTY-je Daytona v peskovniku.
- Nastavi `TERM=xterm-256color` in `COLORTERM=truecolor` za polno podporo barvam.
- Za tmux onemogoči vrstico stanja tmux, da UI ostane čist.

### Register terminalov

- Spremlja razpoložljive terminalske seje.
- Ponuja seznam za UI in preverja izbrane ID-je terminalov.

### Preverjanje pristnosti in seja

- Enkratni žeton se izpiše kot URL in kodira v kodo QR.
- `GET /__tb/s/:token` unovči žeton in nastavi sejo s piškotkom.
- Za povezave WebSocket sta potrebna veljaven sejni piškotek in žeton CSRF.
- Žeton CSRF se pridobi prek `GET /__tb/api/csrf` in posreduje kot parameter v poizvedbi WebSocket.

### Način posredovanja

Ko je podan `--proxy <port>`:
- Vse poti termbridge so pod predpono `/__tb/`
- Zahteve, ki niso `/__tb/`, se posredujejo ciljni aplikaciji
- UI prek preklopnika Views prikaže poglede Terminal/Preview
- Pogled Preview naloži okvir iframe, ki kaže na `/`
- Povezave WebSocket za HMR se posredujejo cilju

### Varnost

- **Zaščita CSRF**: Za nadgradnjo povezav WebSocket je potreben žeton CSRF, ki preprečuje ugrabitev z drugega spletnega mesta.
- **Omejitve vnosa**: Telo HTTP do 64KB, sporočilo WebSocket do 1MB, vhod terminala do 64KB na sporočilo.
- **Omejevanje hitrosti**: Omejitve na IP za unovčenje žetonov in povezave WebSocket.

## Končne točke API

Vse poti so pod predpono `/__tb/`, da se preprečijo konflikti s posredovanimi aplikacijami:

- `GET /__tb/healthz` – preverjanje stanja
- `GET /__tb/s/:token` – unovčenje žetona → piškotek → preusmeritev
- `GET /__tb/api/terminals` – seznam terminalov
- `GET /__tb/api/csrf` – pridobitev žetona CSRF za WebSocket
- `GET /__tb/api/config` – pridobitev konfiguracije (proxyPort, devProxyUrl)
- `POST /__tb/api/terminals` – ustvarjanje nove seje tmux
- `GET /__tb/app/*` – rezervni prikaz SPA
- `WS /__tb/ws/terminal/:terminalId?csrf=<token>` – pretakanje V/I terminala

Ko je omogočen način posredovanja:
- `GET /` – preusmeri na posredovano aplikacijo (ali na `/__tb/app`, če je onemogočena)
- `* /*` – posredovano ciljni aplikaciji

## Protokol WebSocket

Odjemalec -> strežnik:

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

Strežnik -> odjemalec:

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

## Sklad UI

- Vite + TanStack Router
- xterm.js + dodatek Fit + izrisovalnik WebGL
- Postavitev, prilagojena najprej mobilnim napravam, s fiksno vrstico za vnos
- Samodejna ponovna povezava z eksponentnim podaljševanjem čakanja (do 10 poskusov)
- Kazalnik stanja povezave
