mirror of
https://github.com/patriceckhart/zot.git
synced 2026-06-27 05:46:34 +02:00
282 lines
7.1 KiB
Markdown
282 lines
7.1 KiB
Markdown
# zot themes
|
||
|
||
zot themes are JSON files that override any subset of the built-in
|
||
light/dark TUI theme. Nothing is required: a theme can change one
|
||
color, only the spinner, only syntax highlighting, or all of them.
|
||
Missing values inherit from zot's built-in default for the detected
|
||
terminal background.
|
||
|
||
## Where themes live
|
||
|
||
User themes are discovered from:
|
||
|
||
```text
|
||
$ZOT_HOME/themes/*.json
|
||
```
|
||
|
||
Open `/settings` and choose **color theme** to switch. Changes are
|
||
saved in `$ZOT_HOME/config.json` and apply immediately. If the selected
|
||
file is deleted later, zot resets the setting to the built-in auto
|
||
(default) theme.
|
||
|
||
Theme files bundled with extensions are discovered in-place from loaded
|
||
extension directories:
|
||
|
||
```text
|
||
$ZOT_HOME/extensions/<extension>/theme.json
|
||
$ZOT_HOME/extensions/<extension>/themes/theme.json
|
||
<project>/.zot/extensions/<extension>/theme.json
|
||
<project>/.zot/extensions/<extension>/themes/theme.json
|
||
```
|
||
|
||
zot does **not** copy extension themes into `$ZOT_HOME/themes`; extension
|
||
owned themes stay in the extension directory. The settings picker shows
|
||
source info such as `from extension my-theme-extension`.
|
||
|
||
## Minimal themes
|
||
|
||
All of these are valid.
|
||
|
||
Metadata only:
|
||
|
||
```json
|
||
{
|
||
"name": "my-theme",
|
||
"description": "Metadata only; all visuals inherit zot defaults."
|
||
}
|
||
```
|
||
|
||
One shared color for both light and dark terminals:
|
||
|
||
```json
|
||
{
|
||
"name": "pink-accent",
|
||
"colors": {
|
||
"accent": 204
|
||
}
|
||
}
|
||
```
|
||
|
||
One color per mode:
|
||
|
||
```json
|
||
{
|
||
"name": "split-accent",
|
||
"colors": {
|
||
"dark": { "accent": 204 },
|
||
"light": { "accent": 161 }
|
||
}
|
||
}
|
||
```
|
||
|
||
Spinner-only:
|
||
|
||
```json
|
||
{
|
||
"name": "custom-spinner",
|
||
"description": "Only changes the busy spinner.",
|
||
"spinner_frames": ["◢", "◣", "◤", "◥"],
|
||
"spinner_messages": ["working"],
|
||
"spinner_interval_ms": 120
|
||
}
|
||
```
|
||
|
||
Dark-only themes still work on light terminals. If `colors.light` is
|
||
missing, zot applies `colors.dark` overrides on top of the built-in
|
||
light default. The inverse also works.
|
||
|
||
```json
|
||
{
|
||
"name": "custom-spinner",
|
||
"description": "An alternative spinner for zot that only displays a single spinner text.",
|
||
"colors": {
|
||
"dark": {
|
||
"spinner_frames": ["◢", "◣", "◤", "◥"],
|
||
"spinner_messages": ["working"],
|
||
"spinner_interval_ms": 120
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## Full shape
|
||
|
||
All fields are optional.
|
||
|
||
```json
|
||
{
|
||
"name": "my-theme",
|
||
"description": "Shown in /settings → color theme.",
|
||
"color_descriptions": {
|
||
"accent": "Optional documentation for humans. zot ignores this object."
|
||
},
|
||
"colors": {
|
||
"dark": {
|
||
"fg": 253,
|
||
"muted": 244,
|
||
"accent": 111,
|
||
"background": "#0b1020",
|
||
"user": 180,
|
||
"user_bubble_bg": "#42454b",
|
||
"user_bubble_fg": 248,
|
||
"assistant": 117,
|
||
"tool": 114,
|
||
"tool_out": 245,
|
||
"error": 203,
|
||
"warning": 214,
|
||
"spinner": 183,
|
||
"selection_bg": 24,
|
||
"selection_fg": 231,
|
||
"spinner_frames": ["⠋", "⠙", "⠚", "⠞", "⠖", "⠦", "⠴", "⠲", "⠳", "⠓"],
|
||
"spinner_messages": ["thinking", "working"],
|
||
"spinner_interval_ms": 80,
|
||
"syntax_base_style": "monokai",
|
||
"syntax": {
|
||
"keyword": "#81a1c1 bold",
|
||
"keyword_constant": "#81a1c1",
|
||
"keyword_declaration": "#81a1c1",
|
||
"keyword_namespace": "#81a1c1",
|
||
"keyword_reserved": "#81a1c1 bold",
|
||
"keyword_type": "#88c0d0",
|
||
"name_builtin": "#88c0d0",
|
||
"name_function": "#8fbcbb",
|
||
"name_class": "#a3be8c bold",
|
||
"name_decorator": "#b48ead",
|
||
"literal_string": "#a3be8c",
|
||
"literal_string_escape": "#bf616a",
|
||
"literal_number": "#d08770",
|
||
"comment": "#616e88 italic",
|
||
"comment_preproc": "#b48ead",
|
||
"operator": "#eceff4",
|
||
"punctuation": "#d8dee9",
|
||
"text": "#e5e9f0"
|
||
}
|
||
},
|
||
"light": {
|
||
"fg": 236,
|
||
"muted": 244,
|
||
"accent": 33
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
You may also put overrides directly at the top level or directly under
|
||
`colors` when they should apply to both modes:
|
||
|
||
```json
|
||
{
|
||
"name": "tiny",
|
||
"accent": 204,
|
||
"colors": {
|
||
"spinner_messages": ["shipping"]
|
||
}
|
||
}
|
||
```
|
||
|
||
## Color fields
|
||
|
||
Most color fields are xterm-256 indexes (`0`–`255`).
|
||
|
||
- `fg` — default foreground text.
|
||
- `muted` — secondary text, dividers, gutters, inactive hints.
|
||
- `accent` — prompt bar, bullets, links, headings, active markers.
|
||
- `background` — optional full-row TUI background. If missing, zot uses the terminal's existing background. Experimental: terminal background colors can vary by emulator and scrollback behavior; for the most reliable result, change your terminal background color in your terminal settings instead.
|
||
- `user` — user role label color; mostly compatibility.
|
||
- `user_bubble_bg` — background behind user message rows.
|
||
- `user_bubble_fg` — foreground inside user message rows.
|
||
- `assistant` — assistant/zot accent and spinner text.
|
||
- `tool` — tool names, success marks, diff additions.
|
||
- `tool_out` — plain tool-output text.
|
||
- `error` — errors, refused calls, diff deletions.
|
||
- `warning` — warnings and high context-usage state.
|
||
- `spinner` — reserved spinner color slot.
|
||
- `selection_bg` — highlighted row background.
|
||
- `selection_fg` — highlighted row foreground.
|
||
|
||
`background` and `user_bubble_bg` support richer terminal color forms:
|
||
|
||
```json
|
||
254
|
||
"#42454b"
|
||
{ "mode": "256", "index": 254 }
|
||
{ "mode": "ansi", "index": 100 }
|
||
{ "mode": "rgb", "r": 66, "g": 69, "b": 75 }
|
||
```
|
||
|
||
## Spinner fields
|
||
|
||
Spinner settings can appear at top level, under `colors`, or under
|
||
`colors.dark` / `colors.light`.
|
||
|
||
- `spinner_frames` — list of frame strings. Single-cell glyphs keep
|
||
status-bar alignment clean.
|
||
- `spinner_messages` — list of messages; zot picks one per turn.
|
||
- `spinner_interval_ms` — frame interval in milliseconds. Missing or
|
||
invalid falls back to 80ms.
|
||
|
||
## Syntax fields
|
||
|
||
Syntax highlighting uses Chroma style entries. Values may include
|
||
attributes after the color, such as `bold`, `italic`, or `underline`.
|
||
|
||
Supported syntax override keys:
|
||
|
||
```text
|
||
keyword, keyword_constant, keyword_declaration, keyword_namespace,
|
||
keyword_reserved, keyword_type, name_builtin, name_function,
|
||
name_class, name_decorator, literal_string, literal_string_escape,
|
||
literal_number, comment, comment_preproc, operator, punctuation, text
|
||
```
|
||
|
||
Example:
|
||
|
||
```json
|
||
{
|
||
"colors": {
|
||
"dark": {
|
||
"syntax_base_style": "monokai",
|
||
"syntax": {
|
||
"keyword": "#f05b8d",
|
||
"name_function": "#b675f1",
|
||
"literal_string": "#58c760",
|
||
"comment": "#a1a1a1 italic"
|
||
}
|
||
}
|
||
}
|
||
}
|
||
```
|
||
|
||
## Theme-only extensions
|
||
|
||
An extension can exist only to ship a theme. No slash command,
|
||
subprocess, or executable is required when the extension contains a
|
||
valid theme file.
|
||
|
||
```text
|
||
$ZOT_HOME/extensions/my-theme-extension/
|
||
├── extension.json
|
||
└── theme.json
|
||
```
|
||
|
||
`extension.json`:
|
||
|
||
```json
|
||
{
|
||
"name": "my-theme-extension",
|
||
"version": "1.0.0",
|
||
"description": "Ships a zot color theme",
|
||
"enabled": true
|
||
}
|
||
```
|
||
|
||
No `exec` is needed when `theme.json` or `themes/theme.json` exists.
|
||
If `exec` is present, zot treats it as a normal extension too.
|
||
|
||
## Validate
|
||
|
||
zot theme files are plain JSON, not JSONC. Validate before installing:
|
||
|
||
```bash
|
||
python3 -m json.tool theme.json >/dev/null
|
||
```
|