نظام التصميم الخاص بك
احتفظ بملف طبقة واحد في منتجك. أمر واحد يكتب الرموز والشيفرة لكل منصة تصدر عليها، في طلب سحب واحد.
لا تتغير مكوّنات Tanrei أبدًا حين يتغير مظهر منتجك. الذي يتغير هو الطبقة: ملف JSON صغير يعيّن قيمًا من المفردات المشتركة ويعلن لوحات ألوانك. وتحوّل الأداة @tanrei/cli هذا الملف الواحد إلى كل ما تحتاج إليه كل منصة.
إصدار تمهيدي
نُشر 0.1.0-next.0 على npm تحت وسم التوزيع (dist-tag) next: وحتى 0.1.0، ثبِّت @tanrei/cli@next و@tanrei/mcp@next. لا يُحافَظ على التوافق مع الإصدارات السابقة طوال الإصدارات التمهيدية 0.x: قد يكسر أي إصدار تمهيدي أي شيء دون أن يُعلَن شيء مهمَلًا قبله، ويذكر الـ changeset الخاص به ما الذي انكسر.
أضِف أداة سطر الأوامر إلى منتجك اعتماديةً للتطوير، فيشغّل كل أمر npx tanrei … في هذه الصفحة تلك النسخة. وهي تحمل Theme Studio الذي يقدّمه tanrei studio.
npm install --save-dev @tanrei/cliلا يحتاج خادم MCP إلى تثبيت: يجلب npx الحزمة @tanrei/mcp حين يشغّله وكيل، كما يُسجَّل في موضع لاحق من هذه الصفحة.
لاستعمال الشيفرة المصدرية كما هي على main، ابنِ الحزمتين في نسخة مستنسخة من المستودع، وثبِّت الملفين المحزومين في منتجك اعتمادياتٍ للتطوير:
git clone https://github.com/chnotchy/tanrei.git
cd tanrei
pnpm install
pnpm --filter @tanrei/studio build:app # Theme Studio، الذي يقدّمه الأمر `tanrei studio`
pnpm --filter @tanrei/cli --filter @tanrei/mcp build
pnpm --filter @tanrei/cli --filter @tanrei/mcp pack --pack-destination ../tanrei-packages# في منتجك: المسار إلى المجلد الذي كُتبت فيه الحزم
npm install --save-dev path/to/tanrei-packages/tanrei-cli-*.tgz path/to/tanrei-packages/tanrei-mcp-*.tgzولخادم MCP، سجِّل النسخة المثبَّتة بدلًا من ذلك: claude mcp add tanrei -- npx tanrei-mcp، وشغِّله في مجلد منتجك.
-
ابدأ طبقة، من النظام الافتراضي أو من إعداد جاهز.
npx tanrei init acme --extends tanreiيكتب هذا الأمر الملفين
design/acme.system.jsonوtanrei.json. تفضّل أشرطة التمرير؟ شكِّل الطبقة في Theme Studio ثم نزِّلها. -
حدِّد وجهة كل مُخرَج في
tanrei.json. اذكر ما تصدره فقط.{ "system": "design/acme.system.json", "kotlinPackage": "com.acme.design", "outputs": { "tokens": "design/tokens/acme", "web": "apps/web/src/styles", "swiftui": "apps/ios/Acme/Design", "compose": "apps/android/app/src/main/kotlin/com/acme/design", "flutter": "apps/flutter/lib/design", "react-native": "apps/mobile/src/design" } } -
ابنِ.
npx tanrei buildأودِع النتيجة في المستودع. وأضف
npx tanrei build --checkإلى CI: لا يكتب هذا الأمر شيئًا، ويفشل إذا كان أحد المخرجات المودَعة قديمًا. -
استخدمه. تحتوي الملفات المولَّدة على قيم نظامك؛ أما الأنواع فتأتي من المكتبة، ولذلك فإن أي تغيير في المفردات يكسر البناء بدل أن ينحرف بصمت.
المنصة ما تحصل عليه ما تكتبه Web acme.css<html data-tanrei-system="acme">SwiftUI TanreiSystem+Acme.swift.tanreiTheme(TanreiTheme(system: .acme))Compose TanreiSystemAcme.ktTanreiTheme(system = TanreiSystem.Acme) { … }Flutter acme_system.g.dartTanreiTheme(data: TanreiThemeData.platform(context, system: acmeSystem), …)React Native acme.ts<TanreiProvider system={acme}>
عدِّل قيمة في الطبقة وشغِّل tanrei build، فيتغير ملف كل منصة في الإيداع نفسه. تكبير النص كله قليلًا سطر واحد:
"tanrei.dial.type.base": { "$value": { "value": 17, "unit": "px" }, "reason": "يُقرأ على بُعد ذراع." }انظر أنظمة التصميم والتخصيص لمعرفة الأمور الأربعة التي تستطيع الطبقة أن تفعلها بقيمة ما (ضبط قرص، أو تكبير رمز أو تصغيره بنسبة، أو إعادة توجيه اسم بديل، أو تثبيت قيمة مع ذكر السبب)، ولإعلان لوحات ألوان مثل لون العلامة التجارية أو لونَي «صحيح» و«خاطئ» في اختبار، ولإضافة رموز حين لا تكفي القيم.
التخصيص درجات، وكل درجة تعدّل الملف الواحد <id>.system.json:
| ما تريده | ما تستخدمه |
|---|---|
| إعداد سريع | Theme Studio → العمود الجانبي: صفوف المظهر التسعة (لون العلامة التجارية، والرمادي، والخط، والحجم، والزوايا، وتنعيم الزوايا، والأيقونات، واستجابة الضغط، ومظهر التركيز)، كلٌّ منها بضغطة واحدة، مع القفل والخلط العشوائي |
| ضبط المجموعات | Studio → «المزيد» في العمود الجانبي: الأقراص الثمانية كلها، وكل لوحات الألوان، وكل مكوّن، وكل سلوك |
| تعديل رمز واحد في كل مرة، في واجهة رسومية | Studio → فحص → الرموز: ابحث في المفردات كلها؛ يعرض كل رمز التعديلات المسموح بها له فقط، ويبيّن ما يتبعه |
| تحرير المصدر | Studio → فحص → المصدر، أو محرّرك: ملف JSON، يُتحقَّق منه وفق المخطط (schema) وبالمحرّك |
| رمز غير موجود | أضفه: درجة في سلسلة، أو حجم أو طراز (variant) للمكوّن Button في سطر واحد، أو رموز خاصة بك |
npx tanrei studioيفتح هذا الأمر Theme Studio على ملف طبقتك: تُحفظ التعديلات فيه فور إجرائها (راجعها بـ git كأي تغيير)، ولا يُكتب أبدًا فوق تعديل أجريته في محرّرك في الوقت نفسه، والزر «Build» يشغّل tanrei build. يستمع الخادم على 127.0.0.1 فقط، ويحمل الرابط المطبوع مفتاحًا يُستخدم مرة واحدة. و Studio الموجود في هذا الموقع هو الأداة نفسها، بالاستيراد والتصدير بدل الملف.
npx tanrei audit srcيقرأ شيفرة منتجك — السكربت (JS وTS وJSX) والترميز (HTML وVue وSvelte وAstro) وأوراق الأنماط (CSS وSass وLess) — ويُبلغ عمّا لا يملكه نظامك، كلٌّ في ملفه وسطره وعموده، مع ما يُكتب بدلًا منه:
- عنصر لمكوّن لا يملكه النظام —
<tanrei-fab-menu>في صفحة أو قالب أو JSX أو سلسلة نصية، أو مغلّف React مستورد، أو محدِّد CSS يسمّيه — مع المكوّنات التي يقدّمها النظام للمهمة نفسها، والأنظمة التي تملكه، والسطر الذي تكتبه في طبقتك لتضمينه؛ - استيراد من نقطة دخول لا تناسب النظام —
@tanrei/web/m3-likeأو@tanrei/react/allفي منتج مبني على النظام الافتراضي — مع نقطة الدخول التي تناسبه؛ - قيمة
variant="…"مكتوبة يستبعدها النظام، مع القيم التي يقدّمها.
يفحص مقابل نظام منتجك (tanrei.json)، أو النظام الذي يسمّيه --system: نظام مضمَّن مثل m3-like، أو ملف طبقة. مرِّر إليه ملفات أو مجلدات أو نمط glob بين علامتي اقتباس ('src/**/*.{ts,tsx,html,css}')؛ ويُقرأ المجلد من دون node_modules والمجلدات المخفية. ويطبع --format json النتائج بيانات. ينتهي برمز الخروج 1 حين يجد شيئًا، فيمكن تشغيله في CI بجانب tanrei build --check، وبالرمز 2 حين يتعذّر تشغيله. ويُجري check_usage في خادم MCP الفحص نفسه.
إنه يقرأ النص، لا صفحة قيد التشغيل: يتخطّى التعليقات، لكنه لا يرى قيمة variant محفوظة في متغيّر، ولا اسم وسم مُركَّبًا من أجزاء.
أضف "tailwind" أو "shadcn" إلى outputs. كلا الملفين يربط أسماء بخصائص Tanrei المخصصة لا غير، فتظل السمات ومستويات التباين والأقراص الحيّة تعمل من تحتها.
@import "tailwindcss";
@import "@tanrei/web/tokens.css";
@import "./styles/acme.css";
@import "./styles/acme.tailwind.css"; /* bg-primary · text-on-primary · rounded-medium · p-200 · text-heading-4 */-
المُخرَج
tokensحزمة DTCG 2025.10 مكتفية بذاتها مع محلِّل (resolver) قياسي. تستطيع أي أداة لرموز التصميم قراءتها؛ وملفات الطبقات التي أنتجتها محمولة بداخلها، وتحمل كل مجموعة إرشادات استخدام للوكلاء في$extensions["dev.tanrei.llm"]. -
وتحتوي أيضًا على
components.json، أي المكوّنات التي يشحنها نظامك: لكلٍّ منها عنصره (أو صنفه)، واسمه في React، والوحدة التي تسجّله، ومعها المكوّنات التي لا يملكها النظام، مع الطبقة التي استبعدت كلًّا منها وما يُستخدم بدلًا منه. والوكيل الذي يقرؤه لا يقترح إلا مكوّنات يستطيع منتجك استخدامها. ولكل نظام مشحون مع Tanrei ملفٌّ مثله:@tanrei/web/systems/<id>.components.json. -
الحزمة
@tanrei/mcpخادم
Model Context Protocol. يستطيع وكيل يعمل في مستودعك أن يبحث في المفردات، وأن يرى مصدر قيمة ما، وأن يقارن بين الأنظمة، وأن يقترح امتدادًا (حجمًا جديدًا للمكوّن Button، أو درجة، أو رمزًا خاصًّا بك) مع القيم الناتجة عنه، وأن يتحقق من تعديل على الطبقة قبل أن يكتبه. ويُبلَّغ الوكيل بالقواعد: غيِّر القيم عبر طبقة، ووسِّع المفردات بالإضافة فقط ومع مسوِّغ، واذكر سببًا لكل قيمة مثبَّتة، ولا تمسّ عتبة أبدًا. أما الواجهة نفسها فيجيب عنها من بيان مكوّنات النظام (components manifest) ومن المواصفات: أيّ المكوّنات يملكها النظام (وما البديل عن مكوّن لا يملكه)، وخصائص المكوّن وأحداثه وقواعد سلوكه، وأيّ العناصر وعمليات الاستيراد والمتغيّرات (variants) في شيفرتك لا يملكها النظام، مع مواضعها؛ وهو الفحص نفسه الذي يجريه tanrei audit.سجِّله من npm في مجلد منتجك (وفي استخدام Tanrei مع وكلاء الذكاء الاصطناعي إعدادات العملاء الآخرين):
claude mcp add tanrei -- npx -y @tanrei/mcp
إمكانية الوصول
عتبات التباين والفحوص البنيوية ثوابت. في طبقتك تكون المخالفة تحذيرًا، ولا تمرّ بصمت أبدًا: يطبعها tanrei build، وتُكتب في a11y-report.json، وتُختم في ترويسة كل ملف مولَّد. عند التباين المتوسط والعالي اجعل هدفك صفرًا: فهذان المخططان اللونيان موجودان لأن شخصًا طلب التباين. والإعدادات الجاهزة المضمَّنة نفسها يُحكَم عليها بمطابقتها للأنظمة التي تحاكيها، لا بمعايير إمكانية الوصول في Tanrei، في كل مخطط لوني، وقياساتها معلومات. أما الطبقة التي تبنيها فوق إعداد جاهز فتبقى منتجك، وتُحذَّر مما ترثه أيضًا.