mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
dev
7919 Commits
-
[codex] Fully qualify hash-pins in GitHub Actions (#21436)
This builds on top of https://github.com/openai/codex/pull/15828 by ensuring that hash-pinned actions with version comments are fully qualified, rather than referencing floating/mutable comments like "v7". This makes actions management tools behave more consistently. This shouldn't break anything, since it's comment only. But if it does, ping ww@ 🙂
William Woodruff ·
2026-05-07 14:31:20 -07:00 -
Add a Cargo build profile for benchmarking (#21574)
A clean release build takes ~18m and an incremental build takes ~12m. This is far too slow to iterate on performance related changes and the build time is dominated by LTO. This pull request adds a `profiling` profile for Cargo which takes ~13m clean and ~6m incremental, the primary change is that LTO is disabled. This matches a profile used in uv and follows the great work at https://github.com/astral-sh/uv/pull/5955 — there's a bit of commentary there about the trade-offs this implies. We've found that this does not inhibit the ability to accurately benchmark as measurements with LTO disabled are generally consistent with the results with LTO enabled and it makes it much faster (~2x) to rebuild after making a change. This is motivated by my interest in improving Codex TUI performance, which is blocked by the tragically builds right now. I tested incremental build times by making a no-op change to the `codex-cli` crate.
Zanie Blue ·
2026-05-07 14:30:35 -07:00 -
Use descriptive names for Cargo profile options (#21582)
These are equivalent and their intent is clearer, e.g., I was confused if `debug = 1` meant the same thing as `debug = true` (it does not).
Zanie Blue ·
2026-05-07 14:19:32 -07:00 -
Grant sandbox users access to desktop runtime bin (#21564)
## Why Codex desktop copies bundled Windows binaries out of `WindowsApps` into a LocalAppData runtime cache before launching `codex.exe`. Sandboxed commands can then need to execute helpers from that cache, but the sandbox user group may not have read/execute access to the runtime bin directory. This makes the Windows sandbox refresh path repair that access directly so the packaged desktop runtime remains usable from sandboxed sessions. ## What changed - Added `setup_runtime_bin` to locate `%LOCALAPPDATA%\OpenAI\Codex\bin`, matching the desktop bundled-binaries destination path, with the same `USERPROFILE\AppData\Local` fallback shape. - During refresh setup, check whether `CodexSandboxUsers` already has read/execute access to the runtime bin directory. - If access is missing, grant `CodexSandboxUsers` `OI/CI/RX` inheritance on that directory. - If the runtime bin directory does not exist, no-op cleanly. ## Verification - `cargo build -p codex-windows-sandbox --bin codex-windows-sandbox-setup` - `cargo test -p codex-windows-sandbox --bin codex-windows-sandbox-setup` - Manual Windows ACL exercise against the installed packaged runtime bin: - existing inherited `CodexSandboxUsers:(I)(OI)(CI)(RX)` no-ops without changing SDDL - after disabling inheritance and removing the group ACE, setup adds `CodexSandboxUsers:(OI)(CI)(RX)` - with `LOCALAPPDATA` pointed at a fake location without `OpenAI\Codex\bin`, setup exits successfully and does not create the directory - restored the real runtime bin with inherited ACLs and confirmed the final SDDL matched the baseline exactly
iceweasel-oai ·
2026-05-07 11:38:10 -07:00 -
Route ThreadManager rollout path reads through thread store (#21265)
- Route ThreadManager rollout-path resume/fork through ThreadStore history reads. - Add in-memory store coverage proving path-addressed reads are used. This isn't strictly necessary for the ThreadStore migration, since these ThreadManager methods _only_ work for path-based lookups, but I'm trying to migrate all the rollout recorder callsites to use the threadstore were possible for consistency.
Tom ·
2026-05-07 11:25:25 -07:00 -
[codex] Fix pathless thread summaries (#21266)
## Summary Fix `getConversationSummary` so thread-id summaries work for stored threads that do not have a local rollout path, such as remote thread stores. The root cause was that `summary_from_stored_thread` returned `None` when `StoredThread.rollout_path` was absent, and `get_thread_summary_response_inner` treated that as an internal error. This made conversation-id lookups depend on a local-only field even though the thread store can address the thread by id.
Tom ·
2026-05-07 11:18:16 -07:00 -
Move thread name edits to ThreadStore (#21264)
- Route live thread renames through `ThreadStore` metadata updates. - Read resumed thread names from store metadata with legacy local fallback preserved in the store.
Tom ·
2026-05-07 11:12:22 -07:00 -
Upgrade
cargo-shearto 1.11.2 (#21547)## Summary Catches a few additional dependencies (`sha2`, `url`) that should be in `dev-dependencies`.
Charlie Marsh ·
2026-05-07 11:07:18 -07:00 -
[codex] Move tool specs onto handlers (#21461)
## Why This is the next stacked step after deleting the tool-handler kind indirection. Specs should come from the registered handlers themselves so registry construction has a single source of truth for handler behavior and exposed tool definitions. ## What changed - Added `ToolHandler::spec()` plus handler-provided parallel/code-mode metadata, and made `ToolRegistryBuilder::register_handler` automatically collect specs from registered handlers. - Moved builtin tool spec construction into the corresponding handlers and their adjacent `_spec` modules, including shell, unified exec, apply patch, view image, request plugin install, tool search, MCP resource, goals, planning, permissions, agent jobs, and multi-agent tools. - Reworked configurable handlers to receive their tool-building options through constructors, with non-optional handler options where the handler is always spec-backed. Shell fallback handlers keep an explicit no-spec mode because they are also registered as hidden dispatch aliases. - Kept `CodeModeExecuteHandler` on the explicit configured wrapper so the code-mode exec spec can still be built from the nested registry. ## Verification - `cargo check -p codex-core` - `cargo test -p codex-core tools::spec_plan::tests` - `cargo test -p codex-core tools::spec::tests` - `cargo test -p codex-core tools::handlers::multi_agents_spec::tests` - `RUST_MIN_STACK=16777216 cargo test -p codex-core tools::handlers::multi_agents::tests` - `cargo test -p codex-core tools::handlers::apply_patch::tests` - `cargo test -p codex-core tools::handlers::unified_exec::tests` - `just fix -p codex-core` - `git diff --check`
pakrym-oai ·
2026-05-07 10:48:36 -07:00 -
app-server: refresh live threads from latest config snapshot (#21187)
## Why App-server config writes were leaving existing threads partially stale. After a config mutation, the app-server told each live thread to run `Op::ReloadUserConfig`, but that path only re-read the user `config.toml` layer. Settings that came from the app-server's materialized config snapshot did not propagate to existing threads until restart. This change prevent a FS access from `core` for CCA. ## What changed - add `CodexThread::refresh_runtime_config()` and `Session::refresh_runtime_config()` so the app-server can push a freshly rebuilt config snapshot into a live thread - rebuild the latest config with each thread's `cwd` after config mutations, then refresh the thread from that snapshot instead of asking it to reload only `config.toml` - keep session-static settings unchanged during refresh, while updating runtime-refreshable state such as the config layer stack, `tool_suggest`, and derived hook/plugin/skill state - keep `reload_user_config_layer()` as the file-backed fallback for legacy local reload flows, but route the shared refresh logic through the new runtime refresh path ## Testing - add a session test that verifies `refresh_runtime_config()` rebuilds hooks from refreshed config - add a session test that verifies runtime-refreshable fields update while session-static settings like `model` and `notify` stay unchanged --------- Co-authored-by: Codex <noreply@openai.com>
jif-oai ·
2026-05-07 19:22:04 +02:00 -
add top-level remote-control command (#21424)
## Summary `codex --enable remote_control app-server --listen off` is the current way to start a headless, remote-controllable app-server, but it is hard to remember and exposes implementation details. This adds `codex remote-control` as a friendly top-level wrapper for that flow. The command starts a foreground app-server with local transports disabled and enables `remote_control` only for that invocation. ## Changes - Add a visible `codex remote-control` CLI subcommand. - Launch app-server with `AppServerTransport::Off`. - Append `features.remote_control=true` after root feature toggles so the explicit command wins over `--disable remote_control`. - Reject root `--remote` / `--remote-auth-token-env`, matching other non-TUI subcommands. - Add tests for parsing, launch defaults, override ordering, and remote flag rejection. ## Verification - `cargo test -p codex-cli` - `just fix -p codex-cli`
Owen Lin ·
2026-05-07 10:17:07 -07:00 -
[codex] Remove string-keyed MCP tool maps (#21454)
## Summary This PR removes the synthetic `HashMap<String, ToolInfo>` keys from MCP tool discovery. `McpConnectionManager::list_all_tools()` now returns normalized `Vec<ToolInfo>`, and downstream code derives identity from `ToolInfo::canonical_tool_name()`. The motivation is to keep model-visible tool identity on `ToolName`/`ToolInfo` instead of parallel string map keys, so future namespace changes do not have to preserve otherwise-unused lookup keys. ## Changes - Rename the MCP normalization path from `qualify_tools` to `normalize_tools_for_model` and return tool values directly. - Flow MCP tool lists through connectors, plugin injection, router/spec building, code mode, and tool search as vectors/slices. - Keep direct/deferred subtraction local to `mcp_tool_exposure`, using `ToolName` values. - Update tests to compare `ToolName` instances where MCP identity matters. ## Validation - `cargo test -p codex-mcp test_normalize_tools` - `cargo test -p codex-core mcp_tool_exposure` - `cargo test -p codex-core direct_mcp_tools_register_namespaced_handlers` - `cargo test -p codex-core search_tool_registers_namespaced_mcp_tool_aliases` - `just fix -p codex-mcp` - `just fix -p codex-core`
pakrym-oai ·
2026-05-07 10:16:10 -07:00 -
feat: Expose plugin share metadata in shareContext (#21495)
Extends PluginSummary.shareContext with shareUrl and reader shareTargets
xl-openai ·
2026-05-07 10:07:03 -07:00 -
[codex-analytics] add tool review event schema (#18747)
## Why We want to emit terminal review analytics for tool-related approval flows, but the event contract needs to exist before the reducer can publish anything. This PR is the schema-only slice for the Codex review event family. ## What changed - add the `ReviewEvent` analytics envelope in `codex-rs/analytics/src/events.rs` - define the review subject kind, reviewer, trigger, terminal status, and post-review resolution enums - define the review event payload with thread, turn, item, lineage, tool, and timing fields that the emitter stack will populate ## Verification - stacked verification in dependent PRs: `cargo test -p codex-analytics analytics_client_tests --manifest-path codex-rs/Cargo.toml` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/18747). * #18748 * #21434 * __->__ #18747 * #17090 * #17089 * #20514
rhan-oai ·
2026-05-07 09:46:46 -07:00 -
fix: preserve exact turn diffs after partial apply_patch failures (#21518)
## Why Follow-up to #21180: turn diffs are operation-backed now, but a failed `apply_patch` can still leave exact filesystem mutations behind. For example, a move can write the destination file before failing to remove the source. Treating the whole call as unknowable then drops a change that Codex actually knows happened, so the emitted turn diff can drift from the workspace. ## What changed - [`apply-patch`](https://github.com/openai/codex/blob/f55724e0276a9b3213170daf2701ccfa0ce22646/codex-rs/apply-patch/src/lib.rs#L248-L345) now returns `ApplyPatchFailure` with the exact committed prefix accumulated before an error. If a write failure may already have mutated the target, the delta is marked inexact instead of being reused blindly. - Move handling now records the destination write before attempting source removal, so a partially failed move can still report the destination file that definitely landed ([code](https://github.com/openai/codex/blob/f55724e0276a9b3213170daf2701ccfa0ce22646/codex-rs/apply-patch/src/lib.rs#L463-L521)). - [`ApplyPatchRuntime`](https://github.com/openai/codex/blob/f55724e0276a9b3213170daf2701ccfa0ce22646/codex-rs/core/src/tools/runtimes/apply_patch.rs#L49-L67) now accumulates committed deltas across attempts and forwards them even when the visible tool result is failed or sandbox-denied ([runtime path](https://github.com/openai/codex/blob/f55724e0276a9b3213170daf2701ccfa0ce22646/codex-rs/core/src/tools/runtimes/apply_patch.rs#L223-L250), [event path](https://github.com/openai/codex/blob/f55724e0276a9b3213170daf2701ccfa0ce22646/codex-rs/core/src/tools/events.rs#L215-L225)). - `TurnDiffTracker` now consumes committed exact deltas rather than only fully successful patches; exact-empty failures leave the aggregate unchanged, while inexact deltas still invalidate it. ## Verification - Added a regression test covering a failed move that still emits the committed destination diff: [`apply_patch_failed_move_preserves_committed_destination_diff`](https://github.com/openai/codex/blob/f55724e0276a9b3213170daf2701ccfa0ce22646/codex-rs/core/tests/suite/apply_patch_cli.rs#L1517-L1586). - Kept explicit coverage that an inexact delta clears the aggregate instead of publishing a guessed diff: [`apply_patch_clears_aggregated_diff_after_inexact_delta`](https://github.com/openai/codex/blob/f55724e0276a9b3213170daf2701ccfa0ce22646/codex-rs/core/tests/suite/apply_patch_cli.rs#L1589-L1655). --------- Co-authored-by: Codex <noreply@openai.com>
jif-oai ·
2026-05-07 18:05:45 +02:00 -
Ruslan Nigmatullin ·
2026-05-07 09:01:44 -07:00 -
[codex] add account id to feedback uploads (#21498)
## Why Feedback uploads already carry auth-derived context like `chatgpt_user_id`, but they do not include the authenticated workspace/account id. Adding `account_id` makes feedback triage easier when a user can operate across multiple ChatGPT workspaces. ## What changed - emit auth-derived `account_id` into feedback tags in `app-server` before the feedback snapshot is uploaded - preserve that tag through `codex-feedback` upload tag assembly alongside the existing merge behavior for other tags - extend `codex-feedback` coverage to assert that snapshot-derived `account_id` is present in uploaded tags ## Verification - `cargo test -p codex-feedback upload_tags_include_client_tags_and_preserve_reserved_fields` - `cargo test -p codex-app-server --lib feedback_processor`
pakrym-oai ·
2026-05-07 08:45:16 -07:00 -
Make turn diff tracking operation backed (#21180)
## Summary - replace filesystem-based turn diff tracking with an operation-backed accumulator - preserve enough verified apply_patch state to render move-overwrite cases correctly - keep the turn/diff/updated contract intact while removing remote-only turn-diff test skips This takes the assumption that no 3P services rely on the output format of `apply_patch` ## Why For the CCA file system isolation push --------- Co-authored-by: Codex <noreply@openai.com>
jif-oai ·
2026-05-07 11:33:47 +02:00 -
feat: make built-in MCPs first-class runtime servers (#21356)
## DISCLAIMER This is experimental and no production service must rely on this ## Why Built-in MCPs are product-owned runtime capabilities, but they were previously flattened into the same config-backed stdio path as user-configured servers. That made them depend on a hidden `codex builtin-mcp` re-exec path, exposed them through config-oriented CLI flows, and erased distinctions the runtime needs to preserve—most notably whether an MCP call should count as external context for memory-mode pollution. ## What changed - Model product-owned built-ins separately from config-backed MCP servers via `BuiltinMcpServer` and `EffectiveMcpServer`. - Launch built-ins in process through a reusable async transport instead of the hidden `builtin-mcp` stdio subcommand. - Keep config-oriented CLI operations such as `codex mcp list/get/login/logout` scoped to configured servers, while merging built-ins only into the effective runtime server set. - Retain server metadata after launch so parallel-tool support and context classification come from the live server set; built-in `memories` is now classified as local Codex state rather than external context. ## Test plan - `cargo test -p codex-mcp` - `cargo test -p codex-core --test suite builtin_memories_mcp_call_does_not_mark_thread_memory_mode_polluted_when_configured` --------- Co-authored-by: Codex <noreply@openai.com>
jif-oai ·
2026-05-07 10:36:32 +02:00 -
Show plugin hooks in plugin details (#21447)
Supersedes the abandoned #19859, rebuilt on latest `main`. # Why PR #19705 adds discovery for hooks bundled with plugins, but `/plugins` still only shows skills, apps, and MCP servers. This follow-up makes bundled hooks visible in the same plugin detail view so users can inspect the full plugin surface in one place. We also need `PluginHookSummary` to populate Plugin Hooks in the app; `hooks/list` is not enough there because plugin detail needs to show hooks for disabled plugins too. # What - extend `plugin/read` with `PluginHookSummary` entries for bundled hooks - summarize plugin hooks while loading plugin details - render a `Hooks` row in the `/plugins` detail popup <img width="3456" height="848" alt="CleanShot 2026-04-27 at 11 45 34@2x" src="https://github.com/user-attachments/assets/fe3a38d6-a260-4351-8513-fb04c93d725b" />
Abhinav ·
2026-05-07 00:21:14 -07:00 -
[codex] fix PluginListParams test initializer (#21494)
## Summary - update the app-server protocol test fixture to include the required `marketplace_kinds` field on `PluginListParams` ## Why `PluginListParams` now requires `marketplace_kinds`, but a later-added test fixture in `common.rs` still constructed the older shape with only `cwds`. That stale initializer breaks the main build with `missing field marketplace_kinds`. ## Impact This is a test-only repair. It restores compilation without changing the JSON-RPC schema or runtime behavior. ## Validation - `just fmt` - `cargo test -p codex-app-server-protocol`
xli-oai ·
2026-05-06 23:58:26 -07:00 -
Revert state DB injection and agent graph store (#21481)
## Why Reverts #20689 to restore the previous optional state DB plumbing. The conflict resolution keeps the newer installation ID and session/thread identity changes that landed after #20689, while removing the mandatory state DB and agent graph store dependency from ThreadManager construction. ## What changed - Restored `Option<StateDbHandle>` through app-server, MCP server, prompt debug, and test entry points. - Removed the `codex-core` dependency on `codex-agent-graph-store` and reverted descendant lookup back to the existing state DB path when available. - Kept newer `installation_id` forwarding by passing it beside the optional DB handle. - Kept local thread-name updates working when the optional state DB handle is absent. ## Validation - `git diff --check` - `cargo test -p codex-thread-store` - `cargo test -p codex-state -p codex-rollout -p codex-app-server-protocol` - Attempted `env CARGO_INCREMENTAL=0 cargo test -p codex-core -p codex-app-server -p codex-app-server-client -p codex-mcp-server -p codex-thread-manager-sample -p codex-tui`; blocked locally by a rustc ICE while compiling `v8 v146.4.0` with `rustc 1.93.0 (254b59607 2026-01-19)` on `aarch64-apple-darwin`.
pakrym-oai ·
2026-05-06 22:48:29 -07:00 -
[codex] Parallelize skills list cwd loading (#21441)
## Summary - process `skills/list` cwd entries with bounded concurrency of 5 - preserve the caller's requested cwd order in the response - add coverage that verifies response ordering remains stable ## Why Cold-start desktop traces showed that `skills/list` can dominate the shared config queue when it scans many workspace roots serially. The expensive work is largely independent per cwd, so the request was paying the sum of all cwd costs instead of the cost of the slowest bounded batch. ## Impact This keeps current request semantics intact while reducing the wall-clock time of large multi-root `skills/list` calls. That should also reduce how long later config-family requests, such as `plugin/list`, wait behind `skills/list` during startup. ## Validation - `just fmt` - `cargo test -p codex-app-server` - `cargo test -p codex-app-server skills_list_preserves_requested_cwd_order`
xli-oai ·
2026-05-06 21:25:24 -07:00 -
[codex] allow shared config reads in app-server queue (#21340)
## Summary - add a shared-read serialization mode for global app-server request families - let consecutive leading shared reads for the same family run together while keeping exclusive requests ordered - mark only `skills/list`, `config/read` and `plugin/list` as shared reads for now ## Why `skills/list` and `plugin/list` are read-only config-family requests, but the app-server queue currently treats every config request as exclusive. That means one long `skills/list` can make a later `plugin/list` wait even though the two requests do not mutate config. This change keeps the existing queue order but lets adjacent reads overlap. If a write is already waiting, later reads still stay behind it, so writes do not starve. ## Scope This intentionally keeps the first pass narrow: - shared reads: `skills/list`, `plugin/list` - still exclusive: `plugin/install`, `marketplace/*`, `skills/config/write`, `config/*write`, `config/read`, and the rest of the config family ## Validation - `just fmt` - `cargo test -p codex-app-server-protocol` - `cargo test -p codex-app-server` - `just fix -p codex-app-server-protocol` - `just fix -p codex-app-server` ## Desktop verification I ran the dev desktop app against this branch's built binary with the existing UI timing logs enabled. The app did use `/Users/xli/code/codex_6/codex-rs/target/debug/codex`. The new scheduler behavior works, but this narrow change does not remove every cold-start delay: in the observed trace, an earlier exclusive `config/read` was already queued ahead of the later `skills/list` and `plugin/list` requests, so the page-open plugin requests still waited behind that earlier exclusive config-family request before they could run together. That means this PR is the scheduler primitive needed for shared reads, not the complete end-to-end latency fix by itself. ## Not run - full workspace test suite, because repo policy requires explicit approval before running it after touching `app-server-protocol`
xli-oai ·
2026-05-06 21:16:31 -07:00 -
[codex] Add OpenAI Developers to tool suggest allowlist (#21423)
## Summary Add `openai-developers@openai-curated` to `TOOL_SUGGEST_DISCOVERABLE_PLUGIN_ALLOWLIST` so the OpenAI Developers plugin can be surfaced through tool suggestions once it is available in the Built by OpenAI marketplace. Update the discoverable plugin test fixture to assert the plugin is returned from the curated marketplace allowlist path. ## Validation - `cargo fmt --check` passed; rustfmt emitted the existing stable-channel warnings about `imports_granularity`. - `cargo test -p codex-core list_tool_suggest_discoverable_plugins_returns_uninstalled_curated_plugins` passed.
mifan-oai ·
2026-05-06 23:49:15 -04:00 -
[codex] Delete tool handler plan indirection (#21427)
## Why The spec split in the parent PR still left an intermediate registry plan that recorded `ToolHandlerKind` values and translated them into concrete handlers later. That kept tool registration dependent on static enum bookkeeping instead of registering handlers from the same code that assembles their specs. ## What Changed - Make `build_tool_registry_builder` register concrete handlers directly while adding specs. - Add small `ToolRegistryBuilder` helpers for spec augmentation and nested code-mode inspection. - Remove `ToolHandlerKind`, `ToolHandlerSpec`, and `ToolRegistryPlan`. - Update spec-plan tests to assert against the built `ToolRegistry` instead of static handler descriptors. ## Validation - `cargo check -p codex-core` - `cargo test -p codex-core tools::spec_plan::tests` - `cargo test -p codex-core tools::spec::tests` - `just fix -p codex-core`
pakrym-oai ·
2026-05-06 20:36:24 -07:00 -
fix(tui): clear first inline viewport render (#21450)
## Why The alpha TUI can render the initial trust-directory prompt with stale terminal text showing through spaces when startup begins below existing shell output. The first inline viewport transition can happen while the previous viewport is still empty, so the old clear path no-ops before Ratatui draws the prompt. Ratatui then skips blank cells because its previous buffer also thinks those cells are blank, leaving old terminal contents visible inside the prompt. ## What Changed - Clear from the new inline viewport top when the previous viewport is empty during a viewport transition. - Keep the existing clear-from-old-viewport behavior for normal viewport updates. - Add a VT100-backed regression test that pre-fills terminal contents, performs the first viewport clear, and verifies stale text inside the new viewport is removed while shell content above the viewport remains. ## How to Test 1. Start Codex alpha in a terminal that already has visible shell output above the cursor. 2. Use a fresh untrusted project directory so the trust-directory prompt appears. 3. Confirm the prompt text renders cleanly, with spaces staying blank instead of showing fragments of previous shell output. 4. As a regression check, confirm content above the inline viewport is still preserved in terminal scrollback. Targeted tests: - `cargo test -p codex-tui first_viewport_change_clears_from_new_viewport_when_old_viewport_is_empty -- --nocapture` - `cargo test -p codex-tui`
Felipe Coury ·
2026-05-07 02:48:49 +00:00 -
pakrym-oai ·
2026-05-07 02:24:20 +00:00 -
Add compact lifecycle hooks (started by vincentkoc - external contrib) (#19905)
Based on work from Vincent K - https://github.com/openai/codex/pull/19060 <img width="1836" height="642" alt="CleanShot 2026-04-29 at 20 47 40@2x" src="https://github.com/user-attachments/assets/b647bb89-65fe-40c8-80b0-7a6b7c984634" /> ## Why Compaction rewrites the conversation context that future model turns receive, but hooks currently have no deterministic lifecycle point around that rewrite. This adds compact lifecycle hooks so users can audit manual and automatic compaction, surface hook messages in the UI, and run post-compaction follow-up without overloading tool or prompt hooks. ## What Changed - Added `PreCompact` and `PostCompact` hook events across hook config, discovery, dispatch, generated schemas, app-server notifications, analytics, and TUI hook rendering. - Added trigger matching for compact hooks with the documented `manual` and `auto` matcher values. - Wired `PreCompact` before both local and remote compaction, and `PostCompact` after successful local or remote compaction. - Kept compact hook command input to lifecycle metadata: session id, Codex turn id, transcript path, cwd, hook event name, model, and trigger. - Made compact stdout handling consistent with other hooks: plain stdout is ignored as debug output, while malformed JSON-looking stdout is reported as failed hook output. - Added integration coverage for compact hook dispatch, trigger matching, post-compact execution, and the audited behavior that `decision:"block"` does not block compaction. ## Out of Scope - Hook-specific compaction blocking is not implemented; `decision:"block"` and exit-code-2 blocking semantics are intentionally unsupported for `PreCompact`. - Custom compaction instructions are not exposed to compact hooks in this PR. - Compact summaries, summary character counts, and summary previews are not exposed to compact hooks in this PR. ## Verification - `cargo test -p codex-hooks` - `cargo test -p codex-core manual_pre_compact_block_decision_does_not_block_compaction` - `cargo test -p codex-app-server hooks_list` - `cargo test -p codex-core config_schema_matches_fixture` - `cargo test -p codex-tui hooks_browser` ## Docs The developer documentation for Codex hooks should be updated alongside this feature to document `PreCompact` and `PostCompact`, the `manual`/`auto` matcher values, and the compact hook payload fields. --------- Co-authored-by: Vincent Koc <vincentkoc@ieee.org>
Andrei Eternal ·
2026-05-06 18:08:31 -07:00 -
feat: Add marketplace source filtering and plugin share context (#21419)
Adds marketplaceKinds to plugin/list for local, workspace-directory, and shared-with-me; omitted params keep default local plus gated global behavior, while explicit kinds are exact. Exposes shareContext on plugin summaries from local share mappings and remote workspace/shared responses, including remotePluginId and nullable creator metadata. Adds shared-with-me listing through /ps/plugins/workspace/shared, renames the workspace remote namespace to workspace-directory, and keeps direct remote read/share/install/update/delete paths gated by plugins rather than remote_plugin.
xl-openai ·
2026-05-06 16:12:23 -07:00 -
[codex] Move tool specs into core handlers (#21416)
## Why This is the first mechanical slice of moving tool spec ownership toward the handlers. `codex-tools` should keep shared primitives and conversion helpers, while builtin tool specs and registration planning live in `codex-core` with the handlers that own those tools. Keeping this PR to relocation and import updates isolates the copy/move review from the later logic change that wires specs through registered handlers. ## What changed - Moved builtin tool spec constructors from `codex-rs/tools/src` into `codex-rs/core/src/tools/handlers/*_spec.rs` or nearby core tool modules. - Moved the registry planning code into `codex-rs/core/src/tools/spec_plan.rs` and its associated types/tests into core. - Kept shared primitives in `codex-tools`, including `ToolSpec`, schema/types, discovery/config primitives, dynamic/MCP conversion helpers, and code-mode collection helpers. - Updated handlers that referenced moved argument types or tool-name constants to use the core spec modules. - Moved spec tests next to the moved spec modules. ## Verification - `cargo check -p codex-tools` - `cargo check -p codex-core` - `cargo test -p codex-tools` - `cargo test -p codex-core _spec::tests` - `cargo test -p codex-core tools::spec_plan::tests` - `just fix -p codex-tools` - `just fix -p codex-core` Note: I also tried the broader `cargo test -p codex-core tools::`; it reached the moved spec-plan/spec tests successfully, then aborted with a stack overflow in `tools::handlers::multi_agents::tests::tool_handlers_cascade_close_and_resume_and_keep_explicitly_closed_subtrees_closed`, which is outside this spec relocation.
pakrym-oai ·
2026-05-06 15:40:50 -07:00 -
Move skills watcher to app-server (#21287)
## Why Skills update notifications are app-server API behavior, but the watcher lived in `codex-core` and surfaced through `EventMsg::SkillsUpdateAvailable`. Moving the watcher out keeps core focused on thread execution and lets app-server own both cache invalidation and the `skills/changed` notification. ## What changed - Added an app-server-owned skills watcher that watches local skill roots, clears the shared skills cache, and emits `skills/changed` directly. - Registers skill watches from the common app-server thread listener attach path, including direct starts, resumes, and app-server-observed child or forked threads. - Stores the `WatchRegistration` on `ThreadState`, so listener replacement, thread teardown, idle unload, and app-server shutdown deregister by dropping the RAII guard. - Removed `EventMsg::SkillsUpdateAvailable`, the core watcher, and the old core live-reload test. - Extended the app-server skills change test to verify a cached skills list is refreshed after a filesystem change without forcing reload. ## Validation - `cargo check -p codex-core -p codex-app-server -p codex-mcp-server -p codex-rollout -p codex-rollout-trace` - `cargo test -p codex-app-server skills_changed_notification_is_emitted_after_skill_change`
pakrym-oai ·
2026-05-06 15:38:11 -07:00 -
Document Codex git commit attribution config (#21379)
## Summary - document that commit attribution for generated git commit messages is gated by the `codex_git_commit` feature flag - add an example `config.toml` snippet showing `commit_attribution` with `[features].codex_git_commit = true` - update the config schema description so the reference docs explain that `commit_attribution` only takes effect when the feature is enabled Fixes #19799. ## Validation - `cargo run -p codex-core --bin codex-write-config-schema` - `cargo test -p codex-config` - `cargo test -p codex-features` - `cargo fmt --check` - `git diff --check` ## Notes - `cargo test -p codex-core config_schema_matches_fixture` currently fails before reaching the schema test because `core_test_support` imports `similar` without a linked crate in this checkout. The narrower package checks above avoid that unrelated test-support build failure.
Brian Henzelmann ·
2026-05-06 16:14:50 -05:00 -
[codex] Fix Windows sandbox git safe.directory for worktrees (#21409)
## Why Windows sandboxed commands run as a sandbox user, while workspace repositories are usually owned by the real user. The sandbox compensates by injecting a temporary Git `safe.directory` entry into the child environment. That injection was still broken for linked worktrees because the helper followed the `.git` file's `gitdir:` pointer and injected the internal `.git/worktrees/...` location. Git's dubious-ownership check expects the worktree root instead, so sandboxed Git commands still failed in worktree-based Codex checkouts. ## What changed - Treat any `.git` marker, directory or file, as the worktree root for `safe.directory` injection. - Keep the safe-directory logic in `windows-sandbox-rs/src/sandbox_utils.rs` and have the one-shot elevated path reuse it. - Add regression coverage for both normal `.git` directories and gitfile-based worktrees. ## Validation - `cargo test -p codex-windows-sandbox sandbox_utils::tests` - `cargo test -p codex-windows-sandbox` built and ran; the new `sandbox_utils` tests passed, while two pre-existing legacy sandbox tests failed locally with `Access is denied`: `session::tests::legacy_non_tty_cmd_emits_output` and `spawn_prep::tests::legacy_spawn_env_applies_offline_network_rewrite`.
iceweasel-oai ·
2026-05-06 14:08:45 -07:00 -
[codex-analytics] emit tool item events from item lifecycle (#17090)
## Why After the tool-item schemas are in place, analytics needs to emit them from the app-server item lifecycle rather than requiring bespoke tracking at each callsite. The reducer should also reuse the shared thread analytics context introduced below it in the stack so later event families do not repeat the same reducer joins or missing-state ladder. ## What changed - Tracks tool-item completion notifications and emits the matching tool analytics event when a terminal item arrives. - Derives event-specific payload details for command execution, file changes, MCP calls, dynamic tools, collaboration tools, web search, and image generation. - Denormalizes thread, app-server client, runtime, and subagent provenance metadata through the shared thread analytics context. - Adds reducer coverage for item lifecycle emission and subagent metadata inheritance. ## Duration semantics `duration_ms` is computed from the app-server item lifecycle timestamps: `completed_at_ms - started_at_ms`. That makes it the duration of the lifecycle Codex observed locally, not necessarily the upstream provider's full execution time. - Web search usually has a meaningful observed lifecycle because Responses can send `response.output_item.added` before `response.output_item.done`; in that case `started_at_ms` comes from the added event and `completed_at_ms` comes from the done event. - Image generation can be much less precise. In the current observed stream, image generation often arrives only as a completed `response.output_item.done`; when there is no earlier added event, Codex synthesizes the started item immediately before completion, so `duration_ms` can be `0` even though upstream image generation took longer. - Standalone web search and standalone image generation work is expected to land after this stack. Those paths may introduce more direct lifecycle events or timing points, so the current web-search/image-generation duration semantics should be treated as the best available item-lifecycle approximation, not the final latency contract for those tool families. - `execution_duration_ms` is populated only where the completed item already carries a native execution duration; otherwise it remains `null` while `duration_ms` still reflects the local lifecycle interval. ## Currently placeholder / partial fields Some fields are included in the schema for the intended steady-state contract, but this PR does not yet populate them from real approval/review state: - `review_count`, `guardian_review_count`, and `user_review_count` currently default to `0`. - `final_approval_outcome` currently defaults to `unknown`. - `requested_additional_permissions` and `requested_network_access` currently default to `false`. ## Verification - `cargo test -p codex-analytics` --- [//]: # (BEGIN SAPLING FOOTER) Stack created with [Sapling](https://sapling-scm.com). Best reviewed with [ReviewStack](https://reviewstack.dev/openai/codex/pull/17090). * #18748 * #18747 * __->__ #17090 * #17089 * #20514
rhan-oai ·
2026-05-06 20:27:41 +00:00 -
[codex-tui] pass thread source for tui threads (#21401)
## Summary - mark TUI-created thread starts and forks with explicit `thread_source = user` - add focused coverage for embedded and remote lifecycle request builders ## Why Thread analytics now consume an explicit thread-level source classification instead of inferring it from `session_source`. The TUI still omitted that field, so TUI-created interactive threads would continue to land as `null` even after the new analytics plumbing shipped. ## Validation - `cargo test -p codex-tui app_server_session --lib`
rhan-oai ·
2026-05-06 13:18:41 -07:00 -
[codex] Split tool handlers into separate files (#21395)
## Why Several tool handler modules still bundled multiple `ToolHandler` implementations in one file. That made the handler directory harder to navigate and made otherwise local handler edits land in large shared modules. ## What - Split grouped tool handlers into one handler file each for agent jobs, goals, MCP resources, shell tools, and unified exec. - Kept shared parsing, payload, and runtime helpers in the existing parent modules, with re-exports preserving the existing handler import paths. - Updated the shell handler tests to construct `ShellCommandHandler` through the existing `ShellCommandBackendConfig` conversion now that the backend detail lives with the shell-command handler. ## Validation - `cargo check -p codex-core` - `cargo clippy -p codex-core --lib -- -D warnings` - `git diff --check -- codex-rs/core/src/tools/handlers` Targeted `codex-core` handler tests did not run locally because `core_test_support` currently fails to compile before reaching these tests due to an unresolved `similar` import.
pakrym-oai ·
2026-05-06 13:12:24 -07:00 -
[codex] Dedupe fallback model metadata warnings (#21090)
Fixes #21070. This is a small cleanup around model metadata handling for gateway/provider model names. It follows the report and proposed direction from @dkbush by keeping the fallback metadata warning useful without repeating it every turn, and by tightening the existing provider-prefix lookup path. - Track fallback metadata warning slugs in session state so each unresolved model warns once per session. - Keep warning emission outside the session-state lock and preserve the existing warning text. - Allow one-segment provider prefixes with hyphenated provider IDs, while preserving the multi-segment rejection behavior. - Add focused coverage for warning dedupe and hyphenated provider-prefix metadata matching. Testing: - Ran `just fmt`. - Ran `git diff --check`. - Added tests for the new warning dedupe and provider-prefix lookup behavior.
canvrno-oai ·
2026-05-06 13:11:44 -07:00 -
Avoid hard-coded environment context shell (#21390)
## Summary - make resolved turn environment shell metadata optional instead of hard-coding bash - render environment context shells from explicit environment metadata when present, falling back to the existing session shell - update environment context tests for inherited PowerShell-style fallback and explicit per-environment shell override ## Testing - Not run (not requested; formatted with `just fmt`). Co-authored-by: Codex <noreply@openai.com>
starr-openai ·
2026-05-06 19:54:26 +00:00 -
Avoid noisy OTEL diagnostics in codex exec (#21107)
`codex exec` should not print OpenTelemetry exporter self-diagnostics to stderr by default. Suppress the SDK and OTLP exporter targets unless callers explicitly opt in with `RUST_LOG`. Also stop defaulting the trace exporter to the log exporter, since OTLP HTTP endpoints are signal-specific and a logs endpoint is not valid for spans. Co-authored-by: Codex <noreply@openai.com> Co-authored-by: Codex <noreply@openai.com>
Christoph Paasch (OpenAI) ·
2026-05-06 12:49:13 -07:00 -
Route opted-in MCP elicitations through Guardian (#19431)
# Motivation Browser Use origin-access prompts are MCP elicitations, not direct tool-call approval prompts, so they were bypassing the Guardian approval path. We need a generic opt-in that lets eligible MCP elicitations use Guardian when the current turn already routes approvals there. # Description Add a generic elicitation reviewer hook in codex-mcp and wire codex-core to pass a Guardian reviewer callback when creating the MCP connection manager. The reviewer validates explicit mcp_tool_call opt-in metadata, builds a Guardian MCP tool-call review request from server/tool/connector metadata and tool params, and maps Guardian approval, denial, timeout, and cancellation decisions back to MCP elicitation responses. The new option to trigger this in the `_meta` object is: ``` "codex_request_type": "approval_request", ``` # Testing - RUST_MIN_STACK=8388608 NEXTEST_STATUS_LEVEL=leak cargo nextest run --no-fail-fast --cargo-profile ci-test --test-threads 2 - cargo clippy --tests -- -D warnings - cargo fmt -- --config imports_granularity=Item --check - cargo shear - pnpm run format - python3 .github/scripts/verify_cargo_workspace_manifests.py - python3 .github/scripts/verify_tui_core_boundary.py - python3 .github/scripts/verify_bazel_clippy_lints.py - git diff --check
Clark DuVall ·
2026-05-06 19:42:45 +00:00 -
fix(tui): persist ctrl-c draft via app event (#21397)
## Why The main branch started failing after #21351 merged because the merge commit kept calling `AppCommand::add_to_history` from `BottomPane::clear_composer_for_ctrl_c`, but main had already removed that helper as part of the history persistence refactor. The PR head passed because it was based on an older main commit where the helper still existed. This restores the Ctrl+C draft-stashing behavior using the current app-event path instead of the removed command helper. ## What Changed - Store the active `ThreadId` in `BottomPane` when history metadata is provided. - Emit `AppEvent::AppendMessageHistoryEntry` for Ctrl+C-cleared drafts. - Update the slash-clear regression test to assert the current history event shape. ## How to Test Targeted tests: - `cargo test -p codex-tui slash_clear_after_ctrl_c_keeps_stashed_draft_recallable` Broader local checks: - `just fix -p codex-tui` - `just argument-comment-lint -p codex-tui` - `git diff --check origin/main...HEAD` - `cargo test -p codex-tui` reached completion; the fixed test passed, and the only local failures were `status::tests::status_permissions_full_disk_managed_*`, blocked by this machine config rejecting `DangerFullAccess` via `/etc/codex/requirements.toml`.
Felipe Coury ·
2026-05-06 19:03:11 +00:00 -
[codex] Handle git pagination flags by position (#21381)
## Why This is a follow-up to the Windows Git safe-command bypass fix for BUGB-15601. Git's global `--paginate` / `-p` flags can route output through a configured pager, so they should not be auto-approved as safe before the subcommand. At the same time, `-p` after read-only subcommands like `log`, `diff`, and `show` is the common patch-output flag, so treating every `-p` as unsafe would make ordinary read-only inspection commands prompt unnecessarily. ## What Changed - Split Git option safety matching into explicit global-option and subcommand-option lists. - Treat global `git --paginate ...` and `git -p ...` as unsafe. - Keep post-subcommand patch usage such as `git log -p`, `git diff -p`, and `git show -p HEAD` safe. - Keep the pagination coverage with the shared Git safe-command implementation rather than the Windows wrapper tests. - Remove the stale `git_global_option_requires_prompt` helper now that safe-command Git option matching owns the prompt-required lists. ## Testing - `cargo test -p codex-shell-command`
iceweasel-oai ·
2026-05-06 11:53:26 -07:00 -
Remove core MCP list tools op (#21281)
## Why The core `Op::ListMcpTools` request path is no longer needed. Keeping it around left a dead request/response surface alongside the app-server MCP inventory APIs that own current server status listing. ## What Changed - Removed `Op::ListMcpTools`, `EventMsg::McpListToolsResponse`, and the core handler that built the MCP snapshot response. - Removed the now-unused `codex-mcp` snapshot wrapper/export and passive event handling arms in rollout and MCP-server consumers. - Updated tests that used the old op as a synchronization hook to wait on existing startup/skills events, and deleted the plugin test that only exercised the removed listing op. ## Validation - `cargo test -p codex-protocol` - `cargo test -p codex-mcp` - `cargo test -p codex-rollout -p codex-rollout-trace -p codex-mcp-server` - `cargo test -p codex-core --test all pending_input::queued_inter_agent_mail` - `cargo test -p codex-core --test all rmcp_client::stdio_mcp_tool_call_includes_sandbox_state_meta` - `cargo test -p codex-core --test all rmcp_client::stdio_image_responses` - `just fix -p codex-core -p codex-protocol -p codex-mcp -p codex-rollout -p codex-rollout-trace -p codex-mcp-server`
pakrym-oai ·
2026-05-06 11:20:34 -07:00 -
vendor: update bubblewrap to 0.11.2 (#21389)
## Why `codex-rs/vendor/bubblewrap` had fallen behind upstream, and upstream `v0.11.2` is the current Bubblewrap release. The release is a security update for `CVE-2026-41163`, affecting setuid Bubblewrap builds, and deprecates setuid support in favor of the default non-setuid build mode. ## What changed - Refreshed the vendored Bubblewrap sources under `codex-rs/vendor/bubblewrap` to upstream `v0.11.2`. - Brought in the upstream `-Dsupport_setuid` build option, which defaults setuid support off. - Updated vendored release notes and documentation files included with Bubblewrap. ## Verification Not run locally; this PR only refreshes the vendored upstream Bubblewrap source snapshot. Upstream release: https://github.com/containers/bubblewrap/releases/tag/v0.11.2
Michael Bolin ·
2026-05-06 18:10:30 +00:00 -
fix(tui): keep Ctrl-C stashed drafts after /clear (#21351)
## Why When a user stashes a draft with Ctrl+C, then runs `/clear`, the fresh chat session loses the in-memory composer history that held the stashed draft. Pressing Up after `/clear` can then recall an older submitted prompt instead of the draft the user explicitly saved for later. ## What Changed - Record Ctrl+C-cleared composer text through the existing message history path, so it survives the fresh session created by `/clear`. - Keep `/clear` itself out of local slash-command recall so it does not sit ahead of the stashed draft. - Add regression coverage for the full flow: submit a prompt, stash a later draft with Ctrl+C, run `/clear`, then recall the stashed draft before the older prompt. ## How to Test 1. Start Codex with `just c`. 2. Submit a short prompt such as `ok` and wait for the turn to complete. 3. Type a new draft, press Ctrl+C, then run `/clear`. 4. Press Up and confirm the stashed draft is restored. 5. Press Up again and confirm the older submitted prompt is still reachable after the stashed draft. Targeted tests: - `cargo test -p codex-tui slash_clear_after_ctrl_c_keeps_stashed_draft_recallable` Manual verification: - Reproduced the issue in tmux with `RUST_LOG=trace just c -c log_dir=...`: before the fix, Up after `/clear` recalled the older submitted prompt. - Re-tested the same tmux flow after the fix: Up after `/clear` restored the Ctrl+C-stashed draft.
Felipe Coury ·
2026-05-06 14:46:18 -03:00 -
[codex] Coordinate OpenAI docs sample with API key setup (#21263)
## Summary - Add the same API key setup coordination guidance to the embedded OpenAI Docs sample skill in `codex-rs/skills`. - Keep the skill description/frontmatter unchanged; the coordination lives only in the body. - Preserve direct OpenAI Docs routing for docs-only questions, citations, model/API guidance, conceptual explanations, and non-building examples. ## Why The Codex repo carries its own OpenAI Docs skill variant under `codex-rs/skills/src/assets/samples`. This keeps that embedded sample aligned with the other OpenAI Docs variants patched in the related PRs. ## Validation - `cargo test -p codex-skills` - `git diff --check`
mifan-oai ·
2026-05-06 13:46:15 -04:00 -
feat: move auto vaccum (#21378)
The initial vaccum is not needed anymore. We can consider all the DBs have been reclaimed by now
jif-oai ·
2026-05-06 19:32:28 +02:00 -
rollout: coalesce thread updated_at touches (#21367)
## Why Metadata-irrelevant rollout events currently refresh `threads.updated_at` on every flush. That keeps thread recency accurate, but it also turns high-frequency agent output into unnecessary SQLite writes. Recency only needs to advance periodically during an active session, while the final suppressed touch still needs to be persisted before shutdown. ## What changed - coalesce touch-only `updated_at` writes in the rollout writer, with a short production interval between persisted touches - retain the latest suppressed touch and flush it during shutdown so the thread is not left stale - extend rollout recorder coverage for coalesced touches, delayed refresh, shutdown flushing, and the existing missing-thread fallback path ## Verification - Added regression coverage in `rollout/src/recorder_tests.rs` for coalescing and shutdown flushing behavior. --------- Co-authored-by: Codex <noreply@openai.com>
jif-oai ·
2026-05-06 19:32:24 +02:00 -
[codex] Add response.processed websocket request (#21284)
## Summary - Add a `response.processed` websocket request payload and sender for Responses API websockets. - Send `response.processed` from `try_run_sampling_request` after a response completes, local turn processing succeeds, and the session-owned feature flag is enabled. - Add websocket coverage for both enabled and disabled feature-flag behavior. ## Validation - `just fmt` - `cargo test -p codex-core response_processed` - `cargo test -p codex-api responses_websocket` - `cargo test -p codex-features responses_websocket_response_processed_is_under_development` - `git diff --check` - `just fix -p codex-api -p codex-core -p codex-features` - `git diff --check origin/main...HEAD`
pakrym-oai ·
2026-05-06 09:58:46 -07:00