Tools
الفروقات
diffs هي أداة Plugin اختيارية تتضمن إرشادات نظام مدمجة قصيرة وSkill مرافقة تحوّل محتوى التغييرات إلى أثر diff للقراءة فقط للوكلاء.
تقبل إما:
- نص
beforeوafter patchموحدًا
يمكنها إرجاع:
- عنوان URL لعارض Gateway لعرض canvas
- مسار ملف مُصيَّر (PNG أو PDF) لتسليم الرسائل
- كلا المخرجين في استدعاء واحد
عند تمكينها، تضيف Plugin إرشادات استخدام موجزة في مساحة مطالبة النظام، وتكشف أيضًا عن Skill مفصلة للحالات التي يحتاج فيها الوكيل إلى تعليمات أكمل.
البدء السريع
ثبّت Plugin
openclaw plugins install diffsمكّن Plugin
{ plugins: { entries: { diffs: { enabled: true, }, }, },}اختر وضعًا
view
تدفقات canvas أولًا: يستدعي الوكلاء diffs مع mode: "view" ويفتحون details.viewerUrl باستخدام canvas present.
file
تسليم ملف الدردشة: يستدعي الوكلاء diffs مع mode: "file" ويرسلون details.filePath باستخدام message مع path أو filePath.
both
مدمج: يستدعي الوكلاء diffs مع mode: "both" للحصول على كلا الأثرين في استدعاء واحد.
تعطيل إرشادات النظام المدمجة
إذا أردت إبقاء أداة diffs ممكّنة مع تعطيل إرشادات مطالبة النظام المدمجة بها، فاضبط plugins.entries.diffs.hooks.allowPromptInjection على false:
{ plugins: { entries: { diffs: { enabled: true, hooks: { allowPromptInjection: false, }, }, }, },}يحظر هذا خطاف before_prompt_build الخاص بـ Plugin diffs مع إبقاء Plugin والأداة وSkill المرافقة متاحة.
إذا أردت تعطيل كل من الإرشادات والأداة، فعطّل Plugin بدلًا من ذلك.
سير عمل الوكيل المعتاد
استدعِ diffs
يستدعي الوكيل أداة diffs مع الإدخال.
اقرأ التفاصيل
يقرأ الوكيل حقول details من الاستجابة.
اعرض
يفتح الوكيل إما details.viewerUrl باستخدام canvas present، أو يرسل details.filePath باستخدام message مع path أو filePath، أو يفعل الأمرين معًا.
أمثلة الإدخال
قبل وبعد
{ "before": "# Hello\n\nOne", "after": "# Hello\n\nTwo", "path": "docs/example.md", "mode": "view"}Patch
{ "patch": "diff --git a/src/example.ts b/src/example.ts\n--- a/src/example.ts\n+++ b/src/example.ts\n@@ -1 +1 @@\n-const x = 1;\n+const x = 2;\n", "mode": "both"}مرجع إدخال الأداة
كل الحقول اختيارية ما لم يُذكر خلاف ذلك.
beforestringالنص الأصلي. مطلوب مع after عند حذف patch.
afterstringالنص المحدّث. مطلوب مع before عند حذف patch.
patchstringنص diff موحد. متنافي مع before وafter.
pathstringاسم ملف العرض لوضع قبل وبعد.
langstringتلميح تجاوز اللغة لوضع قبل وبعد. القيم غير المعروفة واللغات خارج مجموعة العارض الافتراضية تعود إلى نص عادي ما لم تكن Diff Viewer Language Pack Plugin مثبتة.
titlestringتجاوز عنوان العارض.
mode"view" | "file" | "both"وضع الإخراج. القيمة الافتراضية هي إعداد Plugin الافتراضي defaults.mode. الاسم المستعار المهمل: "image" يتصرف مثل "file" وما زال مقبولًا للتوافق مع الإصدارات السابقة.
theme"light" | "dark"سمة العارض. القيمة الافتراضية هي إعداد Plugin الافتراضي defaults.theme.
layout"unified" | "split"تخطيط diff. القيمة الافتراضية هي إعداد Plugin الافتراضي defaults.layout.
expandUnchangedbooleanتوسيع الأقسام غير المتغيرة عند توفر السياق الكامل. خيار لكل استدعاء فقط (وليس مفتاحًا افتراضيًا لـ Plugin).
fileFormat"png" | "pdf"تنسيق الملف المُصيَّر. القيمة الافتراضية هي إعداد Plugin الافتراضي defaults.fileFormat.
fileQuality"standard" | "hq" | "print"إعداد جودة مسبق لتصيير PNG أو PDF.
fileScalenumberتجاوز مقياس الجهاز (1-4).
fileMaxWidthnumberأقصى عرض تصيير بوحدات بكسل CSS (640-2400).
ttlSecondsnumberdefault: 1800مدة بقاء الأثر بالثواني لمخرجات العارض والملف المستقل. الحد الأقصى 21600.
baseUrlstringتجاوز أصل عنوان URL للعارض. يتجاوز viewerBaseUrl الخاص بـ Plugin. يجب أن يكون http أو https، بلا استعلام/تجزئة.
أسماء الإدخال المستعارة القديمة
ما زالت مقبولة للتوافق مع الإصدارات السابقة:
format->fileFormatimageFormat->fileFormatimageQuality->fileQualityimageScale->fileScaleimageMaxWidth->fileMaxWidth
التحقق والحدود
beforeوafterبحد أقصى 512 KiB لكل منهما.patchبحد أقصى 2 MiB.pathبحد أقصى 2048 بايت.langبحد أقصى 128 بايت.titleبحد أقصى 1024 بايت.- سقف تعقيد Patch: بحد أقصى 128 ملفًا و120000 سطر إجمالي.
- يتم رفض جمع
patchمعbeforeأوafter. - حدود أمان الملف المُصيَّر (تنطبق على PNG وPDF):
fileQuality: "standard": بحد أقصى 8 MP (8,000,000 بكسل مُصيَّر).fileQuality: "hq": بحد أقصى 14 MP (14,000,000 بكسل مُصيَّر).fileQuality: "print": بحد أقصى 24 MP (24,000,000 بكسل مُصيَّر).- PDF له أيضًا حد أقصى قدره 50 صفحة.
تمييز الصياغة
يتضمن OpenClaw تمييز الصياغة للغات المصدر والتكوين والتوثيق الشائعة:
javascript, typescript, tsx, jsx, json, markdown, yaml, css, html, sh, python, go, rust, java, c, cpp, csharp, php, sql, docker, ruby, swift, kotlin, r, dart, lua, powershell, xml, وtoml.
تتم تسوية الأسماء المستعارة الشائعة مثل js وts وbash وmd وyml وc++ وdockerfile وrb وkt وps1 إلى تلك اللغات الافتراضية.
ثبّت Plugin حزمة لغة عارض الفروقات لتمييز لغات أخرى:
openclaw plugins install clawhub:@openclaw/diffs-language-packعند توفر حزمة اللغة، يستطيع OpenClaw تمييز عدد أكبر بكثير من اللغات. إذا لم تكن الحزمة مثبتة، فستظل الملفات خارج القائمة الافتراضية تُعرض كنص عادي قابل للقراءة. تشمل الأمثلة Astro وVue وSvelte وMDX وGraphQL وTerraform/HCL وNix وClojure وElixir وHaskell وOCaml وScala وZig وSolidity وVerilog/VHDL وFortran وMATLAB وLaTeX وMermaid وSass/Less/SCSS وNginx وApache وCSV وdotenv وINI وملفات diff.
راجع Plugin حزمة لغة الفروقات للتفاصيل ولغات Shiki لفهرس اللغات والأسماء المستعارة الصادر من Shiki.
عقد تفاصيل الإخراج
تعيد الأداة بيانات وصفية منظمة تحت details.
Viewer fields
الحقول المشتركة للأوضاع التي تنشئ عارضًا:
artifactIdviewerUrlviewerPathtitleexpiresAtinputKindfileCountmodecontext(agentIdوsessionIdوmessageChannelوagentAccountIdعند توفرها)
File fields
حقول الملف عند عرض PNG أو PDF:
artifactIdexpiresAtfilePathpath(القيمة نفسها مثلfilePath، للتوافق مع أداة الرسائل)fileBytesfileFormatfileQualityfileScalefileMaxWidth
Compatibility aliases
تُعاد أيضًا للجهات المستدعية الحالية:
format(القيمة نفسها مثلfileFormat)imagePath(القيمة نفسها مثلfilePath)imageBytes(القيمة نفسها مثلfileBytes)imageQuality(القيمة نفسها مثلfileQuality)imageScale(القيمة نفسها مثلfileScale)imageMaxWidth(القيمة نفسها مثلfileMaxWidth)
ملخص سلوك الوضع:
| الوضع | ما الذي يُعاد |
|---|---|
"view" |
حقول العارض فقط. |
"file" |
حقول الملف فقط، بدون عنصر عارض. |
"both" |
حقول العارض بالإضافة إلى حقول الملف. إذا فشل عرض الملف، فسيظل العارض يُعاد مع fileError والاسم المستعار imageError. |
الأقسام غير المتغيرة المطوية
- يمكن للعارض إظهار صفوف مثل
N unmodified lines. - عناصر التحكم في التوسيع على تلك الصفوف شرطية وليست مضمونة لكل نوع إدخال.
- تظهر عناصر التحكم في التوسيع عندما يحتوي الفرق المعروض على بيانات سياق قابلة للتوسيع، وهذا شائع لإدخال ما قبل وما بعد.
- في كثير من إدخالات التصحيحات الموحدة، لا تكون أجسام السياق المحذوفة متاحة في مقاطع التصحيح المحللة، لذلك قد يظهر الصف بدون عناصر تحكم في التوسيع. هذا سلوك متوقع.
- ينطبق
expandUnchangedفقط عند وجود سياق قابل للتوسيع.
افتراضيات Plugin
اضبط الافتراضيات على مستوى Plugin في ~/.openclaw/openclaw.json:
{ plugins: { entries: { diffs: { enabled: true, config: { defaults: { fontFamily: "Fira Code", fontSize: 15, lineSpacing: 1.6, layout: "unified", showLineNumbers: true, diffIndicators: "bars", wordWrap: true, background: true, theme: "dark", fileFormat: "png", fileQuality: "standard", fileScale: 2, fileMaxWidth: 960, mode: "both", ttlSeconds: 21600, }, }, }, }, },}الافتراضيات المدعومة:
fontFamilyfontSizelineSpacinglayoutshowLineNumbersdiffIndicatorswordWrapbackgroundthemefileFormatfileQualityfileScalefileMaxWidthmodettlSeconds
تتجاوز معاملات الأداة الصريحة هذه الافتراضيات.
إعداد عنوان URL عارض دائم
viewerBaseUrlstringبديل احتياطي مملوك لـ Plugin لروابط العارض المُعادة عندما لا تمرر استدعاءة الأداة baseUrl. يجب أن يكون http أو https، بدون استعلام/تجزئة.
{ plugins: { entries: { diffs: { enabled: true, config: { viewerBaseUrl: "https://gateway.example.com/openclaw", }, }, }, },}إعداد الأمان
security.allowRemoteViewerbooleandefault: falsefalse: تُرفض الطلبات غير local loopback إلى مسارات العارض. true: يُسمح بالعارضين البعيدين إذا كان المسار المرمّز صالحًا.
{ plugins: { entries: { diffs: { enabled: true, config: { security: { allowRemoteViewer: false, }, }, }, }, },}دورة حياة العناصر والتخزين
- تُخزَّن الآثار ضمن المجلد الفرعي المؤقت:
$TMPDIR/openclaw-diffs. - تحتوي بيانات تعريف أثر العارض على:
- معرّف أثر عشوائي (20 حرفًا سداسيًا)
- رمز عشوائي (48 حرفًا سداسيًا)
createdAtوexpiresAt- مسار
viewer.htmlالمخزَّن
- قيمة TTL الافتراضية للأثر هي 30 دقيقة عند عدم تحديدها.
- الحد الأقصى المقبول لقيمة TTL للعارض هو 6 ساعات.
- يعمل التنظيف بصورة انتهازية بعد إنشاء الأثر.
- تُحذف الآثار منتهية الصلاحية.
- يزيل التنظيف الاحتياطي المجلدات القديمة التي يتجاوز عمرها 24 ساعة عند غياب بيانات التعريف.
عنوان URL للعارض وسلوك الشبكة
مسار العارض:
/plugins/diffs/view/{artifactId}/{token}
أصول العارض:
/plugins/diffs/assets/viewer.js/plugins/diffs/assets/viewer-runtime.js/plugins/diffs-language-pack/assets/viewer.jsعندما يستخدم الفرق لغة من حزمة لغة عارض الفروقات
يحلّ مستند العارض تلك الأصول نسبةً إلى عنوان URL للعارض، لذلك يُحفَظ بادئ مسار baseUrl الاختياري لطلبات الأصول أيضًا.
سلوك إنشاء عنوان URL:
- إذا تم توفير
baseUrlفي استدعاء الأداة، فيُستخدم بعد تحقق صارم. - وإلا، إذا تم تكوين
viewerBaseUrlفي Plugin، فيُستخدم. - من دون أي من التجاوزين، يكون عنوان URL للعارض افتراضيًا على loopback
127.0.0.1. - إذا كان وضع ربط Gateway هو
customوتم ضبطgateway.customBindHost، فيُستخدم ذلك المضيف.
قواعد baseUrl:
- يجب أن يكون
http://أوhttps://. - تُرفض الاستعلامات والهاش.
- يُسمح بالأصل مع مسار أساسي اختياري.
نموذج الأمان
تقوية العارض
- يقتصر افتراضيًا على loopback.
- مسارات عارض مرمّزة مع تحقق صارم من المعرّف والرمز.
- CSP لاستجابة العارض:
default-src 'none'- السكربتات والأصول من المصدر نفسه فقط
- لا يوجد
connect-srcصادر
- تقييد الإخفاقات البعيدة عند تمكين الوصول البعيد:
- 40 إخفاقًا كل 60 ثانية
- قفل لمدة 60 ثانية (
429 Too Many Requests)
تقوية عرض الملفات
- توجيه طلبات متصفح لقطات الشاشة يرفض افتراضيًا.
- يُسمح فقط بأصول العارض المحلية من
http://127.0.0.1/plugins/diffs/assets/*. - تُحظر طلبات الشبكة الخارجية.
متطلبات المتصفح لوضع الملف
يحتاج mode: "file" وmode: "both" إلى متصفح متوافق مع Chromium.
ترتيب الحل:
التكوين
browser.executablePath في تكوين OpenClaw.
متغيرات البيئة
OPENCLAW_BROWSER_EXECUTABLE_PATHBROWSER_EXECUTABLE_PATHPLAYWRIGHT_CHROMIUM_EXECUTABLE_PATH
الاحتياطي الخاص بالمنصة
احتياطي اكتشاف أمر/مسار المنصة.
نص فشل شائع:
Diff PNG/PDF rendering requires a Chromium-compatible browser...
أصلح ذلك بتثبيت Chrome أو Chromium أو Edge أو Brave، أو بضبط أحد خيارات مسار الملف التنفيذي أعلاه.
استكشاف الأخطاء وإصلاحها
أخطاء التحقق من الإدخال
Provide patch or both before and after text.— أدرج كلًا منbeforeوafter، أو وفّرpatch.Provide either patch or before/after input, not both.— لا تخلط بين أوضاع الإدخال.Invalid baseUrl: ...— استخدم أصلhttp(s)مع مسار اختياري، من دون استعلام/هاش.{field} exceeds maximum size (...)— قلّل حجم الحمولة.- رفض الرقعة الكبيرة — قلّل عدد ملفات الرقعة أو إجمالي الأسطر.
إمكانية الوصول إلى العارض
- يُحلّ عنوان URL للعارض إلى
127.0.0.1افتراضيًا. - في سيناريوهات الوصول البعيد، إما:
- اضبط
viewerBaseUrlفي Plugin، أو - مرّر
baseUrlلكل استدعاء أداة، أو - استخدم
gateway.bind=customوgateway.customBindHost
- اضبط
- إذا كان
gateway.trustedProxiesيتضمن loopback لوكيل على المضيف نفسه (مثل Tailscale Serve)، فإن طلبات عارض loopback الخام من دون ترويسات عنوان IP للعميل المُعاد توجيهها تفشل مغلقة حسب التصميم. - لذلك الهيكل الوكيلي:
- فضّل
mode: "file"أوmode: "both"عندما تحتاج إلى مرفق فقط، أو - مكّن
security.allowRemoteViewerعمدًا واضبطviewerBaseUrlفي Plugin أو مرّرbaseUrlلوكيل/عام عندما تحتاج إلى عنوان URL عارض قابل للمشاركة
- فضّل
- مكّن
security.allowRemoteViewerفقط عندما تقصد إتاحة وصول خارجي إلى العارض.
صف الأسطر غير المعدلة لا يحتوي زر توسيع
يمكن أن يحدث هذا مع إدخال الرقعة عندما لا تحمل الرقعة سياقًا قابلًا للتوسيع. هذا متوقع ولا يشير إلى فشل في العارض.
لم يتم العثور على الأثر
- انتهت صلاحية الأثر بسبب TTL.
- تغيّر الرمز أو المسار.
- أزال التنظيف بيانات قديمة.
إرشادات التشغيل
- فضّل
mode: "view"للمراجعات التفاعلية المحلية في اللوحة. - فضّل
mode: "file"لقنوات الدردشة الصادرة التي تحتاج إلى مرفق. - أبقِ
allowRemoteViewerمعطّلًا ما لم يتطلب النشر لديك عناوين URL بعيدة للعارض. - اضبط
ttlSecondsقصيرة وصريحة للفروقات الحساسة. - تجنّب إرسال الأسرار في إدخال الفرق عندما لا يكون ذلك مطلوبًا.
- إذا كانت قناتك تضغط الصور بقوة (مثل Telegram أو WhatsApp)، ففضّل مخرجات PDF (
fileFormat: "pdf").