Skip to content

feat(ui): add theme presets config for workspace-defined color schemes#84

Open
advancedresearcharray wants to merge 16 commits into
mainfrom
feat/issue-352-theme-presets-config-delivery
Open

feat(ui): add theme presets config for workspace-defined color schemes#84
advancedresearcharray wants to merge 16 commits into
mainfrom
feat/issue-352-theme-presets-config-delivery

Conversation

@advancedresearcharray

@advancedresearcharray advancedresearcharray commented Jul 3, 2026

Copy link
Copy Markdown
Owner

Summary

  • Add [ui.theme] config with presets_dir (default .kiwi/themes/) and optional allowed_presets allow-list
  • Load workspace theme preset JSON via GET /api/kiwi/theme/presets with per-file validation errors
  • Merge workspace presets with built-ins in the UI theme selector; filter by allowed_presets from /api/kiwi/ui-config
  • Harden async preset loading: load gate before clearing CSS vars, cancel stale fetches on space change, apply allow-list before API returns and on failure
  • Fix space-switch races: refetch preferences per space, prefer space-local preset storage, cancel in-flight getTheme

Closes kiwifs#352

Test plan

  • go test ./internal/themepresets/...
  • go test ./internal/config/... -run TestUIConfigThemePresets
  • go test ./internal/api/... -run 'ThemePreset|UIConfig_Theme'
  • cd ui && npm test -- --run src/themes/index.test.ts src/lib/uiConfigStore.test.ts
  • Manual: add .kiwi/themes/corporate-light.json, confirm preset appears in header selector
  • Manual: set allowed_presets in config.toml, confirm only listed presets shown
  • Manual: add invalid JSON preset file, confirm validation error tooltip
  • Manual: switch spaces with different presets, confirm correct preset per space

Array Fleet and others added 16 commits July 3, 2026 17:57
Allow workspaces to define theme preset JSON under [ui.theme] presets_dir
and optionally restrict the selector via allowed_presets. Adds API loading,
UI merge/filter with allow-list fallback, preset selectors in the header and
Theme Editor, and config template documentation.

Closes kiwifs#352
Use uiConfigStore for allowedPresets to avoid redundant fetches, stop
refetching presets on every selection change, sync server prefs when
auto-resolving disallowed presets, and surface validation errors in the
header. Add API path-traversal regression test.

Co-authored-by: Cursor <cursoragent@cursor.com>
Fixes CI TypeScript build after theme.allowedPresets mock support.

Co-authored-by: Cursor <cursoragent@cursor.com>
When GET /theme/presets errors, fall back to built-ins but still honor
allowed_presets from ui-config. Adds filterPresetsWithAllowList helper and
regression test for the fallback path.

Co-authored-by: Cursor <cursoragent@cursor.com>
Avoid stripping CSS variables when localStorage holds a workspace preset
name before GET /theme/presets returns. Sync auto-resolved presets to
the server via PUT /theme. Add shouldRemovePresetTheme regression test.

Closes kiwifs#352

Co-authored-by: Cursor <cursoragent@cursor.com>
Ignore in-flight GET /theme/presets responses after the user switches
spaces so a slow prior response cannot overwrite the active preset list.

Co-authored-by: Cursor <cursoragent@cursor.com>
…fs#352)

Initialize and refresh availablePresets with filterPresetsWithAllowList so
the selector respects allowed_presets immediately. DemoShell awaits
ui-config load before mounting App in demo mode.

Signed-off-by: Array Fleet <fleet@advancedresearcharray.local>
Co-authored-by: Cursor <cursoragent@cursor.com>
Co-authored-by: Cursor <cursoragent@cursor.com>
Re-ran regression tests (Go + UI) — all green. Fix mergePresets doc
comment to match built-in-wins behavior. Add episodic delivery log.

Closes kiwifs#352

Signed-off-by: Array Fleet <fleet@advancedresearcharray.local>
Co-authored-by: Cursor <cursoragent@cursor.com>
Signed-off-by: Array Fleet <fleet@advancedresearcharray.local>
Co-authored-by: Cursor <cursoragent@cursor.com>
Resolve server prefs and space switches through resolveActivePresetName
instead of raw preset assignment, block disallowed getTheme token fallback,
surface presets API failures in presetErrors, and preserve workspace-only
allow-list names until /theme/presets returns.

Closes kiwifs#352

Signed-off-by: Array Fleet <fleet@advancedresearcharray.local>
Co-authored-by: Cursor <cursoragent@cursor.com>
Refetch preferences when the active space changes, prefer space-local
preset storage over stale server prefs, cancel in-flight getTheme on
space switch, and reject setPreset names outside the filtered list.

Closes kiwifs#352

Signed-off-by: Array Fleet <fleet@advancedresearcharray.local>
Co-authored-by: Cursor <cursoragent@cursor.com>
…-07-03)

Record hands-on verification of workspace theme presets config against
acceptance criteria; all Go and UI regression tests pass on delivery branch.

Co-authored-by: Cursor <cursoragent@cursor.com>
Apply peer-review fixes: stop preserving workspace-only allow-list names
after presets finish loading, fall back to built-ins when the filtered list
is empty, and pass theme state into KiwiThemeEditor instead of a second
useTheme() instance.

Co-authored-by: Cursor <cursoragent@cursor.com>
Confirm theme presets implementation passes Go and UI tests after
peer-review fixes; log delivery verification for fleet takeover.

Co-authored-by: Cursor <cursoragent@cursor.com>
Record green test run and PR delivery after fleet takeover.
Closes kiwifs#352 verification path.

Co-authored-by: Cursor <cursoragent@cursor.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

feat(ui): add theme presets config for workspace-defined color schemes

1 participant