fix: rename McpServer to TestAppServer (#25701)

This PR brought to you via VS Code rather than Codex...

- opened `codex-rs/app-server/tests/common/mcp_process.rs`
- put the cursor on `McpServer`
- hit `F2` and renamed the symbol to `TestAppServer`
- went to the file tree
- hit enter and renamed `mcp_process.rs` to `test_app_server.rs`
- ran **Save All Files** from the Command Palette
- ran `just fmt`

The End

(Admittedly, most of the local variables for `TestAppServer` are still
named `mcp`, though.)
This commit is contained in:
Michael Bolin
2026-06-01 21:49:38 +00:00
committed by GitHub
parent 6ae99fd35f
commit 6536841d89
69 changed files with 666 additions and 627 deletions
+4 -4
View File
@@ -1,11 +1,11 @@
mod analytics_server;
mod auth_fixtures;
mod config;
mod mcp_process;
mod mock_model_server;
mod models_cache;
mod responses;
mod rollout;
mod test_app_server;
pub use analytics_server::start_analytics_events_server;
pub use auth_fixtures::ChatGptAuthFixture;
@@ -24,9 +24,6 @@ pub use core_test_support::test_absolute_path;
pub use core_test_support::test_path_buf_with_windows;
pub use core_test_support::test_tmp_path;
pub use core_test_support::test_tmp_path_buf;
pub use mcp_process::DEFAULT_CLIENT_NAME;
pub use mcp_process::DISABLE_PLUGIN_STARTUP_TASKS_ARG;
pub use mcp_process::McpProcess;
pub use mock_model_server::create_mock_responses_server_repeating_assistant;
pub use mock_model_server::create_mock_responses_server_sequence;
pub use mock_model_server::create_mock_responses_server_sequence_unchecked;
@@ -45,6 +42,9 @@ pub use rollout::create_fake_rollout_with_text_elements;
pub use rollout::create_fake_rollout_with_token_usage;
pub use rollout::rollout_path;
use serde::de::DeserializeOwned;
pub use test_app_server::DEFAULT_CLIENT_NAME;
pub use test_app_server::DISABLE_PLUGIN_STARTUP_TASKS_ARG;
pub use test_app_server::TestAppServer;
pub fn to_response<T: DeserializeOwned>(response: JSONRPCResponse) -> anyhow::Result<T> {
let value = serde_json::to_value(response.result)?;
@@ -106,7 +106,7 @@ use codex_app_server_protocol::WindowsSandboxSetupStartParams;
use codex_login::default_client::CODEX_INTERNAL_ORIGINATOR_OVERRIDE_ENV_VAR;
use tokio::process::Command;
pub struct McpProcess {
pub struct TestAppServer {
next_request_id: AtomicI64,
/// Retain this child process until the client is dropped. The Tokio runtime
/// will make a "best effort" to reap the process after it exits, but it is
@@ -122,7 +122,7 @@ pub const DEFAULT_CLIENT_NAME: &str = "codex-app-server-tests";
pub const DISABLE_PLUGIN_STARTUP_TASKS_ARG: &str = "--disable-plugin-startup-tasks-for-tests";
const DISABLE_MANAGED_CONFIG_ENV_VAR: &str = "CODEX_APP_SERVER_DISABLE_MANAGED_CONFIG";
impl McpProcess {
impl TestAppServer {
pub async fn new(codex_home: &Path) -> anyhow::Result<Self> {
Self::new_with_env_and_args(codex_home, &[], &[DISABLE_PLUGIN_STARTUP_TASKS_ARG]).await
}
@@ -1513,7 +1513,7 @@ impl McpProcess {
}
}
impl Drop for McpProcess {
impl Drop for TestAppServer {
fn drop(&mut self) {
// These tests spawn a `codex-app-server` child process.
//
+12 -11
View File
@@ -1,6 +1,6 @@
use anyhow::Result;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
use chrono::Duration;
@@ -92,7 +92,7 @@ shell_snapshot = false
std::fs::write(config_toml, contents)
}
async fn login_with_api_key_via_request(mcp: &mut McpProcess, api_key: &str) -> Result<()> {
async fn login_with_api_key_via_request(mcp: &mut TestAppServer, api_key: &str) -> Result<()> {
let request_id = mcp.send_login_account_api_key_request(api_key).await?;
let resp: JSONRPCResponse = timeout(
@@ -110,7 +110,8 @@ async fn get_auth_status_no_auth() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path())?;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -136,7 +137,7 @@ async fn get_auth_status_with_api_key() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
login_with_api_key_via_request(&mut mcp, "sk-test-key").await?;
@@ -164,7 +165,7 @@ async fn get_auth_status_with_api_key_when_auth_not_required() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml_custom_provider(codex_home.path(), /*requires_openai_auth*/ false)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
login_with_api_key_via_request(&mut mcp, "sk-test-key").await?;
@@ -197,7 +198,7 @@ async fn get_auth_status_with_api_key_no_include_token() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
login_with_api_key_via_request(&mut mcp, "sk-test-key").await?;
@@ -225,7 +226,7 @@ async fn get_auth_status_with_api_key_refresh_requested() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
login_with_api_key_via_request(&mut mcp, "sk-test-key").await?;
@@ -281,7 +282,7 @@ async fn get_auth_status_omits_token_after_permanent_refresh_failure() -> Result
.await;
let refresh_url = format!("{}/oauth/token", server.uri());
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("OPENAI_API_KEY", None),
@@ -363,7 +364,7 @@ async fn get_auth_status_omits_token_after_proactive_refresh_failure() -> Result
.await;
let refresh_url = format!("{}/oauth/token", server.uri());
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("OPENAI_API_KEY", None),
@@ -430,7 +431,7 @@ async fn get_auth_status_returns_token_after_proactive_refresh_recovery() -> Res
.await;
let refresh_url = format!("{}/oauth/token", server.uri());
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("OPENAI_API_KEY", None),
@@ -507,7 +508,7 @@ async fn login_api_key_rejected_when_forced_chatgpt() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml_forced_login(codex_home.path(), "chatgpt")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_fake_rollout;
use app_test_support::rollout_path;
use app_test_support::to_response;
@@ -93,7 +93,7 @@ async fn get_conversation_summary_by_thread_id_reads_rollout() -> Result<()> {
))?,
);
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -212,7 +212,7 @@ async fn get_conversation_summary_by_relative_rollout_path_resolves_from_codex_h
let relative_path = rollout_path.strip_prefix(codex_home.path())?.to_path_buf();
let expected = expected_summary(thread_id, normalized_canonical_path(rollout_path)?);
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1,6 +1,6 @@
use anyhow::Result;
use anyhow::anyhow;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use codex_app_server_protocol::FuzzyFileSearchSessionCompletedNotification;
use codex_app_server_protocol::FuzzyFileSearchSessionUpdatedNotification;
use codex_app_server_protocol::JSONRPCResponse;
@@ -44,15 +44,15 @@ shell_snapshot = false
)
}
async fn initialized_mcp(codex_home: &TempDir) -> Result<McpProcess> {
async fn initialized_mcp(codex_home: &TempDir) -> Result<TestAppServer> {
create_config_toml(codex_home.path())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
Ok(mcp)
}
async fn wait_for_session_updated(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
session_id: &str,
query: &str,
file_expectation: FileExpectation,
@@ -99,7 +99,7 @@ async fn wait_for_session_updated(
}
async fn wait_for_session_completed(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
session_id: &str,
) -> Result<FuzzyFileSearchSessionCompletedNotification> {
let description = format!("session completion for sessionId={session_id}");
@@ -140,7 +140,7 @@ async fn wait_for_session_completed(
}
async fn assert_update_request_fails_for_missing_session(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
session_id: &str,
query: &str,
) -> Result<()> {
@@ -161,7 +161,7 @@ async fn assert_update_request_fails_for_missing_session(
}
async fn assert_no_session_updates_for(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
session_id: &str,
grace_period: std::time::Duration,
duration: std::time::Duration,
@@ -236,7 +236,7 @@ async fn test_fuzzy_file_search_sorts_and_includes_indices() -> Result<()> {
.to_string();
// Start MCP server and initialize.
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let root_path = root.path().to_string_lossy().to_string();
@@ -302,7 +302,7 @@ async fn test_fuzzy_file_search_accepts_cancellation_token() -> Result<()> {
std::fs::write(root.path().join("alpha.txt"), "contents")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let root_path = root.path().to_string_lossy().to_string();
+37 -27
View File
@@ -1,6 +1,6 @@
use anyhow::Result;
use anyhow::bail;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use app_test_support::ChatGptAuthFixture;
@@ -201,7 +201,8 @@ async fn logout_account_removes_auth_and_notifies() -> Result<()> {
)?;
assert!(codex_home.path().join("auth.json").exists());
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let id = mcp.send_logout_account_request().await?;
@@ -268,7 +269,8 @@ async fn set_auth_token_updates_account_and_notifies() -> Result<()> {
.chatgpt_account_id(WORKSPACE_ID_EMBEDDED),
)?;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let set_id = mcp
@@ -342,7 +344,8 @@ async fn account_read_refresh_token_is_noop_in_external_mode() -> Result<()> {
.chatgpt_account_id(WORKSPACE_ID_EMBEDDED),
)?;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let set_id = mcp
@@ -401,7 +404,7 @@ async fn account_read_refresh_token_is_noop_in_external_mode() -> Result<()> {
}
async fn respond_to_refresh_request(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
access_token: &str,
chatgpt_account_id: &str,
chatgpt_plan_type: Option<&str>,
@@ -467,7 +470,8 @@ async fn external_auth_refreshes_on_unauthorized() -> Result<()> {
.chatgpt_account_id(WORKSPACE_ID_REFRESHED),
)?;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let set_id = mcp
@@ -574,7 +578,8 @@ async fn external_auth_refresh_error_fails_turn() -> Result<()> {
.chatgpt_account_id(WORKSPACE_ID_INITIAL),
)?;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let set_id = mcp
@@ -697,7 +702,8 @@ async fn external_auth_refresh_mismatched_workspace_fails_turn() -> Result<()> {
.chatgpt_account_id(WORKSPACE_ID_DISALLOWED),
)?;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let set_id = mcp
@@ -813,7 +819,8 @@ async fn external_auth_refresh_invalid_access_token_fails_turn() -> Result<()> {
.chatgpt_account_id(WORKSPACE_ID_INITIAL),
)?;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let set_id = mcp
@@ -906,7 +913,7 @@ async fn login_account_api_key_succeeds_and_notifies() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), CreateConfigTomlParams::default())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let req_id = mcp
@@ -960,7 +967,7 @@ async fn login_account_api_key_rejected_when_forced_chatgpt() -> Result<()> {
},
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -990,7 +997,7 @@ async fn login_account_chatgpt_rejected_when_forced_api() -> Result<()> {
},
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp.send_login_account_chatgpt_request().await?;
@@ -1023,7 +1030,7 @@ async fn login_account_chatgpt_device_code_returns_error_when_disabled() -> Resu
mock_device_code_usercode_failure(&mock_server, /*status*/ 404).await;
let issuer = mock_server.uri();
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("OPENAI_API_KEY", None),
@@ -1088,7 +1095,7 @@ async fn login_account_chatgpt_device_code_succeeds_and_notifies() -> Result<()>
mock_device_code_oauth_token(&mock_server, &id_token).await;
let issuer = mock_server.uri();
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("OPENAI_API_KEY", None),
@@ -1165,7 +1172,7 @@ async fn login_account_chatgpt_device_code_failure_notifies_without_account_upda
mock_device_code_token_failure(&mock_server, /*status*/ 500).await;
let issuer = mock_server.uri();
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("OPENAI_API_KEY", None),
@@ -1240,7 +1247,7 @@ async fn login_account_chatgpt_device_code_can_be_cancelled() -> Result<()> {
mock_device_code_token_failure(&mock_server, /*status*/ 404).await;
let issuer = mock_server.uri();
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("OPENAI_API_KEY", None),
@@ -1313,7 +1320,7 @@ async fn login_account_chatgpt_start_can_be_cancelled() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), CreateConfigTomlParams::default())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp.send_login_account_chatgpt_request().await?;
@@ -1379,7 +1386,7 @@ async fn set_auth_token_cancels_active_chatgpt_login() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), CreateConfigTomlParams::default())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
// Initiate the ChatGPT login flow
@@ -1454,7 +1461,7 @@ async fn login_account_chatgpt_includes_forced_workspace_query_param() -> Result
},
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp.send_login_account_chatgpt_request().await?;
@@ -1491,7 +1498,7 @@ async fn login_account_chatgpt_includes_forced_workspace_allowlist_query_param()
},
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp.send_login_account_chatgpt_request().await?;
@@ -1530,7 +1537,8 @@ async fn get_account_no_auth() -> Result<()> {
},
)?;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let params = GetAccountParams {
@@ -1561,7 +1569,7 @@ async fn get_account_with_api_key() -> Result<()> {
},
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let req_id = mcp
@@ -1605,7 +1613,7 @@ async fn get_account_when_auth_not_required() -> Result<()> {
},
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let params = GetAccountParams {
@@ -1646,7 +1654,7 @@ region = "us-west-2"
},
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let params = GetAccountParams {
@@ -1687,7 +1695,8 @@ async fn get_account_with_chatgpt() -> Result<()> {
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let params = GetAccountParams {
@@ -1747,7 +1756,7 @@ async fn get_account_omits_chatgpt_after_permanent_refresh_failure() -> Result<(
.await;
let refresh_url = format!("{}/oauth/token", server.uri());
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("OPENAI_API_KEY", None),
@@ -1813,7 +1822,8 @@ async fn get_account_with_chatgpt_missing_plan_claim_returns_unknown() -> Result
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let params = GetAccountParams {
+15 -15
View File
@@ -8,7 +8,7 @@ use std::time::Duration;
use anyhow::Result;
use anyhow::bail;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
use axum::Json;
@@ -63,7 +63,7 @@ const DEFAULT_TIMEOUT: Duration = Duration::from_secs(60);
#[tokio::test]
async fn list_apps_returns_empty_when_connectors_disabled() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
@@ -124,7 +124,7 @@ async fn list_apps_returns_empty_with_api_key_auth() -> Result<()> {
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -186,7 +186,7 @@ async fn list_apps_returns_empty_when_workspace_codex_plugins_disabled() -> Resu
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new_without_managed_config(codex_home.path()).await?;
let mut mcp = TestAppServer::new_without_managed_config(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -245,7 +245,7 @@ async fn list_apps_uses_thread_feature_flag_when_thread_id_is_provided() -> Resu
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let start_request = mcp
@@ -355,7 +355,7 @@ async fn list_apps_keeps_apps_with_app_only_tools_accessible() -> Result<()> {
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -428,7 +428,7 @@ enabled = false
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -547,7 +547,7 @@ async fn list_apps_emits_updates_and_returns_after_both_lists_load() -> Result<(
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -687,7 +687,7 @@ async fn list_apps_waits_for_accessible_data_before_emitting_directory_updates()
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -793,7 +793,7 @@ async fn list_apps_does_not_emit_empty_interim_updates() -> Result<()> {
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -902,7 +902,7 @@ async fn list_apps_paginates_results() -> Result<()> {
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let first_request = mcp
@@ -1022,7 +1022,7 @@ async fn list_apps_force_refetch_preserves_previous_cache_on_failure() -> Result
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let initial_request = mcp
@@ -1148,7 +1148,7 @@ async fn list_apps_force_refetch_patches_updates_from_cached_snapshots() -> Resu
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let warm_request = mcp
@@ -1371,7 +1371,7 @@ async fn experimental_feature_enablement_set_refreshes_apps_list_when_apps_turn_
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let disable_request = mcp
@@ -1438,7 +1438,7 @@ async fn experimental_feature_enablement_set_refreshes_apps_list_when_apps_turn_
}
async fn read_app_list_updated_notification(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
) -> Result<AppListUpdatedNotification> {
let notification = timeout(
DEFAULT_TIMEOUT,
@@ -1,7 +1,7 @@
use anyhow::Result;
use anyhow::bail;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
use codex_app_server_protocol::AttestationGenerateResponse;
@@ -76,7 +76,8 @@ async fn attestation_generate_round_trip_adds_header_to_responses_websocket_hand
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let initialized = timeout(
DEFAULT_READ_TIMEOUT,
mcp.initialize_with_capabilities(
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_fake_parented_rollout_with_source;
use app_test_support::create_fake_rollout;
use app_test_support::to_response;
@@ -59,7 +59,7 @@ async fn turn_start_forwards_client_metadata_to_responses_request_v2() -> Result
/*supports_websockets*/ false,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -152,7 +152,7 @@ async fn turn_start_sends_fork_lineage_in_turn_metadata_for_thread_fork_v2() ->
/*git_info*/ None,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let ThreadForkResponse { thread, .. } =
@@ -236,7 +236,7 @@ async fn review_start_sends_parent_lineage_in_turn_metadata_for_thread_fork_v2()
/*git_info*/ None,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let ThreadForkResponse { thread, .. } =
@@ -333,7 +333,7 @@ async fn turn_start_sends_other_subagent_lineage_after_cold_thread_resume_v2() -
parent_thread_id,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let resume_req = mcp
@@ -423,7 +423,7 @@ async fn turn_steer_updates_client_metadata_on_follow_up_responses_request_v2()
/*supports_websockets*/ false,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -548,7 +548,7 @@ async fn turn_start_forwards_client_metadata_to_responses_websocket_request_body
/*supports_websockets*/ true,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -650,7 +650,7 @@ supports_websockets = {supports_websockets}
}
async fn fork_fake_rollout_thread(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
source_thread_id: String,
) -> Result<ThreadForkResponse> {
let fork_req = mcp
@@ -8,7 +8,7 @@
use std::time::Duration;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use codex_app_server_protocol::CollaborationModeListParams;
use codex_app_server_protocol::CollaborationModeListResponse;
@@ -28,7 +28,7 @@ const DEFAULT_TIMEOUT: Duration = Duration::from_secs(60);
#[tokio::test]
async fn list_collaboration_modes_returns_presets() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
@@ -1,6 +1,6 @@
use anyhow::Context;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_mock_responses_server_sequence_unchecked;
use app_test_support::to_response;
use base64::Engine;
@@ -42,7 +42,7 @@ async fn command_exec_without_streams_can_be_terminated() -> Result<()> {
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let process_id = "sleep-1".to_string();
@@ -92,7 +92,7 @@ async fn command_exec_without_process_id_keeps_buffered_compatibility() -> Resul
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let command_request_id = mcp
@@ -140,7 +140,7 @@ async fn command_exec_env_overrides_merge_with_server_environment_and_support_un
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[("COMMAND_EXEC_BASELINE", Some("server"))],
)
@@ -198,7 +198,7 @@ async fn command_exec_accepts_permission_profile() -> Result<()> {
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let command_request_id = mcp
@@ -249,7 +249,7 @@ async fn command_exec_permission_profile_starts_selected_network_proxy() -> Resu
codex_home.path(),
/*default_permissions*/ None,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let command_request_id = mcp
@@ -297,7 +297,7 @@ async fn command_exec_permission_profile_does_not_reuse_default_network_proxy()
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
insert_networked_permission_profile_config(codex_home.path(), Some("networked"))?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let command_request_id = mcp
@@ -355,7 +355,7 @@ async fn command_exec_permission_profile_project_roots_use_command_cwd() -> Resu
":workspace_roots" = "write"
"#,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let command_request_id = mcp
@@ -406,7 +406,7 @@ async fn command_exec_returns_error_when_local_environment_is_disabled() -> Resu
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[(CODEX_EXEC_SERVER_URL_ENV_VAR, Some("none"))],
)
@@ -445,7 +445,7 @@ async fn command_exec_rejects_sandbox_policy_with_permission_profile() -> Result
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let command_request_id = mcp
@@ -483,7 +483,7 @@ async fn command_exec_rejects_disable_timeout_with_timeout_ms() -> Result<()> {
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let command_request_id = mcp
@@ -521,7 +521,7 @@ async fn command_exec_rejects_disable_output_cap_with_output_bytes_cap() -> Resu
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let command_request_id = mcp
@@ -559,7 +559,7 @@ async fn command_exec_rejects_negative_timeout_ms() -> Result<()> {
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let command_request_id = mcp
@@ -597,7 +597,7 @@ async fn command_exec_without_process_id_rejects_streaming() -> Result<()> {
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let command_request_id = mcp
@@ -635,7 +635,7 @@ async fn command_exec_non_streaming_respects_output_cap() -> Result<()> {
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let command_request_id = mcp
@@ -682,7 +682,7 @@ async fn command_exec_streaming_does_not_buffer_output() -> Result<()> {
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let process_id = "stream-cap-1".to_string();
@@ -746,7 +746,7 @@ async fn command_exec_pipe_streams_output_and_accepts_write() -> Result<()> {
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let process_id = "pipe-1".to_string();
@@ -822,7 +822,7 @@ async fn command_exec_tty_implies_streaming_and_reports_pty_output() -> Result<(
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let process_id = "tty-1".to_string();
@@ -893,7 +893,7 @@ async fn command_exec_tty_supports_initial_size_and_resize() -> Result<()> {
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let process_id = "tty-size-1".to_string();
@@ -1062,7 +1062,7 @@ async fn command_exec_process_ids_are_connection_scoped_and_disconnect_terminate
}
async fn read_command_exec_delta(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
) -> Result<CommandExecOutputDeltaNotification> {
let notification = mcp
.read_stream_until_notification_message("command/exec/outputDelta")
@@ -1071,7 +1071,7 @@ async fn read_command_exec_delta(
}
async fn wait_for_command_exec_output_contains(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
process_id: &str,
stream: CommandExecOutputStream,
expected: &str,
@@ -1094,7 +1094,7 @@ async fn wait_for_command_exec_output_contains(
}
async fn wait_for_command_exec_outputs_contains(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
process_id: &str,
stdout_expected: &str,
stderr_expected: &str,
@@ -1112,7 +1112,7 @@ async fn wait_for_command_exec_outputs_contains(
}
enum CommandExecDeltaReader<'a> {
Mcp(&'a mut McpProcess),
Mcp(&'a mut TestAppServer),
Websocket(&'a mut super::connection_handling_websocket::WsClient),
}
@@ -9,7 +9,7 @@
use anyhow::Result;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
use app_test_support::write_mock_responses_config_toml;
@@ -82,7 +82,7 @@ async fn auto_compaction_local_emits_started_and_completed_items() -> Result<()>
COMPACT_PROMPT,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_thread(&mut mcp).await?;
@@ -162,7 +162,8 @@ async fn auto_compaction_remote_emits_started_and_completed_items() -> Result<()
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_thread(&mut mcp).await?;
@@ -268,7 +269,7 @@ async fn thread_compact_start_triggers_compaction_and_returns_empty_response() -
COMPACT_PROMPT,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_thread(&mut mcp).await?;
@@ -318,7 +319,7 @@ async fn thread_compact_start_rejects_invalid_thread_id() -> Result<()> {
COMPACT_PROMPT,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -354,7 +355,7 @@ async fn thread_compact_start_rejects_unknown_thread_id() -> Result<()> {
COMPACT_PROMPT,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -374,7 +375,7 @@ async fn thread_compact_start_rejects_unknown_thread_id() -> Result<()> {
Ok(())
}
async fn start_thread(mcp: &mut McpProcess) -> Result<String> {
async fn start_thread(mcp: &mut TestAppServer) -> Result<String> {
let thread_id = mcp
.send_thread_start_request(ThreadStartParams {
model: Some("mock-model".to_string()),
@@ -390,7 +391,11 @@ async fn start_thread(mcp: &mut McpProcess) -> Result<String> {
Ok(thread.id)
}
async fn send_turn_and_wait(mcp: &mut McpProcess, thread_id: &str, text: &str) -> Result<String> {
async fn send_turn_and_wait(
mcp: &mut TestAppServer,
thread_id: &str,
text: &str,
) -> Result<String> {
let turn_id = mcp
.send_turn_start_request(TurnStartParams {
thread_id: thread_id.to_string(),
@@ -412,7 +417,7 @@ async fn send_turn_and_wait(mcp: &mut McpProcess, thread_id: &str, text: &str) -
Ok(turn.id)
}
async fn wait_for_turn_completed(mcp: &mut McpProcess, turn_id: &str) -> Result<()> {
async fn wait_for_turn_completed(mcp: &mut TestAppServer, turn_id: &str) -> Result<()> {
loop {
let notification: JSONRPCNotification = timeout(
DEFAULT_READ_TIMEOUT,
@@ -428,7 +433,7 @@ async fn wait_for_turn_completed(mcp: &mut McpProcess, turn_id: &str) -> Result<
}
async fn wait_for_context_compaction_started(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
) -> Result<ItemStartedNotification> {
loop {
let notification: JSONRPCNotification = timeout(
@@ -445,7 +450,7 @@ async fn wait_for_context_compaction_started(
}
async fn wait_for_context_compaction_completed(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
) -> Result<ItemCompletedNotification> {
loop {
let notification: JSONRPCNotification = timeout(
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::test_path_buf_with_windows;
use app_test_support::test_tmp_path_buf;
use app_test_support::to_response;
@@ -58,7 +58,7 @@ sandbox_mode = "workspace-write"
let codex_home_path = codex_home.path().canonicalize()?;
let user_file = AbsolutePathBuf::try_from(codex_home_path.join("config.toml"))?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -108,7 +108,7 @@ allowed_domains = ["example.com"]
let codex_home_path = codex_home.path().canonicalize()?;
let user_file = AbsolutePathBuf::try_from(codex_home_path.join("config.toml"))?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -179,7 +179,7 @@ forced_chatgpt_workspace_id = "{WORKSPACE_ID}"
),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -218,7 +218,7 @@ forced_chatgpt_workspace_id = ["{WORKSPACE_ID_A}", "{WORKSPACE_ID_B}"]
),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -260,7 +260,7 @@ location = { country = "US", city = "New York", timezone = "America/New_York" }
"#,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -304,7 +304,7 @@ web_search = true
"#,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -340,7 +340,7 @@ default_tools_approval_mode = "prompt"
let codex_home_path = codex_home.path().canonicalize()?;
let user_file = AbsolutePathBuf::try_from(codex_home_path.join("config.toml"))?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -427,7 +427,7 @@ width = 320
"#,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -474,7 +474,7 @@ model_reasoning_effort = "high"
set_project_trust_level(codex_home.path(), workspace.path(), TrustLevel::Trusted)?;
let project_config = AbsolutePathBuf::try_from(project_config_dir)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -544,7 +544,7 @@ writable_roots = [{}]
let managed_path_str = managed_path.display().to_string();
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[(
"CODEX_APP_SERVER_MANAGED_CONFIG_PATH",
@@ -640,7 +640,7 @@ model = "gpt-old"
"#,
)?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let read_id = mcp
@@ -701,7 +701,7 @@ async fn config_value_write_updates_desktop_settings() -> Result<()> {
let codex_home = temp_dir.path().canonicalize()?;
write_config(&temp_dir, "")?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let write_id = mcp
@@ -750,7 +750,7 @@ model = "gpt-old"
"#,
)?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let write_id = mcp
@@ -798,7 +798,7 @@ model = "gpt-old"
"#,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let write_id = mcp
@@ -833,7 +833,7 @@ async fn config_batch_write_applies_multiple_edits() -> Result<()> {
let codex_home = tmp_dir.path().canonicalize()?;
write_config(&tmp_dir, "")?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let writable_root = test_tmp_path_buf();
@@ -905,7 +905,7 @@ model = "gpt-5.3-spark"
"#,
)?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let batch_id = mcp
@@ -961,7 +961,7 @@ async fn config_batch_write_updates_multiple_desktop_settings() -> Result<()> {
let codex_home = tmp_dir.path().canonicalize()?;
write_config(&tmp_dir, "")?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let batch_id = mcp
@@ -1,6 +1,6 @@
use anyhow::Context;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_sequence_unchecked;
use app_test_support::to_response;
@@ -51,7 +51,7 @@ async fn thread_start_injects_dynamic_tools_into_model_requests() -> Result<()>
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
// Use a minimal JSON schema so we can assert the tool payload round-trips.
@@ -135,7 +135,7 @@ async fn thread_start_keeps_hidden_dynamic_tools_out_of_model_requests() -> Resu
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let dynamic_tool = DynamicToolSpec {
@@ -208,7 +208,7 @@ async fn thread_start_rejects_hidden_dynamic_tools_without_namespace() -> Result
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let dynamic_tool = DynamicToolSpec {
@@ -248,7 +248,7 @@ async fn thread_start_rejects_dynamic_tools_not_supported_by_responses() -> Resu
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let dynamic_tool = DynamicToolSpec {
@@ -313,7 +313,7 @@ async fn dynamic_tool_call_round_trip_sends_text_content_items_to_model() -> Res
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let dynamic_tool = DynamicToolSpec {
@@ -489,7 +489,7 @@ async fn dynamic_tool_call_round_trip_sends_content_items_to_model() -> Result<(
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let dynamic_tool = DynamicToolSpec {
@@ -708,7 +708,7 @@ fn function_call_output_raw_output(body: &Value, call_id: &str) -> Option<Value>
}
async fn wait_for_dynamic_tool_started(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
call_id: &str,
) -> Result<ItemStartedNotification> {
loop {
@@ -728,7 +728,7 @@ async fn wait_for_dynamic_tool_started(
}
async fn wait_for_dynamic_tool_completed(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
call_id: &str,
) -> Result<ItemCompletedNotification> {
loop {
@@ -1,6 +1,6 @@
use anyhow::Result;
use app_test_support::DEFAULT_CLIENT_NAME;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_mock_responses_server_sequence_unchecked;
use app_test_support::to_response;
use codex_app_server_protocol::AskForApproval;
@@ -30,7 +30,7 @@ const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
#[tokio::test]
async fn mock_experimental_method_requires_experimental_api_capability() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let init = mcp
.initialize_with_capabilities(
@@ -61,7 +61,7 @@ async fn mock_experimental_method_requires_experimental_api_capability() -> Resu
#[tokio::test]
async fn realtime_conversation_start_requires_experimental_api_capability() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let init = mcp
.initialize_with_capabilities(
@@ -99,7 +99,7 @@ async fn realtime_conversation_start_requires_experimental_api_capability() -> R
#[tokio::test]
async fn thread_memory_mode_set_requires_experimental_api_capability() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let init = mcp
.initialize_with_capabilities(
@@ -133,7 +133,7 @@ async fn thread_memory_mode_set_requires_experimental_api_capability() -> Result
#[tokio::test]
async fn thread_settings_update_requires_experimental_api_capability() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let init = mcp
.initialize_with_capabilities(
@@ -167,7 +167,7 @@ async fn thread_settings_update_requires_experimental_api_capability() -> Result
#[tokio::test]
async fn realtime_webrtc_start_requires_experimental_api_capability() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let init = mcp
.initialize_with_capabilities(
@@ -210,7 +210,7 @@ async fn thread_start_mock_field_requires_experimental_api_capability() -> Resul
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let init = mcp
.initialize_with_capabilities(
default_client_info(),
@@ -248,7 +248,7 @@ async fn thread_start_without_dynamic_tools_allows_without_experimental_api_capa
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let init = mcp
.initialize_with_capabilities(
default_client_info(),
@@ -285,7 +285,7 @@ async fn thread_start_granular_approval_policy_requires_experimental_api_capabil
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let init = mcp
.initialize_with_capabilities(
default_client_info(),
@@ -2,7 +2,7 @@ use std::time::Duration;
use anyhow::Result;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_mock_responses_server_repeating_assistant;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
@@ -50,7 +50,7 @@ async fn experimental_feature_list_returns_feature_metadata_with_stage() -> Resu
))
.build()
.await?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
@@ -134,7 +134,7 @@ async fn experimental_feature_list_marks_apps_and_plugins_disabled_by_workspace_
.mount(&server)
.await;
let mut mcp = McpProcess::new_without_managed_config(codex_home.path()).await?;
let mut mcp = TestAppServer::new_without_managed_config(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -195,7 +195,7 @@ memories = true
"#,
)?;
let mut mcp = McpProcess::new_without_managed_config(codex_home.path()).await?;
let mut mcp = TestAppServer::new_without_managed_config(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
@@ -229,7 +229,7 @@ memories = true
#[tokio::test]
async fn experimental_feature_list_rejects_unknown_thread_id() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -264,7 +264,7 @@ async fn experimental_feature_enablement_set_applies_to_global_and_thread_config
let project_cwd = codex_home.path().join("project");
std::fs::create_dir_all(&project_cwd)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let actual =
@@ -299,7 +299,7 @@ async fn experimental_feature_enablement_set_does_not_override_user_config() ->
codex_home.path().join("config.toml"),
"[features]\nmemories = false\n",
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let actual = set_experimental_feature_enablement(
@@ -330,7 +330,7 @@ async fn experimental_feature_enablement_set_does_not_override_user_config() ->
#[tokio::test]
async fn experimental_feature_enablement_set_only_updates_named_features() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
set_experimental_feature_enablement(&mut mcp, BTreeMap::from([("apps".to_string(), true)]))
@@ -411,7 +411,7 @@ async fn experimental_feature_enablement_set_only_updates_named_features() -> Re
#[tokio::test]
async fn experimental_feature_enablement_set_allows_remote_control() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let remote_control_enabled = false;
let enablement = BTreeMap::from([("remote_control".to_string(), remote_control_enabled)]);
@@ -429,7 +429,7 @@ async fn experimental_feature_enablement_set_allows_remote_control() -> Result<(
#[tokio::test]
async fn experimental_feature_enablement_set_empty_map_is_no_op() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
set_experimental_feature_enablement(&mut mcp, BTreeMap::from([("apps".to_string(), true)]))
@@ -459,7 +459,7 @@ async fn experimental_feature_enablement_set_empty_map_is_no_op() -> Result<()>
#[tokio::test]
async fn experimental_feature_enablement_set_rejects_non_allowlisted_feature() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -493,7 +493,7 @@ async fn experimental_feature_enablement_set_rejects_non_allowlisted_feature() -
}
async fn set_experimental_feature_enablement(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
enablement: BTreeMap<String, bool>,
) -> Result<ExperimentalFeatureEnablementSetResponse> {
let request_id = mcp
@@ -504,7 +504,7 @@ async fn set_experimental_feature_enablement(
read_response(mcp, request_id).await
}
async fn read_config(mcp: &mut McpProcess, cwd: Option<String>) -> Result<ConfigReadResponse> {
async fn read_config(mcp: &mut TestAppServer, cwd: Option<String>) -> Result<ConfigReadResponse> {
let request_id = mcp
.send_config_read_request(ConfigReadParams {
include_layers: false,
@@ -514,7 +514,7 @@ async fn read_config(mcp: &mut McpProcess, cwd: Option<String>) -> Result<Config
read_response(mcp, request_id).await
}
async fn read_response<T: DeserializeOwned>(mcp: &mut McpProcess, request_id: i64) -> Result<T> {
async fn read_response<T: DeserializeOwned>(mcp: &mut TestAppServer, request_id: i64) -> Result<T> {
let response: JSONRPCResponse = timeout(
DEFAULT_TIMEOUT,
mcp.read_stream_until_response_message(RequestId::Integer(request_id)),
@@ -1,7 +1,7 @@
use std::time::Duration;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_mock_responses_server_repeating_assistant;
use app_test_support::to_response;
use app_test_support::write_mock_responses_config_toml;
@@ -38,7 +38,8 @@ async fn external_agent_config_import_sends_completion_notification_for_sync_onl
let codex_home = TempDir::new()?;
let home_dir = codex_home.path().display().to_string();
let mut mcp =
McpProcess::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))]).await?;
TestAppServer::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))])
.await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -117,7 +118,8 @@ async fn external_agent_config_import_sends_completion_notification_for_local_pl
let home_dir = codex_home.path().display().to_string();
let mut mcp =
McpProcess::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))]).await?;
TestAppServer::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))])
.await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -205,7 +207,8 @@ async fn external_agent_config_import_sends_completion_notification_after_pendin
let home_dir = codex_home.path().display().to_string();
let mut mcp =
McpProcess::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))]).await?;
TestAppServer::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))])
.await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -283,7 +286,8 @@ async fn external_agent_config_import_creates_session_rollouts() -> Result<()> {
let home_dir = codex_home.path().display().to_string();
let mut mcp =
McpProcess::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))]).await?;
TestAppServer::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))])
.await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -456,7 +460,8 @@ async fn external_agent_config_import_accepts_detected_session_payload_after_res
let home_dir = codex_home.path().display().to_string();
let mut mcp =
McpProcess::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))]).await?;
TestAppServer::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))])
.await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -541,7 +546,8 @@ async fn external_agent_config_import_skips_already_imported_session_versions()
let home_dir = codex_home.path().display().to_string();
let mut mcp =
McpProcess::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))]).await?;
TestAppServer::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))])
.await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -637,7 +643,8 @@ async fn external_agent_config_import_returns_before_background_session_import_f
let home_dir = codex_home.path().display().to_string();
let mut mcp =
McpProcess::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))]).await?;
TestAppServer::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))])
.await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -766,7 +773,8 @@ async fn external_agent_config_import_rejects_undetected_session_paths() -> Resu
let home_dir = codex_home.path().display().to_string();
let mut mcp =
McpProcess::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))]).await?;
TestAppServer::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))])
.await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -885,7 +893,8 @@ async fn external_agent_config_import_compacts_huge_session_before_first_follow_
let home_dir = codex_home.path().display().to_string();
let mut mcp =
McpProcess::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))]).await?;
TestAppServer::new_with_env(codex_home.path(), &[("HOME", Some(home_dir.as_str()))])
.await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
+6 -6
View File
@@ -1,6 +1,6 @@
use anyhow::Context;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use base64::Engine;
use base64::engine::general_purpose::STANDARD;
@@ -36,14 +36,14 @@ const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(60);
const DEFAULT_READ_TIMEOUT: Duration = Duration::from_secs(10);
const OPTIONAL_FS_CHANGE_TIMEOUT: Duration = Duration::from_secs(2);
async fn initialized_mcp(codex_home: &TempDir) -> Result<McpProcess> {
let mut mcp = McpProcess::new(codex_home.path()).await?;
async fn initialized_mcp(codex_home: &TempDir) -> Result<TestAppServer> {
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
Ok(mcp)
}
async fn expect_error_message(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
request_id: i64,
expected_message: &str,
) -> Result<()> {
@@ -125,7 +125,7 @@ async fn fs_methods_return_error_when_local_environment_is_disabled() -> Result<
let codex_home = TempDir::new()?;
let absolute_file = codex_home.path().join("absolute.txt");
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[(CODEX_EXEC_SERVER_URL_ENV_VAR, Some("none"))],
)
@@ -853,7 +853,7 @@ fn fs_changed_notification(notification: JSONRPCNotification) -> Result<FsChange
}
async fn maybe_fs_changed_notification(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
) -> Result<Option<FsChangedNotification>> {
match timeout(
OPTIONAL_FS_CHANGE_TIMEOUT,
@@ -1,7 +1,7 @@
use std::time::Duration;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_sequence_unchecked;
use app_test_support::to_response;
@@ -135,7 +135,7 @@ async fn hooks_list_shows_discovered_hook() -> Result<()> {
let cwd = TempDir::new()?;
write_user_hook_config(codex_home.path())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -211,7 +211,7 @@ async fn hooks_list_shows_discovered_plugin_hook() -> Result<()> {
}"#,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -270,7 +270,7 @@ async fn hooks_list_shows_plugin_hook_load_warnings() -> Result<()> {
let cwd = TempDir::new()?;
write_plugin_hook_config(codex_home.path(), "{ not-json")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -326,7 +326,7 @@ timeout = 5
)?;
set_project_trust_level(codex_home.path(), workspace.path(), TrustLevel::Trusted)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -408,7 +408,7 @@ async fn hooks_list_uses_root_repo_hooks_for_linked_worktrees() -> Result<()> {
write_project_hook_config(&worktree_root.join(".codex"), "echo worktree hook")?;
set_project_trust_level(codex_home.path(), &repo_root, TrustLevel::Trusted)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let list_id = mcp
@@ -478,7 +478,7 @@ async fn config_batch_write_toggles_user_hook() -> Result<()> {
let cwd = TempDir::new()?;
write_user_hook_config(codex_home.path())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -629,7 +629,7 @@ command = "python3 {hook_script_path}"
),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let hook_list_id = mcp
@@ -879,7 +879,7 @@ command = "python3 {hook_script_path}"
),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let hook_list_id = mcp
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_sequence_unchecked;
use app_test_support::to_response;
@@ -33,7 +33,7 @@ async fn initialize_uses_client_info_name_as_originator() -> Result<()> {
let codex_home = TempDir::new()?;
let expected_codex_home = AbsolutePathBuf::try_from(codex_home.path().canonicalize()?)?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let message = timeout(
DEFAULT_READ_TIMEOUT,
@@ -68,7 +68,7 @@ async fn initialize_probe_does_not_override_originator() -> Result<()> {
let server = create_mock_responses_server_sequence_unchecked(responses).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let message = timeout(
DEFAULT_READ_TIMEOUT,
@@ -95,7 +95,7 @@ async fn initialize_codex_backend_does_not_override_originator() -> Result<()> {
let server = create_mock_responses_server_sequence_unchecked(responses).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let message = timeout(
DEFAULT_READ_TIMEOUT,
@@ -123,7 +123,7 @@ async fn initialize_respects_originator_override_env_var() -> Result<()> {
let codex_home = TempDir::new()?;
let expected_codex_home = AbsolutePathBuf::try_from(codex_home.path().canonicalize()?)?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[(
"CODEX_INTERNAL_ORIGINATOR_OVERRIDE",
@@ -165,7 +165,7 @@ async fn initialize_rejects_invalid_client_name() -> Result<()> {
let server = create_mock_responses_server_sequence_unchecked(responses).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[("CODEX_INTERNAL_ORIGINATOR_OVERRIDE", None)],
)
@@ -200,7 +200,7 @@ async fn initialize_opt_out_notification_methods_filters_notifications() -> Resu
let server = create_mock_responses_server_sequence_unchecked(responses).await;
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let message = timeout(
DEFAULT_READ_TIMEOUT,
@@ -282,7 +282,7 @@ async fn turn_start_notify_payload_includes_initialize_client_name() -> Result<(
),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(
DEFAULT_READ_TIMEOUT,
mcp.initialize_with_client_info(ClientInfo {
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use codex_app_server_protocol::JSONRPCResponse;
use codex_app_server_protocol::MarketplaceAddParams;
@@ -28,7 +28,7 @@ async fn marketplace_add_local_directory_source() -> Result<()> {
r#"{"name":"sample"}"#,
)?;
std::fs::write(source.join("plugins/sample/marker.txt"), "local ref")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -2,7 +2,7 @@ use std::time::Duration;
use anyhow::Context;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use codex_app_server_protocol::JSONRPCResponse;
use codex_app_server_protocol::MarketplaceRemoveParams;
@@ -53,7 +53,7 @@ async fn marketplace_remove_deletes_config_and_installed_root() -> Result<()> {
write_installed_marketplace(codex_home.path(), "debug")?;
let installed_root = marketplace_install_root(codex_home.path()).join("debug");
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -91,7 +91,7 @@ async fn marketplace_remove_deletes_config_and_installed_root() -> Result<()> {
async fn marketplace_remove_rejects_unknown_marketplace() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -4,7 +4,7 @@ use std::time::Duration;
use anyhow::Context;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use codex_app_server_protocol::JSONRPCResponse;
use codex_app_server_protocol::MarketplaceUpgradeParams;
@@ -127,7 +127,7 @@ fn expected_installed_root(codex_home: &Path, marketplace_name: &str) -> Result<
}
async fn send_marketplace_upgrade(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
marketplace_name: Option<&str>,
) -> Result<MarketplaceUpgradeResponse> {
let request_id = mcp
@@ -169,7 +169,7 @@ async fn marketplace_upgrade_all_configured_git_marketplaces() -> Result<()> {
)?;
disable_plugin_startup_tasks(codex_home.path())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let debug_root = expected_installed_root(codex_home.path(), "debug")?;
@@ -223,7 +223,7 @@ async fn marketplace_upgrade_named_marketplace_only() -> Result<()> {
)?;
disable_plugin_startup_tasks(codex_home.path())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let tools_root = expected_installed_root(codex_home.path(), "tools")?;
@@ -264,7 +264,7 @@ async fn marketplace_upgrade_returns_empty_roots_when_already_up_to_date() -> Re
)?;
disable_plugin_startup_tasks(codex_home.path())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let first_response = send_marketplace_upgrade(&mut mcp, Some("debug")).await?;
assert!(first_response.errors.is_empty());
@@ -292,7 +292,7 @@ async fn marketplace_upgrade_rejects_unknown_or_non_git_marketplace() -> Result<
&configured_local_marketplace_update(&local_source.path().display().to_string()),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
for marketplace_name in ["missing", "local-only"] {
@@ -3,7 +3,7 @@ use std::time::Duration;
use anyhow::Result;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
use axum::Router;
@@ -92,7 +92,7 @@ stream_max_retries = 0
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
@@ -157,7 +157,7 @@ apps = true
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let read_request_id = mcp
@@ -3,7 +3,7 @@ use std::sync::Arc;
use anyhow::Result;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
use axum::Json;
@@ -116,7 +116,7 @@ async fn mcp_server_elicitation_round_trip() -> Result<()> {
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
@@ -5,7 +5,7 @@ use std::sync::Arc;
use std::time::Duration;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_mock_responses_server_sequence_unchecked;
use app_test_support::to_response;
use app_test_support::write_mock_responses_config_toml;
@@ -67,7 +67,7 @@ url = "{mcp_server_url}/mcp"
));
std::fs::write(config_path, config_toml)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -132,7 +132,7 @@ async fn mcp_server_status_list_uses_thread_project_local_config() -> Result<()>
std::fs::create_dir_all(workspace.path().join(".git"))?;
set_project_trust_level(codex_home.path(), workspace.path(), TrustLevel::Trusted)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
@@ -336,7 +336,7 @@ url = "{mcp_server_url}/mcp"
));
std::fs::write(config_path, config_toml)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -401,7 +401,7 @@ url = "{underscore_server_url}/mcp"
));
std::fs::write(config_path, config_toml)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -4,7 +4,7 @@ use std::sync::Arc;
use std::time::Duration;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_sequence;
use app_test_support::to_response;
@@ -94,7 +94,7 @@ url = "{mcp_server_url}/mcp"
));
std::fs::write(config_path, config_toml)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
@@ -161,7 +161,7 @@ url = "{mcp_server_url}/mcp"
#[tokio::test]
async fn mcp_server_tool_call_returns_error_for_unknown_thread() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -212,7 +212,7 @@ url = "{mcp_server_url}/mcp"
));
std::fs::write(config_path, config_toml)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
@@ -322,7 +322,7 @@ url = "{mcp_server_url}/mcp"
));
std::fs::write(config_path, config_toml)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
@@ -442,7 +442,7 @@ url = "{mcp_server_url}/mcp"
));
std::fs::write(config_path, config_toml)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
@@ -683,7 +683,7 @@ async fn start_mcp_server() -> Result<(String, JoinHandle<()>)> {
}
async fn wait_for_mcp_tool_call_completed(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
call_id: &str,
) -> Result<ItemCompletedNotification> {
loop {
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use chrono::Utc;
use codex_app_server_protocol::JSONRPCResponse;
@@ -36,7 +36,7 @@ async fn memory_reset_clears_memory_files_and_rows_preserves_threads() -> Result
let thread_id = seed_stage1_output(&state_db, codex_home.path()).await?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -2,7 +2,7 @@ use std::time::Duration;
use anyhow::Result;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
use app_test_support::write_models_cache;
@@ -95,7 +95,7 @@ fn expected_visible_models() -> Vec<Model> {
async fn list_models_returns_all_models_with_large_limit() -> Result<()> {
let codex_home = TempDir::new()?;
write_models_cache(codex_home.path())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
@@ -129,7 +129,7 @@ async fn list_models_returns_all_models_with_large_limit() -> Result<()> {
async fn list_models_includes_hidden_models() -> Result<()> {
let codex_home = TempDir::new()?;
write_models_cache(codex_home.path())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
@@ -214,7 +214,8 @@ openai_base_url = "{server_uri}/v1"
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -256,7 +257,7 @@ openai_base_url = "{server_uri}/v1"
async fn list_models_pagination_works() -> Result<()> {
let codex_home = TempDir::new()?;
write_models_cache(codex_home.path())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
@@ -305,7 +306,7 @@ async fn list_models_pagination_works() -> Result<()> {
async fn list_models_rejects_invalid_cursor() -> Result<()> {
let codex_home = TempDir::new()?;
write_models_cache(codex_home.path())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
@@ -1,7 +1,7 @@
use std::time::Duration;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use codex_app_server_protocol::JSONRPCResponse;
use codex_app_server_protocol::ModelProviderCapabilitiesReadParams;
@@ -16,7 +16,7 @@ const DEFAULT_TIMEOUT: Duration = Duration::from_secs(30);
#[tokio::test]
async fn read_default_provider_capabilities() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -46,7 +46,7 @@ async fn read_amazon_bedrock_provider_capabilities() -> Result<()> {
r#"model_provider = "amazon-bedrock"
"#,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use codex_app_server_protocol::JSONRPCResponse;
use codex_app_server_protocol::RequestId;
@@ -32,7 +32,7 @@ async fn turn_start_accepts_output_schema_v2() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -115,7 +115,7 @@ async fn turn_start_output_schema_is_per_turn_v2() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -1,7 +1,7 @@
use std::time::Duration;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use codex_app_server_protocol::JSONRPCResponse;
use codex_app_server_protocol::PermissionProfileListParams;
@@ -41,7 +41,7 @@ description = "Inspect without writes."
"#,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -108,7 +108,7 @@ description = "Project-scoped profile."
)?;
set_project_trust_level(codex_home.path(), workspace.path(), TrustLevel::Trusted)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let first_request_id = mcp
@@ -181,7 +181,7 @@ description = "Project-scoped profile."
)?;
set_project_trust_level(codex_home.path(), workspace.path(), TrustLevel::Trusted)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -221,7 +221,7 @@ description = "Project-scoped profile."
}
async fn read_response<T: serde::de::DeserializeOwned>(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
request_id: i64,
) -> Result<T> {
let response: JSONRPCResponse = timeout(
@@ -1,7 +1,7 @@
use anyhow::Result;
use anyhow::anyhow;
use anyhow::bail;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_mock_responses_server_sequence_unchecked;
use app_test_support::to_response;
use codex_app_server_protocol::ItemCompletedNotification;
@@ -53,7 +53,7 @@ async fn plan_mode_uses_proposed_plan_block_for_plan_item() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let turn = start_plan_mode_turn(&mut mcp).await?;
@@ -111,7 +111,7 @@ async fn plan_mode_without_proposed_plan_does_not_emit_plan_item() -> Result<()>
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let _turn = start_plan_mode_turn(&mut mcp).await?;
@@ -127,7 +127,7 @@ async fn plan_mode_without_proposed_plan_does_not_emit_plan_item() -> Result<()>
Ok(())
}
async fn start_plan_mode_turn(mcp: &mut McpProcess) -> Result<codex_app_server_protocol::Turn> {
async fn start_plan_mode_turn(mcp: &mut TestAppServer) -> Result<codex_app_server_protocol::Turn> {
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
model: Some("mock-model".to_string()),
@@ -170,7 +170,7 @@ async fn start_plan_mode_turn(mcp: &mut McpProcess) -> Result<codex_app_server_p
}
async fn collect_turn_notifications(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
) -> Result<(
Vec<ThreadItem>,
Vec<ThreadItem>,
@@ -9,7 +9,7 @@ use anyhow::Result;
use anyhow::bail;
use app_test_support::ChatGptAuthFixture;
use app_test_support::DEFAULT_CLIENT_NAME;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::start_analytics_events_server;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
@@ -72,7 +72,7 @@ const TEST_ALLOW_HTTP_REMOTE_PLUGIN_BUNDLE_DOWNLOADS: &str =
#[tokio::test]
async fn plugin_install_rejects_relative_marketplace_paths() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -99,7 +99,7 @@ async fn plugin_install_rejects_relative_marketplace_paths() -> Result<()> {
#[tokio::test]
async fn plugin_install_rejects_missing_install_source() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -128,7 +128,7 @@ async fn plugin_install_rejects_missing_install_source() -> Result<()> {
#[tokio::test]
async fn plugin_install_rejects_multiple_install_sources() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -165,7 +165,7 @@ async fn plugin_install_rejects_remote_marketplace_when_plugins_are_disabled() -
plugins = false
"#,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -231,7 +231,7 @@ async fn plugin_install_writes_remote_plugin_to_cloud_and_cache() -> Result<()>
)
.await;
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[(TEST_ALLOW_HTTP_REMOTE_PLUGIN_BUNDLE_DOWNLOADS, Some("1"))],
)
@@ -302,7 +302,7 @@ async fn plugin_install_rejects_missing_remote_bundle_url() -> Result<()> {
.await;
mount_empty_remote_installed_plugins(&server).await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = send_remote_plugin_install_request(&mut mcp, REMOTE_PLUGIN_ID).await?;
@@ -343,7 +343,7 @@ async fn plugin_install_rejects_plain_http_remote_bundle_url() -> Result<()> {
mount_remote_plugin_detail(&server, REMOTE_PLUGIN_ID, "1.2.3", Some(&bundle_url)).await;
mount_empty_remote_installed_plugins(&server).await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = send_remote_plugin_install_request(&mut mcp, REMOTE_PLUGIN_ID).await?;
@@ -389,7 +389,7 @@ async fn plugin_install_rejects_invalid_remote_release_version() -> Result<()> {
.await;
mount_empty_remote_installed_plugins(&server).await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = send_remote_plugin_install_request(&mut mcp, REMOTE_PLUGIN_ID).await?;
@@ -421,7 +421,7 @@ async fn plugin_install_rejects_invalid_remote_release_version() -> Result<()> {
async fn plugin_install_rejects_invalid_remote_plugin_name() -> Result<()> {
let codex_home = TempDir::new()?;
write_remote_plugin_catalog_config(codex_home.path(), "https://example.invalid/backend-api/")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -464,7 +464,7 @@ async fn plugin_install_rejects_remote_plugin_disabled_by_admin_before_download(
.await;
mount_empty_remote_installed_plugins(&server).await;
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[(TEST_ALLOW_HTTP_REMOTE_PLUGIN_BUNDLE_DOWNLOADS, Some("1"))],
)
@@ -544,7 +544,7 @@ async fn plugin_install_rejects_when_workspace_codex_plugins_disabled() -> Resul
.mount(&server)
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -573,7 +573,7 @@ async fn plugin_install_rejects_when_workspace_codex_plugins_disabled() -> Resul
#[tokio::test]
async fn plugin_install_returns_invalid_request_for_missing_marketplace_file() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -614,7 +614,7 @@ async fn plugin_install_returns_invalid_request_for_not_available_plugin() -> Re
let marketplace_path =
AbsolutePathBuf::try_from(repo_root.path().join(".agents/plugins/marketplace.json"))?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -664,7 +664,7 @@ async fn plugin_install_returns_invalid_request_for_disallowed_product_plugin()
AbsolutePathBuf::try_from(repo_root.path().join(".agents/plugins/marketplace.json"))?;
let mut mcp =
McpProcess::new_with_args(codex_home.path(), &["--session-source", "atlas"]).await?;
TestAppServer::new_with_args(codex_home.path(), &["--session-source", "atlas"]).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -713,7 +713,7 @@ async fn plugin_install_tracks_analytics_event() -> Result<()> {
let marketplace_path =
AbsolutePathBuf::try_from(repo_root.path().join(".agents/plugins/marketplace.json"))?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -768,7 +768,7 @@ async fn plugin_install_tracks_remote_plugin_analytics_event() -> Result<()> {
mount_remote_plugin_install(&server, REMOTE_PLUGIN_ID).await;
mount_backend_analytics_events(&server).await;
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[(TEST_ALLOW_HTTP_REMOTE_PLUGIN_BUNDLE_DOWNLOADS, Some("1"))],
)
@@ -820,7 +820,7 @@ async fn plugin_install_errors_when_remote_bundle_download_fails() -> Result<()>
mount_empty_remote_installed_plugins(&server).await;
mount_remote_plugin_install(&server, REMOTE_PLUGIN_ID).await;
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[(TEST_ALLOW_HTTP_REMOTE_PLUGIN_BUNDLE_DOWNLOADS, Some("1"))],
)
@@ -920,7 +920,7 @@ async fn plugin_install_returns_apps_needing_auth() -> Result<()> {
let marketplace_path =
AbsolutePathBuf::try_from(repo_root.path().join(".agents/plugins/marketplace.json"))?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let directory_requests_before_install = server_control.directory_request_count();
@@ -1007,7 +1007,7 @@ async fn plugin_install_filters_disallowed_apps_needing_auth() -> Result<()> {
let marketplace_path =
AbsolutePathBuf::try_from(repo_root.path().join(".agents/plugins/marketplace.json"))?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let directory_requests_before_install =
warm_app_directory_cache(&mut mcp, &server_control, "Alpha").await?;
@@ -1080,7 +1080,7 @@ async fn plugin_install_makes_bundled_mcp_servers_available_to_followup_requests
let marketplace_path =
AbsolutePathBuf::try_from(repo_root.path().join(".agents/plugins/marketplace.json"))?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1141,7 +1141,7 @@ impl AppsServerControl {
}
async fn warm_app_directory_cache(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
server_control: &AppsServerControl,
expected_app_name: &str,
) -> Result<usize> {
@@ -1584,7 +1584,7 @@ async fn mount_remote_plugin_install_after_cache_write(
}
async fn send_remote_plugin_install_request(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
remote_plugin_id: &str,
) -> Result<i64> {
mcp.send_plugin_install_request(PluginInstallParams {
@@ -3,7 +3,7 @@ use std::time::Duration;
use anyhow::Result;
use anyhow::bail;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
use codex_app_server_protocol::JSONRPCResponse;
@@ -81,7 +81,7 @@ async fn plugin_list_skips_invalid_marketplace_file_and_reports_error() -> Resul
std::fs::write(marketplace_path.as_path(), "{not json")?;
let home = codex_home.path().to_string_lossy().into_owned();
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("HOME", Some(home.as_str())),
@@ -146,7 +146,7 @@ enabled = true
"#,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -295,7 +295,7 @@ enabled = true
"#,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -320,7 +320,7 @@ enabled = true
#[tokio::test]
async fn plugin_list_rejects_relative_cwds() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -397,7 +397,7 @@ async fn plugin_list_keeps_valid_marketplaces_when_another_marketplace_fails_to_
std::fs::write(invalid_marketplace_path.as_path(), "{not json")?;
let home = codex_home.path().to_string_lossy().into_owned();
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("HOME", Some(home.as_str())),
@@ -514,7 +514,7 @@ async fn plugin_list_returns_empty_when_workspace_codex_plugins_disabled() -> Re
.await;
let home = codex_home.path().to_string_lossy().into_owned();
let mut mcp = McpProcess::new_without_managed_config_with_env(
let mut mcp = TestAppServer::new_without_managed_config_with_env(
codex_home.path(),
&[
("HOME", Some(home.as_str())),
@@ -605,7 +605,7 @@ async fn plugin_list_reuses_cached_workspace_codex_plugins_setting() -> Result<(
.await;
let home = codex_home.path().to_string_lossy().into_owned();
let mut mcp = McpProcess::new_without_managed_config_with_env(
let mut mcp = TestAppServer::new_without_managed_config_with_env(
codex_home.path(),
&[
("HOME", Some(home.as_str())),
@@ -690,7 +690,7 @@ async fn plugin_list_uses_alternate_discoverable_manifest_and_keeps_undiscoverab
)?;
let home = codex_home.path().to_string_lossy().into_owned();
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("HOME", Some(home.as_str())),
@@ -803,7 +803,7 @@ async fn plugin_list_accepts_omitted_cwds() -> Result<()> {
}"#,
)?;
let home = codex_home.path().to_string_lossy().into_owned();
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("HOME", Some(home.as_str())),
@@ -863,7 +863,7 @@ async fn plugin_list_returns_share_context_for_shared_local_plugin() -> Result<(
&AbsolutePathBuf::try_from(plugin_root)?,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -955,7 +955,7 @@ enabled = false
"#,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1102,7 +1102,7 @@ enabled = false
let workspace_default = TempDir::new()?;
let home = codex_home.path().to_string_lossy().into_owned();
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("HOME", Some(home.as_str())),
@@ -1196,7 +1196,7 @@ async fn plugin_list_returns_plugin_interface_with_absolute_asset_paths() -> Res
}"##,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1309,7 +1309,7 @@ async fn plugin_list_accepts_legacy_string_default_prompt() -> Result<()> {
}"##,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1397,7 +1397,7 @@ enabled = true
"#,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1500,7 +1500,7 @@ async fn app_server_startup_remote_plugin_sync_runs_once() -> Result<()> {
.join(STARTUP_REMOTE_PLUGIN_SYNC_MARKER_FILE);
{
let mut mcp = McpProcess::new_with_plugin_startup_tasks(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_plugin_startup_tasks(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
wait_for_path_exists(&marker_path).await?;
@@ -1539,7 +1539,7 @@ async fn app_server_startup_remote_plugin_sync_runs_once() -> Result<()> {
assert!(config.contains(r#"[plugins."linear@openai-curated"]"#));
{
let mut mcp = McpProcess::new_with_plugin_startup_tasks(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_plugin_startup_tasks(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
}
@@ -1591,7 +1591,7 @@ async fn app_server_startup_sync_downloads_remote_installed_plugin_bundles() ->
let installed_path = codex_home
.path()
.join("plugins/cache/openai-curated-remote/linear/1.2.3");
let mut mcp = McpProcess::new_with_env_and_plugin_startup_tasks(
let mut mcp = TestAppServer::new_with_env_and_plugin_startup_tasks(
codex_home.path(),
&[(TEST_ALLOW_HTTP_REMOTE_PLUGIN_BUNDLE_DOWNLOADS, Some("1"))],
)
@@ -1669,7 +1669,7 @@ async fn plugin_list_sync_upgrades_and_removes_remote_installed_plugin_bundles()
.path()
.join("plugins/cache/openai-curated-remote/stale");
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[(TEST_ALLOW_HTTP_REMOTE_PLUGIN_BUNDLE_DOWNLOADS, Some("1"))],
)
@@ -1839,7 +1839,7 @@ async fn plugin_list_includes_remote_marketplaces_when_remote_plugin_enabled() -
.mount(&server)
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1963,7 +1963,7 @@ async fn plugin_list_includes_openai_curated_remote_collection_when_requested()
mount_remote_installed_plugins(&server, "WORKSPACE", empty_remote_installed_plugins_body())
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -2050,7 +2050,7 @@ async fn plugin_list_fail_opens_openai_curated_remote_collection_errors() -> Res
mount_remote_installed_plugins(&server, "WORKSPACE", empty_remote_installed_plugins_body())
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -2092,7 +2092,7 @@ async fn plugin_list_does_not_query_openai_curated_remote_collection_by_default(
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -2145,7 +2145,7 @@ async fn plugin_list_vertical_kind_noops_when_remote_plugin_enabled() -> Result<
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -2199,7 +2199,7 @@ async fn plugin_list_does_not_append_global_remote_when_marketplace_kinds_are_ex
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -2276,7 +2276,7 @@ plugin_sharing = true
mount_remote_installed_plugins(&server, "GLOBAL", &global_installed_body).await;
mount_remote_installed_plugins(&server, "WORKSPACE", &workspace_installed_body).await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -2365,7 +2365,7 @@ plugin_sharing = false
mount_remote_installed_plugins(&server, "WORKSPACE", empty_remote_installed_plugins_body())
.await;
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[(TEST_ALLOW_HTTP_REMOTE_PLUGIN_BUNDLE_DOWNLOADS, Some("1"))],
)
@@ -2439,7 +2439,7 @@ async fn plugin_list_fetches_workspace_directory_kind_without_remote_plugin_flag
mount_remote_plugin_list(&server, "WORKSPACE", &workspace_plugin_body).await;
mount_remote_installed_plugins(&server, "WORKSPACE", &workspace_installed_body).await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -2556,7 +2556,7 @@ async fn plugin_list_fetches_shared_with_me_kind() -> Result<()> {
mount_remote_installed_plugins(&server, "GLOBAL", empty_remote_installed_plugins_body()).await;
mount_remote_installed_plugins(&server, "WORKSPACE", &workspace_installed_body).await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -2713,7 +2713,7 @@ plugin_sharing = false
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -2848,7 +2848,7 @@ async fn plugin_list_marks_remote_plugin_disabled_by_admin() -> Result<()> {
.await;
}
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -2908,7 +2908,7 @@ remote_plugin = true
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -2944,7 +2944,7 @@ async fn plugin_list_fetches_featured_plugin_ids_without_chatgpt_auth() -> Resul
.mount(&server)
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -2983,7 +2983,7 @@ async fn plugin_list_uses_warmed_featured_plugin_ids_cache_on_first_request() ->
.mount(&server)
.await;
let mut mcp = McpProcess::new_with_plugin_startup_tasks(codex_home.path()).await?;
let mut mcp = TestAppServer::new_with_plugin_startup_tasks(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
wait_for_featured_plugin_request_count(&server, /*expected_count*/ 1).await?;
@@ -5,7 +5,7 @@ use std::time::Duration;
use anyhow::Result;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
use axum::Json;
@@ -64,7 +64,7 @@ const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
#[tokio::test]
async fn plugin_read_rejects_missing_read_source() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -93,7 +93,7 @@ async fn plugin_read_rejects_missing_read_source() -> Result<()> {
#[tokio::test]
async fn plugin_read_rejects_multiple_read_sources() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -190,7 +190,7 @@ plugins = true
.mount(&server)
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -297,7 +297,7 @@ async fn plugin_read_returns_share_context_for_shared_remote_plugin() -> Result<
.mount(&server)
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
for remote_marketplace_name in [
@@ -478,7 +478,7 @@ async fn plugin_read_reads_remote_plugin_details_when_remote_plugin_enabled() ->
.mount(&server)
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -563,7 +563,7 @@ async fn plugin_skill_read_reads_remote_skill_contents_when_remote_plugin_enable
.mount(&server)
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -615,7 +615,7 @@ async fn plugin_read_maps_missing_remote_plugin_to_invalid_request() -> Result<(
.mount(&server)
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -667,7 +667,7 @@ remote_plugin = true
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -697,7 +697,7 @@ remote_plugin = true
async fn plugin_read_rejects_invalid_remote_plugin_name() -> Result<()> {
let codex_home = TempDir::new()?;
write_remote_plugin_catalog_config(codex_home.path(), "https://example.invalid/backend-api/")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -755,7 +755,7 @@ enabled = true
)?;
write_installed_plugin(&codex_home, "openai-curated", "demo-plugin")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let marketplace_path =
@@ -855,7 +855,7 @@ async fn plugin_read_returns_share_context_for_shared_local_plugin() -> Result<(
.expect(1)
.mount(&server)
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -981,7 +981,7 @@ async fn plugin_read_keeps_remote_version_when_share_principals_are_missing() ->
.expect(1)
.mount(&server)
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1037,7 +1037,7 @@ async fn plugin_read_falls_back_to_local_share_context_without_remote_auth() ->
let plugin_path = AbsolutePathBuf::try_from(repo_root.path().join("demo-plugin"))?;
write_plugin_share_local_path_mapping(codex_home.path(), "plugins_123", &plugin_path)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1095,7 +1095,7 @@ async fn plugin_read_fails_on_malformed_share_mapping() -> Result<()> {
"not valid json\n",
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1287,7 +1287,7 @@ enabled = false
)?;
write_installed_plugin(&codex_home, "codex-curated", "demo-plugin")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let marketplace_path =
@@ -1458,7 +1458,7 @@ async fn plugin_read_returns_app_needs_auth() -> Result<()> {
let marketplace_path =
AbsolutePathBuf::try_from(repo_root.path().join(".agents/plugins/marketplace.json"))?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1525,7 +1525,7 @@ async fn plugin_read_accepts_legacy_string_default_prompt() -> Result<()> {
)?;
write_plugins_enabled_config(&codex_home)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1587,7 +1587,7 @@ async fn plugin_read_describes_uninstalled_git_source_without_cloning() -> Resul
)?;
write_plugins_enabled_config(&codex_home)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1650,7 +1650,7 @@ async fn plugin_read_returns_invalid_request_when_plugin_is_missing() -> Result<
)?;
write_plugins_enabled_config(&codex_home)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1703,7 +1703,7 @@ async fn plugin_read_returns_invalid_request_when_plugin_manifest_is_missing() -
)?;
write_plugins_enabled_config(&codex_home)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -4,7 +4,7 @@ use std::time::Duration;
use anyhow::Result;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
use codex_app_server_protocol::JSONRPCError;
@@ -102,7 +102,7 @@ async fn plugin_share_save_uploads_local_plugin() -> Result<()> {
.mount(&server)
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let expected_plugin_path = AbsolutePathBuf::try_from(plugin_path.clone())?;
let request_id = mcp
@@ -251,7 +251,7 @@ async fn plugin_share_save_forwards_access_policy() -> Result<()> {
.mount(&server)
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let expected_plugin_path = AbsolutePathBuf::try_from(plugin_path)?;
let request_id = mcp
@@ -304,7 +304,7 @@ async fn plugin_share_save_rejects_listed_discoverability() -> Result<()> {
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
.send_raw_request(
@@ -359,7 +359,7 @@ plugin_sharing = false
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
.send_raw_request(
@@ -404,7 +404,7 @@ async fn plugin_share_rejects_workspace_targets_from_client() -> Result<()> {
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
.send_raw_request(
@@ -482,7 +482,7 @@ async fn plugin_share_save_rejects_access_policy_for_existing_plugin() -> Result
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
.send_raw_request(
@@ -555,7 +555,7 @@ async fn plugin_share_list_returns_created_workspace_plugins() -> Result<()> {
.mount(&server)
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
.send_raw_request("plugin/share/list", Some(json!({})))
@@ -626,7 +626,7 @@ async fn plugin_share_checkout_adds_personal_marketplace_entry() -> Result<()> {
mount_empty_remote_installed_plugins(&server, "WORKSPACE").await;
let home_env = home.path().to_string_lossy().into_owned();
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("HOME", Some(home_env.as_str())),
@@ -789,7 +789,7 @@ async fn plugin_share_checkout_rejects_non_share_remote_plugin() -> Result<()> {
mount_empty_remote_installed_plugins(&server, "GLOBAL").await;
let home_env = home.path().to_string_lossy().into_owned();
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("HOME", Some(home_env.as_str())),
@@ -880,7 +880,7 @@ async fn plugin_share_checkout_cleans_up_path_when_marketplace_update_fails() ->
mount_empty_remote_installed_plugins(&server, "WORKSPACE").await;
let home_env = home.path().to_string_lossy().into_owned();
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("HOME", Some(home_env.as_str())),
@@ -983,7 +983,7 @@ async fn plugin_share_update_targets_updates_share_targets() -> Result<()> {
.mount(&server)
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
.send_raw_request(
@@ -1065,7 +1065,7 @@ plugin_sharing = false
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
.send_raw_request(
@@ -1114,7 +1114,7 @@ async fn plugin_share_delete_removes_created_workspace_plugin() -> Result<()> {
.mount(&server)
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
.send_raw_request(
@@ -4,7 +4,7 @@ use anyhow::Result;
use anyhow::bail;
use app_test_support::ChatGptAuthFixture;
use app_test_support::DEFAULT_CLIENT_NAME;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::start_analytics_events_server;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
@@ -42,7 +42,7 @@ enabled = true
"#,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let params = PluginUninstallParams {
@@ -100,7 +100,7 @@ async fn plugin_uninstall_tracks_analytics_event() -> Result<()> {
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -161,7 +161,7 @@ async fn plugin_uninstall_rejects_remote_plugin_when_plugins_are_disabled() -> R
plugins = false
"#,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -230,7 +230,7 @@ async fn plugin_uninstall_writes_remote_plugin_to_cloud_when_remote_plugin_enabl
));
std::fs::create_dir_all(legacy_remote_plugin_cache_root.join("local/.codex-plugin"))?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -302,7 +302,7 @@ async fn plugin_uninstall_uses_detail_scope_for_cache_namespace() -> Result<()>
.join("plugins/cache/openai-curated-remote/linear");
std::fs::create_dir_all(global_cache_root.join("1.0.0/.codex-plugin"))?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -376,7 +376,7 @@ async fn plugin_uninstall_accepts_workspace_remote_plugin_id_shape() -> Result<(
r#"{"name":"skill-improver","version":"1.0.0"}"#,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -425,7 +425,7 @@ async fn plugin_uninstall_rejects_before_post_when_remote_detail_fetch_fails() -
));
std::fs::create_dir_all(legacy_remote_plugin_cache_root.join("local/.codex-plugin"))?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -467,7 +467,7 @@ async fn plugin_uninstall_rejects_remote_plugin_id_with_spaces_before_network_ca
codex_home.path(),
&format!("{}/backend-api/", server.uri()),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -502,7 +502,7 @@ async fn plugin_uninstall_rejects_invalid_remote_plugin_id_before_network_call()
codex_home.path(),
&format!("{}/backend-api/", server.uri()),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -537,7 +537,7 @@ async fn plugin_uninstall_rejects_empty_remote_plugin_id() -> Result<()> {
codex_home.path(),
&format!("{}/backend-api/", server.uri()),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1,6 +1,6 @@
use anyhow::Context;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_mock_responses_server_sequence_unchecked;
use codex_app_server_protocol::ProcessExitedNotification;
use codex_app_server_protocol::ProcessKillParams;
@@ -108,7 +108,7 @@ async fn process_spawn_returns_error_when_local_environment_is_disabled() -> Res
let codex_home = TempDir::new()?;
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
create_config_toml(codex_home.path(), &server.uri(), "never")?;
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[(CODEX_EXEC_SERVER_URL_ENV_VAR, Some("none"))],
)
@@ -230,10 +230,10 @@ async fn process_kill_terminates_running_process() -> Result<()> {
Ok(())
}
async fn initialized_mcp(codex_home: &Path) -> Result<(MockServer, McpProcess)> {
async fn initialized_mcp(codex_home: &Path) -> Result<(MockServer, TestAppServer)> {
let server = create_mock_responses_server_sequence_unchecked(Vec::new()).await;
create_config_toml(codex_home, &server.uri(), "never")?;
let mut mcp = McpProcess::new(codex_home).await?;
let mut mcp = TestAppServer::new(codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
Ok((server, mcp))
}
@@ -257,7 +257,7 @@ fn process_spawn_params(
})
}
async fn read_process_exited(mcp: &mut McpProcess) -> Result<ProcessExitedNotification> {
async fn read_process_exited(mcp: &mut TestAppServer) -> Result<ProcessExitedNotification> {
let notification = mcp
.read_stream_until_notification_message("process/exited")
.await?;
@@ -1,6 +1,6 @@
use anyhow::Result;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
use codex_app_server_protocol::AddCreditsNudgeCreditType;
@@ -37,7 +37,8 @@ const INTERNAL_ERROR_CODE: i64 = -32603;
async fn get_account_rate_limits_requires_auth() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp.send_get_account_rate_limits_request().await?;
@@ -62,7 +63,7 @@ async fn get_account_rate_limits_requires_auth() -> Result<()> {
async fn get_account_rate_limits_requires_chatgpt_auth() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
login_with_api_key(&mut mcp, "sk-test-key").await?;
@@ -153,7 +154,8 @@ async fn get_account_rate_limits_returns_snapshot() -> Result<()> {
.mount(&server)
.await;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp.send_get_account_rate_limits_request().await?;
@@ -238,7 +240,8 @@ async fn get_account_rate_limits_returns_snapshot() -> Result<()> {
async fn send_add_credits_nudge_email_requires_auth() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -267,7 +270,7 @@ async fn send_add_credits_nudge_email_requires_auth() -> Result<()> {
async fn send_add_credits_nudge_email_requires_chatgpt_auth() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
login_with_api_key(&mut mcp, "sk-test-key").await?;
@@ -321,7 +324,8 @@ async fn send_add_credits_nudge_email_posts_expected_body() -> Result<()> {
.mount(&server)
.await;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -364,7 +368,8 @@ async fn send_add_credits_nudge_email_maps_cooldown() -> Result<()> {
.mount(&server)
.await;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -407,7 +412,8 @@ async fn send_add_credits_nudge_email_surfaces_backend_failure() -> Result<()> {
.mount(&server)
.await;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -437,7 +443,7 @@ async fn send_add_credits_nudge_email_surfaces_backend_failure() -> Result<()> {
Ok(())
}
async fn login_with_api_key(mcp: &mut McpProcess, api_key: &str) -> Result<()> {
async fn login_with_api_key(mcp: &mut TestAppServer, api_key: &str) -> Result<()> {
let request_id = mcp.send_login_account_api_key_request(api_key).await?;
let response: JSONRPCResponse = timeout(
DEFAULT_READ_TIMEOUT,
@@ -1,6 +1,6 @@
use anyhow::Context;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_sequence_unchecked;
use app_test_support::create_shell_command_sse_response;
@@ -191,7 +191,7 @@ struct RealtimeSidebandScript {
}
struct RealtimeE2eHarness {
mcp: McpProcess,
mcp: TestAppServer,
_codex_home: TempDir,
main_loop_responses_server: MockServer,
realtime_server: WebSocketTestServer,
@@ -280,7 +280,7 @@ impl RealtimeE2eHarness {
sandbox,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
login_with_api_key(&mut mcp, "sk-test-key").await?;
@@ -539,7 +539,7 @@ async fn realtime_conversation_streams_v2_notifications() -> Result<()> {
StartupContextConfig::Generated,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
login_with_api_key(&mut mcp, "sk-test-key").await?;
@@ -788,7 +788,7 @@ async fn realtime_text_output_modality_requests_text_output_and_final_transcript
StartupContextConfig::Generated,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
login_with_api_key(&mut mcp, "sk-test-key").await?;
@@ -890,7 +890,7 @@ async fn realtime_list_voices_returns_supported_names() -> Result<()> {
StartupContextConfig::Generated,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -962,7 +962,7 @@ async fn realtime_conversation_stop_emits_closed_notification() -> Result<()> {
StartupContextConfig::Generated,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
login_with_api_key(&mut mcp, "sk-test-key").await?;
@@ -1058,7 +1058,7 @@ async fn realtime_webrtc_start_emits_sdp_notification() -> Result<()> {
StartupContextConfig::Override("startup context"),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
login_with_api_key(&mut mcp, "sk-test-key").await?;
@@ -1973,7 +1973,7 @@ async fn realtime_webrtc_start_surfaces_backend_error() -> Result<()> {
StartupContextConfig::Override("startup context"),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
login_with_api_key(&mut mcp, "sk-test-key").await?;
@@ -2034,7 +2034,7 @@ async fn realtime_conversation_requires_feature_flag() -> Result<()> {
StartupContextConfig::Generated,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let thread_start_request_id = mcp
@@ -2074,7 +2074,10 @@ async fn realtime_conversation_requires_feature_flag() -> Result<()> {
Ok(())
}
async fn read_notification<T: DeserializeOwned>(mcp: &mut McpProcess, method: &str) -> Result<T> {
async fn read_notification<T: DeserializeOwned>(
mcp: &mut TestAppServer,
method: &str,
) -> Result<T> {
let notification = timeout(
DEFAULT_TIMEOUT,
mcp.read_stream_until_notification_message(method),
@@ -2086,7 +2089,7 @@ async fn read_notification<T: DeserializeOwned>(mcp: &mut McpProcess, method: &s
Ok(serde_json::from_value(params)?)
}
async fn login_with_api_key(mcp: &mut McpProcess, api_key: &str) -> Result<()> {
async fn login_with_api_key(mcp: &mut TestAppServer, api_key: &str) -> Result<()> {
let request_id = mcp.send_login_account_api_key_request(api_key).await?;
let response: JSONRPCResponse = timeout(
DEFAULT_TIMEOUT,
@@ -2100,7 +2103,7 @@ async fn login_with_api_key(mcp: &mut McpProcess, api_key: &str) -> Result<()> {
}
async fn wait_for_started_command_execution(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
) -> Result<ItemStartedNotification> {
loop {
let started = read_notification::<ItemStartedNotification>(mcp, "item/started").await?;
@@ -2111,7 +2114,7 @@ async fn wait_for_started_command_execution(
}
async fn wait_for_completed_command_execution(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
) -> Result<ItemCompletedNotification> {
loop {
let completed =
@@ -3,7 +3,7 @@ use std::time::Duration;
use anyhow::Context;
use anyhow::Result;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
use app_test_support::write_mock_responses_config_toml_with_chatgpt_base_url;
@@ -29,7 +29,7 @@ const DEFAULT_TIMEOUT: Duration = Duration::from_secs(10);
#[tokio::test]
async fn remote_control_disable_returns_disabled_status() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp.send_remote_control_disable_request().await?;
@@ -50,7 +50,7 @@ async fn remote_control_disable_returns_disabled_status() -> Result<()> {
#[tokio::test]
async fn remote_control_status_read_returns_disabled_status() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp.send_remote_control_status_read_request().await?;
@@ -72,7 +72,7 @@ async fn remote_control_status_read_returns_disabled_status() -> Result<()> {
async fn remote_control_enable_returns_connecting_status() -> Result<()> {
let codex_home = TempDir::new()?;
let _backend = BlockingRemoteControlBackend::start(codex_home.path()).await?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp.send_remote_control_enable_request().await?;
@@ -94,7 +94,7 @@ async fn remote_control_enable_returns_connecting_status() -> Result<()> {
async fn remote_control_status_read_returns_connecting_status_after_enable() -> Result<()> {
let codex_home = TempDir::new()?;
let mut backend = BlockingRemoteControlBackend::start(codex_home.path()).await?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp.send_remote_control_enable_request().await?;
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_sequence;
use app_test_support::create_request_permissions_sse_response;
@@ -30,7 +30,7 @@ async fn request_permissions_round_trip() -> Result<()> {
let server = create_mock_responses_server_sequence(responses).await;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_sequence;
use app_test_support::create_request_user_input_sse_response;
@@ -32,7 +32,7 @@ async fn request_user_input_round_trip() -> Result<()> {
let server = create_mock_responses_server_sequence(responses).await;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
+9 -9
View File
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_repeating_assistant;
use app_test_support::create_mock_responses_server_sequence;
@@ -59,7 +59,7 @@ async fn review_start_runs_review_turn_and_emits_code_review_item() -> Result<()
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_default_thread(&mut mcp).await?;
@@ -173,7 +173,7 @@ async fn review_start_exec_approval_item_id_matches_command_execution_item() ->
let codex_home = TempDir::new()?;
create_config_toml_with_approval_policy(codex_home.path(), &server.uri(), "untrusted")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_default_thread(&mut mcp).await?;
@@ -256,7 +256,7 @@ async fn review_start_rejects_empty_base_branch() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_default_thread(&mut mcp).await?;
@@ -299,7 +299,7 @@ async fn review_start_with_detached_delivery_returns_new_thread_id() -> Result<(
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_default_thread(&mut mcp).await?;
@@ -377,7 +377,7 @@ async fn review_start_rejects_empty_commit_sha() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_default_thread(&mut mcp).await?;
@@ -412,7 +412,7 @@ async fn review_start_rejects_empty_custom_instructions() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_default_thread(&mut mcp).await?;
@@ -443,7 +443,7 @@ async fn review_start_rejects_empty_custom_instructions() -> Result<()> {
Ok(())
}
async fn start_default_thread(mcp: &mut McpProcess) -> Result<String> {
async fn start_default_thread(mcp: &mut TestAppServer) -> Result<String> {
let thread_req = mcp
.send_thread_start_request(ThreadStartParams {
model: Some("mock-model".to_string()),
@@ -464,7 +464,7 @@ async fn start_default_thread(mcp: &mut McpProcess) -> Result<String> {
Ok(thread.id)
}
async fn materialize_thread_rollout(mcp: &mut McpProcess, thread_id: &str) -> Result<()> {
async fn materialize_thread_rollout(mcp: &mut TestAppServer, thread_id: &str) -> Result<()> {
let turn_req = mcp
.send_turn_start_request(TurnStartParams {
thread_id: thread_id.to_string(),
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use codex_app_server_protocol::CodexErrorInfo;
use codex_app_server_protocol::ErrorNotification;
@@ -48,7 +48,7 @@ async fn openai_model_header_mismatch_emits_model_rerouted_notification_v2() ->
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -115,7 +115,7 @@ async fn cyber_policy_response_emits_typed_error_notification_v2() -> Result<()>
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -192,7 +192,7 @@ async fn response_model_field_mismatch_emits_model_rerouted_notification_v2_when
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -261,7 +261,7 @@ async fn model_verification_emits_typed_notification_and_warning_v2() -> Result<
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -310,7 +310,7 @@ async fn model_verification_emits_typed_notification_and_warning_v2() -> Result<
}
async fn collect_turn_notifications_and_validate_no_warning_item(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
) -> Result<ModelReroutedNotification> {
let mut rerouted = None;
@@ -352,7 +352,7 @@ async fn collect_turn_notifications_and_validate_no_warning_item(
}
async fn collect_model_verification_notifications_and_validate_no_warning_item(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
) -> Result<ModelVerificationNotification> {
let mut verification = None;
@@ -403,7 +403,7 @@ async fn collect_model_verification_notifications_and_validate_no_warning_item(
}
async fn collect_cyber_policy_error_and_validate_no_reroute(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
) -> Result<ErrorNotification> {
let mut error = None;
@@ -3,7 +3,7 @@ use std::time::Duration;
use anyhow::Context;
use anyhow::Result;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_mock_responses_server_repeating_assistant;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
@@ -44,7 +44,7 @@ fn write_skill(root: &TempDir, name: &str) -> Result<()> {
}
async fn expect_skills_changed_notification(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
timeout_duration: Duration,
) -> Result<()> {
let notification = timeout(
@@ -242,7 +242,7 @@ async fn skills_list_loads_remote_installed_plugin_skills_from_cache() -> Result
.mount(&server)
.await;
}
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let stale_skills_list_request_id = mcp
@@ -366,7 +366,7 @@ async fn skills_list_excludes_plugin_skills_when_workspace_codex_plugins_disable
.mount(&server)
.await;
let mut mcp = McpProcess::new_without_managed_config(codex_home.path()).await?;
let mut mcp = TestAppServer::new_without_managed_config(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -412,7 +412,7 @@ async fn skills_list_skips_cwd_roots_when_environment_disabled() -> Result<()> {
"---\nname: repo-skill\ndescription: from repo root\n---\n\n# Body\n",
)?;
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[(CODEX_EXEC_SERVER_URL_ENV_VAR, Some("none"))],
)
@@ -456,7 +456,7 @@ async fn skills_list_accepts_relative_cwds() -> Result<()> {
let relative_cwd = std::path::PathBuf::from("relative-cwd");
std::fs::create_dir_all(codex_home.path().join(&relative_cwd))?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -484,7 +484,7 @@ async fn skills_list_preserves_requested_cwd_order() -> Result<()> {
let first_cwd = TempDir::new()?;
let second_cwd = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -520,7 +520,7 @@ async fn skills_list_uses_cached_result_until_force_reload() -> Result<()> {
let codex_home = TempDir::new()?;
let cwd = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
// Seed the cwd cache before the cwd-local skill exists.
@@ -606,7 +606,7 @@ async fn skills_extra_roots_set_updates_process_runtime_roots() -> Result<()> {
"---\nname: runtime-skill\ndescription: runtime skill\n---\n\n# Body\n",
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let set_request_id = mcp
@@ -712,7 +712,7 @@ async fn skills_extra_roots_set_updates_process_runtime_roots() -> Result<()> {
);
drop(mcp);
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let skills_request_id = mcp
.send_skills_list_request(SkillsListParams {
@@ -749,7 +749,7 @@ async fn skills_changed_notification_is_emitted_after_skill_change() -> Result<(
write_skill(&codex_home, "demo")?;
let mut mcp =
McpProcess::new_with_env(codex_home.path(), &[(CODEX_EXEC_SERVER_URL_ENV_VAR, None)])
TestAppServer::new_with_env(codex_home.path(), &[(CODEX_EXEC_SERVER_URL_ENV_VAR, None)])
.await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let initial_skills_request_id = mcp
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_fake_rollout;
use app_test_support::create_mock_responses_server_repeating_assistant;
use app_test_support::to_response;
@@ -38,7 +38,7 @@ async fn thread_archive_requires_materialized_rollout() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
// Start a thread.
@@ -221,7 +221,7 @@ async fn thread_archive_archives_spawned_descendants() -> Result<()> {
)
.await?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let archive_id = mcp
@@ -342,7 +342,7 @@ async fn thread_archive_succeeds_when_descendant_archive_fails() -> Result<()> {
.join(child_rollout_path.file_name().expect("rollout file name"));
std::fs::create_dir_all(&archived_child_path)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let archive_id = mcp
@@ -446,7 +446,7 @@ async fn thread_archive_succeeds_when_spawned_descendant_is_missing() -> Result<
)
.await?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let archive_id = mcp
@@ -499,7 +499,7 @@ async fn thread_archive_clears_stale_subscriptions_before_resume() -> Result<()>
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut primary = McpProcess::new(codex_home.path()).await?;
let mut primary = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, primary.initialize()).await??;
let start_id = primary
@@ -539,7 +539,7 @@ async fn thread_archive_clears_stale_subscriptions_before_resume() -> Result<()>
.await??;
primary.clear_message_buffer();
let mut secondary = McpProcess::new(codex_home.path()).await?;
let mut secondary = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, secondary.initialize()).await??;
let archive_id = primary
@@ -1,6 +1,6 @@
use anyhow::Result;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_fake_rollout;
use app_test_support::create_fake_rollout_with_token_usage;
use app_test_support::create_mock_responses_server_repeating_assistant;
@@ -83,7 +83,7 @@ async fn thread_fork_creates_new_thread_and_emits_started() -> Result<()> {
);
let original_contents = std::fs::read_to_string(&original_path)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let fork_id = mcp
@@ -241,7 +241,7 @@ async fn thread_fork_can_load_source_by_path() -> Result<()> {
"rollout-2025-01-05T12-00-00-{conversation_id}.jsonl"
));
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let fork_id = mcp
@@ -281,7 +281,7 @@ async fn thread_fork_emits_restored_token_usage_before_next_turn() -> Result<()>
Some("mock_provider"),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let fork_id = mcp
@@ -335,7 +335,7 @@ async fn thread_fork_can_exclude_turns_and_skip_restored_token_usage() -> Result
Some("mock_provider"),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let fork_id = mcp
@@ -386,7 +386,7 @@ async fn thread_fork_tracks_thread_initialized_analytics() -> Result<()> {
/*git_info*/ None,
)?;
let mut mcp = McpProcess::new_without_managed_config(codex_home.path()).await?;
let mut mcp = TestAppServer::new_without_managed_config(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let fork_id = mcp
@@ -422,7 +422,7 @@ async fn thread_fork_rejects_unmaterialized_thread() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -476,7 +476,7 @@ async fn thread_fork_with_empty_path_uses_thread_id() -> Result<()> {
/*git_info*/ None,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let fork_id = mcp
@@ -550,7 +550,7 @@ async fn thread_fork_surfaces_cloud_requirements_load_errors() -> Result<()> {
)?;
let refresh_token_url = format!("{}/oauth/token", server.uri());
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("OPENAI_API_KEY", None),
@@ -613,7 +613,7 @@ async fn thread_fork_ephemeral_remains_pathless_and_omits_listing() -> Result<()
/*git_info*/ None,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let fork_id = mcp
@@ -1,6 +1,6 @@
use anyhow::Context;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use codex_app_server_protocol::JSONRPCResponse;
use codex_app_server_protocol::RequestId;
@@ -36,7 +36,7 @@ async fn thread_inject_items_adds_raw_response_items_to_thread_history() -> Resu
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -152,7 +152,7 @@ async fn thread_inject_items_adds_raw_response_items_after_a_turn() -> Result<()
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_fake_parented_rollout_with_source;
use app_test_support::create_fake_rollout;
use app_test_support::create_fake_rollout_with_source;
@@ -48,14 +48,14 @@ use uuid::Uuid;
const DEFAULT_READ_TIMEOUT: std::time::Duration = std::time::Duration::from_secs(10);
async fn init_mcp(codex_home: &Path) -> Result<McpProcess> {
let mut mcp = McpProcess::new(codex_home).await?;
async fn init_mcp(codex_home: &Path) -> Result<TestAppServer> {
let mut mcp = TestAppServer::new(codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
Ok(mcp)
}
async fn list_threads(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
cursor: Option<String>,
limit: Option<u32>,
providers: Option<Vec<String>>,
@@ -75,7 +75,7 @@ async fn list_threads(
}
async fn list_threads_with_sort(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
cursor: Option<String>,
limit: Option<u32>,
providers: Option<Vec<String>>,
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_mock_responses_server_repeating_assistant;
use app_test_support::to_response;
use codex_app_server_protocol::JSONRPCResponse;
@@ -21,7 +21,7 @@ async fn thread_loaded_list_returns_loaded_thread_ids() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_thread(&mut mcp).await?;
@@ -51,7 +51,7 @@ async fn thread_loaded_list_paginates() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let first = start_thread(&mut mcp).await?;
@@ -122,7 +122,7 @@ stream_max_retries = 0
)
}
async fn start_thread(mcp: &mut McpProcess) -> Result<String> {
async fn start_thread(mcp: &mut TestAppServer) -> Result<String> {
let req_id = mcp
.send_thread_start_request(ThreadStartParams {
model: Some("gpt-5.2".to_string()),
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_fake_rollout;
use app_test_support::create_mock_responses_server_repeating_assistant;
use app_test_support::to_response;
@@ -27,7 +27,7 @@ async fn thread_memory_mode_set_updates_loaded_thread_state() -> Result<()> {
create_config_toml(codex_home.path(), &server.uri())?;
let state_db = init_state_db(codex_home.path()).await?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -79,7 +79,7 @@ async fn thread_memory_mode_set_updates_stored_thread_state() -> Result<()> {
)?;
let thread_uuid = ThreadId::from_string(&thread_id)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
for mode in [ThreadMemoryMode::Disabled, ThreadMemoryMode::Enabled] {
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_fake_rollout;
use app_test_support::create_mock_responses_server_repeating_assistant;
use app_test_support::rollout_path;
@@ -41,7 +41,7 @@ async fn thread_metadata_update_patches_git_branch_and_returns_updated_thread()
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -136,7 +136,7 @@ async fn thread_metadata_update_rejects_empty_git_info_patch() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -182,7 +182,7 @@ async fn thread_metadata_update_rejects_ephemeral_thread() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -244,7 +244,7 @@ async fn thread_metadata_update_repairs_missing_sqlite_row_for_stored_thread() -
/*git_info*/ None,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let update_id = mcp
@@ -309,7 +309,7 @@ async fn thread_metadata_update_repairs_loaded_thread_without_resetting_summary(
)
.await;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let resume_id = mcp
@@ -387,7 +387,7 @@ async fn thread_metadata_update_repairs_missing_sqlite_row_for_archived_thread()
);
fs::rename(&archived_source, &archived_dest)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let update_id = mcp
@@ -443,7 +443,7 @@ async fn thread_metadata_update_can_clear_stored_git_fields() -> Result<()> {
)?;
let _state_db = init_state_db(codex_home.path()).await?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let update_id = mcp
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_fake_rollout_with_text_elements;
use app_test_support::create_mock_responses_server_repeating_assistant;
use app_test_support::rollout_path;
@@ -104,7 +104,7 @@ async fn thread_read_returns_summary_without_turns() -> Result<()> {
/*git_info*/ None,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let read_id = mcp
@@ -159,7 +159,7 @@ async fn thread_read_can_include_turns() -> Result<()> {
/*git_info*/ None,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let read_id = mcp
@@ -217,7 +217,7 @@ async fn thread_turns_list_can_page_backward_and_forward() -> Result<()> {
append_user_message(rollout_path.as_path(), "2025-01-05T12:01:00Z", "second")?;
append_user_message(rollout_path.as_path(), "2025-01-05T12:02:00Z", "third")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let read_id = mcp
@@ -306,7 +306,7 @@ async fn thread_turns_list_supports_requested_items_view() -> Result<()> {
append_agent_message(rollout_path.as_path(), "2025-01-05T12:01:00Z", "draft")?;
append_agent_message(rollout_path.as_path(), "2025-01-05T12:02:00Z", "final")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let full = read_single_turn_items_view(
@@ -608,7 +608,7 @@ async fn thread_read_can_return_archived_threads_by_id() -> Result<()> {
archived_dir.join(active_rollout_path.file_name().expect("rollout file name"));
std::fs::rename(&active_rollout_path, &archived_rollout_path)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let read_id = mcp
@@ -652,7 +652,7 @@ async fn thread_resume_initial_turns_page_matches_requested_turns_list_page() ->
append_user_message(rollout_path.as_path(), "2025-01-05T12:01:00Z", "second")?;
append_user_message(rollout_path.as_path(), "2025-01-05T12:02:00Z", "third")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let turns_list_id = mcp
@@ -723,7 +723,7 @@ async fn thread_turns_list_rejects_cursor_when_anchor_turn_is_rolled_back() -> R
append_user_message(rollout_path.as_path(), "2025-01-05T12:01:00Z", "second")?;
append_user_message(rollout_path.as_path(), "2025-01-05T12:02:00Z", "third")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let read_id = mcp
@@ -790,7 +790,7 @@ async fn thread_read_returns_forked_from_id_for_forked_threads() -> Result<()> {
/*git_info*/ None,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let fork_id = mcp
@@ -830,7 +830,7 @@ async fn thread_read_loaded_thread_returns_precomputed_path_before_materializati
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -890,7 +890,7 @@ async fn thread_name_set_is_reflected_in_read_list_and_resume() -> Result<()> {
/*git_info*/ None,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
// Set a user-facing thread title.
@@ -1036,7 +1036,7 @@ async fn thread_read_include_turns_rejects_unmaterialized_loaded_thread() -> Res
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -1087,7 +1087,7 @@ async fn thread_turns_list_rejects_unmaterialized_loaded_thread() -> Result<()>
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -1141,7 +1141,7 @@ async fn thread_turns_items_list_returns_unsupported() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let read_id = mcp
@@ -1179,7 +1179,7 @@ async fn thread_read_reports_system_error_idle_flag_after_failed_turn() -> Resul
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -1289,7 +1289,7 @@ fn append_thread_rollback(path: &Path, timestamp: &str, num_turns: u32) -> std::
}
async fn read_single_turn_items_view(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
thread_id: &str,
items_view: Option<TurnItemsView>,
) -> anyhow::Result<codex_app_server_protocol::Turn> {
@@ -1,6 +1,6 @@
use anyhow::Result;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_apply_patch_sse_response;
use app_test_support::create_fake_rollout;
use app_test_support::create_fake_rollout_with_text_elements;
@@ -146,7 +146,7 @@ async fn thread_resume_rejects_unmaterialized_thread() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
// Start a thread.
@@ -193,7 +193,7 @@ async fn thread_resume_with_empty_path_uses_running_thread_id() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -262,7 +262,7 @@ async fn turn_start_updates_runtime_workspace_roots_for_loaded_thread() -> Resul
let extra_root = extra_root_tmp.path().join("extra-root");
std::fs::create_dir_all(&extra_root)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -338,7 +338,7 @@ async fn thread_goal_get_rejects_unmaterialized_thread() -> Result<()> {
config.replace("personality = true\n", "personality = true\ngoals = true\n"),
)?;
let mut mcp = McpProcess::new_without_managed_config(codex_home.path()).await?;
let mut mcp = TestAppServer::new_without_managed_config(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -403,7 +403,7 @@ async fn thread_resume_tracks_thread_initialized_analytics() -> Result<()> {
"user",
)?;
let mut mcp = McpProcess::new_without_managed_config(codex_home.path()).await?;
let mut mcp = TestAppServer::new_without_managed_config(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let resume_id = mcp
@@ -481,7 +481,7 @@ async fn thread_resume_returns_rollout_history() -> Result<()> {
/*git_info*/ None,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let resume_id = mcp
@@ -653,7 +653,7 @@ async fn resume_redaction_fixture(client_name: Option<&str>) -> Result<ThreadRes
&conversation_id,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
if let Some(client_name) = client_name {
let _ = timeout(
DEFAULT_READ_TIMEOUT,
@@ -758,7 +758,7 @@ async fn thread_resume_can_skip_turns_for_metadata_only_resume() -> Result<()> {
/*git_info*/ None,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let resume_id = mcp
@@ -805,7 +805,7 @@ async fn thread_resume_rejects_archived_session_by_id() -> Result<()> {
archived_dir.join(active_rollout_path.file_name().expect("rollout file name")),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let resume_id = mcp
@@ -844,7 +844,7 @@ async fn thread_resume_keeps_paused_goal_paused() -> Result<()> {
config.replace("personality = true\n", "personality = true\ngoals = true\n"),
)?;
let mut mcp = McpProcess::new_without_managed_config(codex_home.path()).await?;
let mut mcp = TestAppServer::new_without_managed_config(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -949,7 +949,7 @@ async fn thread_goal_set_preserves_budget_limited_same_objective() -> Result<()>
config.replace("personality = true\n", "personality = true\ngoals = true\n"),
)?;
let mut mcp = McpProcess::new_without_managed_config(codex_home.path()).await?;
let mut mcp = TestAppServer::new_without_managed_config(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -1048,7 +1048,7 @@ async fn thread_goal_set_persists_resumable_stopped_statuses() -> Result<()> {
config.replace("personality = true\n", "personality = true\ngoals = true\n"),
)?;
let mut mcp = McpProcess::new_without_managed_config(codex_home.path()).await?;
let mut mcp = TestAppServer::new_without_managed_config(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -1143,7 +1143,7 @@ async fn thread_goal_set_edits_objective_without_resetting_usage() -> Result<()>
/*git_info*/ None,
)?;
let mut mcp = McpProcess::new_without_managed_config(codex_home.path()).await?;
let mut mcp = TestAppServer::new_without_managed_config(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let goal_id = mcp
@@ -1244,7 +1244,7 @@ async fn thread_goal_clear_deletes_goal_and_notifies() -> Result<()> {
config.replace("personality = true\n", "personality = true\ngoals = true\n"),
)?;
let mut mcp = McpProcess::new_without_managed_config(codex_home.path()).await?;
let mut mcp = TestAppServer::new_without_managed_config(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -1374,7 +1374,7 @@ async fn thread_resume_emits_restored_token_usage_before_next_turn() -> Result<(
Some("mock_provider"),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let resume_id = mcp
@@ -1427,7 +1427,7 @@ async fn thread_resume_skips_restored_token_usage_when_turns_are_excluded() -> R
Some("mock_provider"),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let first_resume_id = mcp
@@ -1535,7 +1535,7 @@ async fn thread_resume_token_usage_replay_ignores_stale_interrupted_tail_turn()
format!("{persisted_rollout}{appended_rollout}\n"),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let resume_id = mcp
@@ -1659,7 +1659,7 @@ async fn thread_resume_token_usage_replay_can_belong_to_interrupted_turn() -> Re
format!("{persisted_rollout}{appended_rollout}\n"),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let resume_id = mcp
@@ -1848,7 +1848,7 @@ stream_max_retries = 0
.mark_backfill_complete(/*last_watermark*/ None)
.await?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let update_id = mcp
@@ -1942,7 +1942,7 @@ async fn thread_resume_and_read_interrupt_incomplete_rollout_turn_when_thread_is
format!("{persisted_rollout}{appended_rollout}\n"),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let resume_id = mcp
@@ -2016,7 +2016,7 @@ async fn thread_resume_defers_updated_at_until_turn_start() -> Result<()> {
let rollout = setup_rollout_fixture(codex_home.path(), &server.uri())?;
let thread_id = rollout.conversation_id.clone();
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let read_id = mcp
@@ -2114,7 +2114,7 @@ async fn thread_resume_keeps_in_flight_turn_streaming() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut primary = McpProcess::new(codex_home.path()).await?;
let mut primary = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, primary.initialize()).await??;
let start_id = primary
@@ -2153,7 +2153,7 @@ async fn thread_resume_keeps_in_flight_turn_streaming() -> Result<()> {
.await??;
primary.clear_message_buffer();
let mut secondary = McpProcess::new(codex_home.path()).await?;
let mut secondary = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, secondary.initialize()).await??;
let turn_id = primary
@@ -2223,7 +2223,7 @@ async fn thread_resume_rejects_history_when_thread_is_running() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut primary = McpProcess::new(codex_home.path()).await?;
let mut primary = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, primary.initialize()).await??;
let start_id = primary
@@ -2341,7 +2341,7 @@ async fn thread_resume_rejects_mismatched_path_for_running_thread_id() -> Result
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut primary = McpProcess::new(codex_home.path()).await?;
let mut primary = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, primary.initialize()).await??;
let start_id = primary
@@ -2479,7 +2479,7 @@ async fn thread_resume_rejoins_running_thread_even_with_override_mismatch() -> R
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut primary = McpProcess::new(codex_home.path()).await?;
let mut primary = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, primary.initialize()).await??;
let start_id = primary
@@ -2610,7 +2610,7 @@ async fn thread_resume_can_skip_turns_when_thread_is_running() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut primary = McpProcess::new(codex_home.path()).await?;
let mut primary = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, primary.initialize()).await??;
let start_id = primary
@@ -2648,7 +2648,7 @@ async fn thread_resume_can_skip_turns_when_thread_is_running() -> Result<()> {
)
.await??;
let mut secondary = McpProcess::new(codex_home.path()).await?;
let mut secondary = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, secondary.initialize()).await??;
let resume_id = secondary
@@ -2694,7 +2694,7 @@ async fn thread_resume_replays_pending_command_execution_request_approval() -> R
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut primary = McpProcess::new(codex_home.path()).await?;
let mut primary = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, primary.initialize()).await??;
let start_id = primary
@@ -2833,7 +2833,7 @@ async fn thread_resume_replays_pending_file_change_request_approval() -> Result<
let server = create_mock_responses_server_sequence_unchecked(responses).await;
create_config_toml(&codex_home, &server.uri())?;
let mut primary = McpProcess::new(&codex_home).await?;
let mut primary = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, primary.initialize()).await??;
let start_id = primary
@@ -3054,7 +3054,7 @@ async fn thread_resume_fails_when_required_mcp_server_fails_to_initialize() -> R
let rollout = setup_rollout_fixture(codex_home.path(), &server.uri())?;
create_config_toml_with_required_broken_mcp(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let resume_id = mcp
@@ -3133,7 +3133,7 @@ async fn thread_resume_surfaces_cloud_requirements_load_errors() -> Result<()> {
/*git_info*/ None,
)?;
let refresh_token_url = format!("{}/oauth/token", server.uri());
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("OPENAI_API_KEY", None),
@@ -3227,7 +3227,7 @@ async fn thread_resume_can_load_source_by_external_path() -> Result<()> {
)?;
let thread_path = rollout_path(external_home.path(), "2025-01-05T12-00-00", &thread_id);
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let resume_id = mcp
.send_thread_resume_request(ThreadResumeParams {
@@ -3306,7 +3306,7 @@ async fn thread_resume_supports_history_and_overrides() -> Result<()> {
}
struct RestartedThreadFixture {
mcp: McpProcess,
mcp: TestAppServer,
thread_id: String,
rollout_file_path: PathBuf,
updated_at: i64,
@@ -3316,7 +3316,7 @@ async fn start_materialized_thread_and_restart(
codex_home: &Path,
seed_text: &str,
) -> Result<RestartedThreadFixture> {
let mut first_mcp = McpProcess::new(codex_home).await?;
let mut first_mcp = TestAppServer::new(codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, first_mcp.initialize()).await??;
let start_id = first_mcp
@@ -3375,7 +3375,7 @@ async fn start_materialized_thread_and_restart(
drop(first_mcp);
let mut second_mcp = McpProcess::new(codex_home).await?;
let mut second_mcp = TestAppServer::new(codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, second_mcp.initialize()).await??;
Ok(RestartedThreadFixture {
@@ -3406,7 +3406,7 @@ async fn thread_resume_accepts_personality_override() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut primary = McpProcess::new(codex_home.path()).await?;
let mut primary = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, primary.initialize()).await??;
let start_id = primary
@@ -3444,7 +3444,7 @@ async fn thread_resume_accepts_personality_override() -> Result<()> {
)
.await??;
let mut secondary = McpProcess::new(codex_home.path()).await?;
let mut secondary = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, secondary.initialize()).await??;
let resume_id = secondary
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_sequence_unchecked;
use app_test_support::to_response;
@@ -35,7 +35,7 @@ async fn thread_rollback_drops_last_turns_and_persists_to_rollout() -> Result<()
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
// Start a thread.
@@ -1,6 +1,6 @@
use anyhow::Context;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_sequence_unchecked;
use app_test_support::to_response;
@@ -44,7 +44,7 @@ async fn thread_settings_update_emits_notification_and_updates_future_turns() ->
write_models_cache(codex_home.path())?;
let (model_id, service_tier_id) = service_tier_model_and_tier_id()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let thread = start_thread(&mut mcp).await?.thread;
@@ -104,7 +104,7 @@ async fn thread_settings_update_while_turn_is_active_emits_notification() -> Res
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let thread = start_thread(&mut mcp).await?.thread;
start_text_turn(&mut mcp, thread.id.clone()).await?;
@@ -147,7 +147,7 @@ async fn thread_settings_update_null_service_tier_uses_default() -> Result<()> {
write_models_cache(codex_home.path())?;
let (model_id, service_tier_id) = service_tier_model_and_tier_id()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let thread = start_thread(&mut mcp).await?.thread;
@@ -213,7 +213,7 @@ async fn thread_settings_update_rejects_sandbox_policy_with_permissions() -> Res
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let thread = start_thread(&mut mcp).await?.thread;
@@ -247,7 +247,7 @@ async fn turn_start_settings_override_emits_thread_settings_updated() -> Result<
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_TIMEOUT, mcp.initialize()).await??;
let thread = start_thread(&mut mcp).await?.thread;
timeout(
@@ -289,7 +289,7 @@ async fn turn_start_settings_override_emits_thread_settings_updated() -> Result<
}
async fn send_thread_settings_update(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
params: ThreadSettingsUpdateParams,
) -> Result<()> {
let request_id = mcp.send_thread_settings_update_request(params).await?;
@@ -302,7 +302,7 @@ async fn send_thread_settings_update(
Ok(())
}
async fn start_text_turn(mcp: &mut McpProcess, thread_id: String) -> Result<()> {
async fn start_text_turn(mcp: &mut TestAppServer, thread_id: String) -> Result<()> {
let turn_request_id = mcp
.send_turn_start_request(TurnStartParams {
thread_id,
@@ -323,7 +323,7 @@ async fn start_text_turn(mcp: &mut McpProcess, thread_id: String) -> Result<()>
Ok(())
}
async fn start_thread(mcp: &mut McpProcess) -> Result<ThreadStartResponse> {
async fn start_thread(mcp: &mut TestAppServer) -> Result<ThreadStartResponse> {
let request_id = mcp
.send_thread_start_request(ThreadStartParams {
model: Some("mock-model".to_string()),
@@ -339,7 +339,7 @@ async fn start_thread(mcp: &mut McpProcess) -> Result<ThreadStartResponse> {
}
async fn read_thread_with_turns(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
thread_id: &str,
) -> Result<ThreadReadResponse> {
let request_id = mcp
@@ -357,7 +357,7 @@ async fn read_thread_with_turns(
}
async fn read_thread_settings_updated(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
) -> Result<ThreadSettingsUpdatedNotification> {
let notification: JSONRPCNotification = timeout(
DEFAULT_TIMEOUT,
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_sequence;
use app_test_support::create_shell_command_sse_response;
@@ -60,7 +60,7 @@ async fn thread_shell_command_history_responses_exclude_persisted_command_execut
&BTreeMap::default(),
)?;
let mut mcp = McpProcess::new(codex_home.as_path()).await?;
let mut mcp = TestAppServer::new(codex_home.as_path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -196,7 +196,7 @@ async fn thread_shell_command_returns_error_when_local_environment_is_disabled()
&BTreeMap::default(),
)?;
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.as_path(),
&[(CODEX_EXEC_SERVER_URL_ENV_VAR, Some("none"))],
)
@@ -255,7 +255,7 @@ async fn thread_shell_command_uses_existing_active_turn() -> Result<()> {
&BTreeMap::default(),
)?;
let mut mcp = McpProcess::new(codex_home.as_path()).await?;
let mut mcp = TestAppServer::new(codex_home.as_path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -410,7 +410,7 @@ fn current_shell_output_command(text: &str) -> Result<(String, String)> {
}
async fn wait_for_command_execution_started(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
expected_id: Option<&str>,
) -> Result<ItemStartedNotification> {
loop {
@@ -432,7 +432,7 @@ async fn wait_for_command_execution_started(
}
async fn wait_for_command_execution_started_by_source(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
expected_source: CommandExecutionSource,
) -> Result<ItemStartedNotification> {
loop {
@@ -447,7 +447,7 @@ async fn wait_for_command_execution_started_by_source(
}
async fn wait_for_command_execution_completed(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
expected_id: Option<&str>,
) -> Result<ItemCompletedNotification> {
loop {
@@ -469,7 +469,7 @@ async fn wait_for_command_execution_completed(
}
async fn wait_for_command_execution_output_delta(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
item_id: &str,
) -> Result<CommandExecutionOutputDeltaNotification> {
loop {
@@ -1,7 +1,7 @@
use anyhow::Result;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::PathBufExt;
use app_test_support::TestAppServer;
use app_test_support::create_mock_responses_server_repeating_assistant;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
@@ -58,7 +58,7 @@ async fn thread_start_deprecates_persist_extended_history_true() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml_without_approval_policy(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let req_id = mcp
@@ -101,7 +101,7 @@ async fn thread_start_creates_thread_and_emits_started() -> Result<()> {
create_config_toml_without_approval_policy(codex_home.path(), &server.uri())?;
// Start server and initialize.
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
// Start a v2 thread with an explicit model override.
@@ -248,7 +248,7 @@ async fn thread_start_resolves_runtime_workspace_roots_against_cwd() -> Result<(
let relative_root = PathBuf::from("extra-root");
std::fs::create_dir_all(cwd.join(&relative_root))?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let req_id = mcp
@@ -292,7 +292,7 @@ async fn thread_start_excludes_profile_workspace_roots_from_runtime_workspace_ro
profile_root.path(),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let req_id = mcp
@@ -327,7 +327,7 @@ async fn thread_start_rejects_unknown_environment_as_invalid_request() -> Result
let codex_home = TempDir::new()?;
create_config_toml_without_approval_policy(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -364,7 +364,7 @@ async fn thread_start_response_includes_loaded_instruction_sources() -> Result<(
let project_agents_path = workspace.path().join("AGENTS.md");
std::fs::write(&project_agents_path, "project instructions")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -420,7 +420,7 @@ async fn thread_start_tracks_thread_initialized_analytics() -> Result<()> {
create_config_toml_with_chatgpt_base_url(codex_home.path(), &server.uri(), &server.uri())?;
mount_analytics_capture(&server, codex_home.path()).await?;
let mut mcp = McpProcess::new_without_managed_config(codex_home.path()).await?;
let mut mcp = TestAppServer::new_without_managed_config(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let req_id = mcp
@@ -468,7 +468,7 @@ model_reasoning_effort = "high"
)?;
set_project_trust_level(codex_home.path(), workspace.path(), TrustLevel::Trusted)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let req_id = mcp
@@ -498,7 +498,7 @@ async fn thread_start_drops_unsupported_service_tier_id() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml_without_approval_policy(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let service_tier_id = "experimental-tier-id".to_string();
@@ -528,7 +528,7 @@ async fn thread_start_accepts_default_service_tier() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml_without_approval_policy(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let req_id = mcp
@@ -559,7 +559,7 @@ async fn thread_start_accepts_metrics_service_name() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml_without_approval_policy(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let req_id = mcp
@@ -586,7 +586,7 @@ async fn thread_start_ephemeral_remains_pathless() -> Result<()> {
let codex_home = TempDir::new()?;
create_config_toml_without_approval_policy(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let req_id = mcp
@@ -632,7 +632,7 @@ async fn thread_start_fails_when_required_mcp_server_fails_to_initialize() -> Re
let codex_home = TempDir::new()?;
create_config_toml_with_required_broken_mcp(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let req_id = mcp
@@ -668,7 +668,7 @@ async fn thread_start_emits_mcp_server_status_updated_notifications() -> Result<
let codex_home = TempDir::new()?;
create_config_toml_with_optional_broken_mcp(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let req_id = mcp
@@ -798,7 +798,7 @@ async fn thread_start_surfaces_cloud_requirements_load_errors() -> Result<()> {
)?;
let refresh_token_url = format!("{}/oauth/token", server.uri());
let mut mcp = McpProcess::new_with_env(
let mut mcp = TestAppServer::new_with_env(
codex_home.path(),
&[
("OPENAI_API_KEY", None),
@@ -858,7 +858,7 @@ model_reasoning_effort = "high"
"#,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let first_request = mcp
@@ -918,7 +918,7 @@ async fn thread_start_with_nested_git_cwd_trusts_repo_root() -> Result<()> {
let nested = repo_root.path().join("nested/project");
std::fs::create_dir_all(&nested)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -956,7 +956,7 @@ async fn thread_start_with_read_only_sandbox_does_not_persist_project_trust() ->
let workspace = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -994,7 +994,7 @@ async fn thread_start_preserves_untrusted_project_trust() -> Result<()> {
std::fs::write(&config_path, config_toml.to_string())?;
let config_before = std::fs::read_to_string(&config_path)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1035,7 +1035,7 @@ model_reasoning_effort = "high"
set_project_trust_level(codex_home.path(), workspace.path(), TrustLevel::Trusted)?;
let config_before = std::fs::read_to_string(codex_home.path().join("config.toml"))?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_sequence;
use app_test_support::to_response;
@@ -29,7 +29,7 @@ async fn thread_status_changed_emits_runtime_updates() -> Result<()> {
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp =
McpProcess::new_with_env(codex_home.path(), &[("RUST_LOG", Some("info"))]).await?;
TestAppServer::new_with_env(codex_home.path(), &[("RUST_LOG", Some("info"))]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_start_id = mcp
@@ -135,7 +135,7 @@ async fn thread_status_changed_can_be_opted_out() -> Result<()> {
let server = create_mock_responses_server_sequence(responses).await;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
let message = timeout(
DEFAULT_READ_TIMEOUT,
mcp.initialize_with_capabilities(
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_mock_responses_server_repeating_assistant;
use app_test_support::to_response;
use codex_app_server::in_process;
@@ -60,7 +60,7 @@ async fn thread_unarchive_moves_rollout_back_into_sessions_directory() -> Result
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -1,5 +1,5 @@
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_mock_responses_server_repeating_assistant;
use app_test_support::to_response;
use codex_app_server_protocol::DynamicToolCallOutputContentItem;
@@ -41,7 +41,7 @@ async fn thread_unsubscribe_keeps_thread_loaded_until_idle_timeout() -> Result<(
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_thread(&mut mcp).await?;
@@ -120,7 +120,7 @@ async fn thread_unsubscribe_during_turn_keeps_turn_running() -> Result<()> {
let final_response_completed = completions.remove(0);
create_config_toml(&codex_home, server.uri())?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -253,7 +253,7 @@ async fn thread_unsubscribe_preserves_cached_status_before_idle_unload() -> Resu
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_thread(&mut mcp).await?;
@@ -340,7 +340,7 @@ async fn thread_unsubscribe_reports_not_subscribed_before_idle_unload() -> Resul
let codex_home = TempDir::new()?;
create_config_toml(codex_home.path(), &server.uri())?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_id = start_thread(&mut mcp).await?;
@@ -379,7 +379,7 @@ async fn thread_unsubscribe_reports_not_subscribed_before_idle_unload() -> Resul
}
async fn wait_for_dynamic_tool_started(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
call_id: &str,
) -> Result<ItemStartedNotification> {
loop {
@@ -419,7 +419,7 @@ stream_max_retries = 0
)
}
async fn start_thread(mcp: &mut McpProcess) -> Result<String> {
async fn start_thread(mcp: &mut TestAppServer) -> Result<String> {
let req_id = mcp
.send_thread_start_request(ThreadStartParams {
model: Some("mock-model".to_string()),
@@ -1,7 +1,7 @@
#![cfg(unix)]
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_sequence;
use app_test_support::create_mock_responses_server_sequence_unchecked;
@@ -57,7 +57,7 @@ async fn turn_interrupt_aborts_running_turn() -> Result<()> {
.await;
create_config_toml(&codex_home, &server.uri(), "never", "workspace-write")?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
// Start a v2 thread and capture its id.
@@ -141,7 +141,7 @@ async fn turn_interrupt_rejects_completed_turn() -> Result<()> {
.await;
create_config_toml(&codex_home, &server.uri(), "never", "workspace-write")?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -236,7 +236,7 @@ async fn turn_interrupt_resolves_pending_command_approval_request() -> Result<()
.await;
create_config_toml(&codex_home, &server.uri(), "untrusted", "read-only")?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -1,7 +1,7 @@
use anyhow::Context;
use anyhow::Result;
use app_test_support::DEFAULT_CLIENT_NAME;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_apply_patch_sse_response;
use app_test_support::create_exec_command_sse_response;
use app_test_support::create_fake_rollout;
@@ -119,7 +119,7 @@ async fn run_local_image_turn(detail: Option<ImageDetail>) -> Result<Vec<Value>>
&BTreeMap::default(),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -216,7 +216,7 @@ async fn turn_start_with_empty_input_runs_model_request() -> Result<()> {
&BTreeMap::default(),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -318,7 +318,7 @@ async fn turn_start_additional_context_flows_to_model_input() -> Result<()> {
&BTreeMap::default(),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -395,7 +395,7 @@ async fn turn_start_sends_originator_header() -> Result<()> {
&BTreeMap::from([(Feature::Personality, true)]),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(
DEFAULT_READ_TIMEOUT,
mcp.initialize_with_client_info(ClientInfo {
@@ -472,7 +472,7 @@ async fn turn_start_emits_user_message_item_with_text_elements() -> Result<()> {
&BTreeMap::from([(Feature::Personality, true)]),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -587,7 +587,7 @@ async fn turn_start_emits_thread_scoped_warning_notification_for_trimmed_skills(
write_test_skill(codex_home.path(), "alpha-skill")?;
write_test_skill(codex_home.path(), "beta-skill")?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -680,7 +680,7 @@ async fn turn_start_sends_service_tier_id_to_model_request() -> Result<()> {
.expect("bundled model catalog should include a picker model with service tiers");
let service_tier_id = service_tier_model.service_tiers[0].id.clone();
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -744,7 +744,7 @@ async fn thread_start_omits_empty_instruction_overrides_from_model_request() ->
&BTreeMap::default(),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -830,7 +830,7 @@ async fn turn_start_tracks_turn_event_analytics() -> Result<()> {
)?;
mount_analytics_capture(&server, codex_home.path()).await?;
let mut mcp = McpProcess::new_without_managed_config(codex_home.path()).await?;
let mut mcp = TestAppServer::new_without_managed_config(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -920,7 +920,7 @@ async fn turn_start_accepts_text_at_limit_with_mention_item() -> Result<()> {
&BTreeMap::from([(Feature::Personality, true)]),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -980,7 +980,7 @@ async fn turn_start_rejects_combined_oversized_text_input() -> Result<()> {
&BTreeMap::from([(Feature::Personality, true)]),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -1060,7 +1060,7 @@ async fn turn_start_rejects_invalid_permission_selection_before_starting_turn()
"sandbox_mode = \"read-only\"\n",
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -1132,7 +1132,7 @@ async fn turn_start_rejects_unknown_environment_before_starting_turn() -> Result
&BTreeMap::default(),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -1204,7 +1204,7 @@ async fn turn_start_emits_notifications_and_accepts_model_override() -> Result<(
&BTreeMap::from([(Feature::Personality, true)]),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
// Start a thread (v2) and capture its id.
@@ -1349,7 +1349,7 @@ async fn turn_start_accepts_collaboration_mode_override_v2() -> Result<()> {
&BTreeMap::default(),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -1435,7 +1435,7 @@ async fn turn_start_uses_thread_feature_overrides_for_request_user_input_tool_de
&BTreeMap::default(),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -1520,7 +1520,7 @@ async fn turn_start_accepts_personality_override_v2() -> Result<()> {
&BTreeMap::from([(Feature::Personality, true)]),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -1602,7 +1602,7 @@ async fn turn_start_change_personality_mid_thread_v2() -> Result<()> {
&BTreeMap::from([(Feature::Personality, true)]),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -1718,7 +1718,7 @@ async fn turn_start_uses_migrated_pragmatic_personality_without_override_v2() ->
/*git_info*/ None,
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let persisted_toml: ConfigToml = toml::from_str(&std::fs::read_to_string(
@@ -1849,7 +1849,7 @@ async fn turn_start_exec_approval_toggle_v2() -> Result<()> {
&BTreeMap::default(),
)?;
let mut mcp = McpProcess::new(codex_home.as_path()).await?;
let mut mcp = TestAppServer::new(codex_home.as_path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
// thread/start
@@ -1994,7 +1994,7 @@ async fn turn_start_exec_approval_decline_v2() -> Result<()> {
&BTreeMap::default(),
)?;
let mut mcp = McpProcess::new(codex_home.as_path()).await?;
let mut mcp = TestAppServer::new(codex_home.as_path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -2147,7 +2147,7 @@ async fn turn_start_updates_sandbox_and_cwd_between_turns_v2() -> Result<()> {
&BTreeMap::default(),
)?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
// thread/start
@@ -2337,7 +2337,7 @@ stream_max_retries = 0
),
)?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -2448,7 +2448,7 @@ url = "ws://127.0.0.1:1"
"#,
)?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
for case in [
@@ -2491,7 +2491,7 @@ struct EnvironmentSelectionCase {
}
async fn run_environment_selection_case(
mcp: &mut McpProcess,
mcp: &mut TestAppServer,
workspace: &Path,
case: EnvironmentSelectionCase,
) -> Result<()> {
@@ -2609,7 +2609,7 @@ async fn turn_start_file_change_approval_v2() -> Result<()> {
&BTreeMap::default(),
)?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_req = mcp
@@ -2800,7 +2800,7 @@ async fn turn_start_does_not_stream_apply_patch_change_updates_without_feature_v
let server = create_mock_responses_server_sequence(responses).await;
create_config_toml(&codex_home, &server.uri(), "never", &BTreeMap::default())?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_req = mcp
@@ -2938,7 +2938,7 @@ async fn turn_start_streams_apply_patch_change_updates_v2() -> Result<()> {
model["apply_patch_tool_type"] = serde_json::Value::from("freeform");
std::fs::write(&cache_path, serde_json::to_string_pretty(&cache)?)?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_req = mcp
@@ -3070,7 +3070,7 @@ async fn turn_start_emits_spawn_agent_item_with_model_metadata_v2() -> Result<()
&BTreeMap::from([(Feature::Collab, true)]),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -3290,7 +3290,7 @@ config_file = "./custom-role.toml"
),
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -3434,7 +3434,7 @@ async fn turn_start_file_change_approval_accept_for_session_persists_v2() -> Res
&BTreeMap::default(),
)?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_req = mcp
@@ -3607,7 +3607,7 @@ async fn turn_start_file_change_approval_decline_v2() -> Result<()> {
&BTreeMap::default(),
)?;
let mut mcp = McpProcess::new(&codex_home).await?;
let mut mcp = TestAppServer::new(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_req = mcp
@@ -3754,7 +3754,7 @@ async fn command_execution_notifications_include_process_id() -> Result<()> {
"danger-full-access",
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let start_id = mcp
@@ -3888,7 +3888,7 @@ async fn turn_start_with_elevated_override_does_not_persist_project_trust() -> R
let workspace = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_request = mcp
@@ -7,7 +7,7 @@
// network access are required the first time the artifact is fetched.
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_final_assistant_message_sse_response;
use app_test_support::create_mock_responses_server_sequence;
use app_test_support::create_mock_responses_server_sequence_unchecked;
@@ -743,10 +743,10 @@ async fn create_zsh_test_mcp_process(
codex_home: &Path,
zdotdir: &Path,
zsh_path: &Path,
) -> Result<McpProcess> {
) -> Result<TestAppServer> {
let app_server = create_test_package_app_server(codex_home, zsh_path)?;
let zdotdir = zdotdir.to_string_lossy().into_owned();
McpProcess::new_with_program_and_env(
TestAppServer::new_with_program_and_env(
codex_home,
&app_server,
&[("ZDOTDIR", Some(zdotdir.as_str()))],
@@ -2,7 +2,7 @@
use anyhow::Context;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_mock_responses_server_sequence;
use app_test_support::create_mock_responses_server_sequence_unchecked;
use app_test_support::create_shell_command_sse_response;
@@ -50,7 +50,7 @@ async fn turn_steer_requires_active_turn() -> Result<()> {
)?;
mount_analytics_capture(&server, &codex_home).await?;
let mut mcp = McpProcess::new_without_managed_config(&codex_home).await?;
let mut mcp = TestAppServer::new_without_managed_config(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -136,7 +136,7 @@ async fn turn_steer_rejects_oversized_text_input() -> Result<()> {
)?;
mount_analytics_capture(&server, &codex_home).await?;
let mut mcp = McpProcess::new_without_managed_config(&codex_home).await?;
let mut mcp = TestAppServer::new_without_managed_config(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -250,7 +250,7 @@ async fn turn_steer_returns_active_turn_id() -> Result<()> {
)?;
mount_analytics_capture(&server, &codex_home).await?;
let mut mcp = McpProcess::new_without_managed_config(&codex_home).await?;
let mut mcp = TestAppServer::new_without_managed_config(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -387,7 +387,7 @@ async fn turn_steer_rejects_context_only_input_without_merging_context() -> Resu
)?;
mount_analytics_capture(&server, &codex_home).await?;
let mut mcp = McpProcess::new_without_managed_config(&codex_home).await?;
let mut mcp = TestAppServer::new_without_managed_config(&codex_home).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -4,7 +4,7 @@ use std::time::Duration;
use anyhow::Context;
use anyhow::Result;
use app_test_support::ChatGptAuthFixture;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::to_response;
use app_test_support::write_chatgpt_auth;
use codex_app_server_protocol::ItemCompletedNotification;
@@ -78,7 +78,8 @@ async fn standalone_web_search_round_trips_encrypted_output() -> Result<()> {
AuthCredentialsStoreMode::File,
)?;
let mut mcp = McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
let mut mcp =
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let thread_req = mcp
@@ -194,7 +195,7 @@ async fn standalone_web_search_round_trips_encrypted_output() -> Result<()> {
drop(mcp);
let mut reloaded_mcp =
McpProcess::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
TestAppServer::new_with_env(codex_home.path(), &[("OPENAI_API_KEY", None)]).await?;
timeout(DEFAULT_READ_TIMEOUT, reloaded_mcp.initialize()).await??;
let read_req = reloaded_mcp
.send_thread_read_request(ThreadReadParams {
@@ -219,7 +220,7 @@ async fn standalone_web_search_round_trips_encrypted_output() -> Result<()> {
Ok(())
}
async fn wait_for_web_search_started(mcp: &mut McpProcess) -> Result<ItemStartedNotification> {
async fn wait_for_web_search_started(mcp: &mut TestAppServer) -> Result<ItemStartedNotification> {
loop {
let notification = mcp
.read_stream_until_notification_message("item/started")
@@ -235,7 +236,9 @@ async fn wait_for_web_search_started(mcp: &mut McpProcess) -> Result<ItemStarted
}
}
async fn wait_for_web_search_completed(mcp: &mut McpProcess) -> Result<ItemCompletedNotification> {
async fn wait_for_web_search_completed(
mcp: &mut TestAppServer,
) -> Result<ItemCompletedNotification> {
loop {
let notification = mcp
.read_stream_until_notification_message("item/completed")
@@ -1,6 +1,6 @@
use anyhow::Context;
use anyhow::Result;
use app_test_support::McpProcess;
use app_test_support::TestAppServer;
use app_test_support::create_mock_responses_server_sequence_unchecked;
use app_test_support::to_response;
use app_test_support::write_mock_responses_config_toml;
@@ -31,7 +31,7 @@ async fn windows_sandbox_setup_start_emits_completion_notification() -> Result<(
"mock_provider",
"compact prompt",
)?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp
@@ -66,7 +66,7 @@ async fn windows_sandbox_setup_start_emits_completion_notification() -> Result<(
#[tokio::test]
async fn windows_sandbox_setup_start_rejects_relative_cwd() -> Result<()> {
let codex_home = TempDir::new()?;
let mut mcp = McpProcess::new(codex_home.path()).await?;
let mut mcp = TestAppServer::new(codex_home.path()).await?;
timeout(DEFAULT_READ_TIMEOUT, mcp.initialize()).await??;
let request_id = mcp