Fix the ChatGPT login OAuth parameter rejected by OpenAI auth and refresh provider agent defaults for the Antigravity CLI migration path while preserving legacy aliases.
Fixes#589Fixes#590
## Why
The TUI currently creates a shared plaintext `codex-tui.log` under the
default log directory. That append-only file can keep growing across
runs even though the TUI already records diagnostics in bounded local
stores.
Make the plaintext file log an explicit troubleshooting choice instead
of a default side effect.
This is possible because logs are also stored in the DB with proper
rotation
## What changed
- Only install the TUI file logging layer when `log_dir` is explicitly
set.
- Remove the prior `codex-tui.log` at startup before an opt-in file
layer is created.
- Clarify the `log_dir` config/schema text and `docs/install.md` example
so users opt in with `codex -c log_dir=...` when they need a plaintext
log.
`cargo test` for the core and other crates fails on a fresh macOS
checkout without the right stack size variable. This change encourages
using the just test command that sets the environment up correctly.
As a bonus, this should encourage agents to get more benefit out of
nextest's parallel execution.
## Why
Enterprise-managed hook policy needs a narrow way to require Codex to
ignore user-controlled lifecycle hooks without adopting the broader
trust-precedence model from earlier hook work. This keeps the policy
anchored in `requirements.toml`, so admins can opt into managed hooks
only while normal `config.toml` files cannot enable the restriction
themselves.
## What changed
- Added `allow_managed_hooks_only` to the requirements data flow and
preserved explicit `false` values.
- Also adds it to /debug-config
- Marked MDM, system, and legacy managed config layers as managed for
hook discovery.
- Updated hook discovery so `allow_managed_hooks_only = true`:
- keeps managed requirements hooks and managed config-layer hooks,
- skips user/project/session `hooks.json` and `[hooks]` entries with
concise startup warnings,
- skips current unmanaged plugin hooks,
- ignores any `allow_managed_hooks_only` key placed in ordinary
`config.toml` layers.
## Summary
Codex keeps trying to add documentation to the `docs/` directory. With
the exception of app server API documentation, the docs for Codex should
not live in this repo. We don't want the local `docs/` folder to become
a stale shadow of the official docs.
This PR updates `AGENTS.md` to make that boundary explicit and scopes
the existing API documentation guidance to app-server docs/examples. It
also removes the extra `docs/config.md` sections that were recently
added.
Add Codex config for static trace span attributes and structured W3C
tracestate field upserts. The config flows through OtelSettings so
callers can attach trace metadata without touching every span call site.
Apply span attributes with an SDK span processor so every exported
trace span carries the configured metadata. Model tracestate as nested
member fields so configured keys can be upserted while unrelated
propagated state in the same member is preserved.
Validate configured tracestate before installing provider-global state,
including header-unsafe values the SDK does not reject by itself. This
keeps Codex from propagating malformed trace context from config.
Update the config schema, public docs, and OTLP loopback coverage for
config parsing, span export, propagation, and invalid-header rejection.
There's already a preference for this in the codebase, but a few of them
have drifted away. Generally `--locked` is preferred to reduce exposure
to supply-chain attacks (and just generally improve reproducibility).
In an ideal world these dependencies would maybe even be pinned to
versions but Cargo is kinda bad at that for devtools. Still better to
use --locked than not.
## Summary
- document that commit attribution for generated git commit messages is
gated by the `codex_git_commit` feature flag
- add an example `config.toml` snippet showing `commit_attribution` with
`[features].codex_git_commit = true`
- update the config schema description so the reference docs explain
that `commit_attribution` only takes effect when the feature is enabled
Fixes#19799.
## Validation
- `cargo run -p codex-core --bin codex-write-config-schema`
- `cargo test -p codex-config`
- `cargo test -p codex-features`
- `cargo fmt --check`
- `git diff --check`
## Notes
- `cargo test -p codex-core config_schema_matches_fixture` currently
fails before reaching the schema test because `core_test_support`
imports `similar` without a linked crate in this checkout. The narrower
package checks above avoid that unrelated test-support build failure.
## Summary
We should not check local-only docs or planning specs into this
repository. Keeping those files here duplicates the canonical Codex
documentation surface and makes transient implementation notes look like
supported docs.
This PR removes the local-only docs/spec files from `docs/` and trims
`docs/config.md` back to links for the maintained configuration
documentation on developers.openai.com.
# Why
`notify` is the remaining compatibility surface from the legacy hook
implementation. The newer lifecycle hook engine now owns the active hook
system, so we should start steering users away from adding new `notify`
configs before removing the old path entirely. This also adds a
lightweight watchpoint for the deprecation so we can see how much legacy
usage remains before the clean drop.
# What
- emit a startup deprecation notice when a non-empty `notify` command is
configured
- emit `codex.notify.configured` when a session starts with legacy
`notify` configured
- emit `codex.notify.run` when the legacy notify path fires after a
completed turn
- mark `notify` as deprecated in the config schema and repo docs
- remove the orphaned `codex-rs/hooks/src/user_notification.rs` file
that is no longer compiled
- add regression coverage for the new deprecation notice
# Next steps
A follow-up PR can remove the legacy notify path entirely once we are
ready for the clean drop. Before then, we can watch
`codex.notify.configured` and `codex.notify.run` to understand the
deprecation impact and remaining active usage. The cleanup PR should
then delete the `notify` config field, the `legacy_notify`
implementation, the old compatibility dispatch types and callsites that
only exist for the legacy path, and the remaining compatibility
docs/tests.
# Testing
- `cargo test -p codex-hooks`
- `cargo test -p codex-config`
- `cargo test -p codex-core emits_deprecation_notice_for_notify`
## Summary
- Add `disable_tool_suggest` to app and plugin config, schema, and
TypeScript output
- Exclude disabled connectors and plugins from tool suggestion discovery
- Persist "never show again" tool-suggestion choices back into
`config.toml`
- Update config docs and add coverage for connector and plugin
suppression
## Testing
- Added and updated unit tests for config persistence and tool-suggest
filtering
- Not run (not requested)
Keep raw shell scripts intact until execution so heredocs and apply_patch invocations survive profile wrapping, and add the shell_command tool path for supported models.
Also record richer TUI and exec crash diagnostics, including session log paths, panic backtraces, and Auto Drive coordinator telemetry, and document the new debugging flow.
## Summary
- honor `_meta["codex/imageDetail"] == "original"` on MCP image content
and map it to `detail: "original"` where supported
- strip that detail back out when the active model does not support
original-detail image inputs
- update code-mode `image(...)` to accept individual MCP image blocks
- teach `js_repl` / `codex.emitImage(...)` to preserve the same hint
from raw MCP image outputs
- document the new `_meta` contract and add generic RMCP-backed coverage
across protocol, core, code-mode, and js_repl paths
## Why
For more advanced MCP usage, we want the model to be able to emit
parallel MCP tool calls and have Codex execute eligible ones
concurrently, instead of forcing all MCP calls through the serial block.
The main design choice was where to thread the config. I made this
server-level because parallel safety depends on the MCP server
implementation. Codex reads the flag from `mcp_servers`, threads the
opted-in server names into `ToolRouter`, and checks the parsed
`ToolPayload::Mcp { server, .. }` at execution time. That avoids relying
on model-visible tool names, which can be incomplete in
deferred/search-tool paths or ambiguous for similarly named
servers/tools.
## What was added
Added `supports_parallel_tool_calls` for MCP servers.
Before:
```toml
[mcp_servers.docs]
command = "docs-server"
```
After:
```toml
[mcp_servers.docs]
command = "docs-server"
supports_parallel_tool_calls = true
```
MCP calls remain serial by default. Only tools from opted-in servers are
eligible to run in parallel. Docs also now warn to enable this only when
the server’s tools are safe to run concurrently, especially around
shared state or read/write races.
## Testing
Tested with a local stdio MCP server exposing real delay tools. The
model/Responses side was mocked only to deterministically emit two MCP
calls in the same turn.
Each test called `query_with_delay` and `query_with_delay_2` with `{
"seconds": 25 }`.
| Build/config | Observed | Wall time |
| --- | --- | --- |
| main with flag enabled | serial | `58.79s` |
| PR with flag enabled | parallel | `31.73s` |
| PR without flag | serial | `56.70s` |
PR with flag enabled showed both tools start before either completed;
main and PR-without-flag completed the first delay before starting the
second.
Also added an integration test.
Additional checks:
- `cargo test -p codex-tools` passed
- `cargo test -p codex-core
mcp_parallel_support_uses_exact_payload_server` passed
- `git diff --check` passed
## Problem
The TUI had shell-style Up/Down history recall, but `Ctrl+R` did not
provide the reverse incremental search workflow users expect from
shells. Users needed a way to search older prompts without immediately
replacing the current draft, and the interaction needed to handle async
persistent history, repeated navigation keys, duplicate prompt text,
footer hints, and preview highlighting without making the main composer
file even harder to review.
https://github.com/user-attachments/assets/5165affd-4c9a-46e9-adbd-89088f5f7b6b
<img width="1227" height="722" alt="image"
src="https://github.com/user-attachments/assets/8bc83289-eeca-47c7-b0c3-8975101901af"
/>
## Mental model
`Ctrl+R` opens a temporary search session owned by the composer. The
footer line becomes the search input, the composer body previews the
current match only after the query has text, and `Enter` accepts that
preview as an editable draft while `Esc` restores the draft that existed
before search started. The history layer provides a combined offset
space over persistent and local history, but search navigation exposes
unique prompt text rather than every physical history row.
## Non-goals
This change does not rewrite stored history, change normal Up/Down
browsing semantics, add fuzzy matching, or add persistent metadata for
attachments in cross-session history. Search deduplication is
deliberately scoped to the active Ctrl+R search session and uses exact
prompt text, so case, whitespace, punctuation, and attachment-only
differences are not normalized.
## Tradeoffs
The implementation keeps search state in the existing composer and
history state machines instead of adding a new cross-module controller.
That keeps ownership local and testable, but it means the composer still
coordinates visible search status, draft restoration, footer rendering,
cursor placement, and match highlighting while `ChatComposerHistory`
owns traversal, async fetch continuation, boundary clamping, and
unique-result caching. Unique-result caching stores cloned
`HistoryEntry` values so known matches can be revisited without cache
lookups; this is simple and robust for interactive search sizes, but it
is not a global history index.
## Architecture
`ChatComposer` detects `Ctrl+R`, snapshots the current draft, switches
the footer to `FooterMode::HistorySearch`, and routes search-mode keys
before normal editing. Query edits call `ChatComposerHistory::search`
with `restart = true`, which starts from the newest combined-history
offset. Repeated `Ctrl+R` or Up searches older; Down searches newer
through already discovered unique matches or continues the scan.
Persistent history entries still arrive asynchronously through
`on_entry_response`, where a pending search either accepts the response,
skips a duplicate, or requests the next offset.
The composer-facing pieces now live in
`codex-rs/tui/src/bottom_pane/chat_composer/history_search.rs`, leaving
`chat_composer.rs` responsible for routing and rendering integration
instead of owning every search helper inline.
`codex-rs/tui/src/bottom_pane/chat_composer_history.rs` remains the
owner of stored history, combined offsets, async fetch state, boundary
semantics, and duplicate suppression. Match highlighting is computed
from the current composer text while search is active and disappears
when the match is accepted.
## Observability
There are no new logs or telemetry. The practical debug path is state
inspection: `ChatComposer.history_search` tells whether the footer query
is idle, searching, matched, or unmatched; `ChatComposerHistory.search`
tracks selected raw offsets, pending persistent fetches, exhausted
directions, and unique match cache state. If a user reports skipped or
repeated results, first inspect the exact stored prompt text, the
selected offset, whether an async persistent response is still pending,
and whether a query edit restarted the search session.
## Tests
The change is covered by focused `codex-tui` unit tests for opening
search without previewing the latest entry, accepting and canceling
search, no-match restoration, boundary clamping, footer hints,
case-insensitive highlighting, local duplicate skipping, and persistent
duplicate skipping through async responses. Snapshot coverage captures
the footer-mode visual changes. Local verification used `just fmt`,
`cargo test -p codex-tui history_search`, `cargo test -p codex-tui`, and
`just fix -p codex-tui`.
## Summary
- remove protocol and core support for discovering and listing custom
prompts
- simplify the TUI slash-command flow and command popup to built-in
commands only
- delete obsolete custom prompt tests, helpers, and docs references
- clean up downstream event handling for the removed protocol events
This is a follow-up to https://github.com/openai/codex/pull/15922. That
previous PR deleted the old `tui` directory and left the new
`tui_app_server` directory in place. This PR renames `tui_app_server` to
`tui` and fixes up all references.
This is the part 1 of 2 PRs that will delete the `tui` /
`tui_app_server` split. This part simply deletes the existing `tui`
directory and marks the `tui_app_server` feature flag as removed. I left
the `tui_app_server` feature flag in place for now so its presence
doesn't result in an error. It is simply ignored.
Part 2 will rename the `tui_app_server` directory `tui`. I did this as
two parts to reduce visible code churn.