Uh oh!
There was an error while loading. Please reload this page.
fix(web): point settings panels at a connected device - #5692
Conversation
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Repository UI Review profile: CHILL Plan: Pro Plus Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
ApprovabilityVerdict: Needs human review This PR changes runtime behavior for settings resolution: when no primary device exists, settings panels now target a connected catalog device instead of using defaults. While fixing a bug, this fundamentally changes which environment receives settings reads/writes and should be reviewed by someone familiar with the settings architecture. You can customize Macroscope's approvability policy. Learn more. |
The settings panels read and write server settings through the primary
environment, which only resolves via a `PrimaryConnectionTarget`. The
hosted app never has one — every device is paired remotely — so the
panels degraded silently there:
- `primaryServerProvidersAtom` returned no providers, leaving the text
generation model picker with nothing to offer ("No models found"), so
the model backing thread titles, commit messages, change request
content and branch names could not be changed at all.
- `useUpdatePrimarySettings` resolved to a null environment id, and
`useUpdateSettingsTarget` no-ops on null, so every write from these
panels was dropped without an error.
- Reads fell back to `DEFAULT_SERVER_SETTINGS`, presenting the schema
default as if it were the user's configuration.
Resolve the settings target to the primary device when there is one and
the first connected device otherwise. Sessions with a primary device are
unaffected. Rename the hook pair to `useGlobalSettings` /
`useUpdateGlobalSettings`, since the module header documents the
primary-only scoping as deliberate and it no longer holds.
Left alone: the primary-scoped atoms behind the primary-device update
notification, sidebar and command palette, and the diagnostics panel,
whose RPCs target the primary environment.
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>Two consumers were left on the primary environment after the settings panels moved to the resolved settings environment, so on a hosted session with no primary device they disagreed with the panels that write them. - New-thread defaults (`defaultThreadEnvMode`, `newWorktreesStartFromOrigin`) read `primaryServerSettingsAtom` in `useNewThreadHandler` and `ChatView`, so the General controls saved and re-displayed while new drafts kept the schema defaults. Both now read `settingsServerSettingsAtom` — the environment those controls write. - `SourceControlSettingsPanel` still resolved its discovery target and gated `SourceControlWritingSettingsSection` on `usePrimaryEnvironment`, so the writer-model and fetch-interval controls never mounted there. It now uses `useSettingsEnvironmentId`, matching the section's own hooks. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
646f549 to
7e3dd2bCompareDismissing prior approval to re-evaluate 7e3dd2b
Uh oh!
There was an error while loading. Please reload this page.
The no-primary fallback walked every persisted catalog entry, so an offline device ahead of a live one stole the settings target and dropped writes. Filter to connected environments before picking the fallback. Co-authored-by: Cursor <cursoragent@cursor.com>
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit 622c0e3. Configure here.
Uh oh!
There was an error while loading. Please reload this page.
LegacyFeaturesSection and ProjectSettingsPanel still called the removed usePrimarySettings pair after the settings-environment retarget, so those surfaces could not compile or write server-backed legacy/global defaults. Co-authored-by: Cursor <cursoragent@cursor.com>
t3dotgg
commented
Aug 27, 2026
Note 🤖 GPT-5.6 Sol responding on behalf of Theo We're closing this PR as we clean up the T3 Code backlog. Thank you for taking the time to put this together. Closing this implementation because global settings can write to whichever remote environment connects first, without an explicit target choice. The hosted model-picker and dropped-write bugs are valid. #4559 is related explicit-target work, not a shipped replacement. We should preserve these cases while choosing that behavior. If you believe we closed this in error, please reopen the PR and leave a comment explaining what we missed. If GitHub does not let you reopen it, leave a comment here and we'll take another look. |

What Changed
The settings panels resolve their server-settings target to the primary device when there is one, and to the first connected device otherwise.
apps/web/src/state/settingsEnvironment.ts—resolveSettingsEnvironmentId(pure, unit tested) plus the atom and hook wrapping it.settingsServerConfigAtom/settingsServerSettingsAtom/settingsServerProvidersAtominstate/server.ts, scoped to that environment.usePrimarySettings/useUpdatePrimarySettings→useGlobalSettings/useUpdateGlobalSettings, reading and writing that environment. Renamed rather than silently re-pointed, because the module header documents the primary-only scoping as deliberate and that is no longer what the hooks do.Unchanged: the primary-scoped atoms behind the primary-device update notification, sidebar and command palette, and the diagnostics panel, whose RPCs target the primary environment. A session that has a primary device resolves to it exactly as before.
Why
The settings panels read and write server settings through the primary environment, which only resolves via a
PrimaryConnectionTarget(state/primaryEnvironment.ts:7). The hosted app never has one — every device is paired remotely — so the panels degraded silently there, in three compounding ways:primaryServerProvidersAtomreturnedEMPTY_SERVER_PROVIDERS, soderiveProviderInstanceEntriesproduced nothing and the model picker rendered "No models found". The Text generation model and Source control writer model pickers were therefore unusable, and the model backing thread titles, commit messages, change request content and branch names could not be changed at all.useUpdatePrimarySettingsresolved to a null environment id, anduseUpdateSettingsTargetno-ops on null (hooks/useSettings.ts:326), so every write from these panels was dropped without an error.DEFAULT_SERVER_SETTINGS, presenting the schema default (instanceId: "codex"/gpt-5.6-luna,packages/contracts/src/settings.ts:566) as if it were the user's configuration.The user-visible symptom is that generated commit messages, change request titles and bodies, branch names and thread titles are all produced by the hardcoded default model with no way to change it, on a device where that provider may not even be the one in use.
UI Changes
No layout or styling changes. The behavioural difference is that the Text generation model and Source control writer model pickers populate instead of showing an empty "No models found" popup, and edits in these panels now persist. Reproducing the before state requires a hosted session with no primary device.
Checklist
🤖 Generated with Claude Code
Note
Medium Risk
Changes which server's
settings.jsonthe global UI edits when there is no primary (e.g. hosted); multi-remote-device fallback is arbitrary but matches existing provider-panel behavior. Primary-device sessions are unchanged.Overview
Fixes hosted and no-primary sessions where settings panels showed schema defaults, model pickers were empty, and writes were silently dropped because everything keyed off the primary server only.
Introduces
settingsEnvironmentIdAtom(primary when present, otherwise first connected catalog device, skipping offline entries) plussettingsServerSettingsAtom/settingsServerProvidersAtomscoped to that environment.usePrimarySettings/useUpdatePrimarySettingsare renamed touseGlobalSettings/useUpdateGlobalSettingsand wired through all settings panels,ChatView, anduseNewThreadHandlerso displayed values, persistence, and new-thread defaults (defaultThreadEnvMode,newWorktreesStartFromOrigin) match the same environment the settings UI writes. Source control discovery usesuseSettingsEnvironmentIdfor the same reason.Sessions with a primary device behave as before; primary-only atoms for diagnostics and similar surfaces are unchanged.
Reviewed by Cursor Bugbot for commit 24e304f. Bugbot is set up for automated code reviews on this repo. Configure here.
Note
Point settings panels at a connected device when no primary device is present
settingsEnvironmentIdAtomin settingsEnvironment.ts to select a settings target: the primary environment if available, otherwise the first connected catalog environment.settingsServerConfigAtom,settingsServerSettingsAtom, andsettingsServerProvidersAtomin server.ts to expose config, settings, and providers for the chosen environment.usePrimarySettings/useUpdatePrimarySettingswithuseGlobalSettings/useUpdateGlobalSettingsacross all settings panels (appearance, general, source control, fonts, legacy features) so reads and writes target the settings environment.ChatViewdraft-thread defaults (env mode, start-from-origin) now also read from the settings environment.Macroscope summarized 24e304f.