feat(theme-forge): desktop theme editor plugin - #8
Open
criptogus wants to merge 8 commits into
Open
Conversation
Full theme editor for the Hermes Desktop: - 13 presets incl. film-inspired line (Matrix rain, Terminator scanlines, Wolverine, Deadpool, Iron Man, Batman, Dune, Sith) + editable custom - Wallpapers (local file/URL), extended --ui-* palette, 3-level bold, conversation font size, markdown accent colors (headings/links/code) - Live authoring via data-hermes-theme observer + registry re-register - 1-click apply through Hermes' native skin path (dashboard backend writes skins/<name>.yaml + display.skin; gateway broadcasts skin.changed) - MIT, README with install/architecture/limitations
The desktop applies a skin only when the gateway broadcasts skin.changed, which fires on display.skin/YAML mtime changes. After an app update the desktop falls back to its local-storage theme even though config still says forge-*. Fix: on plugin boot, read the configured skin (config.get 'skin') and re-assert it via the backend /reassert endpoint, which re-writes display.skin → gateway watcher re-broadcasts → desktop re-applies. Retries 3x while the gateway comes up.
- New 'Fundo' tab: image or animated video backdrop (URL or local file; objectURL first, best-effort data-URI persistence up to 3.5MB) - Media is a dedicated FX-container layer (<video> or <div>), z-index stack media 0 -> overlay 1 -> rain 2 -> scanlines 3 - Blur applies to the media layer only (body filter blurred the whole UI) - Wallpaper now REPLACES the default chrome: glass surfaces drop to chrome 14% / sidebar 22% / editor 7% / elevated 12% when media is set - Scanlines-only themes get the glass shell too (were invisible behind opaque chrome) - Video pauses on visibilitychange + prefers-reduced-motion; stale blob: URLs from dead sessions are cleaned on load
The backdrop blur set `filter: blur(Npx) scale(...)` — `scale()` only exists on `transform`, so Chromium dropped the entire declaration and the blur never rendered (silent no-op on both the old body paint and the new media layer). Now `filter: blur(Npx)` (valid) + `transform: scale(...)` (edge-reveal compensation) — verified in real Chromium: the red/blue boundary of a test image smears with blur 8px, and overlay+blur stack. Also verified the overlay (z-index 1) darkens the media exactly 50% at opacity 0.5 in real Chromium.
…y wallpaper Two visible regressions after the media-layer refactor: 1. The sidebar mix with a wallpaper (22%) was so transparent that the sidebar and content merged into one continuous image. Restore the classic glass hierarchy: sidebar 60% / chrome 16% / editor 10% / elevated 18% (dark) — wallpaper dominates the content area while the sidebar stays a distinct darker panel. 2. Hot-reload left the pre-refactor plugin's inline body wallpaper behind (the old paintBodyBackdrop was removed without a cleanup). That stale image propagates to the canvas, so overlay/blur acted on the (invisible) media layer while the stale image kept showing. clearBodyLegacy() now strips any inline backdrop styles the plugin may have left on <body> (the app never sets body backgrounds inline — safe). Also adds a TEMP diagState() log (console.error → desktop.log) to confirm the live runtime state after reload; remove before final merge.
A large wallpaper data URI could overflow the localStorage quota and fail the ENTIRE theme save silently — slider tweaks (blur/overlay/colors) rolled back on every reload. The wallpaper now lives in its own storage key (hermes.plugin.theme-forge.forge-custom-img-v1): the theme JSON always saves, and only the image can be lost if IT overflows (with a clear warn). loadCustom() migrates old inline data URIs and prefers the dedicated key.
diagState() served its purpose — it confirmed blur/overlay were applying and the chrome mix was live. Removing before merge (console.error probes are dev-only; desktop.log forwarding is the intended channel during debugging).
…tems) New 'Sidebar (menu lateral)' section in the Cores tab with three reset-to-default color pickers that emit scoped token overrides against the app's stable data-slot hooks: - Nav (New Session, Capabilities, Messaging, Artifacts): overrides --ui-text-secondary inside the nav group via [data-slot=sidebar-group]:has([data-slot=sidebar-menu-button]) — precise, session/project rows never match sidebar-menu-button - Section titles (Pinned, Recents, ...): [data-slot=sidebar-group-label] - Items (sessions + projects): --ui-text-secondary scoped to [data-slot=sidebar-content] (nav group's more specific rule wins for nav) Hover/active states keep working: they use text-foreground, a different token, so only the resting color changes. Pinned rows follow the item color (no stable hook distinguishes them — the pin lives in the row's actions menu). Verified: buildCss emits the exact scoped rules, defaults merge via loadCustom, paint engine unchanged.
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.
What
Adds theme-forge, a complete desktop-plugin + dashboard-backend example: a visual theme editor for the Hermes Desktop that does what the app's theme model can't natively — wallpapers, extended
--ui-*palette, 3-level bold, conversation font size, markdown accent colors, and animated backdrops (matrix rain, CRT scanlines).Highlights
skins/<name>.yaml+ setsdisplay.skin; the gateway watcher broadcastsskin.changedand every surface (CLI/TUI/desktop) repaints — no restart.MutationObserverondata-hermes-theme+ theme registry re-registration repaint the active theme as you edit.plugin.js(no build), FastAPI backend underdashboard/, MIT, full README (install/architecture/limitations).Notes for reviewers
plugin.jsgoes to~/.hermes/desktop-plugins/; onlydashboard/goes to~/.hermes/plugins/. Documented in the README.