[FEATURE] Add Interactive Shell Support to the Bash Tool via Pseudo-Terminal (PTY)

Open 💬 14 comments Opened Oct 19, 2025 by coygeek

Preflight Checklist

  • [x] I have searched existing requests and this feature hasn't been requested yet
  • [x] This is a single feature request (not multiple features)

Problem Statement

Currently, the Claude Code Bash tool is incredibly powerful for executing non-interactive, stateless commands (ls, grep, cat, etc.). However, its capabilities are limited when a command requires real-time user interaction.

If a user asks Claude to run a command that spawns an interactive session—such as vim file.js, git rebase -i HEAD~3, npm init, or an interactive REPL like python—the Claude Code session will hang, wait for a timeout, or fail.

This forces the user to break their workflow:

  1. Exit or switch away from the Claude Code session.
  2. Open a separate terminal to run the interactive command.
  3. Complete the task.
  4. Return to Claude Code and manually provide context about what just happened.

This process is inefficient and, more importantly, it removes the interactive task from Claude's context. Claude has no awareness of the changes made in vim or the decisions made during a git rebase, limiting its ability to provide continuous, context-aware assistance.

Proposed Solution

I propose enhancing the Bash tool to support fully interactive shell commands by integrating a pseudo-terminal (PTY). This would allow Claude Code to spawn and manage interactive subprocesses, rendering their UI directly within the Claude Code REPL.

Ideal User Experience:

  1. A user prompts Claude: > open src/app.ts in vim so I can make a quick edit.
  2. Claude executes the tool call: Bash(command="vim src/app.ts").
  3. The Claude Code REPL interface is temporarily replaced by a live, interactive vim session. The user sees the file content and can edit it using standard vim commands.
  4. To ensure user input is correctly routed, a keybinding (e.g., Ctrl+F as used in Gemini CLI) could be used to "focus" the interactive terminal session. This would direct all subsequent keystrokes to the vim process instead of the Claude Code prompt.
  5. When the user saves and exits vim (e.g., with :wq), the interactive session terminates.
  6. The user is returned to the standard Claude Code prompt.
  7. Claude receives a ToolResult from the Bash tool indicating that the command completed successfully (e.g., exitCode: 0). Claude is now aware the file was edited and can proceed with the next step, like running tests.

This approach would leverage a library like node-pty to serialize the terminal state (text, colors, cursor position) and stream it to the user, creating a seamless, two-way interactive experience.

Alternative Solutions

  • Current Workaround: The only current workaround is to perform interactive tasks in a separate terminal. The major drawback is the complete loss of context for Claude, which defeats the purpose of an integrated agentic workflow.
  • Agent-Only Edits: One could argue that users should instruct Claude to perform all edits programmatically (e.g., using the Edit tool or sed). While viable for simple changes, this is clunky and inefficient for complex refactoring, multi-line edits, or tasks that are simply faster with a real editor. It also fails to solve the problem for other interactive tools like git rebase -i, htop, or setup scripts.

Priority

Critical - Blocking my work

Feature Category

CLI commands and flags

Use Case Example

A developer is working on a new feature and has made several small, messy commits. They want to clean up their git history before opening a pull request.

  1. User Prompt: > I need to clean up my last 3 commits. Start an interactive git rebase for me.
  2. Claude Action: Claude understands the request and executes Bash(command="git rebase -i HEAD~3").
  3. Interactive Session: The Claude Code REPL transitions into the editor defined by the user's git configuration (e.g., vim or nano). It displays the list of commits for the rebase.
  4. User Interaction: The user directly edits the text, changing pick to squash for two of the commits. They save and exit the editor.
  5. Context Preservation: The user is returned to the Claude Code prompt. Claude receives the output from the git command (e.g., "Successfully rebased and updated HEAD.").
  6. Next Step: The user can now say, > Great. Now push the changes to a new branch and create a PR. Claude has the full context that the rebase occurred and can proceed correctly.

Additional Context

  • Precedent: This feature was recently introduced in the Google Gemini CLI (v0.9.0) and has proven to be a major enhancement for their shell integration. Their implementation demonstrates the technical feasibility and value of this approach.
  • Reference: Google Developers Blog Post on Interactive Shell
  • Technical Considerations:
  • This would likely require the node-pty library or a similar PTY solution.
  • The terminal renderer would need to be updated to handle complex terminal UI escape codes for color and cursor positioning.
  • A clear mechanism for focusing/unfocusing the interactive session is crucial to manage user input.
  • This feature should integrate with Claude Code's existing permission system. A request to run vim would still be a Bash tool call that requires user approval, but once approved, the session becomes fully interactive.

View original on GitHub ↗

This issue has 14 comments on GitHub. Read the full discussion on GitHub ↗