Skip to content

fix(web): point settings panels at a connected device - #5692

Closed
IAmJSD wants to merge 4 commits into
pingdotgg:mainfrom
Infrawrench:fix/settings-env-fallback-no-primary-device
Closed

fix(web): point settings panels at a connected device#5692
IAmJSD wants to merge 4 commits into
pingdotgg:mainfrom
Infrawrench:fix/settings-env-fallback-no-primary-device

Conversation

@IAmJSD

@IAmJSD IAmJSD commented Aug 8, 2026

Copy link
Copy Markdown

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.

  • New apps/web/src/state/settingsEnvironment.tsresolveSettingsEnvironmentId (pure, unit tested) plus the atom and hook wrapping it.
  • New settingsServerConfigAtom / settingsServerSettingsAtom / settingsServerProvidersAtom in state/server.ts, scoped to that environment.
  • usePrimarySettings / useUpdatePrimarySettingsuseGlobalSettings / 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.
  • The three settings components consuming them updated accordingly.

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:

  1. primaryServerProvidersAtom returned EMPTY_SERVER_PROVIDERS, so deriveProviderInstanceEntries produced 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.
  2. useUpdatePrimarySettings resolved to a null environment id, and useUpdateSettingsTarget no-ops on null (hooks/useSettings.ts:326), so every write from these panels was dropped without an error.
  3. Reads fell back to 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

  • This PR is small and focused
  • I explained what changed and why
  • I included before/after screenshots for any UI changes
  • I included a video for animation/interaction changes

🤖 Generated with Claude Code


Note

Medium Risk
Changes which server's settings.json the 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) plus settingsServerSettingsAtom / settingsServerProvidersAtom scoped to that environment. usePrimarySettings / useUpdatePrimarySettings are renamed to useGlobalSettings / useUpdateGlobalSettings and wired through all settings panels, ChatView, and useNewThreadHandler so displayed values, persistence, and new-thread defaults (defaultThreadEnvMode, newWorktreesStartFromOrigin) match the same environment the settings UI writes. Source control discovery uses useSettingsEnvironmentId for 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

  • Introduces settingsEnvironmentIdAtom in settingsEnvironment.ts to select a settings target: the primary environment if available, otherwise the first connected catalog environment.
  • Adds settingsServerConfigAtom, settingsServerSettingsAtom, and settingsServerProvidersAtom in server.ts to expose config, settings, and providers for the chosen environment.
  • Replaces usePrimarySettings/useUpdatePrimarySettings with useGlobalSettings/useUpdateGlobalSettings across all settings panels (appearance, general, source control, fonts, legacy features) so reads and writes target the settings environment.
  • New thread creation and ChatView draft-thread defaults (env mode, start-from-origin) now also read from the settings environment.
  • Behavioral Change: settings panels now mount and operate against the first connected device when no primary device is available; previously they would not function in that state.

Macroscope summarized 24e304f.

@coderabbitai

coderabbitai Bot commented Aug 8, 2026

Copy link
Copy Markdown

Important

Review skipped

Auto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 6ea04340-8bda-4ec2-bfc5-7119f4763b0c

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

Use the checkbox below for a quick retry:

  • 🔍 Trigger review

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@github-actions github-actions Bot added vouch:unvouched PR author is not yet trusted in the VOUCHED list. size:L 100-499 changed lines (additions + deletions). labels Aug 8, 2026
Comment thread apps/web/src/hooks/useSettings.ts
Comment thread apps/web/src/components/settings/SourceControlSettings.tsx
@macroscopeapp

macroscopeapp Bot commented Aug 8, 2026

Copy link
Copy Markdown
Contributor

Approvability

Verdict: 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.

macroscopeapp[bot]
macroscopeapp Bot previously approved these changes Aug 8, 2026
IAmJSD and others added 2 commits August 10, 2026 07:31
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>
@IAmJSD
IAmJSD force-pushed the fix/settings-env-fallback-no-primary-device branch from 646f549 to 7e3dd2b Compare August 10, 2026 06:31
@macroscopeapp
macroscopeapp Bot dismissed their stale review August 10, 2026 06:31

Dismissing prior approval to re-evaluate 7e3dd2b

Comment thread apps/web/src/state/settingsEnvironment.ts Outdated
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>

@cursor cursor Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes using high effort and found 1 potential issue.

Fix All in Cursor

❌ 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.

Comment thread apps/web/src/components/settings/SettingsPanels.tsx
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

t3dotgg commented Aug 27, 2026

Copy link
Copy Markdown
Member

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.

@t3dotgg t3dotgg closed this Aug 27, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

size:L 100-499 changed lines (additions + deletions). vouch:unvouched PR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants