From 9ccc21f70f3c2e79f6b5dbf517785edb2407c586 Mon Sep 17 00:00:00 2001 From: jif-oai Date: Fri, 8 May 2026 17:24:57 +0200 Subject: [PATCH] chore: thread tui --- ...up__tests__terminal_title_setup_basic.snap | 2 +- .../tui/src/bottom_pane/status_line_setup.rs | 15 +++++----- codex-rs/tui/src/bottom_pane/title_setup.rs | 7 +++-- ...tatus_line_setup_popup_hardcoded_only.snap | 2 +- ...ts__status_line_setup_popup_live_only.snap | 2 +- ..._tests__status_line_setup_popup_mixed.snap | 2 +- ...inal_title_setup_popup_hardcoded_only.snap | 2 +- ..._terminal_title_setup_popup_live_only.snap | 2 +- ...sts__terminal_title_setup_popup_mixed.snap | 2 +- .../tui/src/chatwidget/status_surfaces.rs | 29 +++++++++---------- .../tests/status_surface_previews.rs | 16 ++++++++++ 11 files changed, 49 insertions(+), 32 deletions(-) diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__title_setup__tests__terminal_title_setup_basic.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__title_setup__tests__terminal_title_setup_basic.snap index 7dadf02b35d5..598fa418a171 100644 --- a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__title_setup__tests__terminal_title_setup_basic.snap +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__title_setup__tests__terminal_title_setup_basic.snap @@ -11,7 +11,7 @@ expression: "render_lines(&view, 84)" › [x] project-name Project name (falls back to current directory name) [x] activity Spinner while working, action-required message while blo… [x] run-state Compact session run-state text (Ready, Working, Thinking) - [x] thread-title Current thread title (omitted when unavailable) + [x] thread-title Current thread title, or thread identifier when unnamed [ ] app-name Codex app name [ ] current-dir Current working directory [ ] git-branch Current Git branch (omitted when unavailable) diff --git a/codex-rs/tui/src/bottom_pane/status_line_setup.rs b/codex-rs/tui/src/bottom_pane/status_line_setup.rs index db789a11fffa..927c3aca3ddf 100644 --- a/codex-rs/tui/src/bottom_pane/status_line_setup.rs +++ b/codex-rs/tui/src/bottom_pane/status_line_setup.rs @@ -14,7 +14,7 @@ //! - Git information (branch name) //! - Context usage (remaining %, used %, window size) //! - Usage limits (5-hour, weekly) -//! - Session info (thread title, ID, tokens used) +//! - Session info (thread title, thread ID, tokens used) //! - Application version use ratatui::buffer::Buffer; @@ -46,7 +46,7 @@ const STATUS_LINE_USE_THEME_COLORS_ITEM_ID: &str = "status-line-use-theme-colors /// Some items are conditionally displayed based on availability: /// - Git-related items only show when in a git repository /// - Context/limit items only show when data is available from the API -/// - Session ID only shows after a session has started +/// - Thread ID only shows after a session has started #[derive(EnumIter, EnumString, Display, Debug, Clone, Copy, Eq, PartialEq, Ord, PartialOrd)] #[strum(serialize_all = "kebab_case")] pub(crate) enum StatusLineItem { @@ -111,7 +111,8 @@ pub(crate) enum StatusLineItem { /// Total output tokens generated. TotalOutputTokens, - /// Full session UUID. + /// Full thread UUID. + #[strum(to_string = "thread-id", serialize = "session-id")] SessionId, /// Whether Fast mode is currently active. @@ -162,12 +163,12 @@ impl StatusLineItem { StatusLineItem::UsedTokens => "Total tokens used in session (omitted when zero)", StatusLineItem::TotalInputTokens => "Total input tokens used in session", StatusLineItem::TotalOutputTokens => "Total output tokens used in session", - StatusLineItem::SessionId => { - "Current session identifier (omitted until session starts)" - } + StatusLineItem::SessionId => "Current thread identifier (omitted until thread starts)", StatusLineItem::FastMode => "Whether Fast mode is currently active", StatusLineItem::RawOutput => "Whether raw scrollback mode is active", - StatusLineItem::ThreadTitle => "Current thread title (omitted when unavailable)", + StatusLineItem::ThreadTitle => { + "Current thread title, or thread identifier when unnamed" + } StatusLineItem::TaskProgress => { "Latest task progress from update_plan (omitted until available)" } diff --git a/codex-rs/tui/src/bottom_pane/title_setup.rs b/codex-rs/tui/src/bottom_pane/title_setup.rs index 8b46d059c4c3..ae3c56ca3ba7 100644 --- a/codex-rs/tui/src/bottom_pane/title_setup.rs +++ b/codex-rs/tui/src/bottom_pane/title_setup.rs @@ -71,7 +71,8 @@ pub(crate) enum TerminalTitleItem { TotalInputTokens, /// Total output tokens generated. TotalOutputTokens, - /// Full session UUID. + /// Full thread UUID. + #[strum(to_string = "thread-id", serialize = "session-id")] SessionId, /// Whether Fast mode is currently active. FastMode, @@ -96,7 +97,7 @@ impl TerminalTitleItem { TerminalTitleItem::Status => { "Compact session run-state text (Ready, Working, Thinking)" } - TerminalTitleItem::Thread => "Current thread title (omitted when unavailable)", + TerminalTitleItem::Thread => "Current thread title, or thread identifier when unnamed", TerminalTitleItem::GitBranch => "Current Git branch (omitted when unavailable)", TerminalTitleItem::ContextRemaining => { "Percentage of context window remaining (omitted when unknown)" @@ -115,7 +116,7 @@ impl TerminalTitleItem { TerminalTitleItem::TotalInputTokens => "Total input tokens used in session", TerminalTitleItem::TotalOutputTokens => "Total output tokens used in session", TerminalTitleItem::SessionId => { - "Current session identifier (omitted until session starts)" + "Current thread identifier (omitted until thread starts)" } TerminalTitleItem::FastMode => "Whether Fast mode is currently active", TerminalTitleItem::Model => "Current model name", diff --git a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_setup_popup_hardcoded_only.snap b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_setup_popup_hardcoded_only.snap index b3c909647d4f..652c914adf46 100644 --- a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_setup_popup_hardcoded_only.snap +++ b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_setup_popup_hardcoded_only.snap @@ -11,7 +11,7 @@ expression: status_line_popup_snapshot(&mut chat) ─────────────────────── [x] project-name Project name (omitted when unavailable) [x] git-branch Current Git branch (omitted when unavailable) - [x] thread-title Current thread title (omitted when unavailable) + [x] thread-title Current thread title, or thread identifier when unnamed [ ] model Current model name [ ] model-with-reasoning Current model name with reasoning level [ ] current-dir Current working directory diff --git a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_setup_popup_live_only.snap b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_setup_popup_live_only.snap index e1b7e0e777f4..fc713c4cdc04 100644 --- a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_setup_popup_live_only.snap +++ b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_setup_popup_live_only.snap @@ -11,7 +11,7 @@ expression: status_line_popup_snapshot(&mut chat) ─────────────────────── [x] project-name Project name (omitted when unavailable) [x] git-branch Current Git branch (omitted when unavailable) - [x] thread-title Current thread title (omitted when unavailable) + [x] thread-title Current thread title, or thread identifier when unnamed [ ] model Current model name [ ] model-with-reasoning Current model name with reasoning level [ ] current-dir Current working directory diff --git a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_setup_popup_mixed.snap b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_setup_popup_mixed.snap index b76ba0dc4e43..547f70daa838 100644 --- a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_setup_popup_mixed.snap +++ b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__status_line_setup_popup_mixed.snap @@ -11,7 +11,7 @@ expression: status_line_popup_snapshot(&mut chat) ─────────────────────── [x] project-name Project name (omitted when unavailable) [x] git-branch Current Git branch (omitted when unavailable) - [x] thread-title Current thread title (omitted when unavailable) + [x] thread-title Current thread title, or thread identifier when unnamed [ ] model Current model name [ ] model-with-reasoning Current model name with reasoning level [ ] current-dir Current working directory diff --git a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__terminal_title_setup_popup_hardcoded_only.snap b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__terminal_title_setup_popup_hardcoded_only.snap index 9ab8659a374e..cf2248ffddf1 100644 --- a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__terminal_title_setup_popup_hardcoded_only.snap +++ b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__terminal_title_setup_popup_hardcoded_only.snap @@ -7,7 +7,7 @@ expression: terminal_title_popup_snapshot(&mut chat) Type to search > -› [x] thread-title Current thread title (omitted when unavailable) +› [x] thread-title Current thread title, or thread identifier when unnamed [x] git-branch Current Git branch (omitted when unavailable) [x] task-progress Latest task progress from update_plan (omitted until available) [ ] app-name Codex app name diff --git a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__terminal_title_setup_popup_live_only.snap b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__terminal_title_setup_popup_live_only.snap index 6ede93244b77..c22a70f714a1 100644 --- a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__terminal_title_setup_popup_live_only.snap +++ b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__terminal_title_setup_popup_live_only.snap @@ -8,7 +8,7 @@ expression: terminal_title_popup_snapshot(&mut chat) Type to search > › [x] project-name Project name (falls back to current directory name) - [x] thread-title Current thread title (omitted when unavailable) + [x] thread-title Current thread title, or thread identifier when unnamed [x] git-branch Current Git branch (omitted when unavailable) [x] task-progress Latest task progress from update_plan (omitted until available) [ ] app-name Codex app name diff --git a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__terminal_title_setup_popup_mixed.snap b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__terminal_title_setup_popup_mixed.snap index 842938ca0b61..06b988811eac 100644 --- a/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__terminal_title_setup_popup_mixed.snap +++ b/codex-rs/tui/src/chatwidget/snapshots/codex_tui__chatwidget__tests__terminal_title_setup_popup_mixed.snap @@ -8,7 +8,7 @@ expression: terminal_title_popup_snapshot(&mut chat) Type to search > › [x] project-name Project name (falls back to current directory name) - [x] thread-title Current thread title (omitted when unavailable) + [x] thread-title Current thread title, or thread identifier when unnamed [x] task-progress Latest task progress from update_plan (omitted until available) [ ] app-name Codex app name [ ] current-dir Current working directory diff --git a/codex-rs/tui/src/chatwidget/status_surfaces.rs b/codex-rs/tui/src/chatwidget/status_surfaces.rs index 3095556fd04c..f56ca54a5f79 100644 --- a/codex-rs/tui/src/chatwidget/status_surfaces.rs +++ b/codex-rs/tui/src/chatwidget/status_surfaces.rs @@ -648,10 +648,17 @@ impl ChatWidget { }, ), StatusLineItem::RawOutput => self.raw_output_mode().then(|| "raw output".to_string()), - StatusLineItem::ThreadTitle => self.thread_name.as_ref().and_then(|name| { - let trimmed = name.trim(); - (!trimmed.is_empty()).then(|| trimmed.to_string()) - }), + StatusLineItem::ThreadTitle => self.thread_name.as_ref().map_or_else( + || self.thread_id.map(|id| id.to_string()), + |name| { + let trimmed = name.trim(); + if trimmed.is_empty() { + self.thread_id.map(|id| id.to_string()) + } else { + Some(trimmed.to_string()) + } + }, + ), StatusLineItem::TaskProgress => self.terminal_title_task_progress(), } } @@ -713,17 +720,9 @@ impl ChatWidget { )), TerminalTitleItem::Spinner => self.terminal_title_spinner_text_at(now), TerminalTitleItem::Status => Some(self.run_state_status_text()), - TerminalTitleItem::Thread => self.thread_name.as_ref().and_then(|name| { - let trimmed = name.trim(); - if trimmed.is_empty() { - None - } else { - Some(Self::truncate_terminal_title_part( - trimmed.to_string(), - /*max_chars*/ 48, - )) - } - }), + TerminalTitleItem::Thread => self + .status_line_value_for_item(StatusLineItem::ThreadTitle) + .map(|value| Self::truncate_terminal_title_part(value, /*max_chars*/ 48)), TerminalTitleItem::GitBranch => self.status_line_branch.as_ref().map(|branch| { Self::truncate_terminal_title_part(branch.clone(), /*max_chars*/ 32) }), diff --git a/codex-rs/tui/src/chatwidget/tests/status_surface_previews.rs b/codex-rs/tui/src/chatwidget/tests/status_surface_previews.rs index 4b080794b132..2368fd8481c9 100644 --- a/codex-rs/tui/src/chatwidget/tests/status_surface_previews.rs +++ b/codex-rs/tui/src/chatwidget/tests/status_surface_previews.rs @@ -123,6 +123,22 @@ async fn status_surface_preview_lines_hardcoded_only_snapshot() { assert_chatwidget_snapshot!("status_surface_previews_hardcoded_only", snapshot); } +#[tokio::test] +async fn thread_title_falls_back_to_thread_id_when_unnamed() { + let (mut chat, _rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await; + let thread_id = ThreadId::new(); + chat.thread_id = Some(thread_id); + + assert_eq!( + status_preview_line(&mut chat, &[StatusLineItem::ThreadTitle]), + thread_id.to_string() + ); + assert_eq!( + title_preview_line(&mut chat, &[TerminalTitleItem::Thread]), + thread_id.to_string() + ); +} + #[tokio::test] async fn status_line_setup_popup_hardcoded_only_snapshot() { let (mut chat, _rx, _op_rx) = make_chatwidget_manual(/*model_override*/ None).await;