Commit Graph

628 Commits

  • chore: rename for clarity (#6319)
    Co-authored-by: Ahmed Ibrahim <aibrahim@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).
  • 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()
  • fix: --search shouldn't show deprecation message (#6180)
    Use the new feature flags instead of the old config.
  • tui: refine text area word separator handling (#5541)
    ## Summary
    - replace the word part enum with a simple `is_word_separator` helper
    - keep word-boundary logic aligned with the helper and punctuation-aware
    behavior
    - extend forward/backward deletion tests to cover whitespace around
    separators
    
    ## Testing
    - just fix -p codex-tui
    - cargo test -p codex-tui
    
    
    ------
    https://chatgpt.com/codex/tasks/task_i_68f91c71d838832ca2a3c4f0ec1b55d4
  • Do not skip trust prompt on Windows if sandbox is enabled. (#6167)
    If the experimental windows sandbox is enabled, the trust prompt should
    show on Windows.
  • Include reasoning tokens in the context window calculation (#6161)
    This value is used to determine whether mid-turn compaction is required.
    Reasoning items are only excluded between turns (and soon will start to
    be preserved even across turns) so it's incorrect to subtract
    reasoning_output_tokens mid term.
    
    This will result in higher values reported between turns but we are also
    looking into preserving reasoning items for the entire conversation to
    improve performance and caching.
  • fix: improve usage URLs in status card and snapshots (#6111)
    Hi OpenAI Codex team, currently "Visit chatgpt.com/codex/settings/usage
    for up-to-date information on rate limits and credits" message in status
    card and error messages. For now, without the "https://" prefix, the
    link cannot be clicked directly from most terminals or chat interfaces.
    
    <img width="636" height="127" alt="Screenshot 2025-11-02 at 22 47 06"
    src="https://github.com/user-attachments/assets/5ea11e8b-fb74-451c-85dc-f4d492b2678b"
    />
    
    ---
    
    The fix is intent to improve this issue:
    
    - It makes the link clickable in terminals that support it, hence better
    accessibility
    - It follows standard URL formatting practices
    - It maintains consistency with other links in the application (like the
    existing "https://openai.com/chatgpt/pricing" links)
    
    Thank you!
  • fix: pasting api key stray character (#4903)
    When signing in with an API key, pasting (with command+v on mac) adds a
    stray `v` character to the end of the api key.
    
    
    
    demo video (where I'm pasting in `sk-something-super-secret`)
    
    
    https://github.com/user-attachments/assets/b2b34b5f-c7e4-4760-9657-c35686dd8bb8
  • Changes to sandbox command assessment feature based on initial experiment feedback (#6091)
    * Removed sandbox risk categories; feedback indicates that these are not
    that useful and "less is more"
    * Tweaked the assessment prompt to generate terser answers
    * Fixed bug in orchestrator that prevents this feature from being
    exposed in the extension
  • tui: patch crossterm for better color queries (#5935)
    See
    https://github.com/crossterm-rs/crossterm/compare/master...nornagon:crossterm:nornagon/color-query
    
    This patches crossterm to add support for querying fg/bg color as part
    of the crossterm event loop, which fixes some issues where this query
    would fight with other input.
    
    - dragging screenshots into the cli would sometimes paste half of the
    pathname instead of being recognized as an image
    (https://github.com/openai/codex/issues/5603)
    - Fixes https://github.com/openai/codex/issues/4945
  • Add warning on compact (#6052)
    This PR introduces the ability for `core` to send `warnings` as it can
    send `errors. It also sends a warning on compaction.
    
    <img width="811" height="187" alt="image"
    src="https://github.com/user-attachments/assets/0947a42d-b720-420d-b7fd-115f8a65a46a"
    />
  • fix(tui): propagate errors in insert_history_lines_to_writer (#4266)
    ## What?
    Fixed error handling in `insert_history_lines_to_writer` where all
    terminal operations were silently ignoring errors via `.ok()`.
    
      ## Why?
    Silent I/O failures could leave the terminal in an inconsistent state
    (e.g., scroll region not reset) with no way to debug. This violates Rust
    error handling best practices.
    
      ## How?
      - Changed function signature to return `io::Result<()>`
      - Replaced all `.ok()` calls with `?` operator to propagate errors
    - Added `tracing::warn!` in wrapper function for backward compatibility
      - Updated 15 test call sites to handle Result  with `.expect()`
    
      ## Testing
      -  Pass all tests
    
      ## Type of Change
      - [x] Bug fix (non-breaking change)
    
    ---------
    
    Signed-off-by: Huaiwu Li <lhwzds@gmail.com>
    Co-authored-by: Eric Traut <etraut@openai.com>
  • feat: add exit slash command alias for quit (#6002)
    ## Summary
    - add the `/exit` slash command alongside `/quit` and reuse shared exit
    handling
    - refactor the chat widget to funnel quit, exit, logout, and shutdown
    flows through a common `request_exit` helper
    - add focused unit tests that confirm both `/quit` and `/exit` send an
    `ExitRequest`
    
    ## Testing
    - `just fmt`
    - `just fix -p codex-tui`
    - `cargo test -p codex-tui`
    
    
    ------
    https://chatgpt.com/codex/tasks/task_i_6903d5a8f47c8321bf180f031f2fa330
  • 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).
  • [Hygiene] Remove include_view_image_tool config (#5976)
    There's still some debate about whether we want to expose
    `tools.view_image` or `feature.view_image` so those are left unchanged
    for now, but this old `include_view_image_tool` config is good-to-go.
    Also updated the doc to reflect that `view_image` tool is now by default
    true.
  • [codex] add developer instructions (#5897)
    we are using developer instructions for code reviews, we need to pass
    them in cli as well.
  • feat: compaction prompt configurable (#5959)
    ```
     codex -c compact_prompt="Summarize in bullet points"
     ```
  • Add debug-only slash command for rollout path (#5936)
    ## Summary
    - add a debug-only `/rollout` slash command that prints the rollout file
    path or reports when none is known
    - surface the new command in the slash command metadata and cover it
    with unit tests
    
    <img width="539" height="99" alt="image"
    src="https://github.com/user-attachments/assets/688e1334-8a06-4576-abb8-ada33b458661"
    />
  • Add item streaming events (#5546)
    Adds AgentMessageContentDelta, ReasoningContentDelta,
    ReasoningRawContentDelta item streaming events while maintaining
    compatibility for old events.
    
    ---------
    
    Co-authored-by: Owen Lin <owen@openai.com>
  • chore: config editor (#5878)
    The goal is to have a single place where we actually write files
    
    In a follow-up PR, will move everything config related in a dedicated
    module and move the helpers in a dedicated file
  • feat: deprecation warning (#5825)
    <img width="955" height="311" alt="Screenshot 2025-10-28 at 14 26 25"
    src="https://github.com/user-attachments/assets/99729b3d-3bc9-4503-aab3-8dc919220ab4"
    />
  • feature: Add "!cmd" user shell execution (#2471)
    feature: Add "!cmd" user shell execution
    
    This change lets users run local shell commands directly from the TUI by
    prefixing their input with ! (e.g. !ls). Output is truncated to keep the
    exec cell usable, and Ctrl-C cleanly
      interrupts long-running commands (e.g. !sleep 10000).
    
    **Summary of changes**
    
    - Route Op::RunUserShellCommand through a dedicated UserShellCommandTask
    (core/src/tasks/user_shell.rs), keeping the task logic out of codex.rs.
    - Reuse the existing tool router: the task constructs a ToolCall for the
    local_shell tool and relies on ShellHandler, so no manual MCP tool
    lookup is required.
    - Emit exec lifecycle events (ExecCommandBegin/ExecCommandEnd) so the
    TUI can show command metadata, live output, and exit status.
    
    **End-to-end flow**
    
      **TUI handling**
    
    1. ChatWidget::submit_user_message (TUI) intercepts messages starting
    with !.
    2. Non-empty commands dispatch Op::RunUserShellCommand { command };
    empty commands surface a help hint.
    3. No UserInput items are created, so nothing is enqueued for the model.
    
      **Core submission loop**
    4. The submission loop routes the op to handlers::run_user_shell_command
    (core/src/codex.rs).
    5. A fresh TurnContext is created and Session::spawn_user_shell_command
    enqueues UserShellCommandTask.
    
      **Task execution**
    6. UserShellCommandTask::run emits TaskStartedEvent, formats the
    command, and prepares a ToolCall targeting local_shell.
      7. ToolCallRuntime::handle_tool_call dispatches to ShellHandler.
    
      **Shell tool runtime**
    8. ShellHandler::run_exec_like launches the process via the unified exec
    runtime, honoring sandbox and shell policies, and emits
    ExecCommandBegin/End.
    9. Stdout/stderr are captured for the UI, but the task does not turn the
    resulting ToolOutput into a model response.
    
      **Completion**
    10. After ExecCommandEnd, the task finishes without an assistant
    message; the session marks it complete and the exec cell displays the
    final output.
    
      **Conversation context**
    
    - The command and its output never enter the conversation history or the
    model prompt; the flow is local-only.
      - Only exec/task events are emitted for UI rendering.
    
    **Demo video**
    
    
    https://github.com/user-attachments/assets/fcd114b0-4304-4448-a367-a04c43e0b996
  • tui: show queued messages during response stream (#5540)
    This fixes an issue where messages sent during the final response stream
    would seem to disappear, because the "queued messages" UI wasn't shown
    during streaming.
  • tui: wait longer for color query results (#5004)
    this bumps the timeout when reading the responses to OSC 10/11 so that
    we're less likely to pass the deadline halfway through reading the
    response.
  • [Auth] Choose which auth storage to use based on config (#5792)
    This PR is a follow-up to #5591. It allows users to choose which auth
    storage mode they want by using the new
    `cli_auth_credentials_store_mode` config.
  • feat(tui): clarify Windows auto mode requirements (#5568)
    ## Summary
    - Coerce Windows `workspace-write` configs back to read-only, surface
    the forced downgrade in the approvals popup,
      and funnel users toward WSL or Full Access.
    - Add WSL installation instructions to the Auto preset on Windows while
    keeping the preset available for other
      platforms.
    - Skip the trust-on-first-run prompt on native Windows so new folders
    remain read-only without additional
      confirmation.
    - Expose a structured sandbox policy resolution from config to flag
    Windows downgrades and adjust tests (core,
    exec, TUI) to reflect the new behavior; provide a Windows-only approvals
    snapshot.
    
      ## Testing
      - cargo fmt
    - cargo test -p codex-core
    config::tests::add_dir_override_extends_workspace_writable_roots
    - cargo test -p codex-exec
    suite::resume::exec_resume_preserves_cli_configuration_overrides
    - cargo test -p codex-tui
    chatwidget::tests::approvals_selection_popup_snapshot
    - cargo test -p codex-tui
    approvals_popup_includes_wsl_note_for_auto_mode
      - cargo test -p codex-tui windows_skips_trust_prompt
      - just fix -p codex-core
      - just fix -p codex-tui
  • fix image drag drop (#5794)
    fixing drag/drop photos bug in codex
    
    state of the world before:
    
    sometimes, when you drag screenshots into codex, the image does not
    properly render into context. instead, the file name is shown in
    quotation marks.
    
    
    https://github.com/user-attachments/assets/3c0e540a-505c-4ec0-b634-e9add6a73119
    
    the screenshot is not actually included in agent context. the agent
    needs to manually call the view_image tool to see the screenshot. this
    can be unreliable especially if the image is part of a longer prompt and
    is dependent on the agent going out of its way to view the image.
    
    state of the world after:
    
    
    https://github.com/user-attachments/assets/5f2b7bf7-8a3f-4708-85f3-d68a017bfd97
    
    now, images will always be directly embedded into chat context
    
    ## Technical Details
    
    - MacOS sends screenshot paths with a narrow no‑break space right before
    the “AM/PM” suffix, which used to trigger our non‑ASCII fallback in the
    paste burst detector.
    - That fallback flushed the partially buffered paste immediately, so the
    path arrived in two separate `handle_paste` calls (quoted prefix +
    `PM.png'`). The split string could not be normalized to a real path, so
    we showed the quoted filename instead of embedding the image.
    - We now append non‑ASCII characters into the burst buffer when a burst
    is already active. Finder’s payload stays intact, the path normalizes,
    and the image attaches automatically.
    - When no burst is active (e.g. during IME typing), non‑ASCII characters
    still bypass the buffer so text entry remains responsive.
  • [MCP] Render MCP tool call result images to the model (#5600)
    It's pretty amazing we have gotten here without the ability for the
    model to see image content from MCP tool calls.
    
    This PR builds off of 4391 and fixes #4819. I would like @KKcorps to get
    adequete credit here but I also want to get this fix in ASAP so I gave
    him a week to update it and haven't gotten a response so I'm going to
    take it across the finish line.
    
    
    This test highlights how absured the current situation is. I asked the
    model to read this image using the Chrome MCP
    <img width="2378" height="674" alt="image"
    src="https://github.com/user-attachments/assets/9ef52608-72a2-4423-9f5e-7ae36b2b56e0"
    />
    
    After this change, it correctly outputs:
    > Captured the page: image dhows a dark terminal-style UI labeled
    `OpenAI Codex (v0.0.0)` with prompt `model: gpt-5-codex medium` and
    working directory `/codex/codex-rs`
    (and more)  
    
    Before this change, it said:
    > Took the full-page screenshot you asked for. It shows a long,
    horizontally repeating pattern of stylized people in orange, light-blue,
    and mustard clothing, holding hands in alternating poses against a white
    background. No text or other graphics-just rows of flat illustration
    stretching off to the right.
    
    Without this change, the Figma, Playwright, Chrome, and other visual MCP
    servers are pretty much entirely useless.
    
    I tested this change with the openai respones api as well as a third
    party completions api
  • [Auth] Introduce New Auth Storage Abstraction for Codex CLI (#5569)
    This PR introduces a new `Auth Storage` abstraction layer that takes
    care of read, write, and load of auth tokens based on the
    AuthCredentialsStoreMode. It is similar to how we handle MCP client
    oauth
    [here](https://github.com/openai/codex/blob/main/codex-rs/rmcp-client/src/oauth.rs).
    Instead of reading and writing directly from disk for auth tokens, Codex
    CLI workflows now should instead use this auth storage using the public
    helper functions.
    
    This PR is just a refactor of the current code so the behavior stays the
    same. We will add support for keyring and hybrid mode in follow-up PRs.
    
    I have read the CLA Document and I hereby sign the CLA
  • Made token refresh code resilient to missing id_token (#5782)
    This PR does the following:
    1. Changes `try_refresh_token` to handle the case where the endpoint
    returns a response without an `id_token`. The OpenID spec indicates that
    this field is optional and clients should not assume it's present.
    2. Changes the `attempt_stream_responses` to propagate token refresh
    errors rather than silently ignoring them.
    3. Fixes a typo in a couple of error messages (unrelated to the above,
    but something I noticed in passing) - "reconnect" should be spelled
    without a hyphen.
    
    This PR does not implement the additional suggestion from @pakrym-oai
    that we should sign out when receiving `refresh_token_expired` from the
    refresh endpoint. Leaving this as a follow-on because I'm undecided on
    whether this should be implemented in `try_refresh_token` or its
    callers.
  • feat: annotate conversations with model_provider for filtering (#5658)
    Because conversations that use the Responses API can have encrypted
    reasoning messages, trying to resume a conversation with a different
    provider could lead to confusing "failed to decrypt" errors. (This is
    reproducible by starting a conversation using ChatGPT login and resuming
    it as a conversation that uses OpenAI models via Azure.)
    
    This changes `ListConversationsParams` to take a `model_providers:
    Option<Vec<String>>` and adds `model_provider` on each
    `ConversationSummary` it returns so these cases can be disambiguated.
    
    Note this ended up making changes to
    `codex-rs/core/src/rollout/tests.rs` because it had a number of cases
    where it expected `Some` for the value of `next_cursor`, but the list of
    rollouts was complete, so according to this docstring:
    
    
    https://github.com/openai/codex/blob/bcd64c7e7231d6316a2377d1525a0fa74f21b783/codex-rs/app-server-protocol/src/protocol.rs#L334-L337
    
    If there are no more items to return, then `next_cursor` should be
    `None`. This PR updates that logic.
    
    
    
    
    
    
    ---
    [//]: # (BEGIN SAPLING FOOTER)
    Stack created with [Sapling](https://sapling-scm.com). Best reviewed
    with [ReviewStack](https://reviewstack.dev/openai/codex/pull/5658).
    * #5803
    * #5793
    * __->__ #5658
  • Followup feedback (#5663)
    - Added files to be uploaded
    - Refactored
    - Updated title
  • Added model summary and risk assessment for commands that violate sandbox policy (#5536)
    This PR adds support for a model-based summary and risk assessment for
    commands that violate the sandbox policy and require user approval. This
    aids the user in evaluating whether the command should be approved.
    
    The feature works by taking a failed command and passing it back to the
    model and asking it to summarize the command, give it a risk level (low,
    medium, high) and a risk category (e.g. "data deletion" or "data
    exfiltration"). It uses a new conversation thread so the context in the
    existing thread doesn't influence the answer. If the call to the model
    fails or takes longer than 5 seconds, it falls back to the current
    behavior.
    
    For now, this is an experimental feature and is gated by a config key
    `experimental_sandbox_command_assessment`.
    
    Here is a screen shot of the approval prompt showing the risk assessment
    and summary.
    
    <img width="723" height="282" alt="image"
    src="https://github.com/user-attachments/assets/4597dd7c-d5a0-4e9f-9d13-414bd082fd6b"
    />
  • Use Option symbol for mac key hints (#5582)
    ## Summary
    - show the Option (⌥) symbol in key hints when the TUI is built for
    macOS so the shortcut text matches the platform terminology
    
    ## Testing
    - cargo test -p codex-tui
    
    ------
    https://chatgpt.com/codex/tasks/task_i_68fab7505530832992780a9e13fb707b
  • fix: resume lookup for gitignored CODEX_HOME (#5311)
    Walk the sessions tree instead of using file_search so gitignored
    CODEX_HOME directories can resume sessions. Add a regression test that
    covers a .gitignore'd sessions directory.
    
    Fixes #5247
    Fixes #5412
    
    ---------
    
    Co-authored-by: Owen Lin <owen@openai.com>
  • tui: show aggregated output in display (#5539)
    This shows the aggregated (stdout + stderr) buffer regardless of exit
    code.
    
    Many commands output useful / relevant info on stdout when returning a
    non-zero exit code, or the same on stderr when returning an exit code of
    0. Often, useful info is present on both stdout AND stderr. Also, the
    model sees both. So it is confusing to see commands listed as "(no
    output)" that in fact do have output, just on the stream that doesn't
    match the exit status, or to see some sort of trivial output like "Tests
    failed" but lacking any information about the actual failure.
    
    As such, always display the aggregated output in the display. Transcript
    mode remains unchanged as it was already displaying the text that the
    model sees, which seems correct for transcript mode.