---
read_when:
    - أنت تريد تشغيل Gateway من متصفح
    - أنت تريد وصول Tailnet من دون أنفاق SSH
summary: واجهة تحكم معتمدة على المتصفح لـ Gateway (الدردشة، والعُقد، والإعدادات)
title: واجهة التحكم
x-i18n:
    generated_at: "2026-04-05T13:01:08Z"
    model: gpt-5.4
    provider: openai
    source_hash: 1568680a07907343352dbb3a2e6a1b896826404a7d8baba62512f03eac28e3d7
    source_path: web/control-ui.md
    workflow: 15
---

# واجهة التحكم (المتصفح)

واجهة التحكم هي تطبيق صفحة واحدة صغير مبني باستخدام **Vite + Lit** وتقوم Gateway بتقديمه:

- الافتراضي: `http://<host>:18789/`
- بادئة اختيارية: اضبط `gateway.controlUi.basePath` (مثل `/openclaw`)

وهي تتحدث **مباشرةً إلى Gateway WebSocket** على المنفذ نفسه.

## فتح سريع (محلي)

إذا كانت Gateway تعمل على الجهاز نفسه، فافتح:

- [http://127.0.0.1:18789/](http://127.0.0.1:18789/) (أو [http://localhost:18789/](http://localhost:18789/))

إذا فشل تحميل الصفحة، فابدأ Gateway أولًا: `openclaw gateway`.

يتم توفير المصادقة أثناء مصافحة WebSocket عبر:

- `connect.params.auth.token`
- `connect.params.auth.password`
- ترويسات هوية Tailscale Serve عندما يكون `gateway.auth.allowTailscale: true`
- ترويسات هوية trusted-proxy عندما يكون `gateway.auth.mode: "trusted-proxy"`

تحتفظ لوحة إعدادات لوحة المعلومات برمز مميز لجلسة علامة تبويب المتصفح الحالية
وعنوان URL المحدد لـ gateway؛ ولا يتم الاحتفاظ بكلمات المرور. وعادةً ما يقوم الإعداد الأولي
بإنشاء رمز gateway مميز لمصادقة السر المشترك عند أول اتصال، لكن
مصادقة كلمة المرور تعمل أيضًا عندما يكون `gateway.auth.mode` هو `"password"`.

## إقران الجهاز (الاتصال الأول)

عندما تتصل بواجهة التحكم من متصفح أو جهاز جديد، فإن Gateway
تتطلب **موافقة إقران لمرة واحدة** — حتى إذا كنت على Tailnet نفسها
مع `gateway.auth.allowTailscale: true`. وهذا إجراء أمني لمنع
الوصول غير المصرح به.

**ما الذي ستراه:** "disconnected (1008): pairing required"

**للموافقة على الجهاز:**

```bash
# List pending requests
openclaw devices list

# Approve by request ID
openclaw devices approve <requestId>
```

إذا أعاد المتصفح محاولة الإقران بتفاصيل مصادقة متغيرة (الدور/النطاقات/المفتاح
العام)، فسيتم استبدال الطلب المعلق السابق ويُنشأ `requestId` جديد.
أعد تشغيل `openclaw devices list` قبل الموافقة.

بعد الموافقة، يتم تذكر الجهاز ولن يتطلب إعادة الموافقة إلا
إذا ألغيتَه باستخدام `openclaw devices revoke --device <id> --role <role>`. راجع
[CLI الأجهزة](/cli/devices) لمعرفة تدوير الرموز المميزة والإلغاء.

**ملاحظات:**

- تتم الموافقة تلقائيًا على اتصالات المتصفح المحلية المباشرة عبر local loopback (`127.0.0.1` / `localhost`).
- ما تزال اتصالات المتصفح عبر Tailnet وLAN تتطلب موافقة صريحة، حتى عندما
  تأتي من الجهاز نفسه.
- ينشئ كل ملف تعريف متصفح معرّف جهاز فريدًا، لذا فإن تغيير المتصفحات أو
  مسح بيانات المتصفح سيتطلب إعادة الإقران.

## دعم اللغة

يمكن لواجهة التحكم أن توطّن نفسها عند أول تحميل استنادًا إلى لغة متصفحك، ويمكنك تجاوز ذلك لاحقًا من منتقي اللغة في بطاقة الوصول.

- اللغات المدعومة: `en` و`zh-CN` و`zh-TW` و`pt-BR` و`de` و`es`
- يتم تحميل الترجمات غير الإنجليزية بشكل كسول في المتصفح.
- تُحفَظ اللغة المحددة في تخزين المتصفح وتُعاد إعادة استخدامها في الزيارات المستقبلية.
- تعود مفاتيح الترجمة المفقودة إلى الإنجليزية.

## ما الذي يمكنها فعله (اليوم)

- الدردشة مع النموذج عبر Gateway WS (`chat.history`, `chat.send`, `chat.abort`, `chat.inject`)
- بث استدعاءات الأدوات + بطاقات مخرجات الأدوات الحية في الدردشة (أحداث الوكيل)
- القنوات: حالة القنوات المضمّنة بالإضافة إلى قنوات الإضافات المضمّنة/الخارجية، وتسجيل الدخول عبر QR، وإعدادات كل قناة (`channels.status`, `web.login.*`, `config.patch`)
- المثيلات: قائمة التواجد + التحديث (`system-presence`)
- الجلسات: سرد + تجاوزات لكل جلسة للنموذج/التفكير/الوضع السريع/الوضع المطوّل/الاستدلال (`sessions.list`, `sessions.patch`)
- مهام Cron: سرد/إضافة/تعديل/تشغيل/تمكين/تعطيل + سجل التشغيل (`cron.*`)
- Skills: الحالة، والتمكين/التعطيل، والتثبيت، وتحديثات مفاتيح API (`skills.*`)
- العُقد: سرد + الإمكانات (`node.list`)
- موافقات التنفيذ: تعديل قوائم السماح الخاصة بـ gateway أو العقد + سياسة ask لـ `exec host=gateway/node` (`exec.approvals.*`)
- الإعدادات: عرض/تعديل `~/.openclaw/openclaw.json` (`config.get`, `config.set`)
- الإعدادات: تطبيق + إعادة تشغيل مع التحقق (`config.apply`) وتنشيط آخر جلسة نشطة
- تتضمن عمليات كتابة الإعدادات حارس base-hash لمنع الكتابة فوق التعديلات المتزامنة
- تُجري عمليات كتابة الإعدادات (`config.set`/`config.apply`/`config.patch`) أيضًا فحصًا مسبقًا لحل SecretRef النشط للمراجع الموجودة في حمولة الإعدادات المقدمة؛ وتُرفض المراجع النشطة غير المحلولة في الحمولة المقدمة قبل الكتابة
- مخطط الإعدادات + عرض النموذج (`config.schema` / `config.schema.lookup`,
  بما في ذلك `title` / `description` للحقل، وتلميحات UI المطابقة، وملخصات
  العناصر التابعة المباشرة، وبيانات الوثائق الوصفية في عُقد الكائنات/البطاقات العامة/المصفوفات/التركيبات المتداخلة،
  بالإضافة إلى مخططات الإضافات + القنوات عند توفرها)؛ ولا يكون محرر Raw JSON
  متاحًا إلا عندما تمتلك اللقطة رحلة ذهاب وإياب خام آمنة
- إذا تعذر على لقطة ما إجراء رحلة ذهاب وإياب آمنة للنص الخام، فإن واجهة التحكم تفرض وضع النموذج وتعطّل وضع Raw لتلك اللقطة
- تُعرَض قيم كائنات SecretRef المنظمة للقراءة فقط في حقول نص النموذج لمنع الإفساد العرضي الناتج عن تحويل الكائن إلى سلسلة
- التصحيح: لقطات الحالة/الصحة/النماذج + سجل الأحداث + استدعاءات RPC اليدوية (`status`, `health`, `models.list`)
- السجلات: تتبع حي لسجلات ملفات gateway مع التصفية/التصدير (`logs.tail`)
- التحديث: تشغيل تحديث حزمة/git + إعادة تشغيل (`update.run`) مع تقرير إعادة تشغيل

ملاحظات لوحة مهام Cron:

- بالنسبة إلى المهام المعزولة، يكون التسليم افتراضيًا إلى ملخص إعلان. ويمكنك التبديل إلى عدم التسليم إذا كنت تريد تشغيلات داخلية فقط.
- تظهر حقول القناة/الهدف عند تحديد الإعلان.
- يستخدم وضع Webhook `delivery.mode = "webhook"` مع تعيين `delivery.to` إلى عنوان URL صالح لـ webhook من نوع HTTP(S).
- بالنسبة إلى مهام الجلسة الرئيسية، يتوفر وضعا التسليم webhook وعدم التسليم.
- تتضمن عناصر التحكم المتقدمة في التعديل الحذف بعد التشغيل، ومسح تجاوز الوكيل، وخيارات Cron الدقيقة/المتدرجة،
  وتجاوزات نموذج الوكيل/التفكير، وتبديلات التسليم بأفضل جهد.
- يكون التحقق من صحة النموذج مضمنًا مع أخطاء على مستوى الحقل؛ وتعطّل القيم غير الصالحة زر الحفظ حتى يتم إصلاحها.
- اضبط `cron.webhookToken` لإرسال رمز bearer مخصص؛ وإذا حُذف فسيتم إرسال webhook من دون ترويسة مصادقة.
- التراجع القديم: ما تزال المهام القديمة المخزنة مع `notify: true` قادرة على استخدام `cron.webhook` إلى أن تتم هجرتها.

## سلوك الدردشة

- `chat.send` **غير حاجب**: فهو يقرّ فورًا بـ `{ runId, status: "started" }` ويتم بث الاستجابة عبر أحداث `chat`.
- تعيد إعادة الإرسال بالمفتاح نفسه `idempotencyKey` القيمة `{ status: "in_flight" }` أثناء التشغيل، و`{ status: "ok" }` بعد الاكتمال.
- تكون استجابات `chat.history` محدودة الحجم حفاظًا على أمان UI. وعندما تكون إدخالات النص المسجل كبيرة جدًا، قد تقوم Gateway باقتطاع الحقول النصية الطويلة، وحذف كتل البيانات الوصفية الثقيلة، واستبدال الرسائل كبيرة الحجم بعنصر نائب (`[chat.history omitted: message too large]`).
- يقوم `chat.history` أيضًا بإزالة علامات التوجيه المضمنة الخاصة بالعرض فقط من النص المرئي للمساعد (مثل `[[reply_to_*]]` و`[[audio_as_voice]]`)، وحمولات XML النصية العادية لاستدعاءات الأدوات (بما في ذلك `<tool_call>...</tool_call>` و`<function_call>...</function_call>` و`<tool_calls>...</tool_calls>` و`<function_calls>...</function_calls>` وكتل استدعاء الأدوات المقتطعة)، ورموز التحكم في النموذج المسرّبة بصيغة ASCII/العرض الكامل، ويحذف إدخالات المساعد التي يكون نصها المرئي بالكامل هو الرمز الصامت الدقيق `NO_REPLY` / `no_reply`.
- يقوم `chat.inject` بإلحاق ملاحظة مساعد بالنص المسجل للجلسة ويبث حدث `chat` لتحديثات UI فقط (من دون تشغيل وكيل، ومن دون تسليم إلى القناة).
- تقوم منتقيات النموذج والتفكير في رأس الدردشة بتعديل الجلسة النشطة فورًا عبر `sessions.patch`؛ وهي تجاوزات دائمة للجلسة، وليست خيارات إرسال لدور واحد فقط.
- الإيقاف:
  - انقر **Stop** (يستدعي `chat.abort`)
  - اكتب `/stop` (أو عبارات الإلغاء المستقلة مثل `stop` أو `stop action` أو `stop run` أو `stop openclaw` أو `please stop`) للإلغاء خارج النطاق
  - يدعم `chat.abort` القيمة `{ sessionKey }` (من دون `runId`) لإلغاء جميع التشغيلات النشطة لتلك الجلسة
- الاحتفاظ الجزئي عند الإلغاء:
  - عند إلغاء تشغيل، قد يظل النص الجزئي للمساعد ظاهرًا في UI
  - تحتفظ Gateway بالنص الجزئي الملغى للمساعد في سجل النصوص عندما يوجد خرج مخزن مؤقتًا
  - تتضمن الإدخالات المحتفَظ بها بيانات وصفية للإلغاء حتى يتمكن مستهلكو النصوص المسجلة من تمييز الأجزاء الملغاة عن مخرجات الإكمال العادية

## وصول Tailnet (موصى به)

### Tailscale Serve المدمج (المفضل)

أبقِ Gateway على loopback ودع Tailscale Serve يمرّرها عبر HTTPS:

```bash
openclaw gateway --tailscale serve
```

افتح:

- `https://<magicdns>/` (أو `gateway.controlUi.basePath` المهيأ لديك)

افتراضيًا، يمكن لطلبات واجهة التحكم/WebSocket Serve المصادقة عبر ترويسات هوية Tailscale
(`tailscale-user-login`) عندما يكون `gateway.auth.allowTailscale` هو `true`. ويقوم OpenClaw
بالتحقق من الهوية عبر حل عنوان `x-forwarded-for` باستخدام
`tailscale whois` ومطابقته مع الترويسة، ولا يقبل هذه الترويسات إلا عندما
يضرب الطلب loopback مع ترويسات `x-forwarded-*` الخاصة بـ Tailscale. اضبط
`gateway.auth.allowTailscale: false` إذا كنت تريد فرض بيانات اعتماد صريحة تعتمد على السر المشترك
حتى مع حركة Serve. ثم استخدم `gateway.auth.mode: "token"` أو
`"password"`.
وبالنسبة إلى مسار هوية Serve غير المتزامن هذا، تتم سلسلة محاولات المصادقة الفاشلة من عنوان IP العميل نفسه
ونطاق المصادقة نفسه قبل كتابات تحديد المعدل. ولذلك يمكن أن يظهر
`retry later` في الطلب الثاني من إعادة المحاولة السيئة المتزامنة من المتصفح نفسه
بدلًا من سباق فشلَي تطابق عاديين بالتوازي.
تفترض مصادقة Serve من دون رمز أن مضيف gateway موثوق. وإذا كان من الممكن
أن تعمل شيفرة محلية غير موثوقة على ذلك المضيف، فاشترط مصادقة token/password.

### الربط بـ tailnet + token

```bash
openclaw gateway --bind tailnet --token "$(openssl rand -hex 32)"
```

ثم افتح:

- `http://<tailscale-ip>:18789/` (أو `gateway.controlUi.basePath` المهيأ لديك)

ألصق السر المشترك المطابق في إعدادات UI (يُرسل كـ
`connect.params.auth.token` أو `connect.params.auth.password`).

## HTTP غير الآمن

إذا فتحت لوحة المعلومات عبر HTTP عادي (`http://<lan-ip>` أو `http://<tailscale-ip>`)،
فسيعمل المتصفح في **سياق غير آمن** ويحظر WebCrypto. وافتراضيًا،
يقوم OpenClaw **بحظر** اتصالات واجهة التحكم من دون هوية جهاز.

الاستثناءات الموثقة:

- توافق HTTP غير الآمن الخاص بـ localhost فقط مع `gateway.controlUi.allowInsecureAuth=true`
- نجاح مصادقة المشغّل في واجهة التحكم عبر `gateway.auth.mode: "trusted-proxy"`
- وضع الطوارئ `gateway.controlUi.dangerouslyDisableDeviceAuth=true`

**الإصلاح الموصى به:** استخدم HTTPS (عبر Tailscale Serve) أو افتح UI محليًا:

- `https://<magicdns>/` (Serve)
- `http://127.0.0.1:18789/` (على مضيف gateway)

**سلوك تبديل المصادقة غير الآمنة:**

```json5
{
  gateway: {
    controlUi: { allowInsecureAuth: true },
    bind: "tailnet",
    auth: { mode: "token", token: "replace-me" },
  },
}
```

إن `allowInsecureAuth` مجرد تبديل توافق محلي:

- يسمح لجلسات واجهة التحكم على localhost بالمتابعة من دون هوية جهاز في
  سياقات HTTP غير الآمنة.
- لا يتجاوز فحوصات الإقران.
- لا يرخّي متطلبات هوية الجهاز البعيدة (غير localhost).

**للطوارئ فقط:**

```json5
{
  gateway: {
    controlUi: { dangerouslyDisableDeviceAuth: true },
    bind: "tailnet",
    auth: { mode: "token", token: "replace-me" },
  },
}
```

يقوم `dangerouslyDisableDeviceAuth` بتعطيل فحوصات هوية جهاز واجهة التحكم وهو
تخفيض أمني خطير جدًا. أعده سريعًا بعد استخدام الطوارئ.

ملاحظة trusted-proxy:

- يمكن لمصادقة trusted-proxy الناجحة أن تسمح بجلسات واجهة تحكم **للمشغّل** من دون
  هوية جهاز
- وهذا **لا** يمتد إلى جلسات واجهة التحكم ذات دور العقدة
- وما تزال الوكلاءات العكسية loopback الموجودة على المضيف نفسه لا تستوفي مصادقة trusted-proxy؛ راجع
  [Trusted Proxy Auth](/ar/gateway/trusted-proxy-auth)

راجع [Tailscale](/ar/gateway/tailscale) للحصول على إرشادات إعداد HTTPS.

## بناء UI

تقدّم Gateway ملفات ثابتة من `dist/control-ui`. ابنِها باستخدام:

```bash
pnpm ui:build # auto-installs UI deps on first run
```

قاعدة مطلقة اختيارية (عندما تريد عناوين URL ثابتة للأصول):

```bash
OPENCLAW_CONTROL_UI_BASE_PATH=/openclaw/ pnpm ui:build
```

للتطوير المحلي (خادم تطوير منفصل):

```bash
pnpm ui:dev # auto-installs UI deps on first run
```

ثم وجّه UI إلى عنوان URL الخاص بـ Gateway WS (مثل `ws://127.0.0.1:18789`).

## التصحيح/الاختبار: خادم تطوير + Gateway بعيد

واجهة التحكم عبارة عن ملفات ثابتة؛ وهدف WebSocket قابل للتهيئة ويمكن أن يكون
مختلفًا عن أصل HTTP. وهذا مفيد عندما تريد خادم تطوير Vite
محليًا لكن Gateway تعمل في مكان آخر.

1. ابدأ خادم تطوير UI: `pnpm ui:dev`
2. افتح عنوان URL مثل:

```text
http://localhost:5173/?gatewayUrl=ws://<gateway-host>:18789
```

مصادقة لمرة واحدة اختيارية (عند الحاجة):

```text
http://localhost:5173/?gatewayUrl=wss://<gateway-host>:18789#token=<gateway-token>
```

ملاحظات:

- يتم تخزين `gatewayUrl` في localStorage بعد التحميل وإزالته من عنوان URL.
- يجب تمرير `token` عبر جزء URL (`#token=...`) كلما أمكن. لا تُرسل الأجزاء إلى الخادم، ما يتجنب تسربها في سجلات الطلبات وReferer. وما تزال معلمات الاستعلام القديمة `?token=` تُستورد مرة واحدة من أجل التوافق، لكن كخيار رجوع فقط، وتُزال مباشرةً بعد الإقلاع.
- يُحتفَظ بـ `password` في الذاكرة فقط.
- عندما يكون `gatewayUrl` مضبوطًا، لا يعود UI إلى بيانات الاعتماد الموجودة في الإعدادات أو البيئة.
  قدّم `token` (أو `password`) صراحةً. ويُعد غياب بيانات اعتماد صريحة خطأ.
- استخدم `wss://` عندما تكون Gateway خلف TLS (Tailscale Serve أو وكيل HTTPS أو ما شابه).
- لا يُقبل `gatewayUrl` إلا في نافذة من المستوى الأعلى (غير مضمنة) لمنع clickjacking.
- يجب أن تضبط عمليات نشر واجهة التحكم غير loopback قيمة `gateway.controlUi.allowedOrigins`
  صراحةً (كأصول كاملة). ويشمل ذلك إعدادات التطوير البعيد.
- لا تستخدم `gateway.controlUi.allowedOrigins: ["*"]` إلا للاختبار المحلي
  المحكوم بإحكام. فهي تعني السماح لأي أصل متصفح، لا “مطابقة أي مضيف أستخدمه”.
- يفعّل `gateway.controlUi.dangerouslyAllowHostHeaderOriginFallback=true`
  وضع الرجوع إلى الأصل عبر Host-header، لكنه وضع أمني خطير.

مثال:

```json5
{
  gateway: {
    controlUi: {
      allowedOrigins: ["http://localhost:5173"],
    },
  },
}
```

تفاصيل إعداد الوصول البعيد: [الوصول البعيد](/ar/gateway/remote).

## ذو صلة

- [لوحة المعلومات](/web/dashboard) — لوحة معلومات gateway
- [WebChat](/web/webchat) — واجهة دردشة معتمدة على المتصفح
- [TUI](/web/tui) — واجهة مستخدم طرفية
- [فحوصات الصحة](/ar/gateway/health) — مراقبة صحة gateway
