Files
codex/codex-rs/tui/src/app_server_connection.rs
T
Eric Traut b7f710273e Support the app-server daemon on Windows (#42405)
## Why

The managed app-server daemon and automatic TUI attachment were limited to
Unix, so Windows users could not share a background server across Codex
sessions.

## What changed

- Enable daemon lifecycle commands, `codex agents` startup, and AF_UNIX daemon
  discovery on Windows.
- Require Windows daemons to start non-elevated and verify the discovered
  socket directory and peer before connecting.
- Preflight detached process support, preserve path-based environment settings,
  and keep daemon processes out of the launching project's working directory.
- Fall back to an embedded server when an implicitly discovered daemon cannot
  connect, while preserving errors for explicit remote endpoints and bypassing
  daemon reuse when `CODEX_EXEC_SERVER_URL` is set.

## Testing

Add coverage for Windows launch restrictions and socket validation, implicit
connection fallback, executor selection, daemon discovery, and the agents
dashboard startup result.

GitOrigin-RevId: e7fd63cf8690bcca8b5155266416f31f2f792aa2
2026-09-03 01:26:35 +00:00

49 lines
2.1 KiB
Rust

//! Applies the selected server's socket policy on initial connections and reconnects.
use crate::AppServerTarget;
#[cfg(windows)]
use crate::DEFAULT_IN_PROCESS_CHANNEL_CAPACITY;
use crate::connect_remote_app_server;
use codex_app_server_client::AppServerClient;
#[cfg(windows)]
use codex_app_server_client::RemoteAppServerClient;
#[cfg(windows)]
use codex_app_server_client::RemoteAppServerConnectArgs;
#[cfg(windows)]
use codex_app_server_client::RemoteAppServerEndpoint;
#[cfg(windows)]
use codex_utils_absolute_path::AbsolutePathBuf;
pub(crate) async fn connect(target: &AppServerTarget) -> color_eyre::Result<AppServerClient> {
match target {
AppServerTarget::Embedded => {
color_eyre::eyre::bail!("embedded sessions have no remote connection")
}
#[cfg(windows)]
AppServerTarget::LocalDaemon {
endpoint: RemoteAppServerEndpoint::UnixSocket { socket_path },
} => {
// Revalidate at the real connection, not just the earlier discovery probe.
let (socket_path, _directory) =
codex_uds::validate_private_socket_path(socket_path.as_path())?;
let app_server =
RemoteAppServerClient::connect_local_daemon(RemoteAppServerConnectArgs {
endpoint: RemoteAppServerEndpoint::UnixSocket {
socket_path: AbsolutePathBuf::from_absolute_path_checked(socket_path)?,
},
client_name: "codex-tui".to_string(),
client_version: env!("CARGO_PKG_VERSION").to_string(),
experimental_api: true,
mcp_server_openai_form_elicitation: false,
opt_out_notification_methods: Vec::new(),
channel_capacity: DEFAULT_IN_PROCESS_CHANNEL_CAPACITY,
})
.await?;
Ok(AppServerClient::Remote(app_server))
}
AppServerTarget::LocalDaemon { endpoint } | AppServerTarget::Remote { endpoint } => {
connect_remote_app_server(endpoint.clone()).await
}
}
}