Skip to content

feat(agent-input): !-prefix bash command mode - #1414

Open
chphch wants to merge 1 commit into
slopus:mainfrom
chphch:feat/bash-input-mode
Open

chphch wants to merge 1 commit into
slopus:mainfrom
chphch:feat/bash-input-mode

Conversation

@chphch

@chphch chphch commented Jun 19, 2026 •

Copy link
Copy Markdown
Contributor

Adds a !-prefix bash command mode to the chat input, mirroring the Claude Code CLI: a message that starts with ! runs as a one-off shell command in the session's working directory instead of being sent to the agent, and its output renders inline. It's per-message only — there's no persistent mode toggle. The command runs over the existing session-scoped bash RPC (the same handler that powers directory autocomplete and Windows cmd support), so it executes in and is sandboxed to the session cwd; the echoed command and its output are injected as local-only messages (no server round-trip, the agent is never involved), with output shown in a fenced code block.

Proof

Captured locally via a standalone happy-server (PGlite) + Expo web + a paired happy-cli daemon, authenticated through the getDevWebQueryCredentials() dev URL bypass and driven headlessly with Playwright (live e2e — real daemon, real session). Typing !pwd and !echo BASHMODE_OK_4242 runs each as a shell command and renders the output in a sh code block; the agent is never invoked.

!-bash mode running pwd and echo in a real session

Verification: tsc --noEmit clean, and the new strings are added to all 10 locale files. No new message kind and no reducer changes — the output reuses the existing agent-text markdown rendering.

Related: addresses #568 (run shell commands from mobile without burning tokens). #597 proposes the same capability with a $ prefix; this uses ! to mirror the Claude Code CLI's bash mode.

@chphch
chphch force-pushed the feat/bash-input-mode branch from 3de11ab to 9407dbe Compare July 5, 2026 13:15
@chphch

chphch commented Aug 6, 2026

Copy link
Copy Markdown
Contributor Author

Flagging an overlap so you don't have to work it out: #597 (@hztBUAA, opened 2026-02-13) answers the same request (#568) from the other side of the wire, and both PRs are sitting open. Here is the difference as I read it — I have no stake in which one lands.

#597 — CLI-side #1414 — app-side (this one)
Where the command runs new execAsync in runClaude.ts, intercepted in specialCommands.ts before Claude sees the message the session bash RPC that already exists (registerCommonHandlers.ts:176)
Size 2 files, +133/-4 5 source files (~100 lines) + the subtitle in 11 locales
Reaches every client, since the interception is in the CLI only where the app runs it
Ships via a CLI release an app build / OTA
Flag always on expBashMode, off by default
Prefixes $ and ! $ and ! (just matched yours in 6d90e3b)
The output goes through the session, so it persists and reaches your other devices local-only messages — deliberately never sent, so it does not reach your other devices

Two honest notes, one each way:

The sharpest user-visible difference is the last row of the table: my output never leaves the device, which is what keeps it cheap, but it also means the command you ran isn't there when you pick the session up somewhere else. #597 doesn't have that gap.

Say the word and I'll close this in favour of #597 — no explanation needed.

@chphch
chphch force-pushed the feat/bash-input-mode branch from 4cf9f10 to 1397478 Compare August 6, 2026 06:26
@chphch
chphch force-pushed the feat/bash-input-mode branch 5 times, most recently from 1aa8809 to 4140900 Compare August 28, 2026 00:25
Type a message starting with `!` to run it as a one-off shell command in the
session's working directory instead of sending it to the agent — mirrors the
Claude Code CLI's `!` bash mode. Per-message only, no persistent toggle.

The command runs via the session-scoped `bash` RPC (the same handler that
powers directory autocomplete), so it executes in and is sandboxed to the
session cwd. The echoed command and its output are injected as local-only
messages (no server round-trip), rendering the output in a fenced code block.

Generated with [Claude Code](https://claude.ai/code)
via [Happy](https://happy.engineering)

Co-Authored-By: Claude <noreply@anthropic.com>
Co-Authored-By: Happy <yesreply@happy.engineering>
@chphch
chphch force-pushed the feat/bash-input-mode branch from 4140900 to 799abe6 Compare September 22, 2026 01:22

This branch has not been deployed

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

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant