summaryrefslogtreecommitdiff
path: root/packages/cli/src/config/settings.ts
diff options
context:
space:
mode:
authorHugoMurillo <[email protected]>2025-08-19 13:07:42 -0600
committerGitHub <[email protected]>2025-08-19 19:07:42 +0000
commitb9cf1ea3ce513717416317fa21b87ce98a107ec6 (patch)
tree3f9c66440430abeaa4743ceac748c51fae53a3f3 /packages/cli/src/config/settings.ts
parentb24c5887c45edde8690b4d73d8961e63eee13a34 (diff)
fix(#5605): .env file loaded after settings are parsed (#6494)
Diffstat (limited to 'packages/cli/src/config/settings.ts')
-rw-r--r--packages/cli/src/config/settings.ts107
1 files changed, 61 insertions, 46 deletions
diff --git a/packages/cli/src/config/settings.ts b/packages/cli/src/config/settings.ts
index 524eb16c..414caf11 100644
--- a/packages/cli/src/config/settings.ts
+++ b/packages/cli/src/config/settings.ts
@@ -70,6 +70,43 @@ export interface SettingsFile {
settings: Settings;
path: string;
}
+
+function mergeSettings(
+ system: Settings,
+ user: Settings,
+ workspace: Settings,
+): Settings {
+ // folderTrust is not supported at workspace level.
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
+ const { folderTrust, ...workspaceWithoutFolderTrust } = workspace;
+
+ return {
+ ...user,
+ ...workspaceWithoutFolderTrust,
+ ...system,
+ customThemes: {
+ ...(user.customThemes || {}),
+ ...(workspace.customThemes || {}),
+ ...(system.customThemes || {}),
+ },
+ mcpServers: {
+ ...(user.mcpServers || {}),
+ ...(workspace.mcpServers || {}),
+ ...(system.mcpServers || {}),
+ },
+ includeDirectories: [
+ ...(system.includeDirectories || []),
+ ...(user.includeDirectories || []),
+ ...(workspace.includeDirectories || []),
+ ],
+ chatCompression: {
+ ...(system.chatCompression || {}),
+ ...(user.chatCompression || {}),
+ ...(workspace.chatCompression || {}),
+ },
+ };
+}
+
export class LoadedSettings {
constructor(
system: SettingsFile,
@@ -96,39 +133,11 @@ export class LoadedSettings {
}
private computeMergedSettings(): Settings {
- const system = this.system.settings;
- const user = this.user.settings;
- const workspace = this.workspace.settings;
-
- // folderTrust is not supported at workspace level.
- // eslint-disable-next-line @typescript-eslint/no-unused-vars
- const { folderTrust, ...workspaceWithoutFolderTrust } = workspace;
-
- return {
- ...user,
- ...workspaceWithoutFolderTrust,
- ...system,
- customThemes: {
- ...(user.customThemes || {}),
- ...(workspace.customThemes || {}),
- ...(system.customThemes || {}),
- },
- mcpServers: {
- ...(user.mcpServers || {}),
- ...(workspace.mcpServers || {}),
- ...(system.mcpServers || {}),
- },
- includeDirectories: [
- ...(system.includeDirectories || []),
- ...(user.includeDirectories || []),
- ...(workspace.includeDirectories || []),
- ],
- chatCompression: {
- ...(system.chatCompression || {}),
- ...(user.chatCompression || {}),
- ...(workspace.chatCompression || {}),
- },
- };
+ return mergeSettings(
+ this.system.settings,
+ this.user.settings,
+ this.workspace.settings,
+ );
}
forScope(scope: SettingScope): SettingsFile {
@@ -339,10 +348,7 @@ export function loadSettings(workspaceDir: string): LoadedSettings {
try {
if (fs.existsSync(systemSettingsPath)) {
const systemContent = fs.readFileSync(systemSettingsPath, 'utf-8');
- const parsedSystemSettings = JSON.parse(
- stripJsonComments(systemContent),
- ) as Settings;
- systemSettings = resolveEnvVarsInObject(parsedSystemSettings);
+ systemSettings = JSON.parse(stripJsonComments(systemContent)) as Settings;
}
} catch (error: unknown) {
settingsErrors.push({
@@ -355,10 +361,7 @@ export function loadSettings(workspaceDir: string): LoadedSettings {
try {
if (fs.existsSync(USER_SETTINGS_PATH)) {
const userContent = fs.readFileSync(USER_SETTINGS_PATH, 'utf-8');
- const parsedUserSettings = JSON.parse(
- stripJsonComments(userContent),
- ) as Settings;
- userSettings = resolveEnvVarsInObject(parsedUserSettings);
+ userSettings = JSON.parse(stripJsonComments(userContent)) as Settings;
// Support legacy theme names
if (userSettings.theme && userSettings.theme === 'VS') {
userSettings.theme = DefaultLight.name;
@@ -378,10 +381,9 @@ export function loadSettings(workspaceDir: string): LoadedSettings {
try {
if (fs.existsSync(workspaceSettingsPath)) {
const projectContent = fs.readFileSync(workspaceSettingsPath, 'utf-8');
- const parsedWorkspaceSettings = JSON.parse(
+ workspaceSettings = JSON.parse(
stripJsonComments(projectContent),
) as Settings;
- workspaceSettings = resolveEnvVarsInObject(parsedWorkspaceSettings);
if (workspaceSettings.theme && workspaceSettings.theme === 'VS') {
workspaceSettings.theme = DefaultLight.name;
} else if (
@@ -399,6 +401,22 @@ export function loadSettings(workspaceDir: string): LoadedSettings {
}
}
+ // Create a temporary merged settings object to pass to loadEnvironment.
+ const tempMergedSettings = mergeSettings(
+ systemSettings,
+ userSettings,
+ workspaceSettings,
+ );
+
+ // loadEnviroment depends on settings so we have to create a temp version of
+ // the settings to avoid a cycle
+ loadEnvironment(tempMergedSettings);
+
+ // Now that the environment is loaded, resolve variables in the settings.
+ systemSettings = resolveEnvVarsInObject(systemSettings);
+ userSettings = resolveEnvVarsInObject(userSettings);
+ workspaceSettings = resolveEnvVarsInObject(workspaceSettings);
+
// Create LoadedSettings first
const loadedSettings = new LoadedSettings(
{
@@ -429,9 +447,6 @@ export function loadSettings(workspaceDir: string): LoadedSettings {
delete loadedSettings.merged.chatCompression;
}
- // Load environment with merged settings
- loadEnvironment(loadedSettings.merged);
-
return loadedSettings;
}