/**
 * @license
 * Copyright 2025 Google LLC
 * SPDX-License-Identifier: Apache-2.0
 */
import * as fs from 'node:fs';
import * as path from 'node:path';
import { platform } from 'node:os';
import * as dotenv from 'dotenv';
import process from 'node:process';
import { FatalConfigError, GEMINI_DIR, getErrorMessage, Storage, coreEvents, homedir, } from '@google/gemini-cli-core';
import stripJsonComments from 'strip-json-comments';
import { DefaultLight } from '../ui/themes/default-light.js';
import { DefaultDark } from '../ui/themes/default.js';
import { isWorkspaceTrusted } from './trustedFolders.js';
import { getSettingsSchema, } from './settingsSchema.js';
export { getSettingsSchema, };
import { resolveEnvVarsInObject } from '../utils/envVarResolver.js';
import { customDeepMerge } from '../utils/deepMerge.js';
import { updateSettingsFilePreservingFormat } from '../utils/commentJson.js';
import { validateSettings, formatValidationError, } from './settings-validation.js';
export function getMergeStrategyForPath(path) {
    let current = undefined;
    let currentSchema = getSettingsSchema();
    let parent = undefined;
    for (const key of path) {
        if (!currentSchema || !currentSchema[key]) {
            // Key not found in schema - check if parent has additionalProperties
            if (parent?.additionalProperties?.mergeStrategy) {
                return parent.additionalProperties.mergeStrategy;
            }
            return undefined;
        }
        parent = current;
        current = currentSchema[key];
        currentSchema = current.properties;
    }
    return current?.mergeStrategy;
}
export const USER_SETTINGS_PATH = Storage.getGlobalSettingsPath();
export const USER_SETTINGS_DIR = path.dirname(USER_SETTINGS_PATH);
export const DEFAULT_EXCLUDED_ENV_VARS = ['DEBUG', 'DEBUG_MODE'];
const AUTH_ENV_VAR_WHITELIST = [
    'GEMINI_API_KEY',
    'GOOGLE_API_KEY',
    'GOOGLE_CLOUD_PROJECT',
    'GOOGLE_CLOUD_LOCATION',
];
/**
 * Sanitizes an environment variable value to prevent shell injection.
 * Restricts values to a safe character set: alphanumeric, -, _, ., /
 */
export function sanitizeEnvVar(value) {
    return value.replace(/[^a-zA-Z0-9\-_./]/g, '');
}
export function getSystemSettingsPath() {
    if (process.env['GEMINI_CLI_SYSTEM_SETTINGS_PATH']) {
        return process.env['GEMINI_CLI_SYSTEM_SETTINGS_PATH'];
    }
    if (platform() === 'darwin') {
        return '/Library/Application Support/GeminiCli/settings.json';
    }
    else if (platform() === 'win32') {
        return 'C:\\ProgramData\\gemini-cli\\settings.json';
    }
    else {
        return '/etc/gemini-cli/settings.json';
    }
}
export function getSystemDefaultsPath() {
    if (process.env['GEMINI_CLI_SYSTEM_DEFAULTS_PATH']) {
        return process.env['GEMINI_CLI_SYSTEM_DEFAULTS_PATH'];
    }
    return path.join(path.dirname(getSystemSettingsPath()), 'system-defaults.json');
}
export var SettingScope;
(function (SettingScope) {
    SettingScope["User"] = "User";
    SettingScope["Workspace"] = "Workspace";
    SettingScope["System"] = "System";
    SettingScope["SystemDefaults"] = "SystemDefaults";
    // Note that this scope is not supported in the settings dialog at this time,
    // it is only supported for extensions.
    SettingScope["Session"] = "Session";
})(SettingScope || (SettingScope = {}));
/**
 * The actual values of the loadable settings scopes.
 */
const _loadableSettingScopes = [
    SettingScope.User,
    SettingScope.Workspace,
    SettingScope.System,
    SettingScope.SystemDefaults,
];
/**
 * A type guard function that checks if `scope` is a loadable settings scope,
 * and allows promotion to the `LoadableSettingsScope` type based on the result.
 */
export function isLoadableSettingScope(scope) {
    return _loadableSettingScopes.includes(scope);
}
function setNestedProperty(obj, path, value) {
    const keys = path.split('.');
    const lastKey = keys.pop();
    if (!lastKey)
        return;
    let current = obj;
    for (const key of keys) {
        if (current[key] === undefined) {
            current[key] = {};
        }
        const next = current[key];
        if (typeof next === 'object' && next !== null) {
            current = next;
        }
        else {
            // This path is invalid, so we stop.
            return;
        }
    }
    current[lastKey] = value;
}
export function getDefaultsFromSchema(schema = getSettingsSchema()) {
    const defaults = {};
    for (const key in schema) {
        const definition = schema[key];
        if (definition.properties) {
            defaults[key] = getDefaultsFromSchema(definition.properties);
        }
        else if (definition.default !== undefined) {
            defaults[key] = definition.default;
        }
    }
    return defaults;
}
export function mergeSettings(system, systemDefaults, user, workspace, isTrusted) {
    const safeWorkspace = isTrusted ? workspace : {};
    const schemaDefaults = getDefaultsFromSchema();
    // Settings are merged with the following precedence (last one wins for
    // single values):
    // 1. Schema Defaults (Built-in)
    // 2. System Defaults
    // 3. User Settings
    // 4. Workspace Settings
    // 5. System Settings (as overrides)
    return customDeepMerge(getMergeStrategyForPath, schemaDefaults, systemDefaults, user, safeWorkspace, system);
}
/**
 * Creates a fully populated MergedSettings object for testing purposes.
 * It merges the provided overrides with the default settings from the schema.
 *
 * @param overrides Partial settings to override the defaults.
 * @returns A complete MergedSettings object.
 */
export function createTestMergedSettings(overrides = {}) {
    return customDeepMerge(getMergeStrategyForPath, getDefaultsFromSchema(), overrides);
}
export class LoadedSettings {
    constructor(system, systemDefaults, user, workspace, isTrusted, errors = []) {
        this.system = system;
        this.systemDefaults = systemDefaults;
        this.user = user;
        this._workspaceFile = workspace;
        this.isTrusted = isTrusted;
        this.workspace = isTrusted
            ? workspace
            : this.createEmptyWorkspace(workspace);
        this.errors = errors;
        this._merged = this.computeMergedSettings();
    }
    system;
    systemDefaults;
    user;
    workspace;
    isTrusted;
    errors;
    _workspaceFile;
    _merged;
    _remoteAdminSettings;
    get merged() {
        return this._merged;
    }
    setTrusted(isTrusted) {
        if (this.isTrusted === isTrusted) {
            return;
        }
        this.isTrusted = isTrusted;
        this.workspace = isTrusted
            ? this._workspaceFile
            : this.createEmptyWorkspace(this._workspaceFile);
        this._merged = this.computeMergedSettings();
        coreEvents.emitSettingsChanged();
    }
    createEmptyWorkspace(workspace) {
        return {
            ...workspace,
            settings: {},
            originalSettings: {},
        };
    }
    computeMergedSettings() {
        const merged = mergeSettings(this.system.settings, this.systemDefaults.settings, this.user.settings, this.workspace.settings, this.isTrusted);
        // Remote admin settings always take precedence and file-based admin settings
        // are ignored.
        const adminSettingSchema = getSettingsSchema().admin;
        if (adminSettingSchema?.properties) {
            const adminSchema = adminSettingSchema.properties;
            const adminDefaults = getDefaultsFromSchema(adminSchema);
            // The final admin settings are the defaults overridden by remote settings.
            // Any admin settings from files are ignored.
            merged.admin = customDeepMerge((path) => getMergeStrategyForPath(['admin', ...path]), adminDefaults, this._remoteAdminSettings?.admin ?? {});
        }
        return merged;
    }
    forScope(scope) {
        switch (scope) {
            case SettingScope.User:
                return this.user;
            case SettingScope.Workspace:
                return this.workspace;
            case SettingScope.System:
                return this.system;
            case SettingScope.SystemDefaults:
                return this.systemDefaults;
            default:
                throw new Error(`Invalid scope: ${scope}`);
        }
    }
    setValue(scope, key, value) {
        const settingsFile = this.forScope(scope);
        // Clone value to prevent reference sharing between settings and originalSettings
        const valueToSet = typeof value === 'object' && value !== null
            ? structuredClone(value)
            : value;
        setNestedProperty(settingsFile.settings, key, valueToSet);
        // Use a fresh clone for originalSettings to ensure total independence
        setNestedProperty(settingsFile.originalSettings, key, structuredClone(valueToSet));
        this._merged = this.computeMergedSettings();
        saveSettings(settingsFile);
        coreEvents.emitSettingsChanged();
    }
    setRemoteAdminSettings(remoteSettings) {
        const admin = {};
        const { strictModeDisabled, mcpSetting, cliFeatureSetting } = remoteSettings;
        if (Object.keys(remoteSettings).length === 0) {
            this._remoteAdminSettings = { admin };
            this._merged = this.computeMergedSettings();
            return;
        }
        admin.secureModeEnabled = !strictModeDisabled;
        admin.mcp = { enabled: mcpSetting?.mcpEnabled };
        admin.extensions = {
            enabled: cliFeatureSetting?.extensionsSetting?.extensionsEnabled,
        };
        admin.skills = {
            enabled: cliFeatureSetting?.unmanagedCapabilitiesEnabled,
        };
        this._remoteAdminSettings = { admin };
        this._merged = this.computeMergedSettings();
    }
}
function findEnvFile(startDir) {
    let currentDir = path.resolve(startDir);
    while (true) {
        // prefer gemini-specific .env under GEMINI_DIR
        const geminiEnvPath = path.join(currentDir, GEMINI_DIR, '.env');
        if (fs.existsSync(geminiEnvPath)) {
            return geminiEnvPath;
        }
        const envPath = path.join(currentDir, '.env');
        if (fs.existsSync(envPath)) {
            return envPath;
        }
        const parentDir = path.dirname(currentDir);
        if (parentDir === currentDir || !parentDir) {
            // check .env under home as fallback, again preferring gemini-specific .env
            const homeGeminiEnvPath = path.join(homedir(), GEMINI_DIR, '.env');
            if (fs.existsSync(homeGeminiEnvPath)) {
                return homeGeminiEnvPath;
            }
            const homeEnvPath = path.join(homedir(), '.env');
            if (fs.existsSync(homeEnvPath)) {
                return homeEnvPath;
            }
            return null;
        }
        currentDir = parentDir;
    }
}
export function setUpCloudShellEnvironment(envFilePath, isTrusted, isSandboxed) {
    // Special handling for GOOGLE_CLOUD_PROJECT in Cloud Shell:
    // Because GOOGLE_CLOUD_PROJECT in Cloud Shell tracks the project
    // set by the user using "gcloud config set project" we do not want to
    // use its value. So, unless the user overrides GOOGLE_CLOUD_PROJECT in
    // one of the .env files, we set the Cloud Shell-specific default here.
    let value = 'cloudshell-gca';
    if (envFilePath && fs.existsSync(envFilePath)) {
        const envFileContent = fs.readFileSync(envFilePath);
        const parsedEnv = dotenv.parse(envFileContent);
        if (parsedEnv['GOOGLE_CLOUD_PROJECT']) {
            // .env file takes precedence in Cloud Shell
            value = parsedEnv['GOOGLE_CLOUD_PROJECT'];
            if (!isTrusted && isSandboxed) {
                value = sanitizeEnvVar(value);
            }
        }
    }
    process.env['GOOGLE_CLOUD_PROJECT'] = value;
}
export function loadEnvironment(settings, workspaceDir, isWorkspaceTrustedFn = isWorkspaceTrusted) {
    const envFilePath = findEnvFile(workspaceDir);
    const trustResult = isWorkspaceTrustedFn(settings, workspaceDir);
    const isTrusted = trustResult.isTrusted ?? false;
    // Check settings OR check process.argv directly since this might be called
    // before arguments are fully parsed. This is a best-effort sniffing approach
    // that happens early in the CLI lifecycle. It is designed to detect the
    // sandbox flag before the full command-line parser is initialized to ensure
    // security constraints are applied when loading environment variables.
    const args = process.argv.slice(2);
    const doubleDashIndex = args.indexOf('--');
    const relevantArgs = doubleDashIndex === -1 ? args : args.slice(0, doubleDashIndex);
    const isSandboxed = !!settings.tools?.sandbox ||
        relevantArgs.includes('-s') ||
        relevantArgs.includes('--sandbox');
    if (trustResult.isTrusted !== true && !isSandboxed) {
        return;
    }
    // Cloud Shell environment variable handling
    if (process.env['CLOUD_SHELL'] === 'true') {
        setUpCloudShellEnvironment(envFilePath, isTrusted, isSandboxed);
    }
    if (envFilePath) {
        // Manually parse and load environment variables to handle exclusions correctly.
        // This avoids modifying environment variables that were already set from the shell.
        try {
            const envFileContent = fs.readFileSync(envFilePath, 'utf-8');
            const parsedEnv = dotenv.parse(envFileContent);
            const excludedVars = settings?.advanced?.excludedEnvVars || DEFAULT_EXCLUDED_ENV_VARS;
            const isProjectEnvFile = !envFilePath.includes(GEMINI_DIR);
            for (const key in parsedEnv) {
                if (Object.hasOwn(parsedEnv, key)) {
                    let value = parsedEnv[key];
                    // If the workspace is untrusted but we are sandboxed, only allow whitelisted variables.
                    if (!isTrusted && isSandboxed) {
                        if (!AUTH_ENV_VAR_WHITELIST.includes(key)) {
                            continue;
                        }
                        // Sanitize the value for untrusted sources
                        value = sanitizeEnvVar(value);
                    }
                    // If it's a project .env file, skip loading excluded variables.
                    if (isProjectEnvFile && excludedVars.includes(key)) {
                        continue;
                    }
                    // Load variable only if it's not already set in the environment.
                    if (!Object.hasOwn(process.env, key)) {
                        process.env[key] = value;
                    }
                }
            }
        }
        catch (_e) {
            // Errors are ignored to match the behavior of `dotenv.config({ quiet: true })`.
        }
    }
}
/**
 * Loads settings from user and workspace directories.
 * Project settings override user settings.
 */
export function loadSettings(workspaceDir = process.cwd()) {
    let systemSettings = {};
    let systemDefaultSettings = {};
    let userSettings = {};
    let workspaceSettings = {};
    const settingsErrors = [];
    const systemSettingsPath = getSystemSettingsPath();
    const systemDefaultsPath = getSystemDefaultsPath();
    // Resolve paths to their canonical representation to handle symlinks
    const resolvedWorkspaceDir = path.resolve(workspaceDir);
    const resolvedHomeDir = path.resolve(homedir());
    let realWorkspaceDir = resolvedWorkspaceDir;
    try {
        // fs.realpathSync gets the "true" path, resolving any symlinks
        realWorkspaceDir = fs.realpathSync(resolvedWorkspaceDir);
    }
    catch (_e) {
        // This is okay. The path might not exist yet, and that's a valid state.
    }
    // We expect homedir to always exist and be resolvable.
    const realHomeDir = fs.realpathSync(resolvedHomeDir);
    const workspaceSettingsPath = new Storage(workspaceDir).getWorkspaceSettingsPath();
    const load = (filePath) => {
        try {
            if (fs.existsSync(filePath)) {
                const content = fs.readFileSync(filePath, 'utf-8');
                const rawSettings = JSON.parse(stripJsonComments(content));
                if (typeof rawSettings !== 'object' ||
                    rawSettings === null ||
                    Array.isArray(rawSettings)) {
                    settingsErrors.push({
                        message: 'Settings file is not a valid JSON object.',
                        path: filePath,
                        severity: 'error',
                    });
                    return { settings: {} };
                }
                const settingsObject = rawSettings;
                // Validate settings structure with Zod
                const validationResult = validateSettings(settingsObject);
                if (!validationResult.success && validationResult.error) {
                    const errorMessage = formatValidationError(validationResult.error, filePath);
                    settingsErrors.push({
                        message: errorMessage,
                        path: filePath,
                        severity: 'warning',
                    });
                }
                return { settings: settingsObject, rawJson: content };
            }
        }
        catch (error) {
            settingsErrors.push({
                message: getErrorMessage(error),
                path: filePath,
                severity: 'error',
            });
        }
        return { settings: {} };
    };
    const systemResult = load(systemSettingsPath);
    const systemDefaultsResult = load(systemDefaultsPath);
    const userResult = load(USER_SETTINGS_PATH);
    let workspaceResult = {
        settings: {},
        rawJson: undefined,
    };
    if (realWorkspaceDir !== realHomeDir) {
        workspaceResult = load(workspaceSettingsPath);
    }
    const systemOriginalSettings = structuredClone(systemResult.settings);
    const systemDefaultsOriginalSettings = structuredClone(systemDefaultsResult.settings);
    const userOriginalSettings = structuredClone(userResult.settings);
    const workspaceOriginalSettings = structuredClone(workspaceResult.settings);
    // Environment variables for runtime use
    systemSettings = resolveEnvVarsInObject(systemResult.settings);
    systemDefaultSettings = resolveEnvVarsInObject(systemDefaultsResult.settings);
    userSettings = resolveEnvVarsInObject(userResult.settings);
    workspaceSettings = resolveEnvVarsInObject(workspaceResult.settings);
    // Support legacy theme names
    if (userSettings.ui?.theme === 'VS') {
        userSettings.ui.theme = DefaultLight.name;
    }
    else if (userSettings.ui?.theme === 'VS2015') {
        userSettings.ui.theme = DefaultDark.name;
    }
    if (workspaceSettings.ui?.theme === 'VS') {
        workspaceSettings.ui.theme = DefaultLight.name;
    }
    else if (workspaceSettings.ui?.theme === 'VS2015') {
        workspaceSettings.ui.theme = DefaultDark.name;
    }
    // For the initial trust check, we can only use user and system settings.
    const initialTrustCheckSettings = customDeepMerge(getMergeStrategyForPath, getDefaultsFromSchema(), systemDefaultSettings, userSettings, systemSettings);
    const isTrusted = isWorkspaceTrusted(initialTrustCheckSettings, workspaceDir)
        .isTrusted ?? false;
    // Create a temporary merged settings object to pass to loadEnvironment.
    const tempMergedSettings = mergeSettings(systemSettings, systemDefaultSettings, userSettings, workspaceSettings, isTrusted);
    // loadEnvironment depends on settings so we have to create a temp version of
    // the settings to avoid a cycle
    loadEnvironment(tempMergedSettings, workspaceDir);
    // Check for any fatal errors before proceeding
    const fatalErrors = settingsErrors.filter((e) => e.severity === 'error');
    if (fatalErrors.length > 0) {
        const errorMessages = fatalErrors.map((error) => `Error in ${error.path}: ${error.message}`);
        throw new FatalConfigError(`${errorMessages.join('\n')}\nPlease fix the configuration file(s) and try again.`);
    }
    const loadedSettings = new LoadedSettings({
        path: systemSettingsPath,
        settings: systemSettings,
        originalSettings: systemOriginalSettings,
        rawJson: systemResult.rawJson,
    }, {
        path: systemDefaultsPath,
        settings: systemDefaultSettings,
        originalSettings: systemDefaultsOriginalSettings,
        rawJson: systemDefaultsResult.rawJson,
    }, {
        path: USER_SETTINGS_PATH,
        settings: userSettings,
        originalSettings: userOriginalSettings,
        rawJson: userResult.rawJson,
    }, {
        path: workspaceSettingsPath,
        settings: workspaceSettings,
        originalSettings: workspaceOriginalSettings,
        rawJson: workspaceResult.rawJson,
    }, isTrusted, settingsErrors);
    // Automatically migrate deprecated settings when loading.
    migrateDeprecatedSettings(loadedSettings);
    return loadedSettings;
}
/**
 * Migrates deprecated settings to their new counterparts.
 *
 * TODO: After a couple of weeks (around early Feb 2026), we should start removing
 * the deprecated settings from the settings files by default.
 *
 * @returns true if any changes were made and need to be saved.
 */
export function migrateDeprecatedSettings(loadedSettings, removeDeprecated = false) {
    let anyModified = false;
    const migrateBoolean = (settings, oldKey, newKey) => {
        let modified = false;
        const oldValue = settings[oldKey];
        const newValue = settings[newKey];
        if (typeof oldValue === 'boolean') {
            if (typeof newValue === 'boolean') {
                // Both exist, trust the new one
                if (removeDeprecated) {
                    delete settings[oldKey];
                    modified = true;
                }
            }
            else {
                // Only old exists, migrate to new (inverted)
                settings[newKey] = !oldValue;
                if (removeDeprecated) {
                    delete settings[oldKey];
                }
                modified = true;
            }
        }
        return modified;
    };
    const processScope = (scope) => {
        const settings = loadedSettings.forScope(scope).settings;
        // Migrate general settings
        const generalSettings = settings.general;
        if (generalSettings) {
            const newGeneral = { ...generalSettings };
            let modified = false;
            modified =
                migrateBoolean(newGeneral, 'disableAutoUpdate', 'enableAutoUpdate') ||
                    modified;
            modified =
                migrateBoolean(newGeneral, 'disableUpdateNag', 'enableAutoUpdateNotification') || modified;
            if (modified) {
                loadedSettings.setValue(scope, 'general', newGeneral);
                anyModified = true;
            }
        }
        // Migrate ui settings
        const uiSettings = settings.ui;
        if (uiSettings) {
            const newUi = { ...uiSettings };
            const accessibilitySettings = newUi['accessibility'];
            if (accessibilitySettings) {
                const newAccessibility = { ...accessibilitySettings };
                if (migrateBoolean(newAccessibility, 'disableLoadingPhrases', 'enableLoadingPhrases')) {
                    newUi['accessibility'] = newAccessibility;
                    loadedSettings.setValue(scope, 'ui', newUi);
                    anyModified = true;
                }
            }
        }
        // Migrate context settings
        const contextSettings = settings.context;
        if (contextSettings) {
            const newContext = { ...contextSettings };
            const fileFilteringSettings = newContext['fileFiltering'];
            if (fileFilteringSettings) {
                const newFileFiltering = { ...fileFilteringSettings };
                if (migrateBoolean(newFileFiltering, 'disableFuzzySearch', 'enableFuzzySearch')) {
                    newContext['fileFiltering'] = newFileFiltering;
                    loadedSettings.setValue(scope, 'context', newContext);
                    anyModified = true;
                }
            }
        }
        // Migrate experimental agent settings
        anyModified =
            migrateExperimentalSettings(settings, loadedSettings, scope, removeDeprecated) || anyModified;
    };
    processScope(SettingScope.User);
    processScope(SettingScope.Workspace);
    processScope(SettingScope.System);
    processScope(SettingScope.SystemDefaults);
    return anyModified;
}
export function saveSettings(settingsFile) {
    try {
        // Ensure the directory exists
        const dirPath = path.dirname(settingsFile.path);
        if (!fs.existsSync(dirPath)) {
            fs.mkdirSync(dirPath, { recursive: true });
        }
        const settingsToSave = settingsFile.originalSettings;
        // Use the format-preserving update function
        updateSettingsFilePreservingFormat(settingsFile.path, settingsToSave);
    }
    catch (error) {
        coreEvents.emitFeedback('error', 'There was an error saving your latest settings changes.', error);
    }
}
export function saveModelChange(loadedSettings, model) {
    try {
        loadedSettings.setValue(SettingScope.User, 'model.name', model);
    }
    catch (error) {
        coreEvents.emitFeedback('error', 'There was an error saving your preferred model.', error);
    }
}
function migrateExperimentalSettings(settings, loadedSettings, scope, removeDeprecated) {
    const experimentalSettings = settings.experimental;
    if (experimentalSettings) {
        const agentsSettings = {
            ...settings.agents,
        };
        const agentsOverrides = {
            ...(agentsSettings['overrides'] || {}),
        };
        let modified = false;
        // Migrate codebaseInvestigatorSettings -> agents.overrides.codebase_investigator
        if (experimentalSettings['codebaseInvestigatorSettings']) {
            const old = experimentalSettings['codebaseInvestigatorSettings'];
            const override = {
                ...agentsOverrides['codebase_investigator'],
            };
            if (old['enabled'] !== undefined)
                override['enabled'] = old['enabled'];
            const runConfig = {
                ...override['runConfig'],
            };
            if (old['maxNumTurns'] !== undefined)
                runConfig['maxTurns'] = old['maxNumTurns'];
            if (old['maxTimeMinutes'] !== undefined)
                runConfig['maxTimeMinutes'] = old['maxTimeMinutes'];
            if (Object.keys(runConfig).length > 0)
                override['runConfig'] = runConfig;
            if (old['model'] !== undefined || old['thinkingBudget'] !== undefined) {
                const modelConfig = {
                    ...override['modelConfig'],
                };
                if (old['model'] !== undefined)
                    modelConfig['model'] = old['model'];
                if (old['thinkingBudget'] !== undefined) {
                    const generateContentConfig = {
                        ...modelConfig['generateContentConfig'],
                    };
                    const thinkingConfig = {
                        ...generateContentConfig['thinkingConfig'],
                    };
                    thinkingConfig['thinkingBudget'] = old['thinkingBudget'];
                    generateContentConfig['thinkingConfig'] = thinkingConfig;
                    modelConfig['generateContentConfig'] = generateContentConfig;
                }
                override['modelConfig'] = modelConfig;
            }
            agentsOverrides['codebase_investigator'] = override;
            modified = true;
        }
        // Migrate cliHelpAgentSettings -> agents.overrides.cli_help
        if (experimentalSettings['cliHelpAgentSettings']) {
            const old = experimentalSettings['cliHelpAgentSettings'];
            const override = {
                ...agentsOverrides['cli_help'],
            };
            if (old['enabled'] !== undefined)
                override['enabled'] = old['enabled'];
            agentsOverrides['cli_help'] = override;
            modified = true;
        }
        if (modified) {
            agentsSettings['overrides'] = agentsOverrides;
            loadedSettings.setValue(scope, 'agents', agentsSettings);
            if (removeDeprecated) {
                const newExperimental = { ...experimentalSettings };
                delete newExperimental['codebaseInvestigatorSettings'];
                delete newExperimental['cliHelpAgentSettings'];
                loadedSettings.setValue(scope, 'experimental', newExperimental);
            }
            return true;
        }
    }
    return false;
}
//# sourceMappingURL=settings.js.map