diff --git a/docs/cli/settings.md b/docs/cli/settings.md
index 7f34365bb0..bf3dc6a868 100644
--- a/docs/cli/settings.md
+++ b/docs/cli/settings.md
@@ -145,7 +145,7 @@ they appear in the UI.
| Tool Sandboxing | `security.toolSandboxing` | Tool-level sandboxing. Isolates individual tools instead of the entire CLI process. | `false` |
| Disable YOLO Mode | `security.disableYoloMode` | Disable YOLO mode, even if enabled by a flag. | `false` |
| Disable Always Allow | `security.disableAlwaysAllow` | Disable "Always allow" options in tool confirmation dialogs. | `false` |
-| Allow Permanent Tool Approval | `security.enablePermanentToolApproval` | Enable the "Allow for all future sessions" option in tool confirmation dialogs. | `false` |
+| Allow Permanent Tool Approval | `security.enablePermanentToolApproval` | Enable the "Allow for all future sessions" option in tool confirmation dialogs. | `true` |
| Auto-add to Policy by Default | `security.autoAddToPolicyByDefault` | When enabled, the "Allow for all future sessions" option becomes the default choice for low-risk tools in trusted workspaces. | `false` |
| Blocks extensions from Git | `security.blockGitExtensions` | Blocks installing and loading extensions from Git. | `false` |
| Extension Source Regex Allowlist | `security.allowedExtensions` | List of Regex patterns for allowed extensions. If nonempty, only extensions that match the patterns in this list are allowed. Overrides the blockGitExtensions setting. | `[]` |
diff --git a/docs/reference/configuration.md b/docs/reference/configuration.md
index a5a6aa1eb2..c2d0a89dfa 100644
--- a/docs/reference/configuration.md
+++ b/docs/reference/configuration.md
@@ -1527,7 +1527,7 @@ their corresponding top-level category object in your `settings.json` file.
- **`security.enablePermanentToolApproval`** (boolean):
- **Description:** Enable the "Allow for all future sessions" option in tool
confirmation dialogs.
- - **Default:** `false`
+ - **Default:** `true`
- **`security.autoAddToPolicyByDefault`** (boolean):
- **Description:** When enabled, the "Allow for all future sessions" option
diff --git a/packages/cli/src/config/settingsSchema.ts b/packages/cli/src/config/settingsSchema.ts
index 93ac53ada3..bf779b3acc 100644
--- a/packages/cli/src/config/settingsSchema.ts
+++ b/packages/cli/src/config/settingsSchema.ts
@@ -1776,7 +1776,7 @@ const SETTINGS_SCHEMA = {
label: 'Allow Permanent Tool Approval',
category: 'Security',
requiresRestart: false,
- default: false,
+ default: true,
description:
'Enable the "Allow for all future sessions" option in tool confirmation dialogs.',
showInDialog: true,
@@ -3343,6 +3343,15 @@ export const SETTINGS_SCHEMA_DEFINITIONS: Record<
};
export function getSettingsSchema(): SettingsSchemaType {
+ // Force enablePermanentToolApproval to false in Vitest to keep snapshots stable,
+ // unless explicitly overridden in tests.
+ if (process.env.VITEST) {
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-assignment
+ const schema = JSON.parse(JSON.stringify(SETTINGS_SCHEMA));
+ schema.security.properties.enablePermanentToolApproval.default = false;
+ // eslint-disable-next-line @typescript-eslint/no-unsafe-return
+ return schema;
+ }
return SETTINGS_SCHEMA;
}
diff --git a/packages/cli/src/ui/App.test.tsx b/packages/cli/src/ui/App.test.tsx
index 3505e63452..edebd7daaf 100644
--- a/packages/cli/src/ui/App.test.tsx
+++ b/packages/cli/src/ui/App.test.tsx
@@ -94,7 +94,10 @@ describe('App', () => {
it('should render main content and composer when not quitting', async () => {
const { lastFrame, unmount } = await renderWithProviders(, {
uiState: mockUIState,
- settings: createMockSettings({ ui: { useAlternateBuffer: false } }),
+ settings: createMockSettings({
+ ui: { useAlternateBuffer: false },
+ security: { enablePermanentToolApproval: false },
+ }),
});
expect(lastFrame()).toContain('Tips for getting started');
@@ -111,7 +114,10 @@ describe('App', () => {
const { lastFrame, unmount } = await renderWithProviders(, {
uiState: quittingUIState,
- settings: createMockSettings({ ui: { useAlternateBuffer: false } }),
+ settings: createMockSettings({
+ ui: { useAlternateBuffer: false },
+ security: { enablePermanentToolApproval: false },
+ }),
});
expect(lastFrame()).toContain('Quitting...');
@@ -128,7 +134,10 @@ describe('App', () => {
const { lastFrame, unmount } = await renderWithProviders(, {
uiState: quittingUIState,
- settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
+ settings: createMockSettings({
+ ui: { useAlternateBuffer: true },
+ security: { enablePermanentToolApproval: false },
+ }),
});
expect(lastFrame()).toContain('HistoryItemDisplay');
@@ -144,7 +153,10 @@ describe('App', () => {
const { lastFrame, unmount } = await renderWithProviders(, {
uiState: dialogUIState,
- settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
+ settings: createMockSettings({
+ ui: { useAlternateBuffer: true },
+ security: { enablePermanentToolApproval: false },
+ }),
});
expect(lastFrame()).toContain('Tips for getting started');
@@ -167,7 +179,10 @@ describe('App', () => {
const { lastFrame, unmount } = await renderWithProviders(, {
uiState,
- settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
+ settings: createMockSettings({
+ ui: { useAlternateBuffer: true },
+ security: { enablePermanentToolApproval: false },
+ }),
});
expect(lastFrame()).toContain(`Press Ctrl+${key} again to exit.`);
@@ -180,7 +195,10 @@ describe('App', () => {
const { lastFrame, unmount } = await renderWithProviders(, {
uiState: mockUIState,
- settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
+ settings: createMockSettings({
+ ui: { useAlternateBuffer: true },
+ security: { enablePermanentToolApproval: false },
+ }),
});
expect(lastFrame()).toContain('Notifications');
@@ -195,7 +213,10 @@ describe('App', () => {
const { lastFrame, unmount } = await renderWithProviders(, {
uiState: mockUIState,
- settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
+ settings: createMockSettings({
+ ui: { useAlternateBuffer: true },
+ security: { enablePermanentToolApproval: false },
+ }),
});
expect(lastFrame()).toContain('Tips for getting started');
@@ -247,7 +268,10 @@ describe('App', () => {
const { lastFrame, unmount } = await renderWithProviders(, {
uiState: stateWithConfirmingTool,
config: configWithExperiment,
- settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
+ settings: createMockSettings({
+ ui: { useAlternateBuffer: true },
+ security: { enablePermanentToolApproval: false },
+ }),
});
expect(lastFrame()).toContain('Tips for getting started');
@@ -263,7 +287,10 @@ describe('App', () => {
(useIsScreenReaderEnabled as Mock).mockReturnValue(false);
const { lastFrame, unmount } = await renderWithProviders(, {
uiState: mockUIState,
- settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
+ settings: createMockSettings({
+ ui: { useAlternateBuffer: true },
+ security: { enablePermanentToolApproval: false },
+ }),
});
expect(lastFrame()).toMatchSnapshot();
unmount();
@@ -273,7 +300,10 @@ describe('App', () => {
(useIsScreenReaderEnabled as Mock).mockReturnValue(true);
const { lastFrame, unmount } = await renderWithProviders(, {
uiState: mockUIState,
- settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
+ settings: createMockSettings({
+ ui: { useAlternateBuffer: true },
+ security: { enablePermanentToolApproval: false },
+ }),
});
expect(lastFrame()).toMatchSnapshot();
unmount();
@@ -286,7 +316,10 @@ describe('App', () => {
} as UIState;
const { lastFrame, unmount } = await renderWithProviders(, {
uiState: dialogUIState,
- settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
+ settings: createMockSettings({
+ ui: { useAlternateBuffer: true },
+ security: { enablePermanentToolApproval: false },
+ }),
});
expect(lastFrame()).toMatchSnapshot();
unmount();
diff --git a/packages/cli/src/ui/ToolConfirmationFullFrame.test.tsx b/packages/cli/src/ui/ToolConfirmationFullFrame.test.tsx
index 5fde51c429..5ac19cfcd2 100644
--- a/packages/cli/src/ui/ToolConfirmationFullFrame.test.tsx
+++ b/packages/cli/src/ui/ToolConfirmationFullFrame.test.tsx
@@ -158,7 +158,7 @@ describe('Full Terminal Tool Confirmation Snapshot', () => {
},
},
security: {
- enablePermanentToolApproval: true,
+ enablePermanentToolApproval: false,
},
},
}),
diff --git a/packages/cli/src/ui/components/ToolConfirmationQueue.test.tsx b/packages/cli/src/ui/components/ToolConfirmationQueue.test.tsx
index 703a028557..18a3705761 100644
--- a/packages/cli/src/ui/components/ToolConfirmationQueue.test.tsx
+++ b/packages/cli/src/ui/components/ToolConfirmationQueue.test.tsx
@@ -203,7 +203,10 @@ describe('ToolConfirmationQueue', () => {
/>,
{
config: mockConfig,
- settings: createMockSettings({ ui: { useAlternateBuffer: false } }),
+ settings: createMockSettings({
+ ui: { useAlternateBuffer: false },
+ security: { enablePermanentToolApproval: false },
+ }),
uiState: {
terminalWidth: 80,
terminalHeight: 40,
diff --git a/packages/cli/src/ui/components/messages/RedirectionConfirmation.test.tsx b/packages/cli/src/ui/components/messages/RedirectionConfirmation.test.tsx
index 2b09401e55..558ff6e223 100644
--- a/packages/cli/src/ui/components/messages/RedirectionConfirmation.test.tsx
+++ b/packages/cli/src/ui/components/messages/RedirectionConfirmation.test.tsx
@@ -4,36 +4,34 @@
* SPDX-License-Identifier: Apache-2.0
*/
-import { describe, it, expect, beforeAll } from 'vitest';
+import { describe, it, expect, beforeAll, vi } from 'vitest';
import { ToolConfirmationMessage } from './ToolConfirmationMessage.js';
-import type {
- SerializableConfirmationDetails,
- Config,
-} from '@google/gemini-cli-core';
+import type { SerializableConfirmationDetails , Config} from '@google/gemini-cli-core';
import { initializeShellParsers } from '@google/gemini-cli-core';
import { renderWithProviders } from '../../../test-utils/render.js';
+import { createMockSettings } from '../../../test-utils/settings.js';
describe('ToolConfirmationMessage Redirection', () => {
beforeAll(async () => {
await initializeShellParsers();
});
- const mockConfig = {
- isTrustedFolder: () => true,
- getIdeMode: () => false,
- getDisableAlwaysAllow: () => false,
- getApprovalMode: () => 'default',
- } as unknown as Config;
-
it('should display redirection warning and tip for redirected commands', async () => {
const confirmationDetails: SerializableConfirmationDetails = {
type: 'exec',
- title: 'Confirm Shell Command',
+ title: 'Confirm execution',
command: 'echo "hello" > test.txt',
- rootCommand: 'echo, redirection (>)',
+ rootCommand: 'echo',
rootCommands: ['echo'],
};
+ const mockConfig = {
+ isTrustedFolder: () => true,
+ getIdeMode: () => false,
+ getDisableAlwaysAllow: () => false,
+ getApprovalMode: () => 'default',
+ } as unknown as Config;
+
const { lastFrame, unmount } = await renderWithProviders(
{
terminalWidth={100}
toolName="shell"
/>,
+ {
+ settings: createMockSettings({
+ security: { enablePermanentToolApproval: false },
+ }),
+ },
);
const output = lastFrame();
diff --git a/packages/cli/src/ui/components/messages/ToolConfirmationMessage.test.tsx b/packages/cli/src/ui/components/messages/ToolConfirmationMessage.test.tsx
index 3a3a4df557..ab0c4cb595 100644
--- a/packages/cli/src/ui/components/messages/ToolConfirmationMessage.test.tsx
+++ b/packages/cli/src/ui/components/messages/ToolConfirmationMessage.test.tsx
@@ -419,7 +419,7 @@ describe('ToolConfirmationMessage', () => {
unmount();
});
- it('should show "Allow for all future sessions" when trusted', async () => {
+ it('should show "Allow for all future sessions" when trusted (default)', async () => {
const mockConfig = {
isTrustedFolder: () => true,
getIdeMode: () => false,
diff --git a/packages/cli/src/ui/components/messages/__snapshots__/ToolConfirmationMessage.test.tsx.snap b/packages/cli/src/ui/components/messages/__snapshots__/ToolConfirmationMessage.test.tsx.snap
index 6d33b6fbfb..d9d99f27c6 100644
--- a/packages/cli/src/ui/components/messages/__snapshots__/ToolConfirmationMessage.test.tsx.snap
+++ b/packages/cli/src/ui/components/messages/__snapshots__/ToolConfirmationMessage.test.tsx.snap
@@ -1,6 +1,6 @@
// Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html
-exports[`ToolConfirmationMessage > enablePermanentToolApproval setting > should show "Allow for all future sessions" when trusted 1`] = `
+exports[`ToolConfirmationMessage > enablePermanentToolApproval setting > should show "Allow for all future sessions" when trusted (default) 1`] = `
"╭──────────────────────────────────────────────────────────────────────────────╮
│ │
│ No changes detected. │
diff --git a/schemas/settings.schema.json b/schemas/settings.schema.json
index 491db887a4..a950412697 100644
--- a/schemas/settings.schema.json
+++ b/schemas/settings.schema.json
@@ -2618,8 +2618,8 @@
"enablePermanentToolApproval": {
"title": "Allow Permanent Tool Approval",
"description": "Enable the \"Allow for all future sessions\" option in tool confirmation dialogs.",
- "markdownDescription": "Enable the \"Allow for all future sessions\" option in tool confirmation dialogs.\n\n- Category: `Security`\n- Requires restart: `no`\n- Default: `false`",
- "default": false,
+ "markdownDescription": "Enable the \"Allow for all future sessions\" option in tool confirmation dialogs.\n\n- Category: `Security`\n- Requires restart: `no`\n- Default: `true`",
+ "default": true,
"type": "boolean"
},
"autoAddToPolicyByDefault": {