1,104 mirrors rewritten over five passes of run-translation on the 22-source core set: the 14 sources edited since their translation, the 322 mirrors that were still English copies, and the frontmatter the old extractor leaked into the newer locales' bodies. The pipeline now caches per-`## `-section hashes and retranslates only changed sections, never reuses a section that is still English, rebuilds English-copy / leaked mirrors even when the source is unchanged, merges the state on save (parallel runs), and the drift gate (scoped to the core set) is blocking. Final audit: 0 stale, 0 English copies, 0 leaked frontmatter across 1,430 core mirrors. ⚠️ base-red inherited: #12732
37 KiB
Release Checklist (العربية)
🌐 Languages: 🇺🇸 English · 🇪🇹 am · 🇦🇿 az · 🇧🇬 bg · 🇧🇩 bn · 🇨🇿 cs · 🇩🇰 da · 🇩🇪 de · 🇬🇷 el · 🇪🇸 es · 🇪🇪 et · 🇮🇷 fa · 🇫🇮 fi · 🇫🇷 fr · 🇮🇪 ga · 🇮🇳 gu · 🇳🇬 ha · 🇮🇱 he · 🇮🇳 hi · 🇭🇷 hr · 🇭🇺 hu · 🇦🇲 hy · 🇮🇩 id · 🇳🇬 ig · 🇮🇹 it · 🇯🇵 ja · 🇬🇪 ka · 🇰🇭 km · 🇮🇳 kn · 🇰🇷 ko · 🇱🇹 lt · 🇱🇻 lv · 🇮🇳 ml · 🇮🇳 mr · 🇲🇾 ms · 🇲🇹 mt · 🇲🇲 my · 🇳🇵 ne · 🇳🇱 nl · 🇳🇴 no · 🇮🇳 or · 🇮🇳 pa · 🇵🇭 phi · 🇵🇱 pl · 🇵🇹 pt · 🇧🇷 pt-BR · 🇷🇴 ro · 🇷🇺 ru · 🇱🇰 si · 🇸🇰 sk · 🇸🇮 sl · 🇷🇸 sr · 🇸🇪 sv · 🇰🇪 sw · 🇮🇳 ta · 🇮🇳 te · 🇹🇭 th · 🇹🇷 tr · 🇺🇦 uk-UA · 🇵🇰 ur · 🇺🇿 uz · 🇻🇳 vi · 🇳🇬 yo · 🇨🇳 zh-CN · 🇹🇼 zh-TW
آخر تحديث: 2026-08-28 — v3.8.51 مسار إصدار مُبسّط يستفيد من مهارات Claude Code للأتمتة.
حافظ على سلامة قائمة الانتظار/الفرع بين الإصدارات: راجع RELEASE_GREEN.md (عائلة
/green-prs+ npm run check:release-green+ /babysit+ التشغيل الليلي). يساعد تشغيل هذا دوريًا — وخصوصًا قبل قائمة التحقق هذه — على بدء طلب سحب الإصدار بحالة سليمة.
الخلاصة
# 1. ارفع الإصدار وأنشئ CHANGELOG (مهارة)
/version-bump-cc patch # أو minor/major
# 2. شغّل بوابة الجودة محليًا
npm run check # التدقيق + الاختبارات
npm run test:coverage # بوابة التغطية الكاملة (60/60/60/60)
# 3. ابنِ ونفّذ اختبارًا مبدئيًا
npm run build
npm run test:e2e # اختياري لكنه موصى به
# 4. أنشئ الإصدار (مهارة)
/generate-release-cc
# 5. انشر (مهارة)
/deploy-vps-both-cc # أو akamai-cc / local-cc
# 6. التقط أدلة الإصدار (مهارة)
/capture-release-evidences-cc
النشر الموثوق في npm (الافتراضي منذ v3.8.51) — مرحلي عند الطلب، ومباشر كخيار احتياطي
ينشر npm-publish.yml عبر النشر الموثوق في npm (OIDC) افتراضيًا: تستبدل
مهمة stage-npm (المستضافة على GitHub) رمز هوية GitHub ببيانات اعتماد npm
قصيرة الأجل لذلك التشغيل — من دون رمز npm طويل الأجل في أسرار المستودع، ومن دون مطالبة بالمصادقة الثنائية، مع إرفاق إثبات المصدر.
هذا هو التجاوز الذي يقرّه npm الآن بعد بدء إيقاف الرموز التي تتخطى المصادقة الثنائية؛
وهو يعيد المسار المؤتمت بالكامل الذي كان لدى المشروع حتى v3.8.48 مع الحفاظ على
ضمان WS1.3 (لا يمكن لرمز مُسرَّب أن ينشر بمفرده — إذ لا يوجد رمز أصلًا).
إعداد لمرة واحدة (المالك): npmjs.com ← الحزمة omniroute ← Settings ← Trusted
Publisher ← GitHub: المالك diegosouzapw، المستودع OmniRoute، سير العمل npm-publish.yml
(البيئة: لا شيء). وحتى يتم ذلك، تفشل الخطوة التلقائية برسالة ENEEDAUTH:
أعِد التشغيل باستخدام publish_mode=staged (أدناه) أو direct.
النشر المرحلي (عند الطلب — publish_mode=staged)
لم يعد سير عمل npm-publish ينشر مباشرةً: بل يُشغّل حزمة tarball المعبأة
(check:pack-boot) ثم ينفّذ npm stage publish — فتُحفظ وحدات البايت نفسها في
السجل، وتكون غير قابلة للتثبيت إلى أن يوافق المالك. انتقلت بوابة المصادقة الثنائية البشرية
إلى ما بعد الإثبات، وليس قبله.
مسار المالك بعد نجاح سير العمل:
npm stage list omniroute— ابحث عن معرّف المرحلة (يُطبع أيضًا في ملخص سير العمل).- تحقّق من وحدات البايت المرحلية (موصى به):
npm stage download <id>، ثم ثبّت ملف tarball المنزّل في بادئة مؤقتة وشغّله (npm run check:pack-bootيؤتمت نتيجة الحزم←التثبيت←التشغيل نفسها في CI). npm stage approve <id>— مطالبة المصادقة الثنائية هي عملية النشر نفسها. أماnpm stage reject <id>فيتجاهل المرحلة.- شبكة أمان ما بعد النشر: يثبّت مدقّق ما بعد النشر (WS1.4 من خطة v3.8.49) الإصدار المنشور من السجل العام داخل حاوية نظيفة ويشغّله.
الخيار الاحتياطي للطوارئ: يعيد workflow_dispatch مع publish_mode=direct
سلوك npm publish الفوري القديم (استخدمه فقط إذا تعطّل النظام المرحلي نفسه؛ وسجّل السبب).
تحصين لمرة واحدة (المالك، npmjs.com): اضبط Trusted Publisher للحزمة
omniroute على وضع المراحل فقط، بحيث لا يستطيع رمز طويل الأجل مُسرَّب تنفيذ npm publish
مباشرةً من أي مكان — لا يستطيع CI سوى إنشاء مرحلة؛ ولا يُصدرها إلا المالك عبر المصادقة الثنائية.
دليل التعامل مع العنصر المعطّل (من دون تغيير): استخدم npm deprecate omniroute@<bad> "<reason> — use <fixed>"
بصفته الإجراء الافتراضي السريع (دقائق، قابل للعكس)؛ ولا تستخدم npm unpublish إلا ضمن نافذة
72 ساعة/عدم وجود حزم تابعة، وألا يكون ذلك الإجراء الأول أبدًا. بالنسبة إلى Docker: لا تعِد كتابة وسم إصدار مطلقًا — تتم
العودة إلى الإصدار السابق بإعادة توجيه latest إلى آخر بصمة سليمة.
وسم Docker Hub latest (مطلوب مع كل نشر SemVer مستقر): يجب أن يضع سير عمل
docker-publish وسمًا لكلٍ من X.Y.Z و، عندما يؤكد
should-promote-latest.sh أنه أعلى إصدار SemVer مستقر، :latest
باستخدام البصمة نفسها. بعد اكتمال المهمة: يجب أن تساوي بصمة latest على Hub بصمة
SemVer الجديدة وأن تتغير قيمة last_updated. لا تترك :latest يشير إلى
بناء أقدم بينما تتحدث ملاحظات الإصدار عن إصلاحات لا توجد إلا في git. تستخدم
أدلة البدء السريع في Compose الوسم :latest؛ وينبغي أن يستمر GitOps في تثبيت X.Y.Z. راجع
قنوات إصدار Docker و#10317.
المسار السريع للإصلاحات العاجلة (التسمية hotfix)
يتجاوز طلب السحب الذي يحمل التسمية hotfix مصفوفة CI الثقيلة (اختبارات E2E موزعة على 9 أجزاء، وآلية رفع عتبة التغطية،
وquality-gate، وquality-extended)، ويُبقي على بوابات التحقق السريعة وعالية الدلالة: البناء،
وأجزاء اختبارات الوحدة، والتكامل، وvitest، وlint/typecheck، وdocs-sync، وcheck:pack-artifact
واختبار التشغيل الأولي لحزمة tarball (check:pack-boot). الهدف: الوصول إلى الحالة الخضراء خلال ≤15 دقيقة بدلًا من نحو 33 دقيقة.
سياسة الدخول — المتطلبات الأربعة جميعها إلزامية (على غرار مسارات الطوارئ في Chromium/VS Code/Node):
- الخطورة: بيئة الإنتاج معطلة — حزمة منشورة تتعطل عند التشغيل / إصلاح أمني / كل مستخدمي الإصدار متأثرون. «مهم» لا يعني «معطل».
- الصلاحية: مالك المستودع وحده يطبّق التسمية
hotfix. التسمية هي الموافقة — ولا يجوز أبدًا تطبيقها ذاتيًا على طلب سحب ضمن حملة. - الدليل: يتضمن نص طلب السحب رابطًا إلى آخر تشغيل ثقيل مكتمل بحالة خضراء (مجموعة الاختبارات التي كانت المهام المتجاوزة ستعيد التحقق منها)، بالإضافة إلى اختبار الإصلاح نفسه الذي يفشل قبل الإصلاح ثم ينجح بعده.
- النطاق: cherry-pick فقط — الحد الأدنى من الإصلاح، دون إعادة هيكلة أو تغييرات إضافية مرافقة.
تُعاد عملية التحقق من نطاق التغطية/رفع العتبة المتجاوز في التشغيل الكامل التالي على
فرع الإصدار (استمرار خضرة الإصدار) — يتجاوز المسار الانتظار فقط، ولا يتجاوز التحقق مطلقًا.
تتجاوز التغييرات الخاصة بالاختبارات فقط (جميع الملفات تحت tests/، ولا شيء تحت tests/e2e/) مصفوفة E2E
تلقائيًا، دون أي تسمية.
قائمة التحقق التفصيلية
ما قبل الإصدار
- دُمجت جميع طلبات السحب المستهدفة لهذا الإصدار في
release/vX.Y.0 - أُغلقت جميع عناصر Linear/المشكلات المفتوحة لهذا الإصدار أو نُقلت إلى المرحلة الرئيسية التالية
- حالة CI خضراء على فرع
release/vX.Y.0 - لا توجد علامات
TODO(release)في الشيفرة:grep -r "TODO(release)" src/ open-sse/ - صورة Docker الأساسية محدّثة (حاليًا
node:24.15.0-trixie-slim)
الإصدار وسجل التغييرات
- شغّل
/version-bump-cc <patch|minor|major>(مهارة Claude Code)- يرفع الإصدار في
package.jsonوelectron/package.json - يعيد إنشاء
CHANGELOG.mdمن إيداعات git منذ آخر وسم - يحدّث شارات README.md
- يرفع الإصدار في
- راجع CHANGELOG.md يدويًا ونظّف رسائل الإيداعات عند الحاجة
- تأكد من أن أحدث قسم semver في
CHANGELOG.mdيطابق إصدارpackage.json - أبقِ
## [Unreleased]بوصفه أول قسم في سجل التغييرات للأعمال القادمة - حدّث
docs/openapi.yaml← يجب أن تساويinfo.versionإصدارpackage.json
جودة الشيفرة
npm run lint— 0 أخطاء (التحذيرات موجودة مسبقًا)npm run typecheck:core— بلا أخطاءnpm run typecheck:noimplicit:core— بلا أخطاء (صارم)npm run check:cycles— لا توجد تبعيات دائريةnpm run check:any-budget:t11— ضمن الميزانيةnpm run check:route-validation:t06— بلا أخطاءnpm run check:node-runtime— استيفاء الحد الأدنى لبيئة التشغيل المدعومة (>=22.22.2 <23، و>=24.0.0 <27، وفقًا لـSUPPORTED_NODE_RANGEفيsrc/shared/utils/nodeRuntimeSupport.ts؛ ومتوافق معenginesفيpackage.json)
الاختبارات
npm run test:unit— ناجحnpm run test:vitest— ناجح (خادم MCP، وautoCombo، وذاكرة التخزين المؤقت)npm run test:coverage— استيفاء بوابة 60/60/60/60 (العبارات/الأسطر/الدوال/الفروع)npm run test:integration— ناجح (إذا مست التغييرات قاعدة البيانات / المعالجات)npm run test:combo:matrix— ناجح (مصفوفة إستراتيجيات combo: تثبت قرارات الاختيار لجميع إستراتيجيات التوجيه العامة البالغ عددها 19 بصورة حتمية؛ شغّله عند تعديل توجيه combo، أو تحليل الإستراتيجية، أو منطق الرجوع الاحتياطي)RUN_COMBO_LIVE=1 npm run test:combo:live— اختياري/يدوي (اختبار أولي مقيّد لخدمات المنبع الحقيقية؛ يستورد لقطة قاعدة بيانات للقراءة فقط من VPS root@192.168.0.15؛ يتصل بموفّرين حقيقيين ويستهلك رصيدًا؛ لا يعمل مطلقًا في CI؛ ويُتجاوز دون أخطاء عند غياب البوابة)npm run test:combo:live:vps— اختياري/يدوي (اختبار VPS أولي مباشر للمرحلة الثالثة: 7 سيناريوهات HTTP على خادم.15المباشر عبر Node ESM خالص؛ يتطلبssh root@192.168.0.15؛ ينشئ/يحذف فقط مجموعات__live_test__*؛ يتصل بموفّرين حقيقيين؛ ولا يعمل مطلقًا في CI)npm run test:e2e— ناجح (تغييرات واجهة المستخدم)npm run test:protocols:e2e— ناجح (تغييرات MCP/A2A)npm run test:ecosystem— ناجح
الخطافات (متحقق منها بواسطة Husky)
توجد خطافات Husky في .husky/ وتعمل تلقائيًا عند تنفيذ عمليات git.
- pre-commit:
npx lint-staged + node scripts/check/check-docs-sync.mjs + npm run check:any-budget:t11 - pre-push: بوابات تحقق سريعة وحتمية —
npm run check:any-budget:t11 && npm run check:tracked-artifacts(فُعّلت في 2026-06-13). تستبعدtest:unitعمدًا (بطيء؛ وتغطيه مهمة CI المسماةtest-unit).- شغّل
npm run test:unitيدويًا قبل دفع فروع الإصدار.
- شغّل
إذا فشل أحد الخطافات: أصلح المشكلة الأساسية، ولا تتجاوزه باستخدام --no-verify.
الإيداعات التقليدية
يجب أن تتبع جميع الإيداعات الموجهة إلى الإصدار التنسيق type(scope): subject.
الأنواع الصالحة: feat، وfix، وrefactor، وdocs، وtest، وchore، وperf، وstyle، وci
النطاقات الصالحة: db، وsse، وoauth، وdashboard، وapi، وcli، وdocker، وci، وmcp، وa2a، وmemory، وskills، وcloud-agent، وguardrails، وcompression، وauto-combo، وresilience، وproviders، وexecutors، وtranslator، وdomain، وauthz
التغييرات الكاسرة للتوافق: أضف تذييل BREAKING CHANGE: أو ! بعد النطاق (مثل feat(api)!: drop /v0).
التوثيق
- ينجح
npm run check:docs-sync(يُشغَّل تلقائيًا بواسطة pre-commit) - ينجح
npm run check:docs-all(فحص شامل: docs-sync + docs-counts + env-doc-sync + deprecated-versions + doc-links) - ينتهي
npm run check:env-doc-syncبالرمز 0 — عقد متغيرات البيئة بين الشيفرة ↔.env.example↔docs/reference/ENVIRONMENT.mdسليم - ينتهي
npm run check:doc-linksبالرمز 0 — لا توجد مراجع markdown داخلية معطّلة بعد إعادة الهيكلة - تمت مراجعة
docs/architecture/ARCHITECTURE.mdللتحقق من عدم وجود انحراف في التخزين/بيئة التشغيل - تمت مراجعة
docs/guides/TROUBLESHOOTING.mdللتحقق من عدم وجود انحراف في متغيرات البيئة والإجراءات التشغيلية - إذا تغيّر
.env.example: تم تحديثdocs/reference/ENVIRONMENT.md - إذا كانت للميزة الجديدة واجهة مستخدم: يذكرها
docs/guides/USER_GUIDE.md - إذا كانت للميزة الجديدة API: تم تحديث
docs/reference/API_REFERENCE.md+docs/openapi.yaml - إذا كانت الميزة الجديدة وحدة: يوجد ملف مخصص باسم
docs/<MODULE>.md - إذا كان التغيير كاسرًا للتوافق: يتضمن
docs/guides/TROUBLESHOOTING.mdملاحظة ترحيل
التدويل
- ينتهي
npm run i18n:checkبالرمز 0 — حالة الترجمة (.i18n-state.json) متزامنة مع مستندات المصدر (لا توجد مصادر منحرفة في الوضع الصارم؛ يُقبل التحذير الإرشادي في وضع التحذير للتعديلات الأخيرة على المستندات، ولكن يجب أن تكون النتيجة 0 قبل وضع الوسم) - ينتهي
npm run i18n:check-ui-coverageبالرمز 0 — تبلغ تغطية كل لغة لواجهة المستخدم حد 80% الأدنى أو تتجاوزه - يُبلغ
npm run i18n:sync-ui:dryعن عدم وجود أي مفاتيح مفقودة عبر جميع اللغات الـ 42 - إذا تغيّرت مستندات المصدر الإنجليزية، فشغّل
npm run i18n:run(يتطلبOMNIROUTE_TRANSLATION_API_KEYفي.env) قبل وضع الوسم - يمكن تأجيل مساهمات الترجمة إلى الإصدار التالي إذا كانت طفيفة (تُتابع في CHANGELOG)
ترحيلات قاعدة البيانات
- إذا كان
src/lib/db/migrations/يحتوي على ملفات جديدة:- كل ترحيل متكرر التنفيذ بأمان (
CREATE TABLE IF NOT EXISTS، وما إلى ذلك) - الترحيلات مغلّفة ضمن معاملات
- مرقّمة بصورة صحيحة (لا توجد فجوات في التسلسل)
- كل ترحيل متكرر التنفيذ بأمان (
- الاختبار على تثبيت جديد: احذف
~/.omniroute/omniroute.dbوشغّلnpm run dev - الاختبار على تثبيت موجود: أنشئ نسخة احتياطية من قاعدة البيانات، وشغّل الترحيل، وتحقق من المخطط
- تتم معالجة ملفات WAL (
-wal،-shm) بصورة صحيحة إذا كان الترحيل يعيد كتابة الجداول
كتالوج المزوّدين (مُتحقق منه بواسطة Zod)
- مخطط Zod في
src/shared/constants/providers.tsصالح عند التحميل- لدى جميع المزوّدين الحقول المطلوبة (
id،label،kind، وما إلى ذلك) - تم توفير
freeNoteللمزوّدين المجانيين الجدد - لدى مزوّدي OAuth إعداد
oauthConfigمسجل فيsrc/lib/oauth/constants/oauth.ts
- لدى جميع المزوّدين الحقول المطلوبة (
- إذا تمت إضافة مزوّد جديد: يوجد منفّذ مقابل في
open-sse/executors/ - إذا كان التنسيق غير متوافق مع OpenAI: يوجد مترجم في
open-sse/translator/ - النماذج مسجلة في
open-sse/config/providerRegistry.ts - تغطي اختبارات الوحدة في
tests/unit/تصنيف المزوّدين والتوجيه
سطح المكتب (Electron)
إذا تغيّر electron/:
- ينجح
npm run electron:smoke:packaged - تم اختبار عمليات البناء لواحد على الأقل من
:win،:mac،:linux - شهادات توقيع الشيفرة غير منتهية الصلاحية (إذا كان التوقيع مستخدمًا)
- يتطابق إصدار
electron/package.jsonمعpackage.jsonالجذري - تم تحديث مؤشر قناة التحديث التلقائي إذا كان الإصدار موجّهًا إلى
stable
تخطيط البناء
يستخدم المستودع ثلاثة أدلة إخراج منفصلة — لا تخلط بينها مطلقًا:
| الدليل | الغرض | خاضع للتتبع؟ |
|---|---|---|
src/ |
مصدر التطبيق (TypeScript / TSX) | نعم |
.build/ |
نواتج البناء الوسيطة — مخرجات next build (distDir) |
لا (يتجاهله git) |
dist/ |
حزمة npm القابلة للتوزيع — يجمعها assembleStandalone |
لا (يتجاهله git) |
ملاحظة للمشغّل: يظل دليل الصورة على VPS البعيد هو
/usr/lib/node_modules/omniroute/app/. انتقلت فقط مخرجات البناء داخل المستودع (app/→dist/). تستخدم مهارات النشر rsync لمزامنة محتوياتdist/مع دليلapp/البعيد — ولا يلزم إجراء أي تغييرات على مسارات VPS.
تدفق البناء الواحد:
npm run build:release
└─ rm -rf .build dist (تنظيف)
└─ next build → .build/next/ (نواتج وسيطة)
└─ assembleStandalone (ينسخ الحزمة المستقلة + الملفات الثابتة + العامة + الأصلية → dist/)
└─ writes dist/BUILD_SHA (علامة HEAD)
لا تشغّل npm run build متبوعًا بأمر npm run build:cli منفصل للنشر — استخدم
npm run build:release، الذي يُجري إعادة بناء نظيفة + إنشاء العلامة في أمر واحد.
التحقق من الملفات الناتجة
- ينجح
npm run build:releaseوتكونdist/BUILD_SHA==git rev-parse --short HEAD - ينجح
npm run check:pack-artifactدون مشكلات — لا توجدapp.__qa_backupأوscripts/scratchأوpackage-lock.jsonأو أي بقايا محلية أخرى - يوجد
dist/server.jsبعد البناء
وضع الوسم والإصدار
- شغّل
/generate-release-cc(مهارة Claude Code):- ينشئ الوسم
vX.Y.Z - يدفع الوسم والفرع
- ينشئ إصدار GitHub يتضمن سجل التغييرات
- يرفق مثبّتات Electron (إذا تم بناؤها)
- ينشئ الوسم
- أو نفّذ ذلك يدويًا:
git tag -a vX.Y.Z -m "إصدار vX.Y.Z" git push origin vX.Y.Z gh release create vX.Y.Z --notes-from-tag
النشر
تستخدم مهارات النشر تدفق rsync الخفيف — دون npm pack ودون npm i -g:
- استخدم مهارة النشر المطابقة للهدف:
/deploy-vps-local-cc— خادم VPS محلي (192.168.0.15)/deploy-vps-akamai-cc— خادم Akamai VPS (69.164.221.35)/deploy-vps-both-cc— كلاهما
- قبل النشر، تأكد من أن
dist/BUILD_SHA==git rev-parse --short HEAD - يجب تشغيل البناء في مكان يكون فيه
node_modulesحقيقيًا (نسخة العمل الرئيسية أو شجرة عمل نُفّذ فيهاnpm ci— وليست شجرة عمل مرتبطة برابط رمزي) - أجرِ اختبارًا أوليًا على النسخة المنشورة:
- افتح
/dashboard/health← تحقق من تطابق سلسلة الإصدار مع الإصدار المنشور - نفّذ طلب
/v1/chat/completionsباستخدام مزوّد معروف - تحقق من أن
/api/monitoring/healthيعيد قواطع دوائر بالحالةCLOSED - تأكد من استجابة وسائل نقل MCP (
/mcpعبر HTTP، و/mcp-sseعبر SSE)
- افتح
ما بعد الإصدار
- شغّل
/capture-release-evidences-cc(مهارة Claude Code)- يلتقط لقطات شاشة/تسجيلات بصيغة WebP للميزات الجديدة
- يرفقها بملاحظات الإصدار / منشور المدونة
- حدّث GitHub Discussions / Discord بإعلان الإصدار
- افتح مرحلة رئيسية للإصدار التالي
- إذا كان الأمر بالغ الأهمية: ثبّت المناقشة أو انشر في
news.jsonلعرض لافتة داخل التطبيق
بوابة الإطلاق العام لـ Radar
أُدرج إعلان Radar عمدًا مع active: false. ويُعد التفعيل تغييرًا منفصلًا
يتم بعد تقديم أدلة على إنجاز كل بند أدناه:
- دُمجت جميع طلبات السحب المتراكبة الخاصة بـ Radar، وكانت عملية CI لـ release-tip ناجحة
- انشر مسارات Radar مفتوحة المصدر واختبرها مبدئيًا مع إبقاء
RADAR_ENABLEDمعطّلًا افتراضيًا - اختبر مبدئيًا
GET /planosو/termosو/privacidadeو/reembolsoعلى مضيف Radar المحدد - سجّل هوية المشغّل/جهة الاتصال/العنوان والمراجعة القانونية المعتمدة من المالك في الخدمة الخاصة
- اختبر Stripe Checkout وخطاف الويب الموقّع في وضع الاختبار فقط
- اختبر عملية تسليم واحدة لبريد إلكتروني مشفّر خاص بالمعاملات باستخدام المرسِل/النطاق المعتمد
- أثبت نجاح استعادة النسخة الاحتياطية وتنفيذ عملية بحث واحدة خاضعة للإشراف ومحدودة الميزانية
- اعتمد سياسة مراجعة BRL/PIX قبل قبول أدلة التبرعات
- فعّل Checkout العام فقط بعد اجتياز البوابات السابقة، ثم فعّل المعرّف الجديد في
news.json - تحقّق من أن لافتة الصفحة الرئيسية تستخدم نصًا مترجمًا، وأن المعرّف الجديد يظهر مجددًا بعد تجاهل معرّف أقدم
اختبار دخان الخدمات المضمّنة (v3.8.4+)
قبل إصدار أي نسخة تتضمن تغييرات في الخدمات المضمّنة، تحقّق مما يلي:
الإقلاع بقاعدة بيانات جديدة (يكشف تعارضات الترحيل — أُضيف بعد الإصلاح العاجل لـ v3.8.4)
DATA_DIR=$(mktemp -d) npm start &— انتظر 10 ثوانٍ حتى الإقلاع- يُرجع
curl -s http://127.0.0.1:20128/api/services/9router/status | jq '.tool'القيمة"9router"(وليس 404 أو 500). يؤكد تطبيق الترحيل071_services.sql+ إدراج الصف الأولي. - يُرجع
sqlite3 $DATA_DIR/storage.sqlite "PRAGMA table_info(version_manager);" | grep -E "provider_expose|logs_buffer_path|last_sync_at"عدد 3 صفوف. - يُرجع
sqlite3 $DATA_DIR/storage.sqlite "PRAGMA table_info(webhooks);" | grep -E "kind|metadata_encrypted"عدد صفّين (يتحقق من تطبيق070_webhooks_kind_metadata.sql). - ينجح
node --import tsx/esm --test tests/unit/db/no-migration-collisions.test.ts— يحمي من التعارضات المستقبلية.
9Router
- يُرجع
POST /api/services/9router/installالحالة 200 معinstalledVersionخلال أقل من دقيقتين - يُرجع
POST /api/services/9router/startالحالة 200 وstate: "running"خلال أقل من 30 ثانية - يُبلغ
GET /api/services/9router/statusعنhealth: "healthy" - يُرجع
POST /v1/chat/completionsمع"model": "9router/auto/..."الحالة 200 (توجيه شامل من طرف إلى طرف عبر 9Router) - يعرض
GET /dashboard/providers/services/9router/embed/dashboardواجهة 9Router الأصلية داخل الوكيل (من دون iframe مباشر إلى127.0.0.1:port) - يُرجع
POST /api/services/9router/rotate-keyالقيمة{ keyRotated: true }وتُعاد إعادة تشغيل الخدمة بصورة سليمة - يُرجع
POST /api/services/9router/stopالحالة 200 وstate: "stopped" - يُرجع
GET /api/services/9router/logs?tail=50تدفق SSE مع حدثsnapshotيحتوي على الأسطر الحديثة - يُرجع التثبيت في بيئة لا تحتوي على
npmضمن PATH الحالة 500 مع رسالة خطأ مفهومة (من دون تتبّع للمكدس)
CLIProxyAPI
- يُرجع
POST /api/services/cliproxy/installالحالة 200 خلال أقل من دقيقتين - يُرجع
POST /api/services/cliproxy/startالحالة 200 وstate: "running"خلال أقل من 30 ثانية - يُبلغ
GET /api/services/cliproxy/statusعنhealth: "healthy" - يُرجع
POST /api/services/cliproxy/stopالحالة 200 وstate: "stopped" - يُرجع
GET /api/services/cliproxy/logs?tail=50تدفق SSE
التحقق من الانحدارات الأمنية
- يُرجع
curl -H "X-Forwarded-For: 1.2.3.4" http://localhost:20128/api/services/9router/startالقيمة403 LOCAL_ONLY - يُرجع
curl -H "X-Forwarded-For: 1.2.3.4" http://localhost:20128/api/services/cliproxy/startالقيمة403 LOCAL_ONLY - لا تحتوي استجابات الأخطاء من
/api/services/*علىerr.stackأو مسارات ملفات مطلقة
فحوصات v3.8.0+
قبل إصدار أي نسخة من v3.8.x، تحقّق من هذه العناصر الإضافية:
- يُقلع
omniroute --trayعلى macOS (مع تثبيت systray2 في~/.omniroute/runtime/) - يُقلع
omniroute --trayعلى Linux (يتطلب DISPLAY؛ ويعرض خطأً مناسبًا إذا لم يكن معيّنًا) - يُقلع
omniroute --trayعلى Windows (PowerShell NotifyIcon، من دون ملفات ثنائية إضافية) - ينشئ
omniroute config tray enableإدخال تشغيل تلقائي؛ وتؤدي عملية التعطيل إلى إزالته - يشغّل
npm install -g omniroute@<this-version>مرحلة ما بعد التثبيت من دون خروج فادح - يحتفظ مسار التحديث بالتبعيات الاختيارية: يشغّل
omniroute update --applyوالمحدّث التلقائي الأمرnpm install -g … --include=optionalبحيث تبقىoptionalDependencies(better-sqlite3، وkeytar، وtls-client، ومكدس llmlingua SLM: @atjsh/llmlingua-2@2.0.5، وjs-tiktoken) بعد التحديث. تحتاج فئة SLM فائقة المستوىmodelPathأيضًا إلى نموذج tinybert، الذي يُنزَّل تلقائيًا إلى${DATA_DIR}/models/llmlinguaعند أول استخدام. بعد ذلك، تعمل مرحلة ما بعد التثبيت (scripts/build/colocateOptionals.mjs) على وضع إغلاق تبعيات SLM الاختيارية في الموقع نفسه داخلdist/node_modulesلكي يحلّ العامل مثيلًا واحدًا فقط من@huggingface/transformers^4.2.0 — إذ لا تضم حزمة التتبّع المستقلة سوى transformers، وليس التبعيات الاختيارية المستوردة ديناميكيًا، ولذلك، من دون هذا، سيحمّل العامل llmlingua-2 مقابل transformers الموجود في الجذر وستفشل فئة SLM بصمت مع السماح بالمتابعة. - يعمل
omniroute statusمن دون.env(مسار رمز CLI، عبر loopback فقط) - يُرجع
curl http://localhost:20128/api/shutdownالحالة 401 (مسار محمي دائمًا) - يُرجع
curl -H "host: evil.com" http://localhost:20128/api/mcp/sseالحالة 401 (حارس loopback) - يُحل وقت تشغيل SQLite إلى
bundledعند التشغيل الأول (الملف الثنائي المضمّن صالح للمنصة) - يعود وقت تشغيل SQLite إلى
runtimeعند حذفnode_modules/better-sqlite3 - يضغط مرشّح MCP الذكي المخرجات الفعلية للأمر
playwright-mcp browser_snapshot(خفض بنسبة ≥50%) - يمكن جلب جميع ملفات
skills/omniroute*/SKILL.mdالعشرة علنًا عبر عنوان URL خام من GitHub - يعرض معالج الإعداد الأولي خطوة جولة الفئات "كيف يعمل" في الإعداد الجديد
- تعرض أداة تغطية الفئات في لوحة المعلومات الرئيسية أعداد العناصر المهيأة/النشطة
التراجع عن الإصدار
إذا كان الإصدار يحتوي على مشكلة حرجة:
gh release edit vX.Y.Z --prerelease(يضع علامة عليه بأنه ليس الأحدث)git tag -d vX.Y.Z && git push --delete origin vX.Y.Z(فقط إذا لم يكن المستخدمون قد اعتمدوه بعد)- أو: إصلاح عاجل على
release/vX.Y.0← إصدار تصحيحيvX.Y.(Z+1) - أبلغ فورًا عبر GitHub Discussions وDiscord
قواعد صارمة
- لا تُجرِ أي عملية commit مباشرةً إلى
main - لا تستخدم مطلقًا
git push --forceمعmainأو فروعrelease/* - لا تتخطَّ أبدًا خطافات Husky باستخدام (
--no-verify) - لا تُضمِّن أبدًا الأسرار أو بيانات الاعتماد أو ملفات
.envفي أي commit - يجب أن تظل التغطية ≥60/60/60/60 (التعليمات/الأسطر/الدوال/الفروع)
- أضف الاختبارات أو حدّثها دائمًا عند تغيير كود الإنتاج في
src/أوopen-sse/أوelectron/أوbin/
التحقق الآلي من المزامنة
شغّل أداة التحقق من مزامنة الوثائق محليًا قبل فتح PR:
npm run check:docs-sync
يشغّل CI أيضًا هذا التحقق في .github/workflows/ci.yml (مهمة lint).