Skip to content

fix(desktop): honor backend skin on first profile use - #74018

Open
vaibhavjnf wants to merge 1 commit into
NousResearch:mainfrom
vaibhavjnf:fix/73987-backend-skin-startup
Open

fix(desktop): honor backend skin on first profile use#74018
vaibhavjnf wants to merge 1 commit into
NousResearch:mainfrom
vaibhavjnf:fix/73987-backend-skin-startup

Conversation

@vaibhavjnf

Copy link
Copy Markdown
Contributor

Summary

  • honor a profile's resolved backend display.skin the first time Desktop sees that profile
  • preserve explicit Desktop appearance choices across reconnects
  • isolate backend theme registries, apply guards, and queued changes by profile
  • route immediate startup and reconnect events to the primary socket's actual owner

Fixes #73987.

This complements #71447: that PR preserves a custom skin after a manual Desktop selection, while this change adopts backend-authored and user skins on first use.

Root cause

Desktop treated every gateway.ready skin as registry-only seed data. It could not distinguish "no Desktop preference exists" from "the user explicitly chose another theme." The sync state was also global, so simultaneous profile gateways could overwrite one another. Finally, primary gateway events captured a profile before the persisted startup profile was adopted.

Fix

  • detect raw persisted Desktop skin ownership before adopting the backend choice
  • cache backend themes and apply baselines per profile
  • queue the latest pending apply per profile, then persist every source profile while painting only the foreground profile
  • adopt the primary profile before opening its WebSocket and keep its event tag independent from the foreground profile
  • reconnect the primary backend by its owner, not the currently viewed secondary profile

Test plan

  • backend sync behavior and per-profile isolation tests
  • ThemeProvider persistence and foreground-paint routing tests
  • real useMessageStream tests for background gateway.ready and skin.changed
  • real useGatewayBoot test for an immediate open-handshake event
  • primary reconnect test while another profile is foreground
  • 42 focused Vitest tests
  • Desktop renderer, Electron, and E2E TypeScript checks
  • focused ESLint, Prettier, and git diff --check

Credit: Vaibhav Sharma (@vaibhavjnf) identified, reproduced, and contributed this fix.

@alt-glitch alt-glitch added type/bug Something isn't working comp/desktop Electron desktop app (apps/desktop/*) area/config Config system, migrations, profiles P3 Low — cosmetic, nice to have sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state labels Jul 29, 2026
@teknium1

Copy link
Copy Markdown
Contributor

Thanks for the focused fix. I verified that current main still has the reported seed-only behavior: gateway.ready calls ingestBackendSkin(..., { apply: false }) at apps/desktop/src/app/session/hooks/use-message-stream/gateway-event.ts:285-293, and that path returns without scheduling an apply in apps/desktop/src/themes/backend-sync.ts:80-92.

The PR's preference-presence check preserves the manual-choice guard discussed on #73987, while its profile-scoped registry, pending queue, and primary-socket ownership changes address concurrent-profile routing. The changed production-file bases still match current main, and GitHub reports the PR as cleanly mergeable with desktop checks and Linux E2E passing at 105890e009b7.

Automated hermes-sweeper review.

@teknium1 teknium1 added sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform area/profiles Multi-profile isolation, HERMES_HOME scoping labels Jul 30, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

area/config Config system, migrations, profiles area/profiles Multi-profile isolation, HERMES_HOME scoping comp/desktop Electron desktop app (apps/desktop/*) P3 Low — cosmetic, nice to have sweeper:blast-moderate Sweeper blast radius: moderate — a subsystem or single platform sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades sweeper:risk-session-state Sweeper risk: may lose/corrupt/mis-associate session or context state type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Desktop startup ignores display.skin for backend-authored/user skins

3 participants