fix(web): persist theme preference in settings
This commit is contained in:
@@ -308,8 +308,8 @@ describe('settings domain', () => {
|
||||
// The settings seam is general: any plugin may register a namespace for
|
||||
// its own configuration. The Web configuration plane remains opt-in, so a
|
||||
// future internal plugin cannot become remotely configurable just by
|
||||
// registering; permission and the product onboarding namespace are the
|
||||
// non-model namespaces intentionally admitted by this surface.
|
||||
// registering; permission, theme, and the product onboarding namespace
|
||||
// are the non-model namespaces intentionally admitted by this surface.
|
||||
const ctx = await harness()
|
||||
ctx.settings.register(NS, AdapterConfig)
|
||||
ctx.settings.register(settingsNamespace('some-other-plugin'), z.object({ secretPath: z.string() }))
|
||||
@@ -318,15 +318,23 @@ describe('settings domain', () => {
|
||||
}), {
|
||||
base: { defaultPreset: 'read-only' },
|
||||
})
|
||||
ctx.settings.register(settingsNamespace('ui-theme'), z.object({
|
||||
preference: z.union(['light', 'dark', 'system']).default('system'),
|
||||
}))
|
||||
const api = createApiProxy(ctx, DEFAULTS)
|
||||
|
||||
const value = expectOk(await api.settings.describe(request({})))
|
||||
expect(value.namespaces.map(view => view.ns)).toEqual(['llm-deepseek', 'permission'])
|
||||
expect(value.namespaces.map(view => view.ns)).toEqual(['llm-deepseek', 'permission', 'ui-theme'])
|
||||
const permission = expectOk(await api.settings.mutate(request({
|
||||
ns: 'permission',
|
||||
ops: [{ op: 'set', path: ['defaultPreset'], value: 'workspace-write' }],
|
||||
})))
|
||||
expect(permission.value).toEqual({ defaultPreset: 'workspace-write' })
|
||||
const theme = expectOk(await api.settings.mutate(request({
|
||||
ns: 'ui-theme',
|
||||
ops: [{ op: 'set', path: ['preference'], value: 'dark' }],
|
||||
})))
|
||||
expect(theme.value).toEqual({ preference: 'dark' })
|
||||
|
||||
for (const response of [
|
||||
await api.settings.update(request({ ns: 'some-other-plugin', patch: { secretPath: '/etc/shadow' } })),
|
||||
@@ -340,19 +348,29 @@ describe('settings domain', () => {
|
||||
expect(ctx.settings.describe().find(d => String(d.ns) === 'some-other-plugin')?.value).toEqual({})
|
||||
})
|
||||
|
||||
it('serves the product onboarding namespace without invalidating the model catalog', async () => {
|
||||
it('serves product preference namespaces without invalidating the model catalog', async () => {
|
||||
const ctx = await harness()
|
||||
ctx.settings.register(settingsNamespace('ui-onboarding'), z.object({ welcomeNoticeVersion: z.string() }))
|
||||
ctx.settings.register(settingsNamespace('ui-theme'), z.object({
|
||||
preference: z.union(['light', 'dark', 'system']).default('system'),
|
||||
}))
|
||||
const api = createApiProxy(ctx, DEFAULTS)
|
||||
expect(expectOk(await api.settings.describe(request({}))).namespaces.map(view => view.ns))
|
||||
.toEqual(['ui-onboarding'])
|
||||
const frames = await collectHost(api, ['host/settings-changed'], 1, async () => {
|
||||
.toEqual(['ui-onboarding', 'ui-theme'])
|
||||
const frames = await collectHost(api, ['host/settings-changed'], 2, async () => {
|
||||
expectOk(await api.settings.mutate(request({
|
||||
ns: 'ui-onboarding',
|
||||
ops: [{ op: 'set', path: ['welcomeNoticeVersion'], value: 'v1' }],
|
||||
})))
|
||||
expectOk(await api.settings.mutate(request({
|
||||
ns: 'ui-theme',
|
||||
ops: [{ op: 'set', path: ['preference'], value: 'dark' }],
|
||||
})))
|
||||
})
|
||||
expect(frames).toEqual([{ type: 'host/settings-changed', ns: 'ui-onboarding' }])
|
||||
expect(frames).toEqual([
|
||||
{ type: 'host/settings-changed', ns: 'ui-onboarding' },
|
||||
{ type: 'host/settings-changed', ns: 'ui-theme' },
|
||||
])
|
||||
})
|
||||
|
||||
it('refuses even a model-provider namespace once its directory entry is gone', async () => {
|
||||
|
||||
Reference in New Issue
Block a user