Problem
codex app-server currently offers raw newline-delimited protocol messages only through stdio://. When Codex is reached through a launcher or bootstrap process, that process shares stdout with the native app-server. Any bootstrap output is therefore indistinguishable from protocol traffic and can make an otherwise valid app-server installation fail initialization.
This is reproducible with the npm launcher by setting a Node preload that writes to stdout before the native binary starts. The same environment launched directly against the native binary is stdout-clean.
The existing unix://PATH transport avoids shared stdout, but it is WebSocket-framed. A Node 18 client with no runtime dependencies cannot reuse its existing JSONL parser against that transport.
Expected Outcome
Add an app-server listen URL for a dedicated, single-client raw JSONL Unix socket, for example:
codex app-server --listen unix-jsonl://PATH
The transport should:
- carry the existing app-server newline-delimited message schema without introducing a second schema;
- accept one client and exit deterministically when that client disconnects;
- fail with
AddrInUse when the caller-selected endpoint already exists, without probing, unlinking, or replacing it;
- preserve an existing parent directory's permissions and set the created socket to
0600;
- bound the first-client wait so a server whose caller dies before connecting does not remain orphaned;
- remove only its owned socket on timeout, disconnect, or process exit;
- leave the existing
stdio://, Unix WebSocket, TCP WebSocket, and off transports unchanged.
This would let clients keep launcher stdout and stderr as diagnostics while parsing protocol bytes only from the dedicated socket. No environment filtering, launcher changes, output classification, or stdio fallback would be needed.
Approach Notes
The current Unix-socket lifecycle and stdio JSONL reader/writer already contain most of the required behavior. The proposed transport composes the existing Unix endpoint lifecycle with the existing stdio framing and app-server message types.
A reviewed reference implementation is available here for source and test evidence; it is provided as technical context, not as a request to accept an external PR:
seungpyoson@fd4854a
The requested scope is macOS, Linux, and a whole-chain Linux WSL2 environment. No native-Windows behavior is claimed by the supplied evidence.
Risks
- Endpoint ownership must remain fail-closed so a challenger cannot consume or replace an incumbent's single accept.
- The first-client deadline must be non-resetting across recoverable accept failures.
- Existing transport behavior and message schemas must remain unchanged.
Verification
- transport tests for split/coalesced JSONL frames, request/response/notification flow, single-client enforcement, incumbent preservation, parent-permission preservation, socket mode, accept retry, timeout, and cleanup;
- real-process app-server initialization over
unix-jsonl://PATH;
- regression coverage for existing app-server transports;
- formatting, focused lint, focused tests, and a release app-server build.
Relations
Related to openai/codex-plugin-cc#685, which independently makes app-server connection loss terminal and reaps failed children but does not provide channel separation.
Problem
codex app-servercurrently offers raw newline-delimited protocol messages only throughstdio://. When Codex is reached through a launcher or bootstrap process, that process shares stdout with the native app-server. Any bootstrap output is therefore indistinguishable from protocol traffic and can make an otherwise valid app-server installation fail initialization.This is reproducible with the npm launcher by setting a Node preload that writes to stdout before the native binary starts. The same environment launched directly against the native binary is stdout-clean.
The existing
unix://PATHtransport avoids shared stdout, but it is WebSocket-framed. A Node 18 client with no runtime dependencies cannot reuse its existing JSONL parser against that transport.Expected Outcome
Add an app-server listen URL for a dedicated, single-client raw JSONL Unix socket, for example:
The transport should:
AddrInUsewhen the caller-selected endpoint already exists, without probing, unlinking, or replacing it;0600;stdio://, Unix WebSocket, TCP WebSocket, andofftransports unchanged.This would let clients keep launcher stdout and stderr as diagnostics while parsing protocol bytes only from the dedicated socket. No environment filtering, launcher changes, output classification, or stdio fallback would be needed.
Approach Notes
The current Unix-socket lifecycle and stdio JSONL reader/writer already contain most of the required behavior. The proposed transport composes the existing Unix endpoint lifecycle with the existing stdio framing and app-server message types.
A reviewed reference implementation is available here for source and test evidence; it is provided as technical context, not as a request to accept an external PR:
seungpyoson@fd4854a
The requested scope is macOS, Linux, and a whole-chain Linux WSL2 environment. No native-Windows behavior is claimed by the supplied evidence.
Risks
Verification
unix-jsonl://PATH;Relations
Related to openai/codex-plugin-cc#685, which independently makes app-server connection loss terminal and reaps failed children but does not provide channel separation.