- package.json: expose bin as 'code'
- postinstall: detect existing 'code'; create 'coder' fallback and optional 'vscode' alias to existing editor
- keep Rust binary named 'coder' for builds; wrappers updated accordingly
- Remove unnecessary mut from line mapping in history_cell.rs
- Add new diff_popup.rs component for displaying diffs in TUI
- Include markdown_renderer.rs for improved markdown rendering
- Clean up backup files and maintain theme consistency
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
- Add glitch animation effects for assistant messages in chatwidget
- Implement GlitchText widget with multi-phase animation states
- Add status item deduplication for screenshots and system context
- Improve history cell rendering with proper exec command display
- Update browser page handling for screenshot optimization
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
Successfully eliminated 100% of compilation warnings following the trait-based HistoryCell migration:
Core fixes:
- Removed truly unused code that was orphaned after migration
- Marked test-only functions with #[cfg(test)] annotations
- Added #[allow(dead_code)] for intentionally unused future features
- Fixed unreachable pattern and unused variable warnings
Major discoveries during investigation:
- Live ring feature was partially implemented but never connected
- Text element system in textarea was added but never integrated
- history_cell_new.rs and text_block modules orphaned after migration
- ImageOutputCell.image field stored for future terminal image protocol
Files cleaned:
- app.rs: Removed unused event_sender() method
- chatwidget/interrupts.rs: Removed unused is_empty() method
- textarea.rs: Removed entire unused text element system
- colors.rs: Removed unused border_focused() function
- history_cell.rs: Cleaned up unused helper functions
- diff_render.rs: Marked internal constants/types appropriately
- lib.rs: Commented out orphaned module declarations
- text_processing.rs: Marked markdown functions with allow(dead_code)
Build now completes with 0 warnings in all profiles.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
- Implement perceptual hashing (pHash + dHash) for screenshot comparison
- Add smart deduplication to avoid sending duplicate screenshots
- Create status items system for browser context and system state
- Include fresh screenshots with each API request when browser is active
- Clean up old status items to manage token usage efficiently
- Show "[Screenshot unchanged]" message when screenshot hasn't changed
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
- Preserved local enum-based HistoryCell architecture
- Kept local theming system with background colors
- Incorporated upstream timing features for exec commands
- Ported login server from Python to Rust (upstream change)
- Added terminal resize handling from upstream
- Resolved all merge conflicts while maintaining local customizations
When using codex-tui on a linux system I was unable to run `cargo
clippy` inside of codex due to:
```
[pid 3548377] socketpair(AF_UNIX, SOCK_SEQPACKET|SOCK_CLOEXEC, 0, <unfinished ...>
[pid 3548370] close(8 <unfinished ...>
[pid 3548377] <... socketpair resumed>0x7ffb97f4ed60) = -1 EPERM (Operation not permitted)
```
And
```
3611300 <... recvfrom resumed>0x708b8b5cffe0, 8, 0, NULL, NULL) = -1 EPERM (Operation not permitted)
```
This PR:
* Fixes a bug that disallowed AF_UNIX to allow it on `socket()`
* Adds recvfrom() to the syscall allow list, this should be fine since
we disable opening new sockets. But we should validate there is not a
open socket inheritance issue.
* Allow socketpair to be called for AF_UNIX
* Adds tests for AF_UNIX components
* All of which allows running `cargo clippy` within the sandbox on
linux, and possibly other tooling using a fork server model + AF_UNIX
comms.
we have a very unclear lifecycle for the chatwidget—this should only
have to be added in one place! but this fixes the "hanging commands"
issue where the active_exec_cell wasn't correctly cleared when commands
finished.
To repro w/o this PR:
1. prompt "run sleep 10"
2. once the command starts running, press <kbd>Esc</kbd>
3. prompt "run echo hi"
Expected:
```
✓ Completed
└ ⌨️ echo hi
codex
hi
```
Actual:
```
⚙︎ Working
└ ⌨️ echo hi
▌ Ask Codex to do anything
```
i.e. the "Working" never changes to "Completed".
The bug is fixed with this PR.
Our existing path filters for `rust-ci.yml`:
https://github.com/openai/codex/blob/e372f158e5a772d4799402b389a59b7bf0a34d15/.github/workflows/rust-ci.yml#L1-L11
made it so that PRs that touch only `README.md` would not trigger those
builds, which is a problem because our branch protection rules are set
as follows:
<img width="1569" height="1883" alt="Screenshot 2025-08-14 at 4 45
59 PM"
src="https://github.com/user-attachments/assets/5a61f8cc-cdaf-4341-abda-7faa7b46dbd4"
/>
With the existing setup, a change to `README.md` would get stuck in
limbo because not all the CI jobs required to merge would get run. It
turns out that we need to "run" all the jobs, but make them no-ops when
the `codex-rs` and `.github` folders are untouched to get the best of
both worlds.
I asked chat how to fix this, as we want CI to be fast for
documentation-only changes. It had two suggestions:
- Use https://github.com/dorny/paths-filter or some other third-party
action.
- Write an inline Bash script to avoid a third-party dependency.
This PR takes the latter approach so that we are clear about what we're
running in CI.
The high-order bit on this PR is that it makes it so `sandbox.rs` tests
both Mac and Linux, as we introduce a general
`spawn_command_under_sandbox()` function with platform-specific
implementations for testing.
An important, and interesting, discovery in porting the test to Linux is
that (for reasons cited in the code comments), `/dev/shm` has to be
added to `writable_roots` on Linux in order for `multiprocessing.Lock`
to work there. Granting write access to `/dev/shm` comes with some
degree of risk, so we do not make this the default for Codex CLI.
Piggybacking on top of #2317, this moves the
`python_multiprocessing_lock_works` test yet again, moving
`codex-rs/core/tests/sandbox.rs` to `codex-rs/exec/tests/sandbox.rs`
because in `codex-rs/exec/tests` we can use `cargo_bin()` like so:
```
let codex_linux_sandbox_exe = assert_cmd::cargo::cargo_bin("codex-exec");
```
which is necessary so we can use `codex_linux_sandbox_exe` and therefore
`spawn_command_under_linux_sandbox` in an integration test.
This also moves `spawn_command_under_linux_sandbox()` out of `exec.rs`
and into `landlock.rs`, which makes things more consistent with
`seatbelt.rs` in `codex-core`.
For reference, https://github.com/openai/codex/pull/1808 is the PR that
made the change to Seatbelt to get this test to pass on Mac.
Successfully merged upstream changes from openai/codex while preserving:
- Local theming system and theme selection UI
- Custom terminal architecture with enum-based HistoryCell
- Browser tools and Chrome launch options
- Reasoning effort selection UI
- Text verbosity selection UI
- All local UI customizations and animations
Key resolutions:
- Kept local enum-based HistoryCell instead of upstream's trait-based system
- Preserved TextBlock wrapper for text content
- Fixed imports and added missing constants (INITIAL_SUBMIT_ID)
- Updated ParsedCommand handling for upstream's String-based cmd fields
- Added missing pattern matches for new enum variants
- Fixed EnvironmentContext usage with proper constructor
The merge maintains full backward compatibility with all local features
while incorporating upstream bug fixes and improvements.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
- Modified core client and config components
- Enhanced TUI components including chatwidget and bottom pane
- Added verbosity selection view
- Various architectural improvements and local customizations
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
- Add new browser_console tool to capture and return console output from the browser
- Implement get_console_logs() method in BrowserManager with JavaScript hooks to capture console.log, warn, error, info, and debug messages
- Add handle_browser_console() handler in codex.rs to format console logs with timestamps and levels
- Modify get_openai_tools() to conditionally include browser tools based on browser state
- When browser is disabled: only browser_open and browser_status tools are available
- When browser is enabled: all browser interaction tools are included
- Browser state is determined by checking if global browser manager exists
This allows the LLM to debug web pages by capturing console output and ensures browser interaction tools are only available when a browser session is active.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
Previous to this PR, `codex-rs/core/tests/sandbox.rs` contained
integration tests that were specific to Seatbelt. This PR moves those
tests to `codex-rs/core/src/seatbelt.rs` and designates
`codex-rs/core/tests/sandbox.rs` to be used as the home for
cross-platform (well, Mac and Linux...) sandbox tests.
To start, this migrates
`python_multiprocessing_lock_works_under_seatbelt()` from #1823 to the
new `sandbox.rs` because this is the type of thing that should work on
both Mac _and_ Linux, though I still need to do some work to clean up
the test so it works on both platforms.
## Summary
- add a unit test to ensure the macOS seatbelt policy allows POSIX
semaphores
- add a macOS-only test that runs a Python multiprocessing Lock under
Seatbelt
## Testing
- `cargo test -p codex_core seatbelt_base_policy_allows_ipc_posix_sem
--no-fail-fast` (failed: failed to download from
`https://static.crates.io/crates/tokio-stream/0.1.17/download`)
- `cargo test -p codex_core seatbelt_base_policy_allows_ipc_posix_sem
--no-fail-fast --offline` (failed: attempting to make an HTTP request,
but --offline was specified)
- `cargo test --all-features --no-fail-fast --offline` (failed:
attempting to make an HTTP request, but --offline was specified)
- `just fmt` (failed: command not found: just)
- `just fix` (failed: command not found: just)
Ran tests locally to confirm it passes on master and failed before my
previous change
------
https://chatgpt.com/codex/tasks/task_i_6890f221e0a4833381cfb53e11499bcc
The "display format" of commands was sometimes producing incorrect
quoting like `echo foo '>' bar`, which is importantly different from the
actual command that was being run. This refactors ParsedCommand to have
a string in `cmd` instead of a vec, as a `vec` can't accurately capture
a full command.
instead of each shimmer needing to have its own animation thread, have
render_ref schedule a new frame if it wants one and coalesce to the
earliest next frame. this also makes the animations
frame-timing-independent, based on start time instead of frame count.
This improves handling of pasted content in the textarea. It's no longer
possible to partially delete a placeholder (e.g. by ^W or ^D), nor is it
possible to place the cursor inside a placeholder. Also, we now render
placeholders in a different color to make them more clearly
differentiated.
https://github.com/user-attachments/assets/2051b3c3-963d-4781-a610-3afee522ae29
#2291 made it so that `Session::new()` is on the critical path to
`Codex::spawn()`, which means it is on the hot path to CLI startup. This
refactors `Session::new()` to run a number of async tasks in parallel
that were previously run serially to try to reduce latency.
## Summary
Currently, we use request-time logic to determine the user_instructions
and environment_context messages. This means that neither of these
values can change over time as conversations go on. We want to add in
additional details here, so we're migrating these to save these messages
to the rollout file instead. This is simpler for the client, and allows
us to append additional environment_context messages to each turn if we
want
## Testing
- [x] Integration test coverage
- [x] Tested locally with a few turns, confirmed model could reference
environment context and cached token metrics were reasonably high
refactors HistoryCell to be a trait instead of an enum. Also collapse
the many "degenerate" HistoryCell enums which were just a store of lines
into a single PlainHistoryCell type.
The goal here is to allow more ways of rendering history cells (e.g.
expanded/collapsed/"live"), and I expect we will return to more varied
types of HistoryCell as we develop this area.
Historically, `Codex::spawn()` would create the instance of `Codex` and
enforce, by construction, that `Op::ConfigureSession` was the first `Op`
submitted via `submit()`. Then over in `submission_loop()`, it would
handle the case for taking the parameters of `Op::ConfigureSession` and
turning it into a `Session`.
This approach has two challenges from a state management perspective:
https://github.com/openai/codex/blob/a9f986ca04a95944eab395605b035377184d46fe/codex-rs/core/src/codex.rs#L718
- The local `sess` variable in `submission_loop()` has to be `mut` and
`Option<Arc<Session>>` because it is not invariant that a `Session` is
present for the lifetime of the loop, so there is a lot of logic to deal
with the case where `sess` is `None` (e.g., the `send_no_session_event`
function and all of its callsites).
- `submission_loop()` is written in such a way that
`Op::ConfigureSession` could be observed multiple times, but in
practice, it is only observed exactly once at the start of the loop.
In this PR, we try to simplify the state management by _removing_ the
`Op::ConfigureSession` enum variant and constructing the `Session` as
part of `Codex::spawn()` so that it can be passed to `submission_loop()`
as `Arc<Session>`. The original logic from the `Op::ConfigureSession`
has largely been moved to the new `Session::new()` constructor.
---
Incidentally, I also noticed that the handling of `Op::ConfigureSession`
can result in events being dispatched in addition to
`EventMsg::SessionConfigured`, as an `EventMsg::Error` is created for
every MCP initialization error, so it is important to preserve that
behavior:
https://github.com/openai/codex/blob/a9f986ca04a95944eab395605b035377184d46fe/codex-rs/core/src/codex.rs#L901-L916
Though admittedly, I believe this does not play nice with #2264, as
these error messages will likely be dispatched before the client has a
chance to call `addConversationListener`, so we likely need to make it
so `newConversation` automatically creates the subscription, but we must
also guarantee that the "ack" from `newConversation` is returned before
any other conversation-related notifications are sent so the client
knows what `conversation_id` to match on.
Force bash shell for build scripts to ensure consistent syntax across
all platforms. Also add platform-specific CPU core detection:
- Windows: Use NUMBER_OF_PROCESSORS env var
- Unix-like: Use nproc or sysctl
This fixes the 'export' command not recognized error on Windows PowerShell.
Switch to the industry-standard Swatinem/rust-cache action which:
- Automatically handles all Rust caching complexity
- Works perfectly with cross-compilation matrix builds
- Doesn't conflict with incremental compilation
- Provides better cache hit rates
- Is more reliable than sccache GHA service
Also added --locked flag to cargo build commands for reproducible builds.
This should significantly improve build times and reliability.
- Disable rust-ci workflow temporarily due to clippy warnings from upstream merge
- Add comprehensive build caching to Release and rust-release workflows:
- Cache cargo registry and build artifacts
- Add sccache for compilation caching
- Optimize with parallel jobs and incremental compilation
- Fix Rust formatting issues
- Fix some critical clippy warnings (redundant closures, format strings)
- Performance improvements should reduce CI build times significantly
The builds were taking 15-20 minutes but should now be much faster with:
- Cargo registry caching
- Target directory caching with content-aware keys
- sccache for compilation caching
- Parallel job optimization
- Incremental compilation enabled
- Query terminal capabilities at TUI startup using Picker::from_query_stdio()
- Store terminal info (picker and font size) and pass through initialization
- Fix unstable let-chains syntax in mcp-server
- Add missing std::env import in chatwidget.rs
- Add missing FilterType import for image resizing
- Update all ChatWidget creation calls to pass terminal_info
- Improve font size detection by querying once at startup instead of during render
This fixes the issue where from_query_stdio() couldn't work during rendering
because stdio was already in use by the TUI. Now we query capabilities once
at startup when it's safe to do so.
🤖 Generated with [Claude Code](https://claude.ai/code)
Co-Authored-By: Claude <[email protected]>
- Fix PowerShell variable substitution in Windows builds
- Use proper escaping for PowerShell string replacement
- Ensures version is correctly set in Cargo.toml on Windows
- Add determine-version job to calculate version before building
- Set version in Cargo.toml before building binaries
- Use pre-determined version for npm publishing
- This ensures binaries report correct version instead of 0.0.0
- Fixes upgrade check always appearing due to version mismatch
- Fix type mismatch in Chrome path vector on Windows
- Remove trailing whitespace in codex.rs and chatwidget.rs
- Ensure all paths in chrome_paths vector are String type