fix(settings): prevent ~/.claude/ localSettings from overriding userSettings
When CWD is the home directory, projectSettings and localSettings resolve to files inside ~/.claude/ (e.g. settings.local.json). These are not legitimate project-level files — they are user config files that should not take priority over explicit userSettings. Added a guard in loadSettingsFromDisk() that skips projectSettings and localSettings when their resolved path is under the user's claude config home directory. Fixes: CCP --settings flag and default settings loading not working when ~/.claude/settings.local.json contains model overrides.
This commit is contained in:
parent
18f5f99e7d
commit
95f0c99584
|
|
@ -274,25 +274,31 @@ function getUserSettingsFilePath(): string {
|
||||||
export function getSettingsFilePathForSource(
|
export function getSettingsFilePathForSource(
|
||||||
source: SettingSource,
|
source: SettingSource,
|
||||||
): string | undefined {
|
): string | undefined {
|
||||||
|
let result: string | undefined
|
||||||
switch (source) {
|
switch (source) {
|
||||||
case 'userSettings':
|
case 'userSettings':
|
||||||
return join(
|
result = join(
|
||||||
getSettingsRootPathForSource(source),
|
getSettingsRootPathForSource(source),
|
||||||
getUserSettingsFilePath(),
|
getUserSettingsFilePath(),
|
||||||
)
|
)
|
||||||
|
break
|
||||||
case 'projectSettings':
|
case 'projectSettings':
|
||||||
case 'localSettings': {
|
case 'localSettings': {
|
||||||
return join(
|
result = join(
|
||||||
getSettingsRootPathForSource(source),
|
getSettingsRootPathForSource(source),
|
||||||
getRelativeSettingsFilePathForSource(source),
|
getRelativeSettingsFilePathForSource(source),
|
||||||
)
|
)
|
||||||
|
break
|
||||||
}
|
}
|
||||||
case 'policySettings':
|
case 'policySettings':
|
||||||
return getManagedSettingsFilePath()
|
result = getManagedSettingsFilePath()
|
||||||
|
break
|
||||||
case 'flagSettings': {
|
case 'flagSettings': {
|
||||||
return getFlagSettingsPath()
|
result = getFlagSettingsPath()
|
||||||
|
break
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
export function getRelativeSettingsFilePathForSource(
|
export function getRelativeSettingsFilePathForSource(
|
||||||
|
|
@ -746,6 +752,21 @@ function loadSettingsFromDisk(): SettingsWithErrors {
|
||||||
if (!seenFiles.has(resolvedPath)) {
|
if (!seenFiles.has(resolvedPath)) {
|
||||||
seenFiles.add(resolvedPath)
|
seenFiles.add(resolvedPath)
|
||||||
|
|
||||||
|
// Skip project and local settings when they resolve to the user's
|
||||||
|
// claude config directory (~/.claude/). These are not legitimately
|
||||||
|
// separate project-level files — the CWD just happens to be the same
|
||||||
|
// directory as the claude config home. Loading them would let a
|
||||||
|
// local override (e.g. settings.local.json) silently clobber the
|
||||||
|
// user's explicit global settings values.
|
||||||
|
if (
|
||||||
|
(source === 'projectSettings' || source === 'localSettings') &&
|
||||||
|
resolvedPath.startsWith(
|
||||||
|
resolve(getSettingsRootPathForSource('userSettings')),
|
||||||
|
)
|
||||||
|
) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
|
||||||
const { settings, errors } = parseSettingsFile(filePath)
|
const { settings, errors } = parseSettingsFile(filePath)
|
||||||
|
|
||||||
// Add unique errors (deduplication)
|
// Add unique errors (deduplication)
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user