Commit Graph

132 Commits

  • bump(version): 0.1.2504221401 (#559)
    ## `0.1.2504221401`
    
    ### 🚀 Features
    
    - Show actionable errors when api keys are missing (#523)
    - Add CLI `--version` flag (#492)
    
    ### 🐛 Bug Fixes
    
    - Agent loop for ZDR (`disableResponseStorage`) (#543)
    - Fix relative `workdir` check for `apply_patch` (#556)
    - Minimal mid-stream #429 retry loop using existing back-off (#506)
    - Inconsistent usage of base URL and API key (#507)
    - Remove requirement for api key for ollama (#546)
    - Support `[provider]_BASE_URL` (#542)
  • when a shell tool call invokes apply_patch, resolve relative paths against workdir, if specified (#556)
    Previously, we were ignoring the `workdir` field in an `ExecInput` when
    running it through `canAutoApprove()`. For ordinary `exec()` calls, that
    was sufficient, but for `apply_patch`, we need the `workdir` to resolve
    relative paths in the `apply_patch` argument so that we can check them
    in `isPathConstrainedTowritablePaths()`.
    
    Likewise, we also need the workdir when running `execApplyPatch()`
    because the paths need to be resolved again.
    
    Ideally, the `ApplyPatchCommand` returned by `canAutoApprove()` would
    not be a simple `patch: string`, but the parsed patch with all of the
    paths resolved, in which case `execApplyPatch()` could expect absolute
    paths and would not need `workdir`.
  • fix: agent loop for disable response storage (#543)
    - Fixes post-merge of #506
    
    ---------
    
    Co-authored-by: Ilan Bigio <ilan@openai.com>
  • fix: support [provider]_BASE_URL (#542)
    Resolved issue where an OLLAMA_BASE_URL was not properly handled
    (openai/codex#516).
  • fix: remove requirement for api key for ollama (#546)
    Fixes #540 
    # Skip API key validation for Ollama provider
    
    ## Description
    This PR modifies the CLI to not require an API key when using Ollama as
    the provider
    
    ## Changes
    - Modified the validation logic to skip API key checks for these
    providers
    - Updated the README to clarify that Ollama doesn't require an API key
  • feat: show actionable errors when api keys are missing (#523)
    Change errors on missing api key of other providers from
    <img width="854" alt="image"
    src="https://github.com/user-attachments/assets/f488a247-5040-4b02-92d6-90a2204419ff"
    />
    (missing deepseek key but still throws error for openai)
    to
    <img width="854" alt="image"
    src="https://github.com/user-attachments/assets/8333d24a-91f8-4ba8-9a51-ed22a7e8a074"
    />
    This should help new users figure out the issue easier and go to the
    right place to get api keys
    
    OpenAI key missing would popup with the right link
    <img width="854" alt="image"
    src="https://github.com/user-attachments/assets/0ecc9320-380f-425c-972e-4312bf610955"
    />
  • feat: add CLI –version flag (#492)
    Adds a new flag to cli `--version` that prints the current version and
    exits
    
    ---------
    
    Co-authored-by: Thibault Sottiaux <tibo@openai.com>
  • agent-loop: minimal mid-stream #429 retry loop using existing back-off (#506)
    As requested by @tibo-openai at
    https://github.com/openai/codex/pull/357#issuecomment-2816554203, this
    attempts a more minimal implementation of #357 that preserves as much as
    possible of the existing code's exponential backoff logic.
    
    Adds a small retry wrapper around the streaming for‑await loop so that
    HTTP 429s which occur *after* the stream has started no longer crash the
    CLI.
    
    Highlights
    • Re‑uses existing RATE_LIMIT_RETRY_WAIT_MS constant and 5‑attempt
    limit.
    • Exponential back‑off identical to initial request handling. 
    
    This comment is probably more useful here in the PR:
    // The OpenAI SDK may raise a 429 (rate‑limit) *after* the stream has
    // started. Prior logic already retries the initial `responses.create`
            // call, but we need to add equivalent resilience for mid‑stream
            // failures.  We keep the implementation minimal by wrapping the
    // existing `for‑await` loop in a small retry‑for‑loop that re‑creates
            // the stream with exponential back‑off.
  • fix: inconsistent usage of base URL and API key (#507)
    A recent commit introduced the ability to use third-party model
    providers. (Really appreciate it!)
    
    However, the usage is inconsistent: some pieces of code use the custom
    providers, whereas others still have the old behavior. Additionally,
    `OPENAI_BASE_URL` is now being disregarded when it shouldn't be.
    
    This PR normalizes the usage to `getApiKey` and `getBaseUrl`, and
    enables the use of `OPENAI_BASE_URL` if present.
    
    ---------
    
    Co-authored-by: Gabriel Bianconi <GabrielBianconi@users.noreply.github.com>
  • fix(agent-loop): update required properties to include workdir and ti… (#530)
    Without this I get an issue running codex it in a docker container. I
    receive:
    
    ```
    {
        "answer": "{\"role\":\"user\",\"content\":[{\"type\":\"input_text\",\"text\":\"\\\"Say hello world\\\"\"}],\"type\":\"message\"}\n{\"id\":\"error-1745325184914\",\"type\":\"message\",\"role\":\"system\",\"content\":[{\"type\":\"input_text\",\"text\":\"⚠️  OpenAI rejected the request (request ID: req_f9027b59ebbce00061e9cd2dbb2d529a). Error details: Status: 400, Code: invalid_function_parameters, Type: invalid_request_error, Message: 400 Invalid schema for function 'shell': In context=(), 'required' is required to be supplied and to be an array including every key in properties. Missing 'workdir'.. Please verify your settings and try again.\"}]}\n"
    }
    ```
    
    This fix makes it work.
  • bump(version): 0.1.2504220136 (#518)
    ## `0.1.2504220136`
    
    ### 🚀 Features
    
    - Add support for ZDR orgs (#481)
    - Include fractional portion of chunk that exceeds stdout/stderr limit
    (#497)
  • feat: add support for ZDR orgs (#481)
    - Add `store: boolean` to `AgentLoop` to enable client-side storage of
    response items
    - Add `--disable-response-storage` arg + `disableResponseStorage` config
  • include fractional portion of chunk that exceeds stdout/stderr limit (#497)
    I saw cases where the first chunk of output from `ls -R` could be large
    enough to exceed `MAX_OUTPUT_BYTES` or `MAX_OUTPUT_LINES`, in which case
    the loop would exit early in `createTruncatingCollector()` such that
    nothing was appended to the `chunks` array. As a result, the reported
    `stdout` of `ls -R` would be empty.
    
    I asked Codex to add logic to handle this edge case and write a unit
    test. I used this as my test:
    
    ```
    ./codex-cli/dist/cli.js -q 'what is the output of `ls -R`'
    ```
    
    now it appears to include a ton of stuff whereas before this change, I
    saw:
    
    ```
    {"type":"function_call_output","call_id":"call_a2QhVt7HRJYKjb3dIc8w1aBB","output":"{\"output\":\"\\n\\n[Output truncated: too many lines or bytes]\",\"metadata\":{\"exit_code\":0,\"duration_seconds\":0.5}}"}
    ```
  • bump(version): 0.1.2504211509 (#493)
    ## `0.1.2504211509`
    
    ### 🚀 Features
    
    - Support multiple providers via Responses-Completion transformation
    (#247)
    - Add user-defined safe commands configuration and approval logic #380
    (#386)
    - Allow switching approval modes when prompted to approve an
    edit/command (#400)
    - Add support for `/diff` command autocomplete in TerminalChatInput
    (#431)
    - Auto-open model selector if user selects deprecated model (#427)
    - Read approvalMode from config file (#298)
    - `/diff` command to view git diff (#426)
    - Tab completions for file paths (#279)
    - Add /command autocomplete (#317)
    - Allow multi-line input (#438)
    
    ### 🐛 Bug Fixes
    
    - `full-auto` support in quiet mode (#374)
    - Enable shell option for child process execution (#391)
    - Configure husky and lint-staged for pnpm monorepo (#384)
    - Command pipe execution by improving shell detection (#437)
    - Name of the file not matching the name of the component (#354)
    - Allow proper exit from new Switch approval mode dialog (#453)
    - Ensure /clear resets context and exclude system messages from
    approximateTokenUsed count (#443)
    - `/clear` now clears terminal screen and resets context left indicator
    (#425)
    - Correct fish completion function name in CLI script (#485)
    - Auto-open model-selector when model is not found (#448)
    - Remove unnecessary isLoggingEnabled() checks (#420)
    - Improve test reliability for `raw-exec` (#434)
    - Unintended tear down of agent loop (#483)
    - Remove extraneous type casts (#462)
  • do not auto-approve the find command if it contains options that write files or spawn commands (#482)
    Updates `isSafeCommand()` so that an invocation of `find` is not
    auto-approved if it contains any of: `-exec`, `-execdir`, `-ok`,
    `-okdir`, `-delete`, `-fls`, `-fprint`, `-fprint0`, `-fprintf`.
  • chore: drop src from publish (#474)
    Publish shouldn't need the source files published along with the
    distributable bin.
    
    `src` is being shipped to the registry rn:
    https://www.npmjs.com/package/@openai/codex?activeTab=code
    
    You can verify that the src is not needed by packing the project
    manually after removing src from the files:
    
    ```sh
    # from the codex-cli dir
    rm -rf dist # just for hygiene
    pnpm run build
    pnpm pack
    
    mkdir /tmp/codex-tar-test
    mv openai-codex-0.1.2504181820.tgz /tmp/codex-tar-test
    cd /tmp/codex-tar-test
    
    pnpm init
    pnpm add ./openai-codex-0.1.2504181820.tgz /tmp/codex-tar-test
    pnpm exec codex --full-auto "run a bash -c command to echo hello world"
    ```
    
    The cli is operational
    
    > noticed this when checking the screenshot included in
    https://github.com/openai/codex/pull/461
  • revert #386 due to unsafe shell command parsing (#478)
    Reverts https://github.com/openai/codex/pull/386 because:
    
    * The parsing logic for shell commands was unsafe (`split(/\s+/)`
    instead of something like `shell-quote`)
    * We have a different plan for supporting auto-approved commands.
  • fix: /clear now clears terminal screen and resets context left indicator (#425)
    ## What does this PR do?
    * Implements the full `/clear` command in **codex‑cli**:
      * Resets chat history **and** wipes the terminal screen.
      * Shows a single system message: `Context cleared`.
    * Adds comprehensive unit tests for the new behaviour.
    
    ## Why is it needed?
    * Fixes user‑reported bugs:  
      * **#395**  
      * **#405**
    
    ## How is it implemented?
    * **Code** – Adds `process.stdout.write('\x1b[3J\x1b[H\x1b[2J')` in
    `terminal.tsx`. Removed reference to `prev` in `
            setItems((prev) => [
              ...prev,
    ` in `terminal-chat-new-input.tsx` & `terminal-chat-input.tsx`.
    
    ## CI / QA
    All commands pass locally:
    ```bash
    pnpm test      # green
    pnpm run lint  # green
    pnpm run typecheck  # zero TS errors
    ```
    
    ## Results
    
    
    
    https://github.com/user-attachments/assets/11dcf05c-e054-495a-8ecb-ac6ef21a9da4
    
    ---------
    
    Co-authored-by: Thibault Sottiaux <tibo@openai.com>
  • chore(build): cleanup dist before build (#477)
    Another one that I noticed.
    
    The dist structure is very simple rn, so unlikely to run into orphaned
    files as you're emitting a single built artifact which wil be
    overwritten on build, but I always prefer to do clean builds as
    "hygiene".
    
    I had a dirty dist personally after local development and testing some
    things, as an example.
    
    Alternatives could be to create a `clean` script with cross platform
    `rimraf dist`
  • chore: improve storage/ implementation; use log(...) consistently (#473)
    This PR tidies up primitives under storage/.
    
    **Noop changes:**
    
    * Promote logger implementation to top-level utility outside of agent/
    * Use logger within storage primitives
    * Cleanup doc strings and comments
    
    **Functional changes:**
    
    * Increase command history size to 10_000
    * Remove unnecessary debounce implementation and ensure a session ID is
    created only once per agent loop
    
    ---------
    
    Signed-off-by: Thibault Sottiaux <tibo@openai.com>
  • refactor(updates): fetch version from registry instead of npm CLI to support multiple managers (#446)
    ## Background  
    Addressing feedback from
    https://github.com/openai/codex/pull/333#discussion_r2050893224, this PR
    adds support for Bun alongside npm, pnpm while keeping the code simple.
    
    ## Summary  
    The update‑check flow is refactored to use a direct registry lookup
    (`fast-npm-meta` + `semver`) instead of shelling out to `npm outdated`,
    and adds a lightweight installer‑detection mechanism that:
    
    1. Checks if the invoked script lives under a known global‑bin directory
    (npm, pnpm, or bun)
    2. If not, falls back to local detection via `getUserAgent()` (the
    `package‑manager‑detector` library)
    
    ## What’s Changed  
    - **Registry‑based version check**  
    - Replace `execFile("npm", ["outdated"])` with `getLatestVersion()` and
    `semver.gt()`
    - **Multi‑manager support**  
    - New `renderUpdateCommand` handles update commands for `npm`, `pnpm`,
    and `bun`.
      - Detect global installer first via `detectInstallerByPath()`  
      - Fallback to local detection via `getUserAgent()`  
    - **Module cleanup**  
    - Extract `detectInstallerByPath` into
    `utils/package-manager-detector.ts`
    - Remove legacy `checkOutdated`, `getNPMCommandPath`, and child‑process
    JSON parsing
    - **Flow improvements in `checkForUpdates`**  
      1. Short‑circuit by `UPDATE_CHECK_FREQUENCY`  
      3. Fetch & compare versions  
      4. Persist new timestamp immediately  
      5. Render & display styled box only when an update exists  
    - **Maintain simplicity**
    - All multi‑manager logic lives in one small helper and a concise lookup
    rather than a complex adapter hierarchy
    - Core `checkForUpdates` remains a single, easy‑to‑follow async function
    - **Dependencies added**  
    - `fast-npm-meta`, `semver`, `package-manager-detector`, `@types/semver`
    
    ## Considerations
    If we decide to drop the interactive update‑message (`npm install -g
    @openai/codex`) rendering altogether, we could remove most of the
    installer‑detection code and dependencies, which would simplify the
    codebase further but result in a less friendly UX.
    
    ## Preview
    
    * npm
    
    ![refactor-update-check-flow-npm](https://github.com/user-attachments/assets/57320114-3fb6-4985-8780-3388a1d1ec85)
    
    * bun
    
    ![refactor-update-check-flow-bun](https://github.com/user-attachments/assets/d93bf0ae-a687-412a-ab92-581b4f967307)
    
    ## Simple Flow Chart
    
    ```mermaid
    flowchart TD
      A(Start) --> B[Read state]
      B --> C{Recent check?}
      C -- Yes --> Z[End]
      C -- No --> D[Fetch latest version]
      D --> E[Save check time]
      E --> F{Version data OK?}
      F -- No --> Z
      F -- Yes --> G{Update available?}
      G -- No --> Z
      G -- Yes --> H{Global install?}
      H -- Yes --> I[Select global manager]
      H -- No --> K{Local install?}
      K -- No --> Z
      K -- Yes --> L[Select local manager]
      I & L --> M[Render update message]
      M --> N[Format with boxen]
      N --> O[Print update]
      O --> Z
    ```
  • fix: auto-open model-selector when model is not found (#448)
    Change the check from checking if the model has been deprecated to check
    if the model_not_found
    
    
    https://github.com/user-attachments/assets/ad0f7daf-5eb4-4e4b-89e5-04240044c64f
  • Remove README.md and bin from package.json#files field (#461)
    This PR removes always included files and folders from the
    [`package.json#files`
    field](https://docs.npmjs.com/cli/v11/configuring-npm/package-json#files):
    
    > Certain files are always included, regardless of settings:
    > - package.json
    > - README
    > - LICENSE / LICENCE
    > - The file in the "main" field
    > - The file(s) in the "bin" field
    
    Validated by running `pnpm i && cd codex-cli && pnpm build && pnpm
    release:readme && pnpm pack` and confirming both the `README.md` file
    and `bin` directory are still included in the tarball:
    
    <img width="227" alt="image"
    src="https://github.com/user-attachments/assets/ecd90a07-73c7-4940-8c83-cb1d51dfcf96"
    />
  • feat: tab completions for file paths (#279)
    Made a PR as was requested in the #113
  • refactor(history-overlay): split into modular functions & add tests (fixes #402) (#403)
    ## What
    This PR targets #402 and refactors the `history-overlay.tsx`component to
    reduce cognitive complexity by splitting the `buildLists` function into
    smaller, focused helper functions. It also adds comprehensive test
    coverage to ensure the functionality remains intact.
    
    ## Why
    The original `buildLists` function had high cognitive complexity due to
    multiple nested conditionals, complex string manipulation, and mixed
    responsibilities. This refactor makes the code more maintainable and
    easier to understand while preserving all existing functionality.
    
    ## How
    - Split `buildLists` into focused helper functions
    - Added comprehensive test coverage for all functionality
    - Maintained existing behavior and keyboard interactions
    - Improved code organization and readability
    
    ## Testing
    All tests pass, including:
    - Command mode functionality
    - File mode functionality
    - Keyboard interactions
    - Error handling
  • fix: allow proper exit from new Switch approval mode dialog (#453)
    As described in
    https://github.com/openai/codex/issues/392#issuecomment-2817090022
    introduced by #400
    
    The testing I'd done worked correctly because I was using the (s)
    shortcut, but selecting the same option using arrow‑key → Enter on
    “Switch approval mode” was preventing the user from subsequently exiting
    the Switch approval mode dialog, requiring a ^C to quit codex entirely.
    With this fix, both entry methods work correctly in my testing.
    
    Per codex:
    
    Issue
    
    - When you navigated down (↓) to “Switch approval mode (s)” in the Shell
    Command review dialog and pressed Enter, the ApprovalModeOverlay would
    open—but because the underlying `TerminalChatCommandReview` component
    stayed mounted (albeit disabled), its own Ink input handlers immediately
    re‑captured the same key events and re‑opened the overlay as soon as you
    hit Esc or Enter again. In practice this made it impossible to exit the
    submenu.
    
    Root cause
    
    - We only disabled the SelectInput via `isDisabled`, but never fully
    unmounted the review UI when an overlay was shown, so its `useInput` and
    `<Select>` hooks were still active and “stealing” keys.
    
    Fix
    
    - In `terminal-chat.tsx` we now only render `<TerminalChatInput>` (and
    by extension `TerminalChatCommandReview`) when `overlayMode === "none"`.
    That unmounts all of its key handlers whenever any overlay (history,
    model, approval, help, diff) is open, so no input leaks through.
    
    Files changed
    
    - **src/components/chat/terminal-chat.tsx**: Wrapped the entire
    `<TerminalChatInput>` block in `overlayMode === "none" && agent`
    
    With that in place, arrow‑key → Enter on “Switch approval mode”
    correctly opens the overlay, and then you can use Enter/Esc inside the
    overlay without getting stuck or immediately re‑opening it.
  • fix: command pipe execution by improving shell detection (#437)
    ## Description
    This PR fixes Issue #421 where commands with pipes (e.g., `grep -R ...
    -n | head -n 20`) were failing to execute properly after PR #391 was
    merged.
    
    ## Changes
    - Modified the `requiresShell` function to only enable shell mode when
    the command is a single string containing shell operators
    - Added logic to handle the case where shell operators are passed as
    separate arguments
    - Added comprehensive tests to verify the fix
    
    ## Root Cause
    The issue was that the `requiresShell` function was detecting shell
    operators like `|` even when they were passed as separate arguments,
    which caused the command to be executed with `shell: true`
    unnecessarily. This was causing syntax errors when running commands with
    pipes.
    
    ## Testing
    - Added unit tests to verify the fix
    - Manually tested with real commands using pipes
    - Ensured all existing tests pass
    
    Fixes #421
  • feat: support multiple providers via Responses-Completion transformation (#247)
    https://github.com/user-attachments/assets/9ecb51be-fa65-4e99-8512-abb898dda569
    
    Implemented it as a transformation between Responses API and Completion
    API so that it supports existing providers that implement the Completion
    API and minimizes the changes needed to the codex repo.
    
    ---------
    
    Co-authored-by: Thibault Sottiaux <tibo@openai.com>
    Co-authored-by: Fouad Matin <169186268+fouad-openai@users.noreply.github.com>
    Co-authored-by: Fouad Matin <fouad@openai.com>
  • fix(raw-exec-process-group): improve test reliability (#434)
    This PR improves the reliability of `raw-exec-process-group.test`,
    addressing [#415](https://github.com/openai/codex/issues/415)
    
    Before: The test would fail sporadically in CI because it checked for
    process termination immediately after abort, without accounting for the
    time it takes for processes to fully terminate.
    
    Now: We've added a robust `ensureProcessGone` helper that:
    - Polls the process status with a 500ms timeout
    - Retries every 50ms if the process is still alive
    - Provides clear error messages if termination takes too long
    
    We now wait for the child process to fully exit after sending abort
    signals, instead of assuming instant death, fixing flakiness caused by
    asynchronous process termination.
    
    Changes:
    - Added `ensureProcessGone` helper function with retry logic
    - Improved error handling and timeout management
    
    See [this bash
    demo](https://gist.github.com/jdocherty/a84dbca2fbf7b47e5f95c87a07034ae8)
    for a minimal reproduction of why process death is asynchronous and why
    the test needs to retry after aborting.
  • fix: remove unnecessary isLoggingEnabled() checks (#420)
    It appears that use of `isLoggingEnabled()` was erroneously copypasta'd
    in many places. This PR updates its docstring to clarify that should
    only be used to avoid constructing a potentially expensive docstring.
    With this change, the only function that merits/uses this check is
    `execCommand()`.
    
    ---
    [//]: # (BEGIN SAPLING FOOTER)
    Stack created with [Sapling](https://sapling-scm.com). Best reviewed
    with [ReviewStack](https://reviewstack.dev/openai/codex/pull/420).
    * #423
    * __->__ #420
    * #419
  • Make it so CONFIG_DIR is not in the list of writable roots by default (#419)
    To play it safe, let's keep `CONFIG_DIR` out of the default list of
    writable roots.
    
    This also fixes an issue where `execWithSeatbelt()` was modifying
    `writableRoots` instead of creating a new array.
    
    ---
    [//]: # (BEGIN SAPLING FOOTER)
    Stack created with [Sapling](https://sapling-scm.com). Best reviewed
    with [ReviewStack](https://reviewstack.dev/openai/codex/pull/419).
    * #423
    * #420
    * __->__ #419
  • feat: allow multi-line input (#438)
    ## Description
    This PR implements multi-line input support for Codex when it asks for
    user feedback (Issue #344). Users can now use Shift+Enter to add new
    lines in their responses, making it easier to provide formatted code
    snippets, lists, or other structured content.
    
    ## Changes
    - Replace the single-line TextInput component with the
    MultilineTextEditor component in terminal-chat-input.tsx
    - Add support for Shift+Enter to create new lines
    - Update key handling logic to properly handle history navigation in a
    multi-line context
    - Add reference to the editor to access cursor position information
    - Update help text to inform users about the Shift+Enter functionality
    - Add tests for the new functionality
    
    ## Testing
    - Added new test file (terminal-chat-input-multiline.test.tsx) to test
    the multi-line input functionality
    - All existing tests continue to pass
    - Manually tested the feature to ensure it works as expected
    
    ## Fixes
    Closes #344
    
    ## Screenshots
    N/A
    
    ## Additional Notes
    This implementation maintains backward compatibility while adding the
    requested multi-line input functionality. The UI remains clean and
    intuitive, with a simple hint about using Shift+Enter for new lines.
    
    ---------
    
    Co-authored-by: Thibault Sottiaux <tibo@openai.com>
  • use spawn instead of exec to avoid injection vulnerability (#416)
    https://github.com/openai/codex/pull/160 introduced a call to `exec()`
    that takes a format string as an argument, but it is not clear that the
    expansions within the format string are escaped safely. As written, it
    is possible a carefully crafted command (e.g., if `cwd` were `"; && rm
    -rf` or something...) could run arbitrary code.
    
    Moving to `spawn()` makes this a bit better, as now at least `spawn()`
    itself won't run an arbitrary process, though I suppose `osascript`
    itself still could if the value passed to `-e` were abused. I'm not
    clear on the escaping rules for AppleScript to ensure that `safePreview`
    and `cwd` are injected safely.
    
    ---
    [//]: # (BEGIN SAPLING FOOTER)
    Stack created with [Sapling](https://sapling-scm.com). Best reviewed
    with [ReviewStack](https://reviewstack.dev/openai/codex/pull/416).
    * #423
    * #420
    * #419
    * __->__ #416
  • feat: /diff command to view git diff (#426)
    Adds `/diff` command to view git diff
  • re-enable Prettier check for codex-cli in CI (#417)
    This check was lost in https://github.com/openai/codex/pull/287. Both
    the root folder and `codex-cli/` have their own `pnpm format` commands
    that check the formatting of different things.
    
    Also ran `pnpm format:fix` to fix the formatting violations that got in
    while this was disabled in CI.
    
    ---
    [//]: # (BEGIN SAPLING FOOTER)
    Stack created with [Sapling](https://sapling-scm.com). Best reviewed
    with [ReviewStack](https://reviewstack.dev/openai/codex/pull/417).
    * #420
    * #419
    * #416
    * __->__ #417
  • feat: add /command autocomplete (#317)
    Add interactive slash‑command autocomplete & navigation in chat input
    
        Description
    This PR enhances the chat input component by adding first‑class support
    for slash commands (/help, /clear, /compact, etc.)
        with:
    
    * **Live filtering:** As soon as the user types leading `/`, a list of
    matching commands is shown below the prompt.
    * **Arrow‑key navigation:** Up/Down arrows cycle through suggestions.
    * **Enter to autocomplete:** Pressing Enter on a partial command will
    fill it (without submitting) so you can add
        arguments or simply press Enter again to execute.
    * **Type‑safe registry:** A new `slash‑commands.ts` file declares all
    supported commands in one place, along with
        TypeScript types to prevent drift.
    * **Validation:** Only registered commands will ever autocomplete or be
    suggested; unknown single‑word slash inputs still
        show an “Invalid command” system message.
            * **Automated tests:**
                * Unit tests for the command registry and prefix filtering
    
                * Existing tests continue passing with no regressions
    
        Motivation
    Slash commands provide a quick, discoverable way to control the agent
    (clearing history, compacting context, opening overlays,
    etc.). Before, users had to memorize the exact command or rely on the
    generic /help list—autocomplete makes them far more
        accessible and reduces typos.
    
        Changes
    
    * `src/utils/slash‑commands.ts` – defines `SlashCommand` and exports a
    flat list of supported commands + descriptions
            * `terminal‑chat‑input.tsx`
                * Import and type the command registry
    
    * Render filtered suggestions under the prompt when input starts with
    `/`
    
    * Hook into `useInput` to handle Up/Down and Enter for selection & fill
    
    * Flag to swallow the first Enter (autocomplete) and only submit on the
    next
    * Updated tests in `tests/slash‑commands.test.ts` to cover registry
    contents and filtering logic
            * Removed old JS version and fixed stray `@ts‑expect‑error`
    
        How to test locally
    
            1. Type `/` in the prompt—you should see matching commands.
    2. Use arrows to move the highlight, press Enter to fill, then Enter
    again to execute.
    3. Run the full test suite (`npm test`) to verify no regressions.
    
        Notes
    
    * Future work could include fuzzy matching, paging long lists, or more
    visual styling.
    * This change is purely additive and does not affect non‑slash inputs or
    existing slash handlers.
    
    ---------
    
    Co-authored-by: Fouad Matin <169186268+fouad-openai@users.noreply.github.com>
    Co-authored-by: Thibault Sottiaux <tibo@openai.com>
  • feat: read approvalMode from config file (#298)
    This PR implements support for reading the approvalMode setting from the
    user's config file (`~/.codex/config.json` or `~/.codex/config.yaml`),
    allowing users to set a persistent default approval mode without needing
    to specify command-line flags for each session.
    
    Changes:
    - Added approvalMode to the AppConfig type in config.ts
    - Updated loadConfig() to read the approval mode from the config file
    - Modified saveConfig() to persist the approval mode setting
    - Updated CLI logic to respect the config-defined approval mode (while
    maintaining CLI flag priority)
    - Added comprehensive tests for approval mode config functionality
    - Updated README to document the new config option in both YAML and JSON
    formats
    - additions to `.gitignore` for other CLI tools
    
    Motivation:
    As a user who regularly works with CLI-tools, I found it odd to have to
    alias this with the command flags I wanted when `approvalMode` simply
    wasn't being parsed even though it was an optional prop in `config.ts`.
    This change allows me (and other users) to set the preference once in
    the config file, streamlining daily usage while maintaining the ability
    to override via command-line flags when needed.
    
    Testing:
    I've added a new test case loads and saves approvalMode correctly that
    verifies:
    - Reading the approvalMode from the config file works correctly
    - Saving the approvalMode to the config file works as expected
    - The value persists through load/save operations
    
    All tests related to the implementation are passing.
  • gracefully handle SSE parse errors and suppress raw parser code (#367)
    Closes #187
    Closes #358
    
    ---------
    
    Co-authored-by: Thibault Sottiaux <tibo@openai.com>