fix(tui): persist ctrl+s-steered editor drafts into input history - #3021
fix(tui): persist ctrl+s-steered editor drafts into input history#3021bj456736 wants to merge 2 commits into
Conversation
Ctrl-S steering consumes the unsubmitted editor draft directly, bypassing handleUserInput and its persistInputHistory write, so steered messages were lost from up-arrow recall. Persist the draft where the steer consumes it; queued items were already persisted at submit time, and drafts that stay in the editor (rejected media, inline-skill bundles, no model) persist nothing.
🦋 Changeset detectedLatest commit: 7042822 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 |
|
@codex review |
commit: |
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 0a72c408a5
ℹ️ 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".
| // A steered editor draft bypasses handleUserInput (and its input- | ||
| // history write) — persist it here, or ↑ recall loses Ctrl-S-sent | ||
| // input. Queued items were already persisted at submit time. | ||
| if (text.length > 0) host.persistInputHistory(text); |
There was a problem hiding this comment.
Persist expanded paste contents instead of the marker
When the Ctrl-S draft contains a large terminal paste, editor.getText() returns a collapsed value such as [paste #1 +20 lines], while getExpandedText() contains the actual pasted input. This call therefore saves only the temporary marker, and the following editor.setText('') clears the paste registry; recalling the new history entry later produces an unresolvable literal marker instead of the steered draft. Persist the expanded editor text, matching the normal Enter submission path.
Useful? React with 👍 / 👎.
Problem
In the TUI, pressing Ctrl-S while a turn is running steers the unsubmitted editor draft directly into the turn (
onCtrlSineditor-keyboard.ts). That path bypasseshandleUserInput, which is the only place input history (↑ recall) is written (persistInputHistoryinkimi-tui.ts). As a result, messages sent via Ctrl-S steer never land in input history — pressing ↑ afterwards cannot recall them.(Session transcripts are unaffected: the v2 engine records steered messages as durable
context.append_message, so resume/cold rebuild shows them.)Fix
Minimal, TUI-only: when Ctrl-S consumes the editor draft for steering, persist it into input history at the same point the draft is cleared.
persistInputHistoryalready trims and dedupes against the last entry. Queued items are not re-persisted (they were written at submit time); drafts that stay in the editor (rejected media, inline-skill bundles, missing model) persist nothing.editor-keyboard.ts: callhost.persistInputHistory(text)where the steered draft is consumed; addpersistInputHistorytoEditorKeyboardHost.kimi-tui.ts: makepersistInputHistorypublic so the keyboard controller can reach it.Tests
New Ctrl-S steering tests in
editor-keyboard.test.ts:persists a steered editor draft into input history— draft steered → history written with the draft text, editor cleared.does not re-persist queued items — they were persisted at submit time.does not persist the draft when steering is rejected and the draft stays(no model set).does not persist an inline-skill draft left in the editor for the grouped path.Test harness: added a minimal image-store stub (the draft-steer path calls
extractMediaAttachments, which touchesstore.retainFileIdseven for plain text) and areleaseStagingMediamock.Verification
pnpm vitest run test/tui/controllers/editor-keyboard.test.ts— 37/37 passed.pnpm run typecheck(apps/kimi-code) — clean.pnpm vitest run— 2946 passed, 2 skipped (1 pre-existing failure unrelated to this change, also fails on main).