hermes-agent/apps/desktop/electron
brooklyn! 1a3e608524
feat(desktop): per-profile remote gateway hosts (#39778)
* feat(desktop): per-profile remote gateway hosts

Profile switching silently failed whenever the desktop was connected to a
remote backend: the rail routed non-active profiles to a local pool backend,
but spawnPoolBackend hard-threw "Profiles are unavailable when connected to a
remote Hermes backend", and the renderer swallowed the error into an infinite
reconnect backoff while still marking the profile active. Remote was also a
single app-global setting, so there was no way to give a profile its own host.

Add per-profile remote hosts so each profile can point at its own backend:

- connection.json gains a validated `profiles` map; profileRemoteOverride()
  (pure, unit-tested) selects an explicit per-profile remote.
- resolveRemoteBackend(profile) precedence: per-profile override → env override
  → global remote → local spawn. spawnPoolBackend now connects to a profile's
  remote (no local child) instead of throwing; startHermes resolves the primary
  profile's remote.
- coerce/sanitize connection config are scope-aware (global vs named profile)
  and preserve each other's entries; IPC get/save/apply/test thread an optional
  profile. Per-profile apply drops only that profile's pool backend.
- Settings → Gateway adds an "Applies to" scope selector reusing the existing
  URL/token/OAuth/test UX per profile.

Tests: connection-config pure suite (+6) and desktop platform suite pass;
tsc/eslint/vitest clean.

* refactor(desktop): DRY per-profile remote helpers

Share connectionScopeKey + normAuthMode from connection-config.cjs (drop the
main.cjs copy), collapse the scope/auth ternaries, route the env remote through
buildRemoteConnection, and fold the duplicated remote-block validation into
buildRemoteBlock. No behavior change; pure suite + live E2E still green.
2026-06-05 12:14:18 +00:00
..
backend-probes.cjs Add Hermes desktop app (#20059) 2026-05-31 17:46:56 -05:00
backend-probes.test.cjs chore(desktop): zero eslint/typecheck debt + prettier pass (#39100) 2026-06-04 14:10:38 +00:00
bootstrap-platform.cjs chore(desktop): zero eslint/typecheck debt + prettier pass (#39100) 2026-06-04 14:10:38 +00:00
bootstrap-platform.test.cjs chore(desktop): zero eslint/typecheck debt + prettier pass (#39100) 2026-06-04 14:10:38 +00:00
bootstrap-runner.cjs chore(desktop): zero eslint/typecheck debt + prettier pass (#39100) 2026-06-04 14:10:38 +00:00
bootstrap-runner.test.cjs feat(desktop): cancellable first-launch install 2026-06-02 08:50:45 -05:00
connection-config.cjs feat(desktop): per-profile remote gateway hosts (#39778) 2026-06-05 12:14:18 +00:00
connection-config.test.cjs feat(desktop): per-profile remote gateway hosts (#39778) 2026-06-05 12:14:18 +00:00
entitlements.mac.inherit.plist fix(desktop): inherit microphone entitlement for macOS helpers 2026-06-03 07:32:00 +07:00
entitlements.mac.plist Add Hermes desktop app (#20059) 2026-05-31 17:46:56 -05:00
gateway-ws-probe.cjs test(desktop): add injectable gateway WebSocket probe + unit tests 2026-06-04 19:49:06 -07:00
gateway-ws-probe.test.cjs test(desktop): add injectable gateway WebSocket probe + unit tests 2026-06-04 19:49:06 -07:00
hardening.cjs Add Hermes desktop app (#20059) 2026-05-31 17:46:56 -05:00
hardening.test.cjs Add Hermes desktop app (#20059) 2026-05-31 17:46:56 -05:00
main.cjs feat(desktop): per-profile remote gateway hosts (#39778) 2026-06-05 12:14:18 +00:00
preload.cjs feat(desktop): per-profile remote gateway hosts (#39778) 2026-06-05 12:14:18 +00:00