diff --git a/code-rs/core/src/cgroup.rs b/code-rs/core/src/cgroup.rs index 689810ff0be..5fe5c3705d0 100644 --- a/code-rs/core/src/cgroup.rs +++ b/code-rs/core/src/cgroup.rs @@ -1,3 +1,4 @@ +#[cfg(target_os = "linux")] use std::path::{Path, PathBuf}; #[cfg(target_os = "linux")] @@ -174,22 +175,27 @@ pub(crate) fn best_effort_cleanup_exec_cgroup(pid: u32) { } #[cfg(not(target_os = "linux"))] +#[allow(dead_code)] pub(crate) fn default_exec_memory_max_bytes() -> Option { None } #[cfg(not(target_os = "linux"))] +#[allow(dead_code)] pub(crate) fn best_effort_attach_self_to_exec_cgroup(_pid: u32, _memory_max_bytes: u64) {} #[cfg(not(target_os = "linux"))] +#[allow(dead_code)] pub(crate) fn exec_cgroup_oom_killed(_pid: u32) -> Option { None } #[cfg(not(target_os = "linux"))] +#[allow(dead_code)] pub(crate) fn exec_cgroup_memory_max_bytes(_pid: u32) -> Option { None } #[cfg(not(target_os = "linux"))] +#[allow(dead_code)] pub(crate) fn best_effort_cleanup_exec_cgroup(_pid: u32) {} diff --git a/code-rs/core/src/exec.rs b/code-rs/core/src/exec.rs index 2d294d458b8..42cd69bcdd0 100644 --- a/code-rs/core/src/exec.rs +++ b/code-rs/core/src/exec.rs @@ -564,8 +564,14 @@ async fn consume_truncated_output( combined_handle.await.map_err(CodexErr::from)? }; + #[cfg(target_os = "linux")] let mut oom_killed = false; + #[cfg(target_os = "linux")] let mut cgroup_memory_max_bytes: Option = None; + #[cfg(not(target_os = "linux"))] + let oom_killed = false; + #[cfg(not(target_os = "linux"))] + let cgroup_memory_max_bytes: Option = None; #[cfg(target_os = "linux")] { if !timed_out { diff --git a/code-rs/core/src/spawn.rs b/code-rs/core/src/spawn.rs index 7d903356a57..f2a744cd92c 100644 --- a/code-rs/core/src/spawn.rs +++ b/code-rs/core/src/spawn.rs @@ -135,8 +135,6 @@ pub(crate) async fn spawn_child_async( StdioPolicy::RedirectForShellTool => crate::cgroup::default_exec_memory_max_bytes(), StdioPolicy::Inherit => None, }; - #[cfg(not(target_os = "linux"))] - let exec_memory_max_bytes: Option = None; cmd.pre_exec(move || { // Start a new process group let _ = libc::setpgid(0, 0); diff --git a/code-rs/tui/src/app.rs b/code-rs/tui/src/app.rs index 5e8dc5d00b3..32b938654ae 100644 --- a/code-rs/tui/src/app.rs +++ b/code-rs/tui/src/app.rs @@ -72,6 +72,12 @@ const BACKPRESSURE_FORCED_DRAW_SKIPS: u32 = 4; const DEFAULT_PTY_ROWS: u16 = 24; const DEFAULT_PTY_COLS: u16 = 80; +fn config_for_new_chat(config: &Config) -> Config { + let mut new_config = config.clone(); + new_config.experimental_resume = None; + new_config +} + /// Top-level application state: which full-screen view is currently active. #[allow(clippy::large_enum_variant)] enum AppState<'a> { @@ -2225,7 +2231,7 @@ impl App<'_> { // Start a brand new conversation (core session) with no carried history. // Replace the chat widget entirely, mirroring SwitchCwd flow but without import. let mut new_widget = ChatWidget::new( - self.config.clone(), + config_for_new_chat(&self.config), self.app_event_tx.clone(), None, Vec::new(), @@ -3977,3 +3983,27 @@ mod next_event_priority_tests { ); } } + +#[cfg(test)] +mod new_chat_config_tests { + use super::config_for_new_chat; + use code_core::config::{ConfigOverrides, ConfigToml, Config}; + + #[test] + fn new_chat_config_clears_resume_path() { + let temp = tempfile::tempdir().expect("tempdir"); + let mut config = Config::load_from_base_config_with_overrides( + ConfigToml::default(), + ConfigOverrides::default(), + temp.path().to_path_buf(), + ) + .expect("load config"); + config.experimental_resume = Some(temp.path().join("resume.json")); + + let new_config = config_for_new_chat(&config); + assert!( + new_config.experimental_resume.is_none(), + "new chat should not carry experimental_resume" + ); + } +} diff --git a/code-rs/tui/src/chatwidget.rs b/code-rs/tui/src/chatwidget.rs index 2fd2ec0a1d3..82568ea0cbf 100644 --- a/code-rs/tui/src/chatwidget.rs +++ b/code-rs/tui/src/chatwidget.rs @@ -6722,7 +6722,8 @@ impl ChatWidget<'_> { let _ = w.history_insert_plain_state_with_key(notice_state, notice_key, "prelude"); if connecting_mcp && !w.test_mode { // Render connecting status as a separate cell with standard gutter and spacing - w.history_push_top_next_req(history_cell::new_connecting_mcp_status()); + let message = history_cell::connecting_mcp_status_message(); + w.insert_background_event_prelude(message); } // Mark welcome as shown to avoid duplicating the Popular commands section // when SessionConfigured arrives shortly after. @@ -10401,6 +10402,19 @@ impl ChatWidget<'_> { Some(ticket.next_order()), ); } + /// Insert a background event ahead of the very first user prompt. + pub(crate) fn insert_background_event_prelude(&mut self, message: String) { + let cell = history_cell::new_background_event(message); + let record = HistoryDomainRecord::BackgroundEvent(cell.state().clone()); + self.push_system_cell( + Box::new(cell), + SystemPlacement::PrePromptInCurrent, + None, + None, + "background", + Some(record), + ); + } /// Insert a background event using the specified placement semantics. pub(crate) fn insert_background_event_with_placement( &mut self, @@ -25037,6 +25051,8 @@ Have we met every part of this goal and is there no further work to do?"# self.bottom_pane.set_task_running(false); self.bottom_pane.clear_live_ring(); self.maybe_hide_spinner(); + self.flush_history_snapshot_if_needed(true); + self.submit_op(Op::Shutdown); } pub(crate) fn register_approved_command( diff --git a/code-rs/tui/src/history_cell/mod.rs b/code-rs/tui/src/history_cell/mod.rs index 3c49506197a..f59df955607 100644 --- a/code-rs/tui/src/history_cell/mod.rs +++ b/code-rs/tui/src/history_cell/mod.rs @@ -2243,17 +2243,11 @@ pub(crate) fn new_popular_commands_notice( plain_message_state_from_lines(lines, HistoryCellType::Notice) } -/// Background status cell shown during startup while external MCP servers -/// are being connected. Uses the standard background-event gutter (») -/// and inserts a blank line above the message for visual separation from -/// the Popular commands block. -pub(crate) fn new_connecting_mcp_status() -> BackgroundEventCell { - let record = BackgroundEventRecord { - id: HistoryId::ZERO, - title: String::new(), - description: "\nConnecting MCP servers…".to_string(), - }; - BackgroundEventCell::new(record) +/// Background status message shown during startup while external MCP servers +/// are being connected. Includes a blank line above the text for visual +/// separation from the Popular commands block. +pub(crate) fn connecting_mcp_status_message() -> String { + "\nConnecting MCP servers…".to_string() } pub(crate) fn new_user_prompt(message: String) -> PlainMessageState {