Commit Graph

68 Commits

  • add: responses api support for azure (#1321)
    - Use Responses API for Azure provider endpoints
    - Added a unit test to catch regression on the change from
    `/chat/completions` to `/responses`
    - Updated the default AOAI api version from `2025-03-01-preview` to
    `2025-04-01-preview` to avoid user/400 errors due to missing summary
    support in the March API version.
    - Changes have been tested locally on AOAI endpoints
  • Remove unnecessary console log from test (#970)
    When running `npm test` on `codex-cli`, the test
    `agent-cancel-prev-response.test.ts` logs a significant body of text to
    console for no obvious reason.
    
    This is not helpful, as it makes test logs messy and far longer.
    
    This change deletes the `console.log(...)` that produces the behavior.
  • add: session history viewer (#912)
    - A new “/sessions” command is available for browsing previous sessions,
    as shown in the updated slash command list
    
    - The CLI now documents and parses a new “--history” flag to browse past
    sessions from the command line
    
    - A dedicated `SessionsOverlay` component loads session metadata and
    allows toggling between viewing and resuming sessions
    
    - When the sessions overlay is opened during a chat, selecting a session
    can either show the saved rollout or resume it
  • fix: diff command for filenames with special characters (#954)
    ## Summary
    - fix quoting issues in `/diff` to correctly handle files with special
    characters
    - add regression test for `getGitDiff` when filenames contain `$`
    - relax timeout in raw-exec-process-group test
    
    Fixes https://github.com/openai/codex/issues/943
    
    ## Testing
    - `pnpm test`
  • add: codex-mini-latest (#951)
    💽
    
    ---------
    
    Co-authored-by: Trevor Creech <tcreech@openai.com>
  • feat: auto-approve nl and support piping to sed (#920)
    Auto-approved:
    
    ```
    ["nl", "-ba", "README.md"]
    ["sed", "-n", "1,200p", "filename.txt"]
    ["bash", "-lc", "sed -n '1,200p' filename.txt"]
    ["bash", "-lc", "nl -ba README.md | sed -n '1,200p'"]
    ```
    
    Not auto approved:
    
    ```
    ["sed", "-n", "'1,200p'", "filename.txt"]
    ["sed", "-n", "1,200p", "file1.txt", "file2.txt"]
    ```
  • fix: tweak the label for citations for better rendering (#919)
    Adds a space so that sequential citations have some more breathing room.
    
    As I had to update the tests for this change, I also introduced a
    `toDiffableString()` helper to make the test easier to update as we make
    formatting changes to the output.
  • fix: patch in #366 and #367 for marked-terminal (#916)
    This PR uses [`pnpm
    patch`](https://www.petermekhaeil.com/til/pnpm-patch/) to pull in the
    following proposed fixes for `marked-terminal`:
    
    * https://github.com/mikaelbr/marked-terminal/pull/366
    * https://github.com/mikaelbr/marked-terminal/pull/367
    
    This adds a substantial test to `codex-cli/tests/markdown.test.tsx` to
    verify the new behavior.
    
    Note that one of the tests shows two citations being split across a line
    even though the rendered version would fit comfortably on one line.
    Changing this likely requires a subtle fix to `marked-terminal` to
    account for "rendered length" when determining line breaks.
  • fix: add support for fileOpener in config.json (#911)
    This PR introduces the following type:
    
    ```typescript
    export type FileOpenerScheme = "vscode" | "cursor" | "windsurf";
    ```
    
    and uses it as the new type for a `fileOpener` option in `config.json`.
    If set, this will be used to linkify file annotations in the output
    using the URI-based file opener supported in VS Code-based IDEs.
    
    Currently, this does not pass:
    
    Updated `codex-cli/tests/markdown.test.tsx` to verify the new behavior.
    Note it required mocking `supports-hyperlinks` and temporarily modifying
    `chalk.level` to yield the desired output.
  • fix: always load version from package.json at runtime (#909)
    Note the high-level motivation behind this change is to avoid the need
    to make temporary changes in the source tree in order to cut a release
    build since that runs the risk of leaving things in an inconsistent
    state in the event of a failure. The existing code:
    
    ```
    import pkg from "../../package.json" assert { type: "json" };
    ```
    
    did not work as intended because, as written, ESBuild would bake the
    contents of the local `package.json` into the release build at build
    time whereas we want it to read the contents at runtime so we can use
    the `package.json` in the tree to build the code and later inject a
    modified version into the release package with a timestamped build
    version.
    
    Changes:
    
    * move `CLI_VERSION` out of `src/utils/session.ts` and into
    `src/version.ts` so `../package.json` is a correct relative path both
    from `src/version.ts` in the source tree and also in the final
    `dist/cli.js` build output
    * change `assert` to `with` in `import pkg` as apparently `with` became
    standard in Node 22
    * mark `"../package.json"` as external in `build.mjs` so the version is
    not baked into the `.js` at build time
    
    After using `pnpm stage-release` to build a release version, if I use
    Node 22.0 to run Codex, I see the following printed to stderr at
    startup:
    
    ```
    (node:71308) ExperimentalWarning: Importing JSON modules is an experimental feature and might change at any time
    (Use `node --trace-warnings ...` to show where the warning was created)
    ```
    
    Note it is a warning and does not prevent Codex from running.
    
    In Node 22.12, the warning goes away, but the warning still appears in
    Node 22.11. For Node 22, 22.15.0 is the current LTS version, so LTS
    users will not see this.
    
    Also, something about moving the definition of `CLI_VERSION` caused a
    problem with the mocks in `check-updates.test.ts`. I asked Codex to fix
    it, and it came up with the change to the test configs. I don't know
    enough about vitest to understand what it did, but the tests seem
    healthy again, so I'm going with it.
  • fix: increase output limits for truncating collector (#575)
    This Pull Request addresses an issue where the output of commands
    executed in the raw-exec utility was being truncated due to restrictive
    limits on the number of lines and bytes collected. The truncation caused
    the message [Output truncated: too many lines or bytes] to appear when
    processing large outputs, which could hinder the functionality of the
    CLI.
    
    Changes Made
    
    Increased the maximum output limits in the
    [createTruncatingCollector](https://github.com/openai/codex/pull/575)
    utility:
    Bytes: Increased from 10 KB to 100 KB.
    Lines: Increased from 256 lines to 1024 lines.
    Installed the @types/node package to resolve missing type definitions
    for [NodeJS](https://github.com/openai/codex/pull/575) and
    [Buffer](https://github.com/openai/codex/pull/575).
    Verified and fixed any related errors in the
    [createTruncatingCollector](https://github.com/openai/codex/pull/575)
    implementation.
    
    Issue Solved: 
    
    This PR ensures that larger outputs can be processed without truncation,
    improving the usability of the CLI for commands that generate extensive
    output. https://github.com/openai/codex/issues/509
    
    ---------
    
    Co-authored-by: Michael Bolin <bolinfest@gmail.com>
  • feat: @mention files in codex (#701)
    Solves #700
    
    ## State of the World Before
    
    Prior to this PR, when users wanted to share file contents with Codex,
    they had two options:
    - Manually copy and paste file contents into the chat
    - Wait for the assistant to use the shell tool to view the file
    
    The second approach required the assistant to:
    1. Recognize the need to view a file
    2. Execute a shell tool call
    3. Wait for the tool call to complete
    4. Process the file contents
    
    This consumed extra tokens and reduced user control over which files
    were shared with the model.
    
    ## State of the World After
    
    With this PR, users can now:
    - Reference files directly in their chat input using the `@path` syntax
    - Have file contents automatically expanded into XML blocks before being
    sent to the LLM
    
    For example, users can type `@src/utils/config.js` in their message, and
    the file contents will be included in context. Within the terminal chat
    history, these file blocks will be collapsed back to `@path` format in
    the UI for clean presentation.
    
    Tag File suggestions:
    <img width="857" alt="file-suggestions"
    src="https://github.com/user-attachments/assets/397669dc-ad83-492d-b5f0-164fab2ff4ba"
    />
    
    Tagging files in action:
    <img width="858" alt="tagging-files"
    src="https://github.com/user-attachments/assets/0de9d559-7b7f-4916-aeff-87ae9b16550a"
    />
    
    Demo video of file tagging:
    [![Demo video of file
    tagging](https://img.youtube.com/vi/vL4LqtBnqt8/0.jpg)](https://www.youtube.com/watch?v=vL4LqtBnqt8)
    
    ## Implementation Details
    
    This PR consists of 2 main components:
    
    1. **File Tag Utilities**:
    - New `file-tag-utils.ts` utility module that handles both expansion and
    collapsing of file tags
    - `expandFileTags()` identifies `@path` tokens and replaces them with
    XML blocks containing file contents
    - `collapseXmlBlocks()` reverses the process, converting XML blocks back
    to `@path` format for UI display
    - Tokens are only expanded if they point to valid files (directories are
    ignored)
       - Expansion happens just before sending input to the model
    
    2. **Terminal Chat Integration**:
    - Leveraged the existing file system completion system for tabbing to
    support the `@path` syntax
       - Added `updateFsSuggestions` helper to manage filesystem suggestions
    - Added `replaceFileSystemSuggestion` to replace input with filesystem
    suggestions
    - Applied `collapseXmlBlocks` in the chat response rendering so that
    tagged files are shown as simple `@path` tags
    
    The PR also includes test coverage for both the UI and the file tag
    utilities.
    
    ## Next Steps
    
    Some ideas I'd like to implement if this feature gets merged:
    
    - Line selection: `@path[50:80]` to grab specific sections of files
    - Method selection: `@path#methodName` to grab just one function/class
    - Visual improvements: highlight file tags in the UI to make them more
    noticeable
  • fix: remove unused _writableRoots arg to exec() function (#762)
    I suspect this was done originally so that `execForSandbox()` had a
    consistent signature for both the `SandboxType.NONE` and
    `SandboxType.MACOS_SEATBELT` cases, but that is not really necessary and
    turns out to make the upcoming Landlock support a bit more complicated
    to implement, so I had Codex remove it and clean up the call sites.
  • Fixes issue #726 by adding config to configToSave object (#728)
    The saveConfig() function only includes a hardcoded subset of properties
    when writing the config file. Any property not explicitly listed (like
    disableResponseStorage) will be dropped.
    I have added `disableResponseStorage` to the `configToSave` object as
    the immediate fix.
    
    [Linking Issue this fixes.](https://github.com/openai/codex/issues/726)
  • feat: add --reasoning CLI flag (#314)
    This PR adds a new CLI flag: `--reasoning`, which allows users to
    customize the reasoning effort level (`low`, `medium`, or `high`) used
    by OpenAI's `o` models.
    By introducing the `--reasoning` flag, users gain more flexibility when
    working with the models. It enables optimization for either speed or
    depth of reasoning, depending on specific use cases.
    This PR resolves #107
    
    - **Flag**: `--reasoning`
    - **Accepted Values**: `low`, `medium`, `high`
    - **Default Behavior**: If not specified, the model uses the default
    reasoning level.
    
    ## Example Usage
    
    ```bash
    codex --reasoning=low "Write a simple function to calculate factorial"
    
    ---------
    
    Co-authored-by: Fouad Matin <169186268+fouad-openai@users.noreply.github.com>
    Co-authored-by: yashrwealthy <yash.rastogi@wealthy.in>
    Co-authored-by: Thibault Sottiaux <tibo@openai.com>
  • feat: lower default retry wait time and increase number of tries (#720)
    In total we now guarantee that we will wait for at least 60s before
    giving up.
    
    ---------
    
    Signed-off-by: Thibault Sottiaux <tibo@openai.com>
  • feat: user config api key (#569)
    Adds support for reading OPENAI_API_KEY (and other variables) from a
    user‑wide dotenv file (~/.codex.config). Precedence order is now:
      1. explicit environment variable
      2. project‑local .env (loaded earlier)
      3. ~/.codex.config
    
    Also adds a regression test that ensures the multiline editor correctly
    handles cases where printable text and the CSI‑u Shift+Enter sequence
    arrive in the same input chunk.
    
    House‑kept with Prettier; removed stray temp.json artifact.
  • fix: duplicate messages in quiet mode (#680)
    Addressing #600 and #664 (partially)
    
    ## Bug
    Codex was staging duplicate items in output running when the same
    response item appeared in both the streaming events. Specifically:
    
    1. Items would be staged once when received as a
    `response.output_item.done` event
    2. The same items would be staged again when included in the final
    `response.completed` payload
    
    This duplication would result in each message being sent several times
    in the quiet mode output.
    
    ## Changes
    - Added a Set (`alreadyStagedItemIds`) to track items that have already
    been staged
    - Modified the `stageItem` function to check if an item's ID is already
    in this set before staging it
    - Added a regression test (`agent-dedupe-items.test.ts`) that verifies
    items with the same ID are only staged once
    
    ## Testing
    Like other tests, the included test creates a mock OpenAI stream that
    emits the same message twice (once as an incremental event and once in
    the final response) and verifies the item is only passed to `onItem`
    once.
  • perf: optimize token streaming with balanced approach (#635)
    - Replace setTimeout(10ms) with queueMicrotask for immediate processing
    - Add minimal 3ms setTimeout for rendering to maintain readable UX
    - Reduces per-token delay while preserving streaming experience
    - Add performance test to verify optimization works correctly
    
    ---------
    
    Co-authored-by: Claude <noreply@anthropic.com>
    Co-authored-by: Thibault Sottiaux <tibo@openai.com>
  • fix: only allow going up in history when not already in history if input is empty (#654)
    \+ cleanup below input help to be "ctrl+c to exit | "/" to see commands
    | enter to send" now that we have command autocompletion
    \+ minor other drive-by code cleanups
    
    ---------
    
    Signed-off-by: Thibault Sottiaux <tibo@openai.com>
  • chore: upgrade prettier to v3 (#644)
    ## Description
    
    This PR addresses the following improvements:
    
    **Unify Prettier Version**: Currently, the Prettier version used in
    `/package.json` and `/codex-cli/package.json` are different. In this PR,
    we're updating both to use Prettier v3.
    
    - Prettier v3 introduces improved support for JavaScript and TypeScript.
    (e.g. the formatting scenario shown in the image below. This is more
    aligned with the TypeScript indentation standard).
    
    <img width="1126" alt="image"
    src="https://github.com/user-attachments/assets/6e237eb8-4553-4574-b336-ed9561c55370"
    />
    
    **Add Prettier Auto-Formatting in lint-staged**: We've added a step to
    automatically run prettier --write on JavaScript and TypeScript files as
    part of the lint-staged process, before the ESLint checks.
    
    - This will help ensure that all committed code is properly formatted
    according to the project's Prettier configuration.
  • fix(utils): save config (#578)
    ## Description
    
    When `saveConfig` is called, the project doc is incorrectly saved into
    user instructions. This change ensures that only user instructions are
    saved to `instructions.md` during saveConfig, preventing data
    corruption.
    
    close: #576
    
    ---------
    
    Co-authored-by: Thibault Sottiaux <tibo@openai.com>
  • feat: display error on selection of invalid model (#594)
    Up-to-date of #78 
    
    Fixes #32
    
    addressed requested changes @tibo-openai :) made sense to me
    
    
    though, previous rationale with passing the state up was assuming there
    could be a future need to have a shared state with all available models
    being available to the parent
  • feat: more loosely match context for apply_patch (#610)
    More of a proposal than anything but models seem to struggle with
    composing valid patches for `apply_patch` for context matching when
    there are unicode look-a-likes involved. This would normalize them.
    
    ```
    top-level          # ASCII
    top-level          # U+2011 NON-BREAKING HYPHEN
    top–level          # U+2013 EN DASH
    top—level          # U+2014 EM DASH
    top‒level          # U+2012 FIGURE DASH
    ```
    
    thanks unicode.
  • feat: add support for custom provider configuration in the user config (#537)
    ### What
    
    - Add support for loading and merging custom provider configurations
    from a local `providers.json` file.
    - Allow users to override or extend default providers with their own
    settings.
    
    ### Why
    
    This change enables users to flexibly customize and extend provider
    endpoints and API keys without modifying the codebase, making the CLI
    more adaptable for various LLM backends and enterprise use cases.
    
    ### How
    
    - Introduced `loadProvidersFromFile` and `getMergedProviders` in config
    logic.
    - Added/updated related tests in [tests/config.test.tsx]
    
    
    ### Checklist
    
    - [x] Lint passes for changed files
    - [x] Tests pass for all files
    - [x] Documentation/comments updated as needed
    
    ---------
    
    Co-authored-by: Thibault Sottiaux <tibo@openai.com>
  • bug: non-openai mode - fix for gemini content: null, fix 429 to throw before stream (#563)
    Gemini's API is finicky, it 400's without an error when you pass
    content: null
    Also fixed the rate limiting issues by throwing outside of the iterator.
    I think there's a separate issue with the second isRateLimit check in
    agent-loop - turnInput is cleared by that time, so it retries without
    the last message.
  • feat: create parent directories when creating new files. (#552)
    apply_patch doesn't create parent directories when creating a new file
    leading to confusion and flailing by the agent. This will create parent
    directories automatically when absent.
    
    ---------
    
    Co-authored-by: Thibault Sottiaux <tibo@openai.com>
  • 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`.
  • 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}}"}
    ```
  • 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`.
  • 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>
  • 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
    ```
  • 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: 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.
  • 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>
  • 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.
  • Add fallback text for missing images (#397)
    # What?
    * When a prompt references an image path that doesn’t exist, replace it
    with
      ```[missing image: <path>]``` instead of throwing an ENOENT.
    * Adds a few unit tests for input-utils as there weren't any beforehand.
    
    # Why?
    Right now if you enter an invalid image path (e.g. it doesn't exist),
    codex immediately crashes with a ENOENT error like so:
    ```
    Error: ENOENT: no such file or directory, open 'test.png'
       ...
     {
      errno: -2,
      code: 'ENOENT',
      syscall: 'open',
      path: 'test.png'
    }
    ```
    This aborts the entire session. A soft fallback lets the rest of the
    input continue.
    
    # How?
    Wraps the image encoding + inputItem content pushing in a try-catch. 
    
    This is a minimal patch to avoid completely crashing — future work could
    surface a warning to the user when this happens, or something to that
    effect.
    
    ---------
    
    Co-authored-by: Thibault Sottiaux <tibo@openai.com>
  • feat: add user-defined safe commands configuration and approval logic #380 (#386)
    This pull request adds a feature that allows users to configure
    auto-approved commands via a `safeCommands` array in the configuration
    file.
    
    ## Related Issue
    #380 
    
    ## Changes
    - Added loading and validation of the `safeCommands` array in
    `src/utils/config.ts`
    - Implemented auto-approval logic for commands matching `safeCommands`
    prefixes in `src/approvals.ts`
    - Added test cases in `src/tests/approvals.test.ts` to verify
    `safeCommands` behavior
    - Updated documentation with examples and explanations of the
    configuration
  • fix: /bug report command, thinking indicator (#381)
    - Fix `/bug` report command
    - Fix thinking indicator