Skip to content

Commit e7f8d9c

Browse files
committed
Revert "feat: Introduce an AI-driven interactive shell mode with new"
This reverts commit 651ad63.
1 parent 651ad63 commit e7f8d9c

22 files changed

+82
-905
lines changed

packages/cli/src/config/config.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1009,7 +1009,6 @@ export async function loadCliConfig(
10091009
enableInteractiveShell: settings.tools?.shell?.enableInteractiveShell,
10101010
shellBackgroundCompletionBehavior: settings.tools?.shell
10111011
?.backgroundCompletionBehavior as string | undefined,
1012-
interactiveShellMode: settings.tools?.shell?.interactiveShellMode,
10131012
shellToolInactivityTimeout: settings.tools?.shell?.inactivityTimeout,
10141013
enableShellOutputEfficiency:
10151014
settings.tools?.shell?.enableShellOutputEfficiency ?? true,

packages/cli/src/config/settingsSchema.ts

Lines changed: 0 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1512,26 +1512,6 @@ const SETTINGS_SCHEMA = {
15121512
{ label: 'Notify', value: 'notify' },
15131513
],
15141514
},
1515-
interactiveShellMode: {
1516-
type: 'enum',
1517-
label: 'Interactive Shell Mode',
1518-
category: 'Tools',
1519-
requiresRestart: true,
1520-
default: undefined as 'human' | 'ai' | 'off' | undefined,
1521-
description: oneLine`
1522-
Controls who can interact with backgrounded shell processes.
1523-
"human": user can Tab-focus and type into shells (default).
1524-
"ai": model gets write_to_shell/read_shell tools for TUI interaction.
1525-
"off": no interactive shell.
1526-
When set, overrides enableInteractiveShell.
1527-
`,
1528-
showInDialog: true,
1529-
options: [
1530-
{ value: 'human', label: 'Human (Tab to focus)' },
1531-
{ value: 'ai', label: 'AI (model-driven tools)' },
1532-
{ value: 'off', label: 'Off' },
1533-
],
1534-
},
15351515
pager: {
15361516
type: 'string',
15371517
label: 'Pager',

packages/cli/src/ui/hooks/shellReducer.ts

Lines changed: 1 addition & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -92,23 +92,7 @@ export function shellReducer(
9292
nextTasks.delete(action.pid);
9393
}
9494
nextTasks.set(action.pid, updatedTask);
95-
96-
// Auto-hide panel when all tasks have exited
97-
let nextVisible = state.isBackgroundTaskVisible;
98-
if (action.update.status === 'exited') {
99-
const hasRunning = Array.from(nextTasks.values()).some(
100-
(s) => s.status === 'running',
101-
);
102-
if (!hasRunning) {
103-
nextVisible = false;
104-
}
105-
}
106-
107-
return {
108-
...state,
109-
backgroundTasks: nextTasks,
110-
isBackgroundTaskVisible: nextVisible,
111-
};
95+
return { ...state, backgroundTasks: nextTasks };
11296
}
11397
case 'APPEND_TASK_OUTPUT': {
11498
const task = state.backgroundTasks.get(action.pid);

packages/cli/src/ui/hooks/useBackgroundShellManager.ts

Lines changed: 0 additions & 101 deletions
This file was deleted.

packages/cli/src/ui/hooks/useExecutionLifecycle.ts

Lines changed: 0 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -661,18 +661,13 @@ export const useExecutionLifecycle = (
661661
(s: BackgroundTask) => s.status === 'running',
662662
).length;
663663

664-
const showBackgroundShell = useCallback(() => {
665-
dispatch({ type: 'SET_VISIBILITY', visible: true });
666-
}, [dispatch]);
667-
668664
return {
669665
handleShellCommand,
670666
activeShellPtyId: state.activeShellPtyId,
671667
lastShellOutputTime: state.lastShellOutputTime,
672668
backgroundTaskCount,
673669
isBackgroundTaskVisible: state.isBackgroundTaskVisible,
674670
toggleBackgroundTasks,
675-
showBackgroundShell,
676671
backgroundCurrentExecution,
677672
registerBackgroundTask,
678673
dismissBackgroundTask,

packages/cli/src/ui/hooks/useGeminiStream.ts

Lines changed: 0 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -390,7 +390,6 @@ export const useGeminiStream = (
390390
backgroundTaskCount,
391391
isBackgroundTaskVisible,
392392
toggleBackgroundTasks,
393-
showBackgroundShell,
394393
backgroundCurrentExecution,
395394
registerBackgroundTask,
396395
dismissBackgroundTask,
@@ -1918,7 +1917,6 @@ export const useGeminiStream = (
19181917
backgroundedTool.command,
19191918
backgroundedTool.initialOutput,
19201919
);
1921-
showBackgroundShell();
19221920
}
19231921
}
19241922

@@ -2058,7 +2056,6 @@ export const useGeminiStream = (
20582056
modelSwitchedFromQuotaError,
20592057
addItem,
20602058
registerBackgroundTask,
2061-
showBackgroundShell,
20622059
consumeUserHint,
20632060
isLowErrorVerbosity,
20642061
maybeAddSuppressedToolErrorNote,

packages/core/src/config/config.ts

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -36,8 +36,6 @@ import { GlobTool } from '../tools/glob.js';
3636
import { ActivateSkillTool } from '../tools/activate-skill.js';
3737
import { EditTool } from '../tools/edit.js';
3838
import { ShellTool } from '../tools/shell.js';
39-
import { WriteToShellTool } from '../tools/write-to-shell.js';
40-
import { ReadShellTool } from '../tools/read-shell.js';
4139
import { WriteFileTool } from '../tools/write-file.js';
4240
import { WebFetchTool } from '../tools/web-fetch.js';
4341
import { MemoryTool, setGeminiMdFilename } from '../tools/memoryTool.js';
@@ -658,7 +656,6 @@ export interface ConfigParameters {
658656
useRipgrep?: boolean;
659657
enableInteractiveShell?: boolean;
660658
shellBackgroundCompletionBehavior?: string;
661-
interactiveShellMode?: 'human' | 'ai' | 'off';
662659
skipNextSpeakerCheck?: boolean;
663660
shellExecutionConfig?: ShellExecutionConfig;
664661
extensionManagement?: boolean;
@@ -871,7 +868,6 @@ export class Config implements McpContext, AgentLoopContext {
871868
| 'inject'
872869
| 'notify'
873870
| 'silent';
874-
private readonly interactiveShellMode: 'human' | 'ai' | 'off';
875871
private readonly skipNextSpeakerCheck: boolean;
876872
private readonly useBackgroundColor: boolean;
877873
private readonly useAlternateBuffer: boolean;
@@ -1239,14 +1235,6 @@ export class Config implements McpContext, AgentLoopContext {
12391235
this.shellBackgroundCompletionBehavior = 'silent';
12401236
}
12411237

1242-
// interactiveShellMode takes precedence over enableInteractiveShell.
1243-
// If not set, derive from enableInteractiveShell for backward compat.
1244-
if (params.interactiveShellMode) {
1245-
this.interactiveShellMode = params.interactiveShellMode;
1246-
} else {
1247-
this.interactiveShellMode = this.enableInteractiveShell ? 'human' : 'off';
1248-
}
1249-
12501238
this.skipNextSpeakerCheck = params.skipNextSpeakerCheck ?? true;
12511239
this.shellExecutionConfig = {
12521240
terminalWidth: params.shellExecutionConfig?.terminalWidth ?? 80,
@@ -3223,14 +3211,10 @@ export class Config implements McpContext, AgentLoopContext {
32233211
return (
32243212
this.interactive &&
32253213
this.ptyInfo !== 'child_process' &&
3226-
this.interactiveShellMode !== 'off'
3214+
this.enableInteractiveShell
32273215
);
32283216
}
32293217

3230-
getInteractiveShellMode(): 'human' | 'ai' | 'off' {
3231-
return this.interactiveShellMode;
3232-
}
3233-
32343218
isSkillsSupportEnabled(): boolean {
32353219
return this.skillsSupport;
32363220
}
@@ -3591,15 +3575,6 @@ export class Config implements McpContext, AgentLoopContext {
35913575
new ReadBackgroundOutputTool(this, this.messageBus),
35923576
),
35933577
);
3594-
// Register AI-driven interactive shell tools when mode is 'ai'
3595-
if (this.getInteractiveShellMode() === 'ai') {
3596-
maybeRegister(WriteToShellTool, () =>
3597-
registry.registerTool(new WriteToShellTool(this.messageBus)),
3598-
);
3599-
maybeRegister(ReadShellTool, () =>
3600-
registry.registerTool(new ReadShellTool(this.messageBus)),
3601-
);
3602-
}
36033578
if (!this.isMemoryManagerEnabled()) {
36043579
maybeRegister(MemoryTool, () =>
36053580
registry.registerTool(new MemoryTool(this.messageBus, this.storage)),

packages/core/src/prompts/promptProvider.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -200,7 +200,6 @@ export class PromptProvider {
200200
enableShellEfficiency:
201201
context.config.getEnableShellOutputEfficiency(),
202202
interactiveShellEnabled: context.config.isInteractiveShellEnabled(),
203-
interactiveShellMode: context.config.getInteractiveShellMode(),
204203
topicUpdateNarration:
205204
context.config.isTopicUpdateNarrationEnabled(),
206205
memoryManagerEnabled: context.config.isMemoryManagerEnabled(),

packages/core/src/prompts/snippets.ts

Lines changed: 1 addition & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,6 @@ import {
1818
MEMORY_TOOL_NAME,
1919
READ_FILE_TOOL_NAME,
2020
SHELL_TOOL_NAME,
21-
WRITE_TO_SHELL_TOOL_NAME,
22-
READ_SHELL_TOOL_NAME,
2321
WRITE_FILE_TOOL_NAME,
2422
WRITE_TODOS_TOOL_NAME,
2523
GREP_PARAM_TOTAL_MAX_MATCHES,
@@ -83,7 +81,6 @@ export interface PrimaryWorkflowsOptions {
8381
export interface OperationalGuidelinesOptions {
8482
interactive: boolean;
8583
interactiveShellEnabled: boolean;
86-
interactiveShellMode?: 'human' | 'ai' | 'off';
8784
topicUpdateNarration: boolean;
8885
memoryManagerEnabled: boolean;
8986
}
@@ -394,7 +391,7 @@ export function renderOperationalGuidelines(
394391
- **Command Execution:** Use the ${formatToolName(SHELL_TOOL_NAME)} tool for running shell commands, remembering the safety rule to explain modifying commands first.${toolUsageInteractive(
395392
options.interactive,
396393
options.interactiveShellEnabled,
397-
)}${toolUsageRememberingFacts(options)}${toolUsageAiShell(options)}
394+
)}${toolUsageRememberingFacts(options)}
398395
- **Confirmation Protocol:** If a tool call is declined or cancelled, respect the decision immediately. Do not re-attempt the action or "negotiate" for the same tool call unless the user explicitly directs you to. Offer an alternative technical path if possible.
399396
400397
## Interaction Details
@@ -803,17 +800,6 @@ function toolUsageInteractive(
803800
- **Interactive Commands:** Always prefer non-interactive commands (e.g., using 'run once' or 'CI' flags for test runners to avoid persistent watch modes or 'git --no-pager') unless a persistent process is specifically required; however, some commands are only interactive and expect user input during their execution (e.g. ssh, vim).`;
804801
}
805802

806-
function toolUsageAiShell(options: OperationalGuidelinesOptions): string {
807-
if (options.interactiveShellMode !== 'ai') return '';
808-
return `
809-
- **AI-Driven Interactive Shell:** Commands using \`wait_for_output_seconds\` auto-promote to background when they stall. Once promoted, use ${formatToolName(READ_SHELL_TOOL_NAME)} to see the terminal screen, then ${formatToolName(WRITE_TO_SHELL_TOOL_NAME)} to send text input and/or special keys (arrows, Enter, Ctrl-C, etc.).
810-
- Set \`wait_for_output_seconds\` **low (2-5)** for commands that prompt for input (npx, installers, REPLs). Set **high (60+)** for long builds. Omit for instant commands.
811-
- **Always read the screen before writing input.** The screen state tells you what the process is waiting for.
812-
- When waiting for a command to finish (e.g. npm install), use ${formatToolName(READ_SHELL_TOOL_NAME)} with \`wait_seconds\` to delay before reading. Do NOT poll in a tight loop.
813-
- **Clean up when done:** when your task is complete, kill background processes with ${formatToolName(WRITE_TO_SHELL_TOOL_NAME)} sending Ctrl-C, or note the PID for the user to clean up.
814-
- You are the sole operator of promoted shells — the user cannot type into them.`;
815-
}
816-
817803
function toolUsageRememberingFacts(
818804
options: OperationalGuidelinesOptions,
819805
): string {

0 commit comments

Comments
 (0)