- الرئيسية
- Documentation
- TUI
- مرجع السمات
مرجع السمات
يصف هذا المستند كيفية عمل نظام السمات في وكيل الترميز اليوم: المخطط، والتحميل، وسلوك وقت التشغيل، وأوضاع الفشل.
ما يتحكم فيه نظام السمات
Section titled “ما يتحكم فيه نظام السمات”يتحكم نظام السمات في:
- رموز ألوان المقدمة/الخلفية المستخدمة عبر TUI
- محوّلات تنسيق markdown (
getMarkdownTheme()) - محوّلات المحدد/المحرر/قائمة الإعدادات (
getSelectListTheme()،getEditorTheme()،getSettingsListTheme()) - الإعداد المسبق للرموز + تجاوزات الرموز (
unicode،nerd،ascii) - ألوان تمييز بناء الجملة المستخدمة بواسطة المُمَيِّز الأصلي (
@f5-sales-demo/pi-natives) - ألوان أجزاء شريط الحالة
التنفيذ الأساسي: src/modes/theme/theme.ts.
شكل ملف JSON للسمة
Section titled “شكل ملف JSON للسمة”ملفات السمات هي كائنات JSON يتم التحقق من صحتها مقابل مخطط وقت التشغيل في theme.ts (ThemeJsonSchema) والمعكوسة بواسطة src/modes/theme/theme-schema.json.
الحقول ذات المستوى الأعلى:
name(مطلوب)colors(مطلوب؛ جميع رموز الألوان مطلوبة)vars(اختياري؛ متغيرات ألوان قابلة لإعادة الاستخدام)export(اختياري؛ ألوان تصدير HTML)symbols(اختياري)preset(اختياري:unicode | nerd | ascii)overrides(اختياري: تجاوزات مفتاح/قيمة لـSymbolKey)
تقبل قيم الألوان:
- سلسلة hex (
"#RRGGBB") - مؤشر 256 لونًا (
0..255) - سلسلة مرجع متغير (يتم حلها عبر
vars) - سلسلة فارغة (
"") تعني الإعداد الافتراضي للطرفية (\x1b[39mللمقدمة،\x1b[49mللخلفية)
رموز الألوان المطلوبة (الحالية)
Section titled “رموز الألوان المطلوبة (الحالية)”جميع الرموز أدناه مطلوبة في colors.
النص الأساسي والحدود (11)
Section titled “النص الأساسي والحدود (11)”accent، border، borderAccent، borderMuted، success، error، warning، muted، dim، text، thinkingText
كتل الخلفية (7)
Section titled “كتل الخلفية (7)”selectedBg، userMessageBg، customMessageBg، toolPendingBg، toolSuccessBg، toolErrorBg، statusLineBg
نص الرسائل/الأدوات (5)
Section titled “نص الرسائل/الأدوات (5)”userMessageText، customMessageText، customMessageLabel، toolTitle، toolOutput
Markdown (10)
Section titled “Markdown (10)”mdHeading، mdLink، mdLinkUrl، mdCode، mdCodeBlock، mdCodeBlockBorder، mdQuote، mdQuoteBorder، mdHr، mdListBullet
فروق الأدوات + تمييز بناء الجملة (12)
Section titled “فروق الأدوات + تمييز بناء الجملة (12)”toolDiffAdded، toolDiffRemoved، toolDiffContext،
syntaxComment، syntaxKeyword، syntaxFunction، syntaxVariable، syntaxString، syntaxNumber، syntaxType، syntaxOperator، syntaxPunctuation
حدود الوضع/التفكير (8)
Section titled “حدود الوضع/التفكير (8)”thinkingOff، thinkingMinimal، thinkingLow، thinkingMedium، thinkingHigh، thinkingXhigh، bashMode، pythonMode
ألوان أجزاء شريط الحالة (14)
Section titled “ألوان أجزاء شريط الحالة (14)”statusLineSep، statusLineModel، statusLinePath، statusLineGitClean، statusLineGitDirty، statusLineContext، statusLineSpend، statusLineStaged، statusLineDirty، statusLineUntracked، statusLineOutput، statusLineCost، statusLineSubagents
الرموز الاختيارية
Section titled “الرموز الاختيارية”قسم export (اختياري)
Section titled “قسم export (اختياري)”يُستخدم لمساعدات تحديد سمات تصدير HTML:
export.pageBgexport.cardBgexport.infoBg
إذا تم حذفه، يشتق كود التصدير القيم الافتراضية من ألوان السمة المحلولة.
قسم symbols (اختياري)
Section titled “قسم symbols (اختياري)”symbols.presetيضبط مجموعة الرموز الافتراضية على مستوى السمة.symbols.overridesيمكنه تجاوز قيمSymbolKeyالفردية.
أولوية وقت التشغيل:
- تجاوز الإعدادات
symbolPreset(إذا تم ضبطه) symbols.presetفي JSON للسمة- الاحتياطي
"unicode"
يتم تجاهل مفاتيح التجاوز غير الصالحة وتسجيلها (logger.debug).
مصادر السمات المدمجة مقابل المخصصة
Section titled “مصادر السمات المدمجة مقابل المخصصة”ترتيب البحث عن السمات (loadThemeJson):
- السمات المدمجة المضمنة (
defaults/xcsh-dark.jsonوdefaults/xcsh-light.jsonالمترجمة إلىdefaultThemes) - ملف السمة المخصصة:
<customThemesDir>/<name>.json
يأتي دليل السمات المخصصة من getCustomThemesDir():
- الافتراضي:
~/.xcsh/agent/themes - يتم تجاوزه بواسطة
PI_CODING_AGENT_DIR($PI_CODING_AGENT_DIR/themes)
تُرجع getAvailableThemes() الأسماء المدمجة والمخصصة مدمجةً، مرتبةً، مع أسبقية المدمجة عند تعارض الأسماء.
التحميل والتحقق والحل
Section titled “التحميل والتحقق والحل”لملفات السمات المخصصة:
- قراءة JSON
- تحليل JSON
- التحقق من الصحة مقابل
ThemeJsonSchema - حل مراجع
varsبشكل تكراري - تحويل القيم المحلولة إلى ANSI حسب وضع قدرة الطرفية
سلوك التحقق:
- رموز الألوان المطلوبة المفقودة: رسالة خطأ مجمعة صريحة
- أنواع/قيم رموز خاطئة: أخطاء تحقق مع مسار JSON
- ملف سمة غير معروف:
Theme not found: <name>
سلوك مرجع المتغيرات:
- يدعم المراجع المتداخلة
- يُلقي خطأً عند مرجع متغير مفقود
- يُلقي خطأً عند المراجع الدائرية
سلوك وضع ألوان الطرفية
Section titled “سلوك وضع ألوان الطرفية”اكتشاف وضع الألوان (detectColorMode):
COLORTERM=truecolor|24bit=> truecolorWT_SESSION=> truecolorTERMفيdumb،linux، أو فارغ => 256color- وإلا => truecolor
سلوك التحويل:
- hex ->
Bun.color(..., "ansi-16m" | "ansi-256") - رقمي ->
38;5/48;5ANSI ""-> إعادة ضبط fg/bg الافتراضي
سلوك التبديل في وقت التشغيل
Section titled “سلوك التبديل في وقت التشغيل”السمة الأولية (initTheme)
Section titled “السمة الأولية (initTheme)”تقوم main.ts بتهيئة السمة مع الإعدادات:
symbolPresetcolorBlindModetheme.darktheme.light
يستخدم الاختيار التلقائي لفتحة السمة اكتشاف خلفية COLORFGBG:
- تحليل مؤشر الخلفية من
COLORFGBG < 8=> فتحة داكنة (theme.dark)>= 8=> فتحة فاتحة (theme.light)- فشل التحليل => فتحة داكنة
الإعدادات الافتراضية الحالية من مخطط الإعدادات:
theme.dark = "xcsh-dark"theme.light = "xcsh-light"symbolPreset = "unicode"colorBlindMode = false
التبديل الصريح (setTheme)
Section titled “التبديل الصريح (setTheme)”- تحميل السمة المحددة
- تحديث المفرد العام
theme - بدء المراقب اختياريًا
- تشغيل رد النداء
onThemeChange
عند الفشل:
- الرجوع إلى السمة
darkالمدمجة - إرجاع
{ success: false, error }
تبديل المعاينة (previewTheme)
Section titled “تبديل المعاينة (previewTheme)”- تطبيق سمة معاينة مؤقتة على
themeالعام - لا يغير الإعدادات المحفوظة بحد ذاته
- إرجاع النجاح/الخطأ دون استبدال احتياطي
تستخدم واجهة مستخدم الإعدادات هذا للمعاينة المباشرة وتستعيد السمة السابقة عند الإلغاء.
المراقبون وإعادة التحميل المباشر
Section titled “المراقبون وإعادة التحميل المباشر”عند تمكين المراقب (setTheme(..., true) / التهيئة التفاعلية):
- يراقب فقط مسار الملف المخصص
<customThemesDir>/<currentTheme>.json - السمات المدمجة لا تُراقب فعليًا
changeللملف: محاولة إعادة التحميل (مُؤخرة)rename/حذف الملف: الرجوع إلىdark، إغلاق المراقب
يقوم الوضع التلقائي أيضًا بتثبيت مستمع SIGWINCH ويمكنه إعادة تقييم تعيين فتحة داكن/فاتح عند تغير حالة الطرفية.
سلوك وضع عمى الألوان
Section titled “سلوك وضع عمى الألوان”يغير colorBlindMode رمزًا واحدًا فقط في وقت التشغيل:
- يتم ضبط
toolDiffAddedباستخدام HSV (تحويل اللون الأخضر نحو الأزرق) - يُطبَّق الضبط فقط عندما تكون القيمة المحلولة سلسلة hex
الرموز الأخرى لا تتغير.
مكان حفظ إعدادات السمة
Section titled “مكان حفظ إعدادات السمة”يتم حفظ الإعدادات المتعلقة بالسمة بواسطة Settings في ملف YAML للإعداد العام:
- المسار:
<agentDir>/config.yml - دليل الوكيل الافتراضي:
~/.xcsh/agent - الملف الافتراضي الفعلي:
~/.xcsh/agent/config.yml
المفاتيح المحفوظة:
theme.darktheme.lightsymbolPresetcolorBlindMode
يوجد ترحيل قديم: يتم ترحيل theme: "name" المسطح القديم إلى theme.dark أو theme.light المتداخل بناءً على اكتشاف السطوع.
إنشاء سمة مخصصة (عملي)
Section titled “إنشاء سمة مخصصة (عملي)”- أنشئ ملفًا في دليل السمات المخصصة، مثلًا
~/.xcsh/agent/themes/my-theme.json. - أدرج
name، وإختياريًاvars، وجميع رموزcolorsالمطلوبة. - أدرج اختياريًا
symbolsوexport. - حدد السمة في الإعدادات (
Display -> Dark themeأوDisplay -> Light theme) بحسب فتحة التحديد التلقائي التي تريدها.
هيكل عظمي أدنى. كل مفتاح في colors مطلوب — يرفض المدقق في وقت التشغيل
(additionalProperties: false) كلًا من المفاتيح المفقودة والمفاتيح غير المعروفة.
للاطلاع على تطبيقات المرجع المشحونة راجع
packages/coding-agent/src/modes/theme/defaults/xcsh-dark.json
و xcsh-light.json.
يحتوي شريط الحالة على نظامَي ألوان متوازيَين موثقَين في المشكلة #242:
- ألوان النص بصيغة Hex (
statusLinePath،statusLineGitClean،statusLineGitDirty،statusLineStaged،statusLineDirty،statusLineUntracked) تُشغّل عرض non-powerline. - مؤشرات لوحة الألوان 256 (
statusLine<Segment>Bg/statusLine<Segment>Fg) تُشغّل تعبئات أجزاء powerline. وهي مستقلة عن مفاتيح hex أعلاه — يجب ضبط كليهما.
{ "name": "my-theme", "vars": { "accent": "#7aa2f7", "muted": 244 }, "colors": { "accent": "accent", "chromeAccent": "accent", "spinnerAccent": "accent", "contentAccent": "muted", "border": "#4c566a", "borderAccent": "accent", "borderMuted": "muted", "success": "#9ece6a", "error": "#f7768e", "warning": "#e0af68", "muted": "muted", "dim": 240, "gutterSuccess": "#7dcfff", "gutterWarning": "#e0af68", "text": "", "thinkingText": "muted",
"selectedBg": "#2a2f45", "userMessageBg": "#1f2335", "userMessageText": "", "customMessageBg": "#24283b", "customMessageText": "", "customMessageLabel": "accent", "toolPendingBg": "#1f2335", "toolSuccessBg": "#1f2d2a", "toolErrorBg": "#2d1f2a", "toolTitle": "", "toolOutput": "muted",
"mdHeading": "accent", "mdLink": "accent", "mdLinkUrl": "muted", "mdCode": "#c0caf5", "mdCodeBlock": "#c0caf5", "mdCodeBlockBorder": "muted", "mdQuote": "muted", "mdQuoteBorder": "muted", "mdHr": "muted", "mdListBullet": "accent",
"toolDiffAdded": "#9ece6a", "toolDiffRemoved": "#f7768e", "toolDiffContext": "muted",
"syntaxComment": "#565f89", "syntaxKeyword": "#bb9af7", "syntaxFunction": "#7aa2f7", "syntaxVariable": "#c0caf5", "syntaxString": "#9ece6a", "syntaxNumber": "#ff9e64", "syntaxType": "#2ac3de", "syntaxOperator": "#89ddff", "syntaxPunctuation": "#9aa5ce", "syntaxControl": "#bb9af7",
"thinkingOff": 240, "thinkingMinimal": 244, "thinkingLow": "#7aa2f7", "thinkingMedium": "#2ac3de", "thinkingHigh": "#bb9af7", "thinkingXhigh": "#f7768e",
"bashMode": "#2ac3de", "pythonMode": "#bb9af7",
"statusLineBg": "#16161e", "statusLineSep": 240, "statusLineModel": "#bb9af7", "statusLinePath": "#7aa2f7", "statusLineGitClean": "#9ece6a", "statusLineGitDirty": "#e0af68", "statusLineContext": "#2ac3de", "statusLineSpend": "#7dcfff", "statusLineStaged": "#9ece6a", "statusLineDirty": "#e0af68", "statusLineUntracked": "#f7768e", "statusLineOutput": "#c0caf5", "statusLineCost": "#ff9e64", "statusLineSubagents": "#bb9af7",
"statusLineOsIconBg": 7, "statusLineOsIconFg": 232, "statusLinePathBg": 4, "statusLinePathFg": 254, "statusLineGitCleanBg": 2, "statusLineGitCleanFg": 0, "statusLineGitDirtyBg": 3, "statusLineGitDirtyFg": 0, "statusLineGitStagedBg": 64, "statusLineGitStagedFg": 0, "statusLineGitUntrackedBg": 39, "statusLineGitUntrackedFg": 0, "statusLineGitConflictBg": 1, "statusLineGitConflictFg": 7, "statusLinePlanModeBg": 236, "statusLinePlanModeFg": 117, "statusLineProfileXcshBg": "accent", "statusLineProfileXcshFg": 231 }}اختبار السمات المخصصة
Section titled “اختبار السمات المخصصة”استخدم هذه الطريقة:
- ابدأ الوضع التفاعلي (المراقب مُمكَّن منذ بدء التشغيل).
- افتح الإعدادات وقم بمعاينة قيم السمة (مباشر
previewTheme). - لملفات السمات المخصصة، قم بتعديل JSON أثناء التشغيل وتأكد من إعادة التحميل التلقائي عند الحفظ.
- اختبر الأسطح الحيوية:
- عرض markdown
- كتل الأدوات (معلق/ناجح/خطأ)
- عرض الفروق (مضاف/محذوف/سياق)
- قابلية قراءة شريط الحالة
- تغييرات حدود مستوى التفكير
- ألوان حدود وضع bash/python
- تحقق من صحة كلا الإعدادات المسبقة للرموز إذا كانت سمتك تعتمد على عرض/مظهر الرموز.
القيود والتحفظات الفعلية
Section titled “القيود والتحفظات الفعلية”- جميع رموز
colorsمطلوبة للسمات المخصصة. exportوsymbolsاختياريان.$schemaفي JSON للسمة إعلامي؛ يُفرض التحقق في وقت التشغيل بواسطة مخطط TypeBox المترجم في الكود.- فشل
setThemeيرجع إلىdark؛ فشلpreviewThemeلا يستبدل السمة الحالية. - أخطاء إعادة تحميل مراقب الملف تُبقي السمة المحملة الحالية حتى يتم تشغيل إعادة تحميل ناجحة أو مسار احتياطي.