feat(cli): Add --allowed-tools flag to bypass tool confirmation (#2417) (#6453)

This commit is contained in:
Andrew Garrett
2025-08-27 02:17:43 +10:00
committed by GitHub
parent c33a0da1df
commit 52dae2c583
14 changed files with 524 additions and 135 deletions

View File

@@ -70,6 +70,7 @@ export interface CliArgs {
telemetryLogPrompts: boolean | undefined;
telemetryOutfile: string | undefined;
allowedMcpServerNames: string[] | undefined;
allowedTools: string[] | undefined;
experimentalAcp: boolean | undefined;
extensions: string[] | undefined;
listExtensions: boolean | undefined;
@@ -189,6 +190,11 @@ export async function parseArguments(settings: Settings): Promise<CliArgs> {
string: true,
description: 'Allowed MCP server names',
})
.option('allowed-tools', {
type: 'array',
string: true,
description: 'Tools that are allowed to run without confirmation',
})
.option('extensions', {
alias: 'e',
type: 'array',
@@ -489,6 +495,7 @@ export async function loadCliConfig(
question,
fullContext: argv.allFiles || false,
coreTools: settings.coreTools || undefined,
allowedTools: argv.allowedTools || settings.allowedTools || undefined,
excludeTools,
toolDiscoveryCommand: settings.toolDiscoveryCommand,
toolCallCommand: settings.toolCallCommand,

View File

@@ -344,6 +344,16 @@ export const SETTINGS_SCHEMA = {
description: 'Paths to core tool definitions.',
showInDialog: false,
},
allowedTools: {
type: 'array',
label: 'Allowed Tools',
category: 'Advanced',
requiresRestart: true,
default: undefined as string[] | undefined,
description:
'A list of tool names that will bypass the confirmation dialog.',
showInDialog: false,
},
excludeTools: {
type: 'array',
label: 'Exclude Tools',

View File

@@ -53,14 +53,15 @@ const mockToolRegistry = {
const mockConfig = {
getToolRegistry: vi.fn(() => mockToolRegistry as unknown as ToolRegistry),
getApprovalMode: vi.fn(() => ApprovalMode.DEFAULT),
getSessionId: () => 'test-session-id',
getUsageStatisticsEnabled: () => true,
getDebugMode: () => false,
getSessionId: () => 'test-session-id',
getAllowedTools: vi.fn(() => []),
getContentGeneratorConfig: () => ({
model: 'test-model',
authType: 'oauth-personal',
}),
};
} as unknown as Config;
class MockToolInvocation extends BaseToolInvocation<object, ToolResult> {
constructor(
@@ -218,11 +219,6 @@ describe('useReactToolScheduler in YOLO Mode', () => {
await vi.runAllTimersAsync(); // Process execution
});
// Check that shouldConfirmExecute was NOT called
expect(
mockToolRequiresConfirmation.shouldConfirmExecute,
).not.toHaveBeenCalled();
// Check that execute WAS called
expect(mockToolRequiresConfirmation.execute).toHaveBeenCalledWith(
request.args,