Files
codex/codex-rs/app-server-client
Eric Traut ad572709ab Add support for UDS in codex --remote (#22414)
## Why

Added support for UDS connections in `codex --remote`.

TUI also now connects to local app-server using UDS by default if it is
running and set to listen to UDS connection.

## What Changed

- Introduced `RemoteAppServerEndpoint` with `WebSocket` and `UnixSocket`
variants.
- Reused the existing JSON-RPC-over-WebSocket protocol over either a TCP
WebSocket stream or a UDS stream.
- Updated `codex --remote` to accept `ws://host:port`,
`wss://host:port`, `unix://`, and `unix://PATH`.
- Kept `--remote-auth-token-env` restricted to `wss://` and loopback
`ws://` remotes.
- Added a fast TUI startup probe for the default daemon socket, falling
back to the embedded app server when the daemon is absent or
unresponsive.

## Verification

- Manually verified that the updated remote flow works.
- Added coverage for UDS remote round trips, WebSocket auth headers,
auth-token transport policy, remote address parsing, and missing-daemon
fallback.
- Ran focused remote test coverage locally.
2026-05-12 21:17:20 -07:00
..

codex-app-server-client

Shared in-process app-server client used by conversational CLI surfaces:

  • codex-exec
  • codex-tui

Purpose

This crate centralizes startup and lifecycle management for an in-process codex-app-server runtime, so CLI clients do not need to duplicate:

  • app-server bootstrap and initialize handshake
  • in-memory request/event transport wiring
  • lifecycle orchestration around caller-provided startup identity
  • graceful shutdown behavior

Startup identity

Callers pass both the app-server SessionSource and the initialize client_info.name explicitly when starting the facade.

That keeps thread metadata (for example in thread/list and thread/read) aligned with the originating runtime without baking TUI/exec-specific policy into the shared client layer.

Transport model

The in-process path uses typed channels:

  • client -> server: ClientRequest / ClientNotification
  • server -> client: InProcessServerEvent
    • ServerRequest
    • ServerNotification
    • LegacyNotification

JSON serialization is still used at external transport boundaries (stdio/websocket), but the in-process hot path is typed.

Typed requests still receive app-server responses through the JSON-RPC result envelope internally. That is intentional: the in-process path is meant to preserve app-server semantics while removing the process boundary, not to introduce a second response contract.

Bootstrap behavior

The client facade starts an already-initialized in-process runtime, but thread bootstrap still follows normal app-server flow:

  • caller sends thread/start or thread/resume
  • app-server returns the immediate typed response
  • richer session metadata may arrive later as a SessionConfigured legacy event

Surfaces such as TUI and exec may therefore need a short bootstrap phase where they reconcile startup response data with later events.

Backpressure and shutdown

  • Queues are bounded and use DEFAULT_IN_PROCESS_CHANNEL_CAPACITY by default.
  • Full queues return explicit overload behavior instead of unbounded growth.
  • shutdown() performs a bounded graceful shutdown and then aborts if timeout is exceeded.

If the client falls behind on event consumption, the worker emits InProcessServerEvent::Lagged and may reject pending server requests so approval flows do not hang indefinitely behind a saturated queue.