aboutsummaryrefslogtreecommitdiffstats
path: root/AGENTS.md
AgeCommit message (Collapse)AuthorFilesLines
3 daysfeat(grub): render grub-theme-udt's theme.txt and print its root installDanilo M.1-0/+4
theme.txt has no include, so udt-palette substitutes eight roles and the scheme name into the sibling repo's theme.txt.in, conky-style. The accent is the scheme's fixed one; nothing at boot can read the wallpaper. install.sh runs that repo's build as the user and, only when it succeeds, prints the root copy into /boot/grub/themes plus the one-time GRUB_THEME and grub-mkconfig steps. External targets are now skipped whenever their template is missing, not only when the repo is, so a sibling mid-setup cannot break an install. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
3 daysfeat(install): track rofi scripts, wire nvim and hypr-theme, merge qt/gtk keysDanilo M.1-1/+24
The rofi menus' launch scripts lived loose in ~/bin, so the themes were tracked and the only things that open them were not. They now live in bin/ and are symlinked under the names hypr-theme's keybindings call. neovim gets a generated colorscheme: catppuccin/nvim with all 26 palette colours overridden from the active scheme, selected by rewriting only the colorscheme line of init.vim. hypr-theme is linked as the whole of ~/.config/hypr, leaving a real directory there alone. The qt-gtk templates were reference copies nothing installed. They now hold theme keys only and ini_merge writes them into the live qt5ct, qt6ct and gtk3 files key by key, keeping every other line; tests/ini-merge.sh checks it. The stale kvantum.kvconfig template is gone, install.sh writes that file. Fresh-machine fixes: settings.ini and ~/.config/gtk-4.0 are created when missing instead of aborting under set -e, and conky is found as a sibling checkout and skipped when absent, in udt-palette as well as install.sh. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
6 daysfeat(palette): emit peach, mauve and termblue for quickshellDanilo M.1-1/+5
palette.rasi is what udt-accent forwards to quickshell as udt-palette.qml, and the keybind reminder there draws the macropad's orange, purple and blue keycaps. peach and mauve come from the peach and highlight roles every scheme defines; mauve used to be added only to waybar's compat list, which now reads it from ROFI_NAMES instead of defining it twice. The existing "blue" name carries the active-border role, magenta under candy-night, so the terminal's blue goes out as termblue. The first spelling, term_blue, made rofi reject palette.rasi and with it every theme; AGENTS.md now says so next to the selftest. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
9 daysfix: theme KDE Frameworks apps off PlasmaDanilo M.1-1/+8
kcalc rendered white under the dark Kvantum theme. Off Plasma, KStyleManager forces Breeze unless kdeglobals names a widgetStyle, and KColorSchemeManager applies BreezeLight unless kdeglobals names a colour scheme; qt6ct never forwards the portal's prefer-dark to Qt. Generate a udt.colors KColorScheme from the Kvantum roles, install it to ~/.local/share/color-schemes/, and point kdeglobals at it and at kvantum-dark. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
9 daysfeat: stage the wallpaper on homepage and notify on completionDanilo M.1-6/+10
bin/udt-homepage replaces install.sh's inline scp. It stages custom.css and the current wallpaper, keeping the wallpaper's own extension, then raises a desktop notification with the root commands that install both and point settings.yaml at the new background. Plain root commands, not sudo: the login user on that host has no sudo rights. udt-accent starts it detached on every run, so it follows a wallpaper change (wallp) as well as a scheme switch (install.sh) without holding either up when the host is unreachable. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
12 daysfeat: add the candy-night schemeDanilo M.1-4/+4
A tenth scheme, sampled from a desktop shot built on the Candy icon set (https://github.com/EliverLara/candy-icons) over a near-black purple ground. Its hue ramp is deliberately that icon set's folder gradients, so the palette names the same colours the icons are drawn in. The colours are measured from solid regions of the source image rather than taken from a published scheme, which is why the palette names are this file's own. The window body in that image is translucent over the wallpaper and so contributes no value; that is opacity, not a colour. One split is load-bearing: [ui] accent is the true magenta #cc0dbf from the image, while [terminal] magenta is #f00fe0, the same hue lifted to lightness 0.50. Against the scheme's background the original scores 3.79 contrast, under the 4.5 wanted for body text. The accent only ever fills large areas, where it reads fine; terminal magenta is glyphs on a dark ground, where it does not. Every other terminal colour already clears 4.5 (lowest: red at 5.42); ANSI black stays low as it does in every other scheme, since it is never body text. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
13 daysfeat: theme hyprlock from the UDT palette and accentDanilo M.1-12/+15
udt-palette renders the scheme-level palette to templates/hyprlock/hyprlock-palette.conf ($panel, $input_bg, $text, $subtext, $fail); udt-accent writes the wallpaper accent gradient to ~/.cache/udt/hyprlock-border.conf as a hyprlang variable. The hyprlock config sources both, so a scheme switch recolours the lock and a wallpaper change recolours its border. install.sh copies the palette and seeds the border from the committed fallback on a fresh cache. Both selftests cover the new outputs.
2026-09-16docs(gtk): record GTK as a generated consumerDanilo M.1-2/+15
AGENTS.md listed GTK3/GTK4 among the covered consumers, but nothing generated or installed a theme for it: the claim had been aspirational since the repo started. It now describes what the code does, and says plainly that the old state was a gap rather than a drift. templates/qt-gtk/ documented both Qt and GTK as installed from upstream. Qt still derives from catppuccin/Kvantum and GTK from catppuccin/gtk, but both are generated here now, so the table and the gsettings line say 'udt'. Its tracked gtk3-settings.ini carried the old theme name too, which made the record disagree with the live config it mirrors. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16refactor(cache): move the generated files to ~/.cache/udtDanilo M.1-6/+16
They lived in ~/.cache/wal because pywal owned that directory and udt-accent was written alongside a pywal run. Nothing on this desktop invokes pywal any more: the wal binary is unused, and udt-accent imports pywal.backends.colorz as a quantisation library, which writes nothing. Sharing the cache only left the ownership ambiguous. colors.json is the one file that cannot move. pywalfox hardcodes <cache>/wal/colors.json and honours only XDG_CACHE_HOME, which would relocate every cache on the system, so udt-accent writes the real file to ~/.cache/udt and install.sh symlinks the old path at it. ~/.cache/wal now holds that link and nothing else. Consumers repointed here: install.sh, udt-accent, launcher.rasi's @WPAPER@. Outside the repo, wallp, Hyprland's look_and_feel.lua and quickshell's shared/Theme.qml move with it. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-16refactor(dunst): drop dunst as a consumer, quickshell presents nowDanilo M.1-11/+11
dunst no longer runs on this desktop. notifyd owns org.freedesktop.Notifications and the quickshell notifications shell draws the balloons, reading the palette from ~/.cache/wal/udt-palette.qml like every other quickshell component. So the whole dunst path was generating a config nothing read. It was also actively wrong. pywal rendered ~/.cache/wal/dunstrc from the installed template, then wal.sh restarted dunst on it while @ACCENT@ was still an unsubstituted placeholder, and udt-accent restarted it a second time after substituting. Two restarts per wallpaper change, the first on a broken config, for a daemon that could not claim the bus name anyway. Removes gen_dunst and its TARGETS entry, write_dunst and DUNSTRC, the install block, templates/dunstrc.in and the gitignore entry. The reload table now lists quickshell, which needs no signal: it watches the generated palette and re-reads it in place. The [state] roles stay. They were never dunst-only; waybar module states and conky warnings use the same four. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15fix(waybar): drop the per-module colours, and aim at the bar that runsDanilo M.1-4/+7
The bar these roles existed for is gone. The stock one alternated module backgrounds so it read as stripes, and carried a role for each: workspaces, temperature, memory, cpu, time, date, tray, volume, backlight, battery, plus charging. waybar-theme-udt draws every pill on main_bg, and its stylesheets reference seven names in total, none of them a module. So all eleven had no consumer left in any of the nine schemes. They are deleted rather than renamed. Renaming them after the new bar's modules would have invented consumers that do not exist: nothing reads a "mail" or "launcher" colour, because the pills are deliberately uniform. Re-adding one means a stylesheet that actually references it. install.sh was still writing the theme into ~/.config/waybar/, which hyprland no longer launches, so switching scheme recoloured a bar nobody sees while the running one kept its old palette. It writes to ~/.config/waybar-udt/ now, under the fixed name that bar imports, so there is no import to repoint. The stock directory is left exactly as it was, and deliberately gets no new theme: its stylesheets still ask for the per-module names, so writing one there would leave it referencing colours that no longer exist. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-15feat(palette): add Sublime Text as a consumerDanilo M.1-6/+35
Two outputs, not one. The colour scheme themes the editor pane and tracks the wallpaper accent; the theme themes the UI chrome and sits on the scheme's fixed accent, because Sublime reads a theme once per window and a moving accent would leave open windows disagreeing with new ones. The colour scheme costs no new roles. Its scopes map onto the sixteen ANSI slots every scheme already declares, so all nine satisfy it and the identical-role-set selftest passes untouched. The theme is an override layered over Material Behave rather than a theme of its own: that theme hardcodes 419 rules of [r,g,b] literals with no variables, so the chrome surfaces are restated and its geometry, icons and animations are inherited. It installs under the name of the theme it overrides, because Sublime merges .sublime-theme files by filename with Packages/User last; under its own name it would never apply. It also has to follow Material Behave's material_theme_contrast_mode block and carry no settings gate, or contrast mode wins. The accent is replaced by matching the variable's current value rather than a placeholder: install.sh copies the file out of the repo, so after the first wallpaper change there is no placeholder left to substitute. udt-accent --selftest now covers that it stays idempotent. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-09-11feat(palette): add Obsidian and Typora as consumersDanilo M.1-0/+12
Both expose a first-class, update-safe theming hook, which is what separates them from the Electron apps that cannot be consumers: Signal, Discord and Spotify ship closed bundles whose only theming route is patching a signed asar that every update reverts. Obsidian gets a CSS snippet rather than a theme, so it layers over whatever theme a vault already uses instead of replacing the user's choice. Enabling it means appending to enabledCssSnippets in each vault's appearance.json, which bin/udt-appthemes does by reading the list and adding to it: rewriting the file would have switched off the layout snippet one vault was already using. Typora's theme is derived from the Dracula theme installed here, whose 350 rules all resolve through :root variables, so only that block is templated and none of the layout is touched. Verified across six vaults, nested ones included: the vault with an existing snippet kept it, a vault with no appearance.json got a valid one, and three consecutive installs leave exactly one udt entry. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
2026-09-11feat(palette): generate the Kvantum theme so Qt apps follow the schemeDanilo M.1-2/+14
Qt and GTK were the one part of the desktop the palette never reached: Kvantum was pinned to a hand-installed catppuccin-macchiato-lavender directory, so pcmanfm-qt and every other Qt app stayed Macchiato no matter which scheme was selected. A Kvantum theme is a .kvconfig of colours and a .svg of widget artwork with colours baked into the paths, which looked like it needed redrawing. It did not: the SVG carries only 27 distinct colours, 12 of them palette colours and the rest neutral greys that are shading, not theme colour. Both files are now templates with the 12 as placeholders, derived from the theme this desktop was already running. Installs to ~/.config/Kvantum/udt/ under one fixed name for every scheme, so a switch needs no change to kvantum.kvconfig and leaves no stale theme behind. Adds accent_dim and accent_bright roles for Kvantum's hover and pressed states. Verified: no placeholders survive generation, the SVG still parses as XML, and pcmanfm-qt picks up the new colours on restart. Qt reads a theme at startup only, so running apps need restarting; AGENTS.md says so. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
2026-09-11feat(palette): add five more schemes, and parse-check them allDanilo M.1-4/+12
Adds Catppuccin Frappe and Mocha, which share Macchiato's colour names so their role maps are the same mapping against different values, and Material Ocean, Palenight and Darker, which bring their own names and their own maps. Nine schemes now, all dark. Material ships one accent per hue and three greys where the roles want five depths, so each Material palette carries four interpolated shades, marked as not upstream, and its bright_* terminal slots name the same colours as the normal ones. The selftest now renders every scheme to a temp directory and has rofi parse every theme, not just check that roles resolve. Resolving was never the property that mattered: the Tokyo Night breakage resolved fine and still emitted a palette the themes could not use. Verified the check fails when a name is removed. Catppuccin Latte is deliberately absent. It is light, and that is not a role remap: homepage is pinned theme: dark and the generated card overrides target its dark-mode class. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
2026-09-11feat(install): reload running apps after generating configsDanilo M.1-0/+3
install.sh wrote every config and reloaded nothing, so a scheme switch looked half-applied: the files were correct but waybar, kitty, conky and dunst kept drawing the old colours until five commands were run by hand. It now signals waybar, kitty and Hyprland, runs udt-accent (which regenerates the accent and restarts dunst), and restarts conky, which has no hot-reload. Each is guarded on the process actually running, so a missing one is skipped rather than started: verified conky stays stopped when it was not up before. rofi needs nothing, it reads its theme per launch. Qt and GTK apps still need a manual restart and the README says so. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
2026-09-11feat(palette): generate the homepage stylesheet and stage it on installDanilo M.1-1/+10
The dashboard's custom.css was written by hand against Macchiato, so it would have drifted the moment the desktop changed scheme. It is now generated from the same roles as everything else and staged on the host by install.sh. Adds four intermediate grey roles to every scheme. homepage wants a full ten-step ramp where the other consumers want three depths, and without them several steps collapsed onto the same colour, flattening the mid-tones. The scp is deliberately soft: five second timeout, BatchMode, a warning rather than a failure when the host is unreachable, so a laptop away from that network still installs the local theme. It stages to ~/hp-stage only, because /opt/homepage/config is root-owned; install.sh prints the sudo copy to finish. Verified: the generated Macchiato stylesheet reproduces the deployed one colour-for-colour, switching to tokyo-night propagates through to the staged file, and a failing scp leaves install.sh exiting 0. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
2026-09-11feat(palette): move the scheme selection out of the repoDanilo M.1-5/+11
The selector was tracked at palette/roles.conf, which made switching scheme a committable change: the previous commit carried `scheme = tokyo-night` in its diff purely because that was the theme running at the time. Which theme a machine runs is local state, not a property of the project, so the live file is now ~/.config/udt/roles.conf. install.sh seeds it from palette/roles.conf.default on a first run and never overwrites it, so a switch leaves the working tree clean and two machines sharing this repo can run different schemes. udt-palette falls back to the seed when no live file exists, so a bare checkout still generates. This is the one exception to the repo holding the canonical copy of everything, and AGENTS.md says so. Verified: seeding on a missing file, the seed not overwriting an existing choice, generation from the seed alone, and both selftests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
2026-09-11feat(palette): generate every themed config from one schemeDanilo M.1-1/+32
Colours were written down five times: rofi's palette.rasi, the waybar theme, the kitty theme, the conky and dunst templates, and a MACCHIATO dict inside udt-accent. Changing scheme meant finding all five, and they had already drifted: the active waybar theme was Macchiato while theme.css next to it was Mocha, and nothing imported the latter. Now a scheme is two files. palette/<scheme>.conf holds the colours under the scheme's own names, and palette/roles-<scheme>.conf says what each is for. palette/roles.conf is one `scheme =` line selecting the pair. bin/udt-palette renders that into each consumer's syntax and install.sh runs it first. The role map is per-scheme rather than shared because the palettes are genuinely different shapes: Nord has no `base`, Dracula no `surface0`, and forcing Catppuccin's names onto them would have meant either renaming their colours or inventing values. A role names a palette colour with two optional modifiers, `name/75` for alpha and `name*50` for brightness. The second exists because GTK's shade() has no palette name to point at. Ships macchiato, tokyo-night, nord and dracula. --selftest resolves every role in every scheme and asserts they define the same set, so a scheme that cannot satisfy a consumer fails at install rather than when someone switches to it. Verified against the live configs: all 46 waybar colours resolve identically to the previously active theme including its alpha() and shade() derivations, the kitty theme is colour-for-colour identical, and the rofi palette has the same 26 values. Generated files are gitignored; switching scheme and switching back reproduces the originals. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
2026-09-11feat(accent): generate a QML palette for quickshellDanilo M.1-3/+10
udt-accent now writes ~/.cache/wal/udt-palette.qml alongside the accent, border and colors.json it already produced. Quickshell components read it and watch it, so editing the palette here recolours a running shell without restarting it. Unlike the other outputs this one is not only the accent: it carries the structural colours too. Those are parsed out of rofi/udt/palette.rasi rather than restated in the script, so that file stays the single place the Macchiato values are written down. Hardcoding them a second time here is exactly the drift this is meant to remove: the quickshell components each had their own copy before this. The atomic write that write_border already did by hand is now a helper, write_atomic, used by both. Every generated file is watched by something, and a torn read shows up as a theme that briefly loses its colours. colors.json is untouched by this change, verified by running the script before and after and comparing. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G7NRsGyF9jGfPYS4zPqpN7
2026-09-11feat: theme Firefox from the accent via pywalfoxDanilo M.1-9/+20
udt-accent now rewrites ~/.cache/wal/colors.json as a fixed Catppuccin Macchiato palette with the wallpaper's accent in the cursor and the two highlight slots, then runs `pywalfox update`. colors.json is the only file pywalfox reads, so this is the only way Firefox can follow the accent. Overwriting it wholesale costs nothing: wallp already rewrote it moments earlier via `wal --theme`, and nothing else consumes it. kitty reads its own current-theme.conf, so the terminal palette is unaffected. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015gbjA2bmswN8jyPDKzrvqe
2026-09-11docs: add AGENTS.md with the project's non-obvious constraintsDanilo M.1-0/+111
Records what cost real time to discover: that rofi's -dump-theme normalises values and cannot tell you what renders, that measuring screenshot pixels beats reasoning about the box model, that GTK3's theme comes from gsettings rather than settings.ini on Wayland, that ClearlyU shadows Private Use Area glyphs in fontconfig fallback, and why accent extraction must not go through wal -i. CLAUDE.md is a thin pointer at it, matching the user's global convention. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01G6aeE37K4GHBsaM51yLTTq