
# البنية

## التدفق العام

الوضع الافتراضي (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

- يبدأ خادم HTTP الذي يقدّم أصول UI.
- يبدأ خادم WebSocket لإدخال وإخراج الطرفية.
- ينشئ جلسة tmux واحدة أو أكثر (أو PTY من Daytona).
- يصدر رموز استرداد لمرة واحدة.
- يبدأ النفق ويراقبه عند تفعيله (Cloudflare حاليًا).
- في وضع البيئة المعزولة المباشر، يشغّل Termbridge داخل البيئة المعزولة وينتظر URL المشاركة.

### الواجهة الخلفية للطرفية

- **الواجهة الخلفية tmux**: تستخدم `node-pty` للاتصال بـ tmux لإدخال ضغطات المفاتيح الحقيقية واستقبال المخرجات.
- **الواجهة الخلفية Daytona**: تستخدم PTYs من Daytona داخل بيئة معزولة.
- تضبط `TERM=xterm-256color` و`COLORTERM=truecolor` لدعم الألوان الكاملة.
- بالنسبة إلى tmux، تعطّل شريط الحالة tmux لإبقاء UI نظيفًا.

### سجل الطرفيات

- يتتبع جلسات الطرفية المتاحة.
- يوفّر قائمة لـUI ويتحقق من معرّفات الطرفيات المحددة.

### المصادقة والجلسة

- يُطبع الرمز الذي يُستخدم لمرة واحدة على هيئة URL ويُرمّز في رمز QR.
- يسترد `GET /__tb/s/:token` الرمز وينشئ جلسة ملفات تعريف ارتباط.
- تتطلب اتصالات WebSocket ملف تعريف ارتباط جلسة صالحًا ورمز CSRF.
- يُجلب رمز CSRF عبر `GET /__tb/api/csrf` ويُمرر في وسيط الاستعلام لاتصال WebSocket.

### وضع الوكيل

عند تمرير `--proxy <port>`:
- تقع كل مسارات termbridge تحت البادئة `/__tb/`
- تُمرر الطلبات غير التابعة إلى `/__tb/` للتطبيق المستهدف
- يعرض UI عرضي الطرفية والمعاينة عبر مبدّل العروض
- يحمّل عرض المعاينة إطار iframe يشير إلى `/`
- تُمرر اتصالات WebSocket الخاصة بـHMR إلى التطبيق المستهدف

### الأمان

- **الحماية من CSRF**: تتطلب ترقية WebSocket رمز CSRF لمنع الاختطاف عبر المواقع.
- **حدود الإدخال**: متن طلب HTTP بحجم 64KB، ورسالة WebSocket بحجم 1MB، وإدخال طرفية بحجم 64KB لكل رسالة.
- **تحديد المعدل**: حدود لكل IP لاسترداد الرموز واتصالات WebSocket.

## نقاط نهاية API

تقع كل المسارات تحت البادئة `/__tb/` لتجنب التعارض مع التطبيقات الممررة عبر الوكيل:

- `GET /__tb/healthz` - فحص الحالة
- `GET /__tb/s/:token` - استرداد الرمز → ملف تعريف ارتباط → إعادة توجيه
- `GET /__tb/api/terminals` - سرد الطرفيات
- `GET /__tb/api/csrf` - جلب رمز CSRF لـWebSocket
- `GET /__tb/api/config` - جلب الإعدادات (proxyPort وdevProxyUrl)
- `POST /__tb/api/terminals` - إنشاء جلسة tmux جديدة
- `GET /__tb/app/*` - بديل SPA
- `WS /__tb/ws/terminal/:terminalId?csrf=<token>` - بث إدخال وإخراج الطرفية

عند تفعيل وضع الوكيل:
- `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 محاولات)
- مؤشر حالة الاتصال
