Preserve TUI question state and integrate history and queue navigation (#42903)

## What changed

- Retain question drafts, selections, expanded state, and handled message IDs across thread input restoration and reconnects. Preserve buffered live questions during session refresh without replaying their message text.
- Enable history recall and search in question answers, honoring updated key bindings and stripping image attachments and placeholders from recalled entries. Preserve Vim mode when an answer is not accepted.
- Let forward navigation past the last question restore the latest queued message as an editable main composer draft. Keep working status and queued messages visible alongside questions.
- Show a countdown for newly arrived collapsed questions and clear it when the question editor is opened or used.
- Disable question submission and skipping while the thread is unavailable.

## Testing

Add regression tests and snapshots for draft restoration and replay deduplication, history search and key bindings, queued-message editing, countdown rendering, and question layout with working status.

GitOrigin-RevId: de016120a979db860fd0d4b8098b322b312b7d84
This commit is contained in:
Ian MacLeod
2026-09-05 01:13:54 +00:00
committed by copyberry
parent d05e6d5f46
commit be2684ede0
35 changed files with 700 additions and 87 deletions
@@ -247,6 +247,10 @@ impl ChatWidget {
/// Rebuild and update the bottom-pane pending-input preview.
pub(super) fn refresh_pending_input_preview(&mut self) {
let has_queued = self.has_queued_follow_up_messages();
if let Some(questions) = &mut self.bottom_pane.questions {
questions.has_queued_messages = has_queued;
}
let preview = self.input_queue.preview();
self.bottom_pane.set_pending_input_preview(
preview.queued_messages,