Diffex can create themes. Ask it to build one for your setup.
Themes are JSON files that define colors for the TUI.
Diffex loads themes from:
- Built-in:
dark,light - Global:
~/.diffex/agent/themes/*.json - Project:
.diffex/themes/*.json(only after the project is trusted) - Packages:
themes/directories ordiffex.themesentries inpackage.json - Settings:
themesarray with files or directories - CLI:
--theme <path>(repeatable)
Disable discovery with --no-themes.
Select a theme via /settings or in settings.json:
{
"theme": "my-theme"
}On first run, Diffex detects your terminal background and defaults to dark or light.
- Create a theme file:
mkdir -p ~/.diffex/agent/themes
vim ~/.diffex/agent/themes/my-theme.json- Define the theme with all required colors (see Color Tokens):
{
"$schema": "https://raw.githubusercontent.com/diffexai/diffex/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
"name": "my-theme",
"vars": {
"primary": "#00aaff",
"secondary": 242
},
"colors": {
"accent": "primary",
"border": "primary",
"borderAccent": "#00ffff",
"borderMuted": "secondary",
"success": "#00ff00",
"error": "#ff0000",
"warning": "#ffff00",
"muted": "secondary",
"dim": 240,
"text": "",
"thinkingText": "secondary",
"footerModel": "#F7ED4F",
"footerContext": "#F5B427",
"footerWindow": "#3A75F2",
"startupIntroText": "#CDD6F4",
"startupIntroAccent": "#89B4FA",
"selectionAccent": "#89B4FA",
"selectedBg": "#2d2d30",
"scrollbarThumb": "#555566",
"userMessageBg": "#2d2d30",
"userMessageText": "",
"customMessageBg": "#2d2d30",
"customMessageText": "",
"customMessageLabel": "primary",
"toolPendingBg": "#1e1e2e",
"toolSuccessBg": "#1e2e1e",
"toolErrorBg": "#2e1e1e",
"toolTitle": "primary",
"toolOutput": "",
"mdHeading": "#ffaa00",
"mdLink": "primary",
"mdLinkUrl": "secondary",
"mdCode": "#00ffff",
"mdCodeBlock": "",
"mdCodeBlockBorder": "secondary",
"mdQuote": "secondary",
"mdQuoteBorder": "secondary",
"mdHr": "secondary",
"mdListBullet": "#00ffff",
"toolDiffAdded": "#00ff00",
"toolDiffRemoved": "#ff0000",
"toolDiffContext": "secondary",
"syntaxComment": "secondary",
"syntaxKeyword": "primary",
"syntaxFunction": "#00aaff",
"syntaxVariable": "#ffaa00",
"syntaxString": "#00ff00",
"syntaxNumber": "#ff00ff",
"syntaxType": "#00aaff",
"syntaxOperator": "primary",
"syntaxPunctuation": "secondary",
"thinkingOff": "secondary",
"thinkingMinimal": "primary",
"thinkingLow": "#00aaff",
"thinkingMedium": "#00ffff",
"thinkingHigh": "#ff00ff",
"thinkingXhigh": "#ff0000",
"thinkingMax": "#ff0088",
"bashMode": "#ffaa00"
}
}- Select the theme via
/settings.
Hot reload: When you edit the currently active custom theme file, Diffex reloads it automatically for immediate visual feedback.
{
"$schema": "https://raw.githubusercontent.com/diffexai/diffex/main/packages/coding-agent/src/modes/interactive/theme/theme-schema.json",
"name": "my-theme",
"vars": {
"blue": "#0066cc",
"gray": 242
},
"colors": {
"accent": "blue",
"muted": "gray",
"text": "",
...
}
}nameis required, must be unique, and must not contain/.varsis optional. Define reusable colors here, then reference them incolors.colorsmust define all 54 required tokens.editorBorder,thinkingMax,scrollbarThumb,startupIntroText,startupIntroAccent,selectionAccent, andautocompleteSelectedare optional compatibility tokens with fallbacks.
The $schema field enables editor auto-completion and validation.
Every theme must define all 54 required color tokens.
editorBorder, thinkingMax, scrollbarThumb, startupIntroText, startupIntroAccent, selectionAccent, and autocompleteSelected are optional for compatibility with existing themes.
Their fallbacks are borderMuted, thinkingXhigh, selectedBg, text, mdLink, autocompleteSelected or startupIntroAccent, and selectionAccent, respectively.
| Token | Purpose |
|---|---|
accent |
Primary accent for titles, active controls, and status elements |
border |
Normal borders |
borderAccent |
Highlighted borders |
borderMuted |
Subtle borders (editor) |
editorBorder |
Editor border; optional, falls back to borderMuted |
success |
Success states |
error |
Error states |
warning |
Warning states |
muted |
Secondary text |
dim |
Tertiary text |
text |
Default text (usually "") |
thinkingText |
Thinking block text |
| Token | Purpose |
|---|---|
footerModel |
Model name |
footerContext |
Context usage percentage |
footerWindow |
Context window size |
| Token | Purpose |
|---|---|
startupIntroText |
Startup logo art, version, directory, and changelog preview text; optional, falls back to text |
startupIntroAccent |
Startup title and boundary box; optional, falls back to mdLink |
selectionAccent |
Selected row prefix and primary text; optional, falls back to autocompleteSelected, then startupIntroAccent |
autocompleteSelected |
Legacy autocomplete selection color; optional, falls back to selectionAccent |
| Token | Purpose |
|---|---|
selectedBg |
Selected line background |
scrollbarThumb |
Fullscreen scrollbar thumb background; optional, falls back to selectedBg |
userMessageBg |
User message background |
userMessageText |
User message text |
customMessageBg |
Extension message background |
customMessageText |
Extension message text |
customMessageLabel |
Extension message label |
toolPendingBg |
Tool box (pending) |
toolSuccessBg |
Tool box (success) |
toolErrorBg |
Tool box (error) |
toolTitle |
Tool title |
toolOutput |
Tool output text |
| Token | Purpose |
|---|---|
mdHeading |
Headings |
mdLink |
Link text |
mdLinkUrl |
Link URL |
mdCode |
Inline code |
mdCodeBlock |
Code block content |
mdCodeBlockBorder |
Code block fences |
mdQuote |
Blockquote text |
mdQuoteBorder |
Blockquote border |
mdHr |
Horizontal rule |
mdListBullet |
List bullets |
| Token | Purpose |
|---|---|
toolDiffAdded |
Added lines |
toolDiffRemoved |
Removed lines |
toolDiffContext |
Context lines |
| Token | Purpose |
|---|---|
syntaxComment |
Comments |
syntaxKeyword |
Keywords |
syntaxFunction |
Function names |
syntaxVariable |
Variables |
syntaxString |
Strings |
syntaxNumber |
Numbers |
syntaxType |
Types |
syntaxOperator |
Operators |
syntaxPunctuation |
Punctuation |
Editor border colors indicating thinking level (visual hierarchy from subtle to prominent):
| Token | Purpose |
|---|---|
thinkingOff |
Thinking off |
thinkingMinimal |
Minimal thinking |
thinkingLow |
Low thinking |
thinkingMedium |
Medium thinking |
thinkingHigh |
High thinking |
thinkingXhigh |
Extra high thinking |
thinkingMax |
Maximum thinking; optional, falls back to thinkingXhigh |
| Token | Purpose |
|---|---|
bashMode |
Editor border in bash mode (! prefix) |
The export section controls colors for /export HTML output. If omitted, colors are derived from userMessageBg.
{
"export": {
"pageBg": "#18181e",
"cardBg": "#1e1e24",
"infoBg": "#3c3728"
}
}Four formats are supported:
| Format | Example | Description |
|---|---|---|
| Hex | "#ff0000" |
6-digit hex RGB |
| 256-color | 39 |
xterm 256-color palette index (0-255) |
| Variable | "primary" |
Reference to a vars entry |
| Default | "" |
Terminal's default color |
0-15: Basic ANSI colors (terminal-dependent)16-231: 6×6×6 RGB cube (16 + 36×R + 6×G + Bwhere R,G,B are 0-5)232-255: Grayscale ramp
Diffex uses 24-bit RGB colors. Most modern terminals support this (iTerm2, Kitty, WezTerm, Windows Terminal, VS Code). For older terminals with only 256-color support, Diffex falls back to the nearest approximation.
Check truecolor support:
echo $COLORTERM # Should output "truecolor" or "24bit"Dark terminals: Use bright, saturated colors with higher contrast.
Light terminals: Use darker, muted colors with lower contrast.
Color harmony: Start with a base palette (Nord, Gruvbox, Tokyo Night), define it in vars, and reference consistently.
Testing: Check your theme with different message types, tool states, markdown content, and long wrapped text.
VS Code: Set terminal.integrated.minimumContrastRatio to 1 for accurate colors.
See the built-in themes: