test-log is only used by codex-core tests, so it does not need to be part of
the normal codex-core dependency graph. Keeping it in dev-dependencies removes
it from normal builds and keeps the production dependency set a little smaller.
Verification:
- `cargo tree -p codex-core --edges normal --invert test-log`
- `cargo check -p codex-core --lib`
- `cargo test -p codex-core --lib`
## What changed
This PR makes the default Cargo dev profile use line-tables-only debug
info:
```toml
[profile.dev]
debug = 1
```
That keeps useful backtraces while avoiding the cost of full variable
debug
info in normal local dev builds.
This also makes the Bazel CI setting explicit with `-Cdebuginfo=0` for
target
and exec-configuration Rust actions. Bazel/rules_rust does not read
Cargo
profiles for this setting, and the current fastbuild action already
emitted
`--codegen=debuginfo=0`; the Bazel part of this PR makes that choice
direct in
our build configuration.
## Why
The slow codex-core rebuilds are dominated by debug-info codegen, not
parsing
or type checking. On a warm-dependency package rebuild, the baseline
codex-core compile was about 39.5s wall / 38.9s rustc total, with
codegen_crate around 14.0s and LLVM_passes around 13.4s. Setting
codex-core
to line-tables-only debug info brought that to about 27.2s wall / 26.7s
rustc
total, with codegen_crate around 3.1s and LLVM_passes around 2.8s.
`debug = 0` was only about another 0.7s faster than `debug = 1` in the
codex-core measurement, so `debug = 1` is the better default dev
tradeoff: it
captures nearly all of the compile-time win while preserving basic
debuggability.
I also sampled other first-party crates instead of keeping a
codex-core-only
package override. codex-app-server showed the same pattern: rustc total
dropped from 15.85s to 10.48s, while codegen_crate plus LLVM_passes
dropped
from about 13.47s to 3.23s. codex-app-server-protocol had a smaller but
still
real improvement, 16.05s to 14.58s total, and smaller crates showed
modest
wins. That points to a workspace dev-profile policy rather than a
hand-maintained list of large crates.
## Relationship to #18612
[#18612](https://github.com/openai/codex/pull/18612) added the
`dev-small`
profile. That remains useful when someone wants a working local build
quickly
and is willing to opt in with `cargo build --profile dev-small`.
This PR is deliberately less aggressive: it changes the common default
dev
profile while preserving line tables/backtraces. `dev-small` remains the
explicit "build quickly, no debuggability concern" path.
## Other investigation
I looked for another structural win comparable to
[#16631](https://github.com/openai/codex/pull/16631) and
[#16630](https://github.com/openai/codex/pull/16630), but did not find
one.
The attempted TOML monomorphization changes were noisy or worse in
measurement, and the async task changes reduced some instantiations but
only
translated to roughly a one-second improvement while being much more
disruptive. The debug-info setting was the one repeatable, material win
that
survived measurement.
## Verification
- `just bazel-lock-update`
- `just bazel-lock-check`
- `cargo check -p codex-core --lib`
- `cargo test -p codex-core --lib`
- Bazel `aquery --config=ci-linux` confirmed `--codegen=debuginfo=0` and
`-Cdebuginfo=0` for `//codex-rs/core:core`
---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/18844).
* #18846
* __->__ #18844
## Summary
- Move external agent config migration logic and tests from `codex-core`
into `app-server/src/config`.
- Keep the migration service crate-private to app-server and update the
API adapter imports.
- Remove stale core re-exports and expose only the needed marketplace
source helper.
## Testing
- `cargo test -p codex-app-server config::external_agent_config`
- `just fmt`
- `just fix -p codex-app-server`
- `just fix -p codex-core`
- `git diff --check`
test-log is only used by codex-core tests, so it does not need to be part of
the normal codex-core dependency graph. Keeping it in dev-dependencies removes
it from normal builds and keeps the production dependency set a little smaller.
Verification:
- `cargo tree -p codex-core --edges normal --invert test-log`
- `cargo check -p codex-core --lib`
- `cargo test -p codex-core --lib`
The slow codex-core rebuilds are dominated by debug-info codegen, not parsing
or type checking. On a warm-dependency package rebuild, the baseline
codex-core compile was about 39.5s wall / 38.9s rustc total, with
codegen_crate around 14.0s and LLVM_passes around 13.4s. Setting codex-core
to line-tables-only debug info brought that to about 27.2s wall / 26.7s rustc
total, with codegen_crate around 3.1s and LLVM_passes around 2.8s.
I also sampled other first-party crates instead of keeping a codex-core-only
package override. codex-app-server showed the same pattern: rustc total
dropped from 15.85s to 10.48s, while codegen_crate plus LLVM_passes dropped
from about 13.47s to 3.23s. codex-app-server-protocol had a smaller but still
real improvement, 16.05s to 14.58s total, and smaller crates showed modest
wins. That points to a workspace dev-profile policy rather than a
hand-maintained list of large crates.
Use `[profile.dev] debug = 1` so local dev builds keep line tables and useful
backtraces while avoiding full variable debug info. This can cause a one-time
rebuild because the Cargo dev profile hash changes, but subsequent rebuilds
avoid the expensive debug-info work.
Bazel does not read Cargo profiles for this setting. rules_rust derives
debuginfo from Bazel toolchain/compilation-mode settings and the current
fastbuild action already emitted `--codegen=debuginfo=0`. This change makes
the CI choice explicit for both target and exec-configuration Rust actions
with `-Cdebuginfo=0`.
Verification:
- `just bazel-lock-update`
- `just bazel-lock-check`
- `cargo check -p codex-core --lib`
- `cargo test -p codex-core --lib`
- Bazel `aquery --config=ci-linux` confirmed `--codegen=debuginfo=0` and
`-Cdebuginfo=0` for `//codex-rs/core:core`
test-log is only used by codex-core tests, so it does not need to be part of
the normal codex-core dependency graph. Keeping it in dev-dependencies removes
it from normal builds and keeps the production dependency set a little smaller.
Verification:
- `cargo tree -p codex-core --edges normal --invert test-log`
- `cargo check -p codex-core --lib`
- `cargo test -p codex-core --lib`
The slow codex-core rebuilds are dominated by debug-info codegen, not parsing
or type checking. On a warm-dependency package rebuild, the baseline
codex-core compile was about 39.5s wall / 38.9s rustc total, with
codegen_crate around 14.0s and LLVM_passes around 13.4s. Setting codex-core
to line-tables-only debug info brought that to about 27.2s wall / 26.7s rustc
total, with codegen_crate around 3.1s and LLVM_passes around 2.8s.
I also sampled other first-party crates instead of keeping a codex-core-only
package override. codex-app-server showed the same pattern: rustc total
dropped from 15.85s to 10.48s, while codegen_crate plus LLVM_passes dropped
from about 13.47s to 3.23s. codex-app-server-protocol had a smaller but still
real improvement, 16.05s to 14.58s total, and smaller crates showed modest
wins. That points to a workspace dev-profile policy rather than a
hand-maintained list of large crates.
Use `[profile.dev] debug = 1` so local dev builds keep line tables and useful
backtraces while avoiding full variable debug info. This can cause a one-time
rebuild because the Cargo dev profile hash changes, but subsequent rebuilds
avoid the expensive debug-info work.
Bazel does not read Cargo profiles for this setting. rules_rust derives
debuginfo from Bazel toolchain/compilation-mode settings and the current
fastbuild action already emitted `--codegen=debuginfo=0`. This change makes
the CI choice explicit for both target and exec-configuration Rust actions
with `-Cdebuginfo=0`.
Verification:
- `just bazel-lock-update`
- `just bazel-lock-check`
- `cargo check -p codex-core --lib`
- `cargo test -p codex-core --lib`
- Bazel `aquery --config=ci-linux` confirmed `--codegen=debuginfo=0` and
`-Cdebuginfo=0` for `//codex-rs/core:core`
Fixes https://github.com/openai/codex/issues/13638
## Why
VS Code's integrated terminal can run a Linux shell through WSL without
exposing `TERM_PROGRAM` to the Linux process, and with crossterm
keyboard enhancement flags enabled that environment can turn dead-key
composition into malformed key events instead of composed Unicode input.
Codex already handles composed Unicode correctly, so the fix is to avoid
enabling the terminal mode that breaks this path for the affected
terminal combination.
## What Changed
- Automatically skip crossterm keyboard enhancement flags when Codex
detects WSL plus VS Code, including a Windows-side `TERM_PROGRAM` probe
through WSL interop.
- Add `CODEX_TUI_DISABLE_KEYBOARD_ENHANCEMENT` so users can
force-disable or force-enable the keyboard enhancement policy for
diagnosis.
## Verification
- Added unit coverage for env parsing, VS Code detection, and the WSL/VS
Code auto-disable policy.
- `cargo check -p codex-tui` passed.
- `./tools/argument-comment-lint/run.py -p codex-tui -- --tests` passed.
- `cargo test -p codex-tui` was attempted locally, but the checkout
failed during linking before tests executed because V8 symbols from
`codex-code-mode` were unresolved for `arm64`.
## What
- Explicitly show our "bash mode" by changing the color and adding a
callout similar to how we do for `Plan mode (shift + tab to cycle)`
- Also replace our `›` composer prefix with a bang `!`

## Why
- It was unclear that we had a Bash mode
- This feels more responsive
- It looks cool!
---------
Co-authored-by: Codex <noreply@openai.com>
## Summary
This updates the code review orchestrator skill wording so the
instruction explicitly requires returning every issue from every
subagent.
## Impact
The change is limited to `.codex/skills/code-review/SKILL.md` and
clarifies review aggregation behavior for future Codex-driven reviews.
## Validation
No tests were run because this is a markdown-only skill wording change.
Deferred dynamic tools need to round-trip a namespace so a tool returned
by `tool_search` can be called through the same registry key that core
uses for dispatch.
This change adds namespace support for dynamic tool specs/calls,
persists it through app-server thread state, and routes dynamic tool
calls by full `ToolName` while still sending the app the leaf tool name.
Deferred dynamic tools must provide a namespace; non-deferred dynamic
tools may remain top-level.
It also introduces `LoadableToolSpec` as the shared
function-or-namespace Responses shape used by both `tool_search` output
and dynamic tool registration, so dynamic tools use the same wrapping
logic in both paths.
Validation:
- `cargo test -p codex-tools`
- `cargo test -p codex-core tool_search`
---------
Co-authored-by: Sayan Sisodiya <sayan@openai.com>