Skip to content

[Feature]: Run ! shell commands in structured Claude chats, as the TUI does #32165

Description

@jun-planfit

Problem or use case

In a Claude Code chat that runs as a structured chat (Claude launched with --input-format stream-json --output-format stream-json), a !-prefixed line does not run as a shell command. The composer sends !pwd as an ordinary prompt, and the model answers it in prose. Running the command takes a full model turn, and the result depends on the model choosing to call its Bash tool.

The same line does run in a terminal-backed chat, because the composer types it into the Claude TUI and the TUI's bash mode runs it (see #25956, fixed by #31204). So ! works or silently doesn't depending on which kind of chat the user opened, and the composer gives no hint which one it is.

Reproduction outside Orca (Claude Code 2.1.304):

printf '%s\n' '{"type":"user","message":{"role":"user","content":"!pwd"}}' \
  | claude -p --input-format stream-json --output-format stream-json --verbose --max-turns 1

No <bash-input> turn is recorded. The assistant replies with the working directory it read from its system context and says it did not run a shell.

On main (77f1523), classifyNativeChatSend in src/shared/native-chat-slash-commands.ts special-cases only / (and $ for Codex), and the structured send path has no ! handling either. src/shared/claude-bash-input.ts only displays <bash-input> turns that already exist in a transcript.

Orca 1.4.237, macOS.

Proposed solution

Support ! in structured Claude chats the way the TUI does:

  1. When a structured Claude chat's draft starts with !, Orca runs the rest of the line itself in the chat's cwd, using the shell environment structured chats already use (feat(native-chat): one shell-environment setting for every structured chat #22387), instead of sending it to the agent.
  2. The chat shows the command and its stdout/stderr as a command row.
  3. Orca passes the command and its output to the agent with the next message, in the same shape the TUI records (<bash-input> plus <bash-stdout>/<bash-stderr>), so the agent sees it as context without spending a turn on it.

If this is out of scope, a smaller step would help: when a structured chat's draft starts with !, show a hint that bash mode is only available in terminal-backed chats.

Alternatives or additional context

Workarounds today: open the conversation in a terminal tab and use the TUI's !, or ask the agent to run the command and wait for a turn.

Activity

  1. Tauri-EPO commented on Nov 1, 2026

    @Tauri-EPO
    Contributor

    Reproduced on Windows 11, Orca 1.4.245, Claude Code 2.1.316, in a structured Claude chat (3/3 attempts: !echo oi > teste.txt, !pwd, !echo oi > teste2.txt). Each line reached the agent as a plain prompt; neither file was created in the chat's cwd. Nothing in the composer signals that ! is not bash mode here, so the line reads as a normal message — and an agent that chooses to act on it would run the command through its own tool instead, which hides the gap. A composer hint when the draft starts with ! (the smaller step proposed above) would make the difference visible in both chat kinds.

  2. Rudamentary99 commented on Nov 5, 2026

    @Rudamentary99

    This would be really helpful!

    also the "split terminal right" shortcut opens a chat instead of a terminal when using the chat ui

  3. RonanCodes commented on Nov 6, 2026

    @RonanCodes

    +1 on this, I hit it today.

    My use case: an agent hands me a one-liner to finish a step (here pbcopy < "<draft file>" to copy a Slack draft), and I type ! <command> in the same chat. In a structured Claude chat it goes to the model as a prompt instead of running, so I switch to a terminal for a two-second command.

    I also checked whether a plugin could cover it in the meantime: with plugin API 1 there is no hook on the chat composer, and the only shell access is terminal.sendText into a terminal pane, with no way to read the output back. So it needs Orca itself.

    Related: #25956 (the ! message pinned at the bottom in terminal-backed chats).

    Thanks!

  4. RonanCodes commented on Nov 9, 2026

    @RonanCodes

    I opened #40432 for this. In a structured chat, a draft that starts with ! now opens a new terminal tab in the chat's workspace and runs the command there. Nothing is sent to the agent, and the output stays in the terminal tab rather than the transcript.

    Structured chat composer with a ! command

    The command running in a new terminal tab beside the chat

    Until something like that lands, I'm using a small plugin as a workaround: RonanCodes/orca-run-command. It's a sidebar panel with one input line that types the command into an open shell terminal of the workspace (terminal.sendText), and it keeps a history of commands only, never their output. It can't hook the chat box itself.

    The Run Command plugin panel

    🤖 Posted on behalf of Ronan by Claude.

  5. ianfelix commented on Nov 10, 2026

    @ianfelix

    I opened #40620 as another take on this: it runs ! inline in the structured chat with a result card (live output, Stop, and an opt-in "Add to chat" to share the output with the agent). #40432 takes the terminal-tab route. I think they could work together, and I'm happy to follow whichever direction the maintainers prefer. Thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions