Skip to content

Commit 876d4f4

Browse files
authored
bug: fix CLI UP/ENTER (#4944)
Clear the history cursor before checking for duplicate submissions so sending the same message twice exits history mode. This prevents Up/Down from staying stuck in history browsing after duplicate sends.
1 parent f52320b commit 876d4f4

File tree

2 files changed

+32
-2
lines changed

2 files changed

+32
-2
lines changed

codex-rs/tui/src/bottom_pane/chat_composer_history.rs

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,14 +59,15 @@ impl ChatComposerHistory {
5959
return;
6060
}
6161

62+
self.history_cursor = None;
63+
self.last_history_text = None;
64+
6265
// Avoid inserting a duplicate if identical to the previous entry.
6366
if self.local_history.last().is_some_and(|prev| prev == text) {
6467
return;
6568
}
6669

6770
self.local_history.push(text.to_string());
68-
self.history_cursor = None;
69-
self.last_history_text = None;
7071
}
7172

7273
/// Should Up/Down key presses be interpreted as history navigation given

codex-rs/tui/src/chatwidget/tests.rs

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,35 @@ fn alt_up_edits_most_recent_queued_message() {
615615
);
616616
}
617617

618+
/// Pressing Up to recall the most recent history entry and immediately queuing
619+
/// it while a task is running should always enqueue the same text, even when it
620+
/// is queued repeatedly.
621+
#[test]
622+
fn enqueueing_history_prompt_multiple_times_is_stable() {
623+
let (mut chat, _rx, _op_rx) = make_chatwidget_manual();
624+
625+
// Submit an initial prompt to seed history.
626+
chat.bottom_pane.set_composer_text("repeat me".to_string());
627+
chat.handle_key_event(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE));
628+
629+
// Simulate an active task so further submissions are queued.
630+
chat.bottom_pane.set_task_running(true);
631+
632+
for _ in 0..3 {
633+
// Recall the prompt from history and ensure it is what we expect.
634+
chat.handle_key_event(KeyEvent::new(KeyCode::Up, KeyModifiers::NONE));
635+
assert_eq!(chat.bottom_pane.composer_text(), "repeat me");
636+
637+
// Queue the prompt while the task is running.
638+
chat.handle_key_event(KeyEvent::new(KeyCode::Enter, KeyModifiers::NONE));
639+
}
640+
641+
assert_eq!(chat.queued_user_messages.len(), 3);
642+
for message in chat.queued_user_messages.iter() {
643+
assert_eq!(message.text, "repeat me");
644+
}
645+
}
646+
618647
#[test]
619648
fn streaming_final_answer_keeps_task_running_state() {
620649
let (mut chat, _rx, mut op_rx) = make_chatwidget_manual();

0 commit comments

Comments
 (0)