mirror of
https://github.com/openai/codex.git
synced 2026-11-05 16:29:31 +00:00
Normalize /statusline & /title items (#18886)
This change aligns the `/statusline` and `/title` UIs around the same normalized item model so both surfaces use consistent ids, labels, and preview semantics. It keeps the shared preview work from #18435 , tightens the remaining mismatches by standardizing item naming, expands title/status item coverage where appropriate, and makes `/title` preview use the same title-specific formatting path as the real rendered terminal title. - Normalizes persisted item ids and keeps legacy aliases for compatibility - Aligns `status-line` and `terminal-title` items with the shared preview model - Routes `terminal-title` preview through title-specific formatting and truncation - Updates the affected status/title setup snapshots Added to `/statusline`: - status - task-progress Normalized in `/statusline`: - model-name -> model - project-root -> project-name Added to `/title`: - current-dir - context-remaining - context-used - five-hour-limit - weekly-limit - codex-version - used-tokens - total-input-tokens - total-output-tokens - session-id - fast-mode - model-with-reasoning Normalized in `/title`: - project -> project-name - thread -> thread-title - model-name -> model
This commit is contained in:
1 parent
ef00014a46
commit
2202675632
9 files changed
+570
-33
No files matched your search
+1
-1
@@ -13,7 +13,7 @@ expression: terminal_title_popup_snapshot(&mut chat)
|
||||
[ ] app-name Codex app name
|
||||
[ ] project Project name (falls back to current directory name)
|
||||
[ ] spinner Animated task spinner (omitted while idle or when animations are off)
|
||||
[ ] status Compact session status text (Ready, Working, Thinking)
|
||||
[ ] run-state Compact session run-state text (Ready, Working, Thinking)
|
||||
[ ] model Current model name
|
||||
|
||||
thread title | feat/awesome-feature | Tasks 0/0
|
||||
|
||||
+1
-1
@@ -13,7 +13,7 @@ expression: terminal_title_popup_snapshot(&mut chat)
|
||||
[x] task-progress Latest task progress from update_plan (omitted until available)
|
||||
[ ] app-name Codex app name
|
||||
[ ] spinner Animated task spinner (omitted while idle or when animations are off)
|
||||
[ ] status Compact session status text (Ready, Working, Thinking)
|
||||
[ ] run-state Compact session run-state text (Ready, Working, Thinking)
|
||||
[ ] model Current model name
|
||||
|
||||
preview-live-root | Live preview thread | feature/live-preview-branch | Tasks 2/5
|
||||
|
||||
+1
-1
@@ -12,7 +12,7 @@ expression: terminal_title_popup_snapshot(&mut chat)
|
||||
[x] task-progress Latest task progress from update_plan (omitted until available)
|
||||
[ ] app-name Codex app name
|
||||
[ ] spinner Animated task spinner (omitted while idle or when animations are off)
|
||||
[ ] status Compact session status text (Ready, Working, Thinking)
|
||||
[ ] run-state Compact session run-state text (Ready, Working, Thinking)
|
||||
[ ] git-branch Current Git branch (omitted when unavailable)
|
||||
[ ] model Current model name
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ use super::*;
|
||||
|
||||
/// Items shown in the terminal title when the user has not configured a
|
||||
/// custom selection. Intentionally minimal: spinner + project name.
|
||||
pub(super) const DEFAULT_TERMINAL_TITLE_ITEMS: [&str; 2] = ["spinner", "project"];
|
||||
pub(super) const DEFAULT_TERMINAL_TITLE_ITEMS: [&str; 2] = ["spinner", "project-name"];
|
||||
|
||||
/// Braille-pattern dot-spinner frames for the terminal title animation.
|
||||
pub(super) const TERMINAL_TITLE_SPINNER_FRAMES: [&str; 10] =
|
||||
@@ -421,18 +421,7 @@ impl ChatWidget {
|
||||
pub(super) fn status_line_value_for_item(&mut self, item: &StatusLineItem) -> Option<String> {
|
||||
match item {
|
||||
StatusLineItem::ModelName => Some(self.model_display_name().to_string()),
|
||||
StatusLineItem::ModelWithReasoning => {
|
||||
let label =
|
||||
Self::status_line_reasoning_effort_label(self.effective_reasoning_effort());
|
||||
let fast_label = if self
|
||||
.should_show_fast_status(self.current_model(), self.config.service_tier)
|
||||
{
|
||||
" fast"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
Some(format!("{} {label}{fast_label}", self.model_display_name()))
|
||||
}
|
||||
StatusLineItem::ModelWithReasoning => Some(self.model_with_reasoning_display_name()),
|
||||
StatusLineItem::CurrentDir => {
|
||||
Some(format_directory_display(
|
||||
self.status_line_cwd(),
|
||||
@@ -441,6 +430,7 @@ impl ChatWidget {
|
||||
}
|
||||
StatusLineItem::ProjectRoot => self.status_line_project_root_name(),
|
||||
StatusLineItem::GitBranch => self.status_line_branch.clone(),
|
||||
StatusLineItem::Status => Some(self.terminal_title_status_text()),
|
||||
StatusLineItem::UsedTokens => {
|
||||
let usage = self.status_line_total_usage();
|
||||
let total = usage.tokens_in_context_window();
|
||||
@@ -502,6 +492,7 @@ impl ChatWidget {
|
||||
let trimmed = name.trim();
|
||||
(!trimmed.is_empty()).then(|| trimmed.to_string())
|
||||
}),
|
||||
StatusLineItem::TaskProgress => self.terminal_title_task_progress(),
|
||||
}
|
||||
}
|
||||
|
||||
@@ -547,6 +538,10 @@ impl ChatWidget {
|
||||
match item {
|
||||
TerminalTitleItem::AppName => Some("codex".to_string()),
|
||||
TerminalTitleItem::Project => self.terminal_title_project_name(),
|
||||
TerminalTitleItem::CurrentDir => Some(Self::truncate_terminal_title_part(
|
||||
format_directory_display(self.status_line_cwd(), /*max_width*/ None),
|
||||
/*max_chars*/ 32,
|
||||
)),
|
||||
TerminalTitleItem::Spinner => self.terminal_title_spinner_text_at(now),
|
||||
TerminalTitleItem::Status => Some(self.terminal_title_status_text()),
|
||||
TerminalTitleItem::Thread => self.thread_name.as_ref().and_then(|name| {
|
||||
@@ -563,14 +558,59 @@ impl ChatWidget {
|
||||
TerminalTitleItem::GitBranch => self.status_line_branch.as_ref().map(|branch| {
|
||||
Self::truncate_terminal_title_part(branch.clone(), /*max_chars*/ 32)
|
||||
}),
|
||||
TerminalTitleItem::ContextRemaining => self
|
||||
.status_line_value_for_item(&StatusLineItem::ContextRemaining)
|
||||
.map(|value| Self::truncate_terminal_title_part(value, /*max_chars*/ 32)),
|
||||
TerminalTitleItem::ContextUsed => self
|
||||
.status_line_value_for_item(&StatusLineItem::ContextUsed)
|
||||
.map(|value| Self::truncate_terminal_title_part(value, /*max_chars*/ 32)),
|
||||
TerminalTitleItem::FiveHourLimit => self
|
||||
.status_line_value_for_item(&StatusLineItem::FiveHourLimit)
|
||||
.map(|value| Self::truncate_terminal_title_part(value, /*max_chars*/ 32)),
|
||||
TerminalTitleItem::WeeklyLimit => self
|
||||
.status_line_value_for_item(&StatusLineItem::WeeklyLimit)
|
||||
.map(|value| Self::truncate_terminal_title_part(value, /*max_chars*/ 32)),
|
||||
TerminalTitleItem::CodexVersion => self
|
||||
.status_line_value_for_item(&StatusLineItem::CodexVersion)
|
||||
.map(|value| Self::truncate_terminal_title_part(value, /*max_chars*/ 32)),
|
||||
TerminalTitleItem::UsedTokens => self
|
||||
.status_line_value_for_item(&StatusLineItem::UsedTokens)
|
||||
.map(|value| Self::truncate_terminal_title_part(value, /*max_chars*/ 32)),
|
||||
TerminalTitleItem::TotalInputTokens => self
|
||||
.status_line_value_for_item(&StatusLineItem::TotalInputTokens)
|
||||
.map(|value| Self::truncate_terminal_title_part(value, /*max_chars*/ 32)),
|
||||
TerminalTitleItem::TotalOutputTokens => self
|
||||
.status_line_value_for_item(&StatusLineItem::TotalOutputTokens)
|
||||
.map(|value| Self::truncate_terminal_title_part(value, /*max_chars*/ 32)),
|
||||
TerminalTitleItem::SessionId => self
|
||||
.status_line_value_for_item(&StatusLineItem::SessionId)
|
||||
.map(|value| Self::truncate_terminal_title_part(value, /*max_chars*/ 32)),
|
||||
TerminalTitleItem::FastMode => self
|
||||
.status_line_value_for_item(&StatusLineItem::FastMode)
|
||||
.map(|value| Self::truncate_terminal_title_part(value, /*max_chars*/ 32)),
|
||||
TerminalTitleItem::Model => Some(Self::truncate_terminal_title_part(
|
||||
self.model_display_name().to_string(),
|
||||
/*max_chars*/ 32,
|
||||
)),
|
||||
TerminalTitleItem::ModelWithReasoning => Some(Self::truncate_terminal_title_part(
|
||||
self.model_with_reasoning_display_name(),
|
||||
/*max_chars*/ 32,
|
||||
)),
|
||||
TerminalTitleItem::TaskProgress => self.terminal_title_task_progress(),
|
||||
}
|
||||
}
|
||||
|
||||
fn model_with_reasoning_display_name(&self) -> String {
|
||||
let label = Self::status_line_reasoning_effort_label(self.effective_reasoning_effort());
|
||||
let fast_label =
|
||||
if self.should_show_fast_status(self.current_model(), self.config.service_tier) {
|
||||
" fast"
|
||||
} else {
|
||||
""
|
||||
};
|
||||
format!("{} {label}{fast_label}", self.model_display_name())
|
||||
}
|
||||
|
||||
/// Computes the compact runtime status label used by the terminal title.
|
||||
///
|
||||
/// Startup takes precedence over normal task states, and idle state renders
|
||||
|
||||
Reference in new issue
Block a user