mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-06-22 01:07:12 -07:00
feat(cli): enable permanent tool approval by default
This commit is contained in:
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -94,7 +94,10 @@ describe('App', () => {
|
||||
it('should render main content and composer when not quitting', async () => {
|
||||
const { lastFrame, unmount } = await renderWithProviders(<App />, {
|
||||
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(<App />, {
|
||||
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(<App />, {
|
||||
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(<App />, {
|
||||
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(<App />, {
|
||||
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(<App />, {
|
||||
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(<App />, {
|
||||
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(<App />, {
|
||||
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(<App />, {
|
||||
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(<App />, {
|
||||
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(<App />, {
|
||||
uiState: dialogUIState,
|
||||
settings: createMockSettings({ ui: { useAlternateBuffer: true } }),
|
||||
settings: createMockSettings({
|
||||
ui: { useAlternateBuffer: true },
|
||||
security: { enablePermanentToolApproval: false },
|
||||
}),
|
||||
});
|
||||
expect(lastFrame()).toMatchSnapshot();
|
||||
unmount();
|
||||
|
||||
@@ -158,7 +158,7 @@ describe('Full Terminal Tool Confirmation Snapshot', () => {
|
||||
},
|
||||
},
|
||||
security: {
|
||||
enablePermanentToolApproval: true,
|
||||
enablePermanentToolApproval: false,
|
||||
},
|
||||
},
|
||||
}),
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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(
|
||||
<ToolConfirmationMessage
|
||||
callId="test-call-id"
|
||||
@@ -44,6 +42,11 @@ describe('ToolConfirmationMessage Redirection', () => {
|
||||
terminalWidth={100}
|
||||
toolName="shell"
|
||||
/>,
|
||||
{
|
||||
settings: createMockSettings({
|
||||
security: { enablePermanentToolApproval: false },
|
||||
}),
|
||||
},
|
||||
);
|
||||
|
||||
const output = lastFrame();
|
||||
|
||||
@@ -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,
|
||||
|
||||
+1
-1
@@ -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. │
|
||||
|
||||
Reference in New Issue
Block a user