Preserve the remote cwd filter in the in-app resume picker (#53728)

## Why

Opening the in-app resume picker created a new app-server session without the active session's remote working directory override, dropping the remote directory filter from the thread list.

## What changed

Pass the active session's remote working directory override to the picker session so its `thread/list` request retains the `cwd` filter.

## Testing

Add a regression test that opens the in-app picker against a recording remote server and verifies that `thread/list` includes the remote working directory in `cwd`.

GitOrigin-RevId: 0073ed77e9d9b0ffdd647fcb9f157d20ea2aa599
This commit is contained in:
Felipe Coury
2026-10-13 17:41:03 +00:00
committed by copyberry
parent 72ad8747e9
commit 237b7d4323
2 changed files with 85 additions and 0 deletions
+2
View File
@@ -41,6 +41,8 @@ impl App {
return Ok(AppRunControl::Continue);
}
};
picker_app_server = picker_app_server
.with_remote_cwd_override(app_server.remote_cwd_override().map(Path::to_path_buf));
picker_app_server.model_provider_override = self.harness_overrides.model_provider.clone();
let selection =
crate::resume_picker::run_resume_picker_from_existing_session_with_app_server(
@@ -926,6 +926,89 @@ async fn make_history_test_app() -> Result<(Box<App>, tempfile::TempDir)> {
Ok((app, codex_home))
}
#[tokio::test]
async fn in_app_remote_resume_picker_preserves_remote_cwd_filter() -> Result<()> {
let (mut app, _codex_home) = make_history_test_app().await?;
let remote_root = tempdir()?;
let remote_cwd = remote_root.path().join("project");
std::fs::create_dir(&remote_cwd)?;
let (app_server, _requests, active_proxy) =
start_recording_remote_app_server(&app.config).await?;
let mut app_server = app_server.with_remote_cwd_override(Some(remote_cwd.clone()));
app.harness_overrides.model_provider = Some(app.config.model_provider_id.clone());
let listener = TcpListener::bind("127.0.0.1:0").await?;
app.app_server_target = AppServerTarget::Remote {
endpoint: crate::resolve_remote_addr(&format!("ws://{}", listener.local_addr()?))?,
};
let (request_tx, request_rx) = oneshot::channel();
let (release_tx, release_rx) = oneshot::channel::<()>();
let codex_home = app.config.codex_home.display().to_string();
let recorder = tokio::spawn(async move {
let (socket, _) = listener.accept().await?;
let mut websocket = accept_async(socket).await?;
while let Some(frame) = websocket.next().await {
let Message::Text(text) = frame? else {
continue;
};
match serde_json::from_str::<JSONRPCMessage>(&text)? {
JSONRPCMessage::Request(request) if request.method == "initialize" => {
let response = JSONRPCMessage::Response(JSONRPCResponse {
id: request.id,
result: serde_json::json!({
"userAgent": "codex-tui-test",
"codexHome": codex_home,
}),
});
websocket
.send(Message::Text(serde_json::to_string(&response)?.into()))
.await?;
}
JSONRPCMessage::Request(request) if request.method == "thread/list" => {
let _ = request_tx.send(request.params.unwrap_or_default());
let _ = release_rx.await;
return Ok::<(), color_eyre::Report>(());
}
_ => {}
}
}
Err(color_eyre::eyre::eyre!(
"picker disconnected before requesting its thread list"
))
});
let mut tui = crate::tui::test_support::make_test_tui()?;
tui.set_alt_screen_enabled(/*enabled*/ false);
tui.pause_events();
let mut picker = Box::pin(app.open_resume_picker(&mut tui, &mut app_server));
let params = tokio::time::timeout(std::time::Duration::from_secs(/*secs*/ 5), async {
tokio::select! {
biased;
params = request_rx => params.map_err(|_| {
color_eyre::eyre::eyre!("picker request recorder closed")
}),
result = &mut picker => {
result?;
Err(color_eyre::eyre::eyre!(
"picker exited before requesting its thread list"
))
}
}
})
.await??;
drop(picker);
let _ = release_tx.send(());
recorder.await??;
app_server.shutdown().await?;
active_proxy.await??;
assert_eq!(
params["cwd"],
serde_json::Value::String(remote_cwd.display().to_string())
);
Ok(())
}
#[tokio::test]
async fn delete_current_thread_navigates_only_after_success() -> Result<()> {
let endpoint = crate::resolve_remote_addr("ws://127.0.0.1:4500")?;