path-uri: render native paths across platforms

This commit is contained in:
Adam Perry
2026-06-12 21:55:35 -07:00
committed by Adam Perry @ OpenAI
parent 9d938a46d9
commit c66111002d
5 changed files with 490 additions and 0 deletions
+25
View File
@@ -26,6 +26,7 @@ use crate::protocol::ShellInfo;
use crate::remote_file_system::RemoteFileSystem;
use crate::remote_process::RemoteProcess;
use codex_shell_command::shell_detect::DetectedShell;
use codex_utils_path_uri::PathConvention;
pub const CODEX_EXEC_SERVER_URL_ENV_VAR: &str = "CODEX_EXEC_SERVER_URL";
@@ -473,6 +474,7 @@ impl EnvironmentInfo {
pub(crate) fn local() -> Self {
Self {
shell: codex_shell_command::shell_detect::default_user_shell().into(),
path_convention: PathConvention::native(),
}
}
}
@@ -494,10 +496,14 @@ mod tests {
use super::EnvironmentManager;
use super::LOCAL_ENVIRONMENT_ID;
use super::REMOTE_ENVIRONMENT_ID;
use crate::EnvironmentInfo;
use crate::ExecServerRuntimePaths;
use crate::ProcessId;
use crate::ShellInfo;
use crate::environment_provider::EnvironmentDefault;
use crate::environment_provider::EnvironmentProviderSnapshot;
use codex_utils_path_uri::PathConvention;
use codex_utils_path_uri::PathUri;
use pretty_assertions::assert_eq;
fn test_runtime_paths() -> ExecServerRuntimePaths {
@@ -512,6 +518,25 @@ mod tests {
assert!(manager.try_local_environment().is_none());
}
#[test]
fn environment_info_renders_paths_using_its_convention() {
let info = EnvironmentInfo {
shell: ShellInfo {
name: "powershell".to_string(),
path: "powershell.exe".to_string(),
},
path_convention: PathConvention::Windows,
};
let path = PathUri::parse("file:///C:/workspace/src/main.rs").expect("valid file URI");
assert_eq!(
info.render_path(&path)
.expect("Windows path should render")
.into_string(),
r"C:\workspace\src\main.rs"
);
}
#[tokio::test]
async fn create_local_environment_does_not_connect() {
let environment = Environment::create(/*exec_server_url*/ None, test_runtime_paths())
+39
View File
@@ -4,6 +4,9 @@ use std::path::PathBuf;
use crate::FileSystemSandboxContext;
use base64::engine::general_purpose::STANDARD as BASE64_STANDARD;
use codex_protocol::config_types::ShellEnvironmentPolicyInherit;
use codex_utils_path_uri::NativePathString;
use codex_utils_path_uri::NativePathStringError;
use codex_utils_path_uri::PathConvention;
use codex_utils_path_uri::PathUri;
use serde::Deserialize;
use serde::Serialize;
@@ -69,6 +72,18 @@ pub struct InitializeResponse {
#[serde(rename_all = "camelCase")]
pub struct EnvironmentInfo {
pub shell: ShellInfo,
/// Native path syntax used by this environment.
pub path_convention: PathConvention,
}
impl EnvironmentInfo {
/// Renders a path using this environment's native path syntax.
///
/// TODO(anp): Once `PathUri` carries an environment identifier, resolve the
/// environment from that identifier and verify it matches this metadata.
pub fn render_path(&self, path: &PathUri) -> Result<NativePathString, NativePathStringError> {
NativePathString::from_path_uri(path, self.path_convention)
}
}
/// Shell detected for an execution/filesystem environment.
@@ -449,10 +464,13 @@ mod base64_bytes {
#[cfg(test)]
mod tests {
use super::EnvironmentInfo;
use super::FsReadFileParams;
use super::HttpRequestParams;
use super::ShellInfo;
use crate::FileSystemSandboxContext;
use codex_protocol::models::PermissionProfile;
use codex_utils_path_uri::PathConvention;
use codex_utils_path_uri::PathUri;
use pretty_assertions::assert_eq;
@@ -490,6 +508,27 @@ mod tests {
);
}
#[test]
fn environment_info_serializes_path_convention() {
let current = EnvironmentInfo {
shell: ShellInfo {
name: "powershell".to_string(),
path: "powershell.exe".to_string(),
},
path_convention: PathConvention::Windows,
};
assert_eq!(
serde_json::to_value(current).expect("environment info should serialize"),
serde_json::json!({
"shell": {
"name": "powershell",
"path": "powershell.exe",
},
"pathConvention": "windows",
})
);
}
#[test]
fn http_request_timeout_treats_omitted_and_null_as_no_timeout() {
let omitted: HttpRequestParams = serde_json::from_value(serde_json::json!({