mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-04-29 14:34:55 -07:00
chore(shell): Enable interactive shell by default (#10661)
This commit is contained in:
@@ -206,8 +206,8 @@ Settings are organized into categories. All settings should be placed within the
|
|||||||
- **Default:** `undefined`
|
- **Default:** `undefined`
|
||||||
|
|
||||||
- **`tools.shell.enableInteractiveShell`** (boolean):
|
- **`tools.shell.enableInteractiveShell`** (boolean):
|
||||||
|
- **Description:** Enables interactive terminal for running shell commands. If an interactive session cannot be started, it will fall back to a standard shell.
|
||||||
Use `node-pty` for an interactive shell experience. Fallback to `child_process` still applies. Defaults to `false`.
|
- **Default:** `true`
|
||||||
|
|
||||||
- **`tools.core`** (array of strings):
|
- **`tools.core`** (array of strings):
|
||||||
- **Description:** This can be used to restrict the set of built-in tools [with an allowlist](../cli/enterprise.md#restricting-tool-access). See [Built-in Tools](../core/tools-api.md#built-in-tools) for a list of core tools. The match semantics are the same as `tools.allowed`.
|
- **Description:** This can be used to restrict the set of built-in tools [with an allowlist](../cli/enterprise.md#restricting-tool-access). See [Built-in Tools](../core/tools-api.md#built-in-tools) for a list of core tools. The match semantics are the same as `tools.allowed`.
|
||||||
|
|||||||
@@ -737,7 +737,8 @@ export async function loadCliConfig(
|
|||||||
interactive,
|
interactive,
|
||||||
trustedFolder,
|
trustedFolder,
|
||||||
useRipgrep: settings.tools?.useRipgrep,
|
useRipgrep: settings.tools?.useRipgrep,
|
||||||
shouldUseNodePtyShell: settings.tools?.shell?.enableInteractiveShell,
|
enableInteractiveShell:
|
||||||
|
settings.tools?.shell?.enableInteractiveShell ?? true,
|
||||||
skipNextSpeakerCheck: settings.model?.skipNextSpeakerCheck,
|
skipNextSpeakerCheck: settings.model?.skipNextSpeakerCheck,
|
||||||
enablePromptCompletion: settings.general?.enablePromptCompletion ?? false,
|
enablePromptCompletion: settings.general?.enablePromptCompletion ?? false,
|
||||||
truncateToolOutputThreshold: settings.tools?.truncateToolOutputThreshold,
|
truncateToolOutputThreshold: settings.tools?.truncateToolOutputThreshold,
|
||||||
|
|||||||
@@ -110,7 +110,7 @@ const MIGRATION_MAP: Record<string, string> = {
|
|||||||
preferredEditor: 'general.preferredEditor',
|
preferredEditor: 'general.preferredEditor',
|
||||||
sandbox: 'tools.sandbox',
|
sandbox: 'tools.sandbox',
|
||||||
selectedAuthType: 'security.auth.selectedType',
|
selectedAuthType: 'security.auth.selectedType',
|
||||||
shouldUseNodePtyShell: 'tools.shell.enableInteractiveShell',
|
enableInteractiveShell: 'tools.shell.enableInteractiveShell',
|
||||||
shellPager: 'tools.shell.pager',
|
shellPager: 'tools.shell.pager',
|
||||||
shellShowColor: 'tools.shell.showColor',
|
shellShowColor: 'tools.shell.showColor',
|
||||||
skipNextSpeakerCheck: 'model.skipNextSpeakerCheck',
|
skipNextSpeakerCheck: 'model.skipNextSpeakerCheck',
|
||||||
|
|||||||
@@ -713,7 +713,7 @@ const SETTINGS_SCHEMA = {
|
|||||||
label: 'Enable Interactive Shell',
|
label: 'Enable Interactive Shell',
|
||||||
category: 'Tools',
|
category: 'Tools',
|
||||||
requiresRestart: true,
|
requiresRestart: true,
|
||||||
default: false,
|
default: true,
|
||||||
description:
|
description:
|
||||||
'Use node-pty for an interactive shell experience. Fallback to child_process still applies.',
|
'Use node-pty for an interactive shell experience. Fallback to child_process still applies.',
|
||||||
showInDialog: true,
|
showInDialog: true,
|
||||||
|
|||||||
@@ -70,7 +70,7 @@ describe('ShellProcessor', () => {
|
|||||||
mockConfig = {
|
mockConfig = {
|
||||||
getTargetDir: vi.fn().mockReturnValue('/test/dir'),
|
getTargetDir: vi.fn().mockReturnValue('/test/dir'),
|
||||||
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
|
getApprovalMode: vi.fn().mockReturnValue(ApprovalMode.DEFAULT),
|
||||||
getShouldUseNodePtyShell: vi.fn().mockReturnValue(false),
|
getEnableInteractiveShell: vi.fn().mockReturnValue(false),
|
||||||
getShellExecutionConfig: vi.fn().mockReturnValue({}),
|
getShellExecutionConfig: vi.fn().mockReturnValue({}),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -171,7 +171,7 @@ export class ShellProcessor implements IPromptProcessor {
|
|||||||
config.getTargetDir(),
|
config.getTargetDir(),
|
||||||
() => {},
|
() => {},
|
||||||
new AbortController().signal,
|
new AbortController().signal,
|
||||||
config.getShouldUseNodePtyShell(),
|
config.getEnableInteractiveShell(),
|
||||||
shellExecutionConfig,
|
shellExecutionConfig,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -93,7 +93,7 @@ export const ToolMessage: React.FC<ToolMessageProps> = ({
|
|||||||
const isThisShellFocusable =
|
const isThisShellFocusable =
|
||||||
(name === SHELL_COMMAND_NAME || name === 'Shell') &&
|
(name === SHELL_COMMAND_NAME || name === 'Shell') &&
|
||||||
status === ToolCallStatus.Executing &&
|
status === ToolCallStatus.Executing &&
|
||||||
config?.getShouldUseNodePtyShell();
|
config?.getEnableInteractiveShell();
|
||||||
|
|
||||||
const shouldShowFocusHint =
|
const shouldShowFocusHint =
|
||||||
isThisShellFocusable && (showFocusHint || userHasFocused);
|
isThisShellFocusable && (showFocusHint || userHasFocused);
|
||||||
|
|||||||
@@ -65,7 +65,7 @@ describe('useShellCommandProcessor', () => {
|
|||||||
setShellInputFocusedMock = vi.fn();
|
setShellInputFocusedMock = vi.fn();
|
||||||
mockConfig = {
|
mockConfig = {
|
||||||
getTargetDir: () => '/test/dir',
|
getTargetDir: () => '/test/dir',
|
||||||
getShouldUseNodePtyShell: () => false,
|
getEnableInteractiveShell: () => false,
|
||||||
getShellExecutionConfig: () => ({
|
getShellExecutionConfig: () => ({
|
||||||
terminalHeight: 20,
|
terminalHeight: 20,
|
||||||
terminalWidth: 80,
|
terminalWidth: 80,
|
||||||
|
|||||||
@@ -160,7 +160,7 @@ export const useShellCommandProcessor = (
|
|||||||
if (isBinaryStream) break;
|
if (isBinaryStream) break;
|
||||||
// PTY provides the full screen state, so we just replace.
|
// PTY provides the full screen state, so we just replace.
|
||||||
// Child process provides chunks, so we append.
|
// Child process provides chunks, so we append.
|
||||||
if (config.getShouldUseNodePtyShell()) {
|
if (config.getEnableInteractiveShell()) {
|
||||||
cumulativeStdout = event.chunk;
|
cumulativeStdout = event.chunk;
|
||||||
shouldUpdate = true;
|
shouldUpdate = true;
|
||||||
} else if (
|
} else if (
|
||||||
@@ -221,7 +221,7 @@ export const useShellCommandProcessor = (
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
abortSignal,
|
abortSignal,
|
||||||
config.getShouldUseNodePtyShell(),
|
config.getEnableInteractiveShell(),
|
||||||
shellExecutionConfig,
|
shellExecutionConfig,
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
@@ -253,7 +253,7 @@ export interface ConfigParameters {
|
|||||||
interactive?: boolean;
|
interactive?: boolean;
|
||||||
trustedFolder?: boolean;
|
trustedFolder?: boolean;
|
||||||
useRipgrep?: boolean;
|
useRipgrep?: boolean;
|
||||||
shouldUseNodePtyShell?: boolean;
|
enableInteractiveShell?: boolean;
|
||||||
skipNextSpeakerCheck?: boolean;
|
skipNextSpeakerCheck?: boolean;
|
||||||
shellExecutionConfig?: ShellExecutionConfig;
|
shellExecutionConfig?: ShellExecutionConfig;
|
||||||
extensionManagement?: boolean;
|
extensionManagement?: boolean;
|
||||||
@@ -342,7 +342,7 @@ export class Config {
|
|||||||
private readonly interactive: boolean;
|
private readonly interactive: boolean;
|
||||||
private readonly trustedFolder: boolean | undefined;
|
private readonly trustedFolder: boolean | undefined;
|
||||||
private readonly useRipgrep: boolean;
|
private readonly useRipgrep: boolean;
|
||||||
private readonly shouldUseNodePtyShell: boolean;
|
private readonly enableInteractiveShell: boolean;
|
||||||
private readonly skipNextSpeakerCheck: boolean;
|
private readonly skipNextSpeakerCheck: boolean;
|
||||||
private shellExecutionConfig: ShellExecutionConfig;
|
private shellExecutionConfig: ShellExecutionConfig;
|
||||||
private readonly extensionManagement: boolean = true;
|
private readonly extensionManagement: boolean = true;
|
||||||
@@ -432,7 +432,7 @@ export class Config {
|
|||||||
this.interactive = params.interactive ?? false;
|
this.interactive = params.interactive ?? false;
|
||||||
this.trustedFolder = params.trustedFolder;
|
this.trustedFolder = params.trustedFolder;
|
||||||
this.useRipgrep = params.useRipgrep ?? true;
|
this.useRipgrep = params.useRipgrep ?? true;
|
||||||
this.shouldUseNodePtyShell = params.shouldUseNodePtyShell ?? false;
|
this.enableInteractiveShell = params.enableInteractiveShell ?? false;
|
||||||
this.skipNextSpeakerCheck = params.skipNextSpeakerCheck ?? true;
|
this.skipNextSpeakerCheck = params.skipNextSpeakerCheck ?? true;
|
||||||
this.shellExecutionConfig = {
|
this.shellExecutionConfig = {
|
||||||
terminalWidth: params.shellExecutionConfig?.terminalWidth ?? 80,
|
terminalWidth: params.shellExecutionConfig?.terminalWidth ?? 80,
|
||||||
@@ -942,8 +942,8 @@ export class Config {
|
|||||||
return this.useRipgrep;
|
return this.useRipgrep;
|
||||||
}
|
}
|
||||||
|
|
||||||
getShouldUseNodePtyShell(): boolean {
|
getEnableInteractiveShell(): boolean {
|
||||||
return this.shouldUseNodePtyShell;
|
return this.enableInteractiveShell;
|
||||||
}
|
}
|
||||||
|
|
||||||
getSkipNextSpeakerCheck(): boolean {
|
getSkipNextSpeakerCheck(): boolean {
|
||||||
|
|||||||
@@ -60,7 +60,7 @@ describe('ShellTool', () => {
|
|||||||
.fn()
|
.fn()
|
||||||
.mockReturnValue(createMockWorkspaceContext('/test/dir')),
|
.mockReturnValue(createMockWorkspaceContext('/test/dir')),
|
||||||
getGeminiClient: vi.fn(),
|
getGeminiClient: vi.fn(),
|
||||||
getShouldUseNodePtyShell: vi.fn().mockReturnValue(false),
|
getEnableInteractiveShell: vi.fn().mockReturnValue(false),
|
||||||
isInteractive: vi.fn().mockReturnValue(true),
|
isInteractive: vi.fn().mockReturnValue(true),
|
||||||
} as unknown as Config;
|
} as unknown as Config;
|
||||||
|
|
||||||
|
|||||||
@@ -251,7 +251,7 @@ export class ShellToolInvocation extends BaseToolInvocation<
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
signal,
|
signal,
|
||||||
this.config.getShouldUseNodePtyShell(),
|
this.config.getEnableInteractiveShell(),
|
||||||
shellExecutionConfig ?? {},
|
shellExecutionConfig ?? {},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user