fix(terminal): paste messages to Kimi Code so they are sent

Kimi Code takes keys arriving faster than anyone types for an unbracketed
paste, and the Enter right behind a typed line for one of its newlines: a
one-line message from the composer sat in Kimi's input with an empty line
under it, never sent. Paste every message instead. Kimi knows a bracketed
paste for one, sends on the Enter after it at once, and still reads a
pasted leading `!`, `?` or `/` as typed.
This commit is contained in:
l0ng-ai
2026-10-01 15:28:01 +08:00
parent aae6b12196
commit e90ed33c0d
+20 -1
View File
@@ -143,6 +143,10 @@ pub(super) struct Step {
/// - **So is Copilot.** A typed leading `?` is the key that opens its help,
/// and the rest of the line goes out without it. Its shell mode is a
/// leading `!` it reads off a paste as well.
/// - **So is Kimi Code.** It takes keys arriving faster than typing for an
/// unbracketed paste, and the Enter right behind a typed line for one of its
/// newlines: the message sat in its input, never sent. A bracketed paste it
/// knows for one, and reads its `!`, `?` and `/` off it as typed.
/// - **A leading `!` goes to Claude Code, CodeBuddy, Gemini, Qwen Code and
/// OpenCode on its own.** It
/// switches the input into shell mode only when it is typed into an empty
@@ -201,7 +205,11 @@ pub(super) fn submit_plan(agent: CLIAgent, text: &str, bracketed: bool) -> Vec<S
pasted = bracketed
&& (matches!(
agent,
CLIAgent::Codex | CLIAgent::OpenCode | CLIAgent::Amp | CLIAgent::Copilot
CLIAgent::Codex
| CLIAgent::OpenCode
| CLIAgent::Amp
| CLIAgent::Copilot
| CLIAgent::Kimi
) || reads_like_gemini(agent)
|| !types_cleanly(body));
let bytes = match pasted {
@@ -2341,6 +2349,17 @@ mod tests {
assert_eq!(bytes(&steps), [&b"!git status"[..], b"\r"]);
}
#[test]
fn kimi_is_always_pasted() {
// Typed, the Enter behind the line is one of its newlines.
for text in ["fix it", "?why", "!ls", "/usage"] {
let steps = submit_plan(CLIAgent::Kimi, text, true);
let pasted = format!("\x1b[200~{text}\x1b[201~");
assert_eq!(bytes(&steps), [pasted.as_bytes(), b"\r"], "{text}");
assert_eq!(steps[1].delay, SETTLE, "{text}");
}
}
#[test]
fn copilot_is_always_pasted() {
// Typed, the leading `?` would open its help and be lost; its shell