Commit Graph

54 Commits

  • 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
  • feat: notify when a newer version is available (#333)
    **Summary**  
    This change introduces a new startup check that notifies users if a
    newer `@openai/codex` version is available. To avoid spamming, it writes
    a small state file recording the last check time and will only re‑check
    once every 24 hours.
    
    **What’s Changed**  
    - **New file** `src/utils/check-updates.ts`  
      - Runs `npm outdated --global @openai/codex`  
      - Reads/writes `codex-state.json` under `CONFIG_DIR`  
      - Limits checks to once per day (`UPDATE_CHECK_FREQUENCY = 24h`)  
    - Uses `boxen` for a styled alert and `which` to locate the npm binary
    - **Hooked into** `src/cli.tsx` entrypoint:
      ```ts
      import { checkForUpdates } from "./utils/check-updates";
      // …
      // after loading config
      await checkForUpdates().catch();
      ```
    - **Dependencies**  
      - Added `boxen@^8.0.1`, `which@^5.0.0`, `@types/which@^3.0.4`  
    - **Tests**  
      - Vitest suite under `tests/check-updates.test.ts`  
      - Snapshot in `__snapshots__/check-updates.test.ts.snap`  
    
    **Motivation**  
    Addresses issue #244. Users running a stale global install will now see
    a friendly reminder—at most once per day—to upgrade and enjoy the latest
    features.
    
    **Test Plan**  
    - `getNPMCommandPath()` resolves npm correctly  
    - `checkOutdated()` parses `npm outdated` JSON  
    - State file prevents repeat alerts within 24h  
    - Boxen snapshot matches expected output  
    - No console output when state indicates a recent check  
    
    **Related Issue**  
    try resolves #244
    
    
    **Preview**
    Prompt a pnpm‑style alert when outdated  
    
    ![outdated‑alert](https://github.com/user-attachments/assets/294dad45-d858-45d1-bf34-55e672ab883a)
    
    Let me know if you’d tweak any of the messaging, throttle frequency,
    placement in the startup flow, or anything else.
    
    ---------
    
    Co-authored-by: Thibault Sottiaux <tibo@openai.com>
  • Fix handling of Shift+Enter in e.g. Ghostty (#338)
    Fix: Shift + Enter no longer prints “[27;2;13~” in the single‑line
    input. Validated as working and necessary in Ghostty on Linux.
    
    ## Key points
    - src/components/vendor/ink-text-input.tsx
    - Added early handler that recognises the two modifyOtherKeys
    escape‑sequences
        - [13;<mod>u  (mode 2 / CSI‑u)
        - [27;<mod>;13~ (mode 1 / legacy CSI‑~)
    - If Ctrl is held (hasCtrl flag) → call onSubmit() (same as plain
    Enter).
    - Otherwise → insert a real newline at the caret (same as Option+Enter).
      - Prevents the raw sequence from being inserted into the buffer.
    
    - src/components/chat/multiline-editor.tsx
    - Replaced non‑breaking spaces with normal spaces to satisfy eslint
    no‑irregular‑whitespace rule (no behaviour change).
    
    All unit tests (114) and ESLint now pass:
    npm test ✔️
    npm run lint ✔️
  • fix: raw-exec-process-group.test improve reliability and error handling (#280)
    description:
    
    Makes the test verifying process group termination more
    robust against timing variations. It increases a delay slightly 
    and correctly handles the scenario where the test process might 
    be aborted before it can output the grandchild PID
    
    current:
    
    ![image](https://github.com/user-attachments/assets/6dd7a9b4-b578-433d-a3db-c0c8c71950d9)
    
    fixed:
    
    ![image](https://github.com/user-attachments/assets/c9a1ffdf-3001-4563-b486-fbefb1830a8b)
  • feat: add /compact (#289)
    Added the ability to compact. Not sure if I should switch the model over
    to gpt-4.1 for longer context or if keeping the current model is fine.
    Also I'm not sure if setting the compacted to system is best practice,
    would love feedback 😄
    
    Mentioned in this issue: https://github.com/openai/codex/issues/230
  • feat: add notifications for MacOS using Applescript (#160)
    yolo'ed it with codex. Let me know if this looks good to you.
    
    https://github.com/openai/codex/issues/148
    
    tested with:
    ```
    npm run build:dev
    ```
    
    <img width="377" alt="Screenshot 2025-04-16 at 18 12 01"
    src="https://github.com/user-attachments/assets/79aa799b-b0b9-479d-84f1-bfb83d34bfb9"
    />
  • add support for -w,--writable-root to add more writable roots for sandbox (#263)
    This adds support for a new flag, `-w,--writable-root`, that can be
    specified multiple times to _amend_ the list of folders that should be
    configured as "writable roots" by the sandbox used in `full-auto` mode.
    Values that are passed as relative paths will be resolved to absolute
    paths.
    
    Incidentally, this required updating a number of the `agent*.test.ts`
    files: it feels like some of the setup logic across those tests could be
    consolidated.
    
    In my testing, it seems that this might be slightly out of distribution
    for the model, as I had to explicitly tell it to run `apply_patch` and
    that it had the permissions to write those files (initially, it just
    showed me a diff and told me to apply it myself). Nevertheless, I think
    this is a good starting point.
  • feat: add command history persistence (#152)
    This PR adds a command history persistence feature to Codex CLI that:
    
    1. **Stores command history**: Commands are saved to
    `~/.codex/history.json` and persist between CLI sessions.
    2. **Navigates history**: Users can use the up/down arrow keys to
    navigate through command history, similar to a traditional shell.
    3. **Filters sensitive data**: Built-in regex patterns prevent commands
    containing API keys, passwords, or tokens from being saved.
    4. **Configurable**: Added configuration options for history size,
    enabling/disabling history, and custom regex patterns for sensitive
    content.
    5. **New command**: Added `/clearhistory` command to clear command
    history.
    
      ## Code Changes
    
    - Added `src/utils/storage/command-history.ts` with functions for
    history management
      - Extended config system to support history settings
      - Updated terminal input components to use persistent history
      - Added help text for the new `/clearhistory` command
      - Added CLAUDE.md file for guidance when working with the codebase
    
      ## Testing
    
      - All tests are passing
    - Core functionality works with both input components (standard and
    multiline)
    - History navigation behaves correctly at line boundaries with the
    multiline editor
  • fix(security): Shell commands auto-executing in 'suggest' mode without permission (#197)
    ## Problem
    
    There's a security vulnerability in the current implementation where
    shell commands are being executed without requesting user permission
    even when in 'suggest' mode. According to our documentation:
    
    > In **Suggest** mode (default): All file writes/patches and **ALL
    shell/Bash commands** should require approval.
    
    However, the current implementation in `approvals.ts` was auto-approving
    commands deemed "safe" by the `isSafeCommand` function, bypassing the
    user permission requirement. This is a security risk as users expect all
    shell commands to require explicit approval in 'suggest' mode.
    
    ## Solution
    
    This PR fixes the issue by modifying the `canAutoApprove` function in
    `approvals.ts` to respect the 'suggest' mode policy for all shell
    commands:
    
    1. Added an early check at the beginning of `canAutoApprove` to
    immediately return `{ type: "ask-user" }` when the policy is `suggest`,
    regardless of whether the command is considered "safe" or not.
    
    2. Added a similar check in the bash command handling section to ensure
    bash commands also respect the 'suggest' mode.
    
    3. Updated tests to verify the new behavior, ensuring that all shell
    commands require approval in 'suggest' mode, while still being
    auto-approved in 'auto-edit' and 'full-auto' modes when appropriate.
    
    ## Testing
    
    All tests pass, confirming that the fix works as expected. The updated
    tests verify that:
    - All commands (even "safe" ones) require approval in 'suggest' mode
    - Safe commands are still auto-approved in 'auto-edit' mode
    - Bash commands with redirects still require approval in all modes
    
    This change ensures that the behavior matches what's documented and what
    users expect, improving security by requiring explicit permission for
    all shell commands in the default 'suggest' mode.
  • fix: allow continuing after interrupting assistant (#178)
    ## Description
    This PR fixes the issue where the CLI can't continue after interrupting
    the assistant with ESC ESC (Fixes #114). The problem was caused by
    duplicate code in the `cancel()` method and improper state reset after
    cancellation.
    
    ## Changes
    - Fixed duplicate code in the `cancel()` method of the `AgentLoop` class
    - Added proper reset of the `currentStream` property in the `cancel()`
    method
    - Created a new `AbortController` after aborting the current one to
    ensure future tool calls work
    - Added a system message to indicate the interruption to the user
    - Added a comprehensive test to verify the fix
    
    ## Benefits
    - Users can now continue using the CLI after interrupting the assistant
    - Improved user experience by providing feedback when interruption
    occurs
    - Better state management in the agent loop
    
    ## Testing
    - Added a dedicated test that verifies the agent can process new input
    after cancellation
    - Manually tested the fix by interrupting the assistant and confirming
    that new input is processed correctly
    
    ---------
    
    Signed-off-by: crazywolf132 <crazywolf132@gmail.com>
  • fix(text-buffer): correct word deletion logic for trailing spaces (Ctrl+Backspace) (#131)
    ## Description
    This fix resolves a bug where Ctrl+Backspace (hex 0x17) deletes the
    entire line when the cursor is positioned after a trailing space.
    
    ## Problem
    When the user has a line like "I want you to refactor my view " (with a
    space at the end) and the cursor is after that space, Ctrl+Backspace
    deletes the entire line instead of just removing the word "view".
    
    ## Solution
    - Added a check to detect if the cursor is after spaces
    - Modified the logic to delete only one space at a time in this case
    - Added a unit test to verify this behavior
    
    ## Tests
    All tests pass, including the new test that verifies the corrected
    behavior.
    
    ---------
    
    Signed-off-by: Alpha Diop <alphakhoss@gmail.com>
    Co-authored-by: Thibault Sottiaux <tibo@openai.com>
  • (feat) basic retries when hitting rate limit errors (#105)
    * w
    
    Signed-off-by: Thibault Sottiaux <tibo@openai.com>
    
    * w
    
    Signed-off-by: Thibault Sottiaux <tibo@openai.com>
    
    * w
    
    Signed-off-by: Thibault Sottiaux <tibo@openai.com>
    
    * w
    
    Signed-off-by: Thibault Sottiaux <tibo@openai.com>
    
    * w
    
    Signed-off-by: Thibault Sottiaux <tibo@openai.com>
    
    ---------
    
    Signed-off-by: Thibault Sottiaux <tibo@openai.com>