diff --git a/README.md b/README.md index 95673de4b..98b5f41ab 100644 --- a/README.md +++ b/README.md @@ -20,6 +20,7 @@
Language: English | + العربية | Português (Brasil) | 简体中文 | 繁體中文 | diff --git a/README.zh-CN.md b/README.zh-CN.md index c098f5f41..594f6210e 100644 --- a/README.zh-CN.md +++ b/README.zh-CN.md @@ -23,7 +23,7 @@ **Language / 语言 / 語言 / Dil / Язык / Ngôn ngữ** -[**English**](README.md) | [Português (Brasil)](docs/pt-BR/README.md) | [简体中文](README.zh-CN.md) | [繁體中文](docs/zh-TW/README.md) | [日本語](docs/ja-JP/README.md) | [한국어](docs/ko-KR/README.md) | [Türkçe](docs/tr/README.md) | [Русский](docs/ru/README.md) | [Tiếng Việt](docs/vi-VN/README.md) | [ไทย](docs/th/README.md) | [Deutsch](docs/de-DE/README.md) | [Polski](docs/pl/README.md) +[**English**](README.md) | [العربية](docs/ar/README.md) | [Português (Brasil)](docs/pt-BR/README.md) | [简体中文](README.zh-CN.md) | [繁體中文](docs/zh-TW/README.md) | [日本語](docs/ja-JP/README.md) | [한국어](docs/ko-KR/README.md) | [Türkçe](docs/tr/README.md) | [Русский](docs/ru/README.md) | [Tiếng Việt](docs/vi-VN/README.md) | [ไทย](docs/th/README.md) | [Deutsch](docs/de-DE/README.md) | [Polski](docs/pl/README.md) diff --git a/docs/ar/GLOSSARY.md b/docs/ar/GLOSSARY.md new file mode 100644 index 000000000..9a7916e89 --- /dev/null +++ b/docs/ar/GLOSSARY.md @@ -0,0 +1,63 @@ +# مسرد المصطلحات / Glossary + +مسرد المصطلحات الموحد للترجمة العربية لمشروع ECC. + +المبدأ التوجيهي: تظل أسماء واجهات ECC الأساسية والمصطلحات التقنية المعتمدة باللغة الإنجليزية كما هي (`agents/`، `skills/`، `hooks/`، `rules/`، `commands/`) عندما يكون تعريبها سبباً في صعوبة ربط النص باسم المجلد أو الأمر البرمجي أو واجهة الاستخدام في بيئة العمل. في السياق الوصفي العام، يمكن استخدام المقابل العربي الموضح أدناه. + +| المصطلح بالإنجليزية (English) | المقابل بالعربية (Arabic) | ملاحظات وسياق الاستخدام | +|---|---|---| +| Agent | Agent / وكيل | اسم واجهة `agents/` البرمجية؛ الجمع: وكلاء | +| Skill | Skill / مهارة | اسم واجهة `skills/`؛ الجمع: مهارات | +| Hook | Hook / خُطاف أو معالج أحداث | اسم واجهة `hooks/`؛ معالجات أحداث بيئة العمل | +| Command | Command / أمر | اسم واجهة `commands/`؛ عامةً: "أمر برمجيات" | +| Rule | Rule / قاعدة | اسم واجهة `rules/`؛ عامةً: "قاعدة توجيهية" | +| Harness | بيئة تشغيل الوكيل (Harness) | يُبقى على Harness كمصطلح تقني أصيل لنظام التشغيل | +| Instinct | Instinct / غريزة برمجية | مصطلح مستخدم في ميزة Continuous Learning | +| Plugin | إضافة (Plugin) | حزمة برمجية متكاملة لبيئة العمل | +| Marketplace | سوق الإضافات (Marketplace) | مستودع الإضافات المعتمد | +| Worktree | شجرة عمل (Worktree) | مصطلح Git لبيئات العمل المتوازية | +| Subagent | وكيل فرعي (Subagent) | وكيل منبثق لمهمة محددة | +| Frontmatter | الترويسة التعريفية (Frontmatter) | بيانات YAML الوصفية أعلى الملفات | +| Continuous Learning | التعلّم المستمر | ميزة استخلاص التجارب وتطوير الأنماط | +| Memory | الذاكرة / نظام الذاكرة | كمفهوم بنيوي في ECC: مستودع الذاكرة | +| Context window | نافذة السياق | سعة الرموز المتاحة للنموذج في الجلسة | +| Token | رمز / وحدة معالجة (Token) | أصغر وحدة نصية يفهمها النموذج | +| Coverage | نسبة التغطية (Test Coverage) | تغطية الاختبارات البرمجية للكود | +| Test-Driven Development | التطوير الموجه باختبارات | يُحافظ على الاختصار TDD | +| Code review | مراجعة الكود البرمجي | فحص جودة وشروط الكود | +| Refactoring | إعادة هيكلة الكود (Refactoring) | تحسين بنية الكود دون تغيير سلوكه | +| Pull request | طلب السحب (PR) | طلب دمج التعديلات في المستودع | +| Commit | إيداع / تثبيت (Commit) | تسجيل التغييرات في سجل Git | +| Branch | فرع (Branch) | مسار تطوير مستقل | +| Merge | دمج (Merge) | دمج فرع في آخر | +| Build | بناء (Build) | إنتاج الحزمة البرمجية النهائية | +| Deploy | نشر (Deploy) | إطلاق البرمجية في بيئة التشغيل | +| Pipeline | خط أنابيب المعالجة (Pipeline) | مسار أتمتة العمليات البرمجية | +| Orchestration | التنسيق التلقائي (Orchestration) | إدارة تفاعل الوكلاء والمهام | +| Repository | مستودع (Repository) | اختصاراً: مستودع (Repo) | +| Dependency | تبعية برمجية (Dependency) | الجمع: تبعيات | +| Edge case | حالة طرفية / حدّية | سيناريو غير تقليدي في عمل البرنامج | +| Best practice | أفضل الممارسات | المعايير الهندسية الفضلى الموصى بها | +| Anti-pattern | نمط مضاد (Anti-pattern) | ممارسة برمجية تبدو حلاً ولكنها تخلق مشاكل | +| Middleware | برمجية وسيطة (Middleware) | طبقة اعتراض ومعالجة الطلبات | +| Endpoint | نقطة نهاية (Endpoint) | رابط واجهة برمجة التطبيقات (API) | +| Schema | مخطط هيكلي (Schema) | توصيف بنية البيانات وقواعدها | +| Payload | حمولة البيانات (Payload) | البيانات المرسلة في الطلب البرمجي | +| Callback | رد نداء (Callback) | دالة تُنفذ كرد على حدث معين | +| Checkpoint | نقطة فحص / استعادة | نقطة حفظ مرحلية لحالة العمل | +| Linter | أداة فحص الكود (Linter) | مدقق المعايير الصياغية للكود | +| Formatter | أداة تنسيق الكود (Formatter) | منظم شكل وترتيب الكود البرمجي | +| Staging | بيئة الاختبار والتجهيز (Staging) | بيئة تحاكي بيئة الإنتاج قبل الإطلاق | +| Production | بيئة الإنتاج (Production) | البيئة الحية المستخدمة فعلياً | +| Debugging | تنقيح الأخطاء (Debugging) | تشخيص وإصلاح العلل البرمجية | +| Logging | تسجيل السجلات (Logging) | تدوين أحداث وسجلات النظام | +| Monitoring | المراقبة والمتابعة (Monitoring) | رصد أداء واستقرار الخدمات البرمجية | +| Rate limit | حد معدل الطلبات (Rate Limit) | السقف الزمني المسموح به للطلبات | +| Retry | إعادة المحاولة (Retry) | تكرار تنفيذ عملية فشلت مؤقتاً | +| Fallback | خيار بديل / مسار تراجعي | آلية عمل بديلة عند تعذر المسار الأساسي | +| Sandboxing | العزل في بيئة آمنة (Sandboxing) | تشغيل الكود في بيئة محكمة معزولة | +| Sanitization | تنقية وتطهير البيانات | تنظيف المدخلات من الشوائب والرموز غير الآمنة | +| Selective install | التثبيت الانتقائي | تثبيت مكونات محددة وفق الاحتياج | +| Profile | ملف تعريف التثبيت (Profile) | إعداد مسبق لحزمة التثبيت | +| Component | مكوّن (Component) | عنصر معرف ضمن كتالوج المثبت | +| Module | وحدة نمطية (Module) | وحدة ملفات قابلة للتثبيت والنقل | diff --git a/docs/ar/README.md b/docs/ar/README.md new file mode 100644 index 000000000..818ba29d9 --- /dev/null +++ b/docs/ar/README.md @@ -0,0 +1,174 @@ +**اللغة:** [English](../../README.md) | **العربية** | [Deutsch](../de-DE/README.md) | [Español](../es/README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) + +# ECC + + + +> يغطي هذا التوثيق دليل البدء السريع والواجهات والمفاهيم الأساسية لنظام ECC. +> مصدر المحتوى الإنجليزي المعتمد هو الفرع main في المستودع الرسمي. +> يظل الكتالوج الكامل والمحدّث باستمرار متوفراً في [README باللغة الإنجليزية](../../README.md)؛ +> وتتم متابعة وتحديث الأقسام دورياً لضمان الدقة والتوافق. + +--- + +**نظام تشغيل مهام الوكلاء الأصلي لبيئات العمل (Harness-Native Agent Operating System).** + +مشروع ECC ليس مجرد مجموعة من ملفات الإعداد الثابتة. بل يدمج وكلاء متخصصين (Agents)، +ومهارات معيارية (Skills)، ومعالجات أحداث تلقائية (Hooks)، وقواعد توجيهية (Rules)، +وتكوينات بروتوكول سياق النموذج (MCP)، وطبقة توافق للأوامر السابقة (Commands). +صُمم النظام بناءً على ممارسات عمل حقيقية ويمتد ليعمل بتناسق عبر بيئات متعددة: +**Claude Code**، **Codex**، **Cursor**، **OpenCode**، **Gemini**، **Zed**، **GitHub Copilot** وغيرها الكثير. + +## المصادر الرسمية + +ثبّت ECC حصرياً عبر القنوات الرسمية المعتمدة: + +- مستودع المشروع الرسمي: [github.com/affaan-m/ECC](https://github.com/affaan-m/ECC) +- حزم npm المعتمدة: [`ecc-universal`](https://www.npmjs.com/package/ecc-universal) و[`ecc-agentshield`](https://www.npmjs.com/package/ecc-agentshield) +- تطبيق [ECC Tools على GitHub](https://github.com/apps/ecc-tools) +- معرّف الإضافة المعتمد: `ecc@ecc` +- الموقع الرسمي: [ecc.tools](https://ecc.tools) + +يُرجى الحذر من النسخ غير الرسمية أو المستودعات البديلة غير المعتمدة حيث لا تخضع للمراجعة الأمنية أو الصيانة من قبل فريق المشروع. + +## البدء السريع + +اختر **طريقة تثبيت واحدة فقط**. الجمع بين تثبيت الإضافة والتثبيت اليدوي الكامل هو السبب الأكثر شيوعاً لتكرار الوكلاء والمهارات والخطافات. + +### الإعداد التفاعلي الموجه (الموصى به) + +```bash +npx ecc-universal@2.2.1 setup +``` + +يمكنك أيضاً استخدام مدير الحزم المفضل لديك: + +```bash +pnpm dlx ecc-universal@2.2.1 setup +yarn dlx ecc-universal@2.2.1 setup +bunx ecc-universal@2.2.1 setup +``` + +قبل تشغيل كود الحزمة، تحقق من مصدر الإصدار وسلامة السجل المعتمد. + +### Claude Code + +في Claude Code، أضف سوق الإضافات ثم ثبّت الإضافة المعتمدة: + +```text +/plugin marketplace add https://github.com/affaan-m/ECC +/plugin install ecc@ecc +``` + +بعد ذلك، ابدأ بـ `rules/common` بالإضافة إلى حزم اللغات وأطر العمل التي تستخدمها بالفعل في مشروعك. +تحذير مهم: بعد إتمام تثبيت الإضافة عبر `/plugin install`، لا تقم بتشغيل أمر التثبيت الكامل `./install.sh --profile full` إطلاقاً لتجنب تكرار الوكلاء والمهارات. + +### Codex + +```bash +codex plugin marketplace add affaan-m/ECC +codex plugin add ecc@ecc +``` + +في Codex، استخدم `$configure-ecc` لإجراء التكوين المخصص المناسب لمزود الخدمة في بيئتك. + +### البيئات الأخرى (Other Harnesses) + +شغّل الأوامر التالية من المجلد الرئيسي للمستودع المحلي بعد تنزيله. يختار سطر OpenCode الملف التعريفي الكامل ويفعّل الخطافات التلقائية صراحة. + +| بيئة العمل (Harness) | أمر التثبيت من المستودع | +|---|---| +| Cursor | `./install.sh --profile minimal --target cursor` | +| Gemini CLI | `./install.sh --profile minimal --target gemini` | +| Zed | `./install.sh --profile minimal --target zed` | +| OpenCode | `npm install && npm run build:opencode && ./install.sh --profile full --target opencode --enable-hooks` | +| Hermes | `./install.sh --profile minimal --target hermes` | +| OpenClaw | `./install.sh --profile minimal --target openclaw` | +| Kimi Code CLI | `./install.sh --profile minimal --target kimi` | + +للاطلاع على مصفوفة الدعم الكاملة لكافة المنصات والمتطلبات التفصيلية، راجع [قسم Platform Support في README الأساسي](../../README.md#platform-support). + +## تثبيت التوثيق العربي + +تستخدم اللغة العربية الرمز `ar`، ويُقبل أيضاً الاسم المستعار `ar-SA`. استخدم نسخة محلية من المستودع تحتوي على الدليل `docs/ar/` والمكوّن `locale:ar`. نفّذ الأوامر التالية من المجلد الرئيسي للمستودع بعد تثبيت تبعيات المشروع (يتطلب Node.js 18 أو أحدث). الإصدار الحالي من حزمة `ecc-universal` قد لا يتضمن التوثيق العربي بعد. + +أولاً، عاين خطة التثبيت دون كتابة الملفات (Dry Run): + +```bash +node scripts/install-apply.js --target claude --locale ar --dry-run +``` + +ثم ثبّت التوثيق العربي في المسار `~/.claude/docs/ar/`: + +```bash +node scripts/install-apply.js --target claude --locale ar +``` + +يثبت هذا الخيار وحدة التوثيق `docs-ar` بشكل مستقل؛ ولا يثبت الملف التعريفي الكامل لـ ECC ولا الخطافات التلقائية. + +## مكونات وواجهات ECC + +| الواجهة | الدور البرمجي والوظيفي | +|---|---| +| `agents/` | وكلاء متخصصون للتخطيط والتنفيذ والمراجعة والتشخيص | +| `skills/` | إجراءات ومعارف نمطية متخصصة تُحمّل عند الحاجة إليها في المهمة | +| `hooks/` | أتمتة ومعالجات أحداث تُنفّذ عند وقوع أحداث محددة في بيئة العمل | +| `rules/` | قواعد توجيهية دائمة ومعايير خاصة باللغات وأطر العمل | +| `commands/` | طبقة توافق مع الأوامر السابقة للأوامر المسبوقة بشرطة مائلة | +| `mcp-configs/` | تكوينات خوادم بروتوكول سياق النموذج (Model Context Protocol) | +| `manifests/` | بيانات تعريفية معيارية للوحدات والمكونات وملفات التثبيت | + +يعتمد مسار المشروع منهجية **المهارات أولاً (skills-first)**: حيث تُضاف مهام سير العمل الجديدة أولاً إلى `skills/`؛ وتبقى `commands/` كواجهة توافق حيثما دعت الحاجة. + +## المفاهيم الأساسية + +### الوكلاء (Agents) + +يمتلك كل وكيل دوراً محدداً، ومجموعة أدوات مخصصة، وأسلوب عمل واضحاً؛ مثل وكيل التخطيط، ومراجعي الكود للغات البرمجية المختلفة، ومتخصصي تشخيص وحل أخطاء البناء والترجمة. + +### المهارات (Skills) + +تحتوي المهارة على إجراء عمل مركز أو معرفة بمجال تقني محدد. بفضل ذلك، يُحمّل السياق فقط عندما يلائم المهمة الحالية، بدلاً من إثقال كل موجّه نظام (System Prompt) بسياق عام غير ضروري. + +### الخطافات (Hooks) + +تستجيب الخطافات للأحداث البرمجية مثل بدء الجلسة أو استدعاء الأدوات. صُممت الخطافات لتكون آمنة وقابلة للنقل؛ ولا يلزم نسخها يدوياً إلى ملف الإعدادات بعد تثبيت الإضافة، حيث تقوم الإصدارات الحديثة من بيئات العمل بتحميل `hooks/hooks.json` تلقائياً. + +### القواعد (Rules) + +تحدد القواعد الأعراف والاصطلاحات البرمجية الواجب اتباعها دائماً. ثبّت النواة المشتركة والحزم المطابقة لاحتياجاتك فقط، لتجنب استهلاك نافذة السياق بقواعد لا صلة لها بالمشروع. + +للاطلاع على تفاصيل تعريب المفاهيم والمصطلحات، راجع [مسرد المصطلحات العربي](GLOSSARY.md). + +## الأمان والخصوصية + +- لا تقم أبداً بتخزين مفاتيح واجهات برمجة التطبيقات (API Keys) أو كلمات المرور أو الرموز السرية داخل المستودع. +- راجع السكربتات ومصادر الحزم قبل تشغيلها في بيئتك. +- تجنب الجمع بين عدة طرق تثبيت لتفادي تضارب وتكرار الملفات. +- لا تنسخ ملف `hooks/hooks.json` الخام مباشرة إلى `~/.claude/settings.json` بعد تثبيت الإضافة. +- التزم بمبدأ الحد الأدنى من الصلاحيات وتحقق من سلامة المدخلات عند حدود النظام. + +للمزيد من الإرشادات الأمنية، راجع [قسم Security في README الأساسي](../../README.md#security). + +## تحديث التعريب والمساهمة + +تتم صيانة التوثيق المترجم وفق أفضل الممارسات المستمرة. يُستحسن في كل طلب سحب (PR) توضيح ما يلي: + +1. رقم إيداع المصدر الإنجليزي (Commit SHA) المعتمد. +2. النطاق الدقيق للمحتوى المترجم أو المحدّث. +3. أي تعديلات أو إضافات على [مسرد المصطلحات](GLOSSARY.md). +4. نتائج فحوصات الروابط وسلامة التنسيق ومخططات التثبيت (Manifests). + +يُفضل أن تكون طلبات السحب مركزة ومقسمة حسب المجال (مثل `docs/`، `agents/`، `skills/`) لتسهيل المراجعة والمزامنة مع المستودع الأساسي. + +## المساهمة في المشروع + +قبل البدء في ترجمات موسعة أو ميزات جديدة، راجع المهام وقوائم النقاش المفتوحة لتنسيق الجهود وتجنب العمل المزدوج. للاطلاع على الإرشادات الكاملة للمساهمة، راجع [CONTRIBUTING.md](../../CONTRIBUTING.md). + +## الترخيص + +مرخص بموجب رخصة MIT — يمنحك ذلك حرية الاستخدام والتعديل ومشاركة التحسينات مع مجتمع المطورين. + +--- + +**إذا كان ECC يقدم لك قيمة في عملك، شارك بنجمة للمستودع، واقرأ الأدلة، وابنِ برمجيات استثنائية.** diff --git a/docs/de-DE/README.md b/docs/de-DE/README.md index c520a611c..561608611 100644 --- a/docs/de-DE/README.md +++ b/docs/de-DE/README.md @@ -1,4 +1,4 @@ -**Sprache:** [English](../../README.md) | [Deutsch](README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) +**Sprache:** [English](../../README.md) | [العربية](../ar/README.md) | [Deutsch](README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) # ECC @@ -27,7 +27,7 @@ **Language / 语言 / 語言 / Dil / Язык / Ngôn ngữ** -[English](../../README.md) | [**Deutsch**](README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) +[English](../../README.md) | [العربية](../ar/README.md) | [**Deutsch**](README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) diff --git a/docs/es/README.md b/docs/es/README.md index 954adaa86..f3fd565f8 100644 --- a/docs/es/README.md +++ b/docs/es/README.md @@ -1,4 +1,4 @@ -**Idioma:** [English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Deutsch](../de-DE/README.md) | **Español** | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) +**Idioma:** [English](../../README.md) | [العربية](../ar/README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Deutsch](../de-DE/README.md) | **Español** | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) # ECC diff --git a/docs/ja-JP/README.md b/docs/ja-JP/README.md index 3c772b7bd..89de43bd1 100644 --- a/docs/ja-JP/README.md +++ b/docs/ja-JP/README.md @@ -20,6 +20,7 @@
Language: English | + العربية | Português (Brasil) | 简体中文 | 繁體中文 | diff --git a/docs/ko-KR/README.md b/docs/ko-KR/README.md index 25be75d36..9f0c29822 100644 --- a/docs/ko-KR/README.md +++ b/docs/ko-KR/README.md @@ -1,4 +1,4 @@ -**언어:** [English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | 한국어 | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) +**언어:** [English](../../README.md) | [العربية](../ar/README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | 한국어 | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) # ECC diff --git a/docs/pl/README.md b/docs/pl/README.md index 582549f6b..7881c6362 100644 --- a/docs/pl/README.md +++ b/docs/pl/README.md @@ -1,4 +1,4 @@ -**Język:** [English](../../README.md) | **Polski** | [Deutsch](../de-DE/README.md) | [Español](../es/README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Українська](../uk-UA/README.md) +**Język:** [English](../../README.md) | [العربية](../ar/README.md) | **Polski** | [Deutsch](../de-DE/README.md) | [Español](../es/README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Українська](../uk-UA/README.md) # ECC diff --git a/docs/pt-BR/README.md b/docs/pt-BR/README.md index 5cd268864..8fed5e513 100644 --- a/docs/pt-BR/README.md +++ b/docs/pt-BR/README.md @@ -1,4 +1,4 @@ -**Idioma:** [English](../../README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | Português (Brasil) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) +**Idioma:** [English](../../README.md) | [العربية](../ar/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | Português (Brasil) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) # ECC diff --git a/docs/ru/README.md b/docs/ru/README.md index beeb4e59e..09a9794c7 100644 --- a/docs/ru/README.md +++ b/docs/ru/README.md @@ -1,4 +1,4 @@ -**Язык:** [English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | **Русский** | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) +**Язык:** [English](../../README.md) | [العربية](../ar/README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | **Русский** | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) # ECC diff --git a/docs/th/README.md b/docs/th/README.md index a74671910..5e7b5c972 100644 --- a/docs/th/README.md +++ b/docs/th/README.md @@ -1,4 +1,4 @@ -**ภาษา:** [English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | **ไทย** | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) +**ภาษา:** [English](../../README.md) | [العربية](../ar/README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | **ไทย** | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) # ECC @@ -18,7 +18,7 @@ **ภาษา / Language / 语言 / 語言 / Dil / Язык / Ngôn ngữ** -[English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | **ไทย** | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) +[English](../../README.md) | [العربية](../ar/README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | **ไทย** | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) diff --git a/docs/tr/README.md b/docs/tr/README.md index 3f480127b..0b795a322 100644 --- a/docs/tr/README.md +++ b/docs/tr/README.md @@ -23,7 +23,7 @@ **Dil / Language / 语言 / 語言 / Язык / Ngôn ngữ** -[**English**](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [**Türkçe**](README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) +[**English**](../../README.md) | [العربية](../ar/README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [**Türkçe**](README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) diff --git a/docs/uk-UA/README.md b/docs/uk-UA/README.md index f76959dc6..d5e452c88 100644 --- a/docs/uk-UA/README.md +++ b/docs/uk-UA/README.md @@ -5,6 +5,7 @@
Мова: English | + العربية | Português (Brasil) | 简体中文 | 繁體中文 | diff --git a/docs/ur/README.md b/docs/ur/README.md index d98a0dc4c..7f4765336 100644 --- a/docs/ur/README.md +++ b/docs/ur/README.md @@ -1,4 +1,4 @@ -**زبان:** [English](../../README.md) | [اردو](README.md) | [Deutsch](../de-DE/README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) +**زبان:** [English](../../README.md) | [العربية](../ar/README.md) | [اردو](README.md) | [Deutsch](../de-DE/README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) # ECC @@ -27,7 +27,7 @@ **زبان / Language / 语言** -[English](../../README.md) | [**اردو**](README.md) | [Deutsch](../de-DE/README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) +[English](../../README.md) | [العربية](../ar/README.md) | [**اردو**](README.md) | [Deutsch](../de-DE/README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) diff --git a/docs/vi-VN/README.md b/docs/vi-VN/README.md index 8fa868509..2a68b8ab2 100644 --- a/docs/vi-VN/README.md +++ b/docs/vi-VN/README.md @@ -1,4 +1,4 @@ -**Ngôn ngữ:** [English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | **Tiếng Việt** | [ไทย](../th/README.md) | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) +**Ngôn ngữ:** [English](../../README.md) | [العربية](../ar/README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | **Tiếng Việt** | [ไทย](../th/README.md) | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) # ECC @@ -18,7 +18,7 @@ **Ngôn ngữ / Language / 语言 / 語言 / Dil / Язык** -[English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | **Tiếng Việt** | [ไทย](../th/README.md) | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) +[English](../../README.md) | [العربية](../ar/README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | **Tiếng Việt** | [ไทย](../th/README.md) | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) diff --git a/docs/zh-CN/README.md b/docs/zh-CN/README.md index 4e64b2389..9347cc940 100644 --- a/docs/zh-CN/README.md +++ b/docs/zh-CN/README.md @@ -1,4 +1,4 @@ -**语言:** [English](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) +**语言:** [English](../../README.md) | [العربية](../ar/README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | [繁體中文](../zh-TW/README.md) | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) # ECC diff --git a/docs/zh-TW/README.md b/docs/zh-TW/README.md index 6f1654c66..71cac112d 100644 --- a/docs/zh-TW/README.md +++ b/docs/zh-TW/README.md @@ -13,7 +13,7 @@ **Language / 语言 / 語言 / Dil / Язык / Ngôn ngữ** -[**English**](../../README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | **繁體中文** | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) +[**English**](../../README.md) | [العربية](../ar/README.md) | [Português (Brasil)](../pt-BR/README.md) | [简体中文](../../README.zh-CN.md) | **繁體中文** | [日本語](../ja-JP/README.md) | [한국어](../ko-KR/README.md) | [Türkçe](../tr/README.md) | [Русский](../ru/README.md) | [Tiếng Việt](../vi-VN/README.md) | [ไทย](../th/README.md) | [Deutsch](../de-DE/README.md) | [Українська](../uk-UA/README.md) | [Polski](../pl/README.md) diff --git a/manifests/install-components.json b/manifests/install-components.json index 5f8970c75..55ac377b2 100644 --- a/manifests/install-components.json +++ b/manifests/install-components.json @@ -205,7 +205,7 @@ { "id": "capability:ito-compute", "family": "capability", - "description": "Authenticated It\u00f4 GPU inventory, RFQ, status, device revocation, and explicitly gated node-qualification workflows through the separately installed canonical CLI.", + "description": "Authenticated Itô GPU inventory, RFQ, status, device revocation, and explicitly gated node-qualification workflows through the separately installed canonical CLI.", "modules": [ "ito-compute" ] @@ -685,6 +685,14 @@ "modules": [ "docs-pl" ] + }, + { + "id": "locale:ar", + "family": "locale", + "description": "Arabic (ar) translated reference docs installed to ~/.claude/docs/ar/.", + "modules": [ + "docs-ar" + ] } ] } diff --git a/manifests/install-modules.json b/manifests/install-modules.json index b61d4e20f..a8b3a06d1 100644 --- a/manifests/install-modules.json +++ b/manifests/install-modules.json @@ -642,7 +642,7 @@ { "id": "ito-compute", "kind": "skills", - "description": "Authenticated It\u00f4 GPU inventory, RFQ, status, device revocation, and explicitly gated node-qualification workflows through the separately installed canonical CLI.", + "description": "Authenticated Itô GPU inventory, RFQ, status, device revocation, and explicitly gated node-qualification workflows through the separately installed canonical CLI.", "paths": [ "skills/ito-compute", "skills/ito-inference", @@ -1194,6 +1194,22 @@ "defaultInstall": false, "cost": "heavy", "stability": "stable" + }, + { + "id": "docs-ar", + "kind": "docs", + "description": "Arabic (ar) getting-started and core-concepts guide with a terminology glossary.", + "paths": [ + "docs/ar" + ], + "targets": [ + "claude", + "claude-project" + ], + "dependencies": [], + "defaultInstall": false, + "cost": "heavy", + "stability": "stable" } ] } diff --git a/package.json b/package.json index 983370b3a..a326b98eb 100644 --- a/package.json +++ b/package.json @@ -79,6 +79,7 @@ "assets/images/sponsors/", "agents/", "commands/", + "docs/ar/", "docs/de-DE/", "docs/CODEX-NAVIGATION-GUIDE.md", "docs/COMMAND-AGENT-MAP.md", diff --git a/scripts/lib/install-manifests.js b/scripts/lib/install-manifests.js index 6d0fac5cf..d64c627f2 100644 --- a/scripts/lib/install-manifests.js +++ b/scripts/lib/install-manifests.js @@ -15,7 +15,7 @@ const COMPONENT_FAMILY_PREFIXES = { skill: 'skill:', locale: 'locale:', }; -const SUPPORTED_LOCALES = Object.freeze(['ja', 'zh-CN', 'ko-KR', 'pt-BR', 'ru', 'tr', 'vi-VN', 'zh-TW', 'de-DE', 'uk-UA', 'pl']); +const SUPPORTED_LOCALES = Object.freeze(['ja', 'zh-CN', 'ko-KR', 'pt-BR', 'ru', 'tr', 'vi-VN', 'zh-TW', 'de-DE', 'uk-UA', 'pl', 'ar']); const LOCALE_ALIAS_TO_COMPONENT_ID = Object.freeze({ 'ja': 'locale:ja', 'ja-JP': 'locale:ja', @@ -35,7 +35,9 @@ const LOCALE_ALIAS_TO_COMPONENT_ID = Object.freeze({ 'uk-UA': 'locale:uk-ua', 'uk': 'locale:uk-ua', 'pl': 'locale:pl', - 'pl-PL': 'locale:pl' + 'pl-PL': 'locale:pl', + 'ar': 'locale:ar', + 'ar-SA': 'locale:ar' }); function listSupportedLocales() { diff --git a/tests/docs/install-identifiers.test.js b/tests/docs/install-identifiers.test.js index 184e1b861..fdfe6b23c 100644 --- a/tests/docs/install-identifiers.test.js +++ b/tests/docs/install-identifiers.test.js @@ -26,6 +26,7 @@ const publicInstallDocs = [ 'README.zh-CN.md', 'docs/pt-BR/README.md', 'docs/zh-CN/README.md', + 'docs/ar/README.md', 'docs/ja-JP/skills/configure-ecc/SKILL.md', 'docs/zh-CN/skills/configure-ecc/SKILL.md', ]; diff --git a/tests/lib/locale-install.test.js b/tests/lib/locale-install.test.js index 373427224..8420417ba 100644 --- a/tests/lib/locale-install.test.js +++ b/tests/lib/locale-install.test.js @@ -53,9 +53,63 @@ function runTests() { assert.ok(components.some(component => component.id === 'locale:de-de')); assert.ok(components.some(component => component.id === 'locale:uk-ua')); assert.ok(components.some(component => component.id === 'locale:pl')); + assert.ok(components.some(component => component.id === 'locale:ar')); assert.ok(components.every(component => component.family === 'locale')); })) passed++; else failed++; + if (test('locale:ar resolves to the Arabic translated docs module', () => { + const homeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'locale-plan-ar-')); + try { + const plan = resolveInstallPlan({ + includeComponentIds: ['locale:ar'], + target: 'claude', + homeDir, + }); + + assert.deepStrictEqual(plan.selectedModuleIds, ['docs-ar']); + assert.ok( + plan.operations.some(operation => ( + normalizePlanPath(operation.sourceRelativePath) === 'docs/ar' + && normalizePlanPath(operation.destinationPath).endsWith('/.claude/docs/ar') + )), + 'Should map docs/ar to ~/.claude/docs/ar' + ); + } finally { + fs.rmSync(homeDir, { recursive: true, force: true }); + } + })) passed++; else failed++; + + if (test('end-to-end: --locale ar-SA dry-run includes docs-ar operations', () => { + const homeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'locale-dry-run-ar-')); + const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'locale-dry-run-ar-project-')); + + try { + const output = runInstallApply([ + '--locale', 'ar-SA', + '--dry-run', + '--json', + ], { + cwd: projectDir, + env: { HOME: homeDir }, + }); + const json = JSON.parse(output); + + assert.strictEqual(json.plan.mode, 'manifest'); + assert.deepStrictEqual(json.plan.includedComponentIds, ['locale:ar']); + assert.deepStrictEqual(json.plan.selectedModuleIds, ['docs-ar']); + assert.ok( + json.plan.operations.some(operation => ( + normalizePlanPath(operation.sourceRelativePath) === 'docs/ar/README.md' + && normalizePlanPath(operation.destinationPath).endsWith('/.claude/docs/ar/README.md') + )), + 'Should copy translated README into ~/.claude/docs/ar' + ); + } finally { + fs.rmSync(homeDir, { recursive: true, force: true }); + fs.rmSync(projectDir, { recursive: true, force: true }); + } + })) passed++; else failed++; + if (test('locale:pl resolves to the Polish translated docs module', () => { const homeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'locale-plan-pl-')); try { @@ -327,6 +381,38 @@ function runTests() { } })) passed++; else failed++; + if (test('end-to-end: --locale ar installs translated docs cleanly', () => { + const homeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'locale-install-ar-')); + const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'locale-install-ar-project-')); + + try { + runInstallApply([ + '--locale', 'ar', + ], { + cwd: projectDir, + env: { HOME: homeDir }, + }); + + const claudeRoot = path.join(homeDir, '.claude'); + assert.ok( + fs.existsSync(path.join(claudeRoot, 'docs', 'ar', 'README.md')), + 'Should install Arabic README under docs/ar' + ); + assert.ok( + !fs.existsSync(path.join(claudeRoot, 'skills', 'configure-ecc', 'SKILL.md')), + 'Locale-only install should not install English skills' + ); + + const statePath = path.join(claudeRoot, 'ecc', 'install-state.json'); + const state = JSON.parse(fs.readFileSync(statePath, 'utf8')); + assert.deepStrictEqual(state.request.includeComponents, ['locale:ar']); + assert.deepStrictEqual(state.resolution.selectedModules, ['docs-ar']); + } finally { + fs.rmSync(homeDir, { recursive: true, force: true }); + fs.rmSync(projectDir, { recursive: true, force: true }); + } + })) passed++; else failed++; + if (test('end-to-end: --locale uk-UA installs translated docs cleanly', () => { const homeDir = fs.mkdtempSync(path.join(os.tmpdir(), 'locale-install-uk-')); const projectDir = fs.mkdtempSync(path.join(os.tmpdir(), 'locale-install-uk-project-'));