Commit Graph

62 Commits

  • fix: --search shouldn't show deprecation message (#6180)
    Use the new feature flags instead of the old config.
  • Windows Sandbox - Alpha version (#4905)
    - Added the new codex-windows-sandbox crate that builds both a library
    entry point (run_windows_sandbox_capture) and a CLI executable to launch
    commands inside a Windows restricted-token sandbox, including ACL
    management, capability SID provisioning, network lockdown, and output
    capture
    (windows-sandbox-rs/src/lib.rs:167, windows-sandbox-rs/src/main.rs:54).
    - Introduced the experimental WindowsSandbox feature flag and wiring so
    Windows builds can opt into the sandbox:
    SandboxType::WindowsRestrictedToken, the in-process execution path, and
    platform sandbox selection now honor the flag (core/src/features.rs:47,
    core/src/config.rs:1224, core/src/safety.rs:19,
    core/src/sandboxing/mod.rs:69, core/src/exec.rs:79,
    core/src/exec.rs:172).
    - Updated workspace metadata to include the new crate and its
    Windows-specific dependencies so the core crate can link against it
    (codex-rs/
        Cargo.toml:91, core/Cargo.toml:86).
    - Added a PowerShell bootstrap script that installs the Windows
    toolchain, required CLI utilities, and builds the workspace to ease
    development
        on the platform (scripts/setup-windows.ps1:1).
    - Landed a Python smoke-test suite that exercises
    read-only/workspace-write policies, ACL behavior, and network denial for
    the Windows sandbox
        binary (windows-sandbox-rs/sandbox_smoketests.py:1).
  • fix terminal corruption that could happen when onboarding and update banner (#5269)
    Instead of printing characters before booting the app, make the upgrade
    banner a history cell so it's well-behaved.
    
    <img width="771" height="586" alt="Screenshot 2025-10-16 at 4 20 51 PM"
    src="https://github.com/user-attachments/assets/90629d47-2c3d-4970-a826-283795ab34e5"
    />
    
    ---------
    
    Co-authored-by: Josh McKinney <joshka@openai.com>
  • fix: update CLI usage order for codex -h (#5356)
    Set clap usage override so help lists subcommands before the prompt
    argument.
  • feat: add --add-dir flag for extra writable roots (#5335)
    Add a `--add-dir` CLI flag so sessions can use extra writable roots in
    addition to the ones specified in the config file. These are ephemerally
    added during the session only.
    
    Fixes #3303
    Fixes #2797
  • feat: Auto update approval (#5185)
    Adds an update prompt when the CLI starts:
    
    <img width="1410" height="608" alt="Screenshot 2025-10-14 at 5 53 17 PM"
    src="https://github.com/user-attachments/assets/47c8bafa-7bed-4be8-b597-c4c6c79756b8"
    />
  • feat: feature flag (#4948)
    Add proper feature flag instead of having custom flags for everything.
    This is just for experimental/wip part of the code
    It can be used through CLI:
    ```bash
    codex --enable unified_exec --disable view_image_tool
    ```
    
    Or in the `config.toml`
    ```toml
    # Global toggles applied to every profile unless overridden.
    [features]
    apply_patch_freeform = true
    view_image_tool = false
    ```
    
    Follow-up:
    In a following PR, the goal is to have a default have `bundles` of
    features that we can associate to a model
  • Create alias (#4971)
    # External (non-OpenAI) Pull Request Requirements
    
    Before opening this Pull Request, please read the dedicated
    "Contributing" markdown file or your PR may be closed:
    https://github.com/openai/codex/blob/main/docs/contributing.md
    
    If your PR conforms to our contribution guidelines, replace this text
    with a detailed and high quality description of your changes.
  • remove experimental prefix (#4907)
    # External (non-OpenAI) Pull Request Requirements
    
    Before opening this Pull Request, please read the dedicated
    "Contributing" markdown file or your PR may be closed:
    https://github.com/openai/codex/blob/main/docs/contributing.md
    
    If your PR conforms to our contribution guidelines, replace this text
    with a detailed and high quality description of your changes.
  • print codex resume note when quitting after codex resume (#4695)
    when exiting a session that was started with `codex resume`, the note
    about how to resume again wasn't being printed.
    
    thanks @aibrahim-oai for pointing out this issue!
  • add codex sandbox {linux|macos} (#4782)
    ## Summary
    - add a `codex sandbox` subcommand with macOS and Linux targets while
    keeping the legacy `codex debug` aliases
    - update documentation to highlight the new sandbox entrypoints and
    point existing references to the new command
    - clarify the core README about the linux sandbox helper alias
    
    ## Testing
    - just fmt
    - just fix -p codex-cli
    - cargo test -p codex-cli
    
    
    ------
    https://chatgpt.com/codex/tasks/task_i_68e2e00ca1e8832d8bff53aa0b50b49e
  • Use assert_matches (#4756)
    assert_matches is soon to be in std but is experimental for now.
  • fix: replace --api-key with --with-api-key in codex login (#4646)
    Previously, users could supply their API key directly via:
    
    ```shell
    codex login --api-key KEY
    ```
    
    but this has the drawback that `KEY` is more likely to end up in shell
    history, can be read from `/proc`, etc.
    
    This PR removes support for `--api-key` and replaces it with
    `--with-api-key`, which reads the key from stdin, so either of these are
    better options:
    
    ```
    printenv OPENAI_API_KEY | codex login --with-api-key
    codex login --with-api-key < my_key.txt
    ```
    
    Other CLIs, such as `gh auth login --with-token`, follow the same
    practice.
  • fix: remove mcp-types from app server protocol (#4537)
    We continue the separation between `codex app-server` and `codex
    mcp-server`.
    
    In particular, we introduce a new crate, `codex-app-server-protocol`,
    and migrate `codex-rs/protocol/src/mcp_protocol.rs` into it, renaming it
    `codex-rs/app-server-protocol/src/protocol.rs`.
    
    Because `ConversationId` was defined in `mcp_protocol.rs`, we move it
    into its own file, `codex-rs/protocol/src/conversation_id.rs`, and
    because it is referenced in a ton of places, we have to touch a lot of
    files as part of this PR.
    
    We also decide to get away from proper JSON-RPC 2.0 semantics, so we
    also introduce `codex-rs/app-server-protocol/src/jsonrpc_lite.rs`, which
    is basically the same `JSONRPCMessage` type defined in `mcp-types`
    except with all of the `"jsonrpc": "2.0"` removed.
    
    Getting rid of `"jsonrpc": "2.0"` makes our serialization logic
    considerably simpler, as we can lean heavier on serde to serialize
    directly into the wire format that we use now.
  • fix: enable process hardening in Codex CLI for release builds (#4521)
    I don't believe there is any upside in making process hardening opt-in
    for Codex CLI releases. If you want to tinker with Codex CLI, then build
    from source (or run as `root`)?
  • Add cloud tasks (#3197)
    Adds a TUI for managing, applying, and creating cloud tasks
  • fix: separate codex mcp into codex mcp-server and codex app-server (#4471)
    This is a very large PR with some non-backwards-compatible changes.
    
    Historically, `codex mcp` (or `codex mcp serve`) started a JSON-RPC-ish
    server that had two overlapping responsibilities:
    
    - Running an MCP server, providing some basic tool calls.
    - Running the app server used to power experiences such as the VS Code
    extension.
    
    This PR aims to separate these into distinct concepts:
    
    - `codex mcp-server` for the MCP server
    - `codex app-server` for the "application server"
    
    Note `codex mcp` still exists because it already has its own subcommands
    for MCP management (`list`, `add`, etc.)
    
    The MCP logic continues to live in `codex-rs/mcp-server` whereas the
    refactored app server logic is in the new `codex-rs/app-server` folder.
    Note that most of the existing integration tests in
    `codex-rs/mcp-server/tests/suite` were actually for the app server, so
    all the tests have been moved with the exception of
    `codex-rs/mcp-server/tests/suite/mod.rs`.
    
    Because this is already a large diff, I tried not to change more than I
    had to, so `codex-rs/app-server/tests/common/mcp_process.rs` still uses
    the name `McpProcess` for now, but I will do some mechanical renamings
    to things like `AppServer` in subsequent PRs.
    
    While `mcp-server` and `app-server` share some overlapping functionality
    (like reading streams of JSONL and dispatching based on message types)
    and some differences (completely different message types), I ended up
    doing a bit of copypasta between the two crates, as both have somewhat
    similar `message_processor.rs` and `outgoing_message.rs` files for now,
    though I expect them to diverge more in the near future.
    
    One material change is that of the initialize handshake for `codex
    app-server`, as we no longer use the MCP types for that handshake.
    Instead, we update `codex-rs/protocol/src/mcp_protocol.rs` to add an
    `Initialize` variant to `ClientRequest`, which takes the `ClientInfo`
    object we need to update the `USER_AGENT_SUFFIX` in
    `codex-rs/app-server/src/message_processor.rs`.
    
    One other material change is in
    `codex-rs/app-server/src/codex_message_processor.rs` where I eliminated
    a use of the `send_event_as_notification()` method I am generally trying
    to deprecate (because it blindly maps an `EventMsg` into a
    `JSONNotification`) in favor of `send_server_notification()`, which
    takes a `ServerNotification`, as that is intended to be a custom enum of
    all notification types supported by the app server. So to make this
    update, I had to introduce a new variant of `ServerNotification`,
    `SessionConfigured`, which is a non-backwards compatible change with the
    old `codex mcp`, and clients will have to be updated after the next
    release that contains this PR. Note that
    `codex-rs/app-server/tests/suite/list_resume.rs` also had to be update
    to reflect this change.
    
    I introduced `codex-rs/utils/json-to-toml/src/lib.rs` as a small utility
    crate to avoid some of the copying between `mcp-server` and
    `app-server`.
  • Rakesh/support device auth (#3531)
    # External (non-OpenAI) Pull Request Requirements
    
    Before opening this Pull Request, please read the dedicated
    "Contributing" markdown file or your PR may be closed:
    https://github.com/openai/codex/blob/main/docs/contributing.md
    
    If your PR conforms to our contribution guidelines, replace this text
    with a detailed and high quality description of your changes.
    
    # test
    
    ```
    codex-rs % export CODEX_DEVICE_AUTH_BASE_URL=http://localhost:3007
    codex-rs % cargo run --bin codex login --experimental_use-device-code
       Compiling codex-login v0.0.0 (/Users/rakesh/code/codex/codex-rs/login)
       Compiling codex-mcp-server v0.0.0 (/Users/rakesh/code/codex/codex-rs/mcp-server)
       Compiling codex-tui v0.0.0 (/Users/rakesh/code/codex/codex-rs/tui)
       Compiling codex-cli v0.0.0 (/Users/rakesh/code/codex/codex-rs/cli)
        Finished `dev` profile [unoptimized + debuginfo] target(s) in 2.90s
         Running `target/debug/codex login --experimental_use-device-code`
    To authenticate, enter this code when prompted: 6Q27-KBVRF with interval 5
    ^C
    
    ```
    
    The error in the last line is since the poll endpoint is not yet
    implemented
  • chore: remove responses-api-proxy from the multitool (#4404)
    This removes the `codex responses-api-proxy` subcommand in favor of
    running it as a standalone CLI.
    
    As part of this change, we:
    
    - remove the dependency on `tokio`/`async/await` as well as `codex_arg0`
    - introduce the use of `pre_main_hardening()` so `CODEX_SECURE_MODE=1`
    is not required
    
    ---
    [//]: # (BEGIN SAPLING FOOTER)
    Stack created with [Sapling](https://sapling-scm.com). Best reviewed
    with [ReviewStack](https://reviewstack.dev/openai/codex/pull/4404).
    * #4406
    * __->__ #4404
    * #4403
  • feat: introduce responses-api-proxy (#4246)
    Details are in `responses-api-proxy/README.md`, but the key contribution
    of this PR is a new subcommand, `codex responses-api-proxy`, which reads
    the auth token for use with the OpenAI Responses API from `stdin` at
    startup and then proxies `POST` requests to `/v1/responses` over to
    `https://api.openai.com/v1/responses`, injecting the auth token as part
    of the `Authorization` header.
    
    The expectation is that `codex responses-api-proxy` is launched by a
    privileged user who has access to the auth token so that it can be used
    by unprivileged users of the Codex CLI on the same host.
    
    If the client only has one user account with `sudo`, one option is to:
    
    - run `sudo codex responses-api-proxy --http-shutdown --server-info
    /tmp/server-info.json` to start the server
    - record the port written to `/tmp/server-info.json`
    - relinquish their `sudo` privileges (which is irreversible!) like so:
    
    ```
    sudo deluser $USER sudo || sudo gpasswd -d $USER sudo || true
    ```
    
    - use `codex` with the proxy (see `README.md`)
    - when done, make a `GET` request to the server using the `PORT` from
    `server-info.json` to shut it down:
    
    ```shell
    curl --fail --silent --show-error "http://127.0.0.1:$PORT/shutdown"
    ```
    
    To protect the auth token, we:
    
    - allocate a 1024 byte buffer on the stack and write `"Bearer "` into it
    to start
    - we then read from `stdin`, copying to the contents into the buffer
    after the prefix
    - after verifying the input looks good, we create a `String` from that
    buffer (so the data is now on the heap)
    - we zero out the stack-allocated buffer using
    https://crates.io/crates/zeroize so it is not optimized away by the
    compiler
    - we invoke `.leak()` on the `String` so we can treat its contents as a
    `&'static str`, as it will live for the rest of the processs
    - on UNIX, we `mlock(2)` the memory backing the `&'static str`
    - when using the `&'static str` when building an HTTP request, we use
    `HeaderValue::from_static()` to avoid copying the `&str`
    - we also invoke `.set_sensitive(true)` on the `HeaderValue`, which in
    theory indicates to other parts of the HTTP stack that the header should
    be treated with "special care" to avoid leakage:
    
    
    https://github.com/hyperium/http/blob/439d1c50d71e3be3204b6c4a1bf2255ed78e1f93/src/header/value.rs#L346-L376
  • feat: add support for CODEX_SECURE_MODE=1 to restrict process observability (#4220)
    Because the `codex` process could contain sensitive information in
    memory, such as API keys, we add logic so that when
    `CODEX_SECURE_MODE=1` is specified, we avail ourselves of whatever the
    operating system provides to restrict observability/tampering, which
    includes:
    
    - disabling `ptrace(2)`, so it is not possible to attach to the process
    with a debugger, such as `gdb`
    - disabling core dumps
    
    Admittedly, a user with root privileges can defeat these safeguards.
    
    For now, we only add support for this in the `codex` multitool, but we
    may ultimately want to support this in some of the smaller CLIs that are
    buildable out of our Cargo workspace.
  • fix codex resume message at end of session (#3957)
    This was only being printed when running the codex-tui executable
    directly, not via the codex-cli wrapper.
  • hint for codex resume on tui exit (#3757)
    <img width="931" height="438" alt="Screenshot 2025-09-16 at 4 25 19 PM"
    src="https://github.com/user-attachments/assets/ccfb8df1-feaf-45b4-8f7f-56100de916d5"
    />
  • Fix codex resume so flags (cd, model, search, etc.) still work (#3625)
    Bug: now we can add flags/config values only before resume. 
    
    `codex -m gpt-5 resume` works
    
    However, `codex resume -m gpt-5` should also work.
    
    This PR is following this
    [approach](https://stackoverflow.com/questions/76408952/rust-clap-re-use-same-arguments-in-different-subcommand)
    in doing so.
    
    I didn't convert those flags to global because we have `codex login`
    that shouldn't expect them.
  • initial mcp add interface (#3543)
    Adds `codex mcp add`, `codex mcp list`, `codex mcp remove`. Currently writes to global config.
  • enable-resume (#3537)
    Adding the ability to resume conversations.
    we have one verb `resume`. 
    
    Behavior:
    
    `tui`:
    `codex resume`: opens session picker
    `codex resume --last`: continue last message
    `codex resume <session id>`: continue conversation with `session id`
    
    `exec`:
    `codex resume --last`: continue last conversation
    `codex resume <session id>`: continue conversation with `session id`
    
    Implementation:
    - I added a function to find the path in `~/.codex/sessions/` with a
    `UUID`. This is helpful in resuming with session id.
    - Added the above mentioned flags
    - Added lots of testing
  • Added new auth-related methods and events to mcp server (#2496)
    This PR adds the following:
    * A getAuthStatus method on the mcp server. This returns the auth method
    currently in use (chatgpt or apikey) or none if the user is not
    authenticated. It also returns the "preferred auth method" which
    reflects the `preferred_auth_method` value in the config.
    * A logout method on the mcp server. If called, it logs out the user and
    deletes the `auth.json` file — the same behavior in the cli's `/logout`
    command.
    * An `authStatusChange` event notification that is sent when the auth
    status changes due to successful login or logout operations.
    * Logic to pass command-line config overrides to the mcp server at
    startup time. This allows use cases like `codex mcp -c
    preferred_auth_method=apikey`.
  • fix: display canonical command name in help (#2246)
    ## Summary
    - ensure CLI help uses `codex` as program name regardless of binary
    filename
    
    ## Testing
    - `just fmt`
    - `just fix` *(fails: `let` expressions in this position are unstable)*
    - `cargo test --all-features` *(fails: `let` expressions in this
    position are unstable)*
    
    ------
    https://chatgpt.com/codex/tasks/task_i_689bd5a731188320814dcbbc546ce22a
  • Add logout command to CLI and TUI (#1932)
    ## Summary
    - support `codex logout` via new subcommand and helper that removes the
    stored `auth.json`
    - expose a `logout` function in `codex-login` and test it
    - add `/logout` slash command in the TUI; command list is filtered when
    not logged in and the handler deletes `auth.json` then exits
    
    ## Testing
    - `just fix` *(fails: failed to get `diffy` from crates.io)*
    - `cargo test --all-features` *(fails: failed to get `diffy` from
    crates.io)*
    
    ------
    https://chatgpt.com/codex/tasks/task_i_68945c3facac832ca83d48499716fb51
  • First pass at a TUI onboarding (#1876)
    This sets up the scaffolding and basic flow for a TUI onboarding
    experience. It covers sign in with ChatGPT, env auth, as well as some
    safety guidance.
    
    Next up:
    1. Replace the git warning screen
    2. Use this to configure default approval/sandbox modes
    
    
    Note the shimmer flashes are from me slicing the video, not jank.
    
    https://github.com/user-attachments/assets/0fbe3479-fdde-41f3-87fb-a7a83ab895b8
  • Add codex login --api-key (#1759)
    Allow setting the API key via `codex login --api-key`
  • Add login status command (#1716)
    Print the current login mode, sanitized key and return an appropriate
    status.
  • replace login screen with a simple prompt (#1713)
    Perhaps there was an intention to make the login screen prettier, but it
    feels quite silly right now to just have a screen that says "press q",
    so replace it with something that lets the user directly login without
    having to quit the app.
    
    <img width="1283" height="635" alt="Screenshot 2025-07-28 at 2 54 05 PM"
    src="https://github.com/user-attachments/assets/f19e5595-6ef9-4a2d-b409-aa61b30d3628"
    />
  • Easily Selectable History (#1672)
    This update replaces the previous ratatui history widget with an
    append-only log so that the terminal can handle text selection and
    scrolling. It also disables streaming responses, which we'll do our best
    to bring back in a later PR. It also adds a small summary of token use
    after the TUI exits.
  • Fix flaky test (#1664)
    Co-authored-by: aibrahim-oai <aibrahim@openai.com>
  • Add codex apply to apply a patch created from the Codex remote agent (#1528)
    In order to to this, I created a new `chatgpt` crate where we can put
    any code that interacts directly with ChatGPT as opposed to the OpenAI
    API. I added a disclaimer to the README for it that it should primarily
    be modified by OpenAI employees.
    
    
    https://github.com/user-attachments/assets/bb978e33-d2c9-4d8e-af28-c8c25b1988e8
  • fix: the completion subcommand should assume the CLI is named codex, not codex-cli (#1496)
    Current 0.4.0 release:
    
    ```
    ~/code/codex2/codex-rs$ codex completion | head
    _codex-cli() {
        local i cur prev opts cmd
        COMPREPLY=()
        if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
            cur="$2"
        else
            cur="${COMP_WORDS[COMP_CWORD]}"
        fi
        prev="$3"
        cmd=""
    ```
    
    with this change:
    
    ```
    ~/code/codex2/codex-rs$ just codex completion | head
    cargo run --bin codex -- "$@"
        Finished `dev` profile [unoptimized + debuginfo] target(s) in 0.82s
         Running `target/debug/codex completion`
    _codex() {
        local i cur prev opts cmd
        COMPREPLY=()
        if [[ "${BASH_VERSINFO[0]}" -ge 4 ]]; then
            cur="$2"
        else
            cur="${COMP_WORDS[COMP_CWORD]}"
        fi
        prev="$3"
        cmd=""
    ```
  • feat: add support for login with ChatGPT (#1212)
    This does not implement the full Login with ChatGPT experience, but it
    should unblock people.
    
    **What works**
    
    * The `codex` multitool now has a `login` subcommand, so you can run
    `codex login`, which should write `CODEX_HOME/auth.json` if you complete
    the flow successfully. The TUI will now read the `OPENAI_API_KEY` from
    `auth.json`.
    * The TUI should refresh the token if it has expired and the necessary
    information is in `auth.json`.
    * There is a `LoginScreen` in the TUI that tells you to run `codex
    login` if both (1) your model provider expects to use `OPENAI_API_KEY`
    as its env var, and (2) `OPENAI_API_KEY` is not set.
    
    **What does not work**
    
    * The `LoginScreen` does not support the login flow from within the TUI.
    Instead, it tells you to quit, run `codex login`, and then run `codex`
    again.
    * `codex exec` does read from `auth.json` yet, nor does it direct the
    user to go through the login flow if `OPENAI_API_KEY` is not be found.
    * The `maybeRedeemCredits()` function from `get-api-key.tsx` has not
    been ported from TypeScript to `login_with_chatgpt.py` yet:
    
    
    https://github.com/openai/codex/blob/a67a67f3258fc21e147b6786a143fe3e15e6d5ba/codex-cli/src/utils/get-api-key.tsx#L84-L89
    
    **Implementation**
    
    Currently, the OAuth flow requires running a local webserver on
    `127.0.0.1:1455`. It seemed wasteful to incur the additional binary cost
    of a webserver dependency in the Rust CLI just to support login, so
    instead we implement this logic in Python, as Python has a `http.server`
    module as part of its standard library. Specifically, we bundle the
    contents of a single Python file as a string in the Rust CLI and then
    use it to spawn a subprocess as `python3 -c
    {{SOURCE_FOR_PYTHON_SERVER}}`.
    
    As such, the most significant files in this PR are:
    
    ```
    codex-rs/login/src/login_with_chatgpt.py
    codex-rs/login/src/lib.rs
    ```
    
    Now that the CLI may load `OPENAI_API_KEY` from the environment _or_
    `CODEX_HOME/auth.json`, we need a new abstraction for reading/writing
    this variable, so we introduce:
    
    ```
    codex-rs/core/src/openai_api_key.rs
    ```
    
    Note that `std::env::set_var()` is [rightfully] `unsafe` in Rust 2024,
    so we use a LazyLock<RwLock<Option<String>>> to store `OPENAI_API_KEY`
    so it is read in a thread-safe manner.
    
    Ultimately, it should be possible to go through the entire login flow
    from the TUI. This PR introduces a placeholder `LoginScreen` UI for that
    right now, though the new `codex login` subcommand introduced in this PR
    should be a viable workaround until the UI is ready.
    
    **Testing**
    
    Because the login flow is currently implemented in a standalone Python
    file, you can test it without building any Rust code as follows:
    
    ```
    rm -rf /tmp/codex_home && mkdir /tmp/codex_home
    CODEX_HOME=/tmp/codex_home python3 codex-rs/login/src/login_with_chatgpt.py
    ```
    
    For reference:
    
    * the original TypeScript implementation was introduced in
    https://github.com/openai/codex/pull/963
    * support for redeeming credits was later added in
    https://github.com/openai/codex/pull/974
  • feat: add support for -c/--config to override individual config items (#1137)
    This PR introduces support for `-c`/`--config` so users can override
    individual config values on the command line using `--config
    name=value`. Example:
    
    ```
    codex --config model=o4-mini
    ```
    
    Making it possible to set arbitrary config values on the command line
    results in a more flexible configuration scheme and makes it easier to
    provide single-line examples that can be copy-pasted from documentation.
    
    Effectively, it means there are four levels of configuration for some
    values:
    
    - Default value (e.g., `model` currently defaults to `o4-mini`)
    - Value in `config.toml` (e.g., user could override the default to be
    `model = "o3"` in their `config.toml`)
    - Specifying `-c` or `--config` to override `model` (e.g., user can
    include `-c model=o3` in their list of args to Codex)
    - If available, a config-specific flag can be used, which takes
    precedence over `-c` (e.g., user can specify `--model o3` in their list
    of args to Codex)
    
    Now that it is possible to specify anything that could be configured in
    `config.toml` on the command line using `-c`, we do not need to have a
    custom flag for every possible config option (which can clutter the
    output of `--help`). To that end, as part of this PR, we drop support
    for the `--disable-response-storage` flag, as users can now specify `-c
    disable_response_storage=true` to get the equivalent functionality.
    
    Under the hood, this works by loading the `config.toml` into a
    `toml::Value`. Then for each `key=value`, we create a small synthetic
    TOML file with `value` so that we can run the TOML parser to get the
    equivalent `toml::Value`. We then parse `key` to determine the point in
    the original `toml::Value` to do the insert/replace. Once all of the
    overrides from `-c` args have been applied, the `toml::Value` is
    deserialized into a `ConfigToml` and then the `ConfigOverrides` are
    applied, as before.
  • fix: overhaul how we spawn commands under seccomp/landlock on Linux (#1086)
    Historically, we spawned the Seatbelt and Landlock sandboxes in
    substantially different ways:
    
    For **Seatbelt**, we would run `/usr/bin/sandbox-exec` with our policy
    specified as an arg followed by the original command:
    
    
    https://github.com/openai/codex/blob/d1de7bb383552e8fadd94be79d65d188e00fd562/codex-rs/core/src/exec.rs#L147-L219
    
    For **Landlock/Seccomp**, we would do
    `tokio::runtime::Builder::new_current_thread()`, _invoke
    Landlock/Seccomp APIs to modify the permissions of that new thread_, and
    then spawn the command:
    
    
    https://github.com/openai/codex/blob/d1de7bb383552e8fadd94be79d65d188e00fd562/codex-rs/core/src/exec_linux.rs#L28-L49
    
    While it is neat that Landlock/Seccomp supports applying a policy to
    only one thread without having to apply it to the entire process, it
    requires us to maintain two different codepaths and is a bit harder to
    reason about. The tipping point was
    https://github.com/openai/codex/pull/1061, in which we had to start
    building up the `env` in an unexpected way for the existing
    Landlock/Seccomp approach to continue to work.
    
    This PR overhauls things so that we do similar things for Mac and Linux.
    It turned out that we were already building our own "helper binary"
    comparable to Mac's `sandbox-exec` as part of the `cli` crate:
    
    
    https://github.com/openai/codex/blob/d1de7bb383552e8fadd94be79d65d188e00fd562/codex-rs/cli/Cargo.toml#L10-L12
    
    We originally created this to build a small binary to include with the
    Node.js version of the Codex CLI to provide support for Linux
    sandboxing.
    
    Though the sticky bit is that, at this point, we still want to deploy
    the Rust version of Codex as a single, standalone binary rather than a
    CLI and a supporting sandboxing binary. To satisfy this goal, we use
    "the arg0 trick," in which we:
    
    * use `std::env::current_exe()` to get the path to the CLI that is
    currently running
    * use the CLI as the `program` for the `Command`
    * set `"codex-linux-sandbox"` as arg0 for the `Command`
    
    A CLI that supports sandboxing should check arg0 at the start of the
    program. If it is `"codex-linux-sandbox"`, it must invoke
    `codex_linux_sandbox::run_main()`, which runs the CLI as if it were
    `codex-linux-sandbox`. When acting as `codex-linux-sandbox`, we make the
    appropriate Landlock/Seccomp API calls and then use `execvp(3)` to spawn
    the original command, so do _replace_ the process rather than spawn a
    subprocess. Incidentally, we do this before starting the Tokio runtime,
    so the process should only have one thread when `execvp(3)` is called.
    
    Because the `core` crate that needs to spawn the Linux sandboxing is not
    a CLI in its own right, this means that every CLI that includes `core`
    and relies on this behavior has to (1) implement it and (2) provide the
    path to the sandboxing executable. While the path is almost always
    `std::env::current_exe()`, we needed to make this configurable for
    integration tests, so `Config` now has a `codex_linux_sandbox_exe:
    Option<PathBuf>` property to facilitate threading this through,
    introduced in https://github.com/openai/codex/pull/1089.
    
    This common pattern is now captured in
    `codex_linux_sandbox::run_with_sandbox()` and all of the `main.rs`
    functions that should use it have been updated as part of this PR.
    
    The `codex-linux-sandbox` crate added to the Cargo workspace as part of
    this PR now has the bulk of the Landlock/Seccomp logic, which makes
    `core` a bit simpler. Indeed, `core/src/exec_linux.rs` and
    `core/src/landlock.rs` were removed/ported as part of this PR. I also
    moved the unit tests for this code into an integration test,
    `linux-sandbox/tests/landlock.rs`, in which I use
    `env!("CARGO_BIN_EXE_codex-linux-sandbox")` as the value for
    `codex_linux_sandbox_exe` since `std::env::current_exe()` is not
    appropriate in that case.
  • feat: add codex_linux_sandbox_exe: Option<PathBuf> field to Config (#1089)
    https://github.com/openai/codex/pull/1086 is a work-in-progress to make
    Linux sandboxing work more like Seatbelt where, for the command we want
    to sandbox, we build up the command and then hand it, and some sandbox
    configuration flags, to another command to set up the sandbox and then
    run it.
    
    In the case of Seatbelt, macOS provides this helper binary and provides
    it at `/usr/bin/sandbox-exec`. For Linux, we have to build our own and
    pass it through (which is what #1086 does), so this makes the new
    `codex_linux_sandbox_exe` available on `Config` so that it will later be
    available in `exec.rs` when we need it in #1086.