diff --git a/codex-rs/app-server-protocol/src/protocol/v2/tests.rs b/codex-rs/app-server-protocol/src/protocol/v2/tests.rs index c1dd3ffdca..0bd6e3242a 100644 --- a/codex-rs/app-server-protocol/src/protocol/v2/tests.rs +++ b/codex-rs/app-server-protocol/src/protocol/v2/tests.rs @@ -72,6 +72,57 @@ fn test_absolute_path() -> AbsolutePathBuf { absolute_path("readable") } +#[test] +fn thread_background_terminals_list_response_round_trips_foreign_paths() { + for (uri, expected_cwd) in [ + ("file:///home/alice/repo", "/home/alice/repo"), + ( + "file:///C:/Users/Alice%20Smith/repo", + r"C:\Users\Alice Smith\repo", + ), + ("file://server/share/repo", r"\\server\share\repo"), + ] { + let response = ThreadBackgroundTerminalsListResponse { + data: vec![ThreadBackgroundTerminal { + item_id: "item_123".to_string(), + process_id: "42".to_string(), + command: "run server".to_string(), + cwd: PathUri::parse(uri) + .expect("cross-platform path URI should parse") + .into(), + os_pid: None, + cpu_percent: None, + rss_kb: None, + }], + next_cursor: None, + }; + let expected = json!({ + "data": [{ + "itemId": "item_123", + "processId": "42", + "command": "run server", + "cwd": expected_cwd, + "osPid": null, + "cpuPercent": null, + "rssKb": null, + }], + "nextCursor": null, + }); + + assert_eq!( + serde_json::to_value(&response).expect("response should serialize"), + expected, + "serializing {uri}", + ); + assert_eq!( + serde_json::from_value::(expected) + .expect("response should deserialize"), + response, + "deserializing {uri}", + ); + } +} + #[test] fn thread_sources_round_trip_as_scalar_labels() { for (source, label) in [ diff --git a/codex-rs/app-server-protocol/src/protocol/v2/thread.rs b/codex-rs/app-server-protocol/src/protocol/v2/thread.rs index 75b61357c8..e0c70778e3 100644 --- a/codex-rs/app-server-protocol/src/protocol/v2/thread.rs +++ b/codex-rs/app-server-protocol/src/protocol/v2/thread.rs @@ -1044,7 +1044,7 @@ pub struct ThreadBackgroundTerminal { pub item_id: String, pub process_id: String, pub command: String, - pub cwd: AbsolutePathBuf, + pub cwd: LegacyAppPathString, pub os_pid: Option, pub cpu_percent: Option, pub rss_kb: Option, diff --git a/codex-rs/app-server/src/request_processors/thread_processor.rs b/codex-rs/app-server/src/request_processors/thread_processor.rs index 88595243fe..15513bfd96 100644 --- a/codex-rs/app-server/src/request_processors/thread_processor.rs +++ b/codex-rs/app-server/src/request_processors/thread_processor.rs @@ -1909,22 +1909,16 @@ impl ThreadRequestProcessor { .list_background_terminals() .await .into_iter() - .map(|terminal| { - // TODO(anp): Migrate ThreadBackgroundTerminal to PathUri. - let cwd = terminal.cwd.to_abs_path().map_err(|err| { - internal_error(format!("background terminal has invalid cwd: {err}")) - })?; - Ok(ThreadBackgroundTerminal { - item_id: terminal.item_id, - process_id: terminal.process_id, - command: terminal.command, - cwd, - os_pid: None, - cpu_percent: None, - rss_kb: None, - }) + .map(|terminal| ThreadBackgroundTerminal { + item_id: terminal.item_id, + process_id: terminal.process_id, + command: terminal.command, + cwd: terminal.cwd.into(), + os_pid: None, + cpu_percent: None, + rss_kb: None, }) - .collect::, JSONRPCErrorError>>()?; + .collect::>(); let (data, next_cursor) = paginate_background_terminals(&terminals, cursor, limit)?; diff --git a/codex-rs/app-server/src/request_processors/thread_processor_tests.rs b/codex-rs/app-server/src/request_processors/thread_processor_tests.rs index 26760c6546..3d8a78e89c 100644 --- a/codex-rs/app-server/src/request_processors/thread_processor_tests.rs +++ b/codex-rs/app-server/src/request_processors/thread_processor_tests.rs @@ -39,7 +39,7 @@ mod thread_list_cwd_filter_tests { mod background_terminal_pagination_tests { use super::super::paginate_background_terminals; use codex_app_server_protocol::ThreadBackgroundTerminal; - use codex_utils_absolute_path::AbsolutePathBuf; + use codex_utils_path_uri::LegacyAppPathString; use pretty_assertions::assert_eq; fn terminal(process_id: &str) -> ThreadBackgroundTerminal { @@ -49,7 +49,7 @@ mod background_terminal_pagination_tests { item_id: format!("item-{process_id}"), process_id: process_id.to_string(), command: format!("command-{process_id}"), - cwd: AbsolutePathBuf::from_absolute_path(cwd).expect("absolute cwd"), + cwd: LegacyAppPathString::from_string(cwd), os_pid: None, cpu_percent: None, rss_kb: None,