Commit Graph

740 Commits

  • Express rate limit warning as % remaining (#7795)
    <img width="342" height="264" alt="image"
    src="https://github.com/user-attachments/assets/f1e932ff-c550-47b3-9035-0299ada4998d"
    />
    
    Earlier, the warning was expressed as consumed% whereas status was
    expressed as remaining%. This change brings the two into sync to
    minimize confusion and improve visual consistency.
  • Add vim-style navigation for CLI option selection (#7784)
    ## Summary
    
    Support "j" and "k" keys as aliases for "down" and "up" so vim users
    feel loved. Only support these keys when the selection is not
    searchable.
    
    ## Testing
    - env -u NO_COLOR TERM=xterm-256color cargo test -p codex-tui
    
    
    ------
    [Codex
    Task](https://chatgpt.com/codex/tasks/task_i_693771b53bc8833088669060dfac2083)
  • Add vim navigation keys to transcript pager (#7550)
    ## Summary
    - add vim-style pager navigation for transcript overlays (j/k,
    ctrl+f/b/d/u) without removing existing keys
    - add shift-space to page up
    
    ------
    [Codex
    Task](https://chatgpt.com/codex/tasks/task_i_69309d26da508329908b2dc8ca40afb7)
  • Fix transcript pager page continuity (#7363)
    ## What
    
    Fix PageUp/PageDown behaviour in the Ctrl+T transcript overlay so that
    paging is continuous and reversible, and add tests to lock in the
    expected behaviour.
    
    ## Why
    
    Today, paging in the transcript overlay uses the raw viewport height
    instead of the effective content height after layout. Because the
    overlay reserves some rows for chrome (header/footer), this can cause:
    
    - PageDown to skip transcript lines between pages.
    - PageUp/PageDown not to “round-trip” cleanly (PageDown then PageUp does
    not always return to the same set of visible lines).
    
    This shows up when inspecting longer transcripts via Ctrl+T; see #7356
    for context.
    
    ## How
    
    - Add a dedicated `PagerView::page_step` helper that computes the page
    size from the last rendered content height and falls back to
    `content_area(viewport_area).height` when that is not yet available.
    - Use `page_step(...)` for both PageUp and PageDown (including SPACE) so
    the scroll step always matches the actual content area height, not the
    full viewport height.
    - Add a focused test
    `transcript_overlay_paging_is_continuous_and_round_trips` that:
      - Renders a synthetic transcript with numbered `line-NN` rows.
    - Asserts that successive PageDown operations show continuous line
    numbers (no gaps).
    - Asserts that PageDown+PageUp and PageUp+PageDown round-trip correctly
    from non-edge offsets.
    
    The change is limited to `codex-rs/tui/src/pager_overlay.rs` and only
    affects the transcript overlay paging semantics.
    
    ## Related issue
    
    - #7356
    
    ## Testing
    
    On Windows 11, using PowerShell 7 in the repo root:
    
    ```powershell
    cargo test
    cargo clippy --tests
    cargo fmt -- --config imports_granularity=Item
    ```
    
    - All tests passed.
    - `cargo clippy --tests` reported some pre-existing warnings that are
    unrelated to this change; no new lints were introduced in the modified
    code.
    
    ---------
    
    Signed-off-by: muyuanjin <24222808+muyuanjin@users.noreply.github.com>
    Co-authored-by: Eric Traut <etraut@openai.com>
  • Remove legacy ModelInfo and merge it with ModelFamily (#7748)
    This is a step towards removing the need to know `model` when
    constructing config. We firstly don't need to know `model_info` and just
    respect if the user has already set it. Next step, we don't need to know
    `model` unless the user explicitly set it in `config.toml`
  • Restore status header after stream recovery (#7660)
    ## Summary
    - restore the previous status header when a non-error event arrives
    after a stream retry
    - add a regression test to ensure the reconnect banner clears once
    streaming resumes
    
    ## Testing
    - cargo fmt -- --config imports_granularity=Item
    - cargo clippy --fix --all-features --tests --allow-dirty -p codex-tui
    - NO_COLOR=0 cargo test -p codex-tui *(fails: vt100 color assertion
    tests expect colored cells but the environment returns Default colors
    even with NO_COLOR cleared and TERM/COLORTERM set)*
    
    ------
    [Codex
    Task](https://chatgpt.com/codex/tasks/task_i_69337f8c77508329b3ea85134d4a7ac7)
  • Enhance model picker (#7709)
    # 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.
    
    Include a link to a bug report or enhancement request.
  • load models from disk and set a ttl and etag (#7722)
    # 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.
    
    Include a link to a bug report or enhancement request.
  • fix(tui): add missing Ctrl+n/Ctrl+p support to ListSelectionView (#7629)
    ## Summary
    
    Extend Ctrl+n/Ctrl+p navigation support to selection popups (model
    picker, approval mode, etc.)
    
    This is a follow-up to #7530, which added Ctrl+n/Ctrl+p navigation to
    the textarea.
    The same keybindings were missing from `ListSelectionView`, causing
    inconsistent behavior
      when navigating selection popups.
    
      ## Related
    
      - #7530 - feat(tui): map Ctrl-P/N to arrow navigation in textarea
    
      ## Changes
    
      - Added Ctrl+n as alternative to Down arrow in selection popups
      - Added Ctrl+p as alternative to Up arrow in selection popups
      - Added unit tests for the new keybindings
    
      ## Test Plan
    
      - [x] `cargo test -p codex-tui list_selection_view` - all tests pass
    - [x] Manual testing: verified Ctrl+n/p navigation works in model
    selection popup
    
    ---------
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • fix wrap behavior for long commands (#7655)
    before:
    <img width="720" height="225" alt="image"
    src="https://github.com/user-attachments/assets/19b7ad7c-db14-4792-97cc-80677a3a52ec"
    />
    after:
    <img width="500" height="219" alt="Screenshot 2025-12-05 at 4 37 14 PM"
    src="https://github.com/user-attachments/assets/f877f846-5943-4ca7-8949-89e8524ffdb9"
    />
    
    
    also removes `is_current`, which is deadcode
  • fix: update URLs to use HTTPS in model migration prompts (#7705)
    Update URLs to use HTTPS in model migration prompts
    
    Closes #6685
  • Wire with_remote_overrides to construct model families (#7621)
    - This PR wires `with_remote_overrides` and make the
    `construct_model_families` an async function
    - Moves getting model family a level above to keep the function `sync`
    - Updates the tests to local, offline, and `sync` helper for model
    families
  • fix: taking plan type from usage endpoint instead of thru auth token (#7610)
    pull plan type from the usage endpoint, persist it in session state /
    tui state, and propagate through rate limit snapshots
  • Call models endpoint in models manager (#7616)
    - Introduce `with_remote_overrides` and update
    `refresh_available_models`
    - Put `auth_manager` instead of `auth_mode` on `models_manager`
    - Remove `ShellType` and `ReasoningLevel` to use already existing
    structs
  • Fix handle_shortcut_overlay_key for cross-platform consistency (#7583)
    **Summary**
    - Shortcut toggle using `?` in `handle_shortcut_overlay_key` fails to
    trigger on some platforms (notably Windows). Current match requires
    `KeyCode::Char('?')` with `KeyModifiers::NONE`. Some terminals set
    `SHIFT` when producing `?` (since it is typically `Shift + /`), so the
    strict `NONE` check prevents toggling.
    
    **Impact**
    - On Windows consoles/terminals, pressing `?` with an empty composer
    often does nothing, leading to inconsistent UX compared to macOS/Linux.
    
    **Root Cause**
    - Crossterm/terminal backends report modifiers inconsistently across
    platforms. Generating `?` may include `SHIFT`. The code enforces
    `modifiers == NONE`, so valid `?` presses with `SHIFT` are ignored.
    AltGr keyboards may also surface as `ALT`.
    
    **Repro Steps**
    - Open the TUI, ensure the composer is empty.
    - Press `?`.
    - Expected: Shortcut overlay toggles.
    - Actual (Windows frequently): No toggle occurs.
    
    **Fix Options**
    - Option 1 (preferred): Accept `?` regardless of `SHIFT`, but reject
    `CONTROL` and `ALT`.
    - Rationale: Keeps behavior consistent across platforms with minimal
    code change.
    	- Example change:
    		- Before: matching `KeyModifiers::NONE` only.
    		- After: allow `SHIFT`, disallow `CONTROL | ALT`.
    		- Suggested condition:
    			```rust
    			let toggles = matches!(key_event.code, KeyCode::Char('?'))
    && !key_event.modifiers.intersects(KeyModifiers::CONTROL |
    KeyModifiers::ALT)
    					&& self.is_empty();
    			```
    
    - Option 2: Platform-specific handling (Windows vs non-Windows).
    - Implement two variants or conditional branches using `#[cfg(target_os
    = "windows")]`.
    - On Windows, accept `?` with `SHIFT`; on other platforms, retain
    current behavior.
    - Trade-off: Higher maintenance burden and code divergence for limited
    benefit.
    
    ---
    
    close #5495
  • remove model_family from `config (#7571)
    - Remove `model_family` from `config`
    - Make sure to still override config elements related to `model_family`
    like supporting reasoning
  • FIX: WSL Paste image does not work (#6793)
    ## Related issues:  
    - https://github.com/openai/codex/issues/3939  
    - https://github.com/openai/codex/issues/2292  
    - https://github.com/openai/codex/issues/7528 (After correction
    https://github.com/openai/codex/pull/3990)
    
    **Area:** `codex-cli` (image handling / clipboard & file uploads)  
    **Platforms affected:** WSL (Ubuntu on Windows 10/11). No behavior
    change on native Linux/macOS/Windows.
    
    ## Summary
    
    This PR fixes image pasting and file uploads when running `codex-cli`
    inside WSL. Previously, image operations failed silently or with
    permission errors because paths weren't properly mapped between Windows
    and WSL filesystems.
    
    ## Visual Result
    
    <img width="1118" height="798" alt="image"
    src="https://github.com/user-attachments/assets/14e10bc4-6b71-4d1f-b2a6-52c0a67dd069"
    />
    
    ## Last Rust-Cli
    
    <img width="1175" height="859" alt="image"
    src="https://github.com/user-attachments/assets/7ef41e29-9118-42c9-903c-7116d21e1751"
    />
    
    ## Root cause
    
    The CLI assumed native Linux/Windows environments and didn't handle the
    WSL↔Windows boundary:
    
    - Used Linux paths for files that lived on the Windows host
    - Missing path normalization between Windows (`C:\...`) and WSL
    (`/mnt/c/...`)
    - Clipboard access failed under WSL
    
    ### Why `Ctrl+V` doesn't work in WSL terminals
    
    Most WSL terminal emulators (Windows Terminal, ConEmu, etc.) intercept
    `Ctrl+V` at the terminal level to paste text from the Windows clipboard.
    This keypress never reaches the CLI application itself, so our clipboard
    image handler never gets triggered. Users need `Ctrl+Alt+V`.
    
    ## Changes
    
    ### WSL detection & path mapping
    
    - Detects WSL by checking `/proc/sys/kernel/osrelease` and the
    `WSL_INTEROP` env var
    - Maps Windows drive paths to WSL mount paths (`C:\...` → `/mnt/c/...`)
    
    ### Clipboard fallback for WSL
    
    - When clipboard access fails under WSL, falls back to PowerShell to
    extract images from the Windows clipboard
    - Saves to a temp file and maps the path back to WSL
    
    ### UI improvements
    
    - Shows `Ctrl+Alt+V` hint on WSL (many terminals intercept plain
    `Ctrl+V`)
    - Better error messages for unreadable images
    
    ## Performance
    
    - Negligible overhead. The fallback adds a single FS copy to a temp file
    only when needed.
    - Direct streaming remains the default.
    
    ## Files changed
    
    - `protocol/src/lib.rs` – Added platform detection module  
    - `protocol/src/models.rs` – Added WSL path mapping for local images  
    - `protocol/src/platform.rs` – New module with WSL detection utilities  
    - `tui/src/bottom_pane/chat_composer.rs` – Added base64 data URL support
    and WSL path mapping
    - `tui/src/bottom_pane/footer.rs` – WSL-aware keyboard shortcuts  
    - `tui/src/clipboard_paste.rs` – PowerShell clipboard fallback
    
    ## How to reproduce the original bug (pre-fix)
    
    1. Run `codex-cli` inside WSL2 on Windows.  
    2. Paste an image from the Windows clipboard or drag an image from
    `C:\...` into the terminal.
    3. Observe that the image is not attached (silent failure) or an error
    is logged; no artifact reaches the tool.
    
    ## How to verify the fix
    
    1. Build this branch and run `codex-cli` inside WSL2.  
    2. Paste from clipboard and drag from both Windows and WSL paths.  
    3. Confirm that the image appears in the tool and the CLI shows a single
    concise info line (no warning unless fallback was used).
    
    I’m happy to adjust paths, naming, or split helpers into a separate
    module if you prefer.
    
    ## How to try this branch
    
    If you want to try this before it’s merged, you can use my Git branch:
    
    Repository: https://github.com/Waxime64/codex.git  
    Branch: `wsl-image-2`
    
    1. Start WSL on your Windows machine.
    2. Clone the repository and switch to the branch:
       ```bash
       git clone https://github.com/Waxime64/codex.git
       cd codex
       git checkout wsl-image-2
       # then go into the Rust workspace root, e.g.:
       cd codex-rs
    3. Build the TUI binary:
      cargo build -p codex-tui --bin codex-tui --release
    4. Install the binary:
       sudo install -m 0755 target/release/codex-tui /usr/local/bin/codex
    5. From the project directory where you want to use Codex, start it
    with:
       cd /path/to/your/project
       /usr/local/bin/codex
    
    On WSL, use CTRL+ALT+V to paste an image from the Windows clipboard into
    the chat.
  • execpolicy tui flow (#7543)
    ## Updating the `execpolicy` TUI flow
    
    In the TUI, when going through the command approval flow, codex will now
    ask the user if they would like to whitelist the FIRST unmatched command
    among a chain of commands.
    
    For example, let's say the agent wants to run `apple | pear` with an
    empty `execpolicy`
    
    Neither apple nor pear will match to an `execpolicy` rule. Thus, when
    prompting the user, codex tui will ask the user if they would like to
    whitelist `apple`.
    
    If the agent wants to run `apple | pear` again, they would be prompted
    again because pear is still unknown. when prompted, the user will now be
    asked if they'd like to whitelist `pear`.
    
    Here's a demo video of this flow:
    
    
    https://github.com/user-attachments/assets/fd160717-f6cb-46b0-9f4a-f0a974d4e710
    
    This PR also removed the `allow for this session` option from the TUI.
  • Add Enterprise plan to ChatGPT login description (#6918)
    ## Summary
    - update ChatGPT onboarding login description to mention Enterprise
    plans alongside Plus, Pro, and Team
    
    ## Testing
    - just fmt
    
    
    ------
    [Codex
    Task](https://chatgpt.com/codex/tasks/task_i_691e088daf20832c88d8b667adf45128)
  • Refactor execpolicy fallback evaluation (#7544)
    ## Refactor of the `execpolicy` crate
    
    To illustrate why we need this refactor, consider an agent attempting to
    run `apple | rm -rf ./`. Suppose `apple` is allowed by `execpolicy`.
    Before this PR, `execpolicy` would consider `apple` and `pear` and only
    render one rule match: `Allow`. We would skip any heuristics checks on
    `rm -rf ./` and immediately approve `apple | rm -rf ./` to run.
    
    To fix this, we now thread a `fallback` evaluation function into
    `execpolicy` that runs when no `execpolicy` rules match a given command.
    In our example, we would run `fallback` on `rm -rf ./` and prevent
    `apple | rm -rf ./` from being run without approval.
  • whitelist command prefix integration in core and tui (#7033)
    this PR enables TUI to approve commands and add their prefixes to an
    allowlist:
    <img width="708" height="605" alt="Screenshot 2025-11-21 at 4 18 07 PM"
    src="https://github.com/user-attachments/assets/56a19893-4553-4770-a881-becf79eeda32"
    />
    
    note: we only show the option to whitelist the command when 
    1) command is not multi-part (e.g `git add -A && git commit -m 'hello
    world'`)
    2) command is not already matched by an existing rule
  • use markdown for rendering tips (#7557)
    ## Summary
    - render tooltip content through the markdown renderer and prepend a
    bold Tip label
    - wrap tooltips at the available width using the indent’s measured width
    before adding the indent
    
    ## Testing
    - `/root/.cargo/bin/just fmt`
    - `RUSTFLAGS="--cfg tokio_unstable" TOKIO_UNSTABLE=1
    /root/.cargo/bin/just fix -p codex-tui` *(fails: codex-tui tests
    reference tokio::time::advance/start_paused gated behind the tokio
    test-util feature)*
    - `RUSTFLAGS="--cfg tokio_unstable" TOKIO_UNSTABLE=1 cargo test -p
    codex-tui` *(fails: codex-tui tests reference
    tokio::time::advance/start_paused gated behind the tokio test-util
    feature)*
    
    ------
    [Codex
    Task](https://chatgpt.com/codex/tasks/task_i_693081406050832c9772ae9fa5dd77ca)
  • Migrate codex max (#7566)
    - make codex max the default
    - fix: we were doing some async work in sync function which caused tui
    to panic
  • Migrate model family to models manager (#7565)
    This PR moves `ModelsFamily` to `openai_models`. It also propagates
    `ModelsManager` to session services and use it to drive model family. We
    also make `derive_default_model_family` private because it's a step
    towards what we want: one place that gives model configuration.
    
    This is a second step at having one source of truth for models
    information and config: `ModelsManager`.
    
    Next steps would be to remove `ModelsFamily` from config. That's massive
    because it's being used in 41 occasions mostly pre launching `codex`.
    Also, we need to make `find_family_for_model` private. It's also big
    because it's being used in 21 occasions ~ all tests.
  • Migrate tui to use models manager (#7555)
    - This PR treats the `ModelsManager` like `AuthManager` and propagate it
    into the tui, replacing the `builtin_model_presets`
    - We are also decreasing the visibility of `builtin_model_presets`
    
    based on https://github.com/openai/codex/pull/7552
  • fix: wrap long exec lines in transcript overlay (#7481)
    What
    -----
    - Fix the Ctrl+T transcript overlay so that very long exec output lines
    are soft‑wrapped to the viewport width instead of being rendered as a
    single truncated row.
    - Add a regression test to `TranscriptOverlay` to ensure long exec
    outputs are rendered on multiple lines in the overlay.
    
    Why
    ----
    - Previously, the transcript overlay rendered extremely long single exec
    lines as one on‑screen row and simply cut them off at the right edge,
    with no horizontal scrolling.
    - This made it impossible to inspect the full content of long tool/exec
    outputs in the transcript view, even though the main TUI view already
    wrapped those lines.
    - Fixes #7454.
    
    How
    ----
    - Update `ExecCell::transcript_lines` to wrap exec output lines using
    the existing `RtOptions`/`word_wrap_line` helpers so that transcript
    rendering is width‑aware.
    - Reuse the existing line utilities to expand the wrapped `Line` values
    into the transcript overlay, preserving styling while respecting the
    current viewport width.
    - Add `transcript_overlay_wraps_long_exec_output_lines` test in
    `pager_overlay.rs` that constructs a long single‑line exec output,
    renders the transcript overlay into a small buffer, and asserts that the
    long marker string spans multiple rendered lines.
  • feat: Support listing and selecting skills via $ or /skills (#7506)
    List/Select skills with $-mention or /skills
  • feat(tui): map Ctrl-P/N to arrow navigation in textarea (#7530)
    - Treat Ctrl-P/N (and their C0 fallbacks) the same as Up/Down so cursor
    movement matches popup/history behavior and control bytes never land in
    the buffer
    
    Fixes #7529
    
    Signed-off-by: Aofei Sheng <aofei@aofeisheng.com>
  • fix(tui): limit user shell output by screen lines (#7448)
    What
    - Limit the TUI "user shell" output panel by the number of visible
    screen lines rather than by the number of logical lines.
    - Apply middle truncation after wrapping, so a few extremely long lines
    cannot expand into hundreds of visible lines.
    - Add a regression test to guard this behavior.
    
    Why
    When the `ExecCommandSource::UserShell` tool returns a small number of
    very long logical lines, the TUI wraps those lines into many visual
    lines. The existing truncation logic applied
    `USER_SHELL_TOOL_CALL_MAX_LINES` to the number of logical lines *before*
    wrapping.
    
    As a result, a command like:
    
    - `Ran bash -lc "grep -R --line-number 'maskAssetId' ."`
    
    or a synthetic command that prints a single ~50,000‑character line, can
    produce hundreds of screen lines and effectively flood the viewport. The
    intended middle truncation for user shell output does not take effect in
    this scenario.
    
    How
    - In `codex-rs/tui/src/exec_cell/render.rs`, change the `ExecCell`
    rendering path for `ExecCommandSource::UserShell` so that:
    - Each logical line from `CommandOutput::aggregated_output` is first
    wrapped via `word_wrap_line` into multiple screen lines using the
    appropriate `RtOptions` and width from the `EXEC_DISPLAY_LAYOUT`
    configuration.
    - `truncate_lines_middle` is then applied to the wrapped screen lines,
    with `USER_SHELL_TOOL_CALL_MAX_LINES` as the limit. This means the limit
    is enforced on visible screen lines, not logical lines.
    - The existing layout struct (`ExecDisplayLayout`) continues to provide
    `output_max_lines`, so user shell output is subject to both
    `USER_SHELL_TOOL_CALL_MAX_LINES` and the layout-specific
    `output_max_lines` constraint.
    - Keep using `USER_SHELL_TOOL_CALL_MAX_LINES` as the cap, but interpret
    it as a per‑tool‑call limit on screen lines.
    - Add a regression test `user_shell_output_is_limited_by_screen_lines`
    in `codex-rs/tui/src/exec_cell/render.rs` that:
    - Constructs two extremely long logical lines containing a short marker
    (`"Z"`), so each wrapped screen line still contains the marker.
      - Wraps them at a narrow width to generate many screen lines.
    - Asserts that the unbounded wrapped output would exceed
    `USER_SHELL_TOOL_CALL_MAX_LINES` screen lines.
    - Renders an `ExecCell` for `ExecCommandSource::UserShell` at the same
    width and counts rendered lines containing the marker.
    - Asserts `output_screen_lines <= USER_SHELL_TOOL_CALL_MAX_LINES`,
    guarding against regressions where truncation happens before wrapping.
    
    This change keeps user shell output readable while ensuring it cannot
    flood the TUI, even when the tool emits a few extremely long lines.
    
    Tests
    - `cargo test -p codex-tui`
    
    Issue
    - Fixes #7447
  • Migrate model preset (#7542)
    - Introduce `openai_models` in `/core`
    - Move `PRESETS` under it
    - Move `ModelPreset`, `ModelUpgrade`, `ReasoningEffortPreset`,
    `ReasoningEffortPreset`, and `ReasoningEffortPreset` to `protocol`
    - Introduce `Op::ListModels` and `EventMsg::AvailableModels`
    
    Next steps:
    - migrate `app-server` and `tui` to use the introduced Operation
  • add slash resume (#7302)
    `codex resume` isn't that discoverable. Adding it to the slash commands
    can help
  • feat: codex tool tips (#7440)
    <img width="551" height="316" alt="Screenshot 2025-12-01 at 12 22 26"
    src="https://github.com/user-attachments/assets/6ca3deff-8ef8-4f74-a8e1-e5ea13fd6740"
    />
  • fix(tui) Support image paste from clipboard on native Windows (#7514)
    Closes #3404 
    
    ## Summary
    On windows, ctrl+v does not work for the same reason that cmd+v does not
    work on macos. This PR adds alt/option+v detection, which allows windows
    users to paste images from the clipboard using.
    
    We could swap between just ctrl on mac and just alt on windows, but this
    felt simpler - I don't feel strongly about it.
    
    Note that this will NOT address image pasting in WSL environments, due
    to issues with WSL <> Windows clipboards. I'm planning to address that
    in a separate PR since it will likely warrant some discussion.
    
    ## Testing
    - [x] Tested locally on a Mac and Windows laptop
  • improve resume performance (#7303)
    Reading the tail can be costly if we have a very big rollout item. we
    can just read the file metadata
  • Ensure duplicate-length paste placeholders stay distinct (#7431)
    Fix issue #7430 
    Generate unique numbered placeholders for multiple large pastes of the
    same length so deleting one no longer removes the others.
    
    Signed-off-by: Joshua <joshua1s@protonmail.com>
  • refactor: tui.rs extract several pieces (#7461)
    Pull FrameRequester out of tui.rs into its own module and make a
    FrameScheduler struct. This is effectively an Actor/Handler approach
    (see https://ryhl.io/blog/actors-with-tokio/). Adds tests and docs.
    
    Small refactor of pending_viewport_area logic.
  • persisting credits if new snapshot does not contain credit info (#7490)
    in response to incoming changes to responses headers where the header
    may sometimes not contain credits info (no longer forcing a credit
    check)
  • Show token used when context window is unknown (#7497)
    - Show context window usage in tokens instead of percentage when the
    window length is unknown.
  • feat: experimental support for skills.md (#7412)
    This change prototypes support for Skills with the CLI. This is an
    **experimental** feature for internal testing.
    
    ---------
    
    Co-authored-by: Gav Verma <gverma@openai.com>
  • fix(tui): handle WSL clipboard image paths (#3990)
    Fixes #3939 
    Fixes #2803
    
    ## Summary
    - convert Windows clipboard file paths into their `/mnt/<drive>`
    equivalents when running inside WSL so pasted images resolve correctly
    - add WSL detection helpers and share them with unit tests to cover both
    native Windows and WSL clipboard normalization cases
    - improve the test suite by exercising Windows path handling plus a
    dedicated WSL conversion scenario and keeping the code path guarded by
    targeted cfgs
    
    ## Testing
    - just fmt
    - cargo test -p codex-tui
    - cargo clippy -p codex-tui --tests
    - just fix -p codex-tui
    
    ## Screenshots
    _Codex TUI screenshot:_
    <img width="1880" height="848" alt="describe this copied image"
    src="https://github.com/user-attachments/assets/c620d43c-f45c-451e-8893-e56ae85a5eea"
    />
    
    _GitHub docs directory screenshot:_
    <img width="1064" height="478" alt="image-copied"
    src="https://github.com/user-attachments/assets/eb5eef6c-eb43-45a0-8bfe-25c35bcae753"
    />
    
    Co-authored-by: Eric Traut <etraut@openai.com>
  • correctly recognize WorkspaceWrite policy on /approvals (#7301)
    the `/approvals` popup fails to recognize that the CLI is in
    WorkspaceWrite mode if that policy has extra bits, like `writable_roots`
    etc.
    
    This change matches the policy, ignoring additional config aspects.