Change CLI update message presentation to reduce confusion
Summary
The Codex CLI update notification (the box prompt rendered by UpdateAvailableHistoryCell) places the npm command and explanatory prose on the same line, making it easy to accidentally copy trailing words as if they were part of the command. This causes npm to install stray packages globally.
Steps to reproduce
- Run a version of Codex CLI that is behind the latest release.
- The update box prompt appears:
╭───────────────────────────────────────────────────╮
│ ✨ Update available! 0.116.0 -> 0.118.0 │
│ Run npm install -g @openai/codex to update. │
│ │
│ See full release notes: │
│ https://github.com/openai/codex/releases/latest │
╰───────────────────────────────────────────────────╯
- User selects and copies the command line. Without colour context (which is lost on copy), the full visible string is:
Run npm install -g @openai/codex to update.
- User strips
Runfrom the front (or copies fromnpmonward), pastes into a terminal, and runs it:
npm install -g @openai/codex to update
- npm interprets
toandupdateas additional package names and installs all three globally.
Observed outcome
Three packages installed at the same timestamp:
@openai/codextoupdate
Root cause
codex-rs/tui/src/history_cell.rs, line 674:
line!["Run ", update_action.command_str().cyan(), " to update."]
The command (npm install -g @openai/codex) is rendered in cyan, and " to update." is plain text — visually distinct by colour, but indistinguishable on copy. The same pattern is in the raw_lines() plaintext fallback at line 707:
format!("Run {} to update.", update_action.command_str())
Security impact
to and update are real npm packages with known vulnerabilities:
to@0.2.9— critical audit findingsupdate@0.7.4— multiple critical/high/moderate audit findings
Users who follow the update prompt as intended end up with vulnerable packages silently added to their global npm environment.
Secondary issue: missing @latest tag
codex-rs/tui/src/update_action.rs, line 39:
UpdateAction::NpmGlobalLatest => ("npm", &["install", "-g", "@openai/codex"]),
The runtime command omits @latest. The snapshot test (codex_tui__update_prompt__tests__update_prompt_modal.snap) shows @openai/codex@latest, so the test fixture and runtime are inconsistent. Without @latest, npm may resolve a cached or older version depending on local registry state.
Recommended fixes
- Separate the command from the prose. Never render a shell command and explanatory text on the same copyable line. Use a dedicated line or a copy-action button for the command itself.
- Use
@latestconsistently in the runtimecommand_args()to match the snapshot test expectations. - Consider a one-click / confirmation update from the TUI (Variant B already moves toward this with the interactive menu — Variant A should follow the same pattern or be removed).
References
- Related issues: #12107, #7104, #16488, #5012
This issue has 5 comments on GitHub. Read the full discussion on GitHub ↗