hermes-agent/apps
David Metcalfe 0831e5e326 fix(desktop): preserve collapsed-provider set across profile switches
The collapsed-providers atom (`hermes.desktop.collapsed-providers`) is a
global presentation-layer preference, but the catalog the picker renders is
profile-scoped (`getGlobalModelOptions` routes through `profileScoped()`,
model-menu-panel.tsx:87-93). The previous code called `pruneStaleCollapsed`
on every render against `pickerProviders`, which silently deleted any
slug not present in the active catalog.

Bug class (review from @teknium1):
- Profile switch to a catalog that lacks a previously-collapsed provider
  → that collapse preference is permanently lost.
- Refresh Models that drops a provider (revoked key, plugin disabled,
  backend policy change) → same loss.
- Any transient empty catalog (loading → []) → guarded by `length > 0`,
  but still loses state once the new (smaller) catalog resolves.

Fix:
- Remove the prune `useEffect` from model-menu-panel.tsx.
- Delete `pruneStaleCollapsed` (no other caller; the AGENTS.md "no
  speculative infrastructure" rule applies — keeping it exported with a
  plausible-sounding docstring is a foot-gun for future contributors who
  would re-call it against a single active catalog and reintroduce the bug).
- Document on the atom why we deliberately don't prune: provider slugs
  come from a bounded configured set (not user input); the render loop
  only visits providers in the active `groups`; dead slugs have no
  observable effect (`collapsedProviders.includes(slug)` against an
  absent slug is a no-op).

Tests:
- `preserves the collapsed set across a profile switch whose catalog
  lacks the slug` — regression pin for the profile-switch case.
- `preserves the collapsed set when Refresh Models drops a provider` —
  regression pin for the refresh-models case.

Verified: `tsc -p . --noEmit` is clean on the changed files. CI is the
source of truth for the vitest run (the local React-detection env
failure pre-dates this PR; CI passes).

Closes the review thread on #64690.
2026-07-20 00:41:11 -07:00
..
bootstrap-installer fix(bootstrap): download timeouts + BOM upgrade for pre-fix cached scripts (#67193 follow-up) 2026-07-19 14:08:48 +05:30
desktop fix(desktop): preserve collapsed-provider set across profile switches 2026-07-20 00:41:11 -07:00
shared fmt(js): npm run fix on merge (#66983) 2026-07-18 15:12:47 +00:00