mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
Add thread title to configurable TUI status line (#17187)
- Add thread-title as an optional TUI status line item, omitted unless the user has set a custom name (`ChatWidget.thread_name`). - Refresh the status line when threads are renamded - Add snapshot coverage for renamed-thread footer behavior.
This commit is contained in:
committed by
GitHub
Unverified
parent
5779be314a
commit
aac1e74cd5
@@ -14,7 +14,7 @@
|
||||
//! - Git information (branch name)
|
||||
//! - Context usage (meter, window size)
|
||||
//! - Usage limits (5-hour, weekly)
|
||||
//! - Session info (ID, tokens used)
|
||||
//! - Session info (thread title, ID, tokens used)
|
||||
//! - Application version
|
||||
|
||||
use ratatui::buffer::Buffer;
|
||||
@@ -98,6 +98,9 @@ pub(crate) enum StatusLineItem {
|
||||
|
||||
/// Whether Fast mode is currently active.
|
||||
FastMode,
|
||||
|
||||
/// Current thread title (if set by user).
|
||||
ThreadTitle,
|
||||
}
|
||||
|
||||
impl StatusLineItem {
|
||||
@@ -129,6 +132,7 @@ impl StatusLineItem {
|
||||
"Current session identifier (omitted until session starts)"
|
||||
}
|
||||
StatusLineItem::FastMode => "Whether Fast mode is currently active",
|
||||
StatusLineItem::ThreadTitle => "Current thread title (omitted unless changed by user)",
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -149,6 +153,7 @@ const SELECTABLE_STATUS_LINE_ITEMS: &[StatusLineItem] = &[
|
||||
StatusLineItem::TotalOutputTokens,
|
||||
StatusLineItem::SessionId,
|
||||
StatusLineItem::FastMode,
|
||||
StatusLineItem::ThreadTitle,
|
||||
];
|
||||
|
||||
/// Runtime values used to preview the current status-line selection.
|
||||
@@ -380,6 +385,33 @@ mod tests {
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn preview_includes_thread_title() {
|
||||
let preview_data = StatusLinePreviewData::from_iter([
|
||||
(StatusLineItem::ModelName, "gpt-5".to_string()),
|
||||
(StatusLineItem::ThreadTitle, "Roadmap cleanup".to_string()),
|
||||
]);
|
||||
let items = vec![
|
||||
MultiSelectItem {
|
||||
id: StatusLineItem::ModelName.to_string(),
|
||||
name: String::new(),
|
||||
description: None,
|
||||
enabled: true,
|
||||
},
|
||||
MultiSelectItem {
|
||||
id: StatusLineItem::ThreadTitle.to_string(),
|
||||
name: String::new(),
|
||||
description: None,
|
||||
enabled: true,
|
||||
},
|
||||
];
|
||||
|
||||
assert_eq!(
|
||||
preview_data.line_for_items(&items),
|
||||
Some(Line::from("gpt-5 · Roadmap cleanup"))
|
||||
);
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn setup_view_snapshot_uses_runtime_preview_values() {
|
||||
let (tx_raw, _rx) = unbounded_channel::<AppEvent>();
|
||||
|
||||
@@ -2151,6 +2151,7 @@ impl ChatWidget {
|
||||
}
|
||||
self.thread_name = event.thread_name;
|
||||
self.refresh_terminal_title();
|
||||
self.refresh_status_surfaces();
|
||||
self.request_redraw();
|
||||
}
|
||||
}
|
||||
|
||||
+9
@@ -0,0 +1,9 @@
|
||||
---
|
||||
source: tui/src/chatwidget/tests.rs
|
||||
expression: terminal.backend()
|
||||
---
|
||||
" "
|
||||
" "
|
||||
"› Ask Codex to do anything "
|
||||
" "
|
||||
" gpt-5.3-codex high · Roadmap cleanup "
|
||||
@@ -495,6 +495,10 @@ impl ChatWidget {
|
||||
"Fast off".to_string()
|
||||
},
|
||||
),
|
||||
StatusLineItem::ThreadTitle => self.thread_name.as_ref().and_then(|name| {
|
||||
let trimmed = name.trim();
|
||||
(!trimmed.is_empty()).then(|| trimmed.to_string())
|
||||
}),
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1198,6 +1198,42 @@ async fn status_line_model_with_reasoning_plan_mode_footer_snapshot() {
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn renamed_thread_footer_title_snapshot() {
|
||||
use ratatui::Terminal;
|
||||
use ratatui::backend::TestBackend;
|
||||
|
||||
let (mut chat, _rx, _op_rx) = make_chatwidget_manual(Some("gpt-5.3-codex")).await;
|
||||
chat.show_welcome_banner = false;
|
||||
chat.config.tui_status_line = Some(vec![
|
||||
"model-with-reasoning".to_string(),
|
||||
"thread-title".to_string(),
|
||||
]);
|
||||
chat.set_reasoning_effort(Some(ReasoningEffortConfig::High));
|
||||
chat.refresh_status_line();
|
||||
|
||||
let thread_id = ThreadId::new();
|
||||
chat.thread_id = Some(thread_id);
|
||||
chat.handle_codex_event(Event {
|
||||
id: "rename".to_string(),
|
||||
msg: EventMsg::ThreadNameUpdated(codex_protocol::protocol::ThreadNameUpdatedEvent {
|
||||
thread_id,
|
||||
thread_name: Some("Roadmap cleanup".to_string()),
|
||||
}),
|
||||
});
|
||||
|
||||
let width = 80;
|
||||
let height = chat.desired_height(width);
|
||||
let mut terminal = Terminal::new(TestBackend::new(width, height)).expect("create terminal");
|
||||
terminal
|
||||
.draw(|f| chat.render(f.area(), f.buffer_mut()))
|
||||
.expect("draw renamed-thread footer");
|
||||
assert_chatwidget_snapshot!(
|
||||
"renamed_thread_footer_title",
|
||||
normalized_backend_snapshot(terminal.backend())
|
||||
);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn status_line_model_with_reasoning_fast_footer_snapshot() {
|
||||
use ratatui::Terminal;
|
||||
|
||||
Reference in New Issue
Block a user