Skip to content

fix(desktop): persist backend-sourced skins so they survive restarts - #82483

Open
Shura0307 wants to merge 1 commit into
NousResearch:mainfrom
Shura0307:fix/backend-skin-persistence
Open

fix(desktop): persist backend-sourced skins so they survive restarts#82483
Shura0307 wants to merge 1 commit into
NousResearch:mainfrom
Shura0307:fix/backend-skin-persistence

Conversation

@Shura0307

Copy link
Copy Markdown

Problem

A backend-sourced skin (e.g. one set via display.skin, like sisyphus) does not survive a desktop restart. The picked skin shows while connected, but every launch comes back as the default.

Root cause is a gateway-timing dependency: the desktop's boot-time paint runs before the gateway connects and registers backend themes, so the persisted skin name cannot be resolved on the first frame — normalizeSkin falls back to DEFAULT_SKIN_NAME. The connect-time seed (ingestBackendSkin with apply: false) deliberately never repaints, so the default sticks for the whole session.

This affects the whole class of backend-sourced skins (ares, daylight, warm-lightmode, poseidon, sisyphus, charizard — anything in skin_engine.py but not in the desktop's BUILTIN_THEMES), not just one name. Built-in desktop skins are unaffected because they resolve locally on the first frame.

Fix

Two changes in apps/desktop/src/themes/backend-sync.ts:

  1. Seed recovery — on connect, if the pushed skin name matches the user's persisted choice, repaint it. This finishes the user's pick instead of stomping it (the guard for manual switches is untouched: a persisted name differing from the backend skin still never repaints).

  2. User-theme persistence — backend skins are converted via skinToDesktopTheme and installed as user themes (localStorage), so the next boot's first paint resolves them synchronously, exactly like a built-in. No timing dependency, and the connecting screen paints the right skin from frame one.

Tests

backend-sync.test.ts grows from 11 to 16 cases: seed recovery when the persisted skin equals the backend skin, per-profile persisted backend skins, no-apply when they differ, user-theme persistence to localStorage, and no rewrite when the persisted theme is unchanged.

Boot paint runs before the gateway connects and registers backend themes,
so a backend-sourced skin (e.g. one set via display.skin, like sisyphus)
could not be resolved on the first frame: normalizeSkin fell back to the
default, and the connect-time seed deliberately never repainted. The user's
picked skin name was stored, but every launch came back as the default.

Two fixes in backend-sync.ts:
- The connect-time seed now checks whether the pushed skin name matches the
  user's persisted choice and repaints it (finishing the pick, not stomping
  a manual switch).
- Backend skins are converted and persisted as user themes in localStorage,
  so the NEXT boot's first paint resolves them synchronously like a built-in
  — no gateway-timing dependency, and no default flash on the connecting
  screen.

Adds tests for seed recovery, per-profile persisted backend skins, and
user-theme persistence.
@alt-glitch alt-glitch added type/bug Something isn't working comp/desktop Electron desktop app (apps/desktop/*) area/config Config system, migrations, profiles sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades P3 Low — cosmetic, nice to have needs-decision Awaiting maintainer decision before any implementation labels Aug 9, 2026
@alt-glitch

Copy link
Copy Markdown
Collaborator

This was generated by AI during triage.

Related to #71447 and #76648: this addresses the same backend-skin restart symptom through persisted converted user themes, a distinct mechanism for maintainers to compare.

lancecheney pushed a commit to lancecheney/hermes-agent that referenced this pull request Aug 9, 2026
The `_micro_compact` docstring cited "NousResearch#82483" for the resume double-load
problem. No such issue exists — the repository's highest number is 74323,
so the reference was invented rather than looked up.

The reasoning it was attached to is correct and stays: the session flush is
append-only, so an in-memory splice alone leaves the original rows active
and a resume loads both the summary and the messages it replaced. Only the
citation was wrong.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
randlee pushed a commit to randlee/hermes-agent that referenced this pull request Aug 11, 2026
The `_micro_compact` docstring cited "NousResearch#82483" for the resume double-load
problem. No such issue exists — the repository's highest number is 74323,
so the reference was invented rather than looked up.

The reasoning it was attached to is correct and stays: the session flush is
append-only, so an in-memory splice alone leaves the original rows active
and a resume loads both the summary and the messages it replaced. Only the
citation was wrong.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
33hodl pushed a commit to 33hodl/hermes-agent that referenced this pull request Aug 12, 2026
The `_micro_compact` docstring cited "NousResearch#82483" for the resume double-load
problem. No such issue exists — the repository's highest number is 74323,
so the reference was invented rather than looked up.

The reasoning it was attached to is correct and stays: the session flush is
append-only, so an in-memory splice alone leaves the original rows active
and a resume loads both the summary and the messages it replaced. Only the
citation was wrong.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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 comp/desktop Electron desktop app (apps/desktop/*) needs-decision Awaiting maintainer decision before any implementation P3 Low — cosmetic, nice to have sweeper:risk-compatibility Sweeper risk: may break existing users, config, migrations, defaults, or upgrades type/bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants