Commit Graph

7475 Commits

Author SHA1 Message Date
Adam Perry
9fc26ff835 path-uri: cover invalid Windows workdir forms 2026-06-13 08:05:36 +00:00
Adam Perry
ecb81b4049 unified-exec: test remote policy rejection before launch 2026-06-13 07:22:04 +00:00
Adam Perry
4aad497e57 exec-server: test Windows state across app-server resume 2026-06-13 07:15:18 +00:00
Adam Perry
c8ee960fe0 core: require explicit cwd for foreign defaults 2026-06-13 07:15:18 +00:00
Adam Perry
eb88561c3f app-server: reject nonportable environment cwd 2026-06-13 07:00:56 +00:00
Adam Perry
bc6931247b rollout: persist bounded command execution history 2026-06-13 06:42:25 +00:00
Adam Perry
7acc90f497 unified-exec: await failed process lifecycle events 2026-06-13 06:26:56 +00:00
Adam Perry
085f93b68b core: fail turns when environment metadata is unavailable 2026-06-13 06:26:56 +00:00
Adam Perry
9b9966b38f shell-command: use selected local environment cwd 2026-06-13 06:26:56 +00:00
Adam Perry
4c45a95cf6 app-server: retarget generated local environment cwd 2026-06-13 06:26:56 +00:00
Adam Perry
cb801e5199 path-uri: reject reserved Windows device names 2026-06-13 06:26:56 +00:00
Adam Perry
67e9065c0e unified-exec: reject foreign background terminal cwd listing 2026-06-13 06:26:56 +00:00
Adam Perry
2b8ebb343f codex: fix CI failure on PR #28026 2026-06-13 06:26:56 +00:00
Adam Perry
550f29ac2a exec-server: prove the real app-server cross-OS flow 2026-06-13 06:26:56 +00:00
Adam Perry
bc83fd5da6 unified-exec: finish short-lived lifecycle before turn completion 2026-06-13 06:26:56 +00:00
Adam Perry
7e93c916da exec-server: add hermetic Windows shell smoke coverage 2026-06-13 06:26:56 +00:00
Adam Perry
4e39c1cd20 bazel: materialize PowerShell in Wine prefixes 2026-06-13 06:26:43 +00:00
Adam Perry
7d8a9ef36b protocol: retain executor cwd in command events 2026-06-13 06:26:43 +00:00
Adam Perry
385e9e546a app-server: use ApiPathString for command cwd 2026-06-13 06:26:43 +00:00
Adam Perry
f89f19659a unified-exec: launch remote commands without host sandbox 2026-06-13 06:26:43 +00:00
Adam Perry
35c88706ff unified-exec: resolve shell and workdir for target 2026-06-13 06:26:43 +00:00
Adam Perry
fe560a0e13 exec-server: carry cwd as PathUri 2026-06-13 06:26:43 +00:00
Adam Perry
f5dfe0cb26 shell: reject foreign environments before host execution 2026-06-13 06:26:43 +00:00
Adam Perry
4d05d4e172 core: retain and persist executor environment identity 2026-06-13 06:26:34 +00:00
Adam Perry
13909721f4 app-server: accept environment-native cwd 2026-06-13 05:55:55 +00:00
Adam Perry
10d930f17b protocol: keep selected environment cwd as PathUri 2026-06-13 05:55:47 +00:00
Adam Perry
fc3d68468d bazel: add opt-in PowerShell runtime for Wine tests 2026-06-13 05:14:23 +00:00
Adam Perry
66756b4eca path-uri: parse and resolve paths by explicit convention 2026-06-13 05:13:58 +00:00
Adam Perry
4b98bc7f1a path-uri: satisfy argument comment lint 2026-06-12 21:55:35 -07:00
Adam Perry
b60c476990 codex: address PR review feedback (#27819) 2026-06-12 21:55:35 -07:00
Adam Perry
6647c365a5 codex: address PR review feedback (#27819) 2026-06-12 21:55:35 -07:00
Adam Perry
c99a7f235a codex: address PR review feedback (#27819) 2026-06-12 21:55:35 -07:00
Adam Perry
7b359240df codex: address PR review feedback (#27819) 2026-06-12 21:55:35 -07:00
Adam Perry
7a60009b73 codex: preserve foreign native path syntax (#27819) 2026-06-12 21:55:35 -07:00
Adam Perry
67639e8d9a codex: fix CI failure on PR #27819 2026-06-12 21:55:35 -07:00
Adam Perry
cd19c9588e codex: expand native path rendering coverage (#27819) 2026-06-12 21:55:35 -07:00
Adam Perry
19ed2d0e89 codex: address PR review feedback (#27819) 2026-06-12 21:55:35 -07:00
Adam Perry
c66111002d path-uri: render native paths across platforms 2026-06-12 21:55:35 -07:00
Adam Perry @ OpenAI
9d938a46d9 [codex] Add hermetic Wine exec-server test (#27937)
## Why

We want to make it possible for an app-server orchestrator on one OS to
control an exec-server on another host running a different OS. In
practice this kinda already works if you get lucky and the two hosts
have the same path format, but we mangle quite a lot of operations if
either end is Windows.

This test starts exercising that interaction, although right now the
initial bootstrap fails. Future changes will expand the test's
assertions to match improved support.

## What

Stacked on #27964. This adds a small Windows exec-server fixture and a
Linux protocol smoke test using the reusable Wine harness, covering
Windows environment discovery, non-TTY `cmd.exe` execution, output, exit
status, and working directory.

Once we've got the full codex binary cross-building under Bazel we could
consider moving to the real binary instead of the stripped down
exec-server-only binary used here.
2026-06-12 20:20:23 -07:00
Anton Panasenko
b9dc3b7a8b feat(app-server): enforce managed remote control disable (#27961)
## Why

Managed deployments need a reliable deny gate for remote control.
Persisted enablement and explicit startup requests currently remain able
to start the transport, while the removed `features.remote_control` key
is intentionally only a compatibility no-op.

This adds a dedicated requirement that administrators can use to force
remote control off without deleting the user's persisted preference.
Removing the requirement and restarting restores the prior choice.

## What Changed

- Added top-level `allow_remote_control` requirements parsing, sourced
layer precedence, debug output, and `configRequirements/read` exposure
as `allowRemoteControl`.
- Added a typed transport policy captured from the startup requirements
snapshot. Managed disable forces the initial state to disabled and
prevents enrollment, refresh, connection, and persisted-preference
mutation.
- Rejected every `remoteControl/*` RPC before parameter deserialization
with JSON-RPC `-32600` and `remote control is disabled by managed
requirements`.
- Preserved the existing disabled status notification and the previous
behavior when the requirement is `true` or omitted.
- Regenerated app-server protocol schemas and documented the new
requirement.

## Verification

- Confirmed all remote-control RPCs, including a malformed request,
return the managed-policy error while the initial status notification
remains `disabled`.
- Confirmed explicit ephemeral startup and persisted enablement make no
backend connection and leave the SQLite preference unchanged.
- Confirmed `allow_remote_control = true` does not enable or block
remote control and `configRequirements/read` returns
`allowRemoteControl: false` for the deny policy.

Related issue: N/A (managed-policy hardening).
2026-06-12 20:10:12 -07:00
felixxia-oai
5d7db08b61 [codex] Gate plugin MCP servers by auth route (#27459)
## Context

Some plugins expose both Apps and MCP servers. This PR moves auth-aware
surface projection into `core-plugins::PluginsManager`, so callers get a
consistent effective plugin view. Later PRs narrow the conflict rule and
update listing/install paths.

The high level goal of this PR is to set up the plumbing to
conditionally filter App/MCP in the plugin manager layer. We start by
removing MCP servers when using SIWC/Codex-backend auth, and removing
Apps when using API-key-style auth.

This PR is now stacked on #27652, which contains only the constructor
plumbing for seeding `PluginsManager` with the current auth mode.

## Stack

- PR1: #27652 seed plugin manager auth at construction.
- PR2: #27459 route plugin surfaces by auth mode.
- PR3: #27607 dedupe plugin MCP servers by App declaration name.
- PR4: #27602 preserve plugin Apps in connector listings.
- PR5: #27461 skip install-time plugin MCP OAuth for matching App
routes.

## Summary

- API-key/non-ChatGPT routes hide plugin Apps and keep plugin MCPs.
- ChatGPT/SIWC with Apps enabled keeps plugin Apps and suppresses MCPs
for dual-surface plugins.
- MCP-only plugins stay available for ChatGPT/SIWC sessions.
- Cached plugin load outcomes are re-projected when auth mode changes.

## Validation

```bash
cargo test -p codex-core-plugins plugin_auth_projection
cargo test -p codex-core list_tool_suggest_discoverable_plugins
git diff --check
```
2026-06-12 19:42:11 -07:00
Adam Perry @ OpenAI
5c8136f48a [codex] Add hermetic Wine test support (#27964)
## Why

We want to make it possible for an app-server orchestrator on one OS to
control an exec-server on another host running a different OS. In
practice this kinda already works if you get lucky and the two hosts
have the same path format, but we mangle quite a lot of operations if
either end is Windows.

We should be able to test the cross-platform interactions for
exec-server, but we want to do this fairly soon and need a lightweight
option for testing. Using Wine to run the Windows side is far from
perfect, but it should give us a decent measure of how well we're
handling the basics of paths, process spawning, shell interaction, etc.

Future changes will add actual exec-server tests and possibly extensions
to the Wine testing environment.

## What

To make the cross-target-triple build easy, these tests are added only
to the Bazel build. This change adds an x86_64 Wine prebuilt managed by
Bazel and some build rules that can set up the needed toolchain
transition.

The support library for running Wine in a test environment created by
the Bazel rules comes with its own basic unit and integration tests.
Their primary priority is to make sure we don't leak child processes on
developer machines and that we can build and launch a basic hello world
binary.

## Validation

Confirmed these new tests are running on the [x86_64 bazel ubuntu
jobs](https://github.com/openai/codex/actions/runs/27446432302/job/81132356855?pr=27937):

```
//bazel/rules/testing/wine:wine-smoke-test                      (cached) PASSED in 3.7s
//bazel/rules/testing/wine:wine-test-support-unit-tests         (cached) PASSED in 15.8s
```
2026-06-12 18:24:49 -07:00
felixxia-oai
aef40ad91f [codex] Add auth mode to plugin manager constructor (#27652)
## Context

Plugins can expose more than one way for Codex to use them: App
connectors for ChatGPT/SIWC-backed sessions and MCP servers for API key
login sessions. The broader goal is to make `PluginsManager` the place
that understands which plugin surfaces should be visible for the current
auth route, so callers do not each have to make that decision
themselves.

This PR is the small setup step for that work. It lets the plugin
manager be created with the current `AuthMode`, which gives the followup
auth routing PRs the information they need without relying on setter
injection.

## Stack

- PR1: #27652 seed plugin manager auth at construction.
- PR2: #27459 route plugin surfaces by auth mode.
- PR3: #27607 dedupe plugin MCP servers by App declaration name.
- PR4: #27602 preserve plugin Apps in connector listings.
- PR5: #27461 skip install-time plugin MCP OAuth for matching App
routes.

## Summary

- Let `PluginsManager::new_with_restriction_product` accept an initial
`AuthMode`.
- Keep `PluginsManager::new` behavior unchanged for ordinary callers.

## Validation

```bash
cargo test -p codex-core-plugins plugins_manager_tracks_auth_mode
cargo test -p codex-core list_tool_suggest_discoverable_plugins
git diff --check
```

---------

Co-authored-by: Xin Lin <xl@openai.com>
2026-06-12 18:00:31 -07:00
xl-openai
044c1420a1 [codex] Limit app-based plugin suggestions to remote catalogs (#27988)
## Summary

- Keep local plugin suggestions bounded to fallback and explicitly
configured plugins.
- Preserve app-overlap recommendations for remote plugins using cached
catalog metadata.
- Remove the WSL-specific local discovery exception and move
manager-owned discovery tests into `codex-core-plugins`.

## Why

Local curated marketplaces were allowlisted before plugin detail
loading, so every uninstalled candidate could be deep-read before its
app IDs were checked. That caused per-turn reads of candidate plugin
manifests, skills, app configs, hooks, and MCP configs, which is
especially expensive on slow disks.

Remote discovery does not need those local candidate reads because app
IDs are already available in the cached remote catalog. Installed local
plugins are still loaded when needed to determine the user's installed
app IDs.

## Validation

- `just fmt`
- `just test -p codex-core-plugins discoverable::tests` (13 passed)
- `just test -p codex-core plugins::discoverable::tests` (4 passed)
- `just bazel-lock-update`
- `just bazel-lock-check`
- `git diff --check`
2026-06-12 17:51:09 -07:00
Felipe Coury
c884536d84 feat(tui): reland token activity command (#27925)
## Why

[#25345](https://github.com/openai/codex/pull/25345) was approved,
green, and squash-merged into its stacked base branch,
`fcoury/tokenmaxxing-api`. Four minutes later, that base branch was
force-pushed back to an API-only rebased head while preparing
[#25344](https://github.com/openai/codex/pull/25344) for `main`. As a
result, the squash commit from #25345 was orphaned and the TUI command
never reached `main` or a release.

This PR relands the orphaned TUI change from
[`411410b8`](411410b85c)
on current `main`.

## What changed

- Add `/usage`, `/usage daily`, `/usage weekly`, and `/usage cumulative`
for account token activity.
- Fetch account usage asynchronously through the existing
`account/usage/read` app-server RPC.
- Render daily, weekly, and cumulative activity with theme-aware
terminal palettes and bounded transient cards.
- Preserve transcript ordering while assistant streams, history
consolidations, active cells, and hooks complete.
- Hide `/usage` from completion when backend auth is unavailable while
keeping typed-command guidance.
- Carry current-main behavior forward for cwd-aware Markdown parsing,
Windows Terminal color detection, and personal access token auth.
- Clear pending usage cards on thread rollback and delay completed cards
until live hook output is committed.
- Add focused regression and snapshot coverage for loading, auth errors,
invalid views, rollback, hook ordering, layout, and charts.

## Prior review

The original implementation was approved by Eric Traut in #25345 after
testing multiple themes and light/dark terminals. This PR preserves that
reviewed implementation while adapting it to current `main` and adding
regression coverage for newer rollback and hook lifecycle behavior.

## Validation

- `just test -p codex-tui token_activity palette renderable
usage_command` — 37 passed.
- Focused rollback, hook-ordering, and error snapshot tests — 4 passed.
- `just fix -p codex-tui` — passed.
- `UV_CACHE_DIR=/private/tmp/codex-uv-cache just fmt` — passed.
- `cargo insta pending-snapshots` — no pending snapshots.
- `just test -p codex-tui` — 2,870 passed; two unrelated guardian
feature-flag tests failed because their expected `OverrideTurnContext`
event was absent:
-
`update_feature_flags_disabling_guardian_clears_manual_review_policy_without_history`
-
`update_feature_flags_disabling_guardian_clears_review_policy_and_restores_default`
- `just argument-comment-lint` could not complete because the local
Bazel LLVM `compiler-rt` repository is missing `include/sanitizer/*.h`.
The touched Rust diff was manually inspected and no missing
opaque-literal argument comments were found.
2026-06-12 17:33:43 -07:00
Eric Traut
9e07892253 [3 of 3] Support images in TUI goals (#27510)
## Stack

1. [1 of 3] Support long raw TUI goal objectives - #27508
2. [2 of 3] Support long pasted text in TUI goals - #27509
3. **[3 of 3] Support images in TUI goals** - this PR

## Why

The first two PRs make goal definitions resilient to long text, but
`/goal` still dropped image inputs from the composer. That meant a user
could attach images while defining a goal and the resulting goal
continuation would not have any useful reference to those images.

Goal state still persists only objective text, so image inputs need to
become paths or URLs that the agent can read later.

## What Changed

- Extends TUI `GoalDraft` with local image attachments and remote image
URLs.
- Copies local goal images through the app-server filesystem layer into
the managed goal attachment directory, then rewrites active image
placeholders to file references.
- Appends unplaced local images and remote image URLs to the objective
as referenced image files or URLs.
- Preserves goal image metadata through live `/goal` submission and
queued `/goal` dispatch.

## Verification

- Added goal materialization coverage for local image files and remote
image URLs.
- Added/updated TUI slash-command coverage showing `/goal` drafts
include attached images instead of dropping them.

## Manual Testing

- Attached an image by bracketed-pasting its local path into a live
`/goal` composer. The `[Image #1]` placeholder became a server-host
`image-1.png` reference, copied bytes matched exactly, and no attachment
was written under the TUI's local home.
- Deleted an image placeholder before submitting a small goal and
verified no image was copied.
- Attached PNG and JPEG files to the same goal. Placeholder order was
preserved as `image-1.png` and `image-2.jpg`, and both remote copies
matched their source bytes.
- Tried extensionless, malformed-extension, and
extension/content-mismatched paths; the composer rejected them as image
attachments before goal dispatch rather than creating misleading managed
image files.
- Combined a local image, a large pasted block, and enough raw text to
exceed 4,000 characters. The remote attachment directory contained the
image, paste sidecar, and `goal-objective.md`; all embedded references
used server-host paths and both payloads matched their sources.
- Submitted an image replacement while a goal was active, verified no
image was copied before confirmation, then canceled and confirmed the
attachment count was unchanged.
2026-06-12 17:14:27 -07:00
rphilizaire-openai
bacfc5e4c0 [codex] add latency tracing spans (#27710)
## Why

We have some large gaps in our thread start, resume, and pre-sampling
traces that make it hard to tell where latency is coming from.

## What Changed

- Added coarse spans around thread start/resume, turn context
construction, rollout reconstruction, skill/plugin loading, and tool
preparation.
- Added a breakdown of discoverable-tool preparation across connector
loading, plugin discovery, and local plugin details.

## Testing

- `cargo check -p codex-app-server -p codex-core -p codex-core-skills -p
codex-core-plugins`
- Built the app-server locally and exercised thread start, first turn,
follow-up turn, server restart, thread resume, and a resumed turn.
2026-06-12 17:11:32 -07:00
Tamir Duberstein
1460b509f4 [codex] stage npm packages concurrently (#27853)
In the release job from

https://github.com/openai/codex/actions/runs/27391514823

staging the nine npm release tarballs serially took 104 seconds.

Each package build writes to a separate staging directory, output path,
and npm cache. Run them through the script's existing thread pool,
bounded by the available CPU count. Delete each staging tree as its
build finishes so concurrency does not retain all copies until the end.

On ubuntu-24.04 in

https://github.com/openai/codex/actions/runs/27397232050

two serial trials took 103 and 101 seconds, while concurrent trials
both took 41 seconds. Comparing every extracted file from the first
serial and concurrent sets found no differences. This removes about one
minute from every release.
2026-06-13 00:01:14 +00:00
Tamir Duberstein
51483bb583 [codex] parallelize Windows package archives (#27854)
In the Windows x64 packaging job from

https://github.com/openai/codex/actions/runs/27391514823

building the primary and app-server package archives serially took 116
seconds.

Both archives read the same signed-binary directory but write separate
package trees and output files. Run them concurrently with xargs -P2.

The package helper rewrites DotSlash executables under the process temp
directory. A naive concurrent run failed when one process tried to
replace an executable used by the other. Give each bundle separate TMP
and TEMP roots to keep those caches independent.

On Windows x64 in

https://github.com/openai/codex/actions/runs/27397197944

three serial trials took 127, 128, and 126 seconds. Concurrent trials
took 76, 74, and 74 seconds, saving 52 to 54 seconds. This removes about
50 seconds from the release critical path without changing the packaging
commands or output set.
2026-06-13 00:00:15 +00:00
Adam Perry @ OpenAI
968a3ac9c1 [codex] make PathUri::from_abs_path infallible (#27976)
## Why

`PathUri::from_abs_path` can fail for absolute paths that do not have a
normal `file:` URI representation, forcing filesystem call sites to
handle a conversion error even though the original path can be preserved
losslessly.

## What

Make `from_abs_path` infallible and migrate its callers. Unrepresentable
paths use `file:///%00/bad/path/<base64>`, encoding Unix bytes or
Windows UTF-16LE; `to_abs_path` validates and decodes that fallback. The
leading encoded null reserves a namespace that cannot collide with a
real Unix or Windows path, and fallback URIs remain opaque to lexical
path operations.

## Validation

Added path-URI coverage for Unix null and non-UTF-8 paths, Windows
device/verbatim and non-Unicode paths, serialization, malformed
fallbacks, opaque lexical operations, invalid native payloads, and
literal `/bad/path` collision resistance.
2026-06-12 16:58:42 -07:00