Commit Graph

1 Commits

  • 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
    ```