@@ -30,6 +30,13 @@ class BashTool(BaseTool):
3030
3131 async def execute (self , arguments : BashToolInput , context : ToolExecutionContext ) -> ToolResult :
3232 cwd = Path (arguments .cwd ).expanduser () if arguments .cwd else context .cwd
33+ preflight_error = _preflight_interactive_command (arguments .command )
34+ if preflight_error is not None :
35+ return ToolResult (
36+ output = preflight_error ,
37+ is_error = True ,
38+ metadata = {"interactive_required" : True },
39+ )
3340 process : asyncio .subprocess .Process | None = None
3441 try :
3542 process = await create_shell_subprocess (
@@ -134,6 +141,18 @@ def _format_timeout_output(output_buffer: bytearray, *, command: str, timeout_se
134141 return "\n " .join (parts )
135142
136143
144+ def _preflight_interactive_command (command : str ) -> str | None :
145+ lowered_command = command .lower ()
146+ if not _looks_like_interactive_scaffold (lowered_command ):
147+ return None
148+ return (
149+ "This command appears to require interactive input before it can continue. "
150+ "The bash tool is non-interactive, so it cannot answer installer/scaffold prompts live. "
151+ "Prefer non-interactive flags (for example --yes, -y, --skip-install, --defaults, --non-interactive), "
152+ "or run the scaffolding step once in an external terminal before asking the agent to continue."
153+ )
154+
155+
137156def _interactive_command_hint (* , command : str , output : str ) -> str | None :
138157 lowered_command = command .lower ()
139158 if _looks_like_interactive_scaffold (lowered_command ) or _looks_like_prompt (output ):
0 commit comments