Make TUI themes data: JSON theme files with user and project discovery#374
Conversation
b3a27e2 to
c47988f
Compare
Themes become data, following Pi's design. The three built-in themes ship as packaged JSON parsed by the same validator as user themes; custom themes are discovered at startup from ~/.tau/themes and <project>/.tau/themes (project wins on name collisions) and appear in /theme, completions, the picker, and Textual's native theme menu. Invalid files are skipped with a startup notice listing every problem at once, and a configured theme that cannot be found falls back to tau-dark without overwriting the setting. The theme format mirrors TuiTheme: name, optional dark (defaulting from background luminance) and syntax_theme, a vars block for palette colors referenced by token inside style strings, colors, and per-role border/body styles. Colors previously hardcoded in the transcript renderer (tool result accents and their background, success/error) are now theme tokens; built-ins render identically except tau-light's failed tool border, which now uses its error token.
c47988f to
c70d4fa
Compare
alejandro-ao
left a comment
There was a problem hiding this comment.
Thanks for making themes data-driven and adding user/project discovery. The implementation and test coverage are generally strong, but there is one startup-safety issue to address before merging.
The theme parser validates palette colors with Rich's Color.parse (src/tau_coding/tui/themes/__init__.py:231-234), while those colors are later passed to Textual's Theme and CSS variables. Rich accepts formats that Textual rejects, such as color(123), bright_red, grey50, and default. As a result, a custom theme can pass validation but crash the TUI when selected—or at startup if it is configured—instead of being skipped with a diagnostic.
Please validate fields consumed by Textual with Textual's color parser, while retaining Rich validation for Rich-only role/style fields. A regression test using a Rich-valid/Textual-invalid color should verify that such a theme is rejected during discovery.
The branch also currently conflicts with the latest main in src/tau_coding/tui/app.py, so it will need to be updated before merging.
# Conflicts: # src/tau_coding/tui/app.py # src/tau_coding/tui/widgets.py
Rich's Color.parse accepts syntax Textual rejects (bright_red, grey50, color(1), default), so a custom theme could pass discovery validation and then crash the TUI at startup or on selection. Colors that reach Textual (CSS variables, Theme slots, role borders via styles.border_left, and the foreground/background of role bodies via styles.color/background) now have to parse under both libraries. tool_success_text/tool_error_text and the completion_* style strings are only ever rendered through Rich and keep Rich-only validation.
|
Thanks, addressed those and got it up to date with main. Summary below!
|
There was a problem hiding this comment.
Thank you, @rian-dolphin — both requested changes are addressed, and this is in great shape.
|
adding hand-written thank you for all your help. merging. you rock! 🤘 |
# Conflicts: # src/tau_coding/tui/config.py # website/content/guides/tui.md
|
Updated this branch with the latest
Local validation on the integrated branch:
All checks passed. The Pagefind command was run against the public npm registry because this environment's configured Hugging Face npm mirror timed out. |
alejandro-ao
left a comment
There was a problem hiding this comment.
Re-approving after the latest main integration and built-in theme compatibility fixes. Local validation and GitHub CI pass.
Themes were hardcoded Python literals behind a closed
Literaltype — adding one meant editingconfig.py. Following Pi, themes are now data: JSON files with avarspalette, color tokens, and per-role styles.I.e. you can change to your own theme without editing any python.
The built-in themes now ship as packaged JSON through the same parser, and custom themes are discovered at startup from
~/.tau/themes/and<project>/.tau/themes/, appearing in/theme, completions, the picker, and Textual's native theme menu.Example of a custom theme can be seen here. Just put it in
~/.tau/themes/catppuccin-mocha.jsonand then it will be available to choose.Notes
A broken theme can never break tau: invalid files are skipped with a startup notice listing every problem at once, and a missing configured theme falls back to tau-dark without overwriting the setting. Colors previously hardcoded in the transcript renderer (tool accents, success/error) became theme tokens; built-ins render identically. The format is documented in the website's new Themes guide.
Hot reload and extension-contributed themes are left as follow-ups.