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

@IAmJSDIAmJSD 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

coderabbitaiBot 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-actionsgithub-actionsBot 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 threadapps/web/src/hooks/useSettings.ts
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
@macroscopeapp

macroscopeappBot 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]
macroscopeappBot previously approved these changes Aug 8, 2026
IAmJSDand 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
IAmJSDforce-pushed the fix/settings-env-fallback-no-primary-device branch from 646f549 to 7e3dd2bCompareAugust 10, 2026 06:31
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 10, 2026 06:31

Dismissing prior approval to re-evaluate 7e3dd2b

Comment threadapps/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>

@cursorcursorBot 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 threadapps/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

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.

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

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@IAmJSD@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Add copy buttons to all
 blocks\n(function() {\n function addCopyButtons() {\n document.querySelectorAll('pre code').forEach(function(codeBlock) {\n if (codeBlock.parentElement.hasAttribute('data-copy-added')) return;\n codeBlock.parentElement.setAttribute('data-copy-added', 'true');\n \n var btn = document.createElement('button');\n btn.textContent = 'Copy';\n btn.style.cssText = 'position:absolute;top:4px;right:4px;padding:2px 8px;font-size:11px;background:#4ecdc4;border:none;border-radius:4px;color:#1a1a2e;cursor:pointer;opacity:0.7;transition:opacity 0.2s;';\n btn.onmouseover = function() { this.style.opacity = '1'; };\n btn.onmouseout = function() { this.style.opacity = '0.7'; };\n btn.onclick = function() {\n navigator.clipboard.writeText(codeBlock.textContent).then(function() {\n btn.textContent = 'Copied!';\n setTimeout(function() { btn.textContent = 'Copy'; }, 1500);\n });\n };\n codeBlock.parentElement.style.position = 'relative';\n codeBlock.parentElement.appendChild(btn);\n });\n }\n \n addCopyButtons();\n \n // Re-run on dynamic content\n var observer = new MutationObserver(addCopyButtons);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Add Copy Buttons to Code Blocks");
}
} catch(__e) { console.warn('[Userscript:Add Copy Buttons to Code Blocks]', __e); }
})();
(function(){
try {
var __m = "github.com";
var __re = new RegExp('^' + "github\\.com" + '
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

@IAmJSDIAmJSD 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

coderabbitaiBot 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-actionsgithub-actionsBot 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 threadapps/web/src/hooks/useSettings.ts
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
@macroscopeapp

macroscopeappBot 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]
macroscopeappBot previously approved these changes Aug 8, 2026
IAmJSDand 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
IAmJSDforce-pushed the fix/settings-env-fallback-no-primary-device branch from 646f549 to 7e3dd2bCompareAugust 10, 2026 06:31
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 10, 2026 06:31

Dismissing prior approval to re-evaluate 7e3dd2b

Comment threadapps/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>

@cursorcursorBot 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 threadapps/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

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.

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

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@IAmJSD@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Force GitHub README to respect dark mode\n(function() {\n var style = document.createElement('style');\n style.textContent = '\n .markdown-body {\n color-scheme: dark light;\n }\n .markdown-body pre { background: #161b22 !important; }\n .markdown-body code { background: rgba(110, 118, 129, 0.4) !important; }\n .markdown-body table th, .markdown-body table td { border-color: #30363d !important; }\n .markdown-body img { background: #0d1117; }\n .markdown-body blockquote { border-left-color: #8b949e; }\n .markdown-body hr { border-color: #30363d; }\n ';\n document.head.appendChild(style);\n})();", "GitHub Dark Mode README Fix"); } } catch(__e) { console.warn('[Userscript:GitHub Dark Mode README Fix]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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

@IAmJSDIAmJSD 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

coderabbitaiBot 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-actionsgithub-actionsBot 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 threadapps/web/src/hooks/useSettings.ts
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
@macroscopeapp

macroscopeappBot 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]
macroscopeappBot previously approved these changes Aug 8, 2026
IAmJSDand 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
IAmJSDforce-pushed the fix/settings-env-fallback-no-primary-device branch from 646f549 to 7e3dd2bCompareAugust 10, 2026 06:31
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 10, 2026 06:31

Dismissing prior approval to re-evaluate 7e3dd2b

Comment threadapps/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>

@cursorcursorBot 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 threadapps/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

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.

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

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@IAmJSD@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Highlight search terms from Google/DuckDuckGo/Bing referrer\n(function() {\n var ref = document.referrer;\n var terms = [];\n \n if (ref.includes('google.com') || ref.includes('duckduckgo.com') || ref.includes('bing.com')) {\n var url = new URL(ref);\n var q = url.searchParams.get('q') || url.searchParams.get('p');\n if (q) {\n terms = q.split(/\\s+/).filter(function(t) { return t.length > 2; });\n }\n }\n \n if (terms.length === 0) return;\n \n var style = document.createElement('style');\n style.textContent = '.userscript-highlight { background: #fbbf24; color: #1a1a2e; padding: 1px 3px; border-radius: 2px; }';\n document.head.appendChild(style);\n \n function highlight(node) {\n if (node.nodeType === 3) { // text node\n var text = node.textContent;\n var found = false;\n terms.forEach(function(term) {\n var regex = new RegExp('(' + term.replace(/[.*+?^${}()|[\\]\\\\]/g, '\\\\') + ')', 'gi');\n if (regex.test(text)) {\n found = true;\n var frag = document.createDocumentFragment();\n var parts = text.split(regex);\n parts.forEach(function(part, i) {\n if (i % 2 === 0) {\n frag.appendChild(document.createTextNode(part));\n } else {\n var span = document.createElement('span');\n span.className = 'userscript-highlight';\n span.textContent = part;\n frag.appendChild(span);\n }\n });\n node.parentNode.replaceChild(frag, node);\n }\n });\n } else if (node.nodeType === 1 && node.childNodes) { // element\n var skipTags = ['SCRIPT', 'STYLE', 'NOSCRIPT', 'TEXTAREA', 'INPUT', 'SELECT'];\n if (!skipTags.includes(node.tagName)) {\n Array.from(node.childNodes).forEach(highlight);\n }\n }\n }\n \n highlight(document.body);\n \n // Re-highlight on dynamic content\n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1 || node.nodeType === 3) highlight(node);\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Highlight Search Terms"); } } catch(__e) { console.warn('[Userscript:Highlight Search Terms]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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

@IAmJSDIAmJSD 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

coderabbitaiBot 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-actionsgithub-actionsBot 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 threadapps/web/src/hooks/useSettings.ts
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
@macroscopeapp

macroscopeappBot 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]
macroscopeappBot previously approved these changes Aug 8, 2026
IAmJSDand 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
IAmJSDforce-pushed the fix/settings-env-fallback-no-primary-device branch from 646f549 to 7e3dd2bCompareAugust 10, 2026 06:31
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 10, 2026 06:31

Dismissing prior approval to re-evaluate 7e3dd2b

Comment threadapps/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>

@cursorcursorBot 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 threadapps/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

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.

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

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@IAmJSD@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Strip utm_, fbclid, gclid, etc. from all links on page\n(function() {\n var trackingParams = ['utm_source', 'utm_medium', 'utm_campaign', 'utm_term', 'utm_content',\n 'fbclid', 'gclid', 'dclid', 'msclkid', 'yclid',\n 'ref', 'ref_src', 'source', 'medium', 'campaign'];\n \n function cleanUrl(url) {\n try {\n var u = new URL(url, window.location.origin);\n var changed = false;\n trackingParams.forEach(function(p) {\n if (u.searchParams.has(p)) {\n u.searchParams.delete(p);\n changed = true;\n }\n });\n return changed ? u.toString() : url;\n } catch (e) {\n return url;\n }\n }\n \n function cleanLinks() {\n document.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n \n cleanLinks();\n \n var observer = new MutationObserver(function(mutations) {\n mutations.forEach(function(m) {\n m.addedNodes.forEach(function(node) {\n if (node.nodeType === 1) {\n if (node.tagName === 'A') cleanLinks();\n node.querySelectorAll('a[href]').forEach(function(a) {\n var clean = cleanUrl(a.href);\n if (clean !== a.href) a.href = clean;\n });\n }\n });\n });\n });\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "Remove Tracking Parameters from Links"); } } catch(__e) { console.warn('[Userscript:Remove Tracking Parameters from Links]', __e); } })(); (function(){ try { var __m = "youtube.com"; var __re = new RegExp('^' + "youtube\\.com" + '
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

@IAmJSDIAmJSD 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

coderabbitaiBot 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-actionsgithub-actionsBot 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 threadapps/web/src/hooks/useSettings.ts
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
@macroscopeapp

macroscopeappBot 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]
macroscopeappBot previously approved these changes Aug 8, 2026
IAmJSDand 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
IAmJSDforce-pushed the fix/settings-env-fallback-no-primary-device branch from 646f549 to 7e3dd2bCompareAugust 10, 2026 06:31
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 10, 2026 06:31

Dismissing prior approval to re-evaluate 7e3dd2b

Comment threadapps/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>

@cursorcursorBot 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 threadapps/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

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.

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

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@IAmJSD@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Auto-enable theater mode on YouTube\n(function() {\n function tryTheater() {\n var btn = document.querySelector('button[aria-label=\"Theater mode\"], ytd-player #player button[title=\"Theater mode\"]');\n if (btn && !btn.classList.contains('activated')) {\n btn.click();\n }\n }\n \n // Try immediately\n tryTheater();\n \n // Try after navigation (SPA)\n var lastUrl = location.href;\n setInterval(function() {\n if (location.href !== lastUrl) {\n lastUrl = location.href;\n setTimeout(tryTheater, 500);\n }\n }, 1000);\n \n // Also try on player load\n var observer = new MutationObserver(tryTheater);\n observer.observe(document.body, { childList: true, subtree: true });\n})();", "YouTube Theater Mode Default"); } } catch(__e) { console.warn('[Userscript:YouTube Theater Mode Default]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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

@IAmJSDIAmJSD 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

coderabbitaiBot 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-actionsgithub-actionsBot 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 threadapps/web/src/hooks/useSettings.ts
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
@macroscopeapp

macroscopeappBot 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]
macroscopeappBot previously approved these changes Aug 8, 2026
IAmJSDand 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
IAmJSDforce-pushed the fix/settings-env-fallback-no-primary-device branch from 646f549 to 7e3dd2bCompareAugust 10, 2026 06:31
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 10, 2026 06:31

Dismissing prior approval to re-evaluate 7e3dd2b

Comment threadapps/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>

@cursorcursorBot 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 threadapps/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

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.

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

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@IAmJSD@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Remove or un-stick sticky/fixed headers that block content\n(function() {\n function unstick() {\n document.querySelectorAll('header, nav, [role=\"banner\"], .header, .navbar, .sticky, .fixed-top, [style*=\"position: fixed\"], [style*=\"position:sticky\"]').forEach(function(el) {\n if (el.style.position === 'fixed' || el.style.position === 'sticky' || \n getComputedStyle(el).position === 'fixed' || getComputedStyle(el).position === 'sticky') {\n el.style.position = 'static';\n el.style.top = 'auto';\n el.style.zIndex = 'auto';\n }\n });\n }\n \n unstick();\n \n var observer = new MutationObserver(unstick);\n observer.observe(document.body, { childList: true, subtree: true, attributes: true, attributeFilter: ['style', 'class'] });\n})();", "Kill Sticky Headers"); } } catch(__e) { console.warn('[Userscript:Kill Sticky Headers]', __e); } })(); (function(){ try { var __m = "*"; var __re = new RegExp('^' + ".*" + '
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

@IAmJSDIAmJSD 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

coderabbitaiBot 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-actionsgithub-actionsBot 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 threadapps/web/src/hooks/useSettings.ts
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
@macroscopeapp

macroscopeappBot 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]
macroscopeappBot previously approved these changes Aug 8, 2026
IAmJSDand 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
IAmJSDforce-pushed the fix/settings-env-fallback-no-primary-device branch from 646f549 to 7e3dd2bCompareAugust 10, 2026 06:31
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 10, 2026 06:31

Dismissing prior approval to re-evaluate 7e3dd2b

Comment threadapps/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>

@cursorcursorBot 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 threadapps/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

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.

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

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@IAmJSD@t3dotgg
, 'i'); if (__m === '*' || __re.test(location.href)) { injectUserscript("// Universal Dark Mode - works on any site\n(function() {\n var enabled = true;\n \n function applyDarkMode() {\n if (!enabled) return;\n \n // Create style element if it doesn't exist\n var style = document.getElementById('universal-dark-mode-style');\n if (!style) {\n style = document.createElement('style');\n style.id = 'universal-dark-mode-style';\n document.head.appendChild(style);\n }\n \n // Dark mode CSS - inverts colors but preserves images/video\n style.textContent = '\n /* Invert everything except media */\n html {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #1a1a2e !important;\n }\n \n /* Restore images, videos, iframes, canvas */\n img, video, iframe, canvas, svg, picture, [style*=\"background-image\"] {\n filter: invert(1) hue-rotate(180deg) !important;\n }\n \n /* Preserve specific elements that should not be inverted */\n .no-dark-mode, .no-dark-mode *,\n [data-theme=\"light\"], [data-theme=\"light\"],\n .ace_editor, .ace_editor *,\n .CodeMirror, .CodeMirror *,\n .monaco-editor, .monaco-editor *,\n .markdown-body pre, .markdown-body pre *,\n .highlight, .highlight *,\n pre code, pre code * {\n filter: none !important;\n }\n \n /* Fix common UI elements */\n .modal, .popup, .dropdown-menu, .tooltip, .popover {\n filter: invert(1) hue-rotate(180deg) !important;\n background: #2d2d44 !important;\n border-color: #444 !important;\n }\n \n /* Scrollbars */\n ::-webkit-scrollbar { background: #1a1a2e !important; }\n ::-webkit-scrollbar-thumb { background: #444 !important; }\n ::-webkit-scrollbar-thumb:hover { background: #555 !important; }\n \n /* Selection */\n ::selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ::-moz-selection { background: #4ecdc4 !important; color: #1a1a2e !important; }\n ';\n }\n \n function removeDarkMode() {\n var style = document.getElementById('universal-dark-mode-style');\n if (style) style.remove();\n }\n \n // Toggle with Alt+Shift+D\n document.addEventListener('keydown', function(e) {\n if (e.altKey && e.shiftKey && e.key === 'D') {\n e.preventDefault();\n enabled = !enabled;\n if (enabled) {\n applyDarkMode();\n console.log('[Universal Dark Mode] Enabled');\n } else {\n removeDarkMode();\n console.log('[Universal Dark Mode] Disabled');\n }\n }\n });\n \n // Apply on load\n applyDarkMode();\n \n // Re-apply on dynamic content\n var observer = new MutationObserver(function(mutations) {\n if (enabled && !document.getElementById('universal-dark-mode-style')) {\n applyDarkMode();\n }\n });\n observer.observe(document.head, { childList: true });\n \n console.log('[Universal Dark Mode] Loaded - Press Alt+Shift+D to toggle');\n})();", "Universal Dark Mode"); } } catch(__e) { console.warn('[Userscript:Universal Dark Mode]', __e); } })(); })();
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

@IAmJSDIAmJSD 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

coderabbitaiBot 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-actionsgithub-actionsBot 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 threadapps/web/src/hooks/useSettings.ts
Comment threadapps/web/src/components/settings/SourceControlSettings.tsx
@macroscopeapp

macroscopeappBot 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]
macroscopeappBot previously approved these changes Aug 8, 2026
IAmJSDand 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
IAmJSDforce-pushed the fix/settings-env-fallback-no-primary-device branch from 646f549 to 7e3dd2bCompareAugust 10, 2026 06:31
@macroscopeapp
macroscopeappBot dismissed their stale reviewAugust 10, 2026 06:31

Dismissing prior approval to re-evaluate 7e3dd2b

Comment threadapps/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>

@cursorcursorBot 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 threadapps/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

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.

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

Labels

size:L100-499 changed lines (additions + deletions).vouch:unvouchedPR author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants

@IAmJSD@t3dotgg