mirror of
https://github.com/backnotprop/plannotator.git
synced 2026-09-14 14:17:26 +08:00
feat/opencode2-native-commands
8 Commits
| Author | SHA1 | Message | Date | |
|---|---|---|---|---|
|
|
2d65c65596 |
feat(ui): pair a light theme and a dark theme, switched by mode (#1217)
* feat(ui): pair a light theme and a dark theme, switched by mode
ThemeProvider stored one palette plus a mode, so picking a dark-only
palette pinned the mode and greyed out the Light/System buttons. Store a
pair instead: { mode, light, dark }, resolved as pair[preferredMode], so
System flips between the two choices as the OS scheme changes.
The Settings Theme tab now assigns one half at a time. A Light/Dark
switch decides which half the grid is filling, the grid lists only the
palettes that can render that half (from the registry's modeSupport), and
a summary line names both halves with each side clickable. Every mode
button is permanently enabled: a dark-only palette simply never occupies
the light slot, so no mode coercion is left to do.
The pair round-trips through the SETTINGS registry to the `theme` key in
~/.plannotator/config.json the way diffOptions does. A user upgrading
seeds both halves from their stored single palette, and the legacy
plannotator-color-theme key keeps tracking the active palette so a
downgrade never lands on an unstyled first frame.
Addresses part 1 of #1211.
* fix(ui): make the theme pair seed local, and keep the legacy API non-destructive
Review of #1217 found a data-loss path and three published-API regressions.
Seeding: ThemeProvider handed its resolved pair to the config store through
set(), which queues a debounced POST. configStore.init() applies the server
config but never cancelled that queued write, so a single cookie-less visit
(fresh profile, incognito, cleared cookies) flushed a default pair to
~/.plannotator/config.json AFTER the real one had arrived, and the next
session restored those defaults over the user's cookies. The provider now
uses a new configStore.seed(): memory plus cookie, never the server, and
never over a value init() already applied. init() additionally retracts
queued writes for the leaves the server just spoke for, which closes the
same race for every server-synced setting rather than this one key.
Deprecated APIs: isThemeModeAvailable() and normalizeThemeMode() are back as
one-line wrappers with @deprecated notes, since packages/ui exports utils/*.
setColorTheme: assigns exactly one half and nothing else. A both-mode palette
goes to the half on screen instead of clobbering both; a mode-restricted one
goes to its half without yanking a System user to an explicit mode (render
time already resolves that). It persists through configStore.setLocal(), so
it stays cookie-only as it was before the pair, unless a host installed its
own serverSync transport.
storageKey / colorThemeStorageKey are honored on the read path, so a host's
stored pre-pair preference is migrated rather than discarded. The two halves
have no pre-pair equivalent and stay on fixed keys, documented on the props.
Tests: a fresh-mount case that pins zero POSTs (the previous helper pre-seeded
cookies, which is why this was invisible), a case that pins a real choice
still reaching config.json, direct setColorTheme cases for all three
semantics, a host-storage-keys migration case, and configStore seed/retract
unit tests. All of them fail against the code they replace.
|
||
|
|
c4acec988c |
feat(ui): add colorblind theme (#1192)
* feat(ui): add colorblind and tritanopia themes Two new built-in themes tuned for color vision deficiency: - Colorblind: for red-green CVD (protanopia and deuteranopia). Diff additions are blue (#4f83d1 dark / #216cab light) and deletions are orange (#c96e12 dark / #a55c1e light), a pair on the blue-yellow axis that survives red-green dichromacy. - Colorblind Tritanopia: for blue-yellow CVD. Additions are teal (#2b939e dark / #1b7981 light) and deletions are vermilion (#db5f38 dark / #c14f2b light), a pair on the surviving red-green axis. Both pairs were verified computationally with Machado et al. (2009) severity-1.0 CVD simulation matrices: the simulated add/del line backgrounds keep CIEDE2000 >= 8.9 (red-green theme) and >= 18.6 (tritanopia theme) at every diffLineBgIntensity in both dark and light modes, and normal-vision foreground contrast stays >= 4.7:1 over the strongest tint. The +/- gutter signs and indicator bars reuse the same base colors and keep >= 4.2:1 contrast on the page background. The review editor's Pierre diff pipeline picks up the pair via the library's own override seam: the theme files set --diffs-addition-color-override / --diffs-deletion-color-override, which inherit into the diff shadow DOM, so no app code changes were needed for the line backgrounds. Syntax colors in diffs map to the @pierre/theme colorblind shiki themes (already in the dependency tree), and plan-editor highlight.js code blocks get theme-scoped token overrides mirroring the same palettes. * feat(ui): drop the tritanopia theme after adversarial review Independent re-simulation showed the shipped default diff pair (the pierre-dark/pierre-light gitDecoration colors, green #07c480 / red #ff2e3f in dark and #18a46c / #d52c36 in light) beats the teal/vermilion pair under tritanopia simulation, and a matched-pair grid search over green/yellow-green vs red/vermilion candidates confirms why: tritanopia preserves the red-green axis, so the stock green/red palette is already near-optimal for tritanopes. No candidate pair that also keeps 4.5:1 normal-vision text contrast over the strongest line tint can beat the default in all six mode/intensity configurations under both Machado severity-1.0 and Vienot 1999 (the best candidates converge on the default's own vivid green/red and still fall 3 to 6 dE00 short in the worst configuration). Shipping a theme named for tritanopia that at best ties the default would invite false confidence, so it is removed rather than renamed. The Colorblind theme (red-green CVD, the common ~95% of cases) is unaffected and also holds up under tritanopia simulation (Vienot dE00 >= 32.8 in every configuration). |
||
|
|
92c311ab1d |
fix(review): show System theme coherently across UI (#1015)
Use one shared Light/Dark/System registry across review, plan, annotate, Settings, and published UI consumers. Preserve the public Mode contract, scope wider menu geometry to theme pickers, and keep constrained palettes coherent in rendering and previews. Co-authored-by: Vladyslav Hrabovyi <vladyslav.hrabovyii@gmail.com> Co-authored-by: sasha <kredich05@gmail.com> |
||
|
|
c23df4db43 |
UI 2.0 visual refresh + HTML-render annotate (strictly UI, off main) (#863)
Extracts the UI 2.0 visual refresh and the HTML-render annotate feature onto main, standalone (no daemon). Faithful copy of feat's UI/HTML logic with the standalone transport kept. |
||
|
|
308e272b10 |
feat(ui): 49 themes with matched syntax highlighting + preview mode (#664)
* feat(ui): expand theme system to 49 themes with matched syntax highlighting Add 25 new themes sourced from shiki's bundled TextMate themes (Everforest, Nord, Solarized, GitHub, One Dark Pro, Night Owl, Material, Vitesse, Vesper, Poimandres, Ayu Dark, Houston, Laserwave, Andromeeda, Aurora X, Dark+/Light+, Min, One Light, Plastic, Red, Slack, Snazzy Light, Vitesse Black). Each theme was audited against the shiki source JSON to ensure correct color mapping. Wire pierre/diffs syntax highlighting to match the active UI theme via a SHIKI_THEME_MAP (35 of 49 themes get matched syntax token colors in diffs). Add theme preview mode — a compact bottom-docked picker that lets users browse themes while seeing the page update live behind it. Settings panel enhancements: - Syntax highlighting badge on themes with diff color matching - Mode unavailability dimming (dark-only themes dim in light mode) - Plannotator pinned first, rest alphabetical * fix(themes): address review feedback — contrast, stale CSS, syntax mode safety 1. Material light: foreground #90A4AE → #546E7A (Blue Grey 600) for readable UI text (~7:1 contrast on white). Primary-foreground #FAFAFA → #263238 for contrast on teal buttons. 2. DiffHunkPreview: add colorTheme to useEffect deps so unsafeCSS (bg/gutter injection) recomputes when themes change, preventing stale mixed-theme state in mounted tooltips during preview mode. 3. SHIKI_THEME_MAP: make mode-aware with null entries for modes lacking a shiki counterpart. resolveSyntaxTheme() returns undefined when the current mode has no match, so pierre falls back to its defaults rather than applying dark token colors on a light background (fixes Tokyo Night light). * fix(review): self-review cleanup — memo, double-call, escape key - DiffHunkPreview: extract resolveSyntaxTheme to a variable instead of calling it twice in the spread expression - PierreDiffContent memo: compare syntaxTheme by dark/light string values instead of reference equality (resolver returns new objects each call) - Preview mode: add Escape key handler to return to full settings * fix(ui): consume Escape event in theme preview to prevent leaking to page |
||
|
|
2b4b556289 |
feat(themes): add Kanagawa Dragon, Wave, and Bones themes (#524)
* feat(themes): add Kanagawa Dragon, Wave, and Bones themes Adds all three Kanagawa variants as dark-only themes, mapped from the official Ghostty color palette to the app's CSS variable schema. For provenance purposes, this commit was AI assisted. * fix(themes): sort Kanagawa themes into alphabetical position For provenance purposes, this commit was AI assisted. * feat(themes): replace Kanagawa Bones with Kanagawa Lotus Bones is a community derivative; Lotus is the official third variant from kanagawa.nvim. Light-only theme with yellow-tan paper background mapped from the canonical lotusWhite/lotusInk palette. For provenance purposes, this commit was AI assisted. * style(themes): standardize border radius to 0.625rem Replaces the previous defaults (0.5rem, 0.75rem, 1rem) with 0.625rem across all themes. Intentionally sharp themes preserved: Doom 64 (0px), Terminal (4px), Solar Dusk (0.3rem). For provenance purposes, this commit was AI assisted. |
||
|
|
46fa92712c |
feat: add Clean Contrast, Code Fork, and Midnight themes (#454)
Three new themes derived from Cursor's color palettes. Code Fork supports both dark and light modes; Clean Contrast and Midnight are dark-only. For provenance purposes, this commit was AI assisted. |
||
|
|
e1bd27aae4 |
feat: custom theme system with 18 built-in themes (#294)
* feat: custom theme system with 15 built-in themes Consolidate CSS theming into a single source of truth (packages/ui/theme.css) and introduce a multi-theme architecture where each theme defines both dark and light mode variants. Users can pick a color palette (theme) and separately toggle dark/light mode within it. - Extract shared color tokens, Tailwind bridge, and base styles into packages/ui/theme.css - Replace hardcoded oklch values with token references (oklch from var syntax) - Fix 3 light-mode bugs in review-editor diff colors - Create 15 built-in themes: Plannotator (default), Claude+, Soft Pop, Adwaita, Caffeine, Cyberdyne, Cyberfunk, Doom 64, Dracula, Gruvbox, PaulMillr, Quantum Rose, Solar Dusk, Terminal, Tinacious - Expand ThemeProvider to manage colorTheme + mode independently - Add Theme tab to Settings with mode toggle, search, and swatch grid - Dark-only themes (Dracula, Terminal, etc.) suppress light class to prevent broken styling; light-only themes (Tinacious) force it - Cookie persistence: plannotator-color-theme for palette, existing key for mode - Include theme conversion script for FinSitter theme adaptation Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: refine themes, add Catppuccin/Rosé Pine/Monokai Pro/Synthwave 84/Tokyo Night Theme curation: - Replace Cyberdyne with Synthwave '84 (from robb0wen/synthwave-vscode) - Replace Cyberfunk with Catppuccin (Mocha dark + Latte light), Rosé Pine (dark + Dawn light), Monokai Pro (dark only), Tokyo Night (Storm + Day) - Rewrite Gruvbox from canonical source (morhetz/gruvbox) - Rewrite Adwaita from canonical VS Code theme (piousdeer/vscode-adwaita) - Rewrite PaulMillr from Ghostty canonical palette Theme fixes: - Fix faded Send Feedback button on Solar Dusk, Quantum Rose, Caffeine (accent colors were too dark/invisible at 15% opacity) - Fix Dracula/Terminal/PaulMillr/Tinacious light mode breakage — dark-only themes now suppress .light class via modeSupport in ThemeProvider - Fix code block backgrounds — use --code-bg token instead of --muted - Add faint green grid overlay for Terminal theme - Alphabetize theme registry (Plannotator first) Code review diff theming: - Pass theme colors into @pierre/diffs shadow DOM via unsafeCSS prop - Dynamic themeType based on resolved mode 18 built-in themes: Plannotator, Absolutely, Adwaita, Caffeine, Catppuccin, Doom 64, Dracula, Gruvbox, Monokai Pro, PaulMillr, Quantum Rose, Rosé Pine, Soft Pop, Solar Dusk, Synthwave '84, Terminal, Tinacious, Tokyo Night Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: increase settings modal height for theme grid visibility Remove 340px cap on theme grid, bump content area from 70vh to 85vh so all themes are visible without scrolling. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * refactor: memoize ThemeProvider context, deduplicate Mode type, clean up DiffViewer From /simplify review: - Export Mode type from ThemeProvider, import in ThemeTab (was duplicated) - Add resolvedMode to context — consumers no longer re-query matchMedia - Memoize context value with useMemo, setters with useCallback (prevents unnecessary re-renders of all useTheme consumers) - Consolidate DiffViewer's two pierre state vars into single object - Use resolvedMode from context in DiffViewer instead of classList check - Format crammed single-line extended tokens in 4 theme CSS files Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * fix: prevent FOUC, fix system mode stale read, restore marketing theme class P1: Marketing site inline script now sets theme-{name} class on <html> before first paint (reads plannotator-color-theme cookie). Without this, CSS tokens under .theme-* selectors were never active. P2: System mode effect now re-reads matchMedia.matches immediately when entering system mode, not just on future changes. Fixes stale resolvedMode when OS preference changed while pinned to explicit dark/light. P3: ThemeProvider applies theme class synchronously during render (not in a passive useEffect) to prevent flash of unstyled content on hard refresh. Also extracted resolveThemeClasses to module scope to avoid useCallback. Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> * feat: add Quick Copy button, fix import icon, comment out agent badge - Add Quick Copy button to annotation panel footer (splits horizontally with existing Quick Share). Copies annotations wrapped with the deny preamble so output is paste-ready for agent sessions. - Export Modal annotations copy also wraps with deny preamble - Extract wrapFeedbackForAgent() utility in parser.ts as single source of truth for the preamble text - Fix desktop import icon to match mobile (arrow-into-document, not download) - Comment out code review agent badge — unreliable across multiple harnesses Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com> --------- Co-authored-by: Claude Opus 4.6 (1M context) <noreply@anthropic.com> |