* feat(docs): mirror every docs/ page in all 65 locales Extends the documentation mirrors from the 22-page core set (#13940) to every Markdown page under docs/: 152 sources x 65 locales = 9,880 mirrors (6,208 new), language bars rewritten for the full locale list, state adopted so the blocking drift gate now covers all 152 pages. run-translation.mjs: an oversized block made only of table rows or list items (PROVIDER_REFERENCE.md 244-row table, FREE_TIERS.md 71-item list) is cut at item boundaries and rejoined without a blank line — the single 16-40 KB request outlived the backend socket for verbose scripts. 48 older mirrors whose tables had lost rows were retranslated with --force. * docs(i18n): refresh mirrors for the sources the base changed since the branch cut Section-level retranslation of the 29 docs (and README.md) whose source or mirrors moved on release/v3.8.51 during the run, then state adoption; the drift gate is green again on the merged tree.
48 KiB
Traffic Inspector (العربية)
🌐 Languages: 🇺🇸 English · 🇪🇹 am · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇦🇲 hy · 🇮🇩 id · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW
مراقب حركة المرور هو مصحّح حركة مرور HTTPS المدمج في OmniRoute — أداة شبيهة بـ Charles Proxy / mitmweb / HTTP Toolkit، وهي مدركة لنماذج LLM ومدركة للوكلاء. توجد في /dashboard/tools/traffic-inspector وتتلقى حركة المرور مباشرةً من ما يصل إلى 5 مصادر التقاط متزامنة.
الموقع في لوحة المعلومات: /dashboard/tools/traffic-inspector
مجموعة الشريط الجانبي: الأدوات (بعد AgentBridge)
راجع أيضًا: AGENTBRIDGE.md — يمثّل AgentBridge وضع الالتقاط 1.
§1 نظرة عامة
ما الذي يميّز مراقب حركة المرور
| الميزة | mitmweb | Charles | Fiddler | مراقب حركة المرور في OmniRoute |
|---|---|---|---|---|
| قائم على الويب | ✓ | ✗ | ✗ | ✓ |
| مفتوح المصدر | ✓ | ✗ | جزئي | ✓ |
| مدرك للوكلاء (يعرف ما إذا كان الطلب واردًا من Antigravity/Copilot/إلخ.) | ✗ | ✗ | ✗ | ✓ |
| مدرك لنماذج LLM (يحلّل بنية OpenAI/Anthropic/Gemini والرموز والنموذج) | ✗ | ✗ | ✗ | ✓ |
| إظهار تعيين النموذج (gemini-3-flash → claude-sonnet-4.7) | ✗ | ✗ | ✗ | ✓ |
| فصل زمن انتقال الوكيل عن المصدر الرئيسي | جزئي | ✗ | ✗ | ✓ |
| متكامل مع OmniRoute للتوجيه والرجوع الاحتياطي والتكلفة | ✗ | ✗ | ✗ | ✓ |
| تصحيح أخطاء الوكيل على مستوى النظام (أي تطبيق على الجهاز) | ✓ | ✓ | ✓ | ✓ |
| التقاط المضيف المخصص (إعادة توجيه DNS لكل مضيف) | ✓ | ✓ | ✓ | ✓ |
| وضع متغير البيئة HTTP_PROXY | ✓ | ✓ | ✓ | ✓ |
| عرض المحادثة (فقاعات متعددة الأدوار، tool_use/tool_result) | ✗ | ✗ | ✗ | ✓ |
| دمج تدفق SSE (إعادة البناء من أحداث delta) | ✗ | ✗ | ✗ | ✓ |
| تسجيل الجلسات (مسمّاة وقابلة للتصدير بصيغة .har/.jsonl) | ✗ | ✓ | ✓ | ✓ |
البنية في فقرة واحدة
يمثّل TrafficBuffer (src/mitm/inspector/buffer.ts) مخزنًا حلقيًا مشتركًا في الذاكرة (1000 إدخال افتراضيًا، وقابلًا للتهيئة عبر INSPECTOR_BUFFER_SIZE). تكتب جميع مصادر الالتقاط إليه عبر push(). تصنّف فئة المخزن المؤقت كل إدخال باستخدام kindDetector.ts (لتحديد ما إذا كان طلب LLM)، وتحسب contextKey (بصمة SHA-256 لموجّه النظام)، وتبث إلى جميع مشتركي WebSocket عبر globalTrafficBuffer.subscribe(). تتصل لوحة المعلومات عبر GET /api/tools/traffic-inspector/ws وتتلقى لقطة عند الاتصال، تليها أحداث new/update/clear.
§2 أوضاع الالتقاط
يدعم Traffic Inspector 5 مصادر التقاط متزامنة. يمكن تفعيل كل منها أو تعطيله بشكل مستقل. حقل source في كل InterceptedRequest (src/mitm/inspector/types.ts) تكون قيمته واحدة من "agent-bridge" أو "custom-host" أو "http-proxy" أو "system-proxy" أو "tproxy".
الوضع 1 — AgentBridge (الافتراضي، مفعّل دائمًا)
المصدر: معالجات AgentBridge (src/mitm/handlers/base.ts)
الآلية: يستدعي كل استدعاء لـ intercept() في MitmHandlerBase الدالة hookBufferStart() قبل إعادة التوجيه، والدالة hookBufferUpdate() عند الاكتمال. لا يتطلب أي إعداد إضافي — يعمل بمجرد تشغيل AgentBridge.
النطاق: وكلاء IDE التسعة المُعدّون في AgentBridge
ملاحظة: حقل source في InterceptedRequest = "agent-bridge"
الوضع 2 — المضيفون المخصصون (إعادة توجيه DNS)
المصدر: قائمة مضيفين يحددها المستخدم (جدول inspector_custom_hosts)
الآلية: تؤدي إضافة مضيف عبر واجهة المستخدم إلى إضافة 127.0.0.1 <host> إلى /etc/hosts (يتطلب sudo). وينشئ خادم MITM الحالي الخاص بـ AgentBridge (المنفذ 443) شهادة SNI ديناميكيًا للمضيف الجديد.
النطاق: أي تطبيق يستخدم المضيف المُضاف — لا يلزم تغيير إعدادات التطبيق
ملاحظة: source = "custom-host"
أمثلة على حالات الاستخدام:
- مراقبة
api.openai.comمن نصوص Python البرمجية - تصحيح أخطاء
my-internal-llm.company.com - التقاط حركة المرور من الأجهزة المحمولة على الشبكة نفسها (عبر انتحال ARP — متقدم)
الوضع 3 — مستمع HTTP_PROXY (المنفذ 8080)
المصدر: التطبيقات التي تستخدم متغيري البيئة HTTP_PROXY/HTTPS_PROXY
الآلية: مستمع ثانوي على المنفذ 8080 (src/mitm/inspector/httpProxyServer.ts) يعمل كوكيل HTTP/HTTPS صريح قياسي. يقبل أنفاق CONNECT (HTTPS) وطلبات HTTP المباشرة.
النطاق: أي تطبيق يحترم متغير البيئة HTTP_PROXY — لا يلزم تغيير DNS ولا استخدام sudo
ملاحظة: source = "http-proxy"
# التقاط سريع لأمر واحد:
HTTPS_PROXY=http://127.0.0.1:8080 curl https://api.openai.com/v1/models
# التقاط مستمر في جلسة shell:
export HTTP_PROXY=http://127.0.0.1:8080
export HTTPS_PROXY=http://127.0.0.1:8080
قيود TLS: تُلتقط أنفاق CONNECT الخاصة بـ HTTPS على هيئة بيانات وصفية فقط (المضيف، والمنفذ، والتوقيت) — ولا يُفك تشفير محتوى TLS افتراضيًا. فعّل مفتاح التبديل "فك تشفير HTTPS في وضع الوكيل" (اختياري، ويتطلب الوثوق بشهادة AgentBridge) لفحص المحتوى بالكامل.
تعارض المنفذ: إذا كان المنفذ 8080 مستخدمًا، يعيد AgentBridge استجابة 409 تتضمن خطأً منظمًا. غيّر المنفذ عبر متغير البيئة INSPECTOR_HTTP_PROXY_PORT.
الوضع 4 — الوكيل على مستوى النظام (متقدم، اختياري)
المصدر: إعدادات الوكيل على مستوى نظام التشغيل (تنطبق على جميع التطبيقات على الجهاز) الآلية: يستخدم واجهات برمجة تطبيقات نظام التشغيل لإعادة توجيه جميع حركة مرور HTTP/HTTPS عبر مستمع HTTP_PROXY:
- macOS:
networksetup -setwebproxy / -setsecurewebproxy - Linux:
gsettings set org.gnome.system.proxy+/etc/environment - Windows:
netsh winhttp set proxy 127.0.0.1:8080النطاق: كل تطبيق على الجهاز يحترم إعدادات وكيل النظام ملاحظة:source="system-proxy"
آليات الأمان:
- مؤقت تعطيل تلقائي (الافتراضي 30 دقيقة، قابل للتهيئة عبر
INSPECTOR_SYSTEM_PROXY_GUARD_MINUTES) - تُحفظ حالة وكيل النظام السابقة في قاعدة البيانات وتُستعاد عند التراجع
- تعرض لوحة المعلومات مطالبة "جارٍ التراجع عن وكيل النظام" إذا انتقل المستخدم بعيدًا بينما يكون نشطًا
- تعرض واجهة المستخدم شارة
⚠ متقدم+ خانة اختيار للتأكيد الصريح
الوضع 5 — فك التشفير الشفاف باستخدام TPROXY (Linux، صلاحيات root، اختياري)
المصدر: TPROXY في النواة + توجيه قائم على السياسات (src/mitm/tproxy/)
الآلية: يضع علامة على اتصالات TCP المحلية الصادرة الجديدة المتجهة إلى منفذ مستهدف (الافتراضي 443) في mangle OUTPUT، ثم تعيد قاعدة ip rule توجيه الحزم المعلّمة إلى التسليم المحلي، ويسلّم هدف TPROXY في mangle PREROUTING هذه الحزم إلى مستمع شفاف (IP_TRANSPARENT) (المنفذ الافتراضي 8443). ينهي المستمع TLS باستخدام شهادة طرفية تصدرها هيئة شهادات ديناميكية لكل اسم مضيف SNI عند الطلب، ويلتقط التبادل بعد فك تشفيره، ثم يعيد تشفير الطلب ويوجهه إلى الوجهة الأصلية.
النطاق: مضيفو وجهة عشوائيون على المنفذ المستهدف — من دون انتحال /etc/hosts، أو متغير البيئة HTTP_PROXY، أو تعديل الوكيل على مستوى النظام. لا تحتاج العملية المعترضة إلى أي تغيير في الإعدادات، لكنها يجب أن تثق بهيئة الشهادات الديناميكية.
ملاحظة: source = "tproxy"
المتطلبات: نظام Linux فقط (IP_TRANSPARENT متاح على Linux فقط)، وإمكانية CAP_NET_ADMIN (root)، وإضافة N-API أصلية يجب بناؤها باستخدام سلسلة أدوات C (npm run build:native:tproxy). عند عدم توفرها، يُعطّل مفتاح التبديل في لوحة المعلومات مع التلميح "يتطلب فك تشفير TPROXY نظام Linux + صلاحيات root + الإضافة الأصلية". تُطبّق قواعد جدار الحماية ويُتراجع عنها بصورة معاملية (لا يؤدي التعطل مطلقًا إلى ترك قاعدة mangle)، وتُمسح عند إعادة التشغيل. تمنع آلية مضادة للحلقات قائمة على SO_MARK إعادة اعتراض عملية إعادة التوجيه المشفرة الخاصة بالوكيل نفسه.
هذا نظام فرعي كبير له دليل تشغيل مخصص — راجع docs/security/MITM-TPROXY-DECRYPT.md (git؛ غير مُضمّن في /docs) للاطلاع على الوصفة الكاملة لجدار الحماية، وهيئة الشهادات الديناميكية لكل SNI + مُثبّت مخزن الثقة، والمسار المحلي فقط، وتفاصيل منع الحلقات، ومخطط الإعدادات. يُتحكم في مفتاح التبديل بواسطة GET / POST / DELETE /api/tools/agent-bridge/tproxy (ملاحظة: يوجد المسار ضمن بادئة AgentBridge، وليس بادئة Traffic Inspector).
مقارنة أوضاع الالتقاط
| الوضع | الإعداد | هل يلزم Sudo؟ | النطاق | ملاحظات |
|---|---|---|---|---|
| 1. AgentBridge | تلقائي | مرة واحدة (الشهادة+hosts) | 9 وكلاء IDE | مفعّل افتراضيًا |
| 2. المضيفون المخصصون | إدخال لكل مضيف | نعم (ملف hosts) | أي تطبيق يستخدم ذلك المضيف | محفوظ في DB |
| 3. HTTP_PROXY | export HTTPS_PROXY=... |
لا | التطبيقات التي تحترم متغيرات البيئة | المنفذ 8080، دون فك تشفير TLS افتراضيًا |
| 4. على مستوى النظام | تبديل + تأكيد | نعم | جميع التطبيقات على الجهاز | تعطيل تلقائي بعد 30 دقيقة |
| 5. فك تشفير TPROXY | تبديل (Linux + إضافة أصلية) | نعم (root + تثبيت CA) | أي مضيف على المنفذ المستهدف | يفك تشفير المضيفين عشوائيين؛ معطّل افتراضيًا — راجع docs/security/MITM-TPROXY-DECRYPT.md (ضمن git؛ غير مضمّن في /docs) |
§3 واجهة المستخدم
3.1 التخطيط
┌─ فاحص حركة المرور ─────────────────────────────────────────────────────┐
│ ┌─ شريط أدوات مصادر الالتقاط ─────────────────────────────────────┐ │
│ │ [✓ AgentBridge] [✓ مضيفون مخصصون (3)] [○ HTTP_PROXY] [○ النظام]│ │
│ └─────────────────────────────────────────────────────────────────────┘ │
│ ┌─ شريط التصفية/التحكم ───────────────────────────────────────────┐ │
│ │ ملف التعريف: (●) LLM فقط (○) مخصص (○) الكل │ │
│ │ [⎉ إيقاف مؤقت] [🗑 مسح] [⬇ .har] [● تسجيل الجلسة] ● مباشر 482/1k│ │
│ └─────────────────────────────────────────────────────────────────────┘ │
├══◀▶══════════════════════════════╬══════════════════════════════════════╤╡
│ قائمة الطلبات (قابلة للتحجيم) ║ لوحة التفاصيل ▲ │
│ ────────────────────────────── │ ║ [المحادثة][الترويسات][الطلب] │ │
│ ▎ 14:32 POST 200 12k AG openai ║ [الاستجابة][التوقيت][LLM][الإحصاءات]│ │
│ ▎ 14:31 POST 200 8k CP openai ║ ▼ │
│ ▎ 14:31 POST 503 ⚠ KR ... ║ │
│ ▎ 14:30 GET 200 3k 🌐 مخصص ║ │
└══════════════════════════════════╝══════════════════════════════════════╝
3.2 قائمة الطلبات (اللوحة اليسرى)
- افتراضية (
useVirtualList+ResizeObserver): تتعامل مع 1000 عنصر دون تجمّد - تمرير تلقائي مع مفتاح تبديل لإيقافه مؤقتًا أثناء الفحص
- حالة مرمّزة بالألوان: أخضر (2xx)، أصفر (3xx)، أحمر (4xx/5xx)، رمادي (قيد التنفيذ)
- رمز تعبيري للوكيل: 🔵 Antigravity، 🟢 Copilot، 🟠 Kiro، 🟣 Codex، 🔷 Cursor، 🟤 Zed، 🟡 Claude Code، ⚫ Open Code، 🌐 مضيف مخصص
- شريط لون السياق: حد أيسر بعرض 1px ملوّن وفقًا لـ
contextKey(SHA-256 لموجّه النظام) — يجمع المحادثات المرتبطة بصريًا - تحميل كسول للنص: لا يُنشأ نص الطلب إلا للطلب المحدد ضمن علامات تبويب التفاصيل (لتجنب عرض 1000 × 1MB من النصوص)
3.3 لوحة التفاصيل — 7 علامات تبويب
| علامة التبويب | المحتوى | ملاحظات |
|---|---|---|
| المحادثة | فقاعات محادثة متعددة الأدوار (النظام/المستخدم/المساعد + tool_use/tool_result) | موحّدة من تنسيق أي موفّر؛ لا تظهر إلا عندما يكون detectedKind === "llm" |
| الترويسات | جدولا ترويسات الطلب والاستجابة | تُحجب الترويسات الحساسة (Authorization، Cookie، api-key) افتراضيًا؛ مع مفتاح تبديل «إظهار الأسرار» |
| الطلب | النص الخام، عرض شجري لـ JSON، شارة حقل النموذج | JSON منسّق بشكل مقروء أو نص خام |
| الاستجابة | النص الخام أو قائمة أحداث SSE؛ مفتاح تبديل «خام ↔ مدمج» | يعيد مدمج SSE إنشاء الرسالة النهائية من أحداث الأجزاء |
| التوقيت | مخطط زمني متدرج: الحمل الإضافي للوكيل مقابل زمن انتقال الخادم الأصلي | الإجمالي، وTTFB، والحجم |
| تفاصيل LLM | الموفّر، والنموذج، وعدد الرسائل، والرموز الداخلة/الخارجة، وتقدير التكلفة، والهدف المعيّن | لا تظهر إلا لطلبات LLM |
| الإحصاءات | Recharts: مخطط زمني لزمن الانتقال، ومخطط شريطي للرموز، ومخطط مبعثر لاستدعاءات الأدوات | لا تظهر إلا عند تحميل جلسة مسجّلة |
3.4 عناصر تحكم شريط الأدوات
| عنصر التحكم | الإجراء |
|---|---|
| ⎉ إيقاف مؤقت | يوقف عرض الطلبات الجديدة؛ وتتراكم شارة «X جديد» |
| 🗑 مسح | يمسح قائمة واجهة المستخدم (لا يتأثر المخزن المؤقت للخادم) |
| ⬇ تصدير .har | ينزّل القائمة المصفّاة الحالية كملف HAR |
| ● تسجيل الجلسة | يبدأ جلسة تسجيل مسماة |
| محدد ملف التعريف | LLM فقط / مضيفون مخصصون / الكل |
| مرشح المضيف | مطابقة سلسلة فرعية في حقل host |
| مرشح الوكيل | قائمة منسدلة: الكل / حسب الوكيل |
| مرشح الحالة | الكل / 2xx / 3xx / 4xx / 5xx / خطأ |
| مرشح المصدر | الكل / agent-bridge / custom-host / http-proxy / system-proxy / tproxy |
| مرشح مباشر | يعرض الطلبات قيد التنفيذ (المفتوحة) فقط — مفتاح تبديل liveOnly (راجع §4.6) |
3.5 لوحات قابلة للتحجيم
- تُفصل القائمة ولوحة التفاصيل بمقبض سحب
- عرض القائمة: 280px كحد أدنى، و720px كحد أقصى، ويُحفظ في
localStorage(inspector.listWidth) - قابلة للطي إلى شريط بعرض 48px (أيقونات فقط)؛ انقر على صف في الشريط لتوسيعه
§4 ميزات مدركة لنماذج LLM
4.1 كاشف النوع (src/mitm/inspector/kindDetector.ts)
يصنّف كل طلب على أنه "llm" أو "app" أو "unknown" باستخدام 4 إشارات:
- سجلّ المضيفين — نحو 18 اسم مضيف معروفًا لواجهات API الخاصة بنماذج LLM (OpenAI وAnthropic وGemini وGroq وMistral وTogether وFireworks وCohere وPerplexity وHugging Face وOpenRouter وxAI وMoonshot وغيرها)
- أنماط المسارات —
/v1/chat/completionsو/v1/messagesو/generateContentو/v1/responsesوغيرها. - بنية المتن — يكتشف حقول
messages[](OpenAI/Claude) وcontents[](Gemini) وpromptوinput - تلميحات وكيل المستخدم — وجود
codexأوclaudeأوgeminiأوantigravityأوkiroأوcopilotأوcursorفي سلسلة UA
ترث المضيفات المخصصة المُضافة عبر الوضع 2 قيمة kind الخاصة بها من إدخال النموذج (القيمة الافتراضية هي "custom").
4.2 أداة دمج SSE (src/mitm/inspector/sseMerger.ts)
تنفيذ مستقل من الصفر. يتبع تحليل الأحداث خوارزمية أحداث الخادم المرسلة من WHATWG، بينما تتبع إعادة البناء مخططات البث العامة الخاصة بكل من OpenAI، وAnthropic، و Gemini.
تعيد بناء رسالة المساعد النهائية من أحداث فروق SSE الخام:
- Anthropic: تجمع
content_block_deltaحسب الفهرس؛ وتتعامل معtext_deltaوinput_json_delta(استدعاءات الأدوات) وthinking_delta - OpenAI: تجمع خيارات Chat Completions واستدعاءات الأدوات وعناصر مخرجات Responses API حسب الفهرس
- Gemini: تجمع
candidates[i].content.parts - غير معروف: تعيد الأحداث الخام كما هي
تعرض علامة تبويب الاستجابة مفتاح تبديل: "الأحداث الخام ↔ المدمجة".
4.3 أداة تسوية المحادثات (src/mitm/inspector/conversationNormalizer.ts)
تنفيذ مستقل من الصفر. تُعرَّف التسوية وفق عقود محلية للصندوق الأسود ومخططات الرسائل العامة الخاصة بـOpenAI وAnthropic وGemini؛ ولا يُستخدم أي مصدر تنفيذ من المنبع.
تحوّل تنسيقات رسائل OpenAI وAnthropic وGemini إلى NormalizedConversation واحد قبل العرض:
interface NormalizedConversation {
request: NormalizedTurn[]; // الرسائل / المحتويات / الموجّه من متن الطلب
response: NormalizedTurn[]; // استجابة المساعد (مدمجة عبر sseMerger)
contextKey: string | null; // بصمة SHA-256 لموجّه النظام
}
أنواع الكتل: text وtool_use وtool_result. تستخدم علامة تبويب المحادثة هذه البنية بغض النظر عن المزوّد.
4.4 تلوين مفتاح السياق (src/mitm/inspector/contextKey.ts)
- تحسب
SHA-256لموجّه النظام (أول رسالةrole:system، أو الحقلsystem، أوsystemInstructionالخاص بـGemini) - تعيد بادئة سداسية عشرية من 12 محرفًا (
"a3f9c2...") - تربط الواجهة الأمامية المفتاح بلون HSL حتمي لشريط الحد الأيسر
- مرشح "السياق نفسه": يؤدي النقر على شريحة
ctx #a3fإلى إضافة مرشح لا يعرض سوى الطلبات ذات البصمة نفسها
يسهّل ذلك التمييز بصريًا بين «الشخصيات» أو المهام المختلفة التي تعمل ضمن جلسة الوكيل نفسها.
4.5 استخراج بيانات LLM الوصفية
بالنسبة إلى طلبات LLM، تستخرج علامة تبويب تفاصيل LLM ما يلي:
interface LlmMetadata {
provider: string | null; // "openai" | "anthropic" | "gemini" | ...
apiKind: string | null; // "chat.completions" | "messages" | "embeddings" | ...
model: string | null; // من متن الطلب أو الاستجابة
messages: number; // عدد الأدوار
tokensIn: number | null; // usage.prompt_tokens / usage.input_tokens
tokensOut: number | null; // usage.completion_tokens / usage.output_tokens
streamed: boolean; // true إذا كانت الاستجابة من نوع SSE
mappedTo: string | null; // ترويسة x-omniroute-mapped
costEstimateUsd: number | null; // التكلفة المقدّرة بناءً على تسعير OmniRoute
}
4.6 مرشح مباشر للطلبات قيد التنفيذ
حقل status للطلب هو number | "in-flight" | "error" — يُضاف إدخال
بالقيمة "in-flight" لحظة بدء الطلب، ثم يُحدَّث في موضعه
عند وصول الاستجابة (أو الخطأ). يقيّد مفتاح تبديل "مباشر" في شريط الأدوات
(liveOnly، مفتاح i18n trafficInspector.liveOnly) القائمة بالإدخالات
التي يكون فيها status === "in-flight"، مما يتيح لك مراقبة الاتصالات المفتوحة في الوقت الفعلي.
المرشح عبارة عن شرط خالص من جانب العميل في
src/lib/inspector/matchesTrafficFilter.ts:
if (f.liveOnly && req.status !== "in-flight") return false;
توجد حالة مفتاح التبديل في useTrafficFilters (خطافات لوحة معلومات الفاحص)،
وتندمج مع المرشحات الأخرى (الملف الشخصي والمضيف والوكيل والمصدر والحالة والسياق).
4.7 إسناد العملية (Linux)
على Linux، يمكن إسناد كل طلب مُعترَض إلى العملية المحلية
المنشئة له. يُضاف حقلان اختياريان إلى InterceptedRequest:
pid?: number; // معرّف العملية المنشئة (Linux فقط)
processName?: string; // اسم العملية المنشئة (Linux فقط)
يربط src/mitm/inspector/processAttribution.ts منفذ العميل المؤقت للاتصال
بمعرّف عملية + اسم من خلال:
- قراءة
/proc/net/tcpو/proc/net/tcp6للعثور على inode المقبس الخاص بالمنفذ (parseProcNetTcpForInode، محلل خالص قابل للاختبار باستخدام تجهيزات ثابتة). - فحص
/proc/<pid>/fd/بحثًا عن رابط رمزي إلىsocket:[<inode>]. - قراءة اسم العملية من
/proc/<pid>/comm.
تحد ذاكرة تخزين مؤقت بقيمة TTL مقدارها ثانية واحدة من تكلفة فحص procfs تحت الحمل. يتم الإسناد
وفق أفضل جهد ممكن — تُحل أي حالة فشل إلى null ولا تعيق الالتقاط مطلقًا. على
macOS/Windows تعيد الدالة null (تنفيذ أولي؛ دعم lsof/GetExtendedTcpTable
متابعة لاحقة).
§5 الجلسات
5.1 تسجيل جلسة
- انقر على "● تسجيل جلسة" في شريط الأدوات ← أدخل اسمًا (اختياري)
- تستمر المتابعة المباشرة بصورة طبيعية؛ ويعرض مؤشر أحمر نابض
◉ تسجيل · <الاسم> · 00:42 · 23 طلبًا - انقر على "⏹ إيقاف" ← تُحفظ لقطة الجلسة في
inspector_sessions+inspector_session_requests
5.2 عرض جلسة مسجّلة
تسرد القائمة المنسدلة الجلسات في شريط الأدوات الجلسات المحفوظة. عند تحديد إحداها:
- تُحمّل لقطة الجلسة (حالة مجمّدة)
- تظهر لافتة نصها:
عرض الجلسة المسجّلة "<الاسم>" — [العودة إلى العرض المباشر] - تصبح علامة تبويب الإحصاءات متاحة مع تجميعات Recharts
5.3 تنسيقات التصدير
يمكن تصدير كل جلسة بالتنسيقات التالية:
| التنسيق | الاستخدام |
|---|---|
| HAR (أرشيف HTTP 1.2) | متوافق مع Chrome DevTools وCharles وFiddler — يمكن استيراده للتحليل دون اتصال |
| JSONL | سجل InterceptedRequest واحد في كل سطر — متوافق مع تنسيق llm-interceptor |
يمكن التصدير عبر GET /api/tools/traffic-inspector/sessions/{id}/export.har أو زر ⬇ في القائمة المنسدلة للجلسات.
§6 الأمان
يعرض فاحص حركة المرور كل حركة مرور HTTPS المعترضة، بما في ذلك ترويسات التخويل ومحتويات الطلبات. تُطبَّق عناصر التحكم التالية:
| عنصر التحكم | التفاصيل |
|---|---|
| LOCAL_ONLY | تقتصر جميع المسارات ونقطة نهاية WebSocket على واجهة الاسترجاع المحلية فقط (يُفرض ذلك في routeGuard.ts قبل المصادقة) |
| إخفاء الأسرار | يحجب الماسح الخطي maskSecret() بيانات اعتماد Bearer وفق RFC 6750، والمفاتيح ذات البادئات الخاصة بمزوّدي الخدمة، والرموز المبهمة الطويلة قبل TrafficBuffer.push() |
| حد حجم المحتوى | تُقتطع المحتويات التي يزيد حجمها على INSPECTOR_MAX_BODY_KB (القيمة الافتراضية 1024 KB) مع إشعار "(تم الاقتطاع لتحسين الأداء)" |
| تنقية الترويسات | تُحوَّل الأسماء إلى أحرف صغيرة؛ وتُحذف ترويسات التأطير/القفزة تلو الأخرى ومصادقة الوكيل؛ وتُحجب ملفات تعريف الارتباط بالكامل؛ وتُمرَّر قيم بيانات الاعتماد إلى maskSecret() |
| CSP | تُطبَّق سياسة صارمة لأمان المحتوى على صفحات فاحص حركة المرور لمنع XSS عبر محتويات الاستجابات المحقونة |
| عدم الحفظ افتراضيًا | يعمل TrafficBuffer في الذاكرة وتُفقد بياناته عند إعادة تشغيل الخادم. ولا تُحفظ الجلسات إلا عند تسجيلها صراحةً |
القواعد الصارمة المطبّقة
| القاعدة | التطبيق |
|---|---|
#12 sanitizeErrorMessage |
تُنقّى جميع استجابات أخطاء HTTP الواردة من مسارات فاحص حركة المرور |
#15 + #17 isLocalOnlyPath() |
المسار /api/tools/traffic-inspector/ هو LOCAL_ONLY + SPAWN_CAPABLE (أوامر وكيل النظام) |
القيود المعروفة
- يؤثر وضع الوكيل على مستوى النظام في جميع التطبيقات الموجودة على الجهاز، بما في ذلك عملاء VPN وSSO. استخدمه دائمًا مع مؤقّت التعطيل التلقائي. لا تستخدمه على الأجهزة المشتركة.
- HTTPS عبر نفق CONNECT: لا يلتقط الوضع 3 (HTTP_PROXY) لوجهات HTTPS سوى البيانات الوصفية للنفق، ما لم يكن اعتراض TLS مفعّلًا. هذا سلوك مقصود — إذ إن الالتقاط الشفاف دون الوثوق بشهادة AgentBridge سيؤدي إلى تعطيل التحقق من TLS في تلك التطبيقات.
- سلاسل نصية ثابتة في بعض المكوّنات: تحتوي بعض مكوّنات واجهة المستخدم (F7/F8) على عدد قليل من السلاسل النصية الثابتة التي لم تشملها بعد مفاتيح i18n. وقد وُثِّقت هذه باعتبارها قيدًا معروفًا في تقرير فجوات i18n؛ وسيتم ترحيلها في مراجعة لاحقة. السلاسل المتأثرة هي تسميات زخرفية في واجهة المستخدم ولا تتطلب ترجمة للاستخدام الوظيفي.
§7 استكشاف الأخطاء وإصلاحها
انقطاع اتصال WebSocket
إذا أظهر التتبّع المباشر "غير متصل":
- تحقّق من أن الخادم لا يزال قيد التشغيل:
GET /api/tools/traffic-inspector/capture-modes - أعد تحميل الصفحة — يعيد WebSocket الاتصال ويتلقى لقطة جديدة
- إذا أُعيد تشغيل الخادم، فسيكون المخزن المؤقت داخل الذاكرة قد مُسح — وستكون الإدخالات القديمة قد اختفت ما لم تكن هناك جلسة مسجّلة
تعارض المنفذ 8080
إذا فشل وضع HTTP_PROXY في البدء:
lsof -i :8080 # ابحث عن العملية
غيّر المنفذ:
# .env
INSPECTOR_HTTP_PROXY_PORT=8888
عدم التراجع عن وكيل النظام
إذا تعطّل OmniRoute بينما كان وضع الوكيل على مستوى النظام نشطًا:
macOS:
networksetup -setwebproxystate Wi-Fi off
networksetup -setsecurewebproxystate Wi-Fi off
Linux (GNOME):
gsettings set org.gnome.system.proxy mode 'none'
Windows:
netsh winhttp reset proxy
ستعرض لوحة المعلومات أيضًا خيار "التراجع عن وكيل النظام" عند التحميل التالي إذا اكتشفت أن حالة قاعدة البيانات تشير إلى أن الوكيل كان نشطًا.
امتلاء المخزن المؤقت
عندما يصل المخزن المؤقت إلى INSPECTOR_BUFFER_SIZE (القيمة الافتراضية 1000)، تحل الإدخالات الجديدة محل أقدم الإدخالات. إذا كانت الطلبات المهمة تُفقد:
- زِد
INSPECTOR_BUFFER_SIZE(مثلًا، 5000) — يؤدي ذلك إلى استهلاك ذاكرة أكبر مقابل الاحتفاظ بالبيانات مدة أطول - سجّل جلسة لحفظ النافذة ذات الصلة في قاعدة البيانات
§8 مرجع API
جميع المسارات هي LOCAL_ONLY (للاتصالات الراجعة فقط) وSPAWN_CAPABLE (أوامر وكيل النظام). راجع src/server/authz/routeGuard.ts.
المسار الأساسي: /api/tools/traffic-inspector/
إدارة الطلبات
| الطريقة | المسار | الوصف |
|---|---|---|
| GET | /requests |
سرد الطلبات (قابلة للتصفية: ?profile=llm&host=&agent=&status=&source=&sessionId=) |
| GET | /requests/{id} |
تفاصيل طلب واحد |
| DELETE | /requests |
مسح المخزن المؤقت داخل الذاكرة |
| POST | /requests/{id}/replay |
إعادة تنفيذ الطلب نفسه عبر موجّه OmniRoute |
| PUT | /requests/{id}/annotation |
حفظ ملاحظة على طلب أو تحديثها |
WebSocket
| الطريقة | المسار | الوصف |
|---|---|---|
| GET | /ws |
بث WebSocket مباشر. يرسل snapshot عند الاتصال، ثم أحداث new/update/clear |
التصدير
| الطريقة | المسار | الوصف |
|---|---|---|
| GET | /export.har |
تصدير القائمة المصفّاة الحالية بتنسيق HAR 1.2 |
المضيفون المخصّصون
| الطريقة | المسار | الوصف |
|---|---|---|
| GET | /hosts |
سرد المضيفين المخصّصين |
| POST | /hosts |
إضافة مضيف (يعدّل /etc/hosts تلقائيًا) |
| DELETE | /hosts/{host} |
إزالة مضيف |
| PATCH | /hosts/{host} |
تبديل enabled |
أوضاع الالتقاط
| الطريقة | المسار | الوصف |
|---|---|---|
| GET | /capture-modes |
حالة أوضاع AgentBridge / المضيفين المخصّصين / HTTP_PROXY / وكيل النظام + مفتاح تبديل tls-intercept |
| POST | /capture-modes/http-proxy |
بدء/إيقاف مستمع HTTP_PROXY ({action: "start"|"stop"}) |
| POST | /capture-modes/system-proxy |
تطبيق/إلغاء وكيل النظام ({action: "apply"|"revert"}) |
| POST | /capture-modes/tls-intercept |
تبديل فك تشفير محتوى HTTPS في وضع الوكيل ({enabled: boolean}) |
يُدار فك تشفير TPROXY (وضع الالتقاط 5) بواسطة مسار منفصل ضمن بادئة AgentBridge —
GET / POST / DELETE /api/tools/agent-bridge/tproxy— وليس ضمن/api/tools/traffic-inspector/. راجعdocs/security/MITM-TPROXY-DECRYPT.md(في git؛ غير مُضمّن في/docs).
الجلسات
| الطريقة | المسار | الوصف |
|---|---|---|
| POST | /sessions |
بدء التسجيل ({name?: string}) |
| PATCH | /sessions/{id} |
الإيقاف أو إعادة التسمية ({action: "stop"|"rename", name?: string}) |
| GET | /sessions |
سرد جميع الجلسات المحفوظة |
| GET | /sessions/{id} |
لقطة الجلسة (جميع الطلبات) |
| DELETE | /sessions/{id} |
حذف الجلسة |
| GET | /sessions/{id}/export.har |
تصدير الجلسة بتنسيق HAR 1.2 |
الاستيعاب الداخلي (البديل الاحتياطي D4)
| الطريقة | المسار | الوصف |
|---|---|---|
| POST | /internal/ingest |
يقبل الطلب المعترض من مسار التمرير في server.cjs؛ ويتطلب ترويسة INSPECTOR_INTERNAL_INGEST_TOKEN |
مخططات OpenAPI الكاملة: docs/openapi.yaml ← الوسم Traffic Inspector.