diff --git a/codex-rs/features/src/lib.rs b/codex-rs/features/src/lib.rs index c907849cb243..20270ce6f1a9 100644 --- a/codex-rs/features/src/lib.rs +++ b/codex-rs/features/src/lib.rs @@ -99,7 +99,7 @@ pub enum Feature { /// on either `unified_exec` or `shell_zsh_fork` because those features have /// separate rollout and enterprise controls. UnifiedExecZshFork, - /// Reflow transcript scrollback when the terminal is resized. + /// Removed compatibility flag. Transcript scrollback reflow on terminal resize is always on. TerminalResizeReflow, /// Add terminal-specific visualization guidance to TUI developer instructions. TerminalVisualizationInstructions, @@ -461,6 +461,9 @@ impl Features { "skill_env_var_dependency_prompt" => { continue; } + "terminal_resize_reflow" => { + continue; + } "use_legacy_landlock" => { self.record_legacy_usage_force( "features.use_legacy_landlock", @@ -807,11 +810,7 @@ pub const FEATURES: &[FeatureSpec] = &[ FeatureSpec { id: Feature::TerminalResizeReflow, key: "terminal_resize_reflow", - stage: Stage::Experimental { - name: "Terminal resize reflow", - menu_description: "Rebuild Codex-owned transcript scrollback when the terminal width changes.", - announcement: "", - }, + stage: Stage::Removed, default_enabled: true, }, FeatureSpec { diff --git a/codex-rs/features/src/tests.rs b/codex-rs/features/src/tests.rs index 4f02815e4170..0995dfe01960 100644 --- a/codex-rs/features/src/tests.rs +++ b/codex-rs/features/src/tests.rs @@ -32,8 +32,7 @@ fn default_enabled_features_are_stable() { for spec in crate::FEATURES { if spec.default_enabled { assert!( - matches!(spec.stage, Stage::Stable | Stage::Removed) - || spec.id == Feature::TerminalResizeReflow, + matches!(spec.stage, Stage::Stable | Stage::Removed), "feature `{}` is enabled by default but is not stable/removed ({:?})", spec.key, spec.stage @@ -151,18 +150,35 @@ fn request_permissions_tool_is_under_development() { } #[test] -fn terminal_resize_reflow_is_experimental_and_enabled_by_default() { +fn terminal_resize_reflow_is_removed_and_enabled_by_default() { assert_eq!( feature_for_key("terminal_resize_reflow"), Some(Feature::TerminalResizeReflow) ); - assert!(matches!( - Feature::TerminalResizeReflow.stage(), - Stage::Experimental { .. } - )); + assert_eq!(Feature::TerminalResizeReflow.stage(), Stage::Removed); assert_eq!(Feature::TerminalResizeReflow.default_enabled(), true); } +#[test] +fn from_sources_ignores_removed_terminal_resize_reflow_feature_key() { + let features_toml = FeaturesToml::from(BTreeMap::from([( + "terminal_resize_reflow".to_string(), + false, + )])); + + let features = Features::from_sources( + FeatureConfigSource { + features: Some(&features_toml), + ..Default::default() + }, + FeatureConfigSource::default(), + FeatureOverrides::default(), + ); + + assert_eq!(features, Features::with_defaults()); + assert_eq!(features.enabled(Feature::TerminalResizeReflow), true); +} + #[test] fn tool_suggest_is_stable_and_enabled_by_default() { assert_eq!(Feature::ToolSuggest.stage(), Stage::Stable); diff --git a/codex-rs/tui/src/app.rs b/codex-rs/tui/src/app.rs index abc86ca67b9b..e442d235d2c0 100644 --- a/codex-rs/tui/src/app.rs +++ b/codex-rs/tui/src/app.rs @@ -1248,16 +1248,8 @@ See the Codex keymap documentation for supported actions and examples." app_server: &mut AppServerSession, event: TuiEvent, ) -> Result { - let terminal_resize_reflow_enabled = self.terminal_resize_reflow_enabled(); - if self.should_handle_draw_pre_render() - && matches!(event, TuiEvent::Draw | TuiEvent::Resize) - { + if matches!(event, TuiEvent::Draw | TuiEvent::Resize) { self.handle_draw_pre_render(tui)?; - } else if matches!(event, TuiEvent::Draw | TuiEvent::Resize) { - let size = tui.terminal.size()?; - if size != tui.terminal.last_known_screen_size { - self.refresh_status_line(); - } } if self.overlay.is_some() { @@ -1289,8 +1281,7 @@ See the Codex keymap documentation for supported actions and examples." } // Allow widgets to process any pending timers before rendering. self.chat_widget.pre_draw_tick(); - let rendered_area = - self.render_chat_widget_frame(tui, terminal_resize_reflow_enabled)?; + let rendered_area = self.render_chat_widget_frame(tui)?; if self.chat_widget.ambient_pet_image_enabled() { let terminal_size = tui.terminal.size()?; let ambient_pet_area = Rect::new( @@ -1329,43 +1320,24 @@ See the Codex keymap documentation for supported actions and examples." pub(super) fn show_shutdown_feedback(&mut self, tui: &mut tui::Tui) -> Result<()> { self.disable_ambient_pet_before_shutdown(tui)?; self.chat_widget.show_shutdown_in_progress(); - let terminal_resize_reflow_enabled = self.terminal_resize_reflow_enabled(); - if self.should_handle_draw_pre_render() { - self.handle_draw_pre_render(tui)?; - } + self.handle_draw_pre_render(tui)?; self.chat_widget.pre_draw_tick(); - self.render_chat_widget_frame(tui, terminal_resize_reflow_enabled)?; + self.render_chat_widget_frame(tui)?; Ok(()) } - fn render_chat_widget_frame( - &mut self, - tui: &mut tui::Tui, - terminal_resize_reflow_enabled: bool, - ) -> Result { + fn render_chat_widget_frame(&mut self, tui: &mut tui::Tui) -> Result { let desired_height = self.chat_widget.desired_height(tui.terminal.size()?.width); let mut rendered_area = Rect::default(); - if terminal_resize_reflow_enabled { - tui.draw_with_resize_reflow(desired_height, |frame| { - let area = frame.area(); - rendered_area = area; - self.chat_widget.render(area, frame.buffer); - if let Some((x, y)) = self.chat_widget.cursor_pos(area) { - frame.set_cursor_style(self.chat_widget.cursor_style(area)); - frame.set_cursor_position((x, y)); - } - })?; - } else { - tui.draw(desired_height, |frame| { - let area = frame.area(); - rendered_area = area; - self.chat_widget.render(area, frame.buffer); - if let Some((x, y)) = self.chat_widget.cursor_pos(area) { - frame.set_cursor_style(self.chat_widget.cursor_style(area)); - frame.set_cursor_position((x, y)); - } - })?; - } + tui.draw_with_resize_reflow(desired_height, |frame| { + let area = frame.area(); + rendered_area = area; + self.chat_widget.render(area, frame.buffer); + if let Some((x, y)) = self.chat_widget.cursor_pos(area) { + frame.set_cursor_style(self.chat_widget.cursor_style(area)); + frame.set_cursor_position((x, y)); + } + })?; Ok(rendered_area) } } diff --git a/codex-rs/tui/src/app/event_dispatch.rs b/codex-rs/tui/src/app/event_dispatch.rs index 6c6a31ee63a1..0a3ab007a8f8 100644 --- a/codex-rs/tui/src/app/event_dispatch.rs +++ b/codex-rs/tui/src/app/event_dispatch.rs @@ -249,14 +249,6 @@ impl App { self.insert_completed_token_activity_output_after_stream_shutdown(tui); } AppEvent::ConsolidateProposedPlan(source) => { - if !self.terminal_resize_reflow_enabled() { - if !self.transcript_reflow.history_cell_refresh_requested() { - self.transcript_reflow.clear(); - } - self.chat_widget.note_stream_consolidation_completed(); - self.insert_completed_token_activity_output_after_stream_shutdown(tui); - return Ok(AppRunControl::Continue); - } let end = self.transcript_cells.len(); let start = trailing_run_start::( &self.transcript_cells, diff --git a/codex-rs/tui/src/app/resize_reflow.rs b/codex-rs/tui/src/app/resize_reflow.rs index 948c1bbfa50f..fd5efd2d9480 100644 --- a/codex-rs/tui/src/app/resize_reflow.rs +++ b/codex-rs/tui/src/app/resize_reflow.rs @@ -18,7 +18,6 @@ use std::collections::VecDeque; use std::sync::Arc; use std::time::Instant; -use codex_features::Feature; use color_eyre::eyre::Result; use ratatui::text::Line; @@ -109,18 +108,14 @@ impl App { } } - pub(super) fn terminal_resize_reflow_enabled(&self) -> bool { - self.config.features.enabled(Feature::TerminalResizeReflow) - } - /// Start retaining initial resume replay rows before they are written to scrollback. /// /// Resume replay can insert thousands of already-finalized history cells before the first draw. - /// When resize reflow is enabled, buffering here lets the same row cap used by resize rebuilds - /// apply to the startup write. Starting this buffer while an overlay owns rendering would split - /// transcript ownership, so overlay replay continues through the normal deferred-history path. + /// Buffering here lets the same row cap used by resize rebuilds apply to the startup write. + /// Starting this buffer while an overlay owns rendering would split transcript ownership, so + /// overlay replay continues through the normal deferred-history path. pub(super) fn begin_initial_history_replay_buffer(&mut self) { - if self.terminal_resize_reflow_enabled() && self.overlay.is_none() { + if self.overlay.is_none() { self.initial_history_replay_buffer = Some(Default::default()); } } @@ -131,10 +126,7 @@ impl App { /// defer terminal writes until the replay is complete and reuse the resize-reflow tail renderer /// so only the rows the terminal would retain are formatted and inserted. pub(super) fn begin_thread_switch_history_replay_buffer(&mut self) { - if self.terminal_resize_reflow_enabled() - && self.resize_reflow_max_rows().is_some() - && self.overlay.is_none() - { + if self.resize_reflow_max_rows().is_some() && self.overlay.is_none() { self.initial_history_replay_buffer = Some(InitialHistoryReplayBuffer { retained_lines: VecDeque::new(), render_from_transcript_tail: true, @@ -233,7 +225,6 @@ impl App { } fn schedule_resize_reflow(&mut self, target_width: Option) -> bool { - debug_assert!(self.terminal_resize_reflow_enabled()); self.transcript_reflow.schedule_debounced(target_width) } @@ -263,19 +254,6 @@ impl App { /// source-backed reflow so terminal scrollback reflects the finalized cell instead of the /// transient stream rows. pub(super) fn maybe_finish_stream_reflow(&mut self, tui: &mut tui::Tui) -> Result<()> { - if !self.terminal_resize_reflow_enabled() { - if self.transcript_reflow.take_stream_finish_reflow_needed() { - self.schedule_immediate_history_cell_refresh(tui); - self.maybe_run_resize_reflow(tui)?; - return Ok(()); - } - if self.transcript_reflow.history_cell_refresh_requested() { - return Ok(()); - } - self.transcript_reflow.clear(); - return Ok(()); - } - if self.transcript_reflow.take_stream_finish_reflow_needed() { self.schedule_immediate_resize_reflow(tui); self.maybe_run_resize_reflow(tui)?; @@ -286,42 +264,16 @@ impl App { } fn schedule_immediate_resize_reflow(&mut self, tui: &mut tui::Tui) { - if !self.terminal_resize_reflow_enabled() { - self.transcript_reflow.clear(); - return; - } self.transcript_reflow.schedule_immediate(); tui.frame_requester().schedule_frame(); } - fn schedule_immediate_history_cell_refresh(&mut self, tui: &mut tui::Tui) { - self.transcript_reflow.schedule_history_cell_refresh(); - tui.frame_requester().schedule_frame(); - } - - pub(crate) fn retry_pending_history_cell_refresh(&self, tui: &mut tui::Tui) { - if self.transcript_reflow.history_cell_refresh_requested() { - tui.frame_requester().schedule_frame(); - } - } - - pub(super) fn should_handle_draw_pre_render(&self) -> bool { - self.terminal_resize_reflow_enabled() - || self.transcript_reflow.history_cell_refresh_requested() - } - /// Force stream-finalized output through the resize reflow path. /// /// Proposed plan consolidation uses this stricter path because a completed plan is inserted or /// replaced as one styled source-backed cell. If this reflow is skipped after a stream-time /// resize, the visible scrollback can keep the pre-consolidation wrapping. pub(super) fn finish_required_stream_reflow(&mut self, tui: &mut tui::Tui) -> Result<()> { - if !self.terminal_resize_reflow_enabled() { - if !self.transcript_reflow.history_cell_refresh_requested() { - self.transcript_reflow.clear(); - } - return Ok(()); - } self.schedule_immediate_resize_reflow(tui); self.maybe_run_resize_reflow(tui)?; if !self.transcript_reflow.has_pending_reflow() { @@ -350,37 +302,24 @@ impl App { self.chat_widget.on_terminal_resize(size.width); } if should_rebuild_transcript { - if self.terminal_resize_reflow_enabled() { - if reflow_needed && self.should_mark_reflow_as_stream_time() { - self.transcript_reflow.mark_resize_requested_during_stream(); - } - let target_width = reflow_needed.then_some(size.width); - if self.schedule_resize_reflow(target_width) { - frame_requester.schedule_frame(); - } else { - frame_requester.schedule_frame_in(TRANSCRIPT_REFLOW_DEBOUNCE); - } - } else if !self.terminal_resize_reflow_enabled() - && width.changed - && !self.transcript_reflow.history_cell_refresh_requested() - { - self.transcript_reflow.clear(); + if reflow_needed && self.should_mark_reflow_as_stream_time() { + self.transcript_reflow.mark_resize_requested_during_stream(); + } + let target_width = reflow_needed.then_some(size.width); + if self.schedule_resize_reflow(target_width) { + frame_requester.schedule_frame(); + } else { + frame_requester.schedule_frame_in(TRANSCRIPT_REFLOW_DEBOUNCE); } } if size != last_known_screen_size { self.refresh_status_line(); } - if self.terminal_resize_reflow_enabled() { - self.maybe_clear_resize_reflow_without_terminal(); - } + self.maybe_clear_resize_reflow_without_terminal(); should_rebuild_transcript } fn maybe_clear_resize_reflow_without_terminal(&mut self) { - if !self.terminal_resize_reflow_enabled() { - self.transcript_reflow.clear(); - return; - } let Some(deadline) = self.transcript_reflow.pending_until() else { return; }; @@ -400,7 +339,7 @@ impl App { tui.terminal.last_known_screen_size, &tui.frame_requester(), ); - if should_rebuild_transcript && self.terminal_resize_reflow_enabled() { + if should_rebuild_transcript { // Resize-sensitive history inserts queued before this frame may be wrapped for the old // viewport or targeted at rows no longer visible. Drop them and let resize reflow // rebuild from transcript cells. @@ -417,12 +356,6 @@ impl App { /// reuse terminal-wrapped output here would preserve exactly the stale wrapping this feature is /// meant to remove. pub(super) fn maybe_run_resize_reflow(&mut self, tui: &mut tui::Tui) -> Result<()> { - if !self.terminal_resize_reflow_enabled() - && !self.transcript_reflow.history_cell_refresh_requested() - { - self.transcript_reflow.clear(); - return Ok(()); - } let Some(deadline) = self.transcript_reflow.pending_until() else { return Ok(()); }; diff --git a/codex-rs/tui/src/app/tests.rs b/codex-rs/tui/src/app/tests.rs index ea6b491043ee..41a72a47c2d8 100644 --- a/codex-rs/tui/src/app/tests.rs +++ b/codex-rs/tui/src/app/tests.rs @@ -4400,13 +4400,6 @@ fn test_thread_session(thread_id: ThreadId, cwd: PathBuf) -> ThreadSessionState } } -fn enable_terminal_resize_reflow(app: &mut App) { - app.config - .features - .set_enabled(Feature::TerminalResizeReflow, /*enabled*/ true) - .expect("feature should be configurable"); -} - fn plain_line_cell(text: impl Into) -> Arc { Arc::new(PlainHistoryCell::new(vec![Line::from(text.into())])) as Arc } @@ -4516,7 +4509,6 @@ async fn uncapped_resize_reflow_renders_all_cells_under_row_limit() { #[tokio::test] async fn initial_replay_buffer_keeps_recent_rows_when_row_cap_present() { let (mut app, _rx, _op_rx) = make_test_app_with_channels().await; - enable_terminal_resize_reflow(&mut app); app.config.terminal_resize_reflow.max_rows = TerminalResizeReflowMaxRows::Limit(3); app.begin_initial_history_replay_buffer(); @@ -4551,7 +4543,6 @@ async fn initial_replay_buffer_keeps_recent_rows_when_row_cap_present() { #[tokio::test] async fn thread_switch_replay_buffer_uses_transcript_tail_mode_when_row_cap_present() { let (mut app, _rx, _op_rx) = make_test_app_with_channels().await; - enable_terminal_resize_reflow(&mut app); app.config.terminal_resize_reflow.max_rows = TerminalResizeReflowMaxRows::Limit(3); app.begin_thread_switch_history_replay_buffer(); @@ -4567,7 +4558,6 @@ async fn thread_switch_replay_buffer_uses_transcript_tail_mode_when_row_cap_pres #[tokio::test] async fn thread_switch_replay_buffer_is_disabled_without_row_cap() { let (mut app, _rx, _op_rx) = make_test_app_with_channels().await; - enable_terminal_resize_reflow(&mut app); app.config.terminal_resize_reflow.max_rows = TerminalResizeReflowMaxRows::Disabled; app.begin_thread_switch_history_replay_buffer(); @@ -4578,7 +4568,6 @@ async fn thread_switch_replay_buffer_is_disabled_without_row_cap() { #[tokio::test] async fn height_shrink_schedules_resize_reflow() { let (mut app, _rx, _op_rx) = make_test_app_with_channels().await; - enable_terminal_resize_reflow(&mut app); let frame_requester = crate::tui::FrameRequester::test_dummy(); assert!(!app.handle_draw_size_change( @@ -4595,32 +4584,6 @@ async fn height_shrink_schedules_resize_reflow() { assert!(app.transcript_reflow.has_pending_reflow()); } -#[tokio::test] -async fn disabled_resize_reflow_preserves_pending_history_cell_refresh() { - let (mut app, _rx, _op_rx) = make_test_app_with_channels().await; - let frame_requester = crate::tui::FrameRequester::test_dummy(); - app.config - .features - .set_enabled(Feature::TerminalResizeReflow, /*enabled*/ false) - .expect("feature should be configurable"); - assert!(!app.should_handle_draw_pre_render()); - app.transcript_reflow.schedule_history_cell_refresh(); - assert!(app.should_handle_draw_pre_render()); - - assert!(!app.handle_draw_size_change( - ratatui::layout::Size::new(/*width*/ 118, /*height*/ 35), - ratatui::layout::Size::new(/*width*/ 118, /*height*/ 35), - &frame_requester, - )); - assert!(app.handle_draw_size_change( - ratatui::layout::Size::new(/*width*/ 119, /*height*/ 35), - ratatui::layout::Size::new(/*width*/ 118, /*height*/ 35), - &frame_requester, - )); - - assert!(app.transcript_reflow.history_cell_refresh_requested()); -} - fn test_turn(turn_id: &str, status: TurnStatus, items: Vec) -> Turn { Turn { id: turn_id.to_string(), diff --git a/codex-rs/tui/src/app/thread_routing.rs b/codex-rs/tui/src/app/thread_routing.rs index c8c36e23a25b..1783f0ec6126 100644 --- a/codex-rs/tui/src/app/thread_routing.rs +++ b/codex-rs/tui/src/app/thread_routing.rs @@ -1098,8 +1098,7 @@ impl App { self.chat_widget .set_initial_user_message_submit_suppressed(/*suppressed*/ true); self.chat_widget.handle_thread_session(session); - let should_buffer_initial_replay = - self.terminal_resize_reflow_enabled() && !turns.is_empty(); + let should_buffer_initial_replay = !turns.is_empty(); if should_buffer_initial_replay { self.app_event_tx .send(AppEvent::BeginInitialHistoryReplayBuffer); @@ -1289,8 +1288,7 @@ impl App { resume_restored_queue: bool, ) { self.refresh_mcp_startup_expected_servers_from_config(); - let should_buffer_replay = self.terminal_resize_reflow_enabled() - && (!snapshot.turns.is_empty() || !snapshot.events.is_empty()); + let should_buffer_replay = !snapshot.turns.is_empty() || !snapshot.events.is_empty(); if should_buffer_replay { self.app_event_tx .send(AppEvent::BeginThreadSwitchHistoryReplayBuffer); diff --git a/codex-rs/tui/src/app_backtrack.rs b/codex-rs/tui/src/app_backtrack.rs index b285d8b7c64e..04020787ad41 100644 --- a/codex-rs/tui/src/app_backtrack.rs +++ b/codex-rs/tui/src/app_backtrack.rs @@ -294,7 +294,7 @@ impl App { } self.overlay = None; self.backtrack.overlay_preview_active = false; - self.retry_pending_history_cell_refresh(tui); + tui.frame_requester().schedule_frame(); if was_backtrack { // Ensure backtrack state is fully reset when overlay closes (e.g. via 'q'). self.reset_backtrack_state(); diff --git a/codex-rs/tui/src/chatwidget.rs b/codex-rs/tui/src/chatwidget.rs index fb89fda2e3c9..232890ed191d 100644 --- a/codex-rs/tui/src/chatwidget.rs +++ b/codex-rs/tui/src/chatwidget.rs @@ -1652,9 +1652,8 @@ impl ChatWidget { /// Update resize-sensitive chat widget state after the terminal width changes. /// - /// The app calls this even when terminal resize reflow is disabled so live stream wrapping - /// remains consistent with the current viewport. Finalized transcript rebuilding stays gated at - /// the app layer. + /// Live stream wrapping stays consistent with the current viewport while finalized transcript + /// rebuilding runs through app-level resize reflow. pub(crate) fn on_terminal_resize(&mut self, width: u16) { let had_rendered_width = self.last_rendered_width.get().is_some(); self.last_rendered_width.set(Some(width as usize)); diff --git a/codex-rs/tui/src/transcript_reflow.rs b/codex-rs/tui/src/transcript_reflow.rs index 56e76a686e5b..d95d99c944b3 100644 --- a/codex-rs/tui/src/transcript_reflow.rs +++ b/codex-rs/tui/src/transcript_reflow.rs @@ -29,7 +29,6 @@ pub(crate) struct TranscriptReflowState { last_reflow_width: Option, pending_reflow_width: Option, pending_until: Option, - history_cell_refresh_requested: bool, ran_during_stream: bool, resize_requested_during_stream: bool, } @@ -37,9 +36,9 @@ pub(crate) struct TranscriptReflowState { impl TranscriptReflowState { /// Reset all width, pending deadline, and stream repair state. /// - /// Call this when resize reflow is disabled or when the app discards the transcript state that - /// pending reflow work would have rebuilt. Leaving stale deadlines behind would make a later - /// draw attempt to rebuild history from unrelated cells. + /// Call this when the app discards the transcript state that pending reflow work would have + /// rebuilt. Leaving stale deadlines behind would make a later draw attempt to rebuild history + /// from unrelated cells. pub(crate) fn clear(&mut self) { *self = Self::default(); } @@ -94,12 +93,6 @@ impl TranscriptReflowState { self.pending_until = Some(Instant::now()); } - /// Schedule an immediate rebuild because an existing history cell changed its rendered output. - pub(crate) fn schedule_history_cell_refresh(&mut self) { - self.history_cell_refresh_requested = true; - self.schedule_immediate(); - } - #[cfg(test)] pub(crate) fn set_due_for_test(&mut self) { self.pending_until = Some(Instant::now() - Duration::from_millis(1)); @@ -117,14 +110,9 @@ impl TranscriptReflowState { self.pending_until.is_some() } - pub(crate) fn history_cell_refresh_requested(&self) -> bool { - self.history_cell_refresh_requested - } - pub(crate) fn clear_pending_reflow(&mut self) { self.pending_until = None; self.pending_reflow_width = None; - self.history_cell_refresh_requested = false; } /// Remember the terminal width that actually rebuilt transcript scrollback. @@ -274,17 +262,6 @@ mod tests { assert!(state.reflow_needed_for_width(/*width*/ 100)); } - #[test] - fn clear_pending_reflow_clears_history_cell_refresh_request() { - let mut state = TranscriptReflowState::default(); - state.schedule_history_cell_refresh(); - - assert!(state.history_cell_refresh_requested()); - state.clear_pending_reflow(); - - assert!(!state.history_cell_refresh_requested()); - } - #[test] fn mark_reflowed_width_reports_unchanged_width() { let mut state = TranscriptReflowState::default(); diff --git a/codex-rs/tui/tests/suite/resize_reflow.rs b/codex-rs/tui/tests/suite/resize_reflow.rs index af5ed445b268..033e1693ce0c 100644 --- a/codex-rs/tui/tests/suite/resize_reflow.rs +++ b/codex-rs/tui/tests/suite/resize_reflow.rs @@ -31,11 +31,7 @@ async fn tmux_split_preserves_fresh_session_composer_row_after_resize_reflow() - let server = MockServer::start().await; let _response_mock = responses::mount_sse_once(&server, resize_reflow_sse()).await; let openai_base_url_config = format!("openai_base_url=\"{}/v1\"", server.uri()); - write_config( - codex_home.path(), - &repo_root, - /*terminal_resize_reflow_enabled*/ true, - )?; + write_config(codex_home.path(), &repo_root)?; write_auth(codex_home.path())?; let session_name = format!("codex-resize-reflow-smoke-{}", std::process::id()); @@ -179,8 +175,7 @@ async fn tmux_repeated_resizes_do_not_push_composer_down() -> Result<()> { return Ok(()); } - run_repeated_resize_smoke(/*terminal_resize_reflow_enabled*/ false).await?; - run_repeated_resize_smoke(/*terminal_resize_reflow_enabled*/ true).await?; + run_repeated_resize_smoke().await?; Ok(()) } @@ -203,11 +198,7 @@ async fn tmux_width_resize_restore_keeps_visible_content_anchored() -> Result<() let server = MockServer::start().await; let _response_mock = responses::mount_sse_once(&server, resize_reflow_sse()).await; let openai_base_url_config = format!("openai_base_url=\"{}/v1\"", server.uri()); - write_config( - codex_home.path(), - &repo_root, - /*terminal_resize_reflow_enabled*/ true, - )?; + write_config(codex_home.path(), &repo_root)?; write_auth(codex_home.path())?; let session_name = format!("codex-resize-width-{}", std::process::id()); @@ -320,26 +311,17 @@ async fn tmux_width_resize_restore_keeps_visible_content_anchored() -> Result<() Ok(()) } -async fn run_repeated_resize_smoke(terminal_resize_reflow_enabled: bool) -> Result<()> { +async fn run_repeated_resize_smoke() -> Result<()> { let repo_root = codex_utils_cargo_bin::repo_root()?; let codex = codex_binary(&repo_root)?; let codex_home = tempdir()?; let server = MockServer::start().await; let _response_mock = responses::mount_sse_once(&server, resize_reflow_sse()).await; let openai_base_url_config = format!("openai_base_url=\"{}/v1\"", server.uri()); - write_config( - codex_home.path(), - &repo_root, - terminal_resize_reflow_enabled, - )?; + write_config(codex_home.path(), &repo_root)?; write_auth(codex_home.path())?; - let suffix = if terminal_resize_reflow_enabled { - "enabled" - } else { - "disabled" - }; - let session_name = format!("codex-resize-repeat-{suffix}-{}", std::process::id()); + let session_name = format!("codex-resize-repeat-{}", std::process::id()); let _session = TmuxSession { name: session_name.clone(), }; @@ -433,30 +415,20 @@ async fn run_repeated_resize_smoke(terminal_resize_reflow_enabled: bool) -> Resu let restored_history_row = first_row_containing(&restored_capture, "resize reflow sentinel") .with_context(|| format!("history row after resize cycle {cycle}"))?; - if terminal_resize_reflow_enabled { - anyhow::ensure!( - restored_row == baseline_row, - "composer row drifted after resize cycle {cycle} with terminal_resize_reflow={terminal_resize_reflow_enabled}: \ - baseline={baseline_row}, restored={restored_row}\n\ - baseline:\n{baseline_capture}\n\ - restored:\n{restored_capture}" - ); - anyhow::ensure!( - restored_history_row == baseline_history_row, - "history row drifted after resize cycle {cycle} with terminal_resize_reflow={terminal_resize_reflow_enabled}: \ - baseline={baseline_history_row}, restored={restored_history_row}\n\ - baseline:\n{baseline_capture}\n\ - restored:\n{restored_capture}" - ); - } else { - anyhow::ensure!( - restored_row <= baseline_row + 1, - "composer row snapped downward after resize cycle {cycle} with terminal_resize_reflow={terminal_resize_reflow_enabled}: \ - baseline={baseline_row}, restored={restored_row}\n\ - baseline:\n{baseline_capture}\n\ - restored:\n{restored_capture}" - ); - } + anyhow::ensure!( + restored_row == baseline_row, + "composer row drifted after resize cycle {cycle}: baseline={baseline_row}, \ + restored={restored_row}\n\ + baseline:\n{baseline_capture}\n\ + restored:\n{restored_capture}" + ); + anyhow::ensure!( + restored_history_row == baseline_history_row, + "history row drifted after resize cycle {cycle}: baseline={baseline_history_row}, \ + restored={restored_history_row}\n\ + baseline:\n{baseline_capture}\n\ + restored:\n{restored_capture}" + ); } Ok(()) @@ -489,20 +461,13 @@ fn codex_binary(repo_root: &Path) -> Result { Ok(fallback) } -fn write_config( - codex_home: &Path, - repo_root: &Path, - terminal_resize_reflow_enabled: bool, -) -> Result<()> { +fn write_config(codex_home: &Path, repo_root: &Path) -> Result<()> { let repo_root_display = repo_root.display(); let config = format!( r#"model = "gpt-5.4" model_provider = "openai" suppress_unstable_features_warning = true -[features] -terminal_resize_reflow = {terminal_resize_reflow_enabled} - [projects."{repo_root_display}"] trust_level = "trusted" "#