انتقل إلى المحتوى

البنية

التدفق العام

الوضع الافتراضي (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 محاولات)
  • مؤشر حالة الاتصال