Files
codex/codex-rs/app-server-client
Benjamin Carlsson 6ddb87e700 Allow Ctrl+C to quit during Cloud session switches (#61481)
## What changed

Handle `Ctrl+C` while preparing a Cloud session and before adopting its thread. Clear buffered draft input first; when no draft or modal handles cancellation, request shutdown and abandon the pending switch.

Cancel abandoned Cloud thread-start requests so they cannot replace the active attachment or block subsequent worker commands. Skip queued starts whose caller has already gone away without disturbing existing recovery.

## Testing

Add regression tests for quitting before thread adoption with pending and completed operations, clearing buffered draft input before quitting, and unblocking the Cloud worker after abandoning regular and project thread starts.

GitOrigin-RevId: 11e8cab13f00f4910a382094d5d857faf72a45bc
2026-11-14 07:19:13 +00: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

  • Command queues and the embedded runtime remain bounded, using DEFAULT_IN_PROCESS_CHANNEL_CAPACITY by default.
  • The facade's local consumer event queue is unbounded and preserves notification order. This keeps the worker draining the bounded runtime while a caller waits for a request, preventing unread notifications from blocking its response.
  • shutdown() performs a bounded graceful shutdown and then aborts if timeout is exceeded.