Skip to content
30 changes: 25 additions & 5 deletions codex-rs/core/src/codex.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,6 +109,7 @@ use crate::rollout::RolloutRecorder;
use crate::rollout::RolloutRecorderParams;
use crate::rollout::map_session_init_error;
use crate::shell;
use crate::shell_snapshot::ShellSnapshot;
use crate::state::ActiveTurn;
use crate::state::SessionServices;
use crate::state::SessionState;
Expand Down Expand Up @@ -571,7 +572,8 @@ impl Session {
);

// Create the mutable state for the Session.
let state = SessionState::new(session_configuration.clone());
let shell_snapshot = ShellSnapshot::try_new(&config.codex_home, &default_shell).await;
let state = SessionState::new(session_configuration.clone(), shell_snapshot);

let services = SessionServices {
mcp_connection_manager: Arc::new(RwLock::new(McpConnectionManager::default())),
Expand Down Expand Up @@ -1442,6 +1444,24 @@ impl Session {
&self.services.user_shell
}

/// Add the shell snapshot the command if the snapshot is available.
///
/// Returns the new command and `true` if a shell snapshot has been
/// applied, `false` otherwise.
pub(crate) async fn shell_snapshot(&self) -> Option<ShellSnapshot> {
if !self.enabled(Feature::ShellSnapshot) {
return None;
}

let state = self.state.lock().await;
state.shell_snapshot.clone()
// if let Some(path) = snapshot_path {
// (wrap_command_with_snapshot(self.user_shell(), &path, command), true)
// } else {
// (command.to_vec(), false)
// }
}

fn show_raw_agent_reasoning(&self) -> bool {
self.services.show_raw_agent_reasoning
}
Expand Down Expand Up @@ -2585,7 +2605,7 @@ mod tests {
session_source: SessionSource::Exec,
};

let mut state = SessionState::new(session_configuration);
let mut state = SessionState::new(session_configuration, None);
let initial = RateLimitSnapshot {
primary: Some(RateLimitWindow {
used_percent: 10.0,
Expand Down Expand Up @@ -2656,7 +2676,7 @@ mod tests {
session_source: SessionSource::Exec,
};

let mut state = SessionState::new(session_configuration);
let mut state = SessionState::new(session_configuration, None);
let initial = RateLimitSnapshot {
primary: Some(RateLimitWindow {
used_percent: 15.0,
Expand Down Expand Up @@ -2863,7 +2883,7 @@ mod tests {
session_source: SessionSource::Exec,
};

let state = SessionState::new(session_configuration.clone());
let state = SessionState::new(session_configuration.clone(), None);

let services = SessionServices {
mcp_connection_manager: Arc::new(RwLock::new(McpConnectionManager::default())),
Expand Down Expand Up @@ -2942,7 +2962,7 @@ mod tests {
session_source: SessionSource::Exec,
};

let state = SessionState::new(session_configuration.clone());
let state = SessionState::new(session_configuration.clone(), None);

let services = SessionServices {
mcp_connection_manager: Arc::new(RwLock::new(McpConnectionManager::default())),
Expand Down
8 changes: 8 additions & 0 deletions codex-rs/core/src/features.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,8 @@ pub enum Feature {
ParallelToolCalls,
/// Experimental skills injection (CLI flag-driven).
Skills,
/// Experimental shell snapshotting.
ShellSnapshot,
}

impl Feature {
Expand Down Expand Up @@ -345,4 +347,10 @@ pub const FEATURES: &[FeatureSpec] = &[
stage: Stage::Experimental,
default_enabled: false,
},
FeatureSpec {
id: Feature::ShellSnapshot,
key: "shell_snapshot",
stage: Stage::Experimental,
default_enabled: false,
},
];
1 change: 1 addition & 0 deletions codex-rs/core/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -73,6 +73,7 @@ mod rollout;
pub(crate) mod safety;
pub mod seatbelt;
pub mod shell;
pub mod shell_snapshot;
pub mod skills;
pub mod spawn;
pub mod terminal;
Expand Down
Loading
Loading