feat(tui): add bang shell command shortcut#1661
Conversation
Add composer support for `! <command>` to run user-initiated shell commands through the existing shell tool path. The shortcut reuses approval, sandbox, command safety, hooks, and tool-card rendering without exposing shell tools to the model when shell access is disabled. Empty bang input reports usage, and Plan mode remains blocked. Add tests for parsing, UI dispatch, approval, execution, and Plan mode blocking.
There was a problem hiding this comment.
Code Review
This pull request introduces a new ! <command> shortcut in the composer, allowing users to execute shell commands directly through the application's tool execution framework. The implementation adds a RunShellCommand operation to the engine, which handles turn management, snapshots, and approval workflows. Corresponding UI logic was added to parse the "bang" input and route it to the engine without creating a model turn. Review feedback suggests ensuring that the approval logic correctly respects the auto_approve flag (e.g., for YOLO mode) and improving the robustness of the input parsing logic to handle multiple spaces.
| "Tool 'exec_shell' is disabled by feature flag".to_string(), | ||
| )) | ||
| } else if let Some(spec) = registry.get(&tool_name) { | ||
| let approval_required = spec.approval_requirement() != ApprovalRequirement::Auto; |
There was a problem hiding this comment.
The approval check for bang commands should respect the auto_approve flag (e.g., when in YOLO mode). Currently, it only checks the tool's static requirement, which means users will still be prompted for approval even in YOLO mode for ! <command> shortcuts. This logic should be updated to check tool_context.auto_approve.
| let approval_required = spec.approval_requirement() != ApprovalRequirement::Auto; | |
| let approval_required = spec.approval_requirement() != ApprovalRequirement::Auto && !tool_context.auto_approve; |
| let command = rest | ||
| .strip_prefix(|c: char| c.is_whitespace()) | ||
| .unwrap_or(rest); | ||
| if command.trim().is_empty() { | ||
| return Err("Usage: ! <shell command>"); | ||
| } |
There was a problem hiding this comment.
The current logic only strips a single leading whitespace character after the ! prefix. If a user types multiple spaces (e.g., ! ls), the resulting command will still have leading whitespace. Using trim() on the remainder is more robust and simplifies the empty check.
let command = rest.trim();
if command.is_empty() {
return Err("Usage: ! <shell command>");
}|
This PR was opened before the v0.8.41 rebrand and is now stale. Feel free to rebase onto current |
Summary
Closes #1546.
Adds composer support for
! <command>so users can run an explicit shell command directly from the input box.The shortcut routes through the existing shell execution path, so it keeps the same approval flow, sandbox policy, command safety checks, hooks, audit events, and tool-card output. It does not turn on model-visible shell access when shell tools are otherwise disabled for the model.
Also handles empty
!input with a usage message and keeps Plan mode shell execution blocked.Testing
cargo test --all-featurescargo fmt --all -- --checkcargo clippy --all-targets --all-featuresChecklist