- Add conversation/thread fork endpoints in the protocol and app server so clients can branch a session into a new thread. (#8866)
- Expose requirements via `requirement/list` so clients can read `requirements.toml` and adjust agent-mode UX. (#8800)
- Introduce metrics capabilities with additional counters for observability. (#8318, #8910)
- Add elevated sandbox onboarding with prompts for upgrade/degraded mode plus the `/elevate-sandbox` command. (#8789)
- Allow explicit skill invocations through v2 API user input. (#8864)
## Bug Fixes
- `/review <instructions>` in TUI/TUI2 now launches the review flow instead of sending plain text. (#8823)
- Patch approval “allow this session” now sticks for previously approved files. (#8451)
- Model upgrade prompt now appears even if the current model is hidden from the picker. (#8802)
- Windows paste handling now supports non-ASCII multiline input reliably. (#8774)
- Git apply path parsing now handles quoted/escaped paths and `/dev/null` correctly to avoid misclassified changes. (#8824)
- Codex CLI subprocesses again inherit env vars like `LD_LIBRARY_PATH`/`DYLD_LIBRARY_PATH` to avoid runtime issues. (#8951)
## Documentation
- App-server README now documents skills support and usage. (#8853)
- Skill-creator docs clarify YAML frontmatter formatting and quoting rules. (#8610)
## Changelog
Full Changelog: https://github.com/openai/codex/compare/rust-v0.79.0...rust-v0.80.0
- #8734 fix: do not propose to add multiline commands to execpolicy @tibo-openai
- #8802 Enable model upgrade popup even when selected model is no longer in picker @charley-oai
- #8805 chore: stabilize core tool parallelism test @tibo-openai
- #8820 chore: silent just fmt @jif-oai
- #8824 fix: parse git apply paths correctly @tibo-openai
- #8823 fix: handle /review arguments in TUI @tibo-openai
- #8822 chore: rename unified exec sessions @jif-oai
- #8825 fix: handle early codex exec exit @tibo-openai
- #8830 chore: unify conversation with thread name @jif-oai
- #8840 Move tests below auth manager @pakrym-oai
- #8845 fix: upgrade lru crate to 0.16.3 @bolinfest
- #8763 Merge Modelfamily into modelinfo @aibrahim-oai
- #8842 remove unnecessary todos @aibrahim-oai
- #8846 Stop using AuthManager as the source of codex_home @pakrym-oai
- #8844 Fix app-server `write_models_cache` to treat models with less priority number as higher priority. @aibrahim-oai
- #8850 chore: drop useless feature flags @jif-oai
- #8848 chore: drop some deprecated @jif-oai
- #8853 [chore] update app server doc with skills @celia-oai
- #8451 fix: implement 'Allow this session' for apply_patch approvals @owenlin0
- #8856 Override truncation policy at model info level @aibrahim-oai
- #8849 Simplify error managment in `run_turn` @aibrahim-oai
- #8767 Add feature for optional request compression @cconger
- #8610 Clarify YAML frontmatter formatting in skill-creator @darlingm
- #8847 Warn in /model if BASE_URL set @gt-oai
- #8801 Support symlink for skills discovery. @xl-openai
- #8800 Feat: appServer.requirementList for requirement.toml @shijie-oai
- #8861 fix: update resource path resolution logic so it works with Bazel @bolinfest
- #8868 fix: use tokio for I/O in an async function @bolinfest
- #8867 add footer note to TUI @iceweasel-oai
- #8879 feat: introduce find_resource! macro that works with Cargo or Bazel @bolinfest
- #8864 Support UserInput::Skill in V2 API. @xl-openai
- #8876 add ability to disable input temporarily in the TUI. @iceweasel-oai
- #8884 fix: make the find_resource! macro responsible for the absolutize() call @bolinfest
- #8774 fix: windows can now paste non-ascii multiline text @dylan-hurd-oai
- #8855 chore: add list thread ids on manager @jif-oai
- #8318 feat: metrics capabilities @jif-oai
- #8826 fix: stabilize list_dir pagination order @tibo-openai
- #8892 chore: drop metrics exporter config @jif-oai
- #8896 chore: align error limit comment @tibo-openai
- #8899 fix: include project instructions in /review subagent @tibo-openai
- #8894 chore: add small debug client @jif-oai
- #8888 fix: leverage find_resource! macro in load_sse_fixture_with_id @bolinfest
- #8691 Avoid setpgid for inherited stdio on macOS @seeekr
- #8887 fix: leverage codex_utils_cargo_bin() in codex-rs/core/tests/suite @bolinfest
- #8907 chore: drop useless interaction_input @jif-oai
- #8903 nit: drop unused function call error @jif-oai
- #8910 feat: add a few metrics @jif-oai
- #8911 gitignore bazel-* @zbarsky-openai
- #8843 config requirements: improve requirement error messages @gt-oai
- #8914 fix: reduce duplicate include_str!() calls @bolinfest
- #8902 feat: add list loaded threads to app server @jif-oai
- #8870 [fix] app server flaky thread/resume tests @celia-oai
- #8916 clean: all history cloning @jif-oai
- #8915 otel test: retry WouldBlock errors @gt-oai
- #8792 Update models.json @github-actions
- #8897 fix: preserve core env vars on Windows @tibo-openai
- #8913 Add `read-only` when backfilling requirements from managed_config @gt-oai
- #8926 add tooltip hint for shell commands (!) @fps7806
- #8857 Immutable CodexAuth @pakrym-oai
- #8927 nit: parse_arguments @jif-oai
- #8932 fix: increase timeout for tests that have been flaking with timeout issues @bolinfest
- #8931 fix: correct login shell mismatch in the accept_elicitation_for_prompt_rule() test @bolinfest
- #8874 [fix] app server flaky send_messages test @celia-oai
- #8866 feat: fork conversation/thread @apanasenko-oai
- #8858 remove `get_responses_requests` and `get_responses_request_bodies` to use in-place matcher @aibrahim-oai
- #8939 [chore] move app server tests from chat completion to responses @celia-oai
- #8880 Attempt to reload auth as a step in 401 recovery @pakrym-oai
- #8946 fix: increase timeout for wait_for_event() for Bazel @bolinfest
- #8789 Elevated sandbox NUX @iceweasel-oai
- #8917 fix: treat null MCP resource args as empty @tibo-openai
- #8942 Add 5s timeout to models list call + integration test @aibrahim-oai
- #8951 fix: remove existing process hardening from Codex CLI @bolinfest
As explained in https://github.com/openai/codex/issues/8945 and
https://github.com/openai/codex/issues/8472, there are legitimate cases
where users expect processes spawned by Codex to inherit environment
variables such as `LD_LIBRARY_PATH` and `DYLD_LIBRARY_PATH`, where
failing to do so can cause significant performance issues.
This PR removes the use of
`codex_process_hardening::pre_main_hardening()` in Codex CLI (which was
added not in response to a known security issue, but because it seemed
like a prudent thing to do from a security perspective:
https://github.com/openai/codex/pull/4521), but we will continue to use
it in `codex-responses-api-proxy`. At some point, we probably want to
introduce a slightly different version of
`codex_process_hardening::pre_main_hardening()` in Codex CLI that
excludes said environment variables from the Codex process itself, but
continues to propagate them to subprocesses.
Handle null tool arguments in the MCP resource handler so optional
resource tools accept null without failing, preserving normal JSON
parsing for non-null payloads and improving robustness when models emit
null; this avoids spurious argument parse errors for list/read MCP
resource calls.
Elevated Sandbox NUX:
* prompt for elevated sandbox setup when agent mode is selected (via
/approvals or at startup)
* prompt for degraded sandbox if elevated setup is declined or fails
* introduce /elevate-sandbox command to upgrade from degraded
experience.
This seems to be necessary to get the Bazel builds on ARM Linux to go
green on https://github.com/openai/codex/pull/8875.
I don't feel great about timeout-whack-a-mole, but we're still learning
here...
Fix flakiness of CI test:
https://github.com/openai/codex/actions/runs/20350530276/job/58473691434?pr=8282
This PR does two things:
1. move the flakiness test to use responses API instead of chat
completion API
2. make mcp_process agnostic to the order of
responses/notifications/requests that come in, by buffering messages not
read
I have seen this test flake out sometimes when running the macOS build
using Bazel in CI: https://github.com/openai/codex/pull/8875. Perhaps
Bazel runs with greater parallelism, inducing a heavier load, causing an
issue?
Historically we started with a CodexAuth that knew how to refresh it's
own tokens and then added AuthManager that did a different kind of
refresh (re-reading from disk).
I don't think it makes sense for both `CodexAuth` and `AuthManager` to
be mutable and contain behaviors.
Move all refresh logic into `AuthManager` and keep `CodexAuth` as a data
object.
This updates core shell environment policy handling to match Windows
case-insensitive variable names and adds a Windows-only regression test,
so Path/TEMP are no longer dropped when inherit=core.
Fix flakiness of CI tests:
https://github.com/openai/codex/actions/runs/20350530276/job/58473691443?pr=8282
This PR does two things:
1. test with responses API instead of chat completions API in
thread_resume tests;
2. have a new responses API fixture that mocks out arbitrary numbers of
responses API calls (including no calls) and have the same repeated
response.
Tested by CI
**Before:**
```
Error loading configuration: value `Never` is not in the allowed set [OnRequest]
```
**After:**
```
Error loading configuration: invalid value for `approval_policy`: `Never` is not in the
allowed set [OnRequest] (set by MDM com.openai.codex:requirements_toml_base64)
```
Done by introducing a new struct `ConfigRequirementsWithSources` onto
which we `merge_unset_fields` now. Also introduces a pair of requirement
value and its `RequirementSource` (inspired by `ConfigLayerSource`):
```rust
pub struct Sourced<T> {
pub value: T,
pub source: RequirementSource,
}
```
## Summary
- avoid setting a new process group when stdio is inherited (keeps child
in foreground PG)
- keep process-group isolation when stdio is redirected so killpg
cleanup still works
- prevents macOS job-control SIGTTIN stops that look like hangs after
output
## Testing
- `cargo build -p codex-cli`
- `GIT_CONFIG_GLOBAL=/dev/null GIT_CONFIG_NOSYSTEM=1
CARGO_BIN_EXE_codex=/Users/denis/Code/codex/codex-rs/target/debug/codex
/opt/homebrew/bin/timeout 30m cargo test -p codex-core -p codex-exec`
## Context
This fixes macOS sandbox hangs for commands like `elixir -v` / `erl
-noshell`, where the child was moved into a new process group while
still attached to the controlling TTY. See issue #8690.
## Authorship & collaboration
- This change and analysis were authored by **Codex** (AI coding agent).
- Human collaborator: @seeekr provided repro environment, context, and
review guidance.
- CLI used: `codex-cli 0.77.0`.
- Model: `gpt-5.2-codex (xhigh)`.
Co-authored-by: Eric Traut <etraut@openai.com>
Include project-level AGENTS.md and skills in /review sessions so the
review sub-agent uses the same instruction pipeline as standard runs,
keeping reviewer context aligned with normal sessions.
Sort list_dir entries before applying offset/limit so pagination matches
the displayed order, update pagination/truncation expectations, and add
coverage for sorted pagination. This ensures stable, predictable
directory pages when list_dir is enabled.
Add metrics capabilities to Codex. The `README.md` is up to date.
This will not be merged with the metrics before this PR of course:
https://github.com/openai/codex/pull/8350
## Summary
This PR builds _heavily_ on the work from @occurrent in #8021 - I've
only added a small fix, added additional tests, and propagated the
changes to tui2.
From the original PR:
> On Windows, Codex relies on PasteBurst for paste detection because
bracketed paste is not reliably available via crossterm.
>
> When pasted content starts with non-ASCII characters, input is routed
through handle_non_ascii_char, which bypasses the normal paste burst
logic. This change extends the paste burst window for that path, which
should ensure that Enter is correctly grouped as part of the paste.
## Testing
- [x] tested locally cross-platform
- [x] added regression tests
---------
Co-authored-by: occur <occurring@outlook.com>
https://github.com/openai/codex/pull/8879 introduced the
`find_resource!` macro, but now that I am about to use it in more
places, I realize that it should take care of this normalization case
for callers.
Note the `use $crate::path_absolutize::Absolutize;` line is there so
that users of `find_resource!` do not have to explicitly include
`path-absolutize` to their own `Cargo.toml`.
To support Bazelification in https://github.com/openai/codex/pull/8875,
this PR introduces a new `find_resource!` macro that we use in place of
our existing logic in tests that looks for resources relative to the
compile-time `CARGO_MANIFEST_DIR` env var.
To make this work, we plan to add the following to all `rust_library()`
and `rust_test()` Bazel rules in the project:
```
rustc_env = {
"BAZEL_PACKAGE": native.package_name(),
},
```
Our new `find_resource!` macro reads this value via
`option_env!("BAZEL_PACKAGE")` so that the Bazel package _of the code
using `find_resource!`_ is injected into the code expanded from the
macro. (If `find_resource()` were a function, then
`option_env!("BAZEL_PACKAGE")` would always be
`codex-rs/utils/cargo-bin`, which is not what we want.)
Note we only consider the `BAZEL_PACKAGE` value when the `RUNFILES_DIR`
environment variable is set at runtime, indicating that the test is
being run by Bazel. In this case, we have to concatenate the runtime
`RUNFILES_DIR` with the compile-time `BAZEL_PACKAGE` value to build the
path to the resource.
In testing this change, I discovered one funky edge case in
`codex-rs/exec-server/tests/common/lib.rs` where we have to _normalize_
(but not canonicalize!) the result from `find_resource!` because the
path contains a `common/..` component that does not exist on disk when
the test is run under Bazel, so it must be semantically normalized using
the [`path-absolutize`](https://crates.io/crates/path-absolutize) crate
before it is passed to `dotslash fetch`.
Because this new behavior may be non-obvious, this PR also updates
`AGENTS.md` to make humans/Codex aware that this API is preferred.
The Bazelification work in-flight over at
https://github.com/openai/codex/pull/8832 needs this fix so that Bazel
can find the path to the DotSlash file for `bash`.
With this change, the following almost works:
```
bazel test --test_output=errors //codex-rs/exec-server:exec-server-all-test
```
That is, now the `list_tools` test passes, but
`accept_elicitation_for_prompt_rule` still fails because it runs
Seatbelt itself, so it needs to be run outside Bazel's local sandboxing.
Skills discovery now follows symlink entries for SkillScope::User
($CODEX_HOME/skills) and SkillScope::Admin (e.g. /etc/codex/skills).
Added cycle protection: directories are canonicalized and tracked in a
visited set to prevent infinite traversal from circular links.
Added per-root traversal limits to avoid accidentally scanning huge
trees:
- max depth: 6
- max directories: 2000 (logs a warning if truncated)
For now, symlink stat failures and traversal truncation are logged
rather than surfaced as UI “invalid SKILL.md” warnings.
<img width="763" height="349" alt="Screenshot 2026-01-07 at 18 37 59"
src="https://github.com/user-attachments/assets/569d01cb-ea91-4113-889b-ba74df24adaf"
/>
It may not make sense to use the `/model` menu with a custom
OPENAI_BASE_URL. But some model proxies may support it, so we shouldn't
disable it completely. A warning is a reasonable compromise.