- Startseite
- Documentation
- TUI
- Theming-Referenz
Theming-Referenz
Dieses Dokument beschreibt, wie das Theming im Coding-Agent funktioniert: Schema, Laden, Laufzeitverhalten und Fehlermodi.
Was das Theme-System steuert
Abschnitt betitelt „Was das Theme-System steuert“Das Theme-System steuert:
- Vordergrund-/Hintergrund-Farb-Tokens, die im gesamten TUI verwendet werden
- Markdown-Styling-Adapter (
getMarkdownTheme()) - Selektor-/Editor-/Einstellungslisten-Adapter (
getSelectListTheme(),getEditorTheme(),getSettingsListTheme()) - Symbol-Voreinstellung + Symbol-Überschreibungen (
unicode,nerd,ascii) - Syntaxhervorhebungsfarben des nativen Highlighters (
@f5-sales-demo/pi-natives) - Farben der Statuszeilensegmente
Primäre Implementierung: src/modes/theme/theme.ts.
JSON-Struktur des Themes
Abschnitt betitelt „JSON-Struktur des Themes“Theme-Dateien sind JSON-Objekte, die gegen das Laufzeitschema in theme.ts (ThemeJsonSchema) validiert werden und durch src/modes/theme/theme-schema.json gespiegelt werden.
Felder der obersten Ebene:
name(erforderlich)colors(erforderlich; alle Farb-Tokens erforderlich)vars(optional; wiederverwendbare Farbvariablen)export(optional; HTML-Export-Farben)symbols(optional)preset(optional:unicode | nerd | ascii)overrides(optional: Schlüssel/Wert-Überschreibungen fürSymbolKey)
Farbwerte akzeptieren:
- Hex-Zeichenkette (
"#RRGGBB") - 256-Farb-Index (
0..255) - Variablenreferenz-Zeichenkette (wird durch
varsaufgelöst) - Leere Zeichenkette (
"") bedeutet Terminal-Standard (\x1b[39mfg,\x1b[49mbg)
Erforderliche Farb-Tokens (aktuell)
Abschnitt betitelt „Erforderliche Farb-Tokens (aktuell)“Alle nachfolgenden Tokens sind in colors erforderlich.
Kerntexte und Rahmen (11)
Abschnitt betitelt „Kerntexte und Rahmen (11)“accent, border, borderAccent, borderMuted, success, error, warning, muted, dim, text, thinkingText
Hintergrundblöcke (7)
Abschnitt betitelt „Hintergrundblöcke (7)“selectedBg, userMessageBg, customMessageBg, toolPendingBg, toolSuccessBg, toolErrorBg, statusLineBg
Nachrichten-/Werkzeugtext (5)
Abschnitt betitelt „Nachrichten-/Werkzeugtext (5)“userMessageText, customMessageText, customMessageLabel, toolTitle, toolOutput
Markdown (10)
Abschnitt betitelt „Markdown (10)“mdHeading, mdLink, mdLinkUrl, mdCode, mdCodeBlock, mdCodeBlockBorder, mdQuote, mdQuoteBorder, mdHr, mdListBullet
Werkzeug-Diff + Syntaxhervorhebung (12)
Abschnitt betitelt „Werkzeug-Diff + Syntaxhervorhebung (12)“toolDiffAdded, toolDiffRemoved, toolDiffContext,
syntaxComment, syntaxKeyword, syntaxFunction, syntaxVariable, syntaxString, syntaxNumber, syntaxType, syntaxOperator, syntaxPunctuation
Modus-/Denkrahmen (8)
Abschnitt betitelt „Modus-/Denkrahmen (8)“thinkingOff, thinkingMinimal, thinkingLow, thinkingMedium, thinkingHigh, thinkingXhigh, bashMode, pythonMode
Statuszeilensegment-Farben (14)
Abschnitt betitelt „Statuszeilensegment-Farben (14)“statusLineSep, statusLineModel, statusLinePath, statusLineGitClean, statusLineGitDirty, statusLineContext, statusLineSpend, statusLineStaged, statusLineDirty, statusLineUntracked, statusLineOutput, statusLineCost, statusLineSubagents
Optionale Tokens
Abschnitt betitelt „Optionale Tokens“Abschnitt export (optional)
Abschnitt betitelt „Abschnitt export (optional)“Wird für HTML-Export-Theming-Hilfsfunktionen verwendet:
export.pageBgexport.cardBgexport.infoBg
Wenn weggelassen, leitet der Export-Code Standardwerte aus den aufgelösten Theme-Farben ab.
Abschnitt symbols (optional)
Abschnitt betitelt „Abschnitt symbols (optional)“symbols.presetlegt einen Standard-Symbolsatz auf Theme-Ebene fest.symbols.overrideskann einzelneSymbolKey-Werte überschreiben.
Laufzeit-Rangfolge:
- Einstellungs-
symbolPreset-Überschreibung (falls gesetzt) - Theme-JSON
symbols.preset - Fallback
"unicode"
Ungültige Überschreibungsschlüssel werden ignoriert und protokolliert (logger.debug).
Eingebaute vs. benutzerdefinierte Theme-Quellen
Abschnitt betitelt „Eingebaute vs. benutzerdefinierte Theme-Quellen“Reihenfolge der Theme-Suche (loadThemeJson):
- Eingebaute, eingebettete Themes (
defaults/xcsh-dark.jsonunddefaults/xcsh-light.json, kompiliert indefaultThemes) - Benutzerdefinierte Theme-Datei:
<customThemesDir>/<name>.json
Das Verzeichnis für benutzerdefinierte Themes stammt von getCustomThemesDir():
- Standard:
~/.xcsh/agent/themes - Überschrieben durch
PI_CODING_AGENT_DIR($PI_CODING_AGENT_DIR/themes)
getAvailableThemes() gibt zusammengeführte eingebaute + benutzerdefinierte Namen zurück, sortiert, wobei eingebaute Themes bei Namenskollisionen Vorrang haben.
Laden, Validierung und Auflösung
Abschnitt betitelt „Laden, Validierung und Auflösung“Für benutzerdefinierte Theme-Dateien:
- JSON lesen
- JSON parsen
- Gegen
ThemeJsonSchemavalidieren vars-Referenzen rekursiv auflösen- Aufgelöste Werte nach ANSI gemäß Terminal-Fähigkeitsmodus konvertieren
Validierungsverhalten:
- Fehlende erforderliche Farb-Tokens: explizite gruppierte Fehlermeldung
- Falsche Token-Typen/-Werte: Validierungsfehler mit JSON-Pfad
- Unbekannte Theme-Datei:
Theme not found: <name>
Verhalten von Variablenreferenzen:
- Unterstützt verschachtelte Referenzen
- Löst Ausnahme bei fehlender Variablenreferenz aus
- Löst Ausnahme bei Zirkularreferenzen aus
Verhalten des Terminal-Farbmodus
Abschnitt betitelt „Verhalten des Terminal-Farbmodus“Farbmoduserkennung (detectColorMode):
COLORTERM=truecolor|24bit=> TruecolorWT_SESSION=> TruecolorTERMindumb,linuxoder leer => 256-Farben- andernfalls => Truecolor
Konvertierungsverhalten:
- Hex ->
Bun.color(..., "ansi-16m" | "ansi-256") - Numerisch ->
38;5/48;5ANSI ""-> Standard fg/bg-Reset
Laufzeit-Wechselverhalten
Abschnitt betitelt „Laufzeit-Wechselverhalten“Initiales Theme (initTheme)
Abschnitt betitelt „Initiales Theme (initTheme)“main.ts initialisiert das Theme mit Einstellungen:
symbolPresetcolorBlindModetheme.darktheme.light
Die automatische Theme-Slot-Auswahl verwendet COLORFGBG-Hintergrunderkennung:
- Hintergrundindex aus
COLORFGBGparsen < 8=> Dunkel-Slot (theme.dark)>= 8=> Hell-Slot (theme.light)- Parse-Fehler => Dunkel-Slot
Aktuelle Standardwerte aus dem Einstellungsschema:
theme.dark = "xcsh-dark"theme.light = "xcsh-light"symbolPreset = "unicode"colorBlindMode = false
Expliziter Wechsel (setTheme)
Abschnitt betitelt „Expliziter Wechsel (setTheme)“- Lädt ausgewähltes Theme
- Aktualisiert globales
theme-Singleton - Startet optional einen Watcher
- Löst
onThemeChange-Callback aus
Bei Fehler:
- Fällt auf eingebautes
darkzurück - Gibt
{ success: false, error }zurück
Vorschau-Wechsel (previewTheme)
Abschnitt betitelt „Vorschau-Wechsel (previewTheme)“- Wendet temporäres Vorschau-Theme auf globales
themean - Ändert nicht die persistierten Einstellungen
- Gibt Erfolg/Fehler ohne Fallback-Ersatz zurück
Die Einstellungs-UI nutzt dies für die Live-Vorschau und stellt beim Abbrechen das vorherige Theme wieder her.
Watcher und Live-Reload
Abschnitt betitelt „Watcher und Live-Reload“Wenn der Watcher aktiviert ist (setTheme(..., true) / interaktive Initialisierung):
- Überwacht nur den benutzerdefinierten Dateipfad
<customThemesDir>/<currentTheme>.json - Eingebaute Themes werden effektiv nicht überwacht
- Datei
change: Versucht Neuladen (entprellt) - Datei
rename/Löschen: Fällt aufdarkzurück, schließt Watcher
Der Auto-Modus installiert außerdem einen SIGWINCH-Listener und kann die Dunkel-/Hell-Slot-Zuordnung neu auswerten, wenn sich der Terminal-Status ändert.
Verhalten des Farbenblind-Modus
Abschnitt betitelt „Verhalten des Farbenblind-Modus“colorBlindMode ändert zur Laufzeit nur ein Token:
toolDiffAddedwird per HSV angepasst (Grün in Richtung Blau verschoben)- Die Anpassung wird nur angewendet, wenn der aufgelöste Wert eine Hex-Zeichenkette ist
Alle anderen Tokens bleiben unverändert.
Wo Theme-Einstellungen gespeichert werden
Abschnitt betitelt „Wo Theme-Einstellungen gespeichert werden“Theme-bezogene Einstellungen werden von Settings in der globalen Konfigurations-YAML gespeichert:
- Pfad:
<agentDir>/config.yml - Standard-Agent-Verzeichnis:
~/.xcsh/agent - Effektive Standarddatei:
~/.xcsh/agent/config.yml
Gespeicherte Schlüssel:
theme.darktheme.lightsymbolPresetcolorBlindMode
Eine Legacy-Migration existiert: Das alte flache theme: "name" wird basierend auf der Luminanz-Erkennung zu verschachteltem theme.dark oder theme.light migriert.
Erstellen eines benutzerdefinierten Themes (praktisch)
Abschnitt betitelt „Erstellen eines benutzerdefinierten Themes (praktisch)“- Erstellen Sie eine Datei im Verzeichnis für benutzerdefinierte Themes, z. B.
~/.xcsh/agent/themes/my-theme.json. - Geben Sie
name, optionalevarsund alle erforderlichencolors-Tokens an. - Fügen Sie optional
symbolsundexporthinzu. - Wählen Sie das Theme in den Einstellungen (
Anzeige -> Dunkles ThemeoderAnzeige -> Helles Theme) aus, je nachdem, welchen Auto-Slot Sie möchten.
Minimales Grundgerüst. Jeder Schlüssel in colors ist erforderlich — der Laufzeit-Validator
(additionalProperties: false) weist sowohl fehlende als auch unbekannte Schlüssel zurück.
Als mitgelieferte Referenzimplementierungen siehe
packages/coding-agent/src/modes/theme/defaults/xcsh-dark.json
und xcsh-light.json.
Die Statuszeile verfügt über zwei parallele Farbsysteme, die in Issue #242 dokumentiert sind:
- Hex-Textfarben (
statusLinePath,statusLineGitClean,statusLineGitDirty,statusLineStaged,statusLineDirty,statusLineUntracked) steuern das Nicht-Powerline- Rendering. - 256-Farb-Palettenindizes (
statusLine<Segment>Bg/statusLine<Segment>Fg) steuern Powerline-Segment-Füllungen. Sie sind unabhängig von den Hex-Schlüsseln oben — beide müssen gesetzt werden.
{ "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 }}Benutzerdefinierte Themes testen
Abschnitt betitelt „Benutzerdefinierte Themes testen“Verwenden Sie diesen Workflow:
- Starten Sie den interaktiven Modus (Watcher wird beim Start aktiviert).
- Öffnen Sie die Einstellungen und zeigen Sie Theme-Werte in der Vorschau an (Live-
previewTheme). - Bearbeiten Sie bei benutzerdefinierten Theme-Dateien das JSON während der Laufzeit und bestätigen Sie das automatische Neuladen beim Speichern.
- Testen Sie kritische Oberflächen:
- Markdown-Rendering
- Werkzeugblöcke (ausstehend/erfolgreich/fehlerhaft)
- Diff-Rendering (hinzugefügt/entfernt/Kontext)
- Lesbarkeit der Statuszeile
- Rahmenänderungen bei Denkstufen
- Rahmenfarben für Bash-/Python-Modus
- Validieren Sie beide Symbol-Voreinstellungen, wenn Ihr Theme von der Glyphenbreite/-darstellung abhängt.
Reale Einschränkungen und Vorbehalte
Abschnitt betitelt „Reale Einschränkungen und Vorbehalte“- Alle
colors-Tokens sind für benutzerdefinierte Themes erforderlich. exportundsymbolssind optional.$schemain Theme-JSON ist informativ; die Laufzeitvalidierung wird durch das kompilierte TypeBox-Schema im Code erzwungen.setTheme-Fehler fallen aufdarkzurück;previewTheme-Fehler ersetzen das aktuelle Theme nicht.- Watcher-Reload-Fehler behalten das aktuell geladene Theme bei, bis ein erfolgreiches Neuladen oder ein Fallback-Pfad ausgelöst wird.