Repository navigation
Complete desktop surfaces; add appearance modes and accent colors - #2
Merged
Merged
Conversation
Lands this worktree's outstanding desktop work together with the new appearance controls, in one commit because the two bodies of work overlap in the same files (index.css, App.tsx, wire.ts, schemas.test.ts, README). Surfaces: Files/Workspace page (tree, read, edit, save, new file, reveal, attachment staging), Memory browser (search, Markdown edit, rename, delete), Skills browser (create/rename/delete), thread search/rename/delete, provider CRUD with model discovery and validation, first-run setup wizard, PIN lock with idle auto-lock, application menu with Lock Now, About/diagnostics card, transcript export, and the renderer->main log bridge. New IPC namespaces (files, memory, skills, providers, threads) behind Zod-validated handlers, plus a shared errors module, an app settings store over sqlite, and per-surface live test scripts. Appearance: System / Light / Dark stays, and Neutral / Blue / Violet / Emerald / Amber / Rose accents repaint `--primary`, `--primary-foreground` and `--ring`, so buttons, the selected sidebar row, the logo tile and focus rings take the hue in both modes. Mode and accent are applied to <html> as `dark` + `data-accent` from one paint path that the OS-scheme listener re-runs, and are persisted as `settings.theme` + `settings.accent`; an unrecognised stored accent reads back as neutral. Every accent holds at least 4.9:1 contrast between its fill and its foreground text in both modes, and that same ratio against its own mode's background for accent text. Verification: - `npm run typecheck` clean. - `npm run test:unit`: 12 files / 142 tests, including the new `theme.test.ts` (mode resolution, accent painting, OS-flip repaint keeping the accent) and accent coverage in `schemas.test.ts`. - `npm run settings:test` green on an isolated HOME: accent round-trips through the sqlite row, survives an unrelated save, and a row edited to nonsense falls back to neutral/system. - `npm run build` green; the built renderer bundle was driven in headless Chromium with a stubbed bridge — all 12 mode x accent combinations match their tokens exactly (nav row background == hsl(--primary), foreground == hsl(--primary-foreground)), and system mode follows a live prefers-color-scheme flip without a settings write.
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 this is
This branch lands the desktop work that was still uncommitted in the worktree (rounds 3–4 of the app spec) together with the new appearance controls. It is one commit because the two bodies of work overlap in the same files (
index.css,App.tsx,wire.ts,schemas.test.ts,README.md), so they cannot be split into commits that each build.Surfaces
workspace/uploads/.⌘L).files,memory,skills,providers,threads) behind Zod-validated handlers, a shared errors module, an app settings store over sqlite, and per-surface live test scripts.Appearance: modes and accent colors
--primary,--primary-foregroundand--ring, so buttons, the selected sidebar row, the logo tile and focus rings take the hue in both modes.theme.ts) onto<html>asdark+data-accent, and are re-applied by theprefers-color-schemelistener so a live OS switch keeps the chosen accent.settings.theme+settings.accent; an unrecognised stored accent reads back asneutral(same fallback shape as an unknown theme reading assystem). The settings schema rejects unknown accents at the IPC edge.variant="link").Test plan
npm run typechecknpm run test:unittheme.test.ts(mode resolution, accent painting, OS-flip repaint keeping the accent) and accent coverage inschemas.test.tsnpm run settings:testHOME: accent round-trips through the sqlite row, survives an unrelated save, and a row hand-edited to nonsense falls back toneutral/systemnpm run build== hsl(--primary), foreground== hsl(--primary-foreground)),systemfollows an emulatedprefers-color-schemeflip with no settings write, and saved payloads carrytheme+accenttogetherNotes for review
window.hermes; it is not committed. Say the word and I will make it a permanentscripts/renderer-ui-test.ts(stub + static server + the CDP assertions).nativeTheme.themeSourceis not wired, so the title bar still follows the OS while the window itself follows the setting. Out of scope here; flagging it since it is the one place mode and OS can visibly disagree.