fix(desktop): settings pages state loudly when they edit a non-default profile's config

After any Bot Mode chat the active gateway profile is the bot's, so the
settings scope silently followed it — edits landed in
profiles/<bot>/config.yaml with only a faint chip tint as the tell
(#89190/#89162/#89597 report class, live-repro'd: Max Agent Steps written
to scout's config). The applies-to note now renders for ANY non-default
target, override or not, accented; default-profile editing stays quiet.
This commit is contained in:
Teknium
2026-08-19 20:47:34 -07:00
parent 8b9df066e2
commit b047b5db4c
2 changed files with 56 additions and 2 deletions

View File

@@ -65,4 +65,45 @@ describe('SettingsProfileScope', () => {
fireEvent.click(screen.getByRole('button', { name: 'default' }))
expect($settingsScopeOverride.get()).toBeNull()
})
// #89190/#89162 class: after opening a Bot Mode chat, the ACTIVE profile is
// the bot's — so with no override the settings pages silently edit the bot's
// config. The target must be stated (accented) whenever it isn't the default
// profile, override or not.
it('states the edit target when the active profile is a non-default bot (no override)', () => {
$activeGatewayProfile.set('scout')
$profiles.set([profile('default', true), profile('scout')])
const { container } = render(<SettingsProfileScope />)
expect($settingsScopeOverride.get()).toBeNull()
expect(container.textContent).toContain('scout')
// The note paragraph is present and accented (font-medium marks the loud variant).
const note = container.querySelector('p')
expect(note).toBeTruthy()
expect(note?.className).toContain('font-medium')
})
it('shows no note when following the active DEFAULT profile', () => {
$activeGatewayProfile.set('default')
$profiles.set([profile('default', true), profile('coder')])
const { container } = render(<SettingsProfileScope />)
expect(container.querySelector('p')).toBeNull()
})
it('keeps the quiet note style for an explicit override onto the default profile', () => {
$activeGatewayProfile.set('scout')
$profiles.set([profile('default', true), profile('scout')])
render(<SettingsProfileScope />)
fireEvent.click(screen.getByRole('button', { name: 'default' }))
expect($settingsScopeOverride.get()).toBe('default')
const note = document.querySelector('p')
expect(note).toBeTruthy()
expect(note?.className).not.toContain('font-medium')
})
})

View File

@@ -51,6 +51,8 @@ export function SettingsProfileScope({ className }: { className?: string }) {
}
const selected = normalizeProfileKey(override ?? active)
const defaultProfile = profiles.find(profile => profile.is_default)
const editingNonDefault = defaultProfile ? selected !== normalizeProfileKey(defaultProfile.name) : false
return (
<div className={cn('grid gap-2', className)}>
@@ -67,8 +69,19 @@ export function SettingsProfileScope({ className }: { className?: string }) {
/>
))}
</div>
{override !== null ? (
<p className="text-[length:var(--conversation-caption-font-size)] leading-(--conversation-caption-line-height) text-(--ui-text-tertiary)">
{/* The scope follows the app's ACTIVE profile when no override is set —
which, after opening any Bot Mode chat, is the BOT's profile. Users
reasonably assume Settings edit their main config, so an edit landing
in profiles/<bot>/config.yaml with only a faint chip tint as the tell
is a silent misdirect (the #89190/#89162 report class). Always state
the target when it isn't the default profile, and make it loud. */}
{override !== null || editingNonDefault ? (
<p
className={cn(
'text-[length:var(--conversation-caption-font-size)] leading-(--conversation-caption-line-height)',
editingNonDefault ? 'font-medium text-(--ui-accent)' : 'text-(--ui-text-tertiary)'
)}
>
{scope.editsProfile(selected)}
</p>
) : null}