dsh-web
zhu1090093659/dsh-webDeepSeek Harness(DSH)Web 插件聚合生态包 · 一切皆插件,创意工坊分发(dsh-market.com)
让 DSH 界面说阿拉伯语:混合阿拉伯文与英文的双向文本排版,通过 DSH 官方语言服务注册完整阿拉伯语界面包(3,307 条),并内置三款 thmanyah 字体(界面 Sans、正文 Serif Text、标题 Serif Display),置于应用自身字体设置之后。
العربية · English
العربية لتطبيق DeepSeek Harness — عرض RTL سليم تقنياً، وحزمة تعريب كاملة للواجهة، وخطّ ثمانية للواجهة.
DSH لا يدعم RTL ولا يوفّر لغة عربية. خلط النص العربي بأسماء المتغيّرات والمسارات والأكواد داخل الواجهة يجعل الكلام مبعثراً، وكل القوائم إنجليزية. هذا البلاقن يحل المشكلتين دون تعديل التطبيق نفسه.
الاتجاه يُحسم لكل كتلة بهيمنة الكلمات، لا بأول حرف قوي. والتقسيم على
المسافات فقط، فـ@deepseek-ai/dsh تُحسب كلمة واحدة لا ثلاثاً:
| المحتوى | الاتجاه | السبب |
|---|---|---|
كيف حالك Hello | RTL | الكلمات العربية غالبَة |
Hello كيف حالك | RTL | ما زالت جملة عربية — وdir="auto" يخطئ هنا |
Error: فشل الاتصال بالخادم | RTL | الجملة عربية والبادئة ليست كذلك |
npm install ثم أعد التشغيل | RTL | ٣ كلمات عربية مقابل ٢ لاتينية |
شغّل npx @deepseek-ai/dsh web | RTL | الرمز التقني يلصق npx … web في وحدة واحدة: عربية ١ مقابل لاتينية ١ |
راجع commit a4c1025b قبل النشر | RTL | البصمة المجرّدة لا تُصوِّت |
نسبة النجاح 15/15 | RTL | النسبة محايدة |
افتح src/index.ts ثم عدّل الدالة | RTL | المسار لا يُصوِّت |
"C:\Users\…\الخطوط\thmanyahseriftext" | بلا تغيير | مسار ويندوز رمز تقني ولو كان أحد مجلداته عربيًا |
@deepseek-ai/dsh مهم جدًا | RTL | المُعرِّف الواحد = وحدة واحدة |
Hello نص | RTL | التعادل يُحسم RTL |
The build failed while parsing سلام in the file | بلا تغيير | نص إنجليزي يقتبس كلمة يبقى LTR |
شغّل "git status" | RTL | الاقتباس وحدة واحدة: يُحتسب مرة لا مرتين |
pre وcode والكود المضمّن | LTR دائماً | الكود لا يُحكم عليه ولا يُقلب |
| مربّع الكتابة والبحث | يتبع ما تكتبه | RTL حين تغلب العربية، وإلا auto الأصلي |
القواعد الأربع خلف الجدول:
١. الرموز الشبيهة بالكود لا تُصوِّت — الروابط، المسارات (بما فيها شرطة ويندوز
المائلة الخلفية)، @scope/name، البصمات، 15/15، أسماء الملفات المنقوطة؛
فرابط واحد أو بصمة واحدة قد ترجّح على جملة عربية كاملة، والرمز التقني يلصق
الكلمات اللاتينية حوله في وحدة تقنية واحدة. والمسار الذي يحمل مجلدًا عربيًا
يبقى مسارًا: احتسابه نصًّا عربيًا هو ما كان يقلب كتلة مسارات إلى RTL، فيُعاد
ترتيب مقاطعها اللاتينية حول تلك الكلمة.
٢. الكلمات هي الوحدة لا الحروف — فالمصطلح اللاتيني أطول حروفاً وأقل كلمات.
والتعادل يُحسم للعربية، والكتلة التي لا كلمة عربية فيها تُحرَّر.
٣. تثبيت أثناء البثّ (hysteresis) — الكتلة التي صارت RTL تبقى كذلك حتى يصير
النص لاتينياً بوضوح (ضعف عدد الكلمات العربية)، فلا يتذبذب الرد المتدرّج.
٤. الاقتباس وحدة واحدة — "git status" نصٌّ مقتبس (أمر، عنوان، جملة) يُحتسب
مرة واحدة لا مرتين؛ فيُقرأ شغّل "git status" جملةً عربية كما هي، بينما
الكلمتان نفسهما بلا اقتباس تبقى LTR (انظر الحدود أدناه). وعلامة اقتباس غير
مغلقة — ردٌّ يتدفّق والاقتباس لم يُغلق بعد — تمتدّ إلى آخر النص، وهي الوحدة
نفسها التي سينتجها الاقتباس المغلق، فلا تذبذب لحظةَ الإغلاق.
كتل النص وحدها تُقلب — والهيكل لا يُقلب أبداً. حاوية flex أو grid تُعيد
ترتيب أبنائها عند القلب، والصف الذي يملك أزراراً هو شريط أدوات: كلاهما مُستثنى،
فيبقى زر الإرسال في مكانه رغم أن وسم الصلاحية العربي في الصف نفسه. والنص العربي
داخل ذلك الصف يعيش في كتلة نصية خاصة به فيُعالَج عادةً.
وشكلان احتاجا أكثر من قرار كتلة عادية، وكلٌّ منهما مُثبَّت باختبار وبـdata/card-pins.json:
button بـflex، ووسمها ووصفها span داخله. الـspan المضمّن فعلاً جزء من
التدفّق حوله، أما عنصر flex فهو كتلة نصية قائمة بذاتها: كل خلية تأخذ RTL،
فيُقرأ ادفع fix/rust-flake كما هو بترتيبه لا مقلوباً، ويبقى رقم الصف في مكانه؛<header>/<footer> بطاقة المحتوى. DSH يضع نص السؤال داخل <header>
(وheader وfooter علامتان للهيكل وتبقيان LTR). وإطار البطاقة يحمل
data-question-key — وهو المُعرِّف الوحيد الذي يقرأه هذا البلاقن من التطبيق —
فعلامة داخل البطاقة جزء من البطاقة، وسؤالها محتوى كأي فقرة.
وscripts/check-card-pins.mjs <app.asar> يفشل مسمّياً الفرق إذا تغيّر هذا
المُعرِّف أو لم يعد صف الخيارات صف flex؛flex يعكس ترتيب أيقونته ووسمه،
والوسم المتوسّط يقفز إلى حافة عند تجاوز المحاذاة. فيبقى الرقم حيث وضعه التصميم،
وتبقى أزرار البطاقة بتخطيطها، ويبدأ النص العربي بجانبها — البطاقة لا تُقلب، بل نصّها.
مُصيَّرة بـChromium بمحرّك bidi الحقيقي: الترميز والنصوص نفسها في اللوحين، مع خصائص dir التي يكتبها البلاقن في اللوح الأيمن. ورقم الخيار يبقى في اليسار في الحالتين. المصدر: docs/question-card.html.
وإذا كان اتجاه كتلة ما مضبوطاً من التطبيق أو منك (dir="ltr" في الترميز)، فلا
نلمسه أبداً — وهذا هو المخرج الاحتياطي لأي كتلة يُخطئ فيها المُقدِّر.
شغّل git status يبقى LTR: كلمتان
لاتينيتان عاديتان ترجّحان على كلمة عربية، ولا فاصل تقني يلصقهما. وقد جُرِّب
اعتبار كل تتابع لاتيني وحدة واحدة فرُفض — لأنه يقلب فقرات إنجليزية تقتبس كلمة عربية.
والاقتباس هو العلاج بيد القارئ: شغّل "git status" ينقلب.code من اليسار
إلى اليمين، فيُقرأ المسار بترتيبه (مُتحقَّق منه في Chromium).ا ل ع ر ب ي ة). هذا قيد في المصدر، نوثّقه ولا نتظاهر بإصلاحه.flex/grid والصفوف التي تملك أزراراً من قرار الاتجاه — فيُقرأ وسم الصلاحية
العربي في شريط المُحرِّر من اليمين دون أن ينتقل زر الإرسال. الخطة المعتمدة تعتمد
المصدر أولاً — انظر docs/roadmap.md.نهج هيمنة الكلمات، وقاعدة «المُعرِّف الواحد كلمة واحدة»، وفكرة حذف الرموز الشبيهة بالكود قبل العدّ — كلها تتبع الإجماع المجتمعي الذي بدأه haythamat/dsh-client-ui-rtl وkfirsch/dsh-hebrew-rtl (رخصة MIT لكلٍّ منهما)؛ وهذا التنفيذ مستقل، ويضيف طبقة مربّع الكتابة والمفتاح والتثبيت أثناء البثّ، ومغطّى باختباراته.

مُصيَّرة بمتصفح Chromium بمحرّك bidi الحقيقي: العمودان يحملان الأسطر الخمسة نفسها، وكلٌّ منها يبدأ بمُعرِّف لاتيني. المصدر: docs/direction.html.
لا يقلب الواجهة كلها إلى RTL. واجهات المطوّرين ثنائية اللغة بطبيعتها، واتجاه كل كتلة على حدة هو ما يُبقي اللغتين مقروءتين.
مُسجَّلة عبر خدمة الترجمة الرسمية (ctx.locale.addLanguage + ctx.locale.register)
— أي بالنفس الآلية التي يستخدمها التطبيق نفسه، بلا استبدال نصوص في DOM وبلا
تعديل دوال قائمة:
fallback: 'en')التغطية وكل قرار ترجمة غير بديهي قابلة للتدقيق في
data/en-catalog.json (مجموعة المفاتيح الإنجليزية الرسمية)،
وlocales/ar.json (الحزمة العربية)،
وdata/overrides.json (توحيد الصيغ بين الدفعات).
العربية تُضاف كخيار ولا تُفرض أبداً:
localStorage). عند الإيقاف لا تُوسَم أي كتلة
ولا يُضبط اتجاه أي خانة كتابة — تتصرّف الواجهة تماماً كما لو لم يكن البلاقن موجوداً.ثلاث قطع من ثمانية، كلٌّ في الدور الذي رُسم له:
| الدور | القطع | أين يظهر |
|---|---|---|
| الواجهة | ثمنية سانس | الافتراضي: الوسوم والأزرار والهيكل والنصوص الصغيرة |
| القراءة | ثمنية سيريف تيكست | فقرات الماركداون وعناصر القوائم والاقتباسات |
| العناوين | ثمنية سيريف ديسپلاي | h1–h6 |
وسطر واحد يحمل دور الواجهة — البلاقن يعيد تعريف --dsw-font-family، المتغيّر الذي
تمرّ منه كل رموز الطباعة في سمة التطبيق — وقاعدتان للعناصر تحملان الدورين
الآخرين. وتبقى حزمة خطوط التطبيق خلف كل عائلة في التعريف نفسه، وخطّ الكود لا
يُلمس، وكل دور يصمت إن غابت ملفاته.
ومنذ DSH 0.2.1 صار ذلك المتغيّر وسيطاً داخلياً عند التطبيق نفسه: يحمل على body
قيمة --dsh-font-family-text — الخط الذي تختاره من الإعدادات ← عام — قبل
حزمة خطوطه المدمجة. فصار البلاقن يسمّي قطعه احتياطياً لذلك المتغيّر لا قيمةً
له: خطٌّ تختاره في حقل التطبيق يتقدّم على قطعنا في الواجهة والفقرات والعناوين
جميعاً، وحقلٌ فارغ — وحينها لا يكتب التطبيق شيئاً — يُبقي ثمانية في مكانها.
والمتغيّر يُقرأ ولا يُعرَّف أبداً، وهذا ما يحفظ ذلك الترتيب.
والأوزان في fonts/ — مجلد فرعي لا جذر المستودع — ومعه
نصّا الرخصة (والعربية هي الحاكمة)، ويخدمها البلاقن من /dsh-arabic/fonts/ على
خادم التطبيق نفسه: نسخة الديسكتوب تحمّل صفحتها من http://127.0.0.1:<port>
فيعمل الرابط نفسه في الوجهين، وتحمل الصفحة تسع قواعد @font-face قصيرة بدل نحو
ميغابايت من base64. ووجّه DSH_ARABIC_FONTS إلى مجلد بالبنية نفسها لتُزوّد نسخةً
أخرى، أو إلى مجلد فارغ لتُبقي خط التطبيق الأصلي — الطبقة تصمت، لا تتعطّل.
لا يتغيّر شيء في الواجهة حتى تختاره أنت.
# من npm
dsh plugin --profile desktop add dsh-arabic
# أو من نسخة محلية (للتطوير)
dsh plugin --profile desktop add link:/المسار/الكامل/dsh-arabic
أو من داخل التطبيق: الإعدادات ← Plugins ← Plugin Manager.
أعد تشغيل DSH بعد التثبيت. تحميل البلاقن نفسه يُقرَّر عند إقلاع المضيف (بوابة الأقران)؛ أما جدول الحقن فيُجمَع عند كل تصيير للصفحة، فتحديث الصفحة يعيد تجميعه بعد الإقلاع.
التوافق: لا سقف أعلى. يُقبل البلاقن على أي نسخة DSH عند
0.2.0أو أحدث؛ التحديثات الأحدث لا تمنع تشغيله، لأن معظمها لا يمسّ نقاط التكامل هذه. وما هو أقدم من0.2.0وحده يُرفض. بوابة الفحص تُنبّه — لا تمنع — إن كانت النسخة أحدث من آخر نسخة مُختبرة (data/tested-runtimes.json).
ثم لتفعيل الواجهة العربية: الإعدادات ← عام ← Language ← العربية. طبقة RTL تعمل مع أي لغة بمجرد تحميل البلاقن.
index.js النصف المضيف
└── صفوف webserver/index-inject
├── { kind: 'style', text: <CSS الاتجاه> }
└── { kind: 'script', placement: 'body', text: <سكربت الوسم> }
lib/client.js النصف البرمجي في المتصفح (مُولَّد)
└── window.__ModuleLoader__.load({ id, factory })
├── ctx.locale.addLanguage({ id: 'ar', label: 'العربية', fallback: 'en' })
│ ctx.locale.register(namespace, 'ar', dictionary) × 59
└── ctx.slots.inject('settings.general.item', …)
└── صف Switch واحد → window.__dshArabic.setEnabled()
لا اعتماديات خارجية على مستوى التحميل: react والمكوّنات الرسمية تُطلَب فقط عند
وجود مقعد الإعدادات، وذاك التسجيل محروس بحيث لا يُسقط تغيير مستقبلي في المواقع
حزمةَ اللغة معه.
| المسار | الغرض |
|---|---|
index.js | النصف المضيف: صفوف حقن الاتجاه |
lib/client.js | النصف البرمجي المُولَّد: حزمة اللغة العربية |
locales/ar.json | القواميس المترجمة |
data/en-catalog.json | مجموعة المفاتيح الإنجليزية الرسمية المستخرجة من مصادر DSH |
data/en-catalog.meta.json | مرجع/بصمة upstream التي قيست عليها المجموعة |
data/glossary.yml | المسرد الآلي (المصطلح، العربية، ما يُتجنّب، ما لا يُترجم) |
data/overrides.json | توحيد الصيغ حيث اختلفت الدفعات المتوازية |
data/term-map.json | تطبيع المصطلحات المُطبَّق على كل قيمة في الخط |
data/bidi-decisions.json | كل عزل في عائلة سطر الحالة — وكل قيمة مختلطة — بسببها |
data/shimmer-pins.json | أسماء الفئات والـkeyframes المُجزأة التي قيست عليها مرآة الوميض |
scripts/extract-catalog.mjs | يعيد توليد data/en-catalog.json من المصادر الرسمية (npm run extract) |
scripts/status.mjs | نسبة التغطية مقابل مرجع upstream المسجَّل (npm run status) |
scripts/build-client.mjs | يتحقق من الحزمة ويعيد توليد lib/client.js (--check لـ CI) |
scripts/assemble-translations.mjs | يدمج دفعات الترجمة في locales/ar.json |
scripts/lint-consistency.mjs | يكشف ترجمة النص الإنجليزي الواحد بصيغتين |
scripts/check-bidi-family.mjs | يفشل — بتسمية المفتاح — على أي عزل غير مسجَّل في عائلة سطر الحالة |
scripts/check-shimmer-pins.mjs | يعيد التحقق من أسماء مرآة الوميض مقابل app.asar مثبَّت (خطوة إصدار) |
tests/golden-direction.mjs | ٤٥ نصاً ذهبياً مع الاتجاه الواجب لكلٍّ منها |
fonts/ | قطع ثمنية الثلاث (سانس · سيريف تيكست · سيريف ديسپلاي) بأوزان 400/500/700 + نصّا الرخصة (العربي حاكم)، والمجلد فرعي لا جذر للمستودع |
docs/roadmap.md | الطبقات الثلاث، وطلبات المصدر، وما لا ننوي فعله |
AUDIT.md | كيف بُني المشروع: كل خطوة وأمر ونتيجة بوابة |
CONTRIBUTING.md | كيف تضيف ترجمة أو تصلحها، والفحوص التي يشغّلها CI |
tests/verify-rtl.mjs | ٦٧ اختباراً سلوكياً لطبقة الاتجاه على محاكي DOM |
tests/verify-locales.mjs | سلامة الكتالوج وعقد الملف وتسجيل اللغة |
data/card-pins.json | شكل بطاقة السؤال (المُعرِّف والعلامات وصفّ flex)، يُعاد التحقق منه من app.asar المثبَّت (خطوة إصدار) |
npm test # الاتجاه (67) + الترجمة (32) + المصفوفة الذهبية (45) + الخطوط (28)
npm run check # الاكتمال + تدقيق الاتساق + المصفوفة الذهبية
npm run build # إعادة توليد lib/client.js
npm run status # التغطية مقابل مرجع upstream المسجَّل
سير عمل أسبوعي (.github/workflows/upstream-sync.yml)
يعيد استخراج مجموعة المفاتيح الرسمية ويفتح PR بالمفاتيح الجديدة وحدها، فيصل
الانحراف كفرق قابل للمراجعة لا كمفاجأة:
GITHUB_TOKEN=$(gh auth token) npm run extract # تحديث data/en-catalog.json
node scripts/build-client.mjs --check # سرد كل مفتاح غير مترجم
npm run status # التغطية + مرجع upstream
المفاتيح الناقصة تعود للإنجليزية وقت التشغيل — فتحديث جزئي لا يكسر الواجهة أبداً. انظر CONTRIBUTING.md وخطة الطريق.
مُختبَر على DSH 0.2.0-rc.2 (تطبيق الديسكتوب) و0.2.1-alpha.2 (نسخة ويب
مخدومة بـdsh web). الوجهان يستخدمان التقاطعين الداخليين الموثّقين نفسهما — الحدث
webserver/index-inject وخدمة locale في العميل — ويتدهور البلاقن بأمان إن تغيّر
أحدهما: طبقة الاتجاه مُغلَّفة فلا تكسر أبداً عرض الفهرس، وحزمة اللغة تتوقف عن
التسجيل فحسب. وفي نسخة الديسكتوب يُجمَع جدول الحقن مرة واحدة عند إقلاع المضيف،
فالمطلوب إعادة تشغيل لا تحديث صفحة.
ومنذ 0.2.1 صار للتطبيق دور خطوط يختاره المستخدم (نص الواجهة، الكود، طرفية
الشريط الجانبي): يكتب التطبيق ما تختاره في --dsh-font-family-text على body،
فتُسمّى قطعنا احتياطياً لذلك المتغيّر — خطٌّ تختاره يتقدّم، وقطعنا يرسم ما لا
يرسمه (العربية عادةً)، وحقلٌ فارغ يُبقي ثمانية في المقدّمة. والمتغيّر يُقرأ ولا
يُعرَّف أبداً، وهذا الترتيب مُثبَّت في tests/verify-fonts.mjs.
التفاعل مع بلاقنز عربية/RTL أخرى. بلاقننا وdsh-client-ui-rtl أو
dsh-rtl-fix كلاهما يضبط dir على كتل المحتوى؛ وتثبيت اثنين معاً يعني تناوبهما
ويفوز آخر كاتب. مفتاح الإعدادات في «عام» يوقف طبقتنا، وهو الطريق النظيف للجمع
بينهما. وكذلك تسجيل لغتين بالمعرّف ar (يفعله @mimateinn/dsh-i18n بتغطية
مختلفة) سيتنازع على المعرّف نفسه — اختر واحداً.
المصطلح. «بلاقن» اختيار واعٍ: هي الصيغة التي يستخدمها المطوّرون العرب في
كلامهم، بينما يبقى plugin في النطاقات التقنية (أسماء الحزم، المسارات، مخرجات
الطرفية). وإن فضّلت الكلمة اللاتينية في الواجهة فالقاموس على بعد تعديل واحد —
انظر CONTRIBUTING.md.
MIT — انظر LICENSE.