diff --git a/docs/cli/plan-mode.md b/docs/cli/plan-mode.md index 39b6db21e0..8d28994aac 100644 --- a/docs/cli/plan-mode.md +++ b/docs/cli/plan-mode.md @@ -36,7 +36,7 @@ implementation strategy. You can configure Gemini CLI to start directly in Plan Mode by default: 1. Type `/settings` in the CLI. -2. Search for `Approval Mode`. +2. Search for `Default Approval Mode`. 3. Set the value to `Plan`. Other ways to start in Plan Mode: @@ -46,8 +46,8 @@ Other ways to start in Plan Mode: ```json { - "tools": { - "approvalMode": "plan" + "general": { + "defaultApprovalMode": "plan" } } ``` diff --git a/docs/cli/settings.md b/docs/cli/settings.md index 07e8c986c6..d699323d86 100644 --- a/docs/cli/settings.md +++ b/docs/cli/settings.md @@ -22,13 +22,14 @@ they appear in the UI. ### General -| UI Label | Setting | Description | Default | -| ------------------------ | ---------------------------------- | ------------------------------------------------------------- | ------- | -| Vim Mode | `general.vimMode` | Enable Vim keybindings | `false` | -| Enable Auto Update | `general.enableAutoUpdate` | Enable automatic updates. | `true` | -| Enable Prompt Completion | `general.enablePromptCompletion` | Enable AI-powered prompt completion suggestions while typing. | `false` | -| Debug Keystroke Logging | `general.debugKeystrokeLogging` | Enable debug logging of keystrokes to the console. | `false` | -| Enable Session Cleanup | `general.sessionRetention.enabled` | Enable automatic session cleanup | `false` | +| UI Label | Setting | Description | Default | +| ------------------------ | ---------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | +| Vim Mode | `general.vimMode` | Enable Vim keybindings | `false` | +| Default Approval Mode | `general.defaultApprovalMode` | The default approval mode for tool execution. 'default' prompts for approval, 'auto_edit' auto-approves edit tools, and 'plan' is read-only mode. 'yolo' is not supported yet. | `"default"` | +| Enable Auto Update | `general.enableAutoUpdate` | Enable automatic updates. | `true` | +| Enable Prompt Completion | `general.enablePromptCompletion` | Enable AI-powered prompt completion suggestions while typing. | `false` | +| Debug Keystroke Logging | `general.debugKeystrokeLogging` | Enable debug logging of keystrokes to the console. | `false` | +| Enable Session Cleanup | `general.sessionRetention.enabled` | Enable automatic session cleanup | `false` | ### Output @@ -96,14 +97,13 @@ they appear in the UI. ### Tools -| UI Label | Setting | Description | Default | -| -------------------------------- | ------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ | ----------- | -| Enable Interactive Shell | `tools.shell.enableInteractiveShell` | Use node-pty for an interactive shell experience. Fallback to child_process still applies. | `true` | -| Show Color | `tools.shell.showColor` | Show color in shell output. | `false` | -| Approval Mode | `tools.approvalMode` | The default approval mode for tool execution. 'default' prompts for approval, 'auto_edit' auto-approves edit tools, and 'plan' is read-only mode. 'yolo' is not supported yet. | `"default"` | -| Use Ripgrep | `tools.useRipgrep` | Use ripgrep for file content search instead of the fallback implementation. Provides faster search performance. | `true` | -| Tool Output Truncation Threshold | `tools.truncateToolOutputThreshold` | Maximum characters to show when truncating large tool outputs. Set to 0 or negative to disable truncation. | `40000` | -| Disable LLM Correction | `tools.disableLLMCorrection` | Disable LLM-based error correction for edit tools. When enabled, tools will fail immediately if exact string matches are not found, instead of attempting to self-correct. | `true` | +| UI Label | Setting | Description | Default | +| -------------------------------- | ------------------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ------- | +| Enable Interactive Shell | `tools.shell.enableInteractiveShell` | Use node-pty for an interactive shell experience. Fallback to child_process still applies. | `true` | +| Show Color | `tools.shell.showColor` | Show color in shell output. | `false` | +| Use Ripgrep | `tools.useRipgrep` | Use ripgrep for file content search instead of the fallback implementation. Provides faster search performance. | `true` | +| Tool Output Truncation Threshold | `tools.truncateToolOutputThreshold` | Maximum characters to show when truncating large tool outputs. Set to 0 or negative to disable truncation. | `40000` | +| Disable LLM Correction | `tools.disableLLMCorrection` | Disable LLM-based error correction for edit tools. When enabled, tools will fail immediately if exact string matches are not found, instead of attempting to self-correct. | `true` | ### Security diff --git a/docs/get-started/configuration.md b/docs/get-started/configuration.md index 33016840c7..41da8d43a8 100644 --- a/docs/get-started/configuration.md +++ b/docs/get-started/configuration.md @@ -106,6 +106,13 @@ their corresponding top-level category object in your `settings.json` file. - **Description:** Enable Vim keybindings - **Default:** `false` +- **`general.defaultApprovalMode`** (enum): + - **Description:** The default approval mode for tool execution. 'default' + prompts for approval, 'auto_edit' auto-approves edit tools, and 'plan' is + read-only mode. 'yolo' is not supported yet. + - **Default:** `"default"` + - **Values:** `"default"`, `"auto_edit"`, `"plan"` + - **`general.devtools`** (boolean): - **Description:** Enable DevTools inspector on launch. - **Default:** `false` @@ -681,13 +688,6 @@ their corresponding top-level category object in your `settings.json` file. performance. - **Default:** `true` -- **`tools.approvalMode`** (enum): - - **Description:** The default approval mode for tool execution. 'default' - prompts for approval, 'auto_edit' auto-approves edit tools, and 'plan' is - read-only mode. 'yolo' is not supported yet. - - **Default:** `"default"` - - **Values:** `"default"`, `"auto_edit"`, `"plan"` - - **`tools.core`** (array): - **Description:** Restrict the set of built-in tools with an allowlist. Match semantics mirror tools.allowed; see the built-in tools documentation for diff --git a/packages/cli/src/config/config.test.ts b/packages/cli/src/config/config.test.ts index 615f6d0cab..3886240811 100644 --- a/packages/cli/src/config/config.test.ts +++ b/packages/cli/src/config/config.test.ts @@ -2624,7 +2624,7 @@ describe('loadCliConfig approval mode', () => { it('should use approvalMode from settings when no CLI flags are set', async () => { process.argv = ['node', 'script.js']; const settings = createTestMergedSettings({ - tools: { approvalMode: 'auto_edit' }, + general: { defaultApprovalMode: 'auto_edit' }, }); const argv = await parseArguments(settings); const config = await loadCliConfig(settings, 'test-session', argv); @@ -2636,7 +2636,7 @@ describe('loadCliConfig approval mode', () => { it('should prioritize --approval-mode flag over settings', async () => { process.argv = ['node', 'script.js', '--approval-mode', 'auto_edit']; const settings = createTestMergedSettings({ - tools: { approvalMode: 'default' }, + general: { defaultApprovalMode: 'default' }, }); const argv = await parseArguments(settings); const config = await loadCliConfig(settings, 'test-session', argv); @@ -2648,7 +2648,7 @@ describe('loadCliConfig approval mode', () => { it('should prioritize --yolo flag over settings', async () => { process.argv = ['node', 'script.js', '--yolo']; const settings = createTestMergedSettings({ - tools: { approvalMode: 'auto_edit' }, + general: { defaultApprovalMode: 'auto_edit' }, }); const argv = await parseArguments(settings); const config = await loadCliConfig(settings, 'test-session', argv); @@ -2658,7 +2658,7 @@ describe('loadCliConfig approval mode', () => { it('should respect plan mode from settings when experimental.plan is enabled', async () => { process.argv = ['node', 'script.js']; const settings = createTestMergedSettings({ - tools: { approvalMode: 'plan' }, + general: { defaultApprovalMode: 'plan' }, experimental: { plan: true }, }); const argv = await parseArguments(settings); @@ -2669,7 +2669,7 @@ describe('loadCliConfig approval mode', () => { it('should throw error if plan mode is in settings but experimental.plan is disabled', async () => { process.argv = ['node', 'script.js']; const settings = createTestMergedSettings({ - tools: { approvalMode: 'plan' }, + general: { defaultApprovalMode: 'plan' }, experimental: { plan: false }, }); const argv = await parseArguments(settings); diff --git a/packages/cli/src/config/config.ts b/packages/cli/src/config/config.ts index 8956d88367..87eb1e8fa7 100755 --- a/packages/cli/src/config/config.ts +++ b/packages/cli/src/config/config.ts @@ -519,8 +519,8 @@ export async function loadCliConfig( const rawApprovalMode = argv.approvalMode || (argv.yolo ? 'yolo' : undefined) || - ((settings.tools?.approvalMode as string) !== 'yolo' - ? settings.tools.approvalMode + ((settings.general?.defaultApprovalMode as string) !== 'yolo' + ? settings.general?.defaultApprovalMode : undefined); if (rawApprovalMode) { diff --git a/packages/cli/src/config/settings.test.ts b/packages/cli/src/config/settings.test.ts index 7c63bf972c..721458952f 100644 --- a/packages/cli/src/config/settings.test.ts +++ b/packages/cli/src/config/settings.test.ts @@ -1936,6 +1936,40 @@ describe('Settings Loading and Merging', () => { ); }); + it('should migrate tools.approvalMode to general.defaultApprovalMode', () => { + const userSettingsContent = { + tools: { + approvalMode: 'plan', + }, + }; + + (fs.readFileSync as Mock).mockImplementation( + (p: fs.PathOrFileDescriptor) => { + if (p === USER_SETTINGS_PATH) + return JSON.stringify(userSettingsContent); + return '{}'; + }, + ); + + const setValueSpy = vi.spyOn(LoadedSettings.prototype, 'setValue'); + const loadedSettings = loadSettings(MOCK_WORKSPACE_DIR); + + migrateDeprecatedSettings(loadedSettings, true); + + expect(setValueSpy).toHaveBeenCalledWith( + SettingScope.User, + 'general', + expect.objectContaining({ defaultApprovalMode: 'plan' }), + ); + + // Verify removal + expect(setValueSpy).toHaveBeenCalledWith( + SettingScope.User, + 'tools', + expect.not.objectContaining({ approvalMode: 'plan' }), + ); + }); + it('should migrate all 4 inverted boolean settings', () => { const userSettingsContent = { general: { diff --git a/packages/cli/src/config/settings.ts b/packages/cli/src/config/settings.ts index a267cfe185..8e9ff7380f 100644 --- a/packages/cli/src/config/settings.ts +++ b/packages/cli/src/config/settings.ts @@ -911,6 +911,36 @@ export function migrateDeprecatedSettings( } } + // Migrate tools settings + const toolsSettings = settings.tools as Record | undefined; + if (toolsSettings) { + if (toolsSettings['approvalMode'] !== undefined) { + foundDeprecated.push('tools.approvalMode'); + + const generalSettings = + (settings.general as Record | undefined) || {}; + const newGeneral = { ...generalSettings }; + + // Only set defaultApprovalMode if it's not already set + if (newGeneral['defaultApprovalMode'] === undefined) { + newGeneral['defaultApprovalMode'] = toolsSettings['approvalMode']; + loadedSettings.setValue(scope, 'general', newGeneral); + if (!settingsFile.readOnly) { + anyModified = true; + } + } + + if (removeDeprecated) { + const newTools = { ...toolsSettings }; + delete newTools['approvalMode']; + loadedSettings.setValue(scope, 'tools', newTools); + if (!settingsFile.readOnly) { + anyModified = true; + } + } + } + } + // Migrate experimental agent settings const experimentalModified = migrateExperimentalSettings( settings, diff --git a/packages/cli/src/config/settingsSchema.ts b/packages/cli/src/config/settingsSchema.ts index 1948960ac3..f753d08f25 100644 --- a/packages/cli/src/config/settingsSchema.ts +++ b/packages/cli/src/config/settingsSchema.ts @@ -179,6 +179,24 @@ const SETTINGS_SCHEMA = { description: 'Enable Vim keybindings', showInDialog: true, }, + defaultApprovalMode: { + type: 'enum', + label: 'Default Approval Mode', + category: 'General', + requiresRestart: false, + default: 'default', + description: oneLine` + The default approval mode for tool execution. + 'default' prompts for approval, 'auto_edit' auto-approves edit tools, + and 'plan' is read-only mode. 'yolo' is not supported yet. + `, + showInDialog: true, + options: [ + { value: 'default', label: 'Default' }, + { value: 'auto_edit', label: 'Auto Edit' }, + { value: 'plan', label: 'Plan' }, + ], + }, devtools: { type: 'boolean', label: 'DevTools', @@ -1083,24 +1101,7 @@ const SETTINGS_SCHEMA = { }, }, }, - approvalMode: { - type: 'enum', - label: 'Approval Mode', - category: 'Tools', - requiresRestart: false, - default: 'default', - description: oneLine` - The default approval mode for tool execution. - 'default' prompts for approval, 'auto_edit' auto-approves edit tools, - and 'plan' is read-only mode. 'yolo' is not supported yet. - `, - showInDialog: true, - options: [ - { value: 'default', label: 'Default' }, - { value: 'auto_edit', label: 'Auto Edit' }, - { value: 'plan', label: 'Plan' }, - ], - }, + core: { type: 'array', label: 'Core Tools', diff --git a/packages/cli/src/ui/components/__snapshots__/SettingsDialog.test.tsx.snap b/packages/cli/src/ui/components/__snapshots__/SettingsDialog.test.tsx.snap index 786867ccc0..b6c7b64496 100644 --- a/packages/cli/src/ui/components/__snapshots__/SettingsDialog.test.tsx.snap +++ b/packages/cli/src/ui/components/__snapshots__/SettingsDialog.test.tsx.snap @@ -13,6 +13,9 @@ exports[`SettingsDialog > Initial Rendering > should render settings list with v │ ● Vim Mode false │ │ Enable Vim keybindings │ │ │ +│ Default Approval Mode Default │ +│ The default approval mode for tool execution. 'default' prompts for approval, 'au… │ +│ │ │ Enable Auto Update true │ │ Enable automatic updates. │ │ │ @@ -31,9 +34,6 @@ exports[`SettingsDialog > Initial Rendering > should render settings list with v │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ -│ Terminal Background Polling Interval 60 │ -│ Interval in seconds to poll the terminal background color. │ -│ │ │ ▼ │ │ │ │ Apply To │ @@ -59,6 +59,9 @@ exports[`SettingsDialog > Snapshot Tests > should render 'accessibility settings │ ● Vim Mode true* │ │ Enable Vim keybindings │ │ │ +│ Default Approval Mode Default │ +│ The default approval mode for tool execution. 'default' prompts for approval, 'au… │ +│ │ │ Enable Auto Update true │ │ Enable automatic updates. │ │ │ @@ -77,9 +80,6 @@ exports[`SettingsDialog > Snapshot Tests > should render 'accessibility settings │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ -│ Terminal Background Polling Interval 60 │ -│ Interval in seconds to poll the terminal background color. │ -│ │ │ ▼ │ │ │ │ Apply To │ @@ -105,6 +105,9 @@ exports[`SettingsDialog > Snapshot Tests > should render 'all boolean settings d │ ● Vim Mode false* │ │ Enable Vim keybindings │ │ │ +│ Default Approval Mode Default │ +│ The default approval mode for tool execution. 'default' prompts for approval, 'au… │ +│ │ │ Enable Auto Update true* │ │ Enable automatic updates. │ │ │ @@ -123,9 +126,6 @@ exports[`SettingsDialog > Snapshot Tests > should render 'all boolean settings d │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ -│ Terminal Background Polling Interval 60 │ -│ Interval in seconds to poll the terminal background color. │ -│ │ │ ▼ │ │ │ │ Apply To │ @@ -151,6 +151,9 @@ exports[`SettingsDialog > Snapshot Tests > should render 'default state' correct │ ● Vim Mode false │ │ Enable Vim keybindings │ │ │ +│ Default Approval Mode Default │ +│ The default approval mode for tool execution. 'default' prompts for approval, 'au… │ +│ │ │ Enable Auto Update true │ │ Enable automatic updates. │ │ │ @@ -169,9 +172,6 @@ exports[`SettingsDialog > Snapshot Tests > should render 'default state' correct │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ -│ Terminal Background Polling Interval 60 │ -│ Interval in seconds to poll the terminal background color. │ -│ │ │ ▼ │ │ │ │ Apply To │ @@ -197,6 +197,9 @@ exports[`SettingsDialog > Snapshot Tests > should render 'file filtering setting │ ● Vim Mode false │ │ Enable Vim keybindings │ │ │ +│ Default Approval Mode Default │ +│ The default approval mode for tool execution. 'default' prompts for approval, 'au… │ +│ │ │ Enable Auto Update true │ │ Enable automatic updates. │ │ │ @@ -215,9 +218,6 @@ exports[`SettingsDialog > Snapshot Tests > should render 'file filtering setting │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ -│ Terminal Background Polling Interval 60 │ -│ Interval in seconds to poll the terminal background color. │ -│ │ │ ▼ │ │ │ │ Apply To │ @@ -243,6 +243,9 @@ exports[`SettingsDialog > Snapshot Tests > should render 'focused on scope selec │ Vim Mode false │ │ Enable Vim keybindings │ │ │ +│ Default Approval Mode Default │ +│ The default approval mode for tool execution. 'default' prompts for approval, 'au… │ +│ │ │ Enable Auto Update true │ │ Enable automatic updates. │ │ │ @@ -261,9 +264,6 @@ exports[`SettingsDialog > Snapshot Tests > should render 'focused on scope selec │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ -│ Terminal Background Polling Interval 60 │ -│ Interval in seconds to poll the terminal background color. │ -│ │ │ ▼ │ │ │ │ > Apply To │ @@ -289,6 +289,9 @@ exports[`SettingsDialog > Snapshot Tests > should render 'mixed boolean and numb │ ● Vim Mode false* │ │ Enable Vim keybindings │ │ │ +│ Default Approval Mode Default │ +│ The default approval mode for tool execution. 'default' prompts for approval, 'au… │ +│ │ │ Enable Auto Update false* │ │ Enable automatic updates. │ │ │ @@ -307,9 +310,6 @@ exports[`SettingsDialog > Snapshot Tests > should render 'mixed boolean and numb │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ -│ Terminal Background Polling Interval 60 │ -│ Interval in seconds to poll the terminal background color. │ -│ │ │ ▼ │ │ │ │ Apply To │ @@ -335,6 +335,9 @@ exports[`SettingsDialog > Snapshot Tests > should render 'tools and security set │ ● Vim Mode false │ │ Enable Vim keybindings │ │ │ +│ Default Approval Mode Default │ +│ The default approval mode for tool execution. 'default' prompts for approval, 'au… │ +│ │ │ Enable Auto Update true │ │ Enable automatic updates. │ │ │ @@ -353,9 +356,6 @@ exports[`SettingsDialog > Snapshot Tests > should render 'tools and security set │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ -│ Terminal Background Polling Interval 60 │ -│ Interval in seconds to poll the terminal background color. │ -│ │ │ ▼ │ │ │ │ Apply To │ @@ -381,6 +381,9 @@ exports[`SettingsDialog > Snapshot Tests > should render 'various boolean settin │ ● Vim Mode true* │ │ Enable Vim keybindings │ │ │ +│ Default Approval Mode Default │ +│ The default approval mode for tool execution. 'default' prompts for approval, 'au… │ +│ │ │ Enable Auto Update false* │ │ Enable automatic updates. │ │ │ @@ -399,9 +402,6 @@ exports[`SettingsDialog > Snapshot Tests > should render 'various boolean settin │ Auto Theme Switching true │ │ Automatically switch between default light and dark themes based on terminal backgro… │ │ │ -│ Terminal Background Polling Interval 60 │ -│ Interval in seconds to poll the terminal background color. │ -│ │ │ ▼ │ │ │ │ Apply To │ diff --git a/schemas/settings.schema.json b/schemas/settings.schema.json index 8434b61867..ed3c3bb2fd 100644 --- a/schemas/settings.schema.json +++ b/schemas/settings.schema.json @@ -42,6 +42,14 @@ "default": false, "type": "boolean" }, + "defaultApprovalMode": { + "title": "Default Approval Mode", + "description": "The default approval mode for tool execution. 'default' prompts for approval, 'auto_edit' auto-approves edit tools, and 'plan' is read-only mode. 'yolo' is not supported yet.", + "markdownDescription": "The default approval mode for tool execution. 'default' prompts for approval, 'auto_edit' auto-approves edit tools, and 'plan' is read-only mode. 'yolo' is not supported yet.\n\n- Category: `General`\n- Requires restart: `no`\n- Default: `default`", + "default": "default", + "type": "string", + "enum": ["default", "auto_edit", "plan"] + }, "devtools": { "title": "DevTools", "description": "Enable DevTools inspector on launch.", @@ -1141,14 +1149,6 @@ }, "additionalProperties": false }, - "approvalMode": { - "title": "Approval Mode", - "description": "The default approval mode for tool execution. 'default' prompts for approval, 'auto_edit' auto-approves edit tools, and 'plan' is read-only mode. 'yolo' is not supported yet.", - "markdownDescription": "The default approval mode for tool execution. 'default' prompts for approval, 'auto_edit' auto-approves edit tools, and 'plan' is read-only mode. 'yolo' is not supported yet.\n\n- Category: `Tools`\n- Requires restart: `no`\n- Default: `default`", - "default": "default", - "type": "string", - "enum": ["default", "auto_edit", "plan"] - }, "core": { "title": "Core Tools", "description": "Restrict the set of built-in tools with an allowlist. Match semantics mirror tools.allowed; see the built-in tools documentation for available names.",