- الرئيسية
- Documentation
- الإضافات
- مدير الإضافات وأنابيب التثبيت
مدير الإضافات وأنابيب التثبيت
يصف هذا المستند كيفية تأثير عمليات xcsh plugin على حالة الإضافات على القرص، وكيف تُصبح الإضافات المثبّتة قدرات وقت تشغيل (الأدوات حالياً، مع توفر حل مسارات الخطافات/الأوامر).
النطاق والمعمارية
Section titled “النطاق والمعمارية”يوجد تطبيقان لإدارة الإضافات في قاعدة الكود:
- المسار النشط المستخدم بواسطة أوامر CLI:
PluginManager(src/extensibility/plugins/manager.ts) - وحدة المساعد القديمة: دوال المثبّت (
src/extensibility/plugins/installer.ts)
يمر تنفيذ الأمر xcsh plugin ... عبر PluginManager.
لا يزال installer.ts يوثّق فحوصات الأمان المهمة وسلوك نظام الملفات، لكنه ليس المسار المستخدم بواسطة src/commands/plugin.ts + src/cli/plugin-cli.ts.
دورة الحياة: من استدعاء CLI إلى التوفر في وقت التشغيل
Section titled “دورة الحياة: من استدعاء CLI إلى التوفر في وقت التشغيل”xcsh plugin <action> ... -> src/commands/plugin.ts -> runPluginCommand(...) in src/cli/plugin-cli.ts -> PluginManager method (install/list/uninstall/link/...) -> mutate ~/.xcsh/plugins/{package.json,node_modules,xcsh-plugins.lock.json} -> runtime discovery: discoverAndLoadCustomTools(...) -> getAllPluginToolPaths(cwd) -> custom tool loader imports tool modulesنقاط دخول الأوامر
Section titled “نقاط دخول الأوامر”- يُعرّف
src/commands/plugin.tsالأمر والأعلام ويُحيل إلىrunPluginCommand. - يُعيّن
src/cli/plugin-cli.tsالأوامر الفرعية إلى أساليبPluginManager:install،uninstall،list،link،doctor،features،config،enable،disable
- لا يوجد إجراء
updateصريح؛ يتم التحديث عبر إعادة تشغيلinstallبمواصفة حزمة/إصدار جديدة.
النموذج على القرص
Section titled “النموذج على القرص”تقع حالة الإضافات العامة تحت ~/.xcsh/plugins:
package.json— بيان التبعيات المستخدم بواسطةbun install/bun uninstallnode_modules/— حزم الإضافات المثبّتة أو الروابط الرمزيةxcsh-plugins.lock.json— حالة وقت التشغيل:- تفعيل/تعطيل لكل إضافة
- مجموعة الميزات المحددة لكل إضافة
- إعدادات الإضافة المُحفوظة
تقع التجاوزات المحلية للمشروع في:
<cwd>/.xcsh/plugin-overrides.json
التجاوزات للقراءة فقط من منظور المدير/المُحمّل (لا يوجد مسار كتابة هنا)، ويمكنها تعطيل الإضافات أو تجاوز الميزات/الإعدادات لهذا المشروع.
تحليل مواصفة الإضافة وتفسير البيانات الوصفية
Section titled “تحليل مواصفة الإضافة وتفسير البيانات الوصفية”قواعد نحو مواصفة التثبيت
Section titled “قواعد نحو مواصفة التثبيت”يدعم parsePluginSpec (parser.ts):
pkg->features: null(السلوك الافتراضي)pkg[*]-> تفعيل جميع ميزات البيانpkg[]-> عدم تفعيل أي ميزات اختياريةpkg[a,b]-> تفعيل الميزات المسمّاة@scope/pkg@1.2.3[feat]-> حزمة محددة النطاق والإصدار مع اختيار ميزات صريح
يُزيل extractPackageName لاحقة الإصدار للبحث عن المسار على القرص بعد التثبيت.
مصدر البيان والحقول المطلوبة
Section titled “مصدر البيان والحقول المطلوبة”يُحلَّل البيان على النحو التالي:
package.json.xcsh- احتياطي
package.json.pi - احتياطي
{ version: package.version }
الانعكاسات:
- لا يوجد تحقق صارم من المخطط في المدير/المُحمّل.
- الحزمة التي تفتقر إلى
xcsh/piلا تزال قابلة للتثبيت والإدراج. - يتخطى تحميل الإضافة في وقت التشغيل (
getEnabledPlugins) الحزم التي تفتقر إلى بيانxcsh/pi. - يُستبدل
manifest.versionدائماً منversionالحزمة.
فشل تحليل JSON في package.json يُعدّ فشلاً صعباً عند القراءة؛ قد يفشل شكل البيان المشوّه لاحقاً فقط عند استهلاك حقول محددة.
تدفق التثبيت/التحديث (PluginManager.install)
Section titled “تدفق التثبيت/التحديث (PluginManager.install)”- تحليل صيغة أقواس الميزات من مواصفة التثبيت.
- التحقق من اسم الحزمة بواسطة regex + قائمة رفض أحرف shell الخاصة.
- التأكد من وجود
package.jsonللإضافة (xcsh-plugins، خريطة التبعيات الخاصة). - تشغيل
bun install <packageSpec>في~/.xcsh/plugins. - قراءة
node_modules/<name>/package.jsonللحزمة المثبّتة. - حل البيان وحساب
enabledFeatures:[*]: جميع الميزات المعلنة (أوnullإذا لم تكن هناك خريطة ميزات)[a,b]: التحقق من وجود كل ميزة في خريطة ميزات البيان[]: قائمة ميزات فارغة- مواصفة مجردة:
null(استخدام سياسة الافتراضيات لاحقاً في المُحمّل)
- تحديث أو إدراج حالة وقت تشغيل ملف القفل:
{ version, enabledFeatures, enabled: true }.
دلالات التحديث
Section titled “دلالات التحديث”نظراً لأن التحديث مدفوع بالتثبيت:
xcsh plugin install pkg@newVersionيُحدّث التبعية وإصدار ملف القفل.- تُحفظ الإعدادات الحالية؛ يُستبدل إدخال الحالة للإصدار/الميزات/التفعيل.
- لا توجد منطق “التحقق من التحديثات” أو الترحيل التحويلي.
تدفق الإزالة (PluginManager.uninstall)
Section titled “تدفق الإزالة (PluginManager.uninstall)”- التحقق من اسم الحزمة.
- تشغيل
bun uninstall <name>في مجلد الإضافة. - إزالة حالة وقت تشغيل الإضافة من ملف القفل:
config.plugins[name]config.settings[name]
إذا فشل أمر إلغاء التثبيت، لا تتغير حالة وقت التشغيل.
تدفق الإدراج (PluginManager.list)
Section titled “تدفق الإدراج (PluginManager.list)”- قراءة خريطة تبعيات الإضافة من
~/.xcsh/plugins/package.json. - تحميل تهيئة وقت تشغيل ملف القفل (الملف غير موجود -> افتراضيات فارغة).
- تحميل تجاوزات المشروع (
<cwd>/.xcsh/plugin-overrides.json، أخطاء التحليل/القراءة -> كائن فارغ مع تحذير). - لكل تبعية تحتوي على
package.jsonقابل للحل:- بناء سجل
InstalledPlugin - دمج حالة الميزة/التفعيل:
- الأساس من ملف القفل (أو الافتراضيات)
- يمكن لتجاوزات المشروع استبدال اختيار الميزات
- قائمة
disabledالخاصة بالمشروع تُخفي الإضافة كمعطّلة
- بناء سجل
هذه هي الحالة الفعّالة المستخدمة بواسطة مخرجات حالة CLI وعمليات الإعدادات/الميزات.
تدفق الربط (PluginManager.link)
Section titled “تدفق الربط (PluginManager.link)”يدعم link تطوير الإضافات المحلية عبر إنشاء رابط رمزي لحزمة محلية في ~/.xcsh/plugins/node_modules/<pkg.name>.
السلوك:
- حل
localPathبالنسبة لـ cwd المدير. - طلب
package.jsonالمحلي وحقلname. - التأكد من وجود مجلدات الإضافة.
- لأسماء النطاق، إنشاء مجلد النطاق.
- إزالة المسار الموجود في موقع الرابط المستهدف.
- إنشاء الرابط الرمزي.
- إضافة إدخال ملف القفل لوقت التشغيل ممكّناً بالميزات الافتراضية (
null).
تنبيه: لا يُطبّق PluginManager.link الحالي فحص حدود مسار cwd الموجود في installer.ts القديم (normalizedPath.startsWith(normalizedCwd))، لذا تقع مسؤولية الثقة على عاتق المستدعي.
التحميل في وقت التشغيل: من الإضافة المثبّتة إلى القدرات القابلة للاستدعاء
Section titled “التحميل في وقت التشغيل: من الإضافة المثبّتة إلى القدرات القابلة للاستدعاء”بوابة الاكتشاف
Section titled “بوابة الاكتشاف”يقرأ getEnabledPlugins(cwd) (plugins/loader.ts):
- بيان تبعيات الإضافة (
package.json) - حالة وقت تشغيل ملف القفل
- تجاوزات المشروع عبر
getConfigDirPaths("plugin-overrides.json", { user: false, cwd })
التصفية:
- تخطي إذا لم يوجد
package.jsonللإضافة - تخطي إذا كان البيان (
xcsh/pi) غائباً - تخطي إذا كان معطّلاً عالمياً في ملف القفل
- تخطي إذا كان معطّلاً على مستوى المشروع
حل مسارات القدرات
Section titled “حل مسارات القدرات”لكل إضافة ممكّنة:
resolvePluginToolPaths(plugin)resolvePluginHookPaths(plugin)resolvePluginCommandPaths(plugin)
يتضمن كل محلِّل إدخالات أساسية بالإضافة إلى إدخالات الميزات:
- قائمة ميزات صريحة -> الميزات المحددة فقط
enabledFeatures === null-> تفعيل الميزات المميّزة بـdefault: true
يتم تخطي الملفات المفقودة بصمت (حارس existsSync).
اختلافات التوصيل الحالي في وقت التشغيل
Section titled “اختلافات التوصيل الحالي في وقت التشغيل”- الأدوات مُوصَّلة في وقت التشغيل اليوم عبر
discoverAndLoadCustomTools(custom-tools/loader.ts)، التي تستدعيgetAllPluginToolPaths(cwd). - تُزال تكرارات المسارات بالمسار المطلق المحلول في اكتشاف الأدوات المخصصة (مجموعة
seen، يفوز المسار الأول). - محلِّلات الخطافات/الأوامر موجودة ومُصدَّرة، لكن هذا المسار البرمجي لا يوصلها حالياً بسجل وقت تشغيل بنفس الطريقة التي تُوصَّل بها الأدوات.
تفاصيل إدارة القفل/الحالة
Section titled “تفاصيل إدارة القفل/الحالة”يُخزّن PluginManager التهيئة في وقت التشغيل مؤقتاً في الذاكرة لكل مثيل (#runtimeConfig) ويُحمّلها بتكاسل مرة واحدة.
سلوك التحميل:
- ملف القفل غير موجود ->
{ plugins: {}, settings: {} } - فشل قراءة/تحليل ملف القفل -> تحذير + نفس الافتراضيات الفارغة
سلوك الحفظ:
- يكتب JSON كامل لملف القفل مُنسَّقاً عند كل تعديل
لا يوجد قفل متعدد العمليات أو استراتيجية دمج؛ يمكن للكتّاب المتزامنين الكتابة فوق بعضهم.
فحوصات الأمان وحدود الثقة
Section titled “فحوصات الأمان وحدود الثقة”التحقق من المدخلات/الحزم
Section titled “التحقق من المدخلات/الحزم”يُطبّق مسار المدير النشط التحقق من اسم الحزمة:
- regex للمواصفات المحددة/غير المحددة النطاق (اختيارياً مع الإصدار)
- قائمة رفض صريحة لأحرف shell الخاصة (
[;&|$(){}[]<>\]`)
يُقيّد هذا مخاطر حقن الأوامر عند استدعاء bun install/uninstall.
حدود ثقة نظام الملفات
Section titled “حدود ثقة نظام الملفات”- يُنفَّذ كود الإضافة داخل العملية عند استيراد وحدات الأدوات المخصصة؛ لا يوجد عزل.
- يُوصَّل المسارات النسبية للبيان بمجلد حزمة الإضافة ويُتحقق من وجودها فقط.
- الحزمة نفسها تُعدّ كوداً موثوقاً به بعد التثبيت.
فحوصات المثبّت القديم فقط
Section titled “فحوصات المثبّت القديم فقط”يتضمن installer.ts فحوصات إضافية عند وقت الربط غير موجودة في PluginManager.link:
- يجب أن يُحلَّل المسار المحلي داخل cwd المشروع
- حراس إضافية لاجتياز اسم الحزمة/المسار لتسمية الهدف الرمزي
نظراً لأن CLI يستخدم PluginManager، فإن هذه الحراس الأكثر صرامة للربط غير موجودة حالياً على المسار الرئيسي.
سلوك الفشل والنجاح الجزئي والتراجع
Section titled “سلوك الفشل والنجاح الجزئي والتراجع”مدير الإضافات ليس تحويلياً.
| مرحلة العملية | سلوك الفشل | التراجع |
|---|---|---|
bun install يفشل | يتوقف التثبيت مع stderr | غير متاح (لا كتابة للحالة بعد) |
| نجاح التثبيت، ثم فشل التحقق من البيان/الميزات | يفشل الأمر | لا تراجع بإلغاء التثبيت؛ قد تبقى التبعية في node_modules/package.json |
| نجاح التثبيت، ثم فشل كتابة ملف القفل | يفشل الأمر | لا تراجع للحزمة المثبّتة |
نجاح bun uninstall، فشل كتابة ملف القفل | يفشل الأمر | الحزمة مُزالة، قد تبقى حالة وقت تشغيل قديمة |
link يُزيل الهدف القديم ثم يفشل إنشاء الرابط الرمزي | يفشل الأمر | لا استعادة للرابط/المجلد السابق |
تشغيلياً، يمكن لـ doctor --fix إصلاح بعض الانحرافات (bun install، تنظيف التهيئة اليتيمة، تنظيف الميزات غير الصالحة)، لكنه مجهود بذل ما في الوسع.
ملخص سلوك البيان المشوّه/المفقود
Section titled “ملخص سلوك البيان المشوّه/المفقود”- الحقل
xcsh/piمفقود:- التثبيت/الإدراج: مسموح به (بيان أدنى)
- اكتشاف الإضافات الممكّنة في وقت التشغيل: يُتخطى كغير إضافة
- ميزة مفقودة مشار إليها بمواصفة التثبيت أو
features --set/--enable: خطأ صعب مع قائمة الميزات المتاحة plugin-overrides.jsonغير صالح: يُتجاهل مع الرجوع إلى{}في كلا مسارات المدير والمُحمّل- مسارات الملفات للأدوات/الخطافات/الأوامر المشار إليها في البيان غير موجودة: يُتجاهل بصمت أثناء توسيع المحلِّل؛ يُشار إليها كأخطاء فقط بواسطة
doctor
اختلافات الوضع والأولوية
Section titled “اختلافات الوضع والأولوية”--dry-run(التثبيت): يُعيد نتيجة تثبيت اصطناعية، لا كتابة لنظام الملفات/الشبكة/الحالة.--json: تنسيق المخرجات فقط، لا تغيير في السلوك.- تجاوزات المشروع تأخذ دائماً الأولوية على ملف القفل العام لعرض الميزات/الإعدادات.
- التفعيل الفعّال هو
runtimeEnabled && !projectDisabled.
ملفات التطبيق
Section titled “ملفات التطبيق”src/commands/plugin.ts— إعلان أمر CLI وتعيين الأعلامsrc/cli/plugin-cli.ts— توزيع الإجراءات، معالجات الأوامر الموجهة للمستخدمsrc/extensibility/plugins/manager.ts— تطبيق التثبيت/الإزالة/الإدراج/الربط/الحالة/doctor النشطsrc/extensibility/plugins/installer.ts— مساعدات المثبّت القديمة وفحوصات أمان الربط الإضافيةsrc/extensibility/plugins/loader.ts— اكتشاف الإضافات الممكّنة وحل مسارات الأدوات/الخطافات/الأوامرsrc/extensibility/plugins/parser.ts— مساعدات تحليل مواصفة التثبيت واسم الحزمةsrc/extensibility/plugins/types.ts— عقود نوع البيان/وقت التشغيل/التجاوزsrc/extensibility/custom-tools/loader.ts— التوصيل في وقت التشغيل لوحدات الأدوات المقدَّمة من الإضافات