Skip to content

feat: add shell mode (!) to the CLI#1079

Open
liruifengv wants to merge 1 commit into
mainfrom
feat/shell-mode
Open

feat: add shell mode (!) to the CLI#1079
liruifengv wants to merge 1 commit into
mainfrom
feat/shell-mode

Conversation

@liruifengv

Copy link
Copy Markdown
Collaborator

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:

  • Typing ! 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.
  • While a command runs, input is queued, the activity pane shows a loading indicator, and the running card shows live output with an elapsed timer.
  • ctrl+b moves a running command to the background; Esc / Ctrl+C cancels it.
  • Command input and output are recorded so they survive resume, and moving a command to the background injects a hidden notification that is sent to the model immediately.
  • Output indentation, command coloring, and stderr rendering (red only on failure) were tuned for readability.

The mode reuses the existing plan-mode pattern (global state plus border highlight) and the existing BashTool for execution, and adds a generic injectAndNotify helper for user-invisible messages that are sent to the model right away.

Checklist

  • I have read the CONTRIBUTING document.
  • I have linked a related issue, or explained the problem above.
  • I have added tests that prove my feature works.
  • Ran gen-changesets skill, or this PR needs no changeset.
  • Ran gen-docs skill, or this PR needs no doc update.

Documentation updates for shell mode will follow in a separate PR.

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-bot

changeset-bot Bot commented Jun 24, 2026

Copy link
Copy Markdown

🦋 Changeset detected

Latest commit: 94bc5b5

The changes in this PR will be included in the next version bump.

This PR includes changesets to release 1 package
Name Type
@moonshot-ai/kimi-code Minor

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

@pkg-pr-new

pkg-pr-new Bot commented Jun 24, 2026

Copy link
Copy Markdown
pnpm dlx https://pkg.pr.new/@moonshot-ai/kimi-code@94bc5b5
npx https://pkg.pr.new/@moonshot-ai/kimi-code@94bc5b5

commit: 94bc5b5

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 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;

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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) {

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge 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 👍 / 👎.

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