From b1f3c2f77e7cb802af0d8ef1c325cb6e9d39d8d9 Mon Sep 17 00:00:00 2001 From: Felipe Coury Date: Tue, 15 Sep 2026 18:45:01 +0000 Subject: [PATCH] Expose experimental analytics plan history and improve navigation (#45772) ## What changed - Expose `analytics_plan_history` in the experimental features menu for previewing consumer five-hour and weekly allowance history in `/analytics`. Keep it disabled by default. - Add `h` and `l` as left/right navigation aliases in analytics, preserving explicit bindings and honoring remapped or unbound arrows. - Use terminal-aware footer key colors to keep analytics shortcuts readable on light backgrounds. ## Testing Add navigation tests for arrow equivalence, custom bindings, modifiers, and key repeat. Extend light-background contrast assertions and update style snapshots. Add a snapshot for the plan history experimental feature entry. GitOrigin-RevId: 310e64a43a7dd08c8a3fd1efed6985805f7dd580 --- codex-rs/features/src/lib.rs | 6 +- codex-rs/tui/src/analytics.rs | 13 +- .../tui/src/analytics/navigation_tests.rs | 272 ++++++++++++++++++ codex-rs/tui/src/analytics/render.rs | 12 +- ...sts__navigation__vim_chart_navigation.snap | 37 +++ ...nal_styles__analytics_dark_business_1.snap | 5 +- ...nal_styles__analytics_dark_business_2.snap | 5 +- ...nal_styles__analytics_dark_business_3.snap | 5 +- ...nal_styles__analytics_dark_business_4.snap | 6 +- ...nal_styles__analytics_dark_business_6.snap | 5 +- ...nal_styles__analytics_dark_business_8.snap | 6 +- ...nal_styles__analytics_dark_consumer_1.snap | 5 +- ...nal_styles__analytics_dark_consumer_2.snap | 5 +- ...nal_styles__analytics_dark_consumer_4.snap | 6 +- ...nal_styles__analytics_dark_consumer_5.snap | 5 +- ...nal_styles__analytics_dark_consumer_6.snap | 5 +- ...nal_styles__analytics_dark_consumer_8.snap | 6 +- ...al_styles__analytics_light_business_1.snap | 3 +- ...al_styles__analytics_light_business_2.snap | 3 +- ...al_styles__analytics_light_business_3.snap | 3 +- ...al_styles__analytics_light_business_4.snap | 3 +- ...al_styles__analytics_light_business_6.snap | 3 +- ...al_styles__analytics_light_business_8.snap | 3 +- ...al_styles__analytics_light_consumer_1.snap | 3 +- ...al_styles__analytics_light_consumer_2.snap | 3 +- ...al_styles__analytics_light_consumer_4.snap | 3 +- ...al_styles__analytics_light_consumer_5.snap | 3 +- ...al_styles__analytics_light_consumer_6.snap | 3 +- ...al_styles__analytics_light_consumer_8.snap | 3 +- codex-rs/tui/src/analytics/styles_tests.rs | 33 ++- codex-rs/tui/src/analytics_tests.rs | 3 + .../experimental_features_view_tests.rs | 21 ++ ...ental_features_analytics_plan_history.snap | 13 + 33 files changed, 450 insertions(+), 60 deletions(-) create mode 100644 codex-rs/tui/src/analytics/navigation_tests.rs create mode 100644 codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__navigation__vim_chart_navigation.snap create mode 100644 codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__experimental_features_view__tests__experimental_features_analytics_plan_history.snap diff --git a/codex-rs/features/src/lib.rs b/codex-rs/features/src/lib.rs index 9c1b8dfec0..4982f63ab2 100644 --- a/codex-rs/features/src/lib.rs +++ b/codex-rs/features/src/lib.rs @@ -911,7 +911,11 @@ pub const FEATURES: &[FeatureSpec] = &[ FeatureSpec { id: Feature::AnalyticsPlanHistory, key: "analytics_plan_history", - stage: Stage::UnderDevelopment, + stage: Stage::Experimental { + name: "Analytics plan history", + menu_description: "Preview five-hour and weekly allowance history for consumer accounts in /analytics.", + announcement: "", + }, default_enabled: false, }, FeatureSpec { diff --git a/codex-rs/tui/src/analytics.rs b/codex-rs/tui/src/analytics.rs index a1962372e7..84cec98f83 100644 --- a/codex-rs/tui/src/analytics.rs +++ b/codex-rs/tui/src/analytics.rs @@ -297,7 +297,18 @@ impl AnalyticsView { let action = if key_hint::plain(KeyCode::Char(' ')).is_press(key) { Some(ListAction::Accept) } else { - self.keymap.action_for(key) + self.keymap.action_for(key).or_else(|| { + if !key.modifiers.is_empty() { + return None; + } + // Keep explicit bindings first and honor remapped or unbound arrows. + let code = match key.code { + KeyCode::Char('h') => KeyCode::Left, + KeyCode::Char('l') => KeyCode::Right, + _ => return None, + }; + self.keymap.action_for(KeyEvent { code, ..key }) + }) }; self.follow_selection = true; diff --git a/codex-rs/tui/src/analytics/navigation_tests.rs b/codex-rs/tui/src/analytics/navigation_tests.rs new file mode 100644 index 0000000000..7e0897fce3 --- /dev/null +++ b/codex-rs/tui/src/analytics/navigation_tests.rs @@ -0,0 +1,272 @@ +//! Vim navigation aliases share arrow behavior while preserving configured bindings. + +use super::*; +use crate::analytics::models::AccountKind; +use codex_config::types::KeybindingSpec; +use codex_config::types::KeybindingsSpec; +use codex_config::types::TuiKeymap; +use pretty_assertions::assert_eq; +use serde_json::json; + +fn navigate(views: &mut [AnalyticsView; 2], keys: &[(char, KeyCode)], size: (u16, u16)) -> String { + let mut output = String::new(); + for &(alias, arrow) in keys { + press(&mut views[0], KeyCode::Char(alias)); + press(&mut views[1], arrow); + output = screen(&mut views[0], size.0, size.1); + assert_eq!(output, screen(&mut views[1], size.0, size.1), "{alias}"); + } + output +} + +#[test] +fn vim_chart_navigation_matches_arrows_in_focused_and_dashboard_views() { + for (kind, section) in [ + (AccountKind::Consumer, Section::Usage), + (AccountKind::Consumer, Section::Activity), + (AccountKind::Consumer, Section::Plugins), + (AccountKind::Consumer, Section::Skills), + (AccountKind::Business, Section::Usage), + (AccountKind::Business, Section::Credits), + ] { + for zoomed in [true, false] { + let mut views = [fixture::view(kind), fixture::view(kind)]; + for view in &mut views { + view.section = section; + view.zoomed = zoomed; + view.sections[section].cursor = 3; + view.sections[section].detail = Some(3); + } + let output = navigate( + &mut views, + &[ + ('h', KeyCode::Left), + ('h', KeyCode::Left), + ('l', KeyCode::Right), + ('j', KeyCode::Down), + ('k', KeyCode::Up), + ], + /*size*/ (96, 32), + ); + assert_eq!( + ( + views[0].section, + views[0].sections[section].cursor, + views[0].sections[section].detail + ), + (section, 2, Some(2)) + ); + if kind == AccountKind::Consumer && section == Section::Usage && zoomed { + insta::assert_snapshot!("vim_chart_navigation", output); + } + } + } +} + +#[test] +fn vim_plan_navigation_preserves_independent_windows_and_collapses_old_details() { + let mut views = [ + fixture::view(AccountKind::Consumer), + fixture::view(AccountKind::Consumer), + ]; + for view in &mut views { + let as_of = "2026-09-02T12:00:00Z" + .parse::>() + .unwrap(); + view.plan.enabled = true; + view.plan.report = Load::Ready(plan::Report { + as_of, + coverage_start: None, + coverage_complete: true, + approximate: false, + periods: std::array::from_fn(|window| { + let length = if window == 0 { + chrono::Duration::hours(/*hours*/ 5) + } else { + chrono::Duration::days(/*days*/ 7) + }; + (0..2) + .map(|index| plan::Period { + id: format!("{window}-{index}"), + start: as_of - length * index, + end: as_of - length * index + length, + complete: true, + used: Some(2500.0), + breakdowns: None, + }) + .collect() + }), + }); + view.plan.poll(); + view.plan.expanded = [Some("0-0".into()), Some("1-0".into())]; + view.section = Section::Plan; + } + navigate( + &mut views, + &[ + ('l', KeyCode::Right), + ('j', KeyCode::Down), + ('k', KeyCode::Up), + ('h', KeyCode::Left), + ('j', KeyCode::Down), + ], + /*size*/ (120, 30), + ); + assert_eq!( + ( + views[0].plan.window, + views[0].plan.cursor, + &views[0].plan.expanded + ), + (0, [1, 0], &[None, None]) + ); +} + +#[test] +fn vim_summary_navigation_scrolls_like_arrows() { + let mut views = [ + fixture::view(AccountKind::Consumer), + fixture::view(AccountKind::Consumer), + ]; + for view in &mut views { + view.section = Section::Summary; + view.profile = Load::Ready( + serde_json::from_value(json!({ + "stats": {"lifetime_tokens": 123, "daily_usage_buckets": [ + {"start_date": "2026-09-02", "tokens": 123} + ]} + })) + .unwrap(), + ); + assert!(screen(view, /*width*/ 64, /*height*/ 18).contains("scroll")); + } + navigate( + &mut views, + &[ + ('h', KeyCode::Left), + ('l', KeyCode::Right), + ('j', KeyCode::Down), + ('j', KeyCode::Down), + ('k', KeyCode::Up), + ], + /*size*/ (64, 18), + ); + assert_eq!(views[0].scroll_offset, 1); +} + +#[test] +fn vim_chat_navigation_expands_collapses_and_moves_like_arrows() { + for kind in [AccountKind::Consumer, AccountKind::Business] { + let mut views = [fixture::view(kind), fixture::view(kind)]; + for view in &mut views { + view.section = Section::Chats; + if kind == AccountKind::Consumer { + view.tasks = Load::Ready(tasks::Chats { + rows: (0..2) + .map(|index| tasks::Chat { + title: format!("Example chat {index}"), + task: Some( + serde_json::from_value(json!({ + "thread_id": format!("chat-{index}"), + "data_status": "available", "usage_source": "accounting", + "weekly_limit_percent": 20 - index, + "five_hour_limit_percent": null, "balance_usage_credits": null, + "groups": [] + })) + .unwrap(), + ), + }) + .collect(), + ..tasks::Chats::default() + }); + } + } + navigate( + &mut views, + &[ + ('l', KeyCode::Right), + ('h', KeyCode::Left), + ('l', KeyCode::Right), + ('j', KeyCode::Down), + ('l', KeyCode::Right), + ('k', KeyCode::Up), + ], + /*size*/ (96, 32), + ); + assert_eq!( + ( + views[0].sections[Section::Chats].cursor, + views[0].sections[Section::Chats].detail + ), + (0, None) + ); + } +} + +#[test] +fn configured_vim_keys_win_over_horizontal_aliases() { + let mut config = TuiKeymap::default(); + config.list.jump_top = Some(KeybindingsSpec::Many(vec![ + KeybindingSpec("h".into()), + KeybindingSpec("l".into()), + ])); + let mut view = fixture::view(AccountKind::Consumer); + view.keymap = RuntimeKeymap::from_config(&config).unwrap().list; + for alias in ['h', 'l'] { + view.sections[Section::Usage].cursor = 3; + press(&mut view, KeyCode::Char(alias)); + assert_eq!(view.sections[Section::Usage].cursor, 0); + } +} + +#[test] +fn vim_aliases_respect_removed_and_remapped_arrows() { + let mut config = TuiKeymap::default(); + config.list.move_left = Some(KeybindingsSpec::Many(Vec::new())); + config.list.move_right = Some(KeybindingsSpec::Many(Vec::new())); + config.list.move_up = Some(KeybindingsSpec::One(KeybindingSpec("up".into()))); + config.list.move_down = Some(KeybindingsSpec::One(KeybindingSpec("down".into()))); + let mut view = fixture::view(AccountKind::Consumer); + view.keymap = RuntimeKeymap::from_config(&config).unwrap().list; + view.sections[Section::Usage].cursor = 3; + for alias in ['h', 'j', 'k', 'l'] { + press(&mut view, KeyCode::Char(alias)); + assert_eq!(view.sections[Section::Usage].cursor, 3); + } + + config.list.move_up = Some(KeybindingsSpec::One(KeybindingSpec("right".into()))); + config.list.move_down = Some(KeybindingsSpec::One(KeybindingSpec("left".into()))); + view.keymap = RuntimeKeymap::from_config(&config).unwrap().list; + press(&mut view, KeyCode::Char('h')); + assert_eq!(view.sections[Section::Usage].cursor, 4); + press(&mut view, KeyCode::Char('l')); + assert_eq!(view.sections[Section::Usage].cursor, 3); +} + +#[test] +fn horizontal_aliases_ignore_modifiers_and_release_but_accept_repeat() { + let mut view = fixture::view(AccountKind::Consumer); + view.sections[Section::Usage].cursor = 3; + for alias in ['h', 'l'] { + for modifiers in [ + KeyModifiers::ALT, + KeyModifiers::SHIFT, + KeyModifiers::CONTROL | KeyModifiers::ALT, + ] { + view.handle_key(KeyEvent::new(KeyCode::Char(alias), modifiers)); + assert_eq!(view.sections[Section::Usage].cursor, 3); + } + view.handle_key(KeyEvent { + kind: KeyEventKind::Release, + ..KeyEvent::new(KeyCode::Char(alias), KeyModifiers::NONE) + }); + assert_eq!(view.sections[Section::Usage].cursor, 3); + } + for (alias, cursor) in [('h', 2), ('l', 3)] { + view.handle_key(KeyEvent { + kind: KeyEventKind::Repeat, + ..KeyEvent::new(KeyCode::Char(alias), KeyModifiers::NONE) + }); + assert_eq!(view.sections[Section::Usage].cursor, cursor); + } +} diff --git a/codex-rs/tui/src/analytics/render.rs b/codex-rs/tui/src/analytics/render.rs index e791b30e27..5f37e27460 100644 --- a/codex-rs/tui/src/analytics/render.rs +++ b/codex-rs/tui/src/analytics/render.rs @@ -9,12 +9,14 @@ use crate::analytics::models::AccountAnalyticsValue; use crate::analytics::sections::Section; use crate::keymap::ListAction; use crate::style::accent_style; +use crate::style::footer_hint_key_style; use crate::wrapping::RtOptions; use crate::wrapping::word_wrap_lines; use ratatui::buffer::Buffer; use ratatui::layout::Constraint; use ratatui::layout::Layout; use ratatui::layout::Rect; +use ratatui::style::Color; use ratatui::style::Styled; use ratatui::style::Stylize; use ratatui::text::Line; @@ -169,11 +171,11 @@ impl AnalyticsView { spans.push(" · ".into()); } let (keys, description) = control.rsplit_once(' ').unwrap_or((control, "")); - #[expect( - clippy::disallowed_methods, - reason = "Analytics shortcut keys intentionally use white to distinguish them from descriptions." - )] - spans.push(keys.to_owned().white().bold().not_dim()); + spans.push( + keys.to_owned() + .fg(Color::Reset) + .patch_style(footer_hint_key_style().bold().not_dim()), + ); if !description.is_empty() { spans.push(format!(" {description}").into()); } diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__navigation__vim_chart_navigation.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__navigation__vim_chart_navigation.snap new file mode 100644 index 0000000000..cd5d4772b0 --- /dev/null +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__navigation__vim_chart_navigation.snap @@ -0,0 +1,37 @@ +--- +source: tui/src/analytics/navigation_tests.rs +assertion_line: 60 +expression: output +--- +" Analytics · Live account " +" [7d] 30d · Aug 27–Sep 2, 2026 " +" " +" 1 Summary [2 Total usage history] 3 Messages 4 Plugins called 5 Skills used 6 Top chats " +" " +" ▎ Total usage history By feature " +" ──────────────────────────────────────────────────────────────────────────────────────────── " +" Total usage · relative units " +" Approximate · may be delayed up to 6 hours " +" 91 100 " +" 100 ▂▂▂▂▂▂▂▂ 81 ████████ 86 " +" 73 64 ████████ ▃▃▃▃▃▃▃▃ ████████ ▇▇▇▇▇▇▇▇ " +" ▆▆▆▆▆▆▆▆ ████████ ████████ ████████ ████████ " +" ████████ ████████ ████████ ████████ ████████ ████████ " +" 50 ████████ ████████ ████████ ████████ ████████ ████████ " +" 20 ████████ ████████ ████████ ████████ ████████ ████████ " +" ▄▄▄▄▄▄▄▄ ████████ ████████ ████████ ████████ ████████ ████████ " +" ████████ ████████ ████████ ████████ ████████ ████████ ████████ " +" 0 ─────────────────────────────────────────────────────────────────────────────────────── " +" ▲ " +" Aug 27 Aug 28 Aug 29 Aug 30 Aug 31 Sep 1 Sep 2 " +" " +" ──────────────────────────────────────────────────────── " +" Aug 29 · 64 usage units " +" Feature Share " +" ● Tasks 64.1% " +" ● Code review 14.1% " +" ● Images 10.9% " +" ● Other 10.9% " +" " +" tab/1–6 section · z dashboard · ←/→ day · enter details " +" r 7/30d · g group · R refresh · esc back · q close " diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_1.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_1.snap index dcb904941b..bfbea75055 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_1.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_1.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -98,5 +99,5 @@ Rows (column:palette): 37: 0:0 2:6 4:0 38: 0:0 2:5 4:0 39: 0:0 -40: 0:0 2:7 9:2 20:7 21:2 34:7 37:2 44:7 49:2 118:0 -41: 0:0 2:7 3:2 12:7 13:2 22:7 23:2 34:7 37:2 45:7 46:2 118:0 +40: 0:0 2:1 9:2 20:1 21:2 34:1 37:2 44:1 49:2 118:0 +41: 0:0 2:1 3:2 12:1 13:2 22:1 23:2 34:1 37:2 45:1 46:2 118:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_2.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_2.snap index 1294e0e6ea..4b02d8fb9d 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_2.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_2.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -98,5 +99,5 @@ Rows (column:palette): 37: 0:0 2:6 4:0 38: 0:0 39: 0:0 -40: 0:0 2:5 9:2 20:5 21:2 34:5 37:2 44:5 49:2 118:0 -41: 0:0 2:5 3:2 12:5 13:2 24:5 27:2 35:5 36:2 118:0 +40: 0:0 2:1 9:2 20:1 21:2 34:1 37:2 44:1 49:2 118:0 +41: 0:0 2:1 3:2 12:1 13:2 24:1 27:2 35:1 36:2 118:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_3.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_3.snap index 5672e1b3a4..2374745fef 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_3.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_3.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -98,5 +99,5 @@ Rows (column:palette): 37: 0:0 2:5 4:0 38: 0:0 39: 0:0 -40: 0:0 2:7 9:2 20:7 21:2 34:7 37:2 44:7 49:2 118:0 -41: 0:0 2:7 3:2 12:7 13:2 24:7 27:2 35:7 36:2 118:0 +40: 0:0 2:1 9:2 20:1 21:2 34:1 37:2 44:1 49:2 118:0 +41: 0:0 2:1 3:2 12:1 13:2 24:1 27:2 35:1 36:2 118:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_4.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_4.snap index e7a71c765e..b23c8ebfdb 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_4.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_4.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -52,7 +53,6 @@ Palette (foreground|background|underline|modifiers): 2: Rgb(165, 165, 165)|Reset|Reset|NONE 3: Cyan|Reset|Reset|BOLD 4: Reset|Reset|Reset|DIM -5: White|Reset|Reset|BOLD Rows (column:palette): 0: 0:0 2:1 11:2 28:0 1: 0:0 @@ -94,5 +94,5 @@ Rows (column:palette): 37: 0:0 38: 0:0 39: 0:0 -40: 0:0 2:5 9:2 20:5 21:2 34:5 37:2 44:5 49:2 118:0 -41: 0:0 2:5 3:2 14:5 17:2 25:5 26:2 118:0 +40: 0:0 2:1 9:2 20:1 21:2 34:1 37:2 44:1 49:2 118:0 +41: 0:0 2:1 3:2 14:1 17:2 25:1 26:2 118:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_6.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_6.snap index cd2102da7d..0a4af96b8e 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_6.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_6.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -98,5 +99,5 @@ Rows (column:palette): 37: 0:0 2:6 4:0 38: 0:0 39: 0:0 -40: 0:0 2:5 9:2 20:5 21:2 34:5 37:2 44:5 49:2 118:0 -41: 0:0 2:5 3:2 12:5 13:2 24:5 27:2 35:5 36:2 118:0 +40: 0:0 2:1 9:2 20:1 21:2 34:1 37:2 44:1 49:2 118:0 +41: 0:0 2:1 3:2 12:1 13:2 24:1 27:2 35:1 36:2 118:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_8.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_8.snap index 70502358d6..d13c95b507 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_8.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_business_8.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -52,7 +53,6 @@ Palette (foreground|background|underline|modifiers): 2: Rgb(165, 165, 165)|Reset|Reset|NONE 3: Cyan|Reset|Reset|BOLD 4: Reset|Reset|Reset|DIM -5: White|Reset|Reset|BOLD Rows (column:palette): 0: 0:0 2:1 11:2 28:0 1: 0:0 @@ -94,5 +94,5 @@ Rows (column:palette): 37: 0:0 38: 0:0 39: 0:0 -40: 0:0 2:5 9:2 20:5 21:2 118:0 -41: 0:0 2:5 3:2 11:5 12:2 23:5 26:2 34:5 35:2 118:0 +40: 0:0 2:1 9:2 20:1 21:2 118:0 +41: 0:0 2:1 3:2 11:1 12:2 23:1 26:2 34:1 35:2 118:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_1.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_1.snap index 90ef03bed9..623a419afe 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_1.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_1.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -98,5 +99,5 @@ Rows (column:palette): 37: 0:0 2:5 4:0 38: 0:0 39: 0:0 -40: 0:0 2:6 9:2 20:6 21:2 34:6 37:2 44:6 49:2 118:0 -41: 0:0 2:6 3:2 12:6 13:2 22:6 23:2 34:6 37:2 45:6 46:2 118:0 +40: 0:0 2:1 9:2 20:1 21:2 34:1 37:2 44:1 49:2 118:0 +41: 0:0 2:1 3:2 12:1 13:2 22:1 23:2 34:1 37:2 45:1 46:2 118:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_2.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_2.snap index e2d2052726..ec95172894 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_2.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_2.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -98,5 +99,5 @@ Rows (column:palette): 37: 0:0 2:6 4:0 38: 0:0 39: 0:0 -40: 0:0 2:5 9:2 20:5 21:2 34:5 37:2 44:5 49:2 118:0 -41: 0:0 2:5 3:2 12:5 13:2 24:5 27:2 35:5 36:2 118:0 +40: 0:0 2:1 9:2 20:1 21:2 34:1 37:2 44:1 49:2 118:0 +41: 0:0 2:1 3:2 12:1 13:2 24:1 27:2 35:1 36:2 118:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_4.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_4.snap index 9672a1ed63..ec82b2cc00 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_4.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_4.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -52,7 +53,6 @@ Palette (foreground|background|underline|modifiers): 2: Rgb(165, 165, 165)|Reset|Reset|NONE 3: Cyan|Reset|Reset|BOLD 4: Reset|Reset|Reset|DIM -5: White|Reset|Reset|BOLD Rows (column:palette): 0: 0:0 2:1 11:2 28:0 1: 0:0 @@ -94,5 +94,5 @@ Rows (column:palette): 37: 0:0 38: 0:0 39: 0:0 -40: 0:0 2:5 9:2 20:5 21:2 29:5 30:2 43:5 46:2 53:5 58:2 118:0 -41: 0:0 2:5 3:2 14:5 17:2 25:5 26:2 118:0 +40: 0:0 2:1 9:2 20:1 21:2 29:1 30:2 43:1 46:2 53:1 58:2 118:0 +41: 0:0 2:1 3:2 14:1 17:2 25:1 26:2 118:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_5.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_5.snap index 310fe8be49..c2f68771d2 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_5.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_5.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -98,5 +99,5 @@ Rows (column:palette): 37: 0:0 2:6 4:0 38: 0:0 39: 0:0 -40: 0:0 2:5 9:2 20:5 21:2 34:5 37:2 44:5 49:2 118:0 -41: 0:0 2:5 3:2 12:5 13:2 22:5 23:2 34:5 37:2 45:5 46:2 118:0 +40: 0:0 2:1 9:2 20:1 21:2 34:1 37:2 44:1 49:2 118:0 +41: 0:0 2:1 3:2 12:1 13:2 22:1 23:2 34:1 37:2 45:1 46:2 118:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_6.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_6.snap index d05fdf853b..7055b2e97e 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_6.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_6.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -98,5 +99,5 @@ Rows (column:palette): 37: 0:0 2:6 4:0 38: 0:0 39: 0:0 -40: 0:0 2:5 9:2 20:5 21:2 34:5 37:2 44:5 49:2 118:0 -41: 0:0 2:5 3:2 12:5 13:2 24:5 27:2 35:5 36:2 118:0 +40: 0:0 2:1 9:2 20:1 21:2 34:1 37:2 44:1 49:2 118:0 +41: 0:0 2:1 3:2 12:1 13:2 24:1 27:2 35:1 36:2 118:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_8.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_8.snap index 676095f522..28745da194 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_8.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_dark_consumer_8.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -52,7 +53,6 @@ Palette (foreground|background|underline|modifiers): 2: Rgb(165, 165, 165)|Reset|Reset|NONE 3: Cyan|Reset|Reset|BOLD 4: Reset|Reset|Reset|DIM -5: White|Reset|Reset|BOLD Rows (column:palette): 0: 0:0 2:1 11:2 28:0 1: 0:0 @@ -94,5 +94,5 @@ Rows (column:palette): 37: 0:0 38: 0:0 39: 0:0 -40: 0:0 2:5 9:2 20:5 21:2 118:0 -41: 0:0 2:5 3:2 11:5 12:2 23:5 26:2 34:5 35:2 118:0 +40: 0:0 2:1 9:2 20:1 21:2 118:0 +41: 0:0 2:1 3:2 11:1 12:2 23:1 26:2 34:1 35:2 118:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_1.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_1.snap index cfd90d095b..1f63635aea 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_1.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_1.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -56,7 +57,7 @@ Palette (foreground|background|underline|modifiers): 6: Magenta|Reset|Reset|NONE 7: Cyan|Reset|Reset|NONE 8: Rgb(0, 95, 135)|Reset|Reset|BOLD | UNDERLINED -9: White|Reset|Reset|BOLD +9: Black|Reset|Reset|BOLD Rows (column:palette): 0: 0:0 2:1 11:2 28:0 1: 0:0 2:3 6:0 11:2 34:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_2.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_2.snap index 2106e8ff7c..a15617282c 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_2.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_2.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -56,7 +57,7 @@ Palette (foreground|background|underline|modifiers): 6: Magenta|Reset|Reset|NONE 7: Cyan|Reset|Reset|NONE 8: Rgb(0, 95, 135)|Reset|Reset|BOLD | UNDERLINED -9: White|Reset|Reset|BOLD +9: Black|Reset|Reset|BOLD Rows (column:palette): 0: 0:0 2:1 11:2 28:0 1: 0:0 2:3 6:0 11:2 34:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_3.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_3.snap index 02044abe31..49269593e2 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_3.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_3.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -56,7 +57,7 @@ Palette (foreground|background|underline|modifiers): 6: Magenta|Reset|Reset|NONE 7: Cyan|Reset|Reset|NONE 8: Rgb(0, 95, 135)|Reset|Reset|BOLD | UNDERLINED -9: White|Reset|Reset|BOLD +9: Black|Reset|Reset|BOLD Rows (column:palette): 0: 0:0 2:1 11:2 28:0 1: 0:0 2:3 6:0 11:2 34:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_4.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_4.snap index 6cae4149df..8662eb5e28 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_4.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_4.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -52,7 +53,7 @@ Palette (foreground|background|underline|modifiers): 2: Rgb(76, 76, 76)|Reset|Reset|NONE 3: Rgb(0, 95, 135)|Reset|Reset|BOLD 4: Reset|Reset|Reset|DIM -5: White|Reset|Reset|BOLD +5: Black|Reset|Reset|BOLD Rows (column:palette): 0: 0:0 2:1 11:2 28:0 1: 0:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_6.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_6.snap index 30b2bdc74c..9f093b8d45 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_6.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_6.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -56,7 +57,7 @@ Palette (foreground|background|underline|modifiers): 6: Magenta|Reset|Reset|NONE 7: Cyan|Reset|Reset|NONE 8: Rgb(0, 95, 135)|Reset|Reset|BOLD | UNDERLINED -9: White|Reset|Reset|BOLD +9: Black|Reset|Reset|BOLD Rows (column:palette): 0: 0:0 2:1 11:2 28:0 1: 0:0 2:3 6:0 11:2 34:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_8.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_8.snap index b206d89ae3..ca433ec2fa 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_8.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_business_8.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -52,7 +53,7 @@ Palette (foreground|background|underline|modifiers): 2: Rgb(76, 76, 76)|Reset|Reset|NONE 3: Rgb(0, 95, 135)|Reset|Reset|BOLD 4: Reset|Reset|Reset|DIM -5: White|Reset|Reset|BOLD +5: Black|Reset|Reset|BOLD Rows (column:palette): 0: 0:0 2:1 11:2 28:0 1: 0:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_1.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_1.snap index 20ecfe9c38..e645f00b8c 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_1.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_1.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -56,7 +57,7 @@ Palette (foreground|background|underline|modifiers): 6: Magenta|Reset|Reset|NONE 7: Cyan|Reset|Reset|NONE 8: Rgb(0, 95, 135)|Reset|Reset|BOLD | UNDERLINED -9: White|Reset|Reset|BOLD +9: Black|Reset|Reset|BOLD Rows (column:palette): 0: 0:0 2:1 11:2 28:0 1: 0:0 2:3 6:0 11:2 34:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_2.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_2.snap index cd90f58801..1ce6707eae 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_2.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_2.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -56,7 +57,7 @@ Palette (foreground|background|underline|modifiers): 6: Magenta|Reset|Reset|NONE 7: Cyan|Reset|Reset|NONE 8: Rgb(0, 95, 135)|Reset|Reset|BOLD | UNDERLINED -9: White|Reset|Reset|BOLD +9: Black|Reset|Reset|BOLD Rows (column:palette): 0: 0:0 2:1 11:2 28:0 1: 0:0 2:3 6:0 11:2 34:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_4.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_4.snap index 53d82b0d4f..7ad65de1c7 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_4.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_4.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -52,7 +53,7 @@ Palette (foreground|background|underline|modifiers): 2: Rgb(76, 76, 76)|Reset|Reset|NONE 3: Rgb(0, 95, 135)|Reset|Reset|BOLD 4: Reset|Reset|Reset|DIM -5: White|Reset|Reset|BOLD +5: Black|Reset|Reset|BOLD Rows (column:palette): 0: 0:0 2:1 11:2 28:0 1: 0:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_5.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_5.snap index 93ccc1b3fa..c3bc5b7441 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_5.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_5.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -56,7 +57,7 @@ Palette (foreground|background|underline|modifiers): 6: Magenta|Reset|Reset|NONE 7: Cyan|Reset|Reset|NONE 8: Rgb(0, 95, 135)|Reset|Reset|BOLD | UNDERLINED -9: White|Reset|Reset|BOLD +9: Black|Reset|Reset|BOLD Rows (column:palette): 0: 0:0 2:1 11:2 28:0 1: 0:0 2:3 6:0 11:2 34:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_6.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_6.snap index c83d36ce48..1637106ca7 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_6.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_6.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -56,7 +57,7 @@ Palette (foreground|background|underline|modifiers): 6: Magenta|Reset|Reset|NONE 7: Cyan|Reset|Reset|NONE 8: Rgb(0, 95, 135)|Reset|Reset|BOLD | UNDERLINED -9: White|Reset|Reset|BOLD +9: Black|Reset|Reset|BOLD Rows (column:palette): 0: 0:0 2:1 11:2 28:0 1: 0:0 2:3 6:0 11:2 34:0 diff --git a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_8.snap b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_8.snap index 4306d815a6..11182eb8a3 100644 --- a/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_8.snap +++ b/codex-rs/tui/src/analytics/snapshots/codex_tui__analytics__tests__terminal_styles__analytics_light_consumer_8.snap @@ -1,5 +1,6 @@ --- source: tui/src/analytics/styles_tests.rs +assertion_line: 145 expression: snapshot --- 120x42 @@ -52,7 +53,7 @@ Palette (foreground|background|underline|modifiers): 2: Rgb(76, 76, 76)|Reset|Reset|NONE 3: Rgb(0, 95, 135)|Reset|Reset|BOLD 4: Reset|Reset|Reset|DIM -5: White|Reset|Reset|BOLD +5: Black|Reset|Reset|BOLD Rows (column:palette): 0: 0:0 2:1 11:2 28:0 1: 0:0 diff --git a/codex-rs/tui/src/analytics/styles_tests.rs b/codex-rs/tui/src/analytics/styles_tests.rs index 157eed12ba..25f7e3a62e 100644 --- a/codex-rs/tui/src/analytics/styles_tests.rs +++ b/codex-rs/tui/src/analytics/styles_tests.rs @@ -79,19 +79,26 @@ fn analytics_sections_adapt_to_terminal_colors() { assert!(marker.modifier.contains(Modifier::BOLD)); } if theme == "light" { - for cell in &buffer.content { - if !cell.symbol().trim().is_empty() - && let Color::Rgb(r, g, b) = cell.fg - { - let contrast = - (luminance(colors.bg) + 0.05) / (luminance((r, g, b)) + 0.05); - assert!( - contrast >= 4.5, - "{}: {:?} has contrast {contrast}", - cell.symbol(), - cell.fg - ); - } + for cell in buffer + .content + .iter() + .filter(|cell| !cell.symbol().trim().is_empty()) + { + let foreground = match cell.fg { + Color::Rgb(r, g, b) => (r, g, b), + Color::White => (255, 255, 255), + Color::Black => (0, 0, 0), + Color::Reset => colors.fg, + _ => continue, + }; + let contrast = + (luminance(colors.bg) + 0.05) / (luminance(foreground) + 0.05); + assert!( + contrast >= 4.5, + "{}: {:?} has contrast {contrast}", + cell.symbol(), + cell.fg + ); } } // Preserve every symbol and style while sharing repeated styles in a palette. diff --git a/codex-rs/tui/src/analytics_tests.rs b/codex-rs/tui/src/analytics_tests.rs index c945f9dd03..042b460a85 100644 --- a/codex-rs/tui/src/analytics_tests.rs +++ b/codex-rs/tui/src/analytics_tests.rs @@ -11,6 +11,9 @@ mod summary; #[path = "analytics/account_layout_tests.rs"] mod account_layout; +#[path = "analytics/navigation_tests.rs"] +mod navigation; + #[path = "analytics/consumer_refresh_tests.rs"] mod consumer_refresh; diff --git a/codex-rs/tui/src/bottom_pane/experimental_features_view_tests.rs b/codex-rs/tui/src/bottom_pane/experimental_features_view_tests.rs index 9c9122560a..bd8660426e 100644 --- a/codex-rs/tui/src/bottom_pane/experimental_features_view_tests.rs +++ b/codex-rs/tui/src/bottom_pane/experimental_features_view_tests.rs @@ -1,6 +1,27 @@ use super::*; use pretty_assertions::assert_eq; +#[test] +fn experimental_features_analytics_plan_history() { + let feature = Feature::AnalyticsPlanHistory; + let stage = feature.stage(); + let (app_tx, _app_rx) = tokio::sync::mpsc::unbounded_channel(); + let view = ExperimentalFeaturesView::new( + vec![ExperimentalFeatureItem { + key: feature.key().to_string(), + name: stage.experimental_menu_name().unwrap().to_string(), + description: stage.experimental_menu_description().unwrap().to_string(), + enabled: feature.default_enabled(), + writable: true, + }], + ThreadId::new(), + /*catalog_rx*/ None, + AppEventSender::new(app_tx), + crate::keymap::RuntimeKeymap::defaults().list, + ); + snapshot_view("experimental_features_analytics_plan_history", &view); +} + fn server_feature(name: &str) -> ExperimentalFeature { ExperimentalFeature { name: name.to_string(), diff --git a/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__experimental_features_view__tests__experimental_features_analytics_plan_history.snap b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__experimental_features_view__tests__experimental_features_analytics_plan_history.snap new file mode 100644 index 0000000000..048354f30c --- /dev/null +++ b/codex-rs/tui/src/bottom_pane/snapshots/codex_tui__bottom_pane__experimental_features_view__tests__experimental_features_analytics_plan_history.snap @@ -0,0 +1,13 @@ +--- +source: tui/src/bottom_pane/experimental_features_view_tests.rs +expression: buffer_text(&buffer) +--- + + Experimental features + Checked features are configured on. Some experimental features take effect + only in new tasks or after restarting the Codex server. + +› [ ] Analytics plan history Preview five-hour and weekly allowance history + for consumer accounts in /analytics. + + Press space to select or enter to save