SaylorTwift HF Staff commited on
Commit
dabfdaa
·
verified ·
1 Parent(s): 5f25733

Add files using upload-large-folder tool

Browse files
This view is limited to 50 files because it contains too many changes.   See raw diff
Files changed (50) hide show
  1. codex-rs/.cargo/audit.toml +15 -0
  2. codex-rs/.cargo/config.toml +11 -0
  3. codex-rs/agent-graph-store/BUILD.bazel +6 -0
  4. codex-rs/agent-graph-store/Cargo.toml +26 -0
  5. codex-rs/agent-roles/BUILD.bazel +6 -0
  6. codex-rs/agent-roles/Cargo.toml +23 -0
  7. codex-rs/analytics/BUILD.bazel +6 -0
  8. codex-rs/analytics/Cargo.toml +35 -0
  9. codex-rs/app-server-client/BUILD.bazel +6 -0
  10. codex-rs/app-server-client/Cargo.toml +40 -0
  11. codex-rs/app-server-client/README.md +66 -0
  12. codex-rs/app-server-daemon/BUILD.bazel +6 -0
  13. codex-rs/app-server-daemon/Cargo.toml +46 -0
  14. codex-rs/app-server-daemon/README.md +192 -0
  15. codex-rs/app-server-protocol-noop-macros/BUILD.bazel +7 -0
  16. codex-rs/app-server-protocol-noop-macros/Cargo.toml +13 -0
  17. codex-rs/app-server-protocol/BUILD.bazel +19 -0
  18. codex-rs/app-server-protocol/Cargo.toml +56 -0
  19. codex-rs/app-server-test-client/BUILD.bazel +6 -0
  20. codex-rs/app-server-test-client/Cargo.toml +31 -0
  21. codex-rs/app-server-test-client/README.md +184 -0
  22. codex-rs/app-server/BUILD.bazel +31 -0
  23. codex-rs/app-server/Cargo.toml +155 -0
  24. codex-rs/app-server/README.md +285 -0
  25. codex-rs/apply-patch/BUILD.bazel +6 -0
  26. codex-rs/apply-patch/Cargo.toml +35 -0
  27. codex-rs/arg0/BUILD.bazel +6 -0
  28. codex-rs/arg0/Cargo.toml +35 -0
  29. codex-rs/async-utils/BUILD.bazel +6 -0
  30. codex-rs/async-utils/Cargo.toml +18 -0
  31. codex-rs/attachment-store/BUILD.bazel +6 -0
  32. codex-rs/attachment-store/Cargo.toml +20 -0
  33. codex-rs/aws-auth/BUILD.bazel +6 -0
  34. codex-rs/aws-auth/Cargo.toml +26 -0
  35. codex-rs/backend-client/BUILD.bazel +7 -0
  36. codex-rs/backend-client/Cargo.toml +31 -0
  37. codex-rs/build-info/BUILD.bazel +6 -0
  38. codex-rs/build-info/Cargo.toml +24 -0
  39. codex-rs/build-info/build.rs +8 -0
  40. codex-rs/chatgpt/BUILD.bazel +6 -0
  41. codex-rs/chatgpt/Cargo.toml +31 -0
  42. codex-rs/chatgpt/README.md +5 -0
  43. codex-rs/cli/BUILD.bazel +23 -0
  44. codex-rs/cli/Cargo.toml +138 -0
  45. codex-rs/cli/build.rs +5 -0
  46. codex-rs/cloud-tasks-client/BUILD.bazel +6 -0
  47. codex-rs/cloud-tasks-client/Cargo.toml +25 -0
  48. codex-rs/cloud-tasks-mock-client/BUILD.bazel +6 -0
  49. codex-rs/cloud-tasks-mock-client/Cargo.toml +20 -0
  50. codex-rs/cloud-tasks/BUILD.bazel +7 -0
codex-rs/.cargo/audit.toml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [advisories]
2
+ # Reviewed 2026-07-02. Keep this list in sync with ../deny.toml.
3
+ ignore = [
4
+ "RUSTSEC-2024-0388", # derivative 2.2.0 via starlark/starlark_syntax; upstream crate is unmaintained
5
+ "RUSTSEC-2025-0057", # fxhash 0.2.1 via starlark_map/bm25; upstream crate is unmaintained
6
+ "RUSTSEC-2024-0436", # paste 1.0.15 via starlark/v8; upstream crate is unmaintained
7
+ "RUSTSEC-2023-0089", # atomic-polyfill via postcard/heapless/pagable; upstream crate is unmaintained
8
+ "RUSTSEC-2024-0320", # yaml-rust via syntect; remove when syntect drops or updates it
9
+ "RUSTSEC-2025-0141", # bincode via syntect; remove when syntect drops or updates it
10
+ "RUSTSEC-2026-0118", # hickory-proto via rama-dns/rama-tcp; remove when rama updates to hickory 0.26.1 or hickory-net
11
+ "RUSTSEC-2026-0119", # hickory-proto via rama-dns/rama-tcp; remove when rama updates to hickory 0.26.1 or hickory-net
12
+ "RUSTSEC-2026-0173", # proc-macro-error2 via i18n-embed-fl/age/codex-secrets; remove when local secrets storage migrates off age or age drops i18n-embed-fl
13
+ "RUSTSEC-2026-0194", # quick-xml via plist/syntect and wayland-scanner; trusted inputs only; remove when rust-plist#191 and wayland-rs#938 are released
14
+ "RUSTSEC-2026-0195", # quick-xml via plist/syntect and wayland-scanner; trusted inputs only; remove when rust-plist#191 and wayland-rs#938 are released
15
+ ]
codex-rs/.cargo/config.toml ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [target.'cfg(all(windows, target_env = "msvc"))']
2
+ rustflags = ["-C", "link-arg=/STACK:8388608", "-C", "target-feature=+crt-static"]
3
+
4
+ # MSVC emits a warning about code that may trip "Cortex-A53 MPCore processor bug #843419" (see
5
+ # https://developer.arm.com/documentation/epm048406/latest) which is sometimes emitted by LLVM.
6
+ # Since Arm64 Windows 10+ isn't supported on that processor, it's safe to disable the warning.
7
+ [target.aarch64-pc-windows-msvc]
8
+ rustflags = ["-C", "link-arg=/STACK:8388608", "-C", "link-arg=/arm64hazardfree"]
9
+
10
+ [target.'cfg(all(windows, target_env = "gnu"))']
11
+ rustflags = ["-C", "link-arg=-Wl,--stack,8388608"]
codex-rs/agent-graph-store/BUILD.bazel ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "agent-graph-store",
5
+ crate_name = "codex_agent_graph_store",
6
+ )
codex-rs/agent-graph-store/Cargo.toml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ edition.workspace = true
3
+ license.workspace = true
4
+ name = "codex-agent-graph-store"
5
+ version.workspace = true
6
+
7
+ [lib]
8
+ name = "codex_agent_graph_store"
9
+ path = "src/lib.rs"
10
+ doctest = false
11
+
12
+ [lints]
13
+ workspace = true
14
+
15
+ [dependencies]
16
+ codex-protocol = { workspace = true }
17
+ codex-state = { workspace = true }
18
+ serde = { workspace = true, features = ["derive"] }
19
+ thiserror = { workspace = true }
20
+
21
+ [dev-dependencies]
22
+ codex-utils-absolute-path = { workspace = true }
23
+ pretty_assertions = { workspace = true }
24
+ serde_json = { workspace = true }
25
+ tempfile = { workspace = true }
26
+ tokio = { workspace = true, features = ["macros", "rt-multi-thread", "sync"] }
codex-rs/agent-roles/BUILD.bazel ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "agent-roles",
5
+ crate_name = "codex_agent_roles",
6
+ )
codex-rs/agent-roles/Cargo.toml ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ edition.workspace = true
3
+ license.workspace = true
4
+ name = "codex-agent-roles"
5
+ version.workspace = true
6
+
7
+ [lib]
8
+ doctest = false
9
+ name = "codex_agent_roles"
10
+ path = "src/lib.rs"
11
+ test = false
12
+
13
+ [lints]
14
+ workspace = true
15
+
16
+ [dependencies]
17
+ codex-config = { workspace = true }
18
+ codex-file-system = { workspace = true }
19
+ codex-utils-absolute-path = { workspace = true }
20
+ codex-utils-path-uri = { workspace = true }
21
+ serde = { workspace = true, features = ["derive"] }
22
+ toml = { workspace = true, features = ["preserve_order"] }
23
+ tracing = { workspace = true }
codex-rs/analytics/BUILD.bazel ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "analytics",
5
+ crate_name = "codex_analytics",
6
+ )
codex-rs/analytics/Cargo.toml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ edition.workspace = true
3
+ license.workspace = true
4
+ name = "codex-analytics"
5
+ version.workspace = true
6
+
7
+ [lib]
8
+ doctest = false
9
+ name = "codex_analytics"
10
+ path = "src/lib.rs"
11
+
12
+ [lints]
13
+ workspace = true
14
+
15
+ [dependencies]
16
+ codex-app-server-protocol = { workspace = true }
17
+ codex-git-utils = { workspace = true }
18
+ codex-login = { workspace = true }
19
+ codex-model-provider = { workspace = true }
20
+ codex-plugin = { workspace = true }
21
+ codex-protocol = { workspace = true }
22
+ codex-state = { workspace = true }
23
+ os_info = { workspace = true }
24
+ serde = { workspace = true, features = ["derive"] }
25
+ serde_json = { workspace = true }
26
+ sha1 = { workspace = true }
27
+ tokio = { workspace = true, features = [
28
+ "macros",
29
+ "rt-multi-thread",
30
+ ] }
31
+ tracing = { workspace = true, features = ["log"] }
32
+
33
+ [dev-dependencies]
34
+ codex-utils-absolute-path = { workspace = true }
35
+ pretty_assertions = { workspace = true }
codex-rs/app-server-client/BUILD.bazel ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "app-server-client",
5
+ crate_name = "codex_app_server_client",
6
+ )
codex-rs/app-server-client/Cargo.toml ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "codex-app-server-client"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+
7
+ [lib]
8
+ name = "codex_app_server_client"
9
+ path = "src/lib.rs"
10
+ doctest = false
11
+
12
+ [lints]
13
+ workspace = true
14
+
15
+ [dependencies]
16
+ codex-app-server = { workspace = true }
17
+ codex-app-server-protocol = { workspace = true }
18
+ codex-arg0 = { workspace = true }
19
+ codex-config = { workspace = true }
20
+ codex-core = { workspace = true }
21
+ codex-exec-server = { workspace = true }
22
+ codex-feedback = { workspace = true }
23
+ codex-protocol = { workspace = true }
24
+ codex-uds = { workspace = true }
25
+ codex-utils-absolute-path = { workspace = true }
26
+ codex-utils-rustls-provider = { workspace = true }
27
+ futures = { workspace = true }
28
+ serde = { workspace = true }
29
+ serde_json = { workspace = true }
30
+ tokio = { workspace = true, features = ["sync", "time", "rt"] }
31
+ tokio-tungstenite = { workspace = true }
32
+ toml = { workspace = true }
33
+ tracing = { workspace = true }
34
+ url = { workspace = true }
35
+
36
+ [dev-dependencies]
37
+ pretty_assertions = { workspace = true }
38
+ serde_json = { workspace = true }
39
+ tempfile = { workspace = true }
40
+ tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
codex-rs/app-server-client/README.md ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # codex-app-server-client
2
+
3
+ Shared in-process app-server client used by conversational CLI surfaces:
4
+
5
+ - `codex-exec`
6
+ - `codex-tui`
7
+
8
+ ## Purpose
9
+
10
+ This crate centralizes startup and lifecycle management for an in-process
11
+ `codex-app-server` runtime, so CLI clients do not need to duplicate:
12
+
13
+ - app-server bootstrap and initialize handshake
14
+ - in-memory request/event transport wiring
15
+ - lifecycle orchestration around caller-provided startup identity
16
+ - graceful shutdown behavior
17
+
18
+ ## Startup identity
19
+
20
+ Callers pass both the app-server `SessionSource` and the initialize
21
+ `client_info.name` explicitly when starting the facade.
22
+
23
+ That keeps thread metadata (for example in `thread/list` and `thread/read`)
24
+ aligned with the originating runtime without baking TUI/exec-specific policy
25
+ into the shared client layer.
26
+
27
+ ## Transport model
28
+
29
+ The in-process path uses typed channels:
30
+
31
+ - client -> server: `ClientRequest` / `ClientNotification`
32
+ - server -> client: `InProcessServerEvent`
33
+ - `ServerRequest`
34
+ - `ServerNotification`
35
+ - `LegacyNotification`
36
+
37
+ JSON serialization is still used at external transport boundaries
38
+ (stdio/websocket), but the in-process hot path is typed.
39
+
40
+ Typed requests still receive app-server responses through the JSON-RPC
41
+ result envelope internally. That is intentional: the in-process path is
42
+ meant to preserve app-server semantics while removing the process
43
+ boundary, not to introduce a second response contract.
44
+
45
+ ## Bootstrap behavior
46
+
47
+ The client facade starts an already-initialized in-process runtime, but
48
+ thread bootstrap still follows normal app-server flow:
49
+
50
+ - caller sends `thread/start` or `thread/resume`
51
+ - app-server returns the immediate typed response
52
+ - richer session metadata may arrive later as a `SessionConfigured`
53
+ legacy event
54
+
55
+ Surfaces such as TUI and exec may therefore need a short bootstrap
56
+ phase where they reconcile startup response data with later events.
57
+
58
+ ## Backpressure and shutdown
59
+
60
+ - Command queues and the embedded runtime remain bounded, using
61
+ `DEFAULT_IN_PROCESS_CHANNEL_CAPACITY` by default.
62
+ - The facade's local consumer event queue is unbounded and preserves notification
63
+ order. This keeps the worker draining the bounded runtime while a caller waits
64
+ for a request, preventing unread notifications from blocking its response.
65
+ - `shutdown()` performs a bounded graceful shutdown and then aborts if timeout
66
+ is exceeded.
codex-rs/app-server-daemon/BUILD.bazel ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "app-server-daemon",
5
+ crate_name = "codex_app_server_daemon",
6
+ )
codex-rs/app-server-daemon/Cargo.toml ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "codex-app-server-daemon"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+
7
+ [lib]
8
+ name = "codex_app_server_daemon"
9
+ path = "src/lib.rs"
10
+ doctest = false
11
+
12
+ [lints]
13
+ workspace = true
14
+
15
+ [dependencies]
16
+ anyhow = { workspace = true }
17
+ codex-app-server-protocol = { workspace = true }
18
+ codex-app-server-transport = { workspace = true }
19
+ codex-http-client = { workspace = true }
20
+ codex-install-context = { workspace = true }
21
+ codex-utils-home-dir = { workspace = true }
22
+ codex-uds = { workspace = true }
23
+ futures = { workspace = true }
24
+ libc = { workspace = true }
25
+ serde = { workspace = true, features = ["derive"] }
26
+ serde_json = { workspace = true }
27
+ semver = { workspace = true }
28
+ blake3 = { workspace = true }
29
+ tokio = { workspace = true, features = [
30
+ "fs",
31
+ "io-util",
32
+ "macros",
33
+ "process",
34
+ "rt-multi-thread",
35
+ "signal",
36
+ "time",
37
+ ] }
38
+ tempfile = { workspace = true }
39
+ tokio-tungstenite = { workspace = true }
40
+ tracing = { workspace = true }
41
+
42
+ [dev-dependencies]
43
+ pretty_assertions = { workspace = true }
44
+
45
+ [target.'cfg(windows)'.dependencies]
46
+ windows-sys = { version = "0.52", features = ["Win32_Foundation", "Win32_Storage_FileSystem", "Win32_System_IO", "Win32_System_JobObjects", "Win32_Security", "Win32_Security_Authorization", "Win32_System_Threading"] }
codex-rs/app-server-daemon/README.md ADDED
@@ -0,0 +1,192 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # codex-app-server-daemon
2
+
3
+ > `codex-app-server-daemon` is experimental and its lifecycle contract may
4
+ > change while the remote-management flow is still being developed.
5
+
6
+ `codex-app-server-daemon` backs the machine-readable `codex app-server`
7
+ lifecycle commands used by remote clients such as the desktop and mobile apps.
8
+ It is intended for Codex instances launched over SSH, including fresh developer
9
+ machines that should expose app-server with `remote_control` enabled.
10
+
11
+ ## Platform support
12
+
13
+ The daemon supports Linux, macOS, and Windows using platform-specific process
14
+ and file-locking primitives. Windows startup requires a non-elevated terminal
15
+ whose host permits detached child processes.
16
+
17
+ Windows automatic attachment requires the canonical socket address to fit the
18
+ 108-byte AF_UNIX limit (including its terminator). A short junction alias whose
19
+ resolved address exceeds that limit falls back to the embedded server. Use a
20
+ shorter `CODEX_HOME` to share the daemon; discovery does not trust a mutable alias.
21
+
22
+ Shared clients use the environment inherited when the daemon started. Opening a
23
+ new terminal or clearing variables there does not clear the running daemon's
24
+ environment; per-client environment isolation is not provided.
25
+ An invocation that sets `CODEX_EXEC_SERVER_URL` skips implicit daemon attachment
26
+ so its executor selection is preserved. If an implicitly discovered daemon cannot
27
+ initialize the connection, the TUI starts an embedded server instead. Explicit
28
+ `--remote` endpoints remain authoritative and report connection failures.
29
+
30
+ ## Commands
31
+
32
+ ```sh
33
+ codex app-server daemon start
34
+ codex app-server daemon restart
35
+ codex app-server daemon update
36
+ codex app-server daemon enable-remote-control
37
+ codex app-server daemon disable-remote-control
38
+ codex app-server daemon stop
39
+ codex app-server daemon version
40
+ codex app-server daemon bootstrap --remote-control
41
+ ```
42
+
43
+ On success, every command writes exactly one JSON object to stdout. Consumers
44
+ should parse that JSON rather than relying on human-readable text. Lifecycle
45
+ responses report the resolved backend, socket path, local CLI version, and
46
+ running app-server version when applicable.
47
+
48
+ Eligible managed daemons check for updates after five minutes, then hourly by
49
+ default. Edit `CODEX_HOME/app-server-daemon/settings.json` to change this:
50
+
51
+ ```json
52
+ {"remoteControlEnabled": false,
53
+ "shutdownGraceSeconds": 60,
54
+ "updater": {"autoUpdateEnabled": false, "updateIntervalMinutes": 120}}
55
+ ```
56
+
57
+ Positive minute intervals have no configured cap. `daemon restart` applies the
58
+ enabled state; the next updater wait reads a new interval. The preference does
59
+ not affect an explicit `codex update` command or `daemon update`.
60
+
61
+ `daemon update` selects the latest stable release, even with automatic updates
62
+ disabled. It also returns pinned or local managed packages to production update
63
+ eligibility, preserving the automatic-update preference. Legacy installations
64
+ migrate to the dedicated root once the published installer and release support
65
+ migration. JSON reports `updated`, `noUpdate`, or `unsupported`, with installed
66
+ and running versions. A running daemon restarts, so active or queued work may be
67
+ interrupted; a stopped daemon stays stopped. Installer errors return nonzero.
68
+ The updater uses saved network settings; CLI `-c` overrides do not reach it.
69
+
70
+ For all managed app-server shutdowns, including explicit stop and restart and
71
+ updater-triggered restarts, `shutdownGraceSeconds` defaults to 60 and accepts
72
+ an integer from 0 through 300. Zero forces shutdown immediately after requesting
73
+ a graceful exit; the five-minute maximum bounds the wait even if a turn is still
74
+ running.
75
+
76
+ ## Bootstrap flow
77
+
78
+ For a new Linux or macOS machine:
79
+
80
+ ```sh
81
+ curl -fsSL https://chatgpt.com/codex/install.sh | sh
82
+ $HOME/.codex/packages/standalone/current/codex app-server daemon bootstrap --remote-control
83
+ ```
84
+
85
+ On Windows, use a non-elevated PowerShell terminal whose host allows breakaway:
86
+
87
+ ```powershell
88
+ irm https://chatgpt.com/codex/install.ps1 | iex
89
+ $codexHome = if ($env:CODEX_HOME) { $env:CODEX_HOME } else { Join-Path $HOME '.codex' }
90
+ & "$codexHome\packages\standalone\current\bin\codex.exe" app-server daemon bootstrap --remote-control
91
+ ```
92
+
93
+ `bootstrap` can use any complete CLI package. If no daemon package is installed,
94
+ it copies the invoking package into `CODEX_HOME/packages/app-server-daemon` and
95
+ prints an installation message without asking for confirmation. Existing daemon
96
+ packages are reused, including legacy installations; a broken selection is not
97
+ silently replaced. A bare executable cannot supply a new installation.
98
+
99
+ It records the daemon settings under `CODEX_HOME/app-server-daemon/`, starts app-server as a
100
+ pidfile-backed detached process. It launches a detached updater loop when
101
+ automatic updates are enabled, the installer selected the stable `latest`
102
+ channel, and the managed binary supports the updater command.
103
+
104
+ ## Installation and update cases
105
+
106
+ New daemons use `CODEX_HOME/packages/app-server-daemon/current/bin/codex`
107
+ (`codex.exe` on Windows). The package contains the executable and its helpers.
108
+ Daemon-only installer updates leave the user's CLI command and shell setup alone.
109
+
110
+ Previously launched legacy daemons retain `CODEX_HOME/packages/standalone/current`,
111
+ including its flat binary layout when present. Starts and scheduled updates keep
112
+ using that location. An explicit production update prepares and validates a
113
+ compatible dedicated package before stopping the legacy updater and daemon,
114
+ selecting the new package, and restarting only a previously running daemon.
115
+ The old CLI package files and selection remain unchanged.
116
+
117
+ | Situation | What starts | Does this daemon fetch new binaries? | Does a running app-server eventually move to a newer binary on its own? |
118
+ | --- | --- | --- | --- |
119
+ | Latest-channel installer has run; `start` or `bootstrap` is used with automatic updates enabled | Managed binary and detached updater when supported | When supported, the platform's installer runs on the configured cadence. | When supported, the running server restarts with the new binary before the updater replaces itself. |
120
+ | Installer selected an explicit release; `bootstrap` is used | Managed binary only | No; the selected release stays pinned. | No; an explicit restart uses the selected binary. |
121
+ | Another tool updates the managed binary | A fresh start or explicit restart uses it; a running server is reused. | Yes, when a latest-channel updater is running, on the configured cadence. | An updater that was running through the change compares binary contents on its next successful installer pass and refreshes the server first. |
122
+
123
+ ### Managed packages
124
+
125
+ For dedicated and retained legacy daemon installations:
126
+
127
+ - lifecycle commands use the selected daemon package, regardless of the invoking
128
+ CLI version; they do not implicitly replace an existing package
129
+ - `bootstrap` is supported
130
+ - managed `start`, `restart`, and `bootstrap` ensure a single detached pid-backed
131
+ updater loop only when automatic updates are enabled for a stable latest-channel
132
+ release whose managed binary supports the updater command
133
+ - the installer records the latest-channel selection alongside `current`;
134
+ selecting an explicit release clears it, even if that version is currently
135
+ latest. The updater checks the selection again while holding the install lock
136
+ so an in-flight update cannot override a new pin
137
+ - installs made before the installer recorded channel selections need one new
138
+ `latest` installation to opt into automatic updates; until then the daemon
139
+ continues to serve app-server without updating the selected release
140
+ - after a successful refresh, if app-server is running and the managed binary
141
+ contents changed, the updater restarts app-server with that binary first and
142
+ only then replaces its own process image
143
+ - the updater loop is not reboot-persistent; a managed start after reboot
144
+ starts it again
145
+
146
+ ### Out-of-band updates
147
+
148
+ This daemon does not watch arbitrary executable files for replacement. If some
149
+ other tool updates the managed binary path:
150
+
151
+ - an updater that was already running notices a changed managed
152
+ binary on its next successful scheduled installer pass; if
153
+ app-server is running, it refreshes app-server first and then refreshes itself
154
+ once that replacement starts successfully
155
+ - if the updater was absent during a same-version binary replacement, a later
156
+ managed start recovers it but cannot infer the running server's previous
157
+ executable identity; use `codex app-server daemon restart` to refresh the server
158
+
159
+ ## Lifecycle semantics
160
+
161
+ `start` is idempotent and returns after app-server is ready to answer the normal
162
+ JSON-RPC initialize handshake on the Unix control socket.
163
+
164
+ `restart` stops any managed daemon and starts it again.
165
+
166
+ `enable-remote-control` and `disable-remote-control` persist the launch setting
167
+ for future starts. If a managed app-server is already running, they restart it
168
+ so the new setting takes effect immediately.
169
+
170
+ Top-level `codex remote-control start` enables and persists remote control for
171
+ the managed daemon, overriding a saved disabled value. It starts or bootstraps
172
+ the daemon as needed. Plain `codex remote-control` runs a separate foreground
173
+ server and does not change daemon settings; `codex remote-control stop` stops
174
+ the managed daemon without clearing its saved remote-control preference.
175
+ `daemon start` and `daemon restart` use that saved preference. `daemon bootstrap`
176
+ sets it according to `--remote-control` (disabled when omitted).
177
+
178
+ `stop` sends a graceful termination request first, then force-terminates the
179
+ process after the configured grace window if it is still alive.
180
+
181
+ All mutating lifecycle commands are serialized per `CODEX_HOME`, so a concurrent
182
+ `start`, `restart`, `enable-remote-control`, `disable-remote-control`, `stop`,
183
+ or `bootstrap` does not race another in-flight lifecycle operation.
184
+
185
+ ## State
186
+
187
+ The daemon stores its local state under `CODEX_HOME/app-server-daemon/`:
188
+
189
+ - `settings.json` for remote-control launch settings and updater preferences
190
+ - `app-server.pid` for the app-server process record
191
+ - `app-server-updater.pid` for the pid-backed standalone updater loop
192
+ - `daemon.lock` for daemon-wide lifecycle serialization
codex-rs/app-server-protocol-noop-macros/BUILD.bazel ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "app-server-protocol-noop-macros",
5
+ crate_name = "codex_app_server_protocol_noop_macros",
6
+ proc_macro = True,
7
+ )
codex-rs/app-server-protocol-noop-macros/Cargo.toml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "codex-app-server-protocol-noop-macros"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+
7
+ [lib]
8
+ proc-macro = true
9
+ test = false
10
+ doctest = false
11
+
12
+ [lints]
13
+ workspace = true
codex-rs/app-server-protocol/BUILD.bazel ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "app-server-protocol",
5
+ compile_data = glob(["schema/precomputed/**"]),
6
+ crate_name = "codex_app_server_protocol",
7
+ test_data_extra = glob(
8
+ ["schema/**"],
9
+ allow_empty = True,
10
+ ),
11
+ )
12
+
13
+ alias(
14
+ name = "schema-generator",
15
+ testonly = True,
16
+ actual = ":app-server-protocol-unit-tests-bin",
17
+ tags = ["manual"],
18
+ visibility = ["//bazel/schema:__pkg__"],
19
+ )
codex-rs/app-server-protocol/Cargo.toml ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "codex-app-server-protocol"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+
7
+ [lib]
8
+ name = "codex_app_server_protocol"
9
+ path = "src/lib.rs"
10
+ doctest = false
11
+
12
+ [lints]
13
+ workspace = true
14
+
15
+ [dependencies]
16
+ anyhow = { workspace = true }
17
+ codex-experimental-api-macros = { workspace = true }
18
+ codex-app-server-protocol-noop-macros = { workspace = true }
19
+ codex-extension-items = { workspace = true }
20
+ codex-history = { workspace = true }
21
+ codex-protocol = { workspace = true }
22
+ codex-rollout = { workspace = true }
23
+ codex-secrets = { workspace = true }
24
+ codex-shell-command = { workspace = true }
25
+ codex-utils-absolute-path = { workspace = true }
26
+ codex-utils-path-uri = { workspace = true }
27
+ codex-utils-redacted-string = { workspace = true }
28
+ serde = { workspace = true, features = ["derive"] }
29
+ serde_json = { workspace = true }
30
+ serde_with = { workspace = true }
31
+ strum_macros = { workspace = true }
32
+ thiserror = { workspace = true }
33
+ rmcp = { workspace = true, default-features = false, features = [
34
+ "base64",
35
+ "macros",
36
+ "server",
37
+ ] }
38
+ inventory = { workspace = true }
39
+ tracing = { workspace = true }
40
+ uuid = { workspace = true, features = ["serde", "v7"] }
41
+ zstd = { workspace = true }
42
+
43
+ [dev-dependencies]
44
+ anyhow = { workspace = true }
45
+ codex-utils-cargo-bin = { workspace = true }
46
+ pretty_assertions = { workspace = true }
47
+ rmcp = { workspace = true, default-features = false, features = [
48
+ "base64",
49
+ "macros",
50
+ "schemars",
51
+ "server",
52
+ ] }
53
+ schemars = { workspace = true }
54
+ similar = { workspace = true }
55
+ tempfile = { workspace = true }
56
+ ts-rs = { workspace = true }
codex-rs/app-server-test-client/BUILD.bazel ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "app-server-test-client",
5
+ crate_name = "codex_app_server_test_client",
6
+ )
codex-rs/app-server-test-client/Cargo.toml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "codex-app-server-test-client"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+
7
+ [lints]
8
+ workspace = true
9
+
10
+ [dependencies]
11
+ anyhow = { workspace = true }
12
+ clap = { workspace = true, features = ["derive", "env"] }
13
+ codex-app-server-protocol = { workspace = true }
14
+ codex-core = { workspace = true }
15
+ codex-otel = { workspace = true }
16
+ codex-protocol = { workspace = true }
17
+ codex-utils-cli = { workspace = true }
18
+ serde = { workspace = true, features = ["derive"] }
19
+ serde_json = { workspace = true }
20
+ tokio = { workspace = true, features = ["rt"] }
21
+ tracing = { workspace = true }
22
+ tracing-subscriber = { workspace = true }
23
+ tungstenite = { workspace = true }
24
+ url = { workspace = true }
25
+ uuid = { workspace = true, features = ["v4"] }
26
+
27
+ [lib]
28
+ doctest = false
29
+
30
+ [dev-dependencies]
31
+ pretty_assertions = { workspace = true }
codex-rs/app-server-test-client/README.md ADDED
@@ -0,0 +1,184 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # App Server Test Client
2
+ Quickstart for running and hitting `codex app-server`.
3
+
4
+ ## Quickstart
5
+
6
+ Run from `<reporoot>/codex-rs`.
7
+
8
+ ```bash
9
+ # 1) Build debug codex binary
10
+ cargo build -p codex-cli --bin codex
11
+
12
+ # 2) Start websocket app-server in background
13
+ cargo run -p codex-app-server-test-client -- \
14
+ --codex-bin ./target/debug/codex \
15
+ serve --listen ws://127.0.0.1:4222 --kill
16
+
17
+ # 3) Call app-server (defaults to ws://127.0.0.1:4222)
18
+ cargo run -p codex-app-server-test-client -- model-list
19
+ ```
20
+
21
+ `send-message` and `send-message-v2` handle `request_user_input` server requests interactively.
22
+ When Codex asks a question, choose a numbered option (or `o` for a free-form answer when offered)
23
+ and the client will send the response and continue streaming the same turn.
24
+
25
+ ## Testing Codex-managed Amazon Bedrock login
26
+
27
+ `test-login --amazon-bedrock` initializes the experimental app-server API, sends an
28
+ `account/login/start` request with an Amazon Bedrock API key, and waits for the
29
+ `account/login/completed` and `account/updated` notifications. Login replaces the current primary
30
+ credential and sets `model_provider = "amazon-bedrock"`, so use an isolated `CODEX_HOME` when
31
+ testing.
32
+
33
+ ```bash
34
+ export CODEX_HOME="$(mktemp -d)"
35
+ printf 'cli_auth_credentials_store = "file"\n' > "$CODEX_HOME/config.toml"
36
+
37
+ cargo build -p codex-cli --bin codex
38
+ cargo run -p codex-app-server-test-client -- \
39
+ --codex-bin ./target/debug/codex \
40
+ test-login \
41
+ --amazon-bedrock \
42
+ --api-key "<BEDROCK_API_KEY>" \
43
+ --region us-west-2
44
+ ```
45
+
46
+ The test client redacts `apiKey` from its outbound request log. After login, start a fresh Codex
47
+ process with the same `CODEX_HOME` to verify that it uses the persisted managed credential.
48
+
49
+ ## Testing logout
50
+
51
+ `test-logout` initializes the app-server, sends an `account/logout` request, and waits for the
52
+ resulting `account/updated` notification. It uses the active `CODEX_HOME`, so point it at an
53
+ isolated directory when testing credential cleanup.
54
+
55
+ ```bash
56
+ cargo run -p codex-app-server-test-client -- \
57
+ --codex-bin ./target/debug/codex \
58
+ test-logout
59
+ ```
60
+
61
+ ## Testing Plugin Analytics
62
+
63
+ The `plugin-analytics-smoke` command exercises `plugin/installed`, plugin
64
+ enable/disable config writes, and a structured plugin mention through one
65
+ app-server connection. Analytics are captured to a local JSONL file and are
66
+ not sent to the analytics backend. The model turn uses a loopback Responses
67
+ API server.
68
+
69
+ The selected plugin must already be installed and enabled remotely, and the
70
+ active Codex profile must be authenticated. On a fresh local cache, the command
71
+ retries ephemeral turns while the installed remote bundle finishes syncing.
72
+
73
+ ```bash
74
+ # Build a debug Codex binary; analytics capture is unavailable in release builds.
75
+ cargo build -p codex-cli --bin codex
76
+
77
+ cargo run -p codex-app-server-test-client -- \
78
+ --codex-bin ./target/debug/codex \
79
+ plugin-analytics-smoke \
80
+ --plugin-id linear@openai-curated-remote
81
+ ```
82
+
83
+ Use `--capture-file /tmp/plugin-analytics.jsonl` to select the output path.
84
+ The command validates one `codex_plugin_disabled`, `codex_plugin_enabled`, and
85
+ `codex_plugin_used` event with the expected local and remote plugin identities
86
+ and capability metadata. Each event includes the local ID in `plugin_id` and the
87
+ backend ID in `remote_plugin_id`. The enabled and disabled events come from
88
+ successful writes to the temporary config; the command does not mutate the
89
+ remote enabled state. It prints the events and leaves the JSONL file in place
90
+ for inspection. It does not install or uninstall plugins and does not modify
91
+ the profile's persistent config.
92
+
93
+ ### Testing remote install and uninstall analytics
94
+
95
+ `plugin-analytics-mutation-smoke` is a manually invoked live smoke test. It
96
+ contacts the configured remote plugin API and temporarily changes the active
97
+ account's installed-plugin state. It is not run by `cargo test`, `just test`,
98
+ or CI.
99
+
100
+ Choose a remote plugin that is available to the active account and is not
101
+ currently installed. The command refuses to run when the plugin is already
102
+ installed, installs it, validates `codex_plugin_installed`, uninstalls it, and
103
+ validates `codex_plugin_uninstalled`, and verifies that the original
104
+ uninstalled state was restored.
105
+
106
+ The mutation events include the local Codex ID in `plugin_id` and the backend ID
107
+ in `remote_plugin_id`.
108
+
109
+ `--remote-plugin-id` takes the backend ID, such as `plugins~Plugin_...`, not the
110
+ local `<plugin>@<marketplace>` ID.
111
+
112
+ ```bash
113
+ cargo run -p codex-app-server-test-client -- \
114
+ --codex-bin ./target/debug/codex \
115
+ plugin-analytics-mutation-smoke \
116
+ --remote-plugin-id <REMOTE_PLUGIN_ID> \
117
+ --confirm-account-mutation \
118
+ --capture-file /tmp/plugin-mutation-analytics.jsonl
119
+ ```
120
+
121
+ Analytics use the normal queue, reduction, batching, and serialization path,
122
+ but the debug capture destination suppresses analytics network delivery. The
123
+ command prints one of these final states:
124
+
125
+ - `PASS`: the install and uninstall events validated and the plugin is uninstalled.
126
+ - `FAIL-CLEAN`: validation failed, but the original uninstalled state was
127
+ restored.
128
+ - `FAIL-LOCAL-CACHE`: the backend is uninstalled, but local cleanup reported
129
+ an error.
130
+ - `FAIL-DIRTY`: cleanup failed and the plugin still appears installed.
131
+ - `FAIL-UNKNOWN`: the command could not verify the final installed state.
132
+
133
+ For a dirty or uncertain result, retry cleanup with:
134
+
135
+ ```bash
136
+ cargo run -p codex-app-server-test-client -- \
137
+ --codex-bin ./target/debug/codex \
138
+ plugin-remote-uninstall \
139
+ --remote-plugin-id <REMOTE_PLUGIN_ID> \
140
+ --confirm-account-mutation
141
+ ```
142
+
143
+ Cleanup does not require analytics capture or a debug Codex binary. When the
144
+ smoke uses global `--config` overrides, its printed recovery command preserves
145
+ them so cleanup targets the same backend and account.
146
+
147
+ ## Watching Raw Inbound Traffic
148
+
149
+ Initialize a connection, then print every inbound JSON-RPC message until you stop it with
150
+ `Ctrl+C`:
151
+
152
+ ```bash
153
+ cargo run -p codex-app-server-test-client -- watch
154
+ ```
155
+
156
+ ## Testing Thread Rejoin Behavior
157
+
158
+ Build and start an app server using commands above. The app-server log is written to `/tmp/codex-app-server-test-client/app-server.log`
159
+
160
+ ### 1) Get a thread id
161
+
162
+ Create at least one thread, then list threads:
163
+
164
+ ```bash
165
+ cargo run -p codex-app-server-test-client -- send-message-v2 "seed thread for rejoin test"
166
+ cargo run -p codex-app-server-test-client -- thread-list --limit 5
167
+ ```
168
+
169
+ Copy a thread id from the `thread-list` output.
170
+
171
+ ### 2) Rejoin while a turn is in progress (two terminals)
172
+
173
+ Terminal A:
174
+
175
+ ```bash
176
+ cargo run --bin codex-app-server-test-client -- \
177
+ resume-message-v2 <THREAD_ID> "respond with thorough docs on the rust core"
178
+ ```
179
+
180
+ Terminal B (while Terminal A is still streaming):
181
+
182
+ ```bash
183
+ cargo run --bin codex-app-server-test-client -- thread-resume <THREAD_ID>
184
+ ```
codex-rs/app-server/BUILD.bazel ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "app-server",
5
+ crate_name = "codex_app_server",
6
+ extra_binaries = [
7
+ "//codex-rs/bwrap:bwrap",
8
+ "//codex-rs/code-mode-host:codex-code-mode-host",
9
+ "//codex-rs/rmcp-client:test_stdio_server",
10
+ ],
11
+ extra_binaries_non_windows = [
12
+ "//codex-rs/cli:codex",
13
+ ],
14
+ integration_test_timeout = "long",
15
+ run_tests_with_wine_exec = True,
16
+ test_shard_counts = {
17
+ # Note app-server-all-test has a large number of integration tests, so
18
+ # even a single shard can be quite slow. When there is a legitimate
19
+ # test failure in a shard, it will still get run 3x in total, which
20
+ # can cause us to exhaust our CI timeout if the shard happens to run
21
+ # long. Using a higher shard count for app-server-all-test should help
22
+ # mitigate this risk.
23
+ "app-server-all-test": 16,
24
+ "app-server-unit-tests": 8,
25
+ },
26
+ test_tags = ["no-sandbox"],
27
+ test_threads = select({
28
+ "@platforms//os:macos": 1,
29
+ "//conditions:default": 0,
30
+ }),
31
+ )
codex-rs/app-server/Cargo.toml ADDED
@@ -0,0 +1,155 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "codex-app-server"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+
7
+ [[bin]]
8
+ name = "codex-app-server"
9
+ path = "src/main.rs"
10
+
11
+ [[bin]]
12
+ name = "codex-app-server-test-notify-capture"
13
+ path = "src/bin/notify_capture.rs"
14
+
15
+ [[bin]]
16
+ name = "exec-server"
17
+ path = "src/bin/exec_server.rs"
18
+
19
+ [lib]
20
+ name = "codex_app_server"
21
+ path = "src/lib.rs"
22
+ doctest = false
23
+
24
+ [lints]
25
+ workspace = true
26
+
27
+ [dependencies]
28
+ anyhow = { workspace = true }
29
+ base64 = { workspace = true }
30
+ axum = { workspace = true, default-features = false, features = [
31
+ "http1",
32
+ "json",
33
+ "tokio",
34
+ "ws",
35
+ ] }
36
+ codex-analytics = { workspace = true }
37
+ codex-agent-extension = { workspace = true }
38
+ codex-arg0 = { workspace = true }
39
+ codex-aws-auth = { workspace = true }
40
+ codex-cloud-config = { workspace = true }
41
+ codex-code-mode = { workspace = true }
42
+ codex-config = { workspace = true }
43
+ codex-network-proxy = { workspace = true }
44
+ codex-connectors = { workspace = true }
45
+ codex-core = { workspace = true }
46
+ codex-core-plugins = { workspace = true }
47
+ codex-diagnostics = { workspace = true }
48
+ codex-home = { workspace = true }
49
+ codex-exec-server = { workspace = true }
50
+ codex-extension-api = { workspace = true }
51
+ codex-external-agent-migration = { workspace = true }
52
+ codex-features = { workspace = true }
53
+ codex-goal-extension = { workspace = true }
54
+ codex-git-attribution = { workspace = true }
55
+ codex-guardian-v2 = { workspace = true }
56
+ codex-git-utils = { workspace = true }
57
+ codex-file-watcher = { workspace = true }
58
+ codex-hooks = { workspace = true }
59
+ codex-history-notes-extension = { workspace = true }
60
+ codex-http-client = { workspace = true }
61
+ codex-otel = { workspace = true }
62
+ codex-plugin = { workspace = true }
63
+ codex-shell-command = { workspace = true }
64
+ codex-skills = { workspace = true }
65
+ codex-skills-extension = { workspace = true }
66
+ codex-utils-cli = { workspace = true }
67
+ codex-user-verification = { workspace = true }
68
+ codex-utils-pty = { workspace = true }
69
+ codex-backend-client = { workspace = true }
70
+ codex-file-search = { workspace = true }
71
+ codex-chatgpt = { workspace = true }
72
+ codex-login = { workspace = true }
73
+ codex-image-generation-extension = { workspace = true }
74
+ codex-memories-extension = { workspace = true }
75
+ codex-web-search-extension = { workspace = true }
76
+ codex-memories-write = { workspace = true }
77
+ codex-mcp = { workspace = true }
78
+ codex-mcp-extension = { workspace = true }
79
+ codex-model-provider = { workspace = true }
80
+ codex-model-provider-info = { workspace = true }
81
+ codex-models-manager = { workspace = true }
82
+ codex-protocol = { workspace = true }
83
+ codex-queue-extension = { workspace = true }
84
+ codex-app-server-protocol = { workspace = true }
85
+ codex-app-server-transport = { workspace = true }
86
+ codex-feedback = { workspace = true }
87
+ codex-rmcp-client = { workspace = true }
88
+ codex-rollout = { workspace = true }
89
+ codex-sandboxing = { workspace = true }
90
+ codex-state = { workspace = true }
91
+ codex-thread-store = { workspace = true }
92
+ codex-tools = { workspace = true }
93
+ codex-utils-absolute-path = { workspace = true }
94
+ codex-utils-json-to-toml = { workspace = true }
95
+ codex-utils-path-uri = { workspace = true }
96
+ chrono = { workspace = true }
97
+ clap = { workspace = true, features = ["derive"] }
98
+ futures = { workspace = true }
99
+ serde = { workspace = true, features = ["derive"] }
100
+ serde_json = { workspace = true }
101
+ sha2 = { workspace = true }
102
+ tempfile = { workspace = true }
103
+ thiserror = { workspace = true }
104
+ time = { workspace = true }
105
+ toml = { workspace = true }
106
+ toml_edit = { workspace = true }
107
+ tokio = { workspace = true, features = [
108
+ "io-std",
109
+ "macros",
110
+ "process",
111
+ "rt-multi-thread",
112
+ "signal",
113
+ ] }
114
+ tokio-util = { workspace = true }
115
+ tracing = { workspace = true, features = ["log"] }
116
+ tracing-subscriber = { workspace = true, features = ["env-filter", "fmt", "json"] }
117
+ url = { workspace = true }
118
+ uuid = { workspace = true, features = ["serde", "v7"] }
119
+
120
+ [target.'cfg(all(target_os = "linux", target_env = "musl", any(target_arch = "x86_64", target_arch = "aarch64")))'.dependencies]
121
+ tikv-jemallocator = { workspace = true }
122
+
123
+ [target.'cfg(windows)'.dependencies]
124
+ codex-windows-sandbox = { workspace = true }
125
+
126
+ [dev-dependencies]
127
+ codex-uds = { workspace = true }
128
+ app_test_support = { workspace = true }
129
+ axum = { workspace = true, default-features = false, features = [
130
+ "http1",
131
+ "json",
132
+ "tokio",
133
+ ] }
134
+ base64 = { workspace = true }
135
+ codex-utils-cargo-bin = { workspace = true }
136
+ core_test_support = { workspace = true }
137
+ flate2 = { workspace = true }
138
+ hmac = { workspace = true }
139
+ http = { workspace = true }
140
+ opentelemetry = { workspace = true }
141
+ opentelemetry_sdk = { workspace = true }
142
+ pretty_assertions = { workspace = true }
143
+ rmcp = { workspace = true, default-features = false, features = [
144
+ "elicitation",
145
+ "server",
146
+ "transport-streamable-http-server",
147
+ ] }
148
+ serial_test = { workspace = true }
149
+ shlex = { workspace = true }
150
+ sqlx = { workspace = true }
151
+ tar = { workspace = true }
152
+ test-case = "3.3.1"
153
+ tokio-tungstenite = { workspace = true }
154
+ tracing-opentelemetry = { workspace = true }
155
+ wiremock = { workspace = true }
codex-rs/app-server/README.md ADDED
@@ -0,0 +1,285 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # MCP App UI
2
+
3
+ `mcpToolCall.mcpAppUi` records the invoked descriptor's `resourceUri`
4
+ and `preferredModelDisplayMode` (`inline` or `fullscreen`). Descriptors with a widget
5
+ URI default to `inline` when the preference is missing or unsupported. The
6
+ UI information is preserved in tool-call events and saved history so clients can
7
+ render without waiting for the full MCP catalog.
8
+
9
+ The field is null for older history and tools that declare widgets only in
10
+ result metadata; clients retain catalog discovery for those calls. Existing
11
+ resource URI fields remain available for older clients.
12
+
13
+ # Initial Daybreak choice (experimental)
14
+
15
+ Persistent threads accept `daybreakEnabled` on `thread/start` with the
16
+ `experimentalApi` opt-in. The response and `thread/started` notification both
17
+ include the initial choice in `thread.daybreakEnabled`. The choice is staged
18
+ with the thread's other initial metadata and saved when the thread is persisted.
19
+ An unused thread is not guaranteed to survive restart. Omitted or null leaves
20
+ the choice unset. Ephemeral threads cannot save it.
21
+ Use `thread/metadata/update` for later changes. This preference does not select
22
+ `turn/start.cyberAccessProgram` or grant access to an access program.
23
+
24
+ # User verification cancellation (experimental)
25
+
26
+ Local UI clients can cancel a native user-verification RPC by sending
27
+ `userVerification/cancel` with `{requestId}` and the `experimentalApi` opt-in.
28
+ The result is an empty acknowledgment (`{}`). This API does not enable desktop
29
+ verification capability advertisement.
30
+
31
+ `requestId` is the original status, enroll, delete, or verify RPC's string or
32
+ integer ID on the same connection, not the server elicitation ID. Use fresh IDs
33
+ for each operation and a distinct ID for the cancel RPC. Unknown, finished,
34
+ unrelated, and other-connection requests are no-ops.
35
+
36
+ The acknowledgment confirms the cancellation signal without waiting for the OS
37
+ prompt to close. The original RPC completes independently, with
38
+ `cancelled/interrupted` when cancellation prevents completion. Cancellation
39
+ cannot roll back completed effects. It remains effective while a proof waits for
40
+ outbound queue capacity, but cannot retract a response already enqueued.
41
+
42
+ Canceling or resolving an elicitation does not itself stop a separate
43
+ `userVerification/verify` RPC. Clients must cancel that RPC separately and discard
44
+ late proofs after the approval is canceled or resolved. Only one native worker
45
+ runs per app-server; if an OS call remains active after cancellation or timeout,
46
+ subsequent local operations return `failed/providerError` until that worker exits.
47
+
48
+ # Hosted Codex Apps MCP protocol
49
+
50
+ The host-owned HTTP `codex_apps` server uses Legacy by default in app-server and
51
+ standalone Codex. To discover the 2026-07-28 protocol, set
52
+ `codex_apps_mcp_2026_07_28 = true` under `[features]`, or send a true runtime
53
+ override via `experimentalFeature/enablement/set`. Discovery falls back to Legacy
54
+ when the server does not support it. Explicit config takes precedence.
55
+ The dedicated setting does not apply to third-party HTTP or local `codex_app`
56
+ stdio servers. The existing `mcp_2026_07_28` flag still governs eligible other
57
+ servers, regardless of whether their names or URLs resemble hosted Apps.
58
+ App-server does not persist this selection.
59
+
60
+ # Thread removal
61
+
62
+ `thread/archive` and `thread/delete` reject attempts to remove a live internal
63
+ worker with JSON-RPC error `-32600`. The worker's owner controls its shutdown.
64
+ For example, a Guardian reviewer remains available to its parent conversation
65
+ after a client tries to archive or delete it.
66
+
67
+ After the owner releases the worker, its saved conversation can be archived or
68
+ deleted normally. Ordinary client-controlled threads keep their existing behavior.
69
+
70
+ ## User verification (experimental)
71
+
72
+ Codex app-server advertises `openai/elicitation.userVerification` to the
73
+ host-owned plugin service for bundled, in-process TUI sessions (`codex-tui`) and
74
+ local stdio desktop sessions (`Codex Desktop`) on devices with supported biometric
75
+ hardware and the `experimentalApi` opt-in. This is an app-server decision,
76
+ independent of whether a key exists; TUI/Desktop/mobile do not advertise this MCP
77
+ capability. Mobile integration requires a separate rollout. Other clients and
78
+ network connections do not receive this mode, even with a recognized client name.
79
+ Before sending verification requests to desktop sessions, deploy a GUI that
80
+ handles the typed verification request, cancellation, and late proofs. The general
81
+ `experimentalApi` opt-in does not identify a compatible GUI version.
82
+
83
+ Local UI clients use five methods. They require the existing
84
+ `experimentalApi` opt-in. The local provider reports
85
+ `unavailable/providerUnavailable` on unsupported platforms or without the required
86
+ ChatGPT account identity.
87
+
88
+ | Method | Params | Result |
89
+ | --- | --- | --- |
90
+ | `userVerification/status` | `{}` | `{credentialId, unavailableReason, unavailableMessage}` |
91
+ | `userVerification/enroll` | `{}` | `{credentialId, algorithm?, publicKey?}` |
92
+ | `userVerification/delete` | `{}` | `{}` |
93
+ | `userVerification/verify` | `{challenge, title, description}` | `{proof: {credentialId, signature}}` |
94
+ | `userVerification/cancel` | `{requestId}` | `{}` |
95
+
96
+ Status reads local readiness without prompting or contacting a backend. A null
97
+ `unavailableReason` means local checks passed, not that registration is valid.
98
+ Unsupported platforms and missing account identity are reported in the status
99
+ response's `unavailableReason` field.
100
+ Enrollment creates or reuses the local key and returns its public metadata. The
101
+ `publicKey` is unpadded base64url SPKI-DER; `algorithm` is `ecdsaP256Sha256X962`.
102
+ During the experimental rollout, `algorithm` and `publicKey` are optional for
103
+ compatibility with older app-servers. Current servers populate both fields;
104
+ callers must check that both are present and non-null before backend registration.
105
+ The trusted UI host owns backend registration: obtain an enrollment challenge,
106
+ sign it with `userVerification/verify`, check that the proof's `credentialId`
107
+ matches this response, and submit the public metadata and proof to the backend.
108
+ Local success is not server enrollment. The caller must preserve the authenticated
109
+ account across this flow and reconcile uncertain registration before retrying.
110
+ Deletion removes the local key; the caller owns backend revocation.
111
+ Enrollment and deletion coordinate credential lifecycle; callers do not issue
112
+ separate generate or rotate commands. Identity comes from the authenticated
113
+ account; this API exposes no caller-selected scope.
114
+
115
+ Verify signs 1–4096 decoded challenge bytes using P-256 ECDSA with SHA-256. The
116
+ challenge and DER signature use unpadded base64url. Title is 1–256 UTF-8 bytes;
117
+ description is at most 4096 bytes. The UI obtains approval for that display
118
+ context before calling. Verify does not require a pending elicitation; a UI with
119
+ its own authenticator can return proof directly in elicitation response content.
120
+ The calling flow owns pending-request checks and discards late proofs.
121
+ Native enroll, delete, and verify accept local stdio and in-process connections.
122
+ WebSocket and remote-control peers must use their own device authenticator;
123
+ status remains available for local readiness. Dropping an embedded RPC, disconnecting,
124
+ or changing authentication cancels its native operation. Responses recheck the
125
+ captured identity after waiting for outbound queue capacity.
126
+ Canceling or resolving an elicitation does not itself stop a separate
127
+ `userVerification/verify` RPC. The GUI must use `userVerification/cancel` to
128
+ cancel that RPC and discard late proofs when an approval is canceled or resolved.
129
+ See [User verification cancellation](#user-verification-cancellation-experimental)
130
+ for request ID and acknowledgment semantics.
131
+ Only one native worker runs per app-server. If an OS call remains active after
132
+ cancellation or timeout, subsequent local operations return `failed/providerError`
133
+ until that worker exits.
134
+
135
+ Failures use the normal JSON-RPC error envelope with closed `{type, reason}` data:
136
+ `invalidRequest`, `unavailable`, `cancelled`, or `failed`. UI clients branch on
137
+ these values rather than message text. Native diagnostic payloads stay private.
138
+
139
+ ## Managed model provider requirements
140
+
141
+ Existing threads retain their provider configuration. Input RPCs reject requests when managed
142
+ `model_provider` or `model_providers` requirements no longer match that configuration, or cannot
143
+ be loaded. This covers turn start/steer, review, compaction, manual queue start, and active goal
144
+ updates. Realtime connections use separate routing configuration and are not checked here.
145
+ Interrupt, realtime stop, and goal pause/clear remain available. User and project
146
+ configuration changes alone do not invalidate existing threads.
147
+
148
+ # Amazon Bedrock authentication
149
+
150
+ If `model_providers.amazon-bedrock.aws.credential_export` is configured, Bedrock setup and
151
+ Bedrock login return an error without changing configuration or saved credentials. Remove the
152
+ exporter configuration before selecting another credential source. `aws.credential_export` and
153
+ `aws.profile` cannot be configured together.
154
+
155
+ ## Stored thread attachments
156
+
157
+ - `thread/attachment/add` — add a durable resource reference to a stored thread without loading it. Repeated writes with the same attachment type and identity key return the existing attachment.
158
+ - `thread/attachment/list` — list attachments for one stored thread in a cursor-paginated request, including a thread that is not loaded.
159
+ - `thread/attachment/remove` — remove an attachment by its thread, attachment type, and identity key; returns `{}`.
160
+ - `thread/attachment/updated` — notification broadcast after an attachment is created or removed; contains the thread, attachment identity, attachment id, and operation.
161
+ ### Example: Manage stored thread attachments
162
+
163
+ Attachments record the resources currently associated with a thread, independently of conversation history. Clients can add, remove, and list attachments for one stored thread at a time without resuming those threads. Adding or removing an attachment does not create or delete the underlying resource or rewrite history. An attachment is idempotently identified by its thread, `attachmentType`, and `identityKey`. For pull requests, clients should reuse the canonical application identity `JSON.stringify([canonicalHostname, lowercaseOwner, lowercaseRepository, pullRequestNumber])` so addition and removal agree across surfaces.
164
+
165
+ ```json
166
+ { "method": "thread/attachment/add", "id": 20, "params": {
167
+ "threadId": "thr_123",
168
+ "attachmentType": "pull_request",
169
+ "identityKey": "[\"github.com\",\"openai\",\"codex\",123]",
170
+ "payload": { "url": "https://github.com/openai/codex/pull/123" }
171
+ } }
172
+ { "id": 20, "result": {
173
+ "outcome": "created",
174
+ "attachment": {
175
+ "id": "01984de2-8f74-7c91-a3b2-5c5e937cf318",
176
+ "attachmentType": "pull_request",
177
+ "identityKey": "[\"github.com\",\"openai\",\"codex\",123]",
178
+ "payload": { "url": "https://github.com/openai/codex/pull/123" },
179
+ "createdAt": 1750000000
180
+ }
181
+ } }
182
+
183
+ { "method": "thread/attachment/list", "id": 21, "params": {
184
+ "threadId": "thr_123",
185
+ "limit": 100
186
+ } }
187
+ { "id": 21, "result": {
188
+ "data": [{
189
+ "id": "01984de2-8f74-7c91-a3b2-5c5e937cf318",
190
+ "attachmentType": "pull_request",
191
+ "identityKey": "[\"github.com\",\"openai\",\"codex\",123]",
192
+ "payload": { "url": "https://github.com/openai/codex/pull/123" },
193
+ "createdAt": 1750000000
194
+ }],
195
+ "nextCursor": null
196
+ } }
197
+
198
+ { "method": "thread/attachment/remove", "id": 22, "params": {
199
+ "threadId": "thr_123",
200
+ "attachmentType": "pull_request",
201
+ "identityKey": "[\"github.com\",\"openai\",\"codex\",123]"
202
+ } }
203
+ { "id": 22, "result": {} }
204
+
205
+ { "method": "thread/attachment/updated", "params": {
206
+ "threadId": "thr_123",
207
+ "attachmentType": "pull_request",
208
+ "identityKey": "[\"github.com\",\"openai\",\"codex\",123]",
209
+ "attachmentId": "01984de2-8f74-7c91-a3b2-5c5e937cf318",
210
+ "operation": "deleted"
211
+ } }
212
+ ```
213
+
214
+ `thread/attachment/list` accepts one `threadId` and returns at most 100 attachments per page, ordered by creation time and attachment id. Continue with `nextCursor` and the same `threadId` until the cursor is `null`. Each thread can retain up to 100 attachments. Removing an attachment frees a slot for a new attachment.
215
+
216
+ A non-ephemeral fork copies the source thread's current attachments, even when forking at an earlier turn. The copies have new attachment IDs and creation timestamps, but retain the same resource identities and payloads. Clients use `forkedFromId` on `thread/started` to detect forks and call `thread/attachment/list` with the new thread ID to load their attachments. Fork copying does not emit per-attachment updates; explicit add/remove operations still do. Copying is awaited before publishing the fork, but is best effort: a copy failure is logged and the conversation fork succeeds without attachments. Membership can then change independently on either thread; the referenced resources themselves are not copied. Resuming a fork does not repeat the copy.
217
+
218
+ Attachment creation and deletion requests using the same thread ID are serialized across connections. The requesting client receives its response before the compact update is broadcast, and duplicate creates or absent deletes do not emit updates. Deleting the owning thread removes its attachments under the same lifecycle exclusion; queued attachment mutations then report that the thread was not found.
219
+
220
+ # Thread plugin settings
221
+
222
+ `thread/settings/update` and `turn/start` accept `disabledPluginIds`, a list of
223
+ `PluginSummary.id` values from `plugin/list`, in the
224
+ `<plugin-name>@<marketplace-name>` format. A supplied list replaces the selection;
225
+ omission or `null` preserves it, and `[]` clears it. Saving this selection does
226
+ not yet filter plugin capabilities.
227
+
228
+ Read the selection from `threadSettings.disabledPluginIds` in
229
+ `thread/settings/updated` notifications, or from `disabledPluginIds` in
230
+ `thread/start`, `thread/resume`, and `thread/fork` responses. Selections persist
231
+ across resume. Forks restore the selection from the history retained at the
232
+ requested fork boundary.
233
+
234
+ # Deprecated thread personality setting
235
+
236
+ `thread/start`, `thread/resume`, `thread/settings/update`, and `turn/start` still
237
+ accept `personality`, but `friendly` and `pragmatic` no longer select a style.
238
+ `model/list` returns `supportsPersonality: false` for every model.
239
+
240
+ `none` removes the literal `# Personality` section when Codex prepares
241
+ instructions from the model catalog, for example when starting a thread or
242
+ switching models. Setting `friendly` or `pragmatic` can replace a previous
243
+ `none` setting for that purpose. Changing the setting does not rewrite the
244
+ thread's existing instructions or change explicitly supplied base instructions.
245
+ The old `features.personality` flag is ignored.
246
+
247
+ # MCP server capabilities
248
+
249
+ `mcpServerStatus/list` returns `serverCapabilities` for each initialized MCP server
250
+ in both `full` and `toolsAndAuthOnly` detail modes, including thread-scoped reads.
251
+ This is the server's advertised MCP capabilities object, including its `extensions`
252
+ map. It is null when the connection has not initialized successfully; capabilities
253
+ are never inferred from tools or copied from a shared catalog cache.
254
+
255
+ # Thread rollback
256
+
257
+ `thread/rollback` has been removed from the API, including its request and response
258
+ types. Requests use the generic unknown-method rejection path. Use `thread/revert`
259
+ for paginated threads instead.
260
+
261
+ Existing rollouts may contain historical `ThreadRolledBack` events. Their replay
262
+ and migration remain supported so resuming, reading, and forking those threads
263
+ preserves the surviving history. This disk compatibility does not require restoring
264
+ support for new `thread/rollback` requests.
265
+
266
+ # Selected workspace routing
267
+
268
+ The experimental `account/read.workspaceRouting` response field returns the selected ChatGPT workspace's `chatgptAccountId`, resolved HTTPS `backendOrigin`, and backend-provided `accountRoutingOverride`. The routing value is `us`, `us_cr`, or the explicit `NO_CONSTRAINT` value. API-only and signed-out accounts return `null` and do not need `accounts/check`.
269
+
270
+ App-server discovers routing for saved ChatGPT logins at startup and for new logins or workspace switches. After requirements and routing are ready, it sends the existing `account/updated` notification. Newly initialized connections also receive this notification once saved-workspace routing is ready, including when discovery finished before the connection initialized. Clients then reread `configRequirements/read` and `account/read`. Saved ChatGPT credentials without a selected workspace ID retain their account information and return `workspaceRouting: null`; app-server does not guess a workspace from the backend's default account. Discovery failures for a selected workspace, including missing or null fields from older backends, return an `account/read` error. They never produce a successful unrestricted result. A later read retries failed discovery. Logout clears the cached routing, and results from earlier authentication owners are discarded. Token refreshes for the same known user and workspace invalidate cached routing without cancelling discovery or failing sign-in. Configuration is reloaded after discovery; a changed backend, model provider, or required backend rejects the result so the next read discovers against current configuration. Account notifications recheck the auth owner generation after waiting for outbound queue capacity. Superseded sign-in attempts emit a failed `account/login/completed` event instead of silently dropping completion. Notifications remain snapshots: clients reread current account and requirements state rather than treating a queued notification as authorization.
271
+
272
+ The origin of a required `chatgpt_base_url` must match the discovered origin by scheme, host, and effective port. The base URL's API path is not part of this comparison. Either origin alone is sufficient. If requirements specify no base URL and discovery explicitly returns `NO_CONSTRAINT`, the effective `chatgpt_base_url` supplies the origin, including its existing default. `backendOrigin` is always a resolved origin; `accountRoutingOverride` preserves `NO_CONSTRAINT` when the backend explicitly returns it. Discovering an origin does not change API paths or apply routing headers to requests.
273
+
274
+ ## Windows sandbox implementation selection
275
+
276
+ `windowsSandbox/setupStart` and `windowsSandbox/readiness` apply only to the
277
+ legacy `elevated` and `unelevated` backends. Clients resolve the desired sandbox
278
+ implementation from configuration. When it is `mxc`, they skip both methods;
279
+ `allowedWindowsSandboxImplementations` can allow `mxc` independently of the
280
+ legacy setup modes. Non-Windows hosts report `notConfigured` for the legacy
281
+ readiness API.
282
+
283
+ MXC uses the standard `command/exec` streaming and process-control path, including
284
+ ConPTY when `tty` is enabled. The buffered legacy Windows sandbox restrictions on
285
+ process control and custom output caps do not apply to MXC.
codex-rs/apply-patch/BUILD.bazel ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "apply-patch",
5
+ crate_name = "codex_apply_patch",
6
+ )
codex-rs/apply-patch/Cargo.toml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "codex-apply-patch"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+
7
+ [lib]
8
+ name = "codex_apply_patch"
9
+ path = "src/lib.rs"
10
+ doctest = false
11
+
12
+ [[bin]]
13
+ name = "apply_patch"
14
+ path = "src/main.rs"
15
+
16
+ [lints]
17
+ workspace = true
18
+
19
+ [dependencies]
20
+ anyhow = { workspace = true }
21
+ codex-exec-server = { workspace = true }
22
+ codex-utils-absolute-path = { workspace = true }
23
+ codex-utils-path-uri = { workspace = true }
24
+ similar = { workspace = true }
25
+ thiserror = { workspace = true }
26
+ tokio = { workspace = true, features = ["macros", "rt"] }
27
+ tree-sitter = { workspace = true }
28
+ tree-sitter-bash = { workspace = true }
29
+
30
+ [dev-dependencies]
31
+ assert_cmd = { workspace = true }
32
+ assert_matches = { workspace = true }
33
+ codex-utils-cargo-bin = { workspace = true }
34
+ pretty_assertions = { workspace = true }
35
+ tempfile = { workspace = true }
codex-rs/arg0/BUILD.bazel ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "arg0",
5
+ crate_name = "codex_arg0",
6
+ )
codex-rs/arg0/Cargo.toml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "codex-arg0"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+
7
+ [lib]
8
+ name = "codex_arg0"
9
+ path = "src/lib.rs"
10
+ doctest = false
11
+
12
+ [lints]
13
+ workspace = true
14
+
15
+ [dependencies]
16
+ anyhow = { workspace = true }
17
+ codex-apply-patch = { workspace = true }
18
+ codex-async-utils = { workspace = true }
19
+ codex-exec-server = { workspace = true }
20
+ codex-install-context = { workspace = true }
21
+ codex-linux-sandbox = { workspace = true }
22
+ codex-sandboxing = { workspace = true }
23
+ codex-shell-escalation = { workspace = true }
24
+ codex-utils-absolute-path = { workspace = true }
25
+ codex-utils-home-dir = { workspace = true }
26
+ dotenvy = { workspace = true }
27
+ tempfile = { workspace = true }
28
+ tokio = { workspace = true, features = ["rt-multi-thread"] }
29
+
30
+ [target.'cfg(windows)'.dependencies]
31
+ codex-windows-sandbox = { workspace = true }
32
+ pathdiff = { workspace = true }
33
+
34
+ [dev-dependencies]
35
+ pretty_assertions = { workspace = true }
codex-rs/async-utils/BUILD.bazel ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "async-utils",
5
+ crate_name = "codex_async_utils",
6
+ )
codex-rs/async-utils/Cargo.toml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "codex-async-utils"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+
7
+ [lints]
8
+ workspace = true
9
+
10
+ [dependencies]
11
+ tokio = { workspace = true, features = ["macros", "rt", "rt-multi-thread", "time"] }
12
+ tokio-util.workspace = true
13
+
14
+ [dev-dependencies]
15
+ pretty_assertions.workspace = true
16
+
17
+ [lib]
18
+ doctest = false
codex-rs/attachment-store/BUILD.bazel ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "attachment-store",
5
+ crate_name = "codex_attachment_store",
6
+ )
codex-rs/attachment-store/Cargo.toml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ edition.workspace = true
3
+ license.workspace = true
4
+ name = "codex-attachment-store"
5
+ version.workspace = true
6
+
7
+ [lib]
8
+ doctest = false
9
+ name = "codex_attachment_store"
10
+ path = "src/lib.rs"
11
+
12
+ [lints]
13
+ workspace = true
14
+
15
+ [dependencies]
16
+ serde = { workspace = true, features = ["derive"] }
17
+
18
+ [dev-dependencies]
19
+ pretty_assertions = { workspace = true }
20
+ tokio = { workspace = true, features = ["macros", "rt", "sync"] }
codex-rs/aws-auth/BUILD.bazel ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "aws-auth",
5
+ crate_name = "codex_aws_auth",
6
+ )
codex-rs/aws-auth/Cargo.toml ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ edition.workspace = true
3
+ license.workspace = true
4
+ name = "codex-aws-auth"
5
+ version.workspace = true
6
+
7
+ [lib]
8
+ doctest = false
9
+ name = "codex_aws_auth"
10
+ path = "src/lib.rs"
11
+
12
+ [lints]
13
+ workspace = true
14
+
15
+ [dependencies]
16
+ aws-config = { workspace = true, features = ["credentials-login"] }
17
+ aws-credential-types = { workspace = true }
18
+ aws-sigv4 = { workspace = true }
19
+ aws-types = { workspace = true }
20
+ bytes = { workspace = true }
21
+ http = { workspace = true }
22
+ thiserror = { workspace = true }
23
+
24
+ [dev-dependencies]
25
+ pretty_assertions = { workspace = true }
26
+ tokio = { workspace = true, features = ["macros", "rt-multi-thread"] }
codex-rs/backend-client/BUILD.bazel ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "backend-client",
5
+ compile_data = glob(["tests/fixtures/**"]),
6
+ crate_name = "codex_backend_client",
7
+ )
codex-rs/backend-client/Cargo.toml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "codex-backend-client"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+ publish = false
7
+
8
+ [lib]
9
+ path = "src/lib.rs"
10
+ doctest = false
11
+
12
+ [lints]
13
+ workspace = true
14
+
15
+ [dependencies]
16
+ anyhow = "1"
17
+ serde = { version = "1", features = ["derive"] }
18
+ serde_json = "1"
19
+ http = { workspace = true }
20
+ url = { workspace = true }
21
+ codex-backend-openapi-models = { path = "../codex-backend-openapi-models" }
22
+ codex-api = { workspace = true }
23
+ codex-http-client = { workspace = true }
24
+ codex-login = { workspace = true }
25
+ codex-model-provider = { workspace = true }
26
+ codex-protocol = { workspace = true }
27
+
28
+ [dev-dependencies]
29
+ pretty_assertions = "1"
30
+ tokio = { workspace = true, features = ["macros", "rt"] }
31
+ wiremock = { workspace = true }
codex-rs/build-info/BUILD.bazel ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "build-info",
5
+ crate_name = "codex_build_info",
6
+ )
codex-rs/build-info/Cargo.toml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ edition.workspace = true
3
+ license.workspace = true
4
+ name = "codex-build-info"
5
+ version.workspace = true
6
+
7
+ [lib]
8
+ doctest = false
9
+ name = "codex_build_info"
10
+ path = "src/lib.rs"
11
+
12
+ [lints]
13
+ workspace = true
14
+
15
+ [dependencies]
16
+ codex-install-context = { workspace = true }
17
+ semver = { workspace = true, features = ["serde"] }
18
+ serde = { workspace = true, features = ["derive"] }
19
+ sha2 = { workspace = true }
20
+
21
+ [dev-dependencies]
22
+ pretty_assertions = { workspace = true }
23
+ serde_json = { workspace = true }
24
+ tempfile = { workspace = true }
codex-rs/build-info/build.rs ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
 
1
+ //! Embed the compilation target, including its architecture and ABI.
2
+
3
+ fn main() -> Result<(), std::env::VarError> {
4
+ let target = std::env::var("TARGET")?;
5
+ println!("cargo:rustc-env=CODEX_BUILD_TARGET={target}");
6
+ println!("cargo:rerun-if-changed=build.rs");
7
+ Ok(())
8
+ }
codex-rs/chatgpt/BUILD.bazel ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "chatgpt",
5
+ crate_name = "codex_chatgpt",
6
+ )
codex-rs/chatgpt/Cargo.toml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "codex-chatgpt"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+
7
+ [lints]
8
+ workspace = true
9
+
10
+ [dependencies]
11
+ anyhow = { workspace = true }
12
+ clap = { workspace = true, features = ["derive"] }
13
+ codex-connectors = { workspace = true }
14
+ codex-core = { workspace = true }
15
+ codex-git-utils = { workspace = true }
16
+ codex-http-client = { workspace = true }
17
+ codex-login = { workspace = true }
18
+ codex-model-provider = { workspace = true }
19
+ codex-plugin = { workspace = true }
20
+ codex-utils-cli = { workspace = true }
21
+ serde = { workspace = true, features = ["derive"] }
22
+ tokio = { workspace = true, features = ["full"] }
23
+
24
+ [dev-dependencies]
25
+ codex-utils-cargo-bin = { workspace = true }
26
+ pretty_assertions = { workspace = true }
27
+ serde_json = { workspace = true }
28
+ tempfile = { workspace = true }
29
+
30
+ [lib]
31
+ doctest = false
codex-rs/chatgpt/README.md ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ # ChatGPT
2
+
3
+ This crate pertains to first party ChatGPT APIs and products such as Codex agent.
4
+
5
+ This crate is built and maintained by OpenAI employees. External code contributions are not accepted; please report bugs and request features in the [Codex issue tracker](https://github.com/openai/codex/issues).
codex-rs/cli/BUILD.bazel ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "MACOS_WEBRTC_RUSTC_LINK_FLAGS", "codex_rust_crate")
2
+ load("//bazel/platforms:release_binaries.bzl", "multiplatform_binaries")
3
+ load("//bazel/rules:e2e_benchmark.bzl", "codex_e2e_benchmark")
4
+
5
+ codex_rust_crate(
6
+ name = "cli",
7
+ binaries_with_build_commit = ["codex"],
8
+ crate_name = "codex_cli",
9
+ extra_binaries = [
10
+ "//codex-rs/bwrap:bwrap",
11
+ ],
12
+ rustc_flags_extra = MACOS_WEBRTC_RUSTC_LINK_FLAGS,
13
+ test_data_extra = glob(["src/**/snapshots/**"]),
14
+ )
15
+
16
+ multiplatform_binaries(
17
+ name = "codex",
18
+ )
19
+
20
+ codex_e2e_benchmark(
21
+ name = "codex-help",
22
+ binaries = [":codex"],
23
+ )
codex-rs/cli/Cargo.toml ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ name = "codex-cli"
3
+ version.workspace = true
4
+ edition.workspace = true
5
+ license.workspace = true
6
+ build = "build.rs"
7
+ default-run = "codex"
8
+
9
+ [[bin]]
10
+ name = "codex"
11
+ path = "src/main.rs"
12
+
13
+ [[bin]]
14
+ name = "logs_client"
15
+ path = "src/bin/logs_client.rs"
16
+
17
+ [lib]
18
+ name = "codex_cli"
19
+ path = "src/lib.rs"
20
+ doctest = false
21
+
22
+ [lints]
23
+ workspace = true
24
+
25
+ [dependencies]
26
+ anyhow = { workspace = true }
27
+ chrono = { workspace = true }
28
+ clap = { workspace = true, features = ["derive", "env"] }
29
+ clap_complete = { workspace = true }
30
+ codex-app-server = { workspace = true }
31
+ codex-app-server-daemon = { workspace = true }
32
+ codex-app-server-protocol = { workspace = true }
33
+ codex-app-server-test-client = { workspace = true }
34
+ codex-arg0 = { workspace = true }
35
+ codex-build-info = { workspace = true }
36
+ codex-api = { workspace = true }
37
+ codex-aws-auth = { workspace = true }
38
+ codex-chatgpt = { workspace = true }
39
+ codex-cloud-config = { workspace = true }
40
+ codex-cloud-tasks = { path = "../cloud-tasks" }
41
+ codex-utils-cli = { workspace = true }
42
+ codex-config = { workspace = true }
43
+ codex-core = { workspace = true }
44
+ codex-core-plugins = { workspace = true }
45
+ codex-history = { workspace = true }
46
+ codex-home = { workspace = true }
47
+ codex-http-client = { workspace = true }
48
+ codex-exec = { workspace = true }
49
+ codex-exec-server = { workspace = true }
50
+ codex-execpolicy = { workspace = true }
51
+ codex-extension-api = { workspace = true }
52
+ codex-features = { workspace = true }
53
+ codex-git-attribution = { workspace = true }
54
+ codex-git-utils = { workspace = true }
55
+ codex-install-context = { workspace = true }
56
+ codex-login = { workspace = true }
57
+ codex-memories-write = { workspace = true }
58
+ codex-mcp = { workspace = true }
59
+ codex-model-provider = { workspace = true }
60
+ codex-models-manager = { workspace = true }
61
+ codex-plugin = { workspace = true }
62
+ codex-protocol = { workspace = true }
63
+ codex-responses-api-proxy = { workspace = true }
64
+ codex-tcp-tunnel = { workspace = true }
65
+ codex-rmcp-client = { workspace = true }
66
+ codex-rollout = { workspace = true }
67
+ codex-rollout-trace = { workspace = true }
68
+ codex-sandboxing = { workspace = true }
69
+ codex-skills-extension = { workspace = true }
70
+ codex-state = { workspace = true }
71
+ codex-stdio-to-uds = { workspace = true }
72
+ codex-terminal-detection = { workspace = true }
73
+ codex-thread-store = { workspace = true }
74
+ codex-tui = { workspace = true }
75
+ codex-utils-absolute-path = { workspace = true }
76
+ codex-utils-path = { workspace = true }
77
+ codex-utils-path-uri = { workspace = true }
78
+ crossterm = { workspace = true, features = ["event-stream"] }
79
+ futures = { workspace = true }
80
+ http = { workspace = true }
81
+ libc = { workspace = true }
82
+ os_info = { workspace = true }
83
+ owo-colors = { workspace = true }
84
+ regex-lite = { workspace = true }
85
+ serde = { workspace = true, features = ["derive"] }
86
+ serde_json = { workspace = true }
87
+ supports-color = { workspace = true }
88
+ sys-locale = { workspace = true }
89
+ tempfile = { workspace = true }
90
+ tokio = { workspace = true, features = [
91
+ "io-std",
92
+ "macros",
93
+ "net",
94
+ "process",
95
+ "rt-multi-thread",
96
+ "signal",
97
+ "time",
98
+ ] }
99
+ toml = { workspace = true }
100
+ tracing = { workspace = true }
101
+ tracing-appender = { workspace = true }
102
+ tracing-subscriber = { workspace = true }
103
+ unicode-segmentation = { workspace = true }
104
+ url = { workspace = true }
105
+ which = { workspace = true }
106
+
107
+ [target.'cfg(all(target_os = "linux", target_env = "musl", any(target_arch = "x86_64", target_arch = "aarch64")))'.dependencies]
108
+ tikv-jemallocator = { workspace = true }
109
+
110
+ [target.'cfg(target_os = "windows")'.dependencies]
111
+ codex_windows_sandbox = { package = "codex-windows-sandbox", path = "../windows-sandbox-rs" }
112
+ windows-sys = { version = "0.52", features = [
113
+ "Win32_Foundation",
114
+ "Win32_Storage_Packaging_Appx",
115
+ "Win32_System_Console",
116
+ "Win32_System_Threading",
117
+ ] }
118
+
119
+ [dev-dependencies]
120
+ app_test_support = { workspace = true }
121
+ assert_cmd = { workspace = true }
122
+ assert_matches = { workspace = true }
123
+ codex-utils-cargo-bin = { workspace = true }
124
+ codex-utils-pty = { workspace = true }
125
+ flate2 = { workspace = true }
126
+ insta = { workspace = true }
127
+ predicates = { workspace = true }
128
+ pretty_assertions = { workspace = true }
129
+ sqlx = { workspace = true }
130
+ tar = { workspace = true }
131
+ tokio-tungstenite = { workspace = true }
132
+ wiremock = { workspace = true }
133
+ zstd = { workspace = true }
134
+
135
+ [package.metadata.cargo-shear]
136
+ # These Rust sources are intentionally Bazel-only macrobenchmarks rather than
137
+ # Cargo targets.
138
+ ignored-paths = ["e2e_benches/*.rs"]
codex-rs/cli/build.rs ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
 
1
+ fn main() {
2
+ if std::env::var("CARGO_CFG_TARGET_OS").as_deref() == Ok("macos") {
3
+ println!("cargo:rustc-link-arg=-ObjC");
4
+ }
5
+ }
codex-rs/cloud-tasks-client/BUILD.bazel ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "cloud-tasks-client",
5
+ crate_name = "codex_cloud_tasks_client",
6
+ )
codex-rs/cloud-tasks-client/Cargo.toml ADDED
@@ -0,0 +1,25 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ [package]
2
+ edition.workspace = true
3
+ license.workspace = true
4
+ name = "codex-cloud-tasks-client"
5
+ version.workspace = true
6
+
7
+ [lib]
8
+ name = "codex_cloud_tasks_client"
9
+ path = "src/lib.rs"
10
+ test = false
11
+ doctest = false
12
+
13
+ [lints]
14
+ workspace = true
15
+
16
+ [dependencies]
17
+ anyhow = { workspace = true }
18
+ chrono = { workspace = true, features = ["serde"] }
19
+ codex-api = { workspace = true }
20
+ codex-backend-client = { workspace = true }
21
+ codex-git-utils = { workspace = true }
22
+ codex-http-client = { workspace = true }
23
+ serde = { version = "1", features = ["derive"] }
24
+ serde_json = { workspace = true }
25
+ thiserror = { workspace = true }
codex-rs/cloud-tasks-mock-client/BUILD.bazel ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "cloud-tasks-mock-client",
5
+ crate_name = "codex_cloud_tasks_mock_client",
6
+ )
codex-rs/cloud-tasks-mock-client/Cargo.toml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ [package]
3
+ edition.workspace = true
4
+ license.workspace = true
5
+ name = "codex-cloud-tasks-mock-client"
6
+ version.workspace = true
7
+
8
+ [lib]
9
+ name = "codex_cloud_tasks_mock_client"
10
+ path = "src/lib.rs"
11
+ test = false
12
+ doctest = false
13
+
14
+ [lints]
15
+ workspace = true
16
+
17
+ [dependencies]
18
+ chrono = { workspace = true }
19
+ codex-cloud-tasks-client = { workspace = true }
20
+ diffy = { workspace = true }
codex-rs/cloud-tasks/BUILD.bazel ADDED
@@ -0,0 +1,7 @@
 
 
 
 
 
 
 
 
1
+ load("//:defs.bzl", "MACOS_WEBRTC_RUSTC_LINK_FLAGS", "codex_rust_crate")
2
+
3
+ codex_rust_crate(
4
+ name = "cloud-tasks",
5
+ crate_name = "codex_cloud_tasks",
6
+ rustc_flags_extra = MACOS_WEBRTC_RUSTC_LINK_FLAGS,
7
+ )