feat: add shell mode (!) to the CLI#1079
Conversation
Add shell mode, letting users run shell commands directly from the prompt with `!`. Output streams live into the transcript, supports backgrounding (ctrl+b), cancellation (Esc / Ctrl+C), input queuing while running, and enters the conversation context with resume support.
🦋 Changeset detectedLatest commit: 94bc5b5 The changes in this PR will be included in the next version bump. This PR includes changesets to release 1 package
Not sure what this means? Click here to learn what changesets are. Click here if you're a maintainer who wants to add another changeset to this PR |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 94bc5b54fc
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| } | ||
| }, | ||
| }); | ||
| isError = result.isError === true; |
There was a problem hiding this comment.
Preserve synthetic Bash failures in shell output
When the Bash tool reports an error via its returned result.output instead of stdout/stderr chunks, stdout and stderr remain empty because only onUpdate mutates them. For inputs like ! false, spawn failures, timeouts, or user interrupts with no process output, this records isError but then appends/returns empty buffers, so the TUI and replay show (no output) instead of the failure reason; fold the string result.output into the displayed/recorded stderr when an error has no captured chunks.
Useful? React with 👍 / 👎.
| // Enter bash mode: typing `!` at the start of an empty prompt. The `!` is | ||
| // not inserted into the buffer — it becomes the mode + prompt symbol, so the | ||
| // cursor never has to skip over it and submit never has to strip it. | ||
| if (this.inputMode === 'prompt' && normalized === '!' && this.getText().length === 0) { |
There was a problem hiding this comment.
Decode
! before entering shell mode
In terminals that send printable keys as CSI-u sequences (the local apps/kimi-code/AGENTS.md calls out VSCode/Kitty mode), pressing ! arrives as something like \x1b[33u, so this raw printable comparison never matches and shell mode cannot be entered; decode with printableChar(...) before comparing so the new ! shortcut works in those terminals.
Useful? React with 👍 / 👎.
Related Issue
No related issue — this implements the shell mode feature that was planned and discussed beforehand.
Problem
Users need a way to run shell commands directly from the Kimi Code prompt without leaving the conversation, and have the command and its output available in the conversation context for the model to reference.
What changed
Implemented shell mode (
!) for the CLI:!enters bash mode — a dedicated input mode with its own border color and prompt indicator. The command runs through the existing BashTool and the output streams live into the transcript.ctrl+bmoves a running command to the background;Esc/Ctrl+Ccancels it.The mode reuses the existing plan-mode pattern (global state plus border highlight) and the existing BashTool for execution, and adds a generic
injectAndNotifyhelper for user-invisible messages that are sent to the model right away.Checklist
gen-changesetsskill, or this PR needs no changeset.gen-docsskill, or this PR needs no doc update.Documentation updates for shell mode will follow in a separate PR.