
# 架构

## 高层流程

默认模式（本地 tmux + 隧道）：

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

直接沙盒模式（Daytona，无隧道）：

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

设置 `--no-tunnel` 时，Termbridge 会跳过 Cloudflare，并使用你提供的公共 URL。

## 组件

### CLI 进程

- 启动提供 UI 资源的 HTTP 服务器。
- 启动用于终端 I/O 的 WebSocket 服务器。
- 创建一个或多个 tmux 会话（或 Daytona PTY）。
- 签发一次性兑换令牌。
- 启用隧道时启动并监控隧道（目前为 Cloudflare）。
- 在直接沙盒模式下，于沙盒内启动 Termbridge，并等待共享 URL。

### 终端后端

- **tmux 后端**：使用 `node-pty` 连接到 tmux，以传输真实的按键输入和输出。
- **Daytona 后端**：在沙盒内使用 Daytona PTY。
- 设置 `TERM=xterm-256color` 和 `COLORTERM=truecolor` 以完整支持颜色。
- 对于 tmux，禁用 tmux 状态栏，让 UI 保持简洁。

### 终端注册表

- 跟踪可用的终端会话。
- 为 UI 提供列表，并验证所选终端 ID。

### 身份验证与会话

- 一次性令牌会以 URL 打印，并编码在 QR 代码中。
- `GET /__tb/s/:token` 兑换令牌并设置 Cookie 会话。
- WebSocket 连接需要有效的会话 Cookie 和 CSRF 令牌。
- 通过 `GET /__tb/api/csrf` 获取 CSRF 令牌，并通过 WebSocket 查询参数传递。

### 代理模式

传入 `--proxy <port>` 时：
- 所有 termbridge 路由都位于 `/__tb/` 前缀下
- 非 `/__tb/` 请求会代理到目标应用
- UI 通过 Views 切换器提供 Terminal/Preview 视图
- Preview 视图会加载指向 `/` 的 iframe
- HMR 的 WebSocket 连接会转发到目标

### 安全

- **CSRF 防护**：WebSocket 升级需要 CSRF 令牌，以防止跨站劫持。
- **输入限制**：HTTP 请求正文 64KB、WebSocket 消息 1MB、每条消息终端输入 64KB。
- **速率限制**：令牌兑换和 WebSocket 连接均按 IP 限制。

## API 端点

所有路由都位于 `/__tb/` 前缀下，以避免与代理应用冲突：

- `GET /__tb/healthz` - 健康检查
- `GET /__tb/s/:token` - 兑换令牌 → Cookie → 重定向
- `GET /__tb/api/terminals` - 列出终端
- `GET /__tb/api/csrf` - 获取 WebSocket 的 CSRF 令牌
- `GET /__tb/api/config` - 获取配置（proxyPort、devProxyUrl）
- `POST /__tb/api/terminals` - 创建新的 tmux 会话
- `GET /__tb/app/*` - SPA 回退
- `WS /__tb/ws/terminal/:terminalId?csrf=<token>` - 流式传输终端 I/O

启用代理模式时：
- `GET /` - 重定向到代理应用（若禁用则转到 `/__tb/app`）
- `* /*` - 代理到目标应用

## WebSocket 协议

客户端 -> 服务器：

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

服务器 -> 客户端：

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

## UI 技术栈

- Vite + TanStack Router
- xterm.js + Fit 插件 + WebGL 渲染器
- 移动端优先布局，带固定输入栏
- 自动重新连接，采用指数退避（最多重试 10 次）
- 连接状态指示器
