app-server: preserve target-native environment cwd (#28146)

## Why

app-server may run on a different OS from the selected exec-server
environment. Parsing that environment’s cwd with the Codex host’s path
rules prevents thread startup.

## What

Carry environment cwd values as `LegacyAppPathString` at the app-server
boundary and `PathUri` internally. Existing tool-call schemas and
relative-path behavior stay host-native; remaining local-only consumers
convert explicitly and leave follow-up TODOs.

The Wine integration test verifies app-server can start a thread and
complete an ordinary turn with a Windows environment cwd from Linux.

## Validation

- `bazel test //codex-rs/core/tests/remote_env_windows:smoke-test
--test_output=errors`
- focused app-server environment-selection and protocol schema tests
- scoped Clippy for `codex-core` and `codex-app-server-protocol`
This commit is contained in:
Adam Perry @ OpenAI
2026-06-16 21:42:28 +00:00
committed by GitHub
parent 33d50234a8
commit f8850cab1d
37 changed files with 346 additions and 208 deletions
+6 -1
View File
@@ -53,11 +53,16 @@ pub(crate) async fn load_project_instructions(
let mut loaded = LoadedAgentsMd::from_user_instructions(user_instructions);
for turn_environment in &environments.turn_environments {
let filesystem = turn_environment.environment.get_filesystem();
// TODO(anp): Migrate AGENTS.md discovery to PathUri so instructions can be loaded from
// environment-native foreign working directories.
let Ok(cwd) = turn_environment.cwd().to_abs_path() else {
continue;
};
match read_agents_md(
config,
filesystem.as_ref(),
&turn_environment.environment_id,
turn_environment.cwd(),
&cwd,
)
.await
{
+1 -1
View File
@@ -267,7 +267,7 @@ fn resolved_local_environments<const N: usize>(
Environment::create_for_tests(/*exec_server_url*/ None)
.expect("local environment"),
),
cwd,
PathUri::from_abs_path(&cwd),
/*shell*/ None,
)
})
@@ -44,14 +44,18 @@ impl EnvironmentContextEnvironment {
fn from_turn_environments(environments: &[TurnEnvironment], shell: &Shell) -> Vec<Self> {
environments
.iter()
.map(|environment| Self {
id: environment.environment_id.clone(),
cwd: environment.cwd().clone(),
shell: environment
.shell
.as_ref()
.map(|shell| shell.name().to_string())
.unwrap_or_else(|| shell.name().to_string()),
.filter_map(|environment| {
// TODO(anp): Migrate EnvironmentContextEnvironment to PathUri so foreign
// environments remain visible in model context.
Some(Self {
id: environment.environment_id.clone(),
cwd: environment.cwd().to_abs_path().ok()?,
shell: environment
.shell
.as_ref()
.map(|shell| shell.name().to_string())
.unwrap_or_else(|| shell.name().to_string()),
})
})
.collect()
}
+10 -13
View File
@@ -97,7 +97,7 @@ impl ThreadEnvironments {
}
let turn_environment = match current.turn_environments.iter().find(|environment| {
environment.environment_id == selected_environment.environment_id
&& environment.cwd_uri() == &selected_environment.cwd
&& environment.cwd() == &selected_environment.cwd
}) {
Some(environment) => environment.clone(),
None => match Self::resolve_selection(
@@ -157,12 +157,7 @@ impl ThreadEnvironments {
let mut turn_environment = TurnEnvironment::new(
environment_id,
environment,
selected_environment.cwd.to_abs_path().map_err(|err| {
CodexErr::InvalidRequest(format!(
"turn environment cwd `{}` is not valid on this host: {err}",
selected_environment.cwd
))
})?,
selected_environment.cwd.clone(),
shell,
);
let task = shell_snapshot
@@ -226,8 +221,10 @@ impl TurnEnvironmentSnapshot {
(!environment.environment.is_remote()).then_some(environment)
}
pub(crate) fn single_local_environment_cwd(&self) -> Option<&AbsolutePathBuf> {
self.single_local_environment().map(TurnEnvironment::cwd)
pub(crate) fn single_local_environment_cwd(&self) -> Option<AbsolutePathBuf> {
// TODO(anp): Migrate local-environment consumers to PathUri so this compatibility
// conversion can be removed.
self.single_local_environment()?.cwd().to_abs_path().ok()
}
}
@@ -560,7 +557,7 @@ url = "ws://127.0.0.1:8765"
Arc::clone(&local_manager),
&[TurnEnvironmentSelection {
environment_id: LOCAL_ENVIRONMENT_ID.to_string(),
cwd: cwd_uri,
cwd: cwd_uri.clone(),
}],
)
.await;
@@ -573,7 +570,7 @@ url = "ws://127.0.0.1:8765"
turn_environments: vec![TurnEnvironment::new(
REMOTE_ENVIRONMENT_ID.to_string(),
remote_environment.clone(),
cwd.clone(),
cwd_uri.clone(),
/*shell*/ None,
)],
};
@@ -583,13 +580,13 @@ url = "ws://127.0.0.1:8765"
TurnEnvironment::new(
REMOTE_ENVIRONMENT_ID.to_string(),
remote_environment,
cwd.clone(),
cwd_uri,
/*shell*/ None,
),
],
};
assert_eq!(local.single_local_environment_cwd(), Some(&cwd));
assert_eq!(local.single_local_environment_cwd(), Some(cwd));
assert_eq!(remote.single_local_environment_cwd(), None);
assert_eq!(multiple.single_local_environment_cwd(), None);
}
+3 -1
View File
@@ -750,11 +750,13 @@ async fn run_review_on_session(
.unwrap_or_default();
let guardian_permission_profile = PermissionProfile::read_only();
let parent_turn_environments = params.parent_turn.environments.to_selections();
// TODO(anp): Migrate guardian review thread settings to a PathUri fallback cwd so foreign
// parent environments do not fall back to the host-native config cwd.
let parent_turn_legacy_fallback_cwd = params
.parent_turn
.environments
.primary()
.map(|environment| environment.cwd().clone())
.and_then(|environment| environment.cwd().to_abs_path().ok())
.unwrap_or_else(|| params.parent_turn.config.cwd.clone());
let submit_result = run_before_review_deadline(
+9 -2
View File
@@ -122,7 +122,13 @@ async fn build_uploaded_argument_value(
"no primary turn environment is available".to_string(),
));
};
let resolved_path = turn_environment.cwd().join(file_path);
// TODO(anp): Resolve app tool file arguments using the selected environment's native path
// convention so uploads can read relative paths from foreign environments.
let native_environment_cwd = turn_environment
.cwd()
.to_abs_path()
.map_err(|error| contextualize_error(error.to_string()))?;
let resolved_path = native_environment_cwd.join(file_path);
let path_uri = PathUri::from_abs_path(&resolved_path);
let fs = turn_environment.environment.get_filesystem();
let metadata = fs
@@ -178,6 +184,7 @@ mod tests {
use crate::session::tests::make_session_and_context;
use crate::session::turn_context::TurnEnvironment;
use codex_utils_absolute_path::AbsolutePathBuf;
use codex_utils_path_uri::PathUri;
use pretty_assertions::assert_eq;
use std::path::Path;
use std::sync::Arc;
@@ -194,7 +201,7 @@ mod tests {
*primary = TurnEnvironment::new(
primary.environment_id.clone(),
Arc::clone(&primary.environment),
cwd,
PathUri::from_abs_path(&cwd),
primary.shell.clone(),
);
}
+11 -10
View File
@@ -318,17 +318,18 @@ impl Session {
)
.await;
let environment_manager = self.services.turn_environments.environment_manager();
let mcp_runtime_context = match turn_context.environments.primary() {
Some(turn_environment) => McpRuntimeContext::new(
Arc::clone(&environment_manager),
turn_environment.cwd().to_path_buf(),
),
None => McpRuntimeContext::new(
environment_manager,
// TODO(anp): Migrate MCP runtime cwd plumbing to PathUri so foreign environment cwd
// values can be used without falling back to the legacy host cwd.
let cwd = turn_context
.environments
.primary()
.and_then(|turn_environment| turn_environment.cwd().to_abs_path().ok())
.map(|cwd| cwd.to_path_buf())
.unwrap_or_else(|| {
#[allow(deprecated)]
turn_context.cwd.to_path_buf(),
),
};
turn_context.cwd.to_path_buf()
});
let mcp_runtime_context = McpRuntimeContext::new(environment_manager, cwd);
let mcp_startup_cancellation_token = {
let mut guard = self.services.mcp_startup_cancellation_token.lock().await;
guard.cancel();
+4 -1
View File
@@ -1119,9 +1119,12 @@ impl Session {
};
let mcp_runtime_context = {
let turn_environments = sess.services.turn_environments.snapshot().await;
// TODO(anp): Migrate MCP runtime cwd plumbing to PathUri so foreign environment
// cwd values can be used without falling back to the session host cwd.
let cwd = turn_environments
.primary()
.map(|turn_environment| turn_environment.cwd().to_path_buf())
.and_then(|turn_environment| turn_environment.cwd().to_abs_path().ok())
.map(|cwd| cwd.to_path_buf())
.unwrap_or_else(|| session_configuration.cwd().to_path_buf());
McpRuntimeContext::new(
sess.services.turn_environments.environment_manager(),
+5 -4
View File
@@ -5697,7 +5697,7 @@ async fn request_permissions_tool_resolves_relative_paths_against_selected_envir
turn_context_mut.environments.turn_environments[0] = TurnEnvironment::new(
"remote".to_string(),
current_environment.environment,
environment_cwd.clone(),
PathUri::from_abs_path(&environment_cwd),
current_environment.shell,
);
@@ -6316,13 +6316,14 @@ async fn primary_environment_uses_first_turn_environment() {
let first_environment = turn_context.environments.turn_environments[0].clone();
#[allow(deprecated)]
let second_cwd = turn_context.cwd.join("second");
let second_cwd_uri = codex_utils_path_uri::PathUri::from_abs_path(&second_cwd);
turn_context
.environments
.turn_environments
.push(TurnEnvironment::new(
"second".to_string(),
Arc::clone(&first_environment.environment),
second_cwd.clone(),
second_cwd_uri.clone(),
/*shell*/ None,
));
@@ -6342,12 +6343,12 @@ async fn primary_environment_uses_first_turn_environment() {
.find(|environment| environment.environment_id == "second")
.expect("second environment")
.cwd(),
&second_cwd
&second_cwd_uri
);
assert_eq!(turn_context.environments.turn_environments.len(), 2);
assert_eq!(
turn_context.environments.turn_environments[1].cwd(),
&second_cwd
&second_cwd_uri
);
}
+18 -11
View File
@@ -414,13 +414,16 @@ pub(crate) async fn run_turn(
async fn turn_diff_display_roots(turn_context: &TurnContext) -> Vec<(String, PathBuf)> {
let mut display_roots = Vec::new();
for turn_environment in &turn_context.environments.turn_environments {
let root = get_git_repo_root_with_fs(
turn_environment.environment.get_filesystem().as_ref(),
turn_environment.cwd(),
)
.await
.unwrap_or_else(|| turn_environment.cwd().clone())
.into_path_buf();
// TODO(anp): Migrate git-root discovery and diff display roots to PathUri so foreign
// environment roots can participate without host-native conversion.
let Ok(cwd) = turn_environment.cwd().to_abs_path() else {
continue;
};
let root =
get_git_repo_root_with_fs(turn_environment.environment.get_filesystem().as_ref(), &cwd)
.await
.unwrap_or(cwd)
.into_path_buf();
display_roots.push((turn_environment.environment_id.clone(), root));
}
display_roots
@@ -634,10 +637,14 @@ async fn build_extension_turn_input_items(
.turn_environments
.iter()
.enumerate()
.map(|(index, environment)| TurnInputEnvironment {
environment_id: environment.environment_id.clone(),
cwd: environment.cwd().as_path().to_path_buf(),
is_primary: index == 0,
.filter_map(|(index, environment)| {
// TODO(anp): Migrate extension turn-input environments to PathUri so foreign cwd
// values are not omitted from extension context.
Some(TurnInputEnvironment {
environment_id: environment.environment_id.clone(),
cwd: environment.cwd().to_abs_path().ok()?.into_path_buf(),
is_primary: index == 0,
})
})
.collect::<Vec<_>>();
+8 -20
View File
@@ -3,7 +3,6 @@ use crate::SkillLoadOutcome;
use crate::agents_md::LoadedAgentsMd;
use crate::config::GhostSnapshotConfig;
use crate::environment_selection::TurnEnvironmentSnapshot;
use crate::path_utils;
use crate::shell_snapshot::ShellSnapshotFile;
use codex_core_skills::HostLoadedSkills;
use codex_file_system::FileSystemSandboxContext;
@@ -49,13 +48,7 @@ pub(crate) type ShellSnapshotTask = Shared<BoxFuture<'static, Option<Arc<ShellSn
pub(crate) struct TurnEnvironment {
pub(crate) environment_id: String,
pub(crate) environment: Arc<Environment>,
// Keep both representations together while cwd consumers migrate to URI semantics. Keeping
// them synchronized means neither representation can be exposed through a mutable reference;
// updates must rebuild the validated pair through `TurnEnvironment::new`. Once
// `TurnEnvironment::cwd` itself becomes a `PathUri`, convert only at native filesystem and
// process-launch boundaries and remove this paired migration state.
cwd: AbsolutePathBuf,
cwd_uri: PathUri,
cwd: PathUri,
pub(crate) shell: Option<shell::Shell>,
pub(crate) shell_snapshot: ShellSnapshotTask,
}
@@ -64,22 +57,20 @@ impl TurnEnvironment {
pub(crate) fn new(
environment_id: String,
environment: Arc<Environment>,
cwd: AbsolutePathBuf,
cwd: PathUri,
shell: Option<shell::Shell>,
) -> Self {
let cwd_uri = PathUri::from_abs_path(&cwd);
Self {
environment_id,
environment,
cwd,
cwd_uri,
shell,
shell_snapshot: futures::future::ready(None).boxed().shared(),
}
}
pub(crate) fn shell_snapshot(&self, cwd: &AbsolutePathBuf) -> Option<AbsolutePathBuf> {
if !path_utils::paths_match_after_normalization(self.cwd.as_path(), cwd.as_path()) {
if self.cwd != PathUri::from_abs_path(cwd) {
return None;
}
self.shell_snapshot
@@ -88,18 +79,14 @@ impl TurnEnvironment {
.map(ShellSnapshotFile::path)
}
pub(crate) fn cwd(&self) -> &AbsolutePathBuf {
pub(crate) fn cwd(&self) -> &PathUri {
&self.cwd
}
pub(crate) fn cwd_uri(&self) -> &PathUri {
&self.cwd_uri
}
pub(crate) fn selection(&self) -> TurnEnvironmentSelection {
TurnEnvironmentSelection {
environment_id: self.environment_id.clone(),
cwd: self.cwd_uri.clone(),
cwd: self.cwd.clone(),
}
}
}
@@ -110,7 +97,6 @@ impl std::fmt::Debug for TurnEnvironment {
.field("environment_id", &self.environment_id)
.field("environment", &self.environment)
.field("cwd", &self.cwd)
.field("cwd_uri", &self.cwd_uri)
.field("shell", &self.shell)
.finish_non_exhaustive()
}
@@ -755,9 +741,11 @@ impl Session {
) -> Arc<TurnContext> {
let turn_environments = self.services.turn_environments.snapshot().await;
let primary_turn_environment = turn_environments.primary().cloned();
// TODO(anp): Migrate per-turn config and legacy TurnContext cwd consumers to PathUri so
// a foreign primary environment does not fall back to the session's host cwd.
let cwd = primary_turn_environment
.as_ref()
.map(|turn_environment| turn_environment.cwd().clone())
.and_then(|turn_environment| turn_environment.cwd().to_abs_path().ok())
.unwrap_or_else(|| session_configuration.cwd().clone());
let per_turn_config = Self::build_per_turn_config(&session_configuration, cwd.clone());
{
+3 -1
View File
@@ -76,7 +76,9 @@ impl ShellSnapshot {
}
let shell = environment.shell.clone()?;
let cwd = environment.cwd().clone();
// TODO(anp): Migrate shell snapshot creation to accept PathUri and defer native
// conversion to the spawned shell process.
let cwd = environment.cwd().to_abs_path().ok()?;
Self::build_for_cwd(Arc::clone(config), cwd, shell).await
}
+12 -2
View File
@@ -144,7 +144,18 @@ pub(crate) async fn execute_user_shell_command(
// We do not source rc files or otherwise reformat the script.
let use_login_shell = true;
let display_command = environment_shell.derive_exec_args(&command, use_login_shell);
let shell_snapshot_location = turn_environment.shell_snapshot(turn_environment.cwd());
// TODO(anp): Migrate user-shell events and execution plumbing to PathUri so this local-only
// feature does not need to project the selected environment cwd onto the Codex host.
let Ok(cwd) = turn_environment.cwd().to_abs_path() else {
send_user_shell_error(
&session,
turn_context.as_ref(),
"shell working directory is not native to the Codex host",
)
.await;
return;
};
let shell_snapshot_location = turn_environment.shell_snapshot(&cwd);
let mut exec_env_map = create_env(
&turn_context.shell_environment_policy,
Some(session.thread_id),
@@ -162,7 +173,6 @@ pub(crate) async fn execute_user_shell_command(
let call_id = Uuid::new_v4().to_string();
let raw_command = command;
let cwd = turn_environment.cwd().clone();
let parsed_cmd = parse_command(&display_command);
session
+4 -4
View File
@@ -606,11 +606,11 @@ async fn resume_and_fork_do_not_restore_thread_environments_from_rollout() {
assert_eq!(resumed_turn.environments.turn_environments.len(), 1);
assert_eq!(
resumed_turn.environments.turn_environments[0].cwd(),
&default_cwd
&PathUri::from_abs_path(&default_cwd)
);
assert_ne!(
resumed_turn.environments.turn_environments[0].cwd(),
&selected_cwd
&PathUri::from_abs_path(&selected_cwd)
);
let forked = manager
@@ -633,11 +633,11 @@ async fn resume_and_fork_do_not_restore_thread_environments_from_rollout() {
assert_eq!(forked_turn.environments.turn_environments.len(), 1);
assert_eq!(
forked_turn.environments.turn_environments[0].cwd(),
&default_cwd
&PathUri::from_abs_path(&default_cwd)
);
assert_ne!(
forked_turn.environments.turn_environments[0].cwd(),
&selected_cwd
&PathUri::from_abs_path(&selected_cwd)
);
}
@@ -299,7 +299,7 @@ pub async fn handle(
Ok(FunctionToolOutput::from_text(content, Some(true)))
}
fn single_local_environment_cwd(turn: &TurnContext) -> Result<&AbsolutePathBuf, FunctionCallError> {
fn single_local_environment_cwd(turn: &TurnContext) -> Result<AbsolutePathBuf, FunctionCallError> {
let [turn_environment] = turn.environments.turn_environments.as_slice() else {
return Err(FunctionCallError::RespondToModel(
"spawn_agents_on_csv requires exactly one local environment".to_string(),
@@ -312,5 +312,12 @@ fn single_local_environment_cwd(turn: &TurnContext) -> Result<&AbsolutePathBuf,
));
}
Ok(turn_environment.cwd())
// TODO(anp): Migrate spawn_agents_on_csv filesystem access to PathUri before enabling it for
// remote environments.
turn_environment.cwd().to_abs_path().map_err(|err| {
FunctionCallError::RespondToModel(format!(
"spawn_agents_on_csv cwd `{}` is not native to the Codex host: {err}",
turn_environment.cwd()
))
})
}
@@ -359,11 +359,18 @@ impl ApplyPatchHandler {
"apply_patch is unavailable in this session".to_string(),
));
};
let cwd = turn_environment.cwd().clone();
// TODO(anp): Migrate apply-patch verification and permission accounting to PathUri so
// patches can target environment-native foreign paths without host projection.
let cwd = turn_environment.cwd().to_abs_path().map_err(|err| {
FunctionCallError::RespondToModel(format!(
"apply_patch cwd `{}` is not native to the Codex host: {err}",
turn_environment.cwd()
))
})?;
let fs = turn_environment.environment.get_filesystem();
let sandbox = turn.file_system_sandbox_context(
/*additional_permissions*/ None,
turn_environment.cwd_uri(),
turn_environment.cwd(),
);
match codex_apply_patch::verify_apply_patch_args(args, &cwd, fs.as_ref(), Some(&sandbox))
.await
@@ -114,10 +114,15 @@ async fn to_extension_call(invocation: &ToolInvocation) -> ExtensionToolCall {
ConversationHistory::new(invocation.session.clone_history().await.into_raw_items());
let mut environments = Vec::with_capacity(invocation.turn.environments.turn_environments.len());
for environment in &invocation.turn.environments.turn_environments {
// TODO(anp): Migrate extension ToolEnvironment and granted-permission lookup to PathUri
// so extensions can receive foreign environment cwd values.
let Ok(native_cwd) = environment.cwd().to_abs_path() else {
continue;
};
let additional_permissions = apply_granted_turn_permissions(
invocation.session.as_ref(),
&environment.environment_id,
environment.cwd().as_path(),
native_cwd.as_path(),
SandboxPermissions::UseDefault,
/*additional_permissions*/ None,
)
@@ -125,10 +130,10 @@ async fn to_extension_call(invocation: &ToolInvocation) -> ExtensionToolCall {
.additional_permissions;
let file_system_sandbox_context = invocation
.turn
.file_system_sandbox_context(additional_permissions, environment.cwd_uri());
.file_system_sandbox_context(additional_permissions, environment.cwd());
environments.push(ToolEnvironment {
environment_id: environment.environment_id.clone(),
cwd: environment.cwd().clone(),
cwd: native_cwd,
file_system: environment.environment.get_filesystem(),
file_system_sandbox_context,
});
@@ -315,7 +320,7 @@ mod tests {
.environments
.turn_environments
.iter()
.map(|environment| Some(environment.cwd_uri().clone()))
.map(|environment| Some(environment.cwd().clone()))
.collect::<Vec<_>>();
let history_item = ResponseItem::Message {
id: None,
@@ -70,8 +70,16 @@ impl RequestPermissionsHandler {
"request_permissions requires a primary environment".to_string(),
));
};
// TODO(anp): Migrate request_permissions parsing and permission profiles to PathUri so
// environment-native foreign paths do not require host conversion.
let native_cwd = turn_environment.cwd().to_abs_path().map_err(|err| {
FunctionCallError::RespondToModel(format!(
"request_permissions cwd `{}` is not native to the Codex host: {err}",
turn_environment.cwd()
))
})?;
let mut args: RequestPermissionsArgs =
parse_arguments_with_base_path(&arguments, turn_environment.cwd())?;
parse_arguments_with_base_path(&arguments, &native_cwd)?;
args.permissions = normalize_additional_permissions(args.permissions.into())
.map(codex_protocol::request_permissions::RequestPermissionProfile::from)
.map_err(FunctionCallError::RespondToModel)?;
@@ -129,13 +129,21 @@ impl ExecCommandHandler {
"unified exec is unavailable in this session".to_string(),
));
};
// TODO(anp): Resolve tool paths using the selected environment's native path convention
// so unified exec can support relative paths in foreign environments.
let native_environment_cwd = turn_environment.cwd().to_abs_path().map_err(|err| {
FunctionCallError::RespondToModel(format!(
"environment cwd `{}` is not native to the Codex host: {err}",
turn_environment.cwd()
))
})?;
let cwd = environment_args
.workdir
.as_deref()
.filter(|workdir| !workdir.is_empty())
.map_or_else(
|| turn_environment.cwd().clone(),
|workdir| turn_environment.cwd().join(workdir),
|| native_environment_cwd.clone(),
|workdir| native_environment_cwd.join(workdir),
);
let environment = Arc::clone(&turn_environment.environment);
let fs = environment.get_filesystem();
@@ -277,7 +285,7 @@ impl ExecCommandHandler {
yield_time_ms,
max_output_tokens,
cwd,
sandbox_cwd: turn_environment.cwd().clone(),
sandbox_cwd: native_environment_cwd,
turn_environment: turn_environment.clone(),
shell_mode,
network: context.turn.network.clone(),
+11 -3
View File
@@ -143,11 +143,18 @@ impl ViewImageHandler {
"view_image is unavailable in this session".to_string(),
));
};
let cwd = turn_environment.cwd().clone();
// TODO(anp): Resolve tool paths using the selected environment's native path convention
// so view_image can support relative paths in foreign environments.
let cwd = turn_environment.cwd().to_abs_path().map_err(|err| {
FunctionCallError::RespondToModel(format!(
"environment cwd `{}` is not native to the Codex host: {err}",
turn_environment.cwd()
))
})?;
let abs_path = cwd.join(path);
let sandbox = turn.file_system_sandbox_context(
/*additional_permissions*/ None,
turn_environment.cwd_uri(),
turn_environment.cwd(),
);
let fs = turn_environment.environment.get_filesystem();
let path_uri = PathUri::from_abs_path(&abs_path);
@@ -272,6 +279,7 @@ mod tests {
use crate::turn_diff_tracker::TurnDiffTracker;
use codex_protocol::models::PermissionProfile;
use codex_utils_absolute_path::AbsolutePathBuf;
use codex_utils_path_uri::PathUri;
use core_test_support::TempDirExt;
use pretty_assertions::assert_eq;
use serde_json::json;
@@ -288,7 +296,7 @@ mod tests {
turn.environments.turn_environments[0] = TurnEnvironment::new(
current.environment_id,
current.environment,
cwd,
PathUri::from_abs_path(&cwd),
current.shell,
);
}
@@ -19,7 +19,7 @@ fn test_turn_environment(environment_id: &str) -> crate::session::turn_context::
crate::session::turn_context::TurnEnvironment::new(
environment_id.to_string(),
std::sync::Arc::new(codex_exec_server::Environment::default_for_tests()),
std::env::temp_dir().abs(),
PathUri::from_abs_path(&std::env::temp_dir().abs()),
/*shell*/ None,
)
}
@@ -427,6 +427,7 @@ mod tests {
use codex_exec_server::Environment;
use codex_exec_server::LOCAL_ENVIRONMENT_ID;
use codex_tools::ZshForkConfig;
use codex_utils_path_uri::PathUri;
use std::sync::Arc;
use std::time::Duration;
use tempfile::tempdir;
@@ -435,7 +436,7 @@ mod tests {
TurnEnvironment::new(
LOCAL_ENVIRONMENT_ID.to_string(),
Arc::new(Environment::default_for_tests()),
cwd,
PathUri::from_abs_path(&cwd),
/*shell*/ None,
)
}