Commit Graph

227 Commits

  • Code mode on v8 (#15276)
    Moves Code Mode to a new crate with no dependencies on codex. This
    create encodes the code mode semantics that we want for lifetime,
    mounting, tool calling.
    
    The model-facing surface is mostly unchanged. `exec` still runs raw
    JavaScript, `wait` still resumes or terminates a `cell_id`, nested tools
    are still available through `tools.*`, and helpers like `text`, `image`,
    `store`, `load`, `notify`, `yield_control`, and `exit` still exist.
    
    The major change is underneath that surface:
    
    - Old code mode was an external Node runtime.
    - New code mode is an in-process V8 runtime embedded directly in Rust.
    - Old code mode managed cells inside a long-lived Node runner process.
    - New code mode manages cells in Rust, with one V8 runtime thread per
    active `exec`.
    - Old code mode used JSON protocol messages over child stdin/stdout plus
    Node worker-thread messages.
    - New code mode uses Rust channels and direct V8 callbacks/events.
    
    This PR also fixes the two migration regressions that fell out of that
    substrate change:
    
    - `wait { terminate: true }` now waits for the V8 runtime to actually
    stop before reporting termination.
    - synchronous top-level `exit()` now succeeds again instead of surfacing
    as a script error.
    
    ---
    
    - `core/src/tools/code_mode/*` is now mostly an adapter layer for the
    public `exec` / `wait` tools.
    - `code-mode/src/service.rs` owns cell sessions and async control flow
    in Rust.
    - `code-mode/src/runtime/*.rs` owns the embedded V8 isolate and
    JavaScript execution.
    - each `exec` spawns a dedicated runtime thread plus a Rust
    session-control task.
    - helper globals are installed directly into the V8 context instead of
    being injected through a source prelude.
    - helper modules like `tools.js` and `@openai/code_mode` are synthesized
    through V8 module resolution callbacks in Rust.
    
    ---
    
    Also added a benchmark for showing the speed of init and use of a code
    mode env:
    ```
    $ cargo bench -p codex-code-mode --bench exec_overhead -- --samples 30 --warm-iterations 25 --tool-counts 0,32,128
    Finished [`bench` profile [optimized]](https://doc.rust-lang.org/cargo/reference/profiles.html#default-profiles) target(s) in 0.18s
         Running benches/exec_overhead.rs (target/release/deps/exec_overhead-008c440d800545ae)
    exec_overhead: samples=30, warm_iterations=25, tool_counts=[0, 32, 128]
    scenario       tools samples    warmups      iters      mean/exec       p95/exec       rssΔ p50       rssΔ max
    cold_exec          0      30          0          1         1.13ms         1.20ms        8.05MiB        8.06MiB
    warm_exec          0      30          1         25       473.43us       512.49us      912.00KiB        1.33MiB
    cold_exec         32      30          0          1         1.03ms         1.15ms        8.08MiB        8.11MiB
    warm_exec         32      30          1         25       509.73us       545.76us      960.00KiB        1.30MiB
    cold_exec        128      30          0          1         1.14ms         1.19ms        8.30MiB        8.34MiB
    warm_exec        128      30          1         25       575.08us       591.03us      736.00KiB      864.00KiB
    memory uses a fresh-process max RSS delta for each scenario
    ```
    
    ---------
    
    Co-authored-by: Codex <noreply@openai.com>
  • Add v8-poc consumer of our new built v8 (#15203)
    This adds a dummy v8-poc project that in Cargo links against our
    prebuilt binaries and the ones provided by rusty_v8 for non musl
    platforms. This demonstrates that we can successfully link and use v8 on
    all platforms that we want to target.
    
    In bazel things are slightly more complicated. Since the libraries as
    published have libc++ linked in already we end up with a lot of double
    linked symbols if we try to use them in bazel land. Instead we fall back
    to building rusty_v8 and v8 from source (cached of course) on the
    platforms we ship to.
    
    There is likely some compatibility drift in the windows bazel builder
    that we'll need to reconcile before we can re-enable them. I'm happy to
    be on the hook to unwind that.
  • Split features into codex-features crate (#15253)
    - Split the feature system into a new `codex-features` crate.
    - Cut `codex-core` and workspace consumers over to the new config and
    warning APIs.
    
    Co-authored-by: Ahmed Ibrahim <219906144+aibrahim-oai@users.noreply.github.com>
    Co-authored-by: Codex <noreply@openai.com>
  • Move terminal module to terminal-detection crate (#15216)
    - Move core/src/terminal.rs and its tests into a standalone
    terminal-detection workspace crate.
    - Update direct consumers to depend on codex-terminal-detection and
    import terminal APIs directly.
    
    ---------
    
    Co-authored-by: Codex <noreply@openai.com>
  • [hooks] use a user message > developer message for prompt continuation (#14867)
    ## Summary
    
    Persist Stop-hook continuation prompts as `user` messages instead of
    hidden `developer` messages + some requested integration tests
    
    This is a followup to @pakrym 's comment in
    https://github.com/openai/codex/pull/14532 to make sure stop-block
    continuation prompts match training for turn loops
    
    - Stop continuation now writes `<hook_prompt hook_run_id="...">stop
    hook's user prompt<hook_prompt>`
    - Introduces quick-xml dependency, though we already indirectly depended
    on it anyway via syntect
    - This PR only has about 500 lines of actual logic changes, the rest is
    tests/schema
    
    ## Testing
    
    Example run (with a sessionstart hook and 3 stop hooks) - this shows
    context added by session start, then two stop hooks sending their own
    additional prompts in a new turn. The model responds with a single
    message addressing both. Then when that turn ends, the hooks detect that
    they just ran using `stop_hook_active` and decide not to infinite loop
    
    test files for this (unzip, move codex -> .codex):
    [codex.zip](https://github.com/user-attachments/files/26075806/codex.zip)
    
    ```
    › cats
    
    
    • Running SessionStart hook: lighting the observatory
    
    SessionStart hook (completed)
      warning: Hi, I'm a session start hook for wizard-tower (startup).
      hook context: A wimboltine stonpet is an exotic cuisine from hyperspace
    
    • Cats are tiny zen wizards, my friend: equal parts nap, mystery, and chaos. If you want, we can talk
      cat facts, cat breeds, cat names, or build something cat-themed in this repo.
    
    • Running Stop hook: checking the tower wards
    
    • Running Stop hook: sacking the guards
    
    • Running Stop hook: hiring the guards
    
    Stop hook (completed)
      warning: Wizard Tower Stop hook reviewed the completed reply (177 chars).
    
    Stop hook (blocked)
      warning: Wizard Tower Stop hook continuing conversation
      feedback: cook the stonpet
    
    Stop hook (blocked)
      warning: Wizard Tower Stop hook continuing conversation
      feedback: eat the cooked stonpet
    
    • Stonpet’s cooked, aloha style: flash-seared over a blue quasiflame, glazed with nebula salt, and
      rested until the hyperspace juices settle.
    
      Now we eat with gratitude, my friend. One mindful bite in, and the flavor is pure cosmic surf:
      smoky, bright, and totally out of this dimension.
    
    • Running Stop hook: checking the tower wards
    
    • Running Stop hook: sacking the guards
    
    • Running Stop hook: hiring the guards
    
    Stop hook (completed)
      warning: Wizard Tower Stop hook reviewed the completed reply (285 chars).
    
    Stop hook (completed)
      warning: Wizard Tower Stop hook saw a second pass and stayed calm to avoid a loop.
    
    Stop hook (completed)
      warning: Wizard Tower Stop hook saw a second pass and stayed calm to avoid a loop.
    ```
  • Move environment abstraction into exec server (#15125)
    The idea is that codex-exec exposes an Environment struct with services
    on it. Each of those is a trait.
    
    Depending on construction parameters passed to Environment they are
    either backed by local or remote server but core doesn't see these
    differences.
  • Add exec-server stub server and protocol docs (#15089)
    Stacked PR 1/3.
    
    This is the initialize-only exec-server stub slice: binary/client
    scaffolding and protocol docs, without exec/filesystem implementation.
    
    ---------
    
    Co-authored-by: Codex <noreply@openai.com>
  • Add FS abstraction and use in view_image (#14960)
    Adds an environment crate and environment + file system abstraction.
    
    Environment is a combination of attributes and services specific to
    environment the agent is connected to:
    File system, process management, OS, default shell.
    
    The goal is to move most of agent logic that assumes environment to work
    through the environment abstraction.
  • Move TUI on top of app server (parallel code) (#14717)
    This PR replicates the `tui` code directory and creates a temporary
    parallel `tui_app_server` directory. It also implements a new feature
    flag `tui_app_server` to select between the two tui implementations.
    
    Once the new app-server-based TUI is stabilized, we'll delete the old
    `tui` directory and feature flag.
  • client: extend custom CA handling across HTTPS and websocket clients (#14239)
    ## Stacked PRs
    
    This work is now effectively split across two steps:
    
    - #14178: add custom CA support for browser and device-code login flows,
    docs, and hermetic subprocess tests
    - #14239: extend that shared custom CA handling across Codex HTTPS
    clients and secure websocket TLS
    
    Note: #14240 was merged into this branch while it was stacked on top of
    this PR. This PR now subsumes that websocket follow-up and should be
    treated as the combined change.
    
    Builds on top of #14178.
    
    ## Problem
    
    Custom CA support landed first in the login path, but the real
    requirement is broader. Codex constructs outbound TLS clients in
    multiple places, and both HTTPS and secure websocket paths can fail
    behind enterprise TLS interception if they do not honor
    `CODEX_CA_CERTIFICATE` or `SSL_CERT_FILE` consistently.
    
    This PR broadens the shared custom-CA logic beyond login and applies the
    same policy to websocket TLS, so the enterprise-proxy story is no longer
    split between “HTTPS works” and “websockets still fail”.
    
    ## What This Delivers
    
    Custom CA support is no longer limited to login. Codex outbound HTTPS
    clients and secure websocket connections can now honor the same
    `CODEX_CA_CERTIFICATE` / `SSL_CERT_FILE` configuration, so enterprise
    proxy/intercept setups work more consistently end-to-end.
    
    For users and operators, nothing new needs to be configured beyond the
    same CA env vars introduced in #14178. The change is that more of Codex
    now respects them, including websocket-backed flows that were previously
    still using default trust roots.
    
    I also manually validated the proxy path locally with mitmproxy using:
    `CODEX_CA_CERTIFICATE=~/.mitmproxy/mitmproxy-ca-cert.pem
    HTTPS_PROXY=http://127.0.0.1:8080 just codex`
    with mitmproxy installed via `brew install mitmproxy` and configured as
    the macOS system proxy.
    
    ## Mental model
    
    `codex-client` is now the owner of shared custom-CA policy for outbound
    TLS client construction. Reqwest callers start from the builder
    configuration they already need, then pass that builder through
    `build_reqwest_client_with_custom_ca(...)`. Websocket callers ask the
    same module for a rustls client config when a custom CA bundle is
    configured.
    
    The env precedence is the same everywhere:
    - `CODEX_CA_CERTIFICATE` wins
    - otherwise fall back to `SSL_CERT_FILE`
    - otherwise use system roots
    
    The helper is intentionally narrow. It loads every usable certificate
    from the configured PEM bundle into the appropriate root store and
    returns either a configured transport or a typed error that explains
    what went wrong.
    
    ## Non-goals
    
    This does not add handshake-level integration tests against a live TLS
    endpoint. It does not validate that the configured bundle forms a
    meaningful certificate chain. It also does not try to force every
    transport in the repo through one abstraction; it extends the shared CA
    policy across the reqwest and websocket paths that actually needed it.
    
    ## Tradeoffs
    
    The main tradeoff is centralizing CA behavior in `codex-client` while
    still leaving adoption up to call sites. That keeps the implementation
    additive and reviewable, but it means the rule "outbound Codex TLS that
    should honor enterprise roots must use the shared helper" is still
    partly enforced socially rather than by types.
    
    For websockets, the shared helper only builds an explicit rustls config
    when a custom CA bundle is configured. When no override env var is set,
    websocket callers still use their ordinary default connector path.
    
    ## Architecture
    
    `codex-client::custom_ca` now owns CA bundle selection, PEM
    normalization, mixed-section parsing, certificate extraction, typed
    CA-loading errors, and optional rustls client-config construction for
    websocket TLS.
    
    The affected consumers now call into that shared helper directly rather
    than carrying login-local CA behavior:
    - backend-client
    - cloud-tasks
    - RMCP client paths that use `reqwest`
    - TUI voice HTTP paths
    - `codex-core` default reqwest client construction
    - `codex-api` websocket clients for both responses and realtime
    websocket connections
    
    The subprocess CA probe, env-sensitive integration tests, and shared PEM
    fixtures also live in `codex-client`, which is now the actual owner of
    the behavior they exercise.
    
    ## Observability
    
    The shared CA path logs:
    - which environment variable selected the bundle
    - which path was loaded
    - how many certificates were accepted
    - when `TRUSTED CERTIFICATE` labels were normalized
    - when CRLs were ignored
    - where client construction failed
    
    Returned errors remain user-facing and include the relevant env var,
    path, and remediation hint. That same error model now applies whether
    the failure surfaced while building a reqwest client or websocket TLS
    configuration.
    
    ## Tests
    
    Pure unit tests in `codex-client` cover env precedence and PEM
    normalization behavior. Real client construction remains in subprocess
    tests so the suite can control process env and avoid the macOS seatbelt
    panic path that motivated the hermetic test split.
    
    The subprocess coverage verifies:
    - `CODEX_CA_CERTIFICATE` precedence over `SSL_CERT_FILE`
    - fallback to `SSL_CERT_FILE`
    - single-cert and multi-cert bundles
    - malformed and empty-file errors
    - OpenSSL `TRUSTED CERTIFICATE` handling
    - CRL tolerance for well-formed CRL sections
    
    The websocket side is covered by the existing `codex-api` / `codex-core`
    websocket test suites plus the manual mitmproxy validation above.
    
    ---------
    
    Co-authored-by: Ivan Zakharchanka <3axap4eHko@gmail.com>
    Co-authored-by: Codex <noreply@openai.com>
  • login: add custom CA support for login flows (#14178)
    ## Stacked PRs
    
    This work is split across three stacked PRs:
    
    - #14178: add custom CA support for browser and device-code login flows,
    docs, and hermetic subprocess tests
    - #14239: broaden the shared custom CA path from login to other outbound
    `reqwest` clients across Codex
    - #14240: extend that shared custom CA handling to secure websocket TLS
    so websocket connections honor the same CA env vars
    
    Review order: #14178, then #14239, then #14240.
    
    Supersedes #6864.
    
    Thanks to @3axap4eHko for the original implementation and investigation
    here. Although this version rearranges the code and history
    significantly, the majority of the credit for this work belongs to them.
    
    ## Problem
    
    Login flows need to work in enterprise environments where outbound TLS
    is intercepted by an internal proxy or gateway. In those setups, system
    root certificates alone are often insufficient to validate the OAuth and
    device-code endpoints used during login. The change adds a
    login-specific custom CA loading path, but the important contracts
    around env precedence, PEM compatibility, test boundaries, and
    probe-only workarounds need to be explicit so reviewers can understand
    what behavior is intentional.
    
    For users and operators, the behavior is simple: if login needs to trust
    a custom root CA, set `CODEX_CA_CERTIFICATE` to a PEM file containing
    one or more certificates. If that variable is unset, login falls back to
    `SSL_CERT_FILE`. If neither is set, login uses system roots. Invalid or
    empty PEM files now fail with an error that points back to those
    environment variables and explains how to recover.
    
    ## What This Delivers
    
    Users can now make Codex login work behind enterprise TLS interception
    by pointing `CODEX_CA_CERTIFICATE` at a PEM bundle containing the
    relevant root certificates. If that variable is unset, login falls back
    to `SSL_CERT_FILE`, then to system roots.
    
    This PR applies that behavior to both browser-based and device-code
    login flows. It also makes login tolerant of the PEM shapes operators
    actually have in hand: multi-certificate bundles, OpenSSL `TRUSTED
    CERTIFICATE` labels, and bundles that include well-formed CRLs.
    
    ## Mental model
    
    `codex-login` is the place where the login flows construct ad hoc
    outbound HTTP clients. That makes it the right boundary for a narrow CA
    policy: look for `CODEX_CA_CERTIFICATE`, fall back to `SSL_CERT_FILE`,
    load every parseable certificate block in that bundle into a
    `reqwest::Client`, and fail early with a clear user-facing error if the
    bundle is unreadable or malformed.
    
    The implementation is intentionally pragmatic about PEM input shape. It
    accepts ordinary certificate bundles, multi-certificate bundles, OpenSSL
    `TRUSTED CERTIFICATE` labels, and bundles that also contain CRLs. It
    does not validate a certificate chain or prove a handshake; it only
    constructs the root store used by login.
    
    ## Non-goals
    
    This change does not introduce a general-purpose transport abstraction
    for the rest of the product. It does not validate whether the provided
    bundle forms a real chain, and it does not add handshake-level
    integration tests against a live TLS server. It also does not change
    login state management or OAuth semantics beyond ensuring the existing
    flows share the same CA-loading rules.
    
    ## Tradeoffs
    
    The main tradeoff is keeping this logic scoped to login-specific client
    construction rather than lifting it into a broader shared HTTP layer.
    That keeps the review surface smaller, but it also means future
    login-adjacent code must continue to use `build_login_http_client()` or
    it can silently bypass enterprise CA overrides.
    
    The `TRUSTED CERTIFICATE` handling is also intentionally a local
    compatibility shim. The rustls ecosystem does not currently accept that
    PEM label upstream, so the code normalizes it locally and trims the
    OpenSSL `X509_AUX` trailer bytes down to the certificate DER that
    `reqwest` can consume.
    
    ## Architecture
    
    `custom_ca.rs` is now the single place that owns login CA behavior. It
    selects the CA file from the environment, reads it, normalizes PEM label
    shape where needed, iterates mixed PEM sections with `rustls-pki-types`,
    ignores CRLs, trims OpenSSL trust metadata when necessary, and returns
    either a configured `reqwest::Client` or a typed error.
    
    The browser login server and the device-code flow both call
    `build_login_http_client()`, so they share the same trust-store policy.
    Environment-sensitive tests run through the `login_ca_probe` helper
    binary because those tests must control process-wide env vars and cannot
    reliably build a real reqwest client in-process on macOS seatbelt runs.
    
    ## Observability
    
    The custom CA path logs which environment variable selected the bundle,
    which file path was loaded, how many certificates were accepted, when
    `TRUSTED CERTIFICATE` labels were normalized, when CRLs were ignored,
    and where client construction failed. Returned errors remain user-facing
    and include the relevant path, env var, and remediation hint.
    
    This gives enough signal for three audiences:
    - users can see why login failed and which env/file caused it
    - sysadmins can confirm which override actually won
    - developers can tell whether the failure happened during file read, PEM
    parsing, certificate registration, or final reqwest client construction
    
    ## Tests
    
    Pure unit tests stay limited to env precedence and empty-value handling.
    Real client construction lives in subprocess tests so the suite remains
    hermetic with respect to process env and macOS sandbox behavior.
    
    The subprocess tests verify:
    - `CODEX_CA_CERTIFICATE` precedence over `SSL_CERT_FILE`
    - fallback to `SSL_CERT_FILE`
    - single-certificate and multi-certificate bundles
    - malformed and empty-bundle errors
    - OpenSSL `TRUSTED CERTIFICATE` handling
    - CRL tolerance for well-formed CRL sections
    
    The named PEM fixtures under `login/tests/fixtures/` are shared by the
    tests so their purpose stays reviewable.
    
    ---------
    
    Co-authored-by: Ivan Zakharchanka <3axap4eHko@gmail.com>
    Co-authored-by: Codex <noreply@openai.com>
  • [apps] Add tool_suggest tool. (#14287)
    - [x] Add tool_suggest tool.
    - [x] Move chatgpt/src/connectors.rs and core/src/connectors.rs into a
    dedicated mod so that we have all the logic and global cache in one
    place.
    - [x] Update TUI app link view to support rendering the installation
    view for mcp elicitation.
    
    ---------
    
    Co-authored-by: Shaqayeq <shaqayeq@openai.com>
    Co-authored-by: Eric Traut <etraut@openai.com>
    Co-authored-by: pakrym-oai <pakrym@openai.com>
    Co-authored-by: Ahmed Ibrahim <aibrahim@openai.com>
    Co-authored-by: guinness-oai <guinness@openai.com>
    Co-authored-by: Eugene Brevdo <ebrevdo@users.noreply.github.com>
    Co-authored-by: Charlie Guo <cguo@openai.com>
    Co-authored-by: Fouad Matin <fouad@openai.com>
    Co-authored-by: Fouad Matin <169186268+fouad-openai@users.noreply.github.com>
    Co-authored-by: xl-openai <xl@openai.com>
    Co-authored-by: alexsong-oai <alexsong@openai.com>
    Co-authored-by: Owen Lin <owenlin0@gmail.com>
    Co-authored-by: sdcoffey <stevendcoffey@gmail.com>
    Co-authored-by: Codex <noreply@openai.com>
    Co-authored-by: Won Park <won@openai.com>
    Co-authored-by: Dylan Hurd <dylan.hurd@openai.com>
    Co-authored-by: celia-oai <celia@openai.com>
    Co-authored-by: gabec-openai <gabec@openai.com>
    Co-authored-by: joeytrasatti-openai <joey.trasatti@openai.com>
    Co-authored-by: Leo Shimonaka <leoshimo@openai.com>
    Co-authored-by: Rasmus Rygaard <rasmus@openai.com>
    Co-authored-by: maja-openai <163171781+maja-openai@users.noreply.github.com>
    Co-authored-by: pash-openai <pash@openai.com>
    Co-authored-by: Josh McKinney <joshka@openai.com>
  • Add in-process app server and wire up exec to use it (#14005)
    This is a subset of PR #13636. See that PR for a full overview of the
    architectural change.
    
    This PR implements the in-process app server and modifies the
    non-interactive "exec" entry point to use the app server.
    
    ---------
    
    Co-authored-by: Felipe Coury <felipe.coury@gmail.com>
  • chore(deps): bump serde_with from 3.16.1 to 3.17.0 in /codex-rs (#13209)
    Bumps [serde_with](https://github.com/jonasbb/serde_with) from 3.16.1 to
    3.17.0.
    <details>
    <summary>Release notes</summary>
    <p><em>Sourced from <a
    href="https://github.com/jonasbb/serde_with/releases">serde_with's
    releases</a>.</em></p>
    <blockquote>
    <h2>serde_with v3.17.0</h2>
    <h3>Added</h3>
    <ul>
    <li>Support <code>OneOrMany</code> with <code>smallvec</code> v1 (<a
    href="https://redirect.github.com/jonasbb/serde_with/issues/920">#920</a>,
    <a
    href="https://redirect.github.com/jonasbb/serde_with/issues/922">#922</a>)</li>
    </ul>
    <h3>Changed</h3>
    <ul>
    <li>Switch to <code>yaml_serde</code> for a maintained yaml dependency
    by <a href="https://github.com/kazan417"><code>@​kazan417</code></a> (<a
    href="https://redirect.github.com/jonasbb/serde_with/issues/921">#921</a>)</li>
    <li>Bump MSRV to 1.82, since that is required for
    <code>yaml_serde</code> dev-dependency.</li>
    </ul>
    </blockquote>
    </details>
    <details>
    <summary>Commits</summary>
    <ul>
    <li><a
    href="https://github.com/jonasbb/serde_with/commit/4031878a4cfced7261105447d8683c296147864b"><code>4031878</code></a>
    Bump version to v3.17.0 (<a
    href="https://redirect.github.com/jonasbb/serde_with/issues/924">#924</a>)</li>
    <li><a
    href="https://github.com/jonasbb/serde_with/commit/204ae56f8ba08bd911ad0f122719bf07f3dcdbbb"><code>204ae56</code></a>
    Bump version to v3.17.0</li>
    <li><a
    href="https://github.com/jonasbb/serde_with/commit/7812b5a006e23e0204c687868e68a8b9dae75cd1"><code>7812b5a</code></a>
    serde_yaml 0.9 to yaml_serde 0.10 (<a
    href="https://redirect.github.com/jonasbb/serde_with/issues/921">#921</a>)</li>
    <li><a
    href="https://github.com/jonasbb/serde_with/commit/614bd8950bc179f4f23c1d9f26866ac216257fed"><code>614bd89</code></a>
    Bump MSRV to 1.82 as required by yaml_serde</li>
    <li><a
    href="https://github.com/jonasbb/serde_with/commit/518d0ed7873616a81c987d7961d78f5f26210694"><code>518d0ed</code></a>
    Suppress RUSTSEC-2026-0009 since we don't have untrusted time input in
    tests ...</li>
    <li><a
    href="https://github.com/jonasbb/serde_with/commit/a6579a89841f269c7f63912e8e808e82212c672e"><code>a6579a8</code></a>
    Suppress RUSTSEC-2026-0009 since we don't have untrusted time input in
    tests</li>
    <li><a
    href="https://github.com/jonasbb/serde_with/commit/9d4d0696e6794da4babf8204d17d11dadb79dd60"><code>9d4d069</code></a>
    Implement OneOrMany for smallvec_1::SmallVec (<a
    href="https://redirect.github.com/jonasbb/serde_with/issues/922">#922</a>)</li>
    <li><a
    href="https://github.com/jonasbb/serde_with/commit/fc78243e8c60c4fcc11a99f2c6ccc0d449a57fd9"><code>fc78243</code></a>
    Add changelog</li>
    <li><a
    href="https://github.com/jonasbb/serde_with/commit/2b8c30bf679309c27143f13070dbeef068310ab5"><code>2b8c30b</code></a>
    Implement OneOrMany for smallvec_1::SmallVec</li>
    <li><a
    href="https://github.com/jonasbb/serde_with/commit/2d9b9a1815cb6d58b17ab6403e57e7c2f62b84cc"><code>2d9b9a1</code></a>
    Carg.lock update</li>
    <li>Additional commits viewable in <a
    href="https://github.com/jonasbb/serde_with/compare/v3.16.1...v3.17.0">compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    
    [![Dependabot compatibility
    score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=serde_with&package-manager=cargo&previous-version=3.16.1&new-version=3.17.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
    
    Dependabot will resolve any conflicts with this PR as long as you don't
    alter it yourself. You can also trigger a rebase manually by commenting
    `@dependabot rebase`.
    
    [//]: # (dependabot-automerge-start)
    [//]: # (dependabot-automerge-end)
    
    ---
    
    <details>
    <summary>Dependabot commands and options</summary>
    <br />
    
    You can trigger Dependabot actions by commenting on this PR:
    - `@dependabot rebase` will rebase this PR
    - `@dependabot recreate` will recreate this PR, overwriting any edits
    that have been made to it
    - `@dependabot show <dependency name> ignore conditions` will show all
    of the ignore conditions of the specified dependency
    - `@dependabot ignore this major version` will close this PR and stop
    Dependabot creating any more for this major version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this minor version` will close this PR and stop
    Dependabot creating any more for this minor version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this dependency` will close this PR and stop
    Dependabot creating any more for this dependency (unless you reopen the
    PR or upgrade to it yourself)
    
    
    </details>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    Co-authored-by: Eric Traut <etraut@openai.com>
  • chore(deps): bump strum_macros from 0.27.2 to 0.28.0 in /codex-rs (#13210)
    Bumps [strum_macros](https://github.com/Peternator7/strum) from 0.27.2
    to 0.28.0.
    <details>
    <summary>Changelog</summary>
    <p><em>Sourced from <a
    href="https://github.com/Peternator7/strum/blob/master/CHANGELOG.md">strum_macros's
    changelog</a>.</em></p>
    <blockquote>
    <h2>0.28.0</h2>
    <ul>
    <li>
    <p><a
    href="https://redirect.github.com/Peternator7/strum/pull/461">#461</a>:
    Allow any kind of passthrough attributes on
    <code>EnumDiscriminants</code>.</p>
    <ul>
    <li>Previously only list-style attributes (e.g.
    <code>#[strum_discriminants(derive(...))]</code>) were supported. Now
    path-only
    (e.g. <code>#[strum_discriminants(non_exhaustive)]</code>) and
    name/value (e.g. <code>#[strum_discriminants(doc =
    &quot;foo&quot;)]</code>)
    attributes are also supported.</li>
    </ul>
    </li>
    <li>
    <p><a
    href="https://redirect.github.com/Peternator7/strum/pull/462">#462</a>:
    Add missing <code>#[automatically_derived]</code> to generated impls not
    covered by <a
    href="https://redirect.github.com/Peternator7/strum/pull/444">#444</a>.</p>
    </li>
    <li>
    <p><a
    href="https://redirect.github.com/Peternator7/strum/pull/466">#466</a>:
    Bump MSRV to 1.71, required to keep up with updated <code>syn</code> and
    <code>windows-sys</code> dependencies. This is a breaking change if
    you're on an old version of rust.</p>
    </li>
    <li>
    <p><a
    href="https://redirect.github.com/Peternator7/strum/pull/469">#469</a>:
    Use absolute paths in generated proc macro code to avoid
    potential name conflicts.</p>
    </li>
    <li>
    <p><a
    href="https://redirect.github.com/Peternator7/strum/pull/465">#465</a>:
    Upgrade <code>phf</code> dependency to v0.13.</p>
    </li>
    <li>
    <p><a
    href="https://redirect.github.com/Peternator7/strum/pull/473">#473</a>:
    Fix <code>cargo fmt</code> / <code>clippy</code> issues and add GitHub
    Actions CI.</p>
    </li>
    <li>
    <p><a
    href="https://redirect.github.com/Peternator7/strum/pull/477">#477</a>:
    <code>strum::ParseError</code> now implements
    <code>core::fmt::Display</code> instead
    <code>std::fmt::Display</code> to make it <code>#[no_std]</code>
    compatible. Note the <code>Error</code> trait wasn't available in core
    until <code>1.81</code>
    so <code>strum::ParseError</code> still only implements that in std.</p>
    </li>
    <li>
    <p><a
    href="https://redirect.github.com/Peternator7/strum/pull/476">#476</a>:
    <strong>Breaking Change</strong> - <code>EnumString</code> now
    implements <code>From&lt;&amp;str&gt;</code>
    (infallible) instead of <code>TryFrom&lt;&amp;str&gt;</code> when the
    enum has a <code>#[strum(default)]</code> variant. This more accurately
    reflects that parsing cannot fail in that case. If you need the old
    <code>TryFrom</code> behavior, you can opt back in using
    <code>parse_error_ty</code> and <code>parse_error_fn</code>:</p>
    <pre lang="rust"><code>#[derive(EnumString)]
    #[strum(parse_error_ty = strum::ParseError, parse_error_fn =
    make_error)]
    pub enum Color {
        Red,
        #[strum(default)]
        Other(String),
    }
    <p>fn make_error(x: &amp;str) -&gt; strum::ParseError {
    strum::ParseError::VariantNotFound
    }
    </code></pre></p>
    </li>
    <li>
    <p><a
    href="https://redirect.github.com/Peternator7/strum/pull/431">#431</a>:
    Fix bug where <code>EnumString</code> ignored the
    <code>parse_err_ty</code>
    attribute when the enum had a <code>#[strum(default)]</code>
    variant.</p>
    </li>
    <li>
    <p><a
    href="https://redirect.github.com/Peternator7/strum/pull/474">#474</a>:
    EnumDiscriminants will now copy <code>default</code> over from the
    original enum to the Discriminant enum.</p>
    <pre lang="rust"><code>#[derive(Debug, Default, EnumDiscriminants)]
    #[strum_discriminants(derive(Default))] // &lt;- Remove this in 0.28.
    enum MyEnum {
        #[default] // &lt;- Will be the #[default] on the MyEnumDiscriminant
        #[strum_discriminants(default)] // &lt;- Remove this in 0.28
        Variant0,
        Variant1 { a: NonDefault },
    }
    </code></pre>
    </li>
    </ul>
    <!-- raw HTML omitted -->
    </blockquote>
    <p>... (truncated)</p>
    </details>
    <details>
    <summary>Commits</summary>
    <ul>
    <li><a
    href="https://github.com/Peternator7/strum/commit/7376771128834d28bb9beba5c39846cba62e71ec"><code>7376771</code></a>
    Peternator7/0.28 (<a
    href="https://redirect.github.com/Peternator7/strum/issues/475">#475</a>)</li>
    <li><a
    href="https://github.com/Peternator7/strum/commit/26e63cd964a2e364331a5dd977d589bb9f649d8c"><code>26e63cd</code></a>
    Display exists in core (<a
    href="https://redirect.github.com/Peternator7/strum/issues/477">#477</a>)</li>
    <li><a
    href="https://github.com/Peternator7/strum/commit/9334c728eedaa8a992d1388a8f4564bbccad1934"><code>9334c72</code></a>
    Make TryFrom and FromStr infallible if there's a default (<a
    href="https://redirect.github.com/Peternator7/strum/issues/476">#476</a>)</li>
    <li><a
    href="https://github.com/Peternator7/strum/commit/0ccbbf823c16e827afc263182cd55e99e3b2a52e"><code>0ccbbf8</code></a>
    Honor parse_err_ty attribute when the enum has a default variant (<a
    href="https://redirect.github.com/Peternator7/strum/issues/431">#431</a>)</li>
    <li><a
    href="https://github.com/Peternator7/strum/commit/2c9e5a9259189ce8397f2f4967060240c6bafd74"><code>2c9e5a9</code></a>
    Automatically add Default implementation to EnumDiscriminant if it
    exists on ...</li>
    <li><a
    href="https://github.com/Peternator7/strum/commit/e241243e48359b8b811b8eaccdcfa1ae87138e0d"><code>e241243</code></a>
    Fix existing cargo fmt + clippy issues and add GH actions (<a
    href="https://redirect.github.com/Peternator7/strum/issues/473">#473</a>)</li>
    <li><a
    href="https://github.com/Peternator7/strum/commit/639b67fefd20eaead1c5d2ea794e9afe70a00312"><code>639b67f</code></a>
    feat: allow any kind of passthrough attributes on
    <code>EnumDiscriminants</code> (<a
    href="https://redirect.github.com/Peternator7/strum/issues/461">#461</a>)</li>
    <li><a
    href="https://github.com/Peternator7/strum/commit/0ea1e2d0fd1460e7492ea32e6b460394d9199ff8"><code>0ea1e2d</code></a>
    docs: Fix typo (<a
    href="https://redirect.github.com/Peternator7/strum/issues/463">#463</a>)</li>
    <li><a
    href="https://github.com/Peternator7/strum/commit/36c051b91086b37d531c63ccf5a49266832a846d"><code>36c051b</code></a>
    Upgrade <code>phf</code> to v0.13 (<a
    href="https://redirect.github.com/Peternator7/strum/issues/465">#465</a>)</li>
    <li><a
    href="https://github.com/Peternator7/strum/commit/9328b38617dc6f4a3bc5fdac03883d3fc766cf34"><code>9328b38</code></a>
    Use absolute paths in proc macro (<a
    href="https://redirect.github.com/Peternator7/strum/issues/469">#469</a>)</li>
    <li>Additional commits viewable in <a
    href="https://github.com/Peternator7/strum/compare/v0.27.2...v0.28.0">compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    
    [![Dependabot compatibility
    score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=strum_macros&package-manager=cargo&previous-version=0.27.2&new-version=0.28.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
    
    Dependabot will resolve any conflicts with this PR as long as you don't
    alter it yourself. You can also trigger a rebase manually by commenting
    `@dependabot rebase`.
    
    [//]: # (dependabot-automerge-start)
    [//]: # (dependabot-automerge-end)
    
    ---
    
    <details>
    <summary>Dependabot commands and options</summary>
    <br />
    
    You can trigger Dependabot actions by commenting on this PR:
    - `@dependabot rebase` will rebase this PR
    - `@dependabot recreate` will recreate this PR, overwriting any edits
    that have been made to it
    - `@dependabot show <dependency name> ignore conditions` will show all
    of the ignore conditions of the specified dependency
    - `@dependabot ignore this major version` will close this PR and stop
    Dependabot creating any more for this major version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this minor version` will close this PR and stop
    Dependabot creating any more for this minor version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this dependency` will close this PR and stop
    Dependabot creating any more for this dependency (unless you reopen the
    PR or upgrade to it yourself)
    
    
    </details>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    Co-authored-by: Eric Traut <etraut@openai.com>
  • feat: external artifacts builder (#13485)
    This PR reverts the built-in artifact render while a decision is being
    reached. No impact expected on any features
  • feat: presentation artifact p1 (#13341)
    Part 1 of presentation tool artifact
  • feat: add local date/timezone to turn environment context (#12947)
    ## Summary
    
    This PR includes the session's local date and timezone in the
    model-visible environment context and persists that data in
    `TurnContextItem`.
    
      ## What changed
    - captures the current local date and IANA timezone when building a turn
    context, with a UTC fallback if the timezone lookup fails
    - includes current_date and timezone in the serialized
    <environment_context> payload
    - stores those fields on TurnContextItem so they survive rollout/history
    handling, subagent review threads, and resume flows
    - treats date/timezone changes as environment updates, so prompt caching
    and context refresh logic do not silently reuse stale time context
    - updates tests to validate the new environment fields without depending
    on a single hardcoded environment-context string
    
    ## test
    
    built a local build and saw it in the rollout file:
    ```
    {"timestamp":"2026-02-26T21:39:50.737Z","type":"response_item","payload":{"type":"message","role":"user","content":[{"type":"input_text","text":"<environment_context>\n  <shell>zsh</shell>\n  <current_date>2026-02-26</current_date>\n  <timezone>America/Los_Angeles</timezone>\n</environment_context>"}]}}
    ```
  • split-debuginfo (#12871)
    Attempt to reduce disk usage in mac ci.
    
    >off - This is the default for platforms with ELF binaries and
    windows-gnu (not Windows MSVC and not macOS). This typically means that
    DWARF debug information can be found in the final artifact in sections
    of the executable. This option is not supported on Windows MSVC. On
    macOS this options prevents the final execution of dsymutil to generate
    debuginfo.
  • otel: add host.name resource attribute to logs/traces via gethostname (#12352)
    **PR Summary**
    
    This PR adds the OpenTelemetry `host.name` resource attribute to Codex
    OTEL exports so every OTEL log (and trace, via the shared resource)
    carries the machine hostname.
    
    **What changed**
    
    - Added `host.name` to the shared OTEL `Resource` in
    `/Users/michael.mcgrew/code/codex/codex-rs/otel/src/otel_provider.rs`
      - This applies to both:
        - OTEL logs (`SdkLoggerProvider`)
        - OTEL traces (`SdkTracerProvider`)
    - Hostname is now resolved via `gethostname::gethostname()`
    (best-effort)
      - Value is trimmed
      - Empty values are omitted (non-fatal)
    - Added focused unit tests for:
      - including `host.name` when present
      - omitting `host.name` when missing/empty
    
    **Why**
    
    - `host.name` is host/process metadata and belongs on the OTEL
    `resource`, not per-event attributes.
    - Attaching it in the shared resource is the smallest change that
    guarantees coverage across all exported OTEL logs/traces.
    
    **Scope / Non-goals**
    
    - No public API changes
    - No changes to metrics behavior (this PR only updates log/trace
    resource metadata)
    
    **Dependency updates**
    
    - Added `gethostname` as a workspace dependency and `codex-otel`
    dependency
    - `Cargo.lock` updated accordingly
    - `MODULE.bazel.lock` unchanged after refresh/check
    
    **Validation**
    
    - `just fmt`
    - `cargo test -p codex-otel`
    - `just bazel-lock-update`
    - `just bazel-lock-check`
  • feat: adding stream parser (#12666)
    Add a stream parser to extract citations (and others) from a stream.
    This support cases where markers are split in differen tokens.
    
    Codex never manage to make this code work so everything was done
    manually. Please review correctly and do not touch this part of the code
    without a very clear understanding of it
  • feat: add large stack test macro (#12768)
    This PR adds the macro `#[large_stack_test]`
    
    This spawns the tests in a dedicated tokio runtime with a larger stack.
    It is useful for tests that needs the full recursion on the harness
    (which is now too deep for windows for example)
  • Agent jobs (spawn_agents_on_csv) + progress UI (#10935)
    ## Summary
    - Add agent job support: spawn a batch of sub-agents from CSV, auto-run,
    auto-export, and store results in SQLite.
    - Simplify workflow: remove run/resume/get-status/export tools; spawn is
    deterministic and completes in one call.
    - Improve exec UX: stable, single-line progress bar with ETA; suppress
    sub-agent chatter in exec.
    
    ## Why
    Enables map-reduce style workflows over arbitrarily large repos using
    the existing Codex orchestrator. This addresses review feedback about
    overly complex job controls and non-deterministic monitoring.
    
    ## Demo (progress bar)
    ```
    ./codex-rs/target/debug/codex exec \
      --enable collab \
      --enable sqlite \
      --full-auto \
      --progress-cursor \
      -c agents.max_threads=16 \
      -C /Users/daveaitel/code/codex \
      - <<'PROMPT'
    Create /tmp/agent_job_progress_demo.csv with columns: path,area and 30 rows:
    path = item-01..item-30, area = test.
    
    Then call spawn_agents_on_csv with:
    - csv_path: /tmp/agent_job_progress_demo.csv
    - instruction: "Run `python - <<'PY'` to sleep a random 0.3–1.2s, then output JSON with keys: path, score (int). Set score = 1."
    - output_csv_path: /tmp/agent_job_progress_demo_out.csv
    PROMPT
    ```
    
    ## Review feedback addressed
    - Auto-start jobs on spawn; removed run/resume/status/export tools.
    - Auto-export on success.
    - More descriptive tool spec + clearer prompts.
    - Avoid deadlocks on spawn failure; pending/running handled safely.
    - Progress bar no longer scrolls; stable single-line redraw.
    
    ## Tests
    - `cd codex-rs && cargo test -p codex-exec`
    - `cd codex-rs && cargo build -p codex-cli`
  • feat: run zsh fork shell tool via shell-escalation (#12649)
    ## Why
    
    This PR switches the `shell_command` zsh-fork path over to
    `codex-shell-escalation` so the new shell tool can use the shared
    exec-wrapper/escalation protocol instead of the `zsh_exec_bridge`
    implementation that was introduced in
    https://github.com/openai/codex/pull/12052. `zsh_exec_bridge` relied on
    UNIX domain sockets, which is not as tamper-proof as the FD-based
    approach in `codex-shell-escalation`.
    
    ## What Changed
    
    - Added a Unix zsh-fork runtime adapter in `core`
    (`core/src/tools/runtimes/shell/unix_escalation.rs`) that:
    - runs zsh-fork commands through
    `codex_shell_escalation::run_escalate_server`
      - bridges exec-policy / approval decisions into `ShellActionProvider`
    - executes escalated commands via a `ShellCommandExecutor` that calls
    `process_exec_tool_call`
    - Updated `ShellRuntime` / `ShellCommandHandler` / tool spec wiring to
    select a `shell_command` backend (`classic` vs `zsh-fork`) while leaving
    the generic `shell` tool path unchanged.
    - Removed the `zsh_exec_bridge`-based session service and deleted
    `core/src/zsh_exec_bridge/mod.rs`.
    - Moved exec-wrapper entrypoint dispatch to `arg0` by handling the
    `codex-execve-wrapper` arg0 alias there, and removed the old
    `codex_core::maybe_run_zsh_exec_wrapper_mode()` hooks from `cli` and
    `app-server` mains.
    - Added the needed `codex-shell-escalation` dependencies for `core` and
    `arg0`.
    
    ## Tests
    
    - `cargo test -p codex-core
    shell_zsh_fork_prefers_shell_command_over_unified_exec`
    - `cargo test -p codex-app-server turn_start_shell_zsh_fork --
    --nocapture`
    - verifies zsh-fork command execution and approval flows through the new
    backend
    - includes subcommand approve/decline coverage using the shared zsh
    DotSlash fixture in `app-server/tests/suite/zsh`
    - To test manually, I added the following to `~/.codex/config.toml`:
    
    ```toml
    zsh_path = "/Users/mbolin/code/codex3/codex-rs/app-server/tests/suite/zsh"
    
    [features]
    shell_zsh_fork = true
    ```
    
    Then I ran `just c` to run the dev build of Codex with these changes and
    sent it the message:
    
    ```
    run `echo $0`
    ```
    
    And it replied with:
    
    ```
      echo $0 printed:
    
      /Users/mbolin/code/codex3/codex-rs/app-server/tests/suite/zsh
    
      In this tool context, $0 reflects the script path used to invoke the shell, not just zsh.
    ```
    
    so the tool appears to be wired up correctly.
    
    ## Notes
    
    - The zsh subcommand-decline integration test now uses `rm` under a
    `WorkspaceWrite` sandbox. The previous `/usr/bin/true` scenario is
    auto-allowed by the new `shell-escalation` policy path, which no longer
    produces subcommand approval prompts.
  • chore: rm hardcoded PRESETS list (#12650)
    rm `PRESETS` list harcoded in `model_presets` as we now have bundled
    `models.json` with equivalent info.
    
    update logic to rely on bundled models instead, update tests.
  • refactor: delete exec-server and move execve wrapper into shell-escalation (#12632)
    ## Why
    
    We already plan to remove the shell-tool MCP path, and doing that
    cleanup first makes the follow-on `shell-escalation` work much simpler.
    
    This change removes the last remaining reason to keep
    `codex-rs/exec-server` around by moving the `codex-execve-wrapper`
    binary and shared shell test fixtures to the crates/tests that now own
    that functionality.
    
    ## What Changed
    
    ### Delete `codex-rs/exec-server`
    
    - Remove the `exec-server` crate, including the MCP server binary,
    MCP-specific modules, and its test support/test suite
    - Remove `exec-server` from the `codex-rs` workspace and update
    `Cargo.lock`
    
    ### Move `codex-execve-wrapper` into `codex-rs/shell-escalation`
    
    - Move the wrapper implementation into `shell-escalation`
    (`src/unix/execve_wrapper.rs`)
    - Add the `codex-execve-wrapper` binary entrypoint under
    `shell-escalation/src/bin/`
    - Update `shell-escalation` exports/module layout so the wrapper
    entrypoint is hosted there
    - Move the wrapper README content from `exec-server` to
    `shell-escalation/README.md`
    
    ### Move shared shell test fixtures to `app-server`
    
    - Move the DotSlash `bash`/`zsh` test fixtures from
    `exec-server/tests/suite/` to `app-server/tests/suite/`
    - Update `app-server` zsh-fork tests to reference the new fixture paths
    
    ### Keep `shell-tool-mcp` as a shell-assets package
    
    - Update `.github/workflows/shell-tool-mcp.yml` packaging so the npm
    artifact contains only patched Bash/Zsh payloads (no Rust binaries)
    - Update `shell-tool-mcp/package.json`, `shell-tool-mcp/src/index.ts`,
    and docs to reflect the shell-assets-only package shape
    - `shell-tool-mcp-ci.yml` does not need changes because it is already
    JS-only
    
    ## Verification
    
    - `cargo shear`
    - `cargo clippy -p codex-shell-escalation --tests`
    - `just clippy`
  • chore(deps): bump owo-colors from 4.2.3 to 4.3.0 in /codex-rs (#12530)
    Bumps [owo-colors](https://github.com/owo-colors/owo-colors) from 4.2.3
    to 4.3.0.
    <details>
    <summary>Release notes</summary>
    <p><em>Sourced from <a
    href="https://github.com/owo-colors/owo-colors/releases">owo-colors's
    releases</a>.</em></p>
    <blockquote>
    <h2>owo-colors 4.3.0</h2>
    <h3>Fixed</h3>
    <ul>
    <li>Scripts in the <code>scripts/</code> directory are no longer
    published in the crate package. Thanks <a
    href="https://redirect.github.com/owo-colors/owo-colors/pull/152">weiznich</a>
    for your first contribution!</li>
    </ul>
    <h3>Changed</h3>
    <ul>
    <li>
    <p>Mark methods with
    <code>#[rust_analyzer::completions(ignore_flyimport)]</code> and the
    <code>OwoColorize</code> trait with
    <code>#[rust_analyzer::completions(ignore_flyimport_methods)]</code>.
    This prevents owo-colors methods from being completed with rust-analyzer
    unless the <code>OwoColorize</code> trait is included.</p>
    <p>Unfortunately, this also breaks explicit autocomplete commands such
    as Ctrl-Space in many editors. (The language server protocol doesn't
    appear to have a way to differentiate between implicit and explicit
    autocomplete commands.) On balance we believe this is the right
    approach, but please do provide feedback on [PR <a
    href="https://redirect.github.com/owo-colors/owo-colors/issues/141">#141</a>](<a
    href="https://redirect.github.com/owo-colors/owo-colors/pull/141">owo-colors/owo-colors#141</a>)
    if it negatively affects you.</p>
    </li>
    <li>
    <p>Updated MSRV to Rust 1.81.</p>
    </li>
    </ul>
    </blockquote>
    </details>
    <details>
    <summary>Changelog</summary>
    <p><em>Sourced from <a
    href="https://github.com/owo-colors/owo-colors/blob/main/CHANGELOG.md">owo-colors's
    changelog</a>.</em></p>
    <blockquote>
    <h2>[4.3.0] - 2026-02-22</h2>
    <h3>Fixed</h3>
    <ul>
    <li>Scripts in the <code>scripts/</code> directory are no longer
    published in the crate package. Thanks <a
    href="https://redirect.github.com/owo-colors/owo-colors/pull/152">weiznich</a>
    for your first contribution!</li>
    </ul>
    <h3>Changed</h3>
    <ul>
    <li>
    <p>Mark methods with
    <code>#[rust_analyzer::completions(ignore_flyimport)]</code> and the
    <code>OwoColorize</code> trait with
    <code>#[rust_analyzer::completions(ignore_flyimport_methods)]</code>.
    This prevents owo-colors methods from being completed with rust-analyzer
    unless the <code>OwoColorize</code> trait is included.</p>
    <p>Unfortunately, this also breaks explicit autocomplete commands such
    as Ctrl-Space in many editors. (The language server protocol doesn't
    appear to have a way to differentiate between implicit and explicit
    autocomplete commands.) On balance we believe this is the right
    approach, but please do provide feedback on [PR <a
    href="https://redirect.github.com/owo-colors/owo-colors/issues/141">#141</a>](<a
    href="https://redirect.github.com/owo-colors/owo-colors/pull/141">owo-colors/owo-colors#141</a>)
    if it negatively affects you.</p>
    </li>
    <li>
    <p>Updated MSRV to Rust 1.81.</p>
    </li>
    </ul>
    </blockquote>
    </details>
    <details>
    <summary>Commits</summary>
    <ul>
    <li><a
    href="https://github.com/owo-colors/owo-colors/commit/baf10f9a74007501379afdc002394a15a787dc59"><code>baf10f9</code></a>
    [owo-colors] version 4.3.0</li>
    <li><a
    href="https://github.com/owo-colors/owo-colors/commit/6abe2026c56ef6eefda30d417462f28f9ea8854d"><code>6abe202</code></a>
    [meta] prepare changelog</li>
    <li><a
    href="https://github.com/owo-colors/owo-colors/commit/ca814470410c819568b381b9b2b3f7a184e7de28"><code>ca81447</code></a>
    [RFC] add ignore_flyimport and ignore_flyimport_methods (<a
    href="https://redirect.github.com/owo-colors/owo-colors/issues/141">#141</a>)</li>
    <li><a
    href="https://github.com/owo-colors/owo-colors/commit/61de72e7f9487a945e8ea59afb9aa1b2046a2bd7"><code>61de72e</code></a>
    Exclude development script from published package (<a
    href="https://redirect.github.com/owo-colors/owo-colors/issues/152">#152</a>)</li>
    <li><a
    href="https://github.com/owo-colors/owo-colors/commit/b2ad6bcd4156207bcbc4c756c0c926e02667a872"><code>b2ad6bc</code></a>
    update MSRV to Rust 1.81 (<a
    href="https://redirect.github.com/owo-colors/owo-colors/issues/156">#156</a>)</li>
    <li>See full diff in <a
    href="https://github.com/owo-colors/owo-colors/compare/v4.2.3...v4.3.0">compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    
    [![Dependabot compatibility
    score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=owo-colors&package-manager=cargo&previous-version=4.2.3&new-version=4.3.0)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
    
    Dependabot will resolve any conflicts with this PR as long as you don't
    alter it yourself. You can also trigger a rebase manually by commenting
    `@dependabot rebase`.
    
    [//]: # (dependabot-automerge-start)
    [//]: # (dependabot-automerge-end)
    
    ---
    
    <details>
    <summary>Dependabot commands and options</summary>
    <br />
    
    You can trigger Dependabot actions by commenting on this PR:
    - `@dependabot rebase` will rebase this PR
    - `@dependabot recreate` will recreate this PR, overwriting any edits
    that have been made to it
    - `@dependabot show <dependency name> ignore conditions` will show all
    of the ignore conditions of the specified dependency
    - `@dependabot ignore this major version` will close this PR and stop
    Dependabot creating any more for this major version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this minor version` will close this PR and stop
    Dependabot creating any more for this minor version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this dependency` will close this PR and stop
    Dependabot creating any more for this dependency (unless you reopen the
    PR or upgrade to it yourself)
    
    
    </details>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • chore(deps): bump libc from 0.2.180 to 0.2.182 in /codex-rs (#12528)
    Bumps [libc](https://github.com/rust-lang/libc) from 0.2.180 to 0.2.182.
    <details>
    <summary>Release notes</summary>
    <p><em>Sourced from <a
    href="https://github.com/rust-lang/libc/releases">libc's
    releases</a>.</em></p>
    <blockquote>
    <h2>0.2.182</h2>
    <h3>Added</h3>
    <ul>
    <li>Android, Linux: Add <code>tgkill</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4970">#4970</a>)</li>
    <li>Redox: Add <code>RENAME_NOREPLACE</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4968">#4968</a>)</li>
    <li>Redox: Add <code>renameat2</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4968">#4968</a>)</li>
    </ul>
    <h2>0.2.181</h2>
    <h3>Added</h3>
    <ul>
    <li>Apple: Add <code>MADV_ZERO</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4924">#4924</a>)</li>
    <li>Redox: Add <code>makedev</code>, <code>major</code>, and
    <code>minor</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4928">#4928</a>)</li>
    <li>GLibc: Add <code>PTRACE_SET_SYSCALL_INFO</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4933">#4933</a>)</li>
    <li>OpenBSD: Add more kqueue related constants for (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4945">#4945</a>)</li>
    <li>Linux: add CAN error types (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4944">#4944</a>)</li>
    <li>OpenBSD: Add siginfo_t::si_status (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4946">#4946</a>)</li>
    <li>QNX NTO: Add <code>max_align_t</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4927">#4927</a>)</li>
    <li>Illumos: Add <code>_CS_PATH</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4956">#4956</a>)</li>
    <li>OpenBSD: add <code>ppoll</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4957">#4957</a>)</li>
    </ul>
    <h3>Fixed</h3>
    <ul>
    <li><strong>Breaking</strong>: Redox: Fix the type of <code>dev_t</code>
    (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4928">#4928</a>)</li>
    <li>AIX: Change 'tv_nsec' of 'struct timespec' to type 'c_long' (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4931">#4931</a>)</li>
    <li>AIX: Use 'struct st_timespec' in 'struct stat{,64}' (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4931">#4931</a>)</li>
    <li>Glibc: Link old version of <code>tc{g,s}etattr</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4938">#4938</a>)</li>
    <li>Glibc: Link the correct version of <code>cf{g,s}et{i,o}speed</code>
    on mips{32,64}r6 (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4938">#4938</a>)</li>
    <li>OpenBSD: Fix constness of tm.tm_zone (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4948">#4948</a>)</li>
    <li>OpenBSD: Fix the definition of <code>ptrace_thread_state</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4947">#4947</a>)</li>
    <li>QuRT: Fix type visibility and defs (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4932">#4932</a>)</li>
    <li>Redox: Fix values for <code>PTHREAD_MUTEX_{NORMAL, RECURSIVE}</code>
    (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4943">#4943</a>)</li>
    <li>Various: Mark additional fields as private padding (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4922">#4922</a>)</li>
    </ul>
    <h3>Changed</h3>
    <ul>
    <li>Fuchsia: Update <code>SO_*</code> constants (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4937">#4937</a>)</li>
    <li>Revert &quot;musl: convert inline timespecs to timespec&quot;
    (resolves build issues on targets only supported by Musl 1.2.3+ ) (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4958">#4958</a>)</li>
    </ul>
    </blockquote>
    </details>
    <details>
    <summary>Changelog</summary>
    <p><em>Sourced from <a
    href="https://github.com/rust-lang/libc/blob/0.2.182/CHANGELOG.md">libc's
    changelog</a>.</em></p>
    <blockquote>
    <h2><a
    href="https://github.com/rust-lang/libc/compare/0.2.181...0.2.182">0.2.182</a>
    - 2026-02-13</h2>
    <h3>Added</h3>
    <ul>
    <li>Android, Linux: Add <code>tgkill</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4970">#4970</a>)</li>
    <li>Redox: Add <code>RENAME_NOREPLACE</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4968">#4968</a>)</li>
    <li>Redox: Add <code>renameat2</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4968">#4968</a>)</li>
    </ul>
    <h2><a
    href="https://github.com/rust-lang/libc/compare/0.2.180...0.2.181">0.2.181</a>
    - 2026-02-09</h2>
    <h3>Added</h3>
    <ul>
    <li>Apple: Add <code>MADV_ZERO</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4924">#4924</a>)</li>
    <li>Redox: Add <code>makedev</code>, <code>major</code>, and
    <code>minor</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4928">#4928</a>)</li>
    <li>GLibc: Add <code>PTRACE_SET_SYSCALL_INFO</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4933">#4933</a>)</li>
    <li>OpenBSD: Add more kqueue related constants for (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4945">#4945</a>)</li>
    <li>Linux: add CAN error types (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4944">#4944</a>)</li>
    <li>OpenBSD: Add siginfo_t::si_status (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4946">#4946</a>)</li>
    <li>QNX NTO: Add <code>max_align_t</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4927">#4927</a>)</li>
    <li>Illumos: Add <code>_CS_PATH</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4956">#4956</a>)</li>
    <li>OpenBSD: add <code>ppoll</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4957">#4957</a>)</li>
    </ul>
    <h3>Fixed</h3>
    <ul>
    <li><strong>breaking</strong>: Redox: Fix the type of dev_t (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4928">#4928</a>)</li>
    <li>AIX: Change 'tv_nsec' of 'struct timespec' to type 'c_long' (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4931">#4931</a>)</li>
    <li>AIX: Use 'struct st_timespec' in 'struct stat{,64}' (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4931">#4931</a>)</li>
    <li>Glibc: Link old version of <code>tc{g,s}etattr</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4938">#4938</a>)</li>
    <li>Glibc: Link the correct version of <code>cf{g,s}et{i,o}speed</code>
    on mips{32,64}r6 (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4938">#4938</a>)</li>
    <li>OpenBSD: Fix constness of tm.tm_zone (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4948">#4948</a>)</li>
    <li>OpenBSD: Fix the definition of <code>ptrace_thread_state</code> (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4947">#4947</a>)</li>
    <li>QuRT: Fix type visibility and defs (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4932">#4932</a>)</li>
    <li>Redox: Fix values for <code>PTHREAD_MUTEX_{NORMAL, RECURSIVE}</code>
    (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4943">#4943</a>)</li>
    <li>Various: Mark additional fields as private padding (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4922">#4922</a>)</li>
    </ul>
    <h3>Changed</h3>
    <ul>
    <li>Fuchsia: Update <code>SO_*</code> constants (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4937">#4937</a>)</li>
    <li>Revert &quot;musl: convert inline timespecs to timespec&quot;
    (resolves build issues on targets only supported by Musl 1.2.3+ ) (<a
    href="https://redirect.github.com/rust-lang/libc/pull/4958">#4958</a>)</li>
    </ul>
    </blockquote>
    </details>
    <details>
    <summary>Commits</summary>
    <ul>
    <li><a
    href="https://github.com/rust-lang/libc/commit/e879ee90b6cd8f79b352d4d4d1f8ca05f94f2f53"><code>e879ee9</code></a>
    chore: Release libc 0.2.182</li>
    <li><a
    href="https://github.com/rust-lang/libc/commit/2efe72f4dae6feebacaf5ec8a4ec5fdc79569e7b"><code>2efe72f</code></a>
    remove copyright year in LICENSE-MIT</li>
    <li><a
    href="https://github.com/rust-lang/libc/commit/634bc4e66e944d54ebc3d1610175c8c6d390bd29"><code>634bc4e</code></a>
    ci: Update the list of tested and documented targets</li>
    <li><a
    href="https://github.com/rust-lang/libc/commit/d7aa109ab5074dbbd35fb52cc72620e29961e76d"><code>d7aa109</code></a>
    Revert &quot;Disable hexagon-unknown-linux-musl testing for
    now&quot;</li>
    <li><a
    href="https://github.com/rust-lang/libc/commit/14e2f5641e2d4356953b0c95959ccfc86af5dcc3"><code>14e2f56</code></a>
    Revert &quot;ci: Skip hexagon-unknown-linux-musl&quot;</li>
    <li><a
    href="https://github.com/rust-lang/libc/commit/b7807c369b468c369661e81ea6f9f649f3b3ddf3"><code>b7807c3</code></a>
    Revert &quot;aix: Temporarily skip checking powerpc64-ibm-aix
    builds&quot;</li>
    <li><a
    href="https://github.com/rust-lang/libc/commit/abe93a0bfedfe6159252d43e5c4273d0b0833ca4"><code>abe93a0</code></a>
    feat(linux): add <code>tgkill</code> for Linux and Android</li>
    <li><a
    href="https://github.com/rust-lang/libc/commit/25f7dde943988c81871d95aaea1afd49cf11425d"><code>25f7dde</code></a>
    feat(redox): add <code>RENAME_NOREPLACE</code></li>
    <li><a
    href="https://github.com/rust-lang/libc/commit/4b4ce4f2205d22121c5e913b118f8fc776d39897"><code>4b4ce4f</code></a>
    feat(redox): add <code>renameat2</code></li>
    <li><a
    href="https://github.com/rust-lang/libc/commit/ab8c36c49327eeee2b5c3818d6706b499dd890a4"><code>ab8c36c</code></a>
    build(deps): bump vmactions/solaris-vm from 1.2.8 to 1.3.0</li>
    <li>Additional commits viewable in <a
    href="https://github.com/rust-lang/libc/compare/0.2.180...0.2.182">compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    
    [![Dependabot compatibility
    score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=libc&package-manager=cargo&previous-version=0.2.180&new-version=0.2.182)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
    
    Dependabot will resolve any conflicts with this PR as long as you don't
    alter it yourself. You can also trigger a rebase manually by commenting
    `@dependabot rebase`.
    
    [//]: # (dependabot-automerge-start)
    [//]: # (dependabot-automerge-end)
    
    ---
    
    <details>
    <summary>Dependabot commands and options</summary>
    <br />
    
    You can trigger Dependabot actions by commenting on this PR:
    - `@dependabot rebase` will rebase this PR
    - `@dependabot recreate` will recreate this PR, overwriting any edits
    that have been made to it
    - `@dependabot show <dependency name> ignore conditions` will show all
    of the ignore conditions of the specified dependency
    - `@dependabot ignore this major version` will close this PR and stop
    Dependabot creating any more for this major version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this minor version` will close this PR and stop
    Dependabot creating any more for this minor version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this dependency` will close this PR and stop
    Dependabot creating any more for this dependency (unless you reopen the
    PR or upgrade to it yourself)
    
    
    </details>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • refactor: normalize unix module layout for exec-server and shell-escalation (#12556)
    ## Why
    Shell execution refactoring in `exec-server` had become split between
    duplicated code paths, which blocked a clean introduction of the new
    reusable shell escalation flow. This commit creates a dedicated
    foundation crate so later shell tooling changes can share one
    implementation.
    
    ## What changed
    - Added the `codex-shell-escalation` crate and moved the core escalation
    pieces (`mcp` protocol/socket/session flow, policy glue) that were
    previously in `exec-server` into it.
    - Normalized `exec-server` Unix structure under a dedicated `unix`
    module layout and kept non-Unix builds narrow.
    - Wired crate/build metadata so `shell-escalation` is a first-class
    workspace dependency for follow-on integration work.
    
    ## Verification
    - Built and linted the stack at this commit point with `just clippy`.
    
    [//]: # (BEGIN SAPLING FOOTER)
    Stack created with [Sapling](https://sapling-scm.com). Best reviewed
    with [ReviewStack](https://reviewstack.dev/openai/codex/pull/12556).
    * #12584
    * #12583
    * __->__ #12556
  • feat(tui): syntax highlighting via syntect with theme picker (#11447)
    ## Summary
    
    Adds syntax highlighting to the TUI for fenced code blocks in markdown
    responses and file diffs, plus a `/theme` command with live preview and
    persistent theme selection. Uses syntect (~250 grammars, 32 bundled
    themes, ~1 MB binary cost) — the same engine behind `bat`, `delta`, and
    `xi-editor`. Includes guardrails for large inputs, graceful fallback to
    plain text, and SSH-aware clipboard integration for the `/copy` command.
    
    <img width="1554" height="1014" alt="image"
    src="https://github.com/user-attachments/assets/38737a79-8717-4715-b857-94cf1ba59b85"
    />
    
    <img width="2354" height="1374" alt="image"
    src="https://github.com/user-attachments/assets/25d30a00-c487-4af8-9cb6-63b0695a4be7"
    />
    
    ## Problem
    
    Code blocks in the TUI (markdown responses and file diffs) render
    without syntax highlighting, making it hard to scan code at a glance.
    Users also have no way to pick a color theme that matches their terminal
    aesthetic.
    
    ## Mental model
    
    The highlighting system has three layers:
    
    1. **Syntax engine** (`render::highlight`) -- a thin wrapper around
    syntect + two-face. It owns a process-global `SyntaxSet` (~250 grammars)
    and a `RwLock<Theme>` that can be swapped at runtime. All public entry
    points accept `(code, lang)` and return ratatui `Span`/`Line` vectors or
    `None` when the language is unrecognized or the input exceeds safety
    guardrails.
    
    2. **Rendering consumers** -- `markdown_render` feeds fenced code blocks
    through the engine; `diff_render` highlights Add/Delete content as a
    whole file and Update hunks per-hunk (preserving parser state across
    hunk lines). Both callers fall back to plain unstyled text when the
    engine returns `None`.
    
    3. **Theme lifecycle** -- at startup the config's `tui.theme` is
    resolved to a syntect `Theme` via `set_theme_override`. At runtime the
    `/theme` picker calls `set_syntax_theme` to swap themes live; on cancel
    it restores the snapshot taken at open. On confirm it persists `[tui]
    theme = "..."` to config.toml.
    
    ## Non-goals
    
    - Inline diff highlighting (word-level change detection within a line).
    - Semantic / LSP-backed highlighting.
    - Theme authoring tooling; users supply standard `.tmTheme` files.
    
    ## Tradeoffs
    
    | Decision | Upside | Downside |
    | ------------------------------------------------ |
    ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
    |
    -----------------------------------------------------------------------------------------------------------------------
    |
    | syntect over tree-sitter / arborium | ~1 MB binary increase for ~250
    grammars + 32 themes; battle-tested crate powering widely-used tools
    (`bat`, `delta`, `xi-editor`). tree-sitter would add ~12 MB for 20-30
    languages or ~35 MB for full coverage. | Regex-based; less structurally
    accurate than tree-sitter for some languages (e.g. language injections
    like JS-in-HTML). |
    | Global `RwLock<Theme>` | Enables live `/theme` preview without
    threading Theme through every call site | Lock contention risk
    (mitigated: reads vastly outnumber writes, single UI thread) |
    | Skip background / italic / underline from themes | Terminal BG
    preserved, avoids ugly rendering on some themes | Themes that rely on
    these properties lose fidelity |
    | Guardrails: 512 KB / 10k lines | Prevents pathological stalls on huge
    diffs or pastes | Very large files render without color |
    
    ## Architecture
    
    ```
    config.toml  ─[tui.theme]─>  set_theme_override()  ─>  THEME (RwLock)
                                                                  │
                      ┌───────────────────────────────────────────┘
                      │
      markdown_render ─── highlight_code_to_lines(code, lang) ─> Vec<Line>
      diff_render     ─── highlight_code_to_styled_spans(code, lang) ─> Option<Vec<Vec<Span>>>
                      │
                      │   (None ⇒ plain text fallback)
                      │
      /theme picker   ─── set_syntax_theme(theme)    // live preview swap
                      ─── current_syntax_theme()      // snapshot for cancel
                      ─── resolve_theme_by_name(name) // lookup by kebab-case
    ```
    
    Key files:
    
    - `tui/src/render/highlight.rs` -- engine, theme management, guardrails
    - `tui/src/diff_render.rs` -- syntax-aware diff line wrapping
    - `tui/src/theme_picker.rs` -- `/theme` command builder
    - `tui/src/bottom_pane/list_selection_view.rs` -- side content panel,
    callbacks
    - `core/src/config/types.rs` -- `Tui::theme` field
    - `core/src/config/edit.rs` -- `syntax_theme_edit()` helper
    
    ## Observability
    
    - `tracing::warn` when a configured theme name cannot be resolved.
    - `Config::startup_warnings` surfaces the same message as a TUI banner.
    - `tracing::error` when persisting theme selection fails.
    
    ## Tests
    
    - Unit tests in `highlight.rs`: language coverage, fallback behavior,
    CRLF stripping, style conversion, guardrail enforcement, theme name
    mapping exhaustiveness.
    - Unit tests in `diff_render.rs`: snapshot gallery at multiple terminal
    sizes (80x24, 94x35, 120x40), syntax-highlighted wrapping, large-diff
    guardrail, rename-to-different-extension highlighting, parser state
    preservation across hunk lines.
    - Unit tests in `theme_picker.rs`: preview rendering (wide + narrow),
    dim overlay on deletions, subtitle truncation, cancel-restore, fallback
    for unavailable configured theme.
    - Unit tests in `list_selection_view.rs`: side layout geometry, stacked
    fallback, buffer clearing, cancel/selection-changed callbacks.
    - Integration test in `lib.rs`: theme warning uses the final
    (post-resume) config.
    
    ## Cargo Deny: Unmaintained Dependency Exceptions
    
    This PR adds two `cargo deny` advisory exceptions for transitive
    dependencies pulled in by `syntect v5.3.0`:
    
    | Advisory | Crate | Status |
    |----------|-------|--------|
    | RUSTSEC-2024-0320 | `yaml-rust` | Unmaintained (maintainer
    unreachable) |
    | RUSTSEC-2025-0141 | `bincode` | Unmaintained (development ceased;
    v1.3.3 considered complete) |
    
    **Why this is safe in our usage:**
    
    - Neither advisory describes a known security vulnerability. Both are
    "unmaintained" notices only.
    - `bincode` is used by syntect to deserialize pre-compiled syntax sets.
    Again, these are **static vendored artifacts** baked into the binary at
    build time. No user-supplied bincode data is ever deserialized. - Attack
    surface is zero for both crates; exploitation would require a
    supply-chain compromise of our own build artifacts.
    - These exceptions can be removed when syntect migrates to `yaml-rust2`
    and drops `bincode`, or when alternative crates are available upstream.
  • refactor(core): move embedded system skills into codex-skills crate (#12435)
    ## Why
    
    `codex-core` was carrying the embedded system-skill sample assets (and a
    `build.rs` that walks those files to register rerun triggers). Those
    assets change infrequently, but any change under `codex-core` still ties
    them to `codex-core`'s build/cache lifecycle.
    
    This change moves the embedded system-skills packaging into a dedicated
    `codex-skills` crate so it can be cached independently. That reduces
    unnecessary invalidation/rebuild pressure on `codex-core` when the
    skills bundle is the only thing that changes.
    
    ## What Changed
    
    - Added a new `codex-rs/skills` crate (`codex-skills`) with:
      - `Cargo.toml`
      - `BUILD.bazel`
      - `build.rs` to track skill asset file changes for Cargo rebuilds
    - `src/lib.rs` containing the embedded system-skills install/cache logic
    previously in `codex-core`
    - Moved the embedded sample skill assets from
    `codex-rs/core/src/skills/assets/samples` to
    `codex-rs/skills/src/assets/samples`.
    - Updated `codex-rs/core/Cargo.toml` to depend on `codex-skills` and
    removed `codex-core`'s direct `include_dir` dependency.
    - Removed `codex-core`'s `build.rs`.
    - Replaced `codex-rs/core/src/skills/system.rs` implementation with a
    thin re-export wrapper to keep existing `codex-core` call sites
    unchanged.
    - Updated workspace manifests/lockfile (`codex-rs/Cargo.toml`,
    `codex-rs/Cargo.lock`) for the new crate.
  • Move sanitizer into codex-secrets (#12306)
    ## Summary
    - move the sanitizer implementation into `codex-secrets`
    (`secrets/src/sanitizer.rs`) and re-export `redact_secrets`
    - switch `codex-core` to depend on/import `codex-secrets` for sanitizer
    usage
    - remove the old `utils/sanitizer` crate wiring and refresh lockfiles
    
    ## Testing
    - `just fmt`
    - `cargo test -p codex-secrets`
    - `cargo test -p codex-core --no-run`
    - `cargo clippy -p codex-secrets -p codex-core --all-targets
    --all-features -- -D warnings`
    - `just bazel-lock-update`
    - `just bazel-lock-check`
    
    ## Notes
    - not run: `cargo test --all-features` (full workspace suite)
  • fix(bazel): replace askama templates with include_str! in memories (#11778)
    ## Summary
    
    - The experimental Bazel CI builds fail on all platforms because askama
    resolves template paths relative to `CARGO_MANIFEST_DIR`, which points
    outside the Bazel sandbox. This produces errors like:
      ```
    error: couldn't read
    `codex-rs/core/src/memories/../../../../../../../../../../../work/codex/codex/codex-rs/core/templates/memories/consolidation.md`:
    No such file or directory
      ```
    - Replaced `#[derive(Template)]` + `#[template(path = "...")]` with
    `include_str!` + `str::replace()` for the three affected templates
    (`consolidation.md`, `stage_one_input.md`, `read_path.md`).
    `include_str!` resolves paths relative to the source file, which works
    correctly in both Cargo and Bazel builds.
    - The templates only use simple `{{ variable }}` substitution with no
    control flow or filters, so no askama functionality is lost.
    - Removes the `askama` dependency from `codex-core` since it was the
    only crate using it. The workspace-level dependency definition is left
    in place.
    - This matches the existing pattern used throughout the codebase — e.g.
    `codex-rs/core/src/memories/mod.rs` already uses
    `include_str!("../../templates/memories/stage_one_system.md")` for the
    fourth template file.
    
    ## Test plan
    
    - [ ] Verify Bazel (experimental) CI passes on all platforms
    - [ ] Verify rust-ci (Cargo) builds and tests continue to pass
    - [ ] Verify `cargo test -p codex-core` passes locally
  • chore(deps): bump env_logger from 0.11.8 to 0.11.9 in /codex-rs (#11889)
    Bumps [env_logger](https://github.com/rust-cli/env_logger) from 0.11.8
    to 0.11.9.
    <details>
    <summary>Release notes</summary>
    <p><em>Sourced from <a
    href="https://github.com/rust-cli/env_logger/releases">env_logger's
    releases</a>.</em></p>
    <blockquote>
    <h2>v0.11.9</h2>
    <h2>[0.11.9] - 2026-02-11</h2>
    </blockquote>
    </details>
    <details>
    <summary>Changelog</summary>
    <p><em>Sourced from <a
    href="https://github.com/rust-cli/env_logger/blob/main/CHANGELOG.md">env_logger's
    changelog</a>.</em></p>
    <blockquote>
    <h2>[0.11.9] - 2026-02-11</h2>
    </blockquote>
    </details>
    <details>
    <summary>Commits</summary>
    <ul>
    <li><a
    href="https://github.com/rust-cli/env_logger/commit/2f06b4c7cf359b348cf92f95f83176897cedc838"><code>2f06b4c</code></a>
    chore: Release</li>
    <li><a
    href="https://github.com/rust-cli/env_logger/commit/57e13acb42cac437ace7d3b9819f46de1d5f5d5a"><code>57e13ac</code></a>
    chore: Release</li>
    <li><a
    href="https://github.com/rust-cli/env_logger/commit/4f9066d8af43095cf95bb9ddae046095af117dd6"><code>4f9066d</code></a>
    Merge pull request <a
    href="https://redirect.github.com/rust-cli/env_logger/issues/393">#393</a>
    from rust-cli/renovate/crate-ci-typos-1.x</li>
    <li><a
    href="https://github.com/rust-cli/env_logger/commit/3e4709a2665c93f39c0cf63b84ceaea8da42864e"><code>3e4709a</code></a>
    chore(deps): Update Rust crate snapbox to v0.6.24 (<a
    href="https://redirect.github.com/rust-cli/env_logger/issues/394">#394</a>)</li>
    <li><a
    href="https://github.com/rust-cli/env_logger/commit/80ff83adba5f55a293a484e684cd10b88c6739de"><code>80ff83a</code></a>
    chore(deps): Update pre-commit hook crate-ci/typos to v1.42.3</li>
    <li><a
    href="https://github.com/rust-cli/env_logger/commit/76891b9e32d7e0c2a43a6f843a20caaf5adb0782"><code>76891b9</code></a>
    Merge pull request <a
    href="https://redirect.github.com/rust-cli/env_logger/issues/392">#392</a>
    from epage/template</li>
    <li><a
    href="https://github.com/rust-cli/env_logger/commit/14cda4a666db7f262fbc87f752ee2bc4d977100f"><code>14cda4a</code></a>
    chore: Update from _rust template</li>
    <li><a
    href="https://github.com/rust-cli/env_logger/commit/e4f2b351a3d5290a8f26db395bf736e0f80a5856"><code>e4f2b35</code></a>
    chore(ci): Update action</li>
    <li><a
    href="https://github.com/rust-cli/env_logger/commit/6d0d36b0723b29856d380eb89b3c571a9f9c570f"><code>6d0d36b</code></a>
    chore(ci): Clean up previous branch in case it was leaked</li>
    <li><a
    href="https://github.com/rust-cli/env_logger/commit/30b3b14bd665d443f45123729dc69d1f085575f9"><code>30b3b14</code></a>
    chore(ci): Fix how rustfmt jobs run</li>
    <li>Additional commits viewable in <a
    href="https://github.com/rust-cli/env_logger/compare/v0.11.8...v0.11.9">compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    
    [![Dependabot compatibility
    score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=env_logger&package-manager=cargo&previous-version=0.11.8&new-version=0.11.9)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
    
    Dependabot will resolve any conflicts with this PR as long as you don't
    alter it yourself. You can also trigger a rebase manually by commenting
    `@dependabot rebase`.
    
    [//]: # (dependabot-automerge-start)
    [//]: # (dependabot-automerge-end)
    
    ---
    
    <details>
    <summary>Dependabot commands and options</summary>
    <br />
    
    You can trigger Dependabot actions by commenting on this PR:
    - `@dependabot rebase` will rebase this PR
    - `@dependabot recreate` will recreate this PR, overwriting any edits
    that have been made to it
    - `@dependabot show <dependency name> ignore conditions` will show all
    of the ignore conditions of the specified dependency
    - `@dependabot ignore this major version` will close this PR and stop
    Dependabot creating any more for this major version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this minor version` will close this PR and stop
    Dependabot creating any more for this minor version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this dependency` will close this PR and stop
    Dependabot creating any more for this dependency (unless you reopen the
    PR or upgrade to it yourself)
    
    
    </details>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
    Co-authored-by: Eric Traut <etraut@openai.com>
  • feat(tui): prevent macOS idle sleep while turns run (#11711)
    ## Summary
    - add a shared `codex-core` sleep inhibitor that uses native macOS IOKit
    assertions (`IOPMAssertionCreateWithName` / `IOPMAssertionRelease`)
    instead of spawning `caffeinate`
    - wire sleep inhibition to turn lifecycle in `tui` (`TurnStarted`
    enables; `TurnComplete` and abort/error finalization disable)
    - gate this behavior behind a `/experimental` feature toggle
    (`[features].prevent_idle_sleep`) instead of a dedicated `[tui]` config
    flag
    - expose the toggle in `/experimental` on macOS; keep it under
    development on other platforms
    - keep behavior no-op on non-macOS targets
    
    <img width="1326" height="577" alt="image"
    src="https://github.com/user-attachments/assets/73fac06b-97ae-46a2-800a-30f9516cf8a3"
    />
    
    ## Testing
    - `cargo check -p codex-core -p codex-tui`
    - `cargo test -p codex-core sleep_inhibitor::tests -- --nocapture`
    - `cargo test -p codex-core
    tui_config_missing_notifications_field_defaults_to_enabled --
    --nocapture`
    - `cargo test -p codex-core prevent_idle_sleep_is_ -- --nocapture`
    
    ## Semantics and API references
    - This PR targets `caffeinate -i` semantics: prevent *idle system sleep*
    while allowing display idle sleep.
    - `caffeinate -i` mapping in Apple open source (`assertionMap`):
      - `kIdleAssertionFlag -> kIOPMAssertionTypePreventUserIdleSystemSleep`
    - Source:
    https://github.com/apple-oss-distributions/PowerManagement/blob/PowerManagement-1846.60.12/caffeinate/caffeinate.c#L52-L54
    - Apple IOKit docs for assertion types and API:
    -
    https://developer.apple.com/documentation/iokit/iopmlib_h/iopmassertiontypes
    -
    https://developer.apple.com/documentation/iokit/1557092-iopmassertioncreatewithname
      - https://developer.apple.com/library/archive/qa/qa1340/_index.html
    
    ## Codex Electron vs this PR (full stack path)
    - Codex Electron app requests sleep blocking with
    `powerSaveBlocker.start("prevent-app-suspension")`:
    -
    https://github.com/openai/codex/blob/main/codex/codex-vscode/electron/src/electron-message-handler.ts
    - Electron maps that string to Chromium wake lock type
    `kPreventAppSuspension`:
    -
    https://github.com/electron/electron/blob/main/shell/browser/api/electron_api_power_save_blocker.cc
    - Chromium macOS backend maps wake lock types to IOKit assertion
    constants and calls IOKit:
      - `kPreventAppSuspension -> kIOPMAssertionTypeNoIdleSleep`
    - `kPreventDisplaySleep / kPreventDisplaySleepAllowDimming ->
    kIOPMAssertionTypeNoDisplaySleep`
    -
    https://github.com/chromium/chromium/blob/main/services/device/wake_lock/power_save_blocker/power_save_blocker_mac.cc
    
    ## Why this PR uses a different macOS constant name
    - This PR uses `"PreventUserIdleSystemSleep"` directly, via
    `IOPMAssertionCreateWithName`, in
    `codex-rs/core/src/sleep_inhibitor.rs`.
    - Apple’s IOKit header documents `kIOPMAssertionTypeNoIdleSleep` as
    deprecated and recommends `kIOPMAssertPreventUserIdleSystemSleep` /
    `kIOPMAssertionTypePreventUserIdleSystemSleep`:
    -
    https://github.com/apple-oss-distributions/IOKitUser/blob/IOKitUser-100222.60.2/pwr_mgt.subproj/IOPMLib.h#L1000-L1030
    - So Chromium and this PR are using different constant names, but
    semantically equivalent idle-system-sleep prevention behavior.
    
    ## Future platform support
    The architecture is intentionally set up for multi-platform extensions:
    - UI code (`tui`) only calls `SleepInhibitor::set_turn_running(...)` on
    turn lifecycle boundaries.
    - Platform-specific behavior is isolated in
    `codex-rs/core/src/sleep_inhibitor.rs` behind `cfg(...)` blocks.
    - Feature exposure is centralized in `core/src/features.rs` and surfaced
    via `/experimental`.
    - Adding new OS backends should not require additional TUI wiring; only
    the backend internals and feature stage metadata need to change.
    
    Potential follow-up implementations:
    - Windows:
    - Add a backend using Win32 power APIs
    (`SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED)` as
    baseline).
    - Optionally move to `PowerCreateRequest` / `PowerSetRequest` /
    `PowerClearRequest` for richer assertion semantics.
    - Linux:
    - Add a backend using logind inhibitors over D-Bus
    (`org.freedesktop.login1.Manager.Inhibit` with `what="sleep"`).
      - Keep a no-op fallback where logind/D-Bus is unavailable.
    
    This PR keeps the cross-platform API surface minimal so future PRs can
    add Windows/Linux support incrementally with low churn.
    
    ---------
    
    Co-authored-by: jif-oai <jif@openai.com>
  • chore: drop and clean from phase 1 (#11605)
    This PR is mostly cleaning and simplifying phase 1 of memories
  • feat: add sanitizer to redact secrets (#11600)
    Adding a sanitizer crate that can redact API keys and other secret with
    known pattern from a String
  • Extract codex-config from codex-core (#11389)
    `codex-core` had accumulated config loading, requirements parsing,
    constraint logic, and config-layer state handling in a single crate.
    This change extracts that subsystem into `codex-config` to reduce
    `codex-core` rebuild/test surface area and isolate future config work.
    
    ## What Changed
    
    ### Added `codex-config`
    
    - Added new workspace crate `codex-rs/config` (`codex-config`).
    - Added workspace/build wiring in:
      - `codex-rs/Cargo.toml`
      - `codex-rs/config/Cargo.toml`
      - `codex-rs/config/BUILD.bazel`
    - Updated lockfiles (`codex-rs/Cargo.lock`, `MODULE.bazel.lock`).
    - Added `codex-core` -> `codex-config` dependency in
    `codex-rs/core/Cargo.toml`.
    
    ### Moved config internals from `core` into `config`
    
    Moved modules to `codex-rs/config/src/`:
    
    - `core/src/config/constraint.rs` -> `config/src/constraint.rs`
    - `core/src/config_loader/cloud_requirements.rs` ->
    `config/src/cloud_requirements.rs`
    - `core/src/config_loader/config_requirements.rs` ->
    `config/src/config_requirements.rs`
    - `core/src/config_loader/fingerprint.rs` -> `config/src/fingerprint.rs`
    - `core/src/config_loader/merge.rs` -> `config/src/merge.rs`
    - `core/src/config_loader/overrides.rs` -> `config/src/overrides.rs`
    - `core/src/config_loader/requirements_exec_policy.rs` ->
    `config/src/requirements_exec_policy.rs`
    - `core/src/config_loader/state.rs` -> `config/src/state.rs`
    
    `codex-config` now re-exports this surface from `config/src/lib.rs` at
    the crate top level.
    
    ### Updated `core` to consume/re-export `codex-config`
    
    - `core/src/config_loader/mod.rs` now imports/re-exports config-loader
    types/functions from top-level `codex_config::*`.
    - Local moved modules were removed from `core/src/config_loader/`.
    - `core/src/config/mod.rs` now re-exports constraint types from
    `codex_config`.
  • feat: split codex-common into smaller utils crates (#11422)
    We are removing feature-gated shared crates from the `codex-rs`
    workspace. `codex-common` grouped several unrelated utilities behind
    `[features]`, which made dependency boundaries harder to reason about
    and worked against the ongoing effort to eliminate feature flags from
    workspace crates.
    
    Splitting these utilities into dedicated crates under `utils/` aligns
    this area with existing workspace structure and keeps each dependency
    explicit at the crate boundary.
    
    ## What changed
    
    - Removed `codex-rs/common` (`codex-common`) from workspace members and
    workspace dependencies.
    - Added six new utility crates under `codex-rs/utils/`:
      - `codex-utils-cli`
      - `codex-utils-elapsed`
      - `codex-utils-sandbox-summary`
      - `codex-utils-approval-presets`
      - `codex-utils-oss`
      - `codex-utils-fuzzy-match`
    - Migrated the corresponding modules out of `codex-common` into these
    crates (with tests), and added matching `BUILD.bazel` targets.
    - Updated direct consumers to use the new crates instead of
    `codex-common`:
      - `codex-rs/cli`
      - `codex-rs/tui`
      - `codex-rs/exec`
      - `codex-rs/app-server`
      - `codex-rs/mcp-server`
      - `codex-rs/chatgpt`
      - `codex-rs/cloud-tasks`
    - Updated workspace lockfile entries to reflect the new dependency graph
    and removal of `codex-common`.
  • chore: rename codex-command to codex-shell-command (#11378)
    This addresses some post-merge feedback on
    https://github.com/openai/codex/pull/11361:
    
    - crate rename
    - reuse `detect_shell_type()` utility
  • # Split command parsing/safety out of codex-core into new codex-command (#11361)
    `codex-core` had accumulated command parsing and command safety logic
    (`bash`, `powershell`, `parse_command`, and `command_safety`) that is
    logically cohesive but orthogonal to most core session/runtime logic.
    Keeping this code in `codex-core` made the crate increasingly monolithic
    and raised iteration cost for unrelated core changes.
    
    This change extracts that surface into a dedicated crate,
    `codex-command`, while preserving existing `codex_core::...` call sites
    via re-exports.
    
    ## Why this refactor
    
    During analysis, command parsing/safety stood out as a good first split
    because it has:
    
    - a clear domain boundary (shell parsing + safety classification)
    - relatively self-contained dependencies (notably `tree-sitter` /
    `tree-sitter-bash`)
    - a meaningful standalone test surface (`134` tests moved with the
    crate)
    - many downstream uses that benefit from independent compilation and
    caching
    
    The practical problem was build latency from a large `codex-core`
    compile/test graph. Clean-build timings before and after this split
    showed measurable wins:
    
    - `cargo check -p codex-core`: `57.08s` -> `53.54s` (~`6.2%` faster)
    - `cargo test -p codex-core --no-run`: `2m39.9s` -> `2m20s` (~`12.4%`
    faster)
    - `codex-core lib` compile unit: `57.18s` -> `49.67s` (~`13.1%` faster)
    - `codex-core lib(test)` compile unit: `60.87s` -> `53.21s` (~`12.6%`
    faster)
    
    This gives a concrete reduction in core build overhead without changing
    behavior.
    
    ## What changed
    
    ### New crate
    
    - Added `codex-rs/command` as workspace crate `codex-command`.
    - Added:
      - `command/src/lib.rs`
      - `command/src/bash.rs`
      - `command/src/powershell.rs`
      - `command/src/parse_command.rs`
      - `command/src/command_safety/*`
      - `command/src/shell_detect.rs`
      - `command/BUILD.bazel`
    
    ### Code moved out of `codex-core`
    
    - Moved modules from `core/src` into `command/src`:
      - `bash.rs`
      - `powershell.rs`
      - `parse_command.rs`
      - `command_safety/*`
    
    ### Dependency graph updates
    
    - Added workspace member/dependency entries for `codex-command` in
    `codex-rs/Cargo.toml`.
    - Added `codex-command` dependency to `codex-rs/core/Cargo.toml`.
    - Removed `tree-sitter` and `tree-sitter-bash` from `codex-core` direct
    deps (now owned by `codex-command`).
    
    ### API compatibility for callers
    
    To avoid immediate downstream churn, `codex-core` now re-exports the
    moved modules/functions:
    
    - `codex_command::bash`
    - `codex_command::powershell`
    - `codex_command::parse_command`
    - `codex_command::is_safe_command`
    - `codex_command::is_dangerous_command`
    
    This keeps existing `codex_core::...` paths working while enabling
    gradual migration to direct `codex-command` usage.
    
    ### Internal decoupling detail
    
    - Added `command::shell_detect` so moved `bash`/`powershell` logic no
    longer depends on core shell internals.
    - Adjusted PowerShell helper visibility in `codex-command` for existing
    core test usage (`UTF8` prefix helper + executable discovery functions).
    
    ## Validation
    
    - `just fmt`
    - `just fix -p codex-command -p codex-core`
    - `cargo test -p codex-command` (`134` passed)
    - `cargo test -p codex-core --no-run`
    - `cargo test -p codex-core shell_command_handler`
    
    ## Notes / follow-up
    
    This commit intentionally prioritizes boundary extraction and
    compatibility. A follow-up can migrate downstream crates to depend
    directly on `codex-command` (instead of through `codex-core` re-exports)
    to realize additional incremental build wins.
  • Extract hooks into dedicated crate (#11311)
    Summary
    - move `core/src/hooks` implementation into a new `codex-hooks` crate
    with its own manifest
    - update `codex-rs` workspace and `codex-core` crate to depend on the
    extracted `hooks` crate and wire up the shared APIs
    - ensure references, modules, and lockfile reflect the new crate layout
    
    Testing
    - Not run (not requested)
  • memories: add extraction and prompt module foundation (#11200)
    ## Summary
    - add the new `core/src/memories` module (phase-one parsing, rollout
    filtering, storage, selection, prompts)
    - add Askama-backed memory templates for stage-one input/system and
    consolidation prompts
    - add module tests for parsing, filtering, path bucketing, and summary
    maintenance
    
    ## Testing
    - just fmt
    - cargo test -p codex-core --lib memories::
  • chore: put crypto provider logic in a shared crate (#11294)
    Ensures a process-wide rustls crypto provider is installed.
    
    Both the `codex-network-proxy` and `codex-api` crates need this.
  • chore(deps): bump regex from 1.12.2 to 1.12.3 in /codex-rs (#11138)
    Bumps [regex](https://github.com/rust-lang/regex) from 1.12.2 to 1.12.3.
    <details>
    <summary>Changelog</summary>
    <p><em>Sourced from <a
    href="https://github.com/rust-lang/regex/blob/master/CHANGELOG.md">regex's
    changelog</a>.</em></p>
    <blockquote>
    <h1>1.12.3 (2025-02-03)</h1>
    <p>This release excludes some unnecessary things from the archive
    published to
    crates.io. Specifically, fuzzing data and various shell scripts are now
    excluded. If you run into problems, please file an issue.</p>
    <p>Improvements:</p>
    <ul>
    <li><a
    href="https://redirect.github.com/rust-lang/regex/pull/1319">#1319</a>:
    Switch from a Cargo <code>exclude</code> list to an <code>include</code>
    list, and exclude some
    unnecessary stuff.</li>
    </ul>
    </blockquote>
    </details>
    <details>
    <summary>Commits</summary>
    <ul>
    <li><a
    href="https://github.com/rust-lang/regex/commit/b028e4f40eac8959d05e82abf8404906b1c565c0"><code>b028e4f</code></a>
    1.12.3</li>
    <li><a
    href="https://github.com/rust-lang/regex/commit/5e195de266e203441b2c8001d6ebefab1161a59e"><code>5e195de</code></a>
    regex-automata-0.4.14</li>
    <li><a
    href="https://github.com/rust-lang/regex/commit/a3433f691863d80300dfd6a52e332cb5a568e895"><code>a3433f6</code></a>
    regex-syntax-0.8.9</li>
    <li><a
    href="https://github.com/rust-lang/regex/commit/0c07fae444adf0802d84455e689f1143d2dd7790"><code>0c07fae</code></a>
    regex-lite-0.1.9</li>
    <li><a
    href="https://github.com/rust-lang/regex/commit/6a810068f030c023a12c93ccae49bc5fd907c4f6"><code>6a81006</code></a>
    cargo: exclude development scripts and fuzzing data</li>
    <li><a
    href="https://github.com/rust-lang/regex/commit/4733e28ba4f281f643ce93e4089eccbb9a9d5a5a"><code>4733e28</code></a>
    automata: fix <code>onepass::DFA::try_search_slots</code> panic when too
    many slots are ...</li>
    <li>See full diff in <a
    href="https://github.com/rust-lang/regex/compare/1.12.2...1.12.3">compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    
    [![Dependabot compatibility
    score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=regex&package-manager=cargo&previous-version=1.12.2&new-version=1.12.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
    
    Dependabot will resolve any conflicts with this PR as long as you don't
    alter it yourself. You can also trigger a rebase manually by commenting
    `@dependabot rebase`.
    
    [//]: # (dependabot-automerge-start)
    [//]: # (dependabot-automerge-end)
    
    ---
    
    <details>
    <summary>Dependabot commands and options</summary>
    <br />
    
    You can trigger Dependabot actions by commenting on this PR:
    - `@dependabot rebase` will rebase this PR
    - `@dependabot recreate` will recreate this PR, overwriting any edits
    that have been made to it
    - `@dependabot show <dependency name> ignore conditions` will show all
    of the ignore conditions of the specified dependency
    - `@dependabot ignore this major version` will close this PR and stop
    Dependabot creating any more for this major version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this minor version` will close this PR and stop
    Dependabot creating any more for this minor version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this dependency` will close this PR and stop
    Dependabot creating any more for this dependency (unless you reopen the
    PR or upgrade to it yourself)
    
    
    </details>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
  • chore(deps): bump insta from 1.46.2 to 1.46.3 in /codex-rs (#11140)
    Bumps [insta](https://github.com/mitsuhiko/insta) from 1.46.2 to 1.46.3.
    <details>
    <summary>Release notes</summary>
    <p><em>Sourced from <a
    href="https://github.com/mitsuhiko/insta/releases">insta's
    releases</a>.</em></p>
    <blockquote>
    <h2>1.46.3</h2>
    <h2>Release Notes</h2>
    <ul>
    <li>Fix inline escaped snapshots incorrectly stripping leading newlines
    when content contains control characters like carriage returns. The
    escaped format (used for snapshots with control chars) now correctly
    preserves the original content without stripping a non-existent
    formatting newline. <a
    href="https://redirect.github.com/mitsuhiko/insta/issues/865">#865</a></li>
    </ul>
    <h2>Install cargo-insta 1.46.3</h2>
    <h3>Install prebuilt binaries via shell script</h3>
    <pre lang="sh"><code>curl --proto '=https' --tlsv1.2 -LsSf
    https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-installer.sh
    | sh
    </code></pre>
    <h3>Install prebuilt binaries via powershell script</h3>
    <pre lang="sh"><code>powershell -ExecutionPolicy Bypass -c &quot;irm
    https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-installer.ps1
    | iex&quot;
    </code></pre>
    <h2>Download cargo-insta 1.46.3</h2>
    <table>
    <thead>
    <tr>
    <th>File</th>
    <th>Platform</th>
    <th>Checksum</th>
    </tr>
    </thead>
    <tbody>
    <tr>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-aarch64-apple-darwin.tar.xz">cargo-insta-aarch64-apple-darwin.tar.xz</a></td>
    <td>Apple Silicon macOS</td>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-aarch64-apple-darwin.tar.xz.sha256">checksum</a></td>
    </tr>
    <tr>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-x86_64-apple-darwin.tar.xz">cargo-insta-x86_64-apple-darwin.tar.xz</a></td>
    <td>Intel macOS</td>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-x86_64-apple-darwin.tar.xz.sha256">checksum</a></td>
    </tr>
    <tr>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-x86_64-pc-windows-msvc.zip">cargo-insta-x86_64-pc-windows-msvc.zip</a></td>
    <td>x64 Windows</td>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-x86_64-pc-windows-msvc.zip.sha256">checksum</a></td>
    </tr>
    <tr>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-x86_64-unknown-linux-gnu.tar.xz">cargo-insta-x86_64-unknown-linux-gnu.tar.xz</a></td>
    <td>x64 Linux</td>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-x86_64-unknown-linux-gnu.tar.xz.sha256">checksum</a></td>
    </tr>
    <tr>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-x86_64-unknown-linux-musl.tar.xz">cargo-insta-x86_64-unknown-linux-musl.tar.xz</a></td>
    <td>x64 MUSL Linux</td>
    <td><a
    href="https://github.com/mitsuhiko/insta/releases/download/1.46.3/cargo-insta-x86_64-unknown-linux-musl.tar.xz.sha256">checksum</a></td>
    </tr>
    </tbody>
    </table>
    </blockquote>
    </details>
    <details>
    <summary>Changelog</summary>
    <p><em>Sourced from <a
    href="https://github.com/mitsuhiko/insta/blob/master/CHANGELOG.md">insta's
    changelog</a>.</em></p>
    <blockquote>
    <h2>1.46.3</h2>
    <ul>
    <li>Fix inline escaped snapshots incorrectly stripping leading newlines
    when content contains control characters like carriage returns. The
    escaped format (used for snapshots with control chars) now correctly
    preserves the original content without stripping a non-existent
    formatting newline. <a
    href="https://redirect.github.com/mitsuhiko/insta/issues/865">#865</a></li>
    </ul>
    </blockquote>
    </details>
    <details>
    <summary>Commits</summary>
    <ul>
    <li><a
    href="https://github.com/mitsuhiko/insta/commit/13245901751701f45677b9cfe3537c182b47af02"><code>1324590</code></a>
    Release 1.46.3 (<a
    href="https://redirect.github.com/mitsuhiko/insta/issues/870">#870</a>)</li>
    <li><a
    href="https://github.com/mitsuhiko/insta/commit/b26bc7ffe1653d42e274077bb711559f2cd5a553"><code>b26bc7f</code></a>
    Fix escaped format inline snapshots not stripping formatting newline (<a
    href="https://redirect.github.com/mitsuhiko/insta/issues/869">#869</a>)</li>
    <li>See full diff in <a
    href="https://github.com/mitsuhiko/insta/compare/1.46.2...1.46.3">compare
    view</a></li>
    </ul>
    </details>
    <br />
    
    
    [![Dependabot compatibility
    score](https://dependabot-badges.githubapp.com/badges/compatibility_score?dependency-name=insta&package-manager=cargo&previous-version=1.46.2&new-version=1.46.3)](https://docs.github.com/en/github/managing-security-vulnerabilities/about-dependabot-security-updates#about-compatibility-scores)
    
    Dependabot will resolve any conflicts with this PR as long as you don't
    alter it yourself. You can also trigger a rebase manually by commenting
    `@dependabot rebase`.
    
    [//]: # (dependabot-automerge-start)
    [//]: # (dependabot-automerge-end)
    
    ---
    
    <details>
    <summary>Dependabot commands and options</summary>
    <br />
    
    You can trigger Dependabot actions by commenting on this PR:
    - `@dependabot rebase` will rebase this PR
    - `@dependabot recreate` will recreate this PR, overwriting any edits
    that have been made to it
    - `@dependabot show <dependency name> ignore conditions` will show all
    of the ignore conditions of the specified dependency
    - `@dependabot ignore this major version` will close this PR and stop
    Dependabot creating any more for this major version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this minor version` will close this PR and stop
    Dependabot creating any more for this minor version (unless you reopen
    the PR or upgrade to it yourself)
    - `@dependabot ignore this dependency` will close this PR and stop
    Dependabot creating any more for this dependency (unless you reopen the
    PR or upgrade to it yourself)
    
    
    </details>
    
    Signed-off-by: dependabot[bot] <support@github.com>
    Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>