feat(theme): tailTUI theme schema, Omarchy template and live reload - #4
Merged
Conversation
Phase 27 taught the loader to read Omarchy's palette, but some mappings are genuinely undecidable in code. osaka-jade defines yellow as #459451 -- a green -- so mapping yellow to the warning role makes exit-node markers nearly indistinguishable from the online color. Preferring orange instead breaks retro-82, where orange is the accent. There is no rule that is right for every theme, so hand the decision to the person looking at the screen. - Add tailTUI's own theme schema: one key per Theme field, tried ahead of both Omarchy schemas, and probed as tailtui.toml before colors.toml in each theme directory. Its keys are disjoint from the Omarchy vocabularies, so detection stays a question of which keys appear. - Ship contrib/tailtui.toml.tpl. Installed into ~/.config/omarchy/themed/, Omarchy renders it into the active theme directory on every theme switch -- the same directory the loader already probes, so no new path was needed. - Reload the palette live. styles.ThemeStamp() reports the active file's path and mtime; checkThemeCmd rides the existing refresh tick, so there is no watcher dependency. Switching the desktop theme re-colors a running tailTUI within one tick. The command returns the parsed Theme rather than applying it: styles.Apply rewrites package-level vars that View reads, so applying it off-thread would race the renderer. Update applies it on the Elm goroutine, records the stamp even when unchanged (so a theme file appearing or vanishing is noticed), and rebuilds viewport-backed overlays, whose content would otherwise keep stale ANSI colors. Zero-config behavior is unchanged: with no template installed, colors.toml is read exactly as before. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Omarchy seds the whole file, comments included, so instructional text
written with {{ placeholders }} got replaced too. The guidance in a
generated tailtui.toml then read "use #a2734b here instead", which does
not tell anyone which placeholder to write.
Name the slots in prose instead. The one {{ placeholder }} left in a
comment is deliberate: no theme defines a key by that name, so it
renders literally and demonstrates the syntax.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Merged
Phundahl
added a commit
that referenced
this pull request
Aug 21, 2026
* chore(release): v1.3.0 Live theme switching and tailTUI's own theme schema (#4). Also fixes a packaging gap the release surfaced: the README told users to copy the template from contrib/, which does not exist for anyone who installed the AUR, .deb or .rpm package. The template is now installed to /usr/share/tailtui/tailtui.toml.tpl and the README documents both paths. Any future user-facing file under contrib/ needs the same treatment or the docs silently break for package users. version_test.go no longer asserts on the real version string, so a release bump does not look like it requires a test edit -- the test covers SetVersion's normalization, not the current version. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * fix(release): ship the Omarchy template in the packages The README now points users at /usr/share/tailtui/tailtui.toml.tpl, but nothing installed it there -- the docs promised a path that did not exist in any artifact. - nfpm installs the template to /usr/share/tailtui/, plus README.md to /usr/share/doc/tailtui/. - The tar.gz carries contrib/tailtui.toml.tpl. Specifying `files` replaces goreleaser's defaults, so LICENSE and README are restated. Verified by building a snapshot release and listing the payloads. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> * chore: ignore goreleaser dist/ output Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
Phase 27 taught the loader to read Omarchy's palette, but left one problem unsolved: some mappings are genuinely undecidable in code.
osaka-jadedefinesyellow = #459451— a green. So mappingyellow→ Warning makes exit-node markers nearly indistinguishable from the online color. Preferringorangeinstead breaksretro-82, where orange is the accent. There is no rule that is right for every theme.The fix is to stop guessing and hand the decision to the person looking at the screen.
What
1. tailTUI's own theme schema. One key per
Themefield —mode,primary,secondary,background,surface,surface_bright,border,text,text_dim,warning,error. Tried ahead of both Omarchy schemas, and probed astailtui.tomlbeforecolors.tomlwithin each theme directory, since it is opt-in and therefore the more deliberate statement.Its keys are deliberately disjoint from the Omarchy vocabularies — only
mode/backgroundare shared, and both are excluded fromhasMarkers()— so three-way detection stays purely a question of which keys appear, never the filename.2.
contrib/tailtui.toml.tpl. Installed into~/.config/omarchy/themed/, Omarchy renders it into the active theme directory on every theme switch. That happens to be the same directory the loader already probes, so no new path was needed. The template is fully commented, including the osaka-jade case and how to fix it.3. Live reload.
styles.ThemeStamp()reports the active file's path and mtime;checkThemeCmdrides the existing refresh tick — no fsnotify, no new dependency. Switch your desktop theme and a running tailTUI re-colors within one tick.The concurrency detail worth reviewing
checkThemeCmdreturns the parsedThemeand never callsstyles.Applyitself.Applyrewrites package-level vars thatViewreads, so applying it inside the command's goroutine would race the renderer. Application happens inUpdate, on the single Elm goroutine.Two related subtleties:
resizeOverlay(). The dashboard re-renders every frame, but overlay content is a pre-rendered string with the old colors baked in as ANSI codes.Compatibility
Zero-config behavior is untouched. With no template installed,
colors.tomlis read and mapped exactly as before — this is purely additive, and the template is optional on every distro.Verification
Beyond the unit tests, I rendered the shipped template through Omarchy's own substitution pipeline against the live
osaka-jadetheme and confirmed the output parses into the expectedTheme, with no unsubstituted placeholders.Note the overlay test forces TrueColor: a TTY-less test strips every SGR, so both renders would compare equal and the assertion would pass vacuously.