mirror of
https://github.com/NanmiCoder/cc-haha
synced 2026-07-18 13:23:33 +08:00
fix: Prevent cached settings writes from resetting desktop preferences
Desktop settings writes update settings.json through SettingsService, while plugin state writes use the shared CLI settings cache. Reset the shared cache after a successful atomic SettingsService write so later plugin updates merge against the fresh file instead of an older in-memory snapshot. Constraint: Desktop general settings and plugin state share ~/.claude/settings.json but use different write paths Rejected: Move plugin writes onto SettingsService | broader API change than needed for this regression Confidence: high Scope-risk: narrow Directive: Keep cache invalidation aligned across all settings.json write paths Tested: bun test src/server/__tests__/settings.test.ts -t "cached CLI settings" Tested: bun test src/server/__tests__/settings.test.ts src/server/__tests__/plugins.test.ts Tested: cd desktop && bun run test -- generalSettings settingsStore pluginsSettings Tested: bun run check:server Tested: git diff --check Not-tested: Full bun run verify still fails on unrelated dirty desktop changed-line coverage and CSS color-mix gate
This commit is contained in:
parent
62980223cf
commit
e292d83282
@ -21,6 +21,11 @@ import {
|
||||
} from '../../utils/secureStorage/macOsKeychainHelpers.js'
|
||||
import type { OpenAIOAuthTokens } from '../../services/openaiAuth/types.js'
|
||||
import { getModelOptions } from '../../utils/model/modelOptions.js'
|
||||
import {
|
||||
getSettingsForSource,
|
||||
updateSettingsForSource,
|
||||
} from '../../utils/settings/settings.js'
|
||||
import { resetSettingsCache } from '../../utils/settings/settingsCache.js'
|
||||
|
||||
// ─── Test helpers ─────────────────────────────────────────────────────────────
|
||||
|
||||
@ -40,6 +45,7 @@ let originalAnthropicDefaultOpusModel: string | undefined
|
||||
|
||||
async function setup() {
|
||||
tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), 'claude-test-'))
|
||||
resetSettingsCache()
|
||||
originalConfigDir = process.env.CLAUDE_CONFIG_DIR
|
||||
originalHome = process.env.HOME
|
||||
originalUserProfile = process.env.USERPROFILE
|
||||
@ -72,6 +78,7 @@ async function teardown() {
|
||||
plainTextStorage.delete()
|
||||
clearKeychainCache()
|
||||
clearOpenAIOAuthTokenCache()
|
||||
resetSettingsCache()
|
||||
|
||||
if (originalConfigDir !== undefined) {
|
||||
process.env.CLAUDE_CONFIG_DIR = originalConfigDir
|
||||
@ -222,6 +229,37 @@ describe('SettingsService', () => {
|
||||
expect(settings.model).toBe('claude-haiku-4-5')
|
||||
})
|
||||
|
||||
it('should not let cached CLI settings overwrite desktop settings updates', async () => {
|
||||
const svc = new SettingsService()
|
||||
await svc.updateUserSettings({
|
||||
enabledPlugins: {
|
||||
'demo@test-market': false,
|
||||
},
|
||||
})
|
||||
|
||||
expect(getSettingsForSource('userSettings')?.enabledPlugins?.['demo@test-market']).toBe(false)
|
||||
|
||||
await svc.updateUserSettings({
|
||||
language: 'chinese',
|
||||
desktopNotificationsEnabled: true,
|
||||
alwaysThinkingEnabled: false,
|
||||
})
|
||||
|
||||
const { error } = updateSettingsForSource('userSettings', {
|
||||
enabledPlugins: {
|
||||
...getSettingsForSource('userSettings')?.enabledPlugins,
|
||||
'demo@test-market': true,
|
||||
},
|
||||
})
|
||||
expect(error).toBeNull()
|
||||
|
||||
const settings = await svc.getUserSettings()
|
||||
expect(settings.language).toBe('chinese')
|
||||
expect(settings.desktopNotificationsEnabled).toBe(true)
|
||||
expect(settings.alwaysThinkingEnabled).toBe(false)
|
||||
expect((settings.enabledPlugins as Record<string, unknown>)['demo@test-market']).toBe(true)
|
||||
})
|
||||
|
||||
it('should read and write project settings', async () => {
|
||||
const projectRoot = path.join(tmpDir, 'myproject')
|
||||
await fs.mkdir(path.join(projectRoot, '.claude'), { recursive: true })
|
||||
|
||||
@ -15,6 +15,7 @@ import * as os from 'os'
|
||||
import { ApiError } from '../middleware/errorHandler.js'
|
||||
import { normalizeJsonObject, readRecoverableJsonFile } from './recoverableJsonFile.js'
|
||||
import { ensurePersistentStorageUpgraded } from './persistentStorageMigrations.js'
|
||||
import { resetSettingsCache } from '../../utils/settings/settingsCache.js'
|
||||
|
||||
const VALID_PERMISSION_MODES = [
|
||||
'default',
|
||||
@ -129,6 +130,7 @@ export class SettingsService {
|
||||
await fs.mkdir(dir, { recursive: true })
|
||||
await fs.writeFile(tmpFile, contents, 'utf-8')
|
||||
await fs.rename(tmpFile, filePath)
|
||||
resetSettingsCache()
|
||||
return
|
||||
} catch (err) {
|
||||
lastError = err
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user