Commit Graph

1875 Commits

  • core: replace Cloudflare 403 HTML with friendly message (#6252)
    ### Motivation
    
    When Codex is launched from a region where Cloudflare blocks access (for
    example, Russia), the CLI currently dumps Cloudflare’s entire HTML error
    page. This isn’t actionable and makes it hard for users to understand
    what happened. We want to detect the Cloudflare block and show a
    concise, user-friendly explanation instead.
    
    ### What Changed
    
    - Added CLOUDFLARE_BLOCKED_MESSAGE and a friendly_message() helper to
    UnexpectedResponseError. Whenever we see a 403 whose body contains the
    Cloudflare block notice, we now emit a single-line message (Access
    blocked by Cloudflare…) while preserving the HTTP status and request id.
    All other responses keep the original behaviour.
    - Added two focused unit tests:
    - unexpected_status_cloudflare_html_is_simplified ensures the Cloudflare
    HTML case yields the friendly message.
    - unexpected_status_non_html_is_unchanged confirms plain-text 403s still
    return the raw body.
    
    ### Testing
    
    - cargo build -p codex-cli
    - cargo test -p codex-core
    - just fix -p codex-core
    - cargo test --all-features
    
    ---------
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • refactor(terminal): cleanup deprecated flush logic (#6373)
    Removes flush logic that was leftover to test against ratatui's flush
    Cleaned up the flush logic so it's a bit more intent revealing.
    DrawCommand now owns the Cells that it draws as this works around a
    borrow checker problem.
  • fix(wsl): normalize Windows paths during update (#6086) (#6097)
    When running under WSL, the update command could receive Windows-style
    absolute paths (e.g., `C:\...`) and pass them to Linux processes
    unchanged, which fails because WSL expects those paths in
    `/mnt/<drive>/...` form.
    
    This patch adds a tiny helper in the CLI (`cli/src/wsl_paths.rs`) that:
    - Detects WSL (`WSL_DISTRO_NAME` or `"microsoft"` in `/proc/version`)  
    - Converts `X:\...` → `/mnt/x/...`  
    
    `run_update_action` now normalizes the package-manager command and
    arguments under WSL before spawning.
    Non-WSL platforms are unaffected.  
    
    Includes small unit tests for the converter.  
    
    **Fixes:** #6086, #6084
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • [SDK] Add network_access and web_search options to TypeScript SDK (#6367)
    ## Summary
    
    This PR adds two new optional boolean fields to `ThreadOptions` in the
    TypeScript SDK:
    
    - **`networkAccess`**: Enables network access in the sandbox by setting
    `sandbox_workspace_write.network_access` config
    - **`webSearch`**: Enables the web search tool by setting
    `tools.web_search` config
    
    These options map to existing Codex configuration options and are
    properly threaded through the SDK layers:
    1. `ThreadOptions` (threadOptions.ts) - User-facing API
    2. `CodexExecArgs` (exec.ts) - Internal execution args  
    3. CLI flags via `--config` in the `codex exec` command
    
    ## Changes
    
    - `sdk/typescript/src/threadOptions.ts`: Added `networkAccess` and
    `webSearch` fields to `ThreadOptions` type
    - `sdk/typescript/src/exec.ts`: Added fields to `CodexExecArgs` and CLI
    flag generation
    - `sdk/typescript/src/thread.ts`: Pass options through to exec layer
    
    ## Test Plan
    
    - [x] Build succeeds (`pnpm build`)
    - [x] Linter passes (`pnpm lint`)
    - [x] Type definitions are properly exported
    - [ ] Manual testing with sample code (to be done by reviewer)
    
    ---------
    
    Co-authored-by: Claude <noreply@anthropic.com>
  • feat: add --promote-alpha option to create_github_release script (#6370)
    Historically, running `create_github_release --publish-release` would
    always publish a new release from latest `main`, which isn't always the
    best idea. We should really publish an alpha, let it bake, and then
    promote it.
    
    This PR introduces a new flag, `--promote-alpha`, which does exactly
    that. It also works with `--dry-run`, so you can sanity check the commit
    it will use as the base commit for the new release before running it for
    real.
    
    ```shell
    $ ./codex-rs/scripts/create_github_release --dry-run --promote-alpha 0.56.0-alpha.2
    Publishing version 0.56.0
    Running gh api GET /repos/openai/codex/git/refs/tags/rust-v0.56.0-alpha.2
    Running gh api GET /repos/openai/codex/git/tags/7d4ef77bc35b011aa0c76c5cbe6cd7d3e53f1dfe
    Running gh api GET /repos/openai/codex/compare/main...8b49211e67d3c863df5ecc13fc5f88516a20fa69
    Would publish version 0.56.0 using base commit 62474a30e8 derived from rust-v0.56.0-alpha.2.
    ```
  • [App-server] Add auth v2 doc & update codex mcp interface auth section (#6353)
    Added doc for auth v2 endpoints. Updated the auth section in Codex MCP
    interface doc too.
  • [app-server] feat: expose additional fields on Thread (#6338)
    Add the following fields to Thread:
    
    ```
        pub preview: String,
        pub model_provider: String,
        pub created_at: i64,
    ```
    
    Will prob need another PR once this lands:
    https://github.com/openai/codex/pull/6337
  • [App-server] Implement account/read endpoint (#6336)
    This PR does two things:
    1. add a new function in core that maps the core-internal plan type to
    the external plan type;
    2. implement account/read that get account status (v2 of
    `getAuthStatus`).
  • Fix apply_patch rename move path resolution (#5486)
    Fixes https://github.com/openai/codex/issues/5485.
    
    Fixed rename hunks so `apply_patch` resolves the destination path using
    the verifier’s effective cwd, ensuring patches that run under `cd
    <worktree> && apply_patch` stay inside the worktree.
    
    Added a regression test
    (`test_apply_patch_resolves_move_path_with_effective_cwd`) that
    reproduced the old behavior (dest path resolved in the main repo) and
    now passes.
    
    Related to https://github.com/openai/codex/issues/5483.
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • Prefer wait_for_event over wait_for_event_with_timeout. (#6346)
    No need to specify the timeout in most cases.
  • Updated the AI labeler rules to match the most recent issue tracker labels (#6347)
    This PR updates the AI prompt used for the workflow that adds automated
    labels to incoming issues. I've been updating and refining the list of
    labels as I work through the issue backlog, and the old prompt was
    becoming somewhat outdated.
  • Remove shell tool when unified exec is enabled (#6345)
    Also drop streameable shell that's just an alias for unified exec.
  • Don't retry "insufficient_quota" errors (#6340)
    This PR makes an "insufficient quota" error fatal so we don't attempt to
    retry it multiple times in the agent loop.
    
    We have multiple bug reports from users about intermittent retry
    behaviors, and this could explain some of them. With this change, we'll
    eliminate the retries and surface a clear error message.
    
    The PR is a nearly identical copy of [this
    PR](https://github.com/openai/codex/pull/4837) contributed by
    @abimaelmartell. The original PR has gone stale. Rather than wait for
    the contributor to resolve merge conflicts, I wanted to get this change
    in.
  • feat: Enable CTRL-n and CTRL-p for navigating slash commands, files, history (#1994)
    Adds CTRL-n and CTRL-p navigation for slash commands, files, and
    history.
    Closes #1992
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • tui: fix backtracking past /status (#6335)
    Fixes https://github.com/openai/codex/issues/4722
    
    Supersedes https://github.com/openai/codex/pull/5058
    
    Ideally we'd have a clearer way of separating history per-session than
    by detecting a specific history cell type, but this is a fairly minimal
    fix for now.
  • Make generate_ts prettier output warn-only (#6342)
    Before, every file would be outputted with the time prettier spent
    formatting it. This made downstream scripts way too noisy.
  • [App Server] Add more session metadata to listConversations (#6337)
    This unlocks a few new product experience for app server consumers
  • core: widen sandbox to allow certificate ops when network is enabled (#5980)
    This allows `gh api` to work in the workspace-write sandbox w/ network
    enabled. Without this we see e.g.
    
    ```
    $ codex debug seatbelt --full-auto gh api repos/openai/codex/pulls --paginate -X GET -F state=all
    Get "https://api.github.com/repos/openai/codex/pulls?per_page=100&state=all": tls: failed to verify certificate: x509: OSStatus -26276
    ```
  • Updated contributing guidelines and PR template to request link to bug report in PR notes (#6332)
    Some PRs are being submitted without reference to existing bug reports
    or feature requests. This updates the PR template and contributing
    guidelines to request that all PRs from the community contain such a
    link. This provides additional context and helps prioritize, track, and
    assess PRs.
  • chore: move relevant tests to app-server/tests/suite/v2 (#6289)
    These are technically app-server v2 APIs, so move them to the same
    directory as the others.
  • Windows Sandbox: Show Everyone-writable directory warning (#6283)
    Show a warning when Auto Sandbox mode becomes enabled, if we detect
    Everyone-writable directories, since they cannot be protected by the
    current implementation of the Sandbox.
    
    This PR also includes changes to how we detect Everyone-writable to be
    *much* faster
  • docs: Fix code fence and typo in advanced guide (#6295)
    - add `bash` to code fence
    - fix spelling of `JavaScript`
  • [app-server] feat: v2 Turn APIs (#6216)
    Implements:
    ```
    turn/start
    turn/interrupt
    ```
    
    along with their integration tests. These are relatively light wrappers
    around the existing core logic, and changes to core logic are minimal.
    
    However, an improvement made for developer ergonomics:
    - `turn/start` replaces both `SendUserMessage` (no turn overrides) and
    `SendUserTurn` (can override model, approval policy, etc.)
  • chore: rename for clarity (#6319)
    Co-authored-by: Ahmed Ibrahim <aibrahim@openai.com>
  • [App-server] Add account/login/cancel v2 endpoint (#6288)
    Add `account/login/cancel` v2 endpoint for auth. this is similar
    implementation to `cancelLoginChatgpt` v1 endpoint.
  • fix: ToC so it doesn’t include itself or duplicate the end marker (#4388)
    turns out the ToC was including itself when generating, which messed up
    comparisons and sometimes made the file rewrite endlessly.
    
    also fixed the slice so `<!-- End ToC -->` doesn’t get duplicated when
    we insert the new ToC.
    
    should behave nicely now - no extra rewrites, no doubled markers.
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • Prevent dismissal of login menu in TUI (#6285)
    We currently allow the user to dismiss the login menu via Ctrl+C. This
    leaves them in a bad state where they're not auth'ed but have an input
    prompt. In the extension, this isn't a problem because we don't allow
    the user to dismiss the login screen.
    
    Testing: I confirmed that Ctrl+C no longer dismisses the login menu.
    
    This is an alternative (simpler) fix for a [community
    PR](https://github.com/openai/codex/pull/3234).
  • [App-server] Implement v2 for account/login/start and account/login/completed (#6183)
    This PR implements `account/login/start` and `account/login/completed`.
    Instead of having separate endpoints for login with chatgpt and api, we
    have a single enum handling different login methods. For sync auth
    methods like sign in with api key, we still send a `completed`
    notification back to be compatible with the async login flow.
  • stop capturing r when environment selection modal is open (#6249)
    This fixes an issue where you can't select environments with an r in them when the selection modal is open
  • Fixes intermittent test failures in CI (#6282)
    I'm seeing two tests fail intermittently in CI. This PR attempts to
    address (or at least mitigate) the flakiness.
    
    * summarize_context_three_requests_and_instructions - The test snapshots
    server.received_requests() immediately after observing TaskComplete.
    Because the OpenAI /v1/responses call is streamed, the HTTP request can
    still be draining when that event fires, so wiremock occasionally
    reports only two captured requests. Fix is to wait for async activity to
    complete.
    * archive_conversation_moves_rollout_into_archived_directory - times out
    on a slow CI run. Mitigation is to increase timeout value from 10s to
    20s.
  • [app-server] feat: v2 Thread APIs (#6214)
    Implements:
    ```
    thread/list
    thread/start
    thread/resume
    thread/archive
    ```
    
    along with their integration tests. These are relatively light wrappers
    around the existing core logic, and changes to core logic are minimal.
    
    However, an improvement made for developer ergonomics:
    - `thread/start` and `thread/resume` automatically attaches a
    conversation listener internally, so clients don't have to make a
    separate `AddConversationListener` call like they do today.
    
    For consistency, also updated `model/list` and `feedback/upload` (naming
    conventions, list API params).
  • Update rmcp to 0.8.5 (#6261)
    Picks up https://github.com/modelcontextprotocol/rust-sdk/pull/511 which
    should fix todoist and some other MCP server oauth and may further
    resolve issues in https://github.com/openai/codex/issues/5045
  • Improved token refresh handling to address "Re-connecting" behavior (#6231)
    Currently, when the access token expires, we attempt to use the refresh
    token to acquire a new access token. This works most of the time.
    However, there are situations where the refresh token is expired,
    exhausted (already used to perform a refresh), or revoked. In those
    cases, the current logic treats the error as transient and attempts to
    retry it repeatedly.
    
    This PR changes the token refresh logic to differentiate between
    permanent and transient errors. It also changes callers to treat the
    permanent errors as fatal rather than retrying them. And it provides
    better error messages to users so they understand how to address the
    problem. These error messages should also help us further understand why
    we're seeing examples of refresh token exhaustion.
    
    Here is the error message in the CLI. The same text appears within the
    extension.
    
    <img width="863" height="38" alt="image"
    src="https://github.com/user-attachments/assets/7ffc0d08-ebf0-4900-b9a9-265064202f4f"
    />
    
    I also correct the spelling of "Re-connecting", which shouldn't have a
    hyphen in it.
    
    Testing: I manually tested these code paths by adding temporary code to
    programmatically cause my refresh token to be exhausted (by calling the
    token refresh endpoint in a tight loop more than 50 times). I then
    simulated an access token expiration, which caused the token refresh
    logic to be invoked. I confirmed that the updated logic properly handled
    the error condition.
    
    Note: We earlier discussed the idea of forcefully logging out the user
    at the point where token refresh failed. I made several attempts to do
    this, and all of them resulted in a bad UX. It's important to surface
    this error to users in a way that explains the problem and tells them
    that they need to log in again. We also previously discussed deleting
    the auth.json file when this condition is detected. That also creates
    problems because it effectively changes the auth status from logged in
    to logged out, and this causes odd failures and inconsistent UX. I think
    it's therefore better not to delete auth.json in this case. If the user
    closes the CLI or VSCE and starts it again, we properly detect that the
    access token is expired and the refresh token is "dead", and we force
    the user to go through the login flow at that time.
    
    This should address aspects of #6191, #5679, and #5505
  • refactor Conversation history file into its own directory (#6229)
    This is just a refactor of `conversation_history` file by breaking it up
    into multiple smaller ones with helper. This refactor will help us move
    more functionality related to context management here. in a clean way.
  • tui: refactor ChatWidget and BottomPane to use Renderables (#5565)
    - introduce RenderableItem to support both owned and borrowed children
    in composite Renderables
    - refactor some of our gnarlier manual layouts, BottomPane and
    ChatWidget, to use ColumnRenderable
    - Renderable and friends now handle cursor_pos()
  • Add modelReasoningEffort option to TypeScript SDK (#6237)
    ## Summary
    - Adds `ModelReasoningEffort` type to TypeScript SDK with values:
    `minimal`, `low`, `medium`, `high`
    - Adds `modelReasoningEffort` option to `ThreadOptions`
    - Forwards the option to the codex CLI via `--config
    model_reasoning_effort="<value>"`
    - Includes test coverage for the new option
    
    ## Changes
    - `sdk/typescript/src/threadOptions.ts`: Define `ModelReasoningEffort`
    type and add to `ThreadOptions`
    - `sdk/typescript/src/index.ts`: Export `ModelReasoningEffort` type
    - `sdk/typescript/src/exec.ts`: Forward `modelReasoningEffort` to CLI as
    config flag
    - `sdk/typescript/src/thread.ts`: Pass option through to exec (+ debug
    logging)
    - `sdk/typescript/tests/run.test.ts`: Add test for
    `modelReasoningEffort` flag forwarding
    
    ---------
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • allow codex to be run from pid 1 (#4200)
    Previously it was not possible for codex to run commands as the init
    process (pid 1) in linux. Commands run in containers tend to see their
    own pid as 1. See https://github.com/openai/codex/issues/4198
    
    This pr implements the solution mentioned in that issue.
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • fix(core): load custom prompts from symlinked Markdown files (#3643)
    - Discover prompts via fs::metadata to follow symlinks
    
    - Add Unix-only symlink test in custom_prompts.rs
    
    - Update docs/prompts.md to mention symlinks
    
    Fixes #3637
    
    ---------
    
    Signed-off-by: Soroush Yousefpour <h.yusefpour@gmail.com>
    Co-authored-by: dedrisian-oai <dedrisian@openai.com>
    Co-authored-by: Eric Traut <etraut@openai.com>
  • Fix nix build (#6230)
    Previously, the `nix build .#default` command fails due to a missing
    output hash in the `./codex-rs/default.nix` for `crossterm-0.28.1`:
    
    ```
    error: No hash was found while vendoring the git dependency crossterm-0.28.1. You can add
    a hash through the `outputHashes` argument of `importCargoLock`:
    
    outputHashes = {
     "crossterm-0.28.1" = "<hash>";
    };
    
    If you use `buildRustPackage`, you can add this attribute to the `cargoLock`
    attribute set.
    ```
    
    This PR adds the missing hash:
    
    ```diff
    cargoLock.outputHashes = {
      "ratatui-0.29.0" = "sha256-HBvT5c8GsiCxMffNjJGLmHnvG77A6cqEL+1ARurBXho=";
    + "crossterm-0.28.1" = "sha256-6qCtfSMuXACKFb9ATID39XyFDIEMFDmbx6SSmNe+728=";
    };
    ```
    
    With this change, `nix build .#default` succeeds:
    
    ```
    > nix build .#default --max-jobs 1 --cores 2
    
    warning: Git tree '/home/lukas/r/github.com/lukasl-dev/codex' is dirty
    [1/0/1 built] building codex-rs-0.1.0 (buildPhase)[1/0/1 built] building codex-rs-0.1.0 (buildP[1/0/1 built] building codex-rs-0.1.0 (buildPhase):    [1/0/1 built] building codex-rs-0.1.0 (b[1/0/1 built] building codex-rs-0.1.0 (buildPhase):    Compi[1/0/1 built] building codex-rs-0.1
    
    > ./result/bin/codex
      You are running Codex in /home/lukas/r/github.com/lukasl-dev/codex
    
      Since this folder is version controlled, you may wish to allow Codex to work in this folder without asking for approval.
      ...
    ```