Commit Graph

6282 Commits

Author SHA1 Message Date
starr-openai
ef74ece7e6 Add CODEX_HOME environments TOML provider
Add the environments.toml schema, parser, validation, and provider implementation for configured websocket and stdio-command environments. This keeps the provider load helper available but does not make product entrypoints use it yet.

Co-authored-by: Codex <noreply@openai.com>
2026-05-07 16:22:05 -07:00
starr-openai
1fa0fec4dd Represent provider defaults with snapshots
Keep EnvironmentManager construction async to preserve caller behavior while moving provider-owned default selection into a single snapshot object.

Co-authored-by: Codex <noreply@openai.com>
2026-05-07 16:22:05 -07:00
starr-openai
0a7006cebc Simplify environment provider defaults
Co-authored-by: Codex <noreply@openai.com>
2026-05-07 16:22:05 -07:00
starr-openai
0db1e4b4d9 Fix exec-server transport CI failures
Co-authored-by: Codex <noreply@openai.com>
2026-05-07 16:22:05 -07:00
starr-openai
dc926a56c7 Represent provider defaults with snapshots
Keep EnvironmentManager construction async to preserve caller behavior while moving provider-owned default selection into a single snapshot object.

Co-authored-by: Codex <noreply@openai.com>
2026-05-07 16:21:56 -07:00
starr-openai
a2ef8e05b5 Simplify environment provider defaults
Co-authored-by: Codex <noreply@openai.com>
2026-05-07 16:21:56 -07:00
starr-openai
5086768859 Inline provider manager construction
Remove the private from_provider_parts helper. EnvironmentManager::from_provider now performs the provider read, validation, and manager construction directly, and tests use a small provider implementation instead of bypassing that path.

Co-authored-by: Codex <noreply@openai.com>
2026-05-07 16:21:56 -07:00
starr-openai
b8f4ee4439 Split provider environments from default id
Remove the EnvironmentProviderSnapshot wrapper. Providers now expose environments and the selected default id directly, while EnvironmentManager validates that the default id exists in the returned environment map.

Co-authored-by: Codex <noreply@openai.com>
2026-05-07 16:21:56 -07:00
starr-openai
7a8bed96eb Return provider environment snapshots
Make environment providers return the environment map and default id together. This keeps provider-owned startup state in one boundary and removes the separate default callback over a map.

Co-authored-by: Codex <noreply@openai.com>
2026-05-07 16:21:55 -07:00
starr-openai
93f68577ed Simplify provider default environment selection
Have providers return a concrete default environment id after constructing their environment map, using None to disable the default. This removes the DefaultEnvironmentSelection tri-state while preserving legacy derived defaults through the trait's default implementation.

Co-authored-by: Codex <noreply@openai.com>
2026-05-07 16:21:55 -07:00
starr-openai
a970e46442 Fix environment manager clippy lints
Co-authored-by: Codex <noreply@openai.com>
2026-05-07 16:21:55 -07:00
starr-openai
729d8109a3 Make environment providers own default selection
Let environment providers return an explicit default selection and let remote environments track the underlying transport instead of treating only websocket URLs as remote. This prepares the environment layer for stdio-backed remotes without introducing config-file loading.

Co-authored-by: Codex <noreply@openai.com>
2026-05-07 16:21:55 -07:00
starr-openai
1bfe59e42d codex: fix Windows stdio transport clippy (#20664)
Co-authored-by: Codex <noreply@openai.com>
2026-05-07 16:21:42 -07:00
starr-openai
26899a2d5b codex: address stdio transport review feedback (#20664)
Co-authored-by: Codex <noreply@openai.com>
2026-05-07 16:06:20 -07:00
starr-openai
9f125d25cb Use PowerShell for Windows stdio test helper
Avoid cmd.exe echo quoting semantics in the Windows stdio client test by reading stdin and writing the JSON-RPC initialize response from PowerShell.

Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:46 -07:00
starr-openai
256760d6b9 Fix Windows stdio test JSON quoting
Escape the JSON-RPC response quotes in the cmd.exe stdio test command so Windows emits valid JSON before the client initialize timeout.

Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:46 -07:00
starr-openai
e58b331d8f Apply rustfmt to stdio transport guard
Match the rustfmt shape reported by the PR20664 Format / etc CI job after boxing the retained stdio transport guard.

Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:46 -07:00
starr-openai
dd1c9ff41a Box retained stdio transport guard
Avoid the Windows clippy large-enum-variant failure while preserving the retained stdio child cleanup guard behavior.

Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:46 -07:00
starr-openai
62bd368d38 Fix stdio transport clippy issues
Keep the stack-introduced stdio transport variant explicit while avoiding dead-code and redundant-pattern lints reported by PR20664 CI.

Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:45 -07:00
starr-openai
28b23c5cd3 Narrow stdio client lifetime handling
Keep the retained transport ownership needed for stdio child cleanup, but drop the broader AtomicBool closed-state behavior and its targeted tests from this PR.

Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:45 -07:00
starr-openai
3ff901257a Flatten JSON-RPC connection state
Drop the separate JsonRpcConnectionRuntime wrapper so JsonRpcConnection directly owns the channels, disconnect watch, transport tasks, and transport guard. This keeps the lifetime model explicit without helper extraction methods.

Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:45 -07:00
starr-openai
c72f484068 Simplify exec-server connection ownership
Remove the runtime extraction helpers and make JsonRpcConnection ownership explicit at the destructuring sites. Let the stdio transport clean up through Drop so ExecServerClient no longer needs to call an explicit shutdown hook.

Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:45 -07:00
starr-openai
7557a7307a Restore exec-server processor ownership boundary
Keep the server-side connection processor on the original by-value parts API, and move the compatibility needed for that shape into JsonRpcConnection. The client still borrows the connection mutably so it can keep transport ownership with ExecServerClient.

Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:45 -07:00
starr-openai
08795f1b65 Simplify exec-server transport ownership
Remove the Option wrapper used only to force connection drop order and call transport shutdown explicitly instead. Also drop dead-code allowances that are no longer needed.

Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:45 -07:00
starr-openai
f47954caef Remove server disconnect race test
The stdio transport no longer adds a processor-side disconnect side channel, so drop the test that asserted that removed behavior. Client cleanup is covered at the RPC/client transport boundary instead.

Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:44 -07:00
starr-openai
c317a66c61 Simplify exec-server disconnect plumbing
Keep transport shutdown responsible for stdio child cleanup, and remove the separate disconnect watch channel from the JSON-RPC connection/runtime. The RPC client now keeps a single closed flag for rejecting calls after the ordered reader exits.

Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:44 -07:00
starr-openai
d4b347176a Fix exec-server transport CI failures
Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:44 -07:00
starr-openai
6a7112ad21 Rename exec-server transport input params
Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:44 -07:00
starr-openai
b4269e85ff Split JSON-RPC transport variants
Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:44 -07:00
starr-openai
29f8812a83 Model retained JSON-RPC transport generically
Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:43 -07:00
starr-openai
942a674042 Name retained exec-server connection field
Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:43 -07:00
starr-openai
6ed49d62d7 Order exec-server transport teardown before RPC teardown
Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:43 -07:00
starr-openai
045c740618 Clarify exec-server transport connect naming
Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:43 -07:00
starr-openai
21297834ed Simplify stdio exec-server transport ownership
Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:42 -07:00
starr-openai
c00a36e727 Address stdio exec-server review feedback
Spawn stdio exec-server commands directly from structured argv/env/cwd instead of wrapping a shell string, redact the connection label, and tie the stdio child guard to transport disconnect.

Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:42 -07:00
starr-openai
74e96987b8 Simplify exec-server transport internals
Keep environment transport connection policy on ExecServerClient instead of the transport enum, and replace the JSON-RPC connection tuple alias with named connection parts.

Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:42 -07:00
starr-openai
caea51d3b7 Clean up stdio client process groups
Use the existing process-group cleanup pattern for stdio command transports so wrapper shell children are terminated with the client lifetime. Add a regression test that drops the client after spawning a background shell child through the command-backed transport.

Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:42 -07:00
starr-openai
c956939cc6 Clarify exec-server transport lifetime ownership
Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:42 -07:00
starr-openai
0bb3f728e1 Remove duplicate stdio client test import
Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:42 -07:00
starr-openai
995a669971 Make exec-server RPC client Send-safe
Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:42 -07:00
starr-openai
9face2bcbf Add stdio exec-server client transport
Allow exec-server clients to connect through a shell command over stdio. The connection can now retain a drop resource so the spawned child is terminated when the JSON-RPC client is dropped.

Co-authored-by: Codex <noreply@openai.com>
2026-05-06 19:19:41 -07:00
Andrei Eternal
527d52df03 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>
2026-05-06 18:08:31 -07:00
xl-openai
11106016ff 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.
2026-05-06 16:12:23 -07:00
pakrym-oai
9417cf9696 [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.
2026-05-06 15:40:50 -07:00
pakrym-oai
d5eea229cc 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`
2026-05-06 15:38:11 -07:00
Brian Henzelmann
8f5d68f9d2 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.
2026-05-06 16:14:50 -05:00
iceweasel-oai
123e78b97b [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`.
2026-05-06 14:08:45 -07:00
rhan-oai
fbdbc6b2fe [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
2026-05-06 20:27:41 +00:00
rhan-oai
21295f47e2 [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`
2026-05-06 13:18:41 -07:00
pakrym-oai
b9c50a53d7 [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.
2026-05-06 13:12:24 -07:00