Commit Graph

226 Commits

Author SHA1 Message Date
iceweasel-oai
2013e04354 Preserve filesystem permission path conventions (#39084)
## Why

Filesystem permission paths can use a convention that differs from the host
running Codex. Converting them immediately to native absolute paths can change
the meaning of ambiguous paths such as `/C:/secret` or Windows UNC paths.

## What changed

- Store literal filesystem permission paths as `PathUri` values through the
  runtime policy and execution protocol.
- Keep legacy string-based serialization at explicit protocol boundaries and
  reject conversions that cannot be represented losslessly.
- Encode native paths as opaque URIs when a normal file URI would imply the
  wrong path convention.

## Testing

Added coverage for cross-platform and ambiguous path round trips, UNC path
variants, permission-profile serialization, and deny-policy enforcement.

GitOrigin-RevId: 5247713796d1f2bb4e02f94eb9fc82d4698060f0
2026-08-17 21:49:30 +00:00
Ankush Gupta
4d9f3021c8 Include node_repl images in Guardian review evidence (#38454)
## What changed

- Preserve valid image content from completed `node_repl` Code Mode responses alongside text evidence for Guardian reviews.
- Enable multimodal evidence for models that require automatic `node_repl` review, or when both `guardian_enhanced_node_repl_transcripts` and `guardian_node_repl_transcript_images` are enabled.
- Bound retained and rendered evidence, deduplicate images already present in review history, and fall back to text-only evidence when the reviewer lacks image support or prompt capacity.
- Keep review evidence out of the parent turn input.

## Testing

- Cover feature gating, mixed text and image ordering, truncation and eviction, unsupported reviewers, prompt pressure, image detail normalization, and reused review sessions.

GitOrigin-RevId: a3e482402f7b3484401b231dadc662e6e3504fdf
2026-08-13 23:29:52 +00:00
jif
c30a3e49c9 Support sandboxed file streaming in exec-server (#38356)
## Why

Streaming reads previously rejected requests that used a platform filesystem
sandbox.

## What changed

- Open streamed files in the sandbox helper and return the open file to the
  exec-server by passing a file descriptor on Unix or duplicating a file handle
  on Windows.
- Advertise support through the `sandboxedFileStreaming` environment capability.
- Preserve close-on-exec behavior for transferred descriptors, including the
  required inherited-descriptor cleanup on macOS.

## Testing

- Cover bounded sandboxed streams, continued reads after path replacement, and
  rejection of symlink escapes outside readable roots.

GitOrigin-RevId: 677b2444b74e834b78b87a8554bc119c1c6e08b2
2026-08-13 11:11:26 +00:00
sayan-oai
f4936d7aba Support execution-host context when resolving cloud config (#38086)
## What changed

- Add a scoped `AbsolutePathBufGuard::with_home_directory` override so `~`
  paths can resolve against an explicitly supplied home directory while
  preserving the existing base-directory behavior. Nested overrides restore
  the previous home directory.
- Expose `compose_requirements_for_hostname` so callers can evaluate
  `remote_sandbox_config` for a supplied execution-host hostname.
- Cover cloud bundle conversion with execution-host path expansion and
  hostname-specific sandbox requirements.

GitOrigin-RevId: 6fd486992b45ff92e22bb4073b888252b544f285
2026-08-11 23:31:26 +00:00
felixxia-oai
bfb7790eb3 Remove obsolete plugin skill discovery helpers (#37832)
## What changed

- Remove the path-only `effective_skill_roots` API and its type-erasing trait in favor of `effective_plugin_skill_roots`, which preserves plugin metadata.
- Remove skill-path ancestor lookup helpers and keep namespace resolution scoped to an explicit plugin root.
- Update plugin manager and namespace tests to exercise the retained APIs directly.

GitOrigin-RevId: 507bf43bc6147bb5ab2deba4fa176bea2535159c
2026-08-10 14:25:13 +00:00
Eric Traut
6db53df37f Preserve child waiters during process termination (#37498)
## Why

Aborting the child waiter during termination can leave an exited PTY child
unreaped and prevent the session from recording its exit status.

## What changed

- Detach the child waiter instead of aborting it when terminating or dropping a
  `ProcessHandle`, while continuing to abort the I/O helper tasks.
- Cover explicit termination and handle drops for pipe processes, plus queued
  PTY waiters and PTY process-group termination on Unix.

GitOrigin-RevId: 313787f4edec80b30cf5a78f0cc6733f1520d9a4
2026-08-07 20:10:08 +00:00
felixxia-oai
e75a1888d7 Load plugin skill roots through the host skills service (#37440)
## What changed

- Implement `SkillRootLoader<PluginSkillRoot>` for `HostSkillsService`.
- Load roots concurrently while preserving request order, product restrictions, cached snapshots, skill errors, and per-skill filesystem metadata.
- Deduplicate overlapping roots and prefer native plugin skills over migrated commands with the same plugin ID and skill name.

## Testing

- Cover native and migrated skill precedence, nested and overlapping roots, product filtering, snapshot reuse, error propagation, and symlinked migration roots.

GitOrigin-RevId: 2270d10616b3a0463852c563ee071c524cd11e6b
2026-08-07 13:23:23 +00:00
Cam moten
9daa491f7c Harden local MCP server process tree cleanup (#37366)
## Why

A local stdio MCP server can exit while its descendants remain alive. Cleaning up
only the server process can therefore leak processes after client shutdown.

## What changed

- Contain locally launched MCP servers in non-breakaway Windows job objects and
  terminate the job during shutdown so descendants exit with the server.
- Preserve compatibility when job creation or assignment is unavailable by
  retrying without containment and terminating an owned process handle instead.
- Use the process-group member fallback when terminating piped processes on
  macOS.

## Testing

- Cover descendant cleanup and breakaway prevention for both local MCP protocol
  modes on Windows.
- Cover the Windows nested-job assignment fallback and verify the suspended
  process resumes before handle-based termination.

GitOrigin-RevId: 33d3cc122de8f7ce0ae69a649b12ea0ff64b7c6f
2026-08-07 03:34:49 +00:00
efrazer-oai
bc8b25ea02 Add durable user-message queue dispatch (#37204)
## What changed

- Add a storage-neutral queue extension for listing, adding, editing, reordering, deleting, and explicitly starting queued user messages.
- Dispatch queued messages in FIFO order when a thread becomes idle after a completed turn, while leaving them queued after interruptions or failures.
- Wait for user input to be persisted before removing its queue item, and report hook rejection, task termination, and persistence failures distinctly.
- Snapshot local image and audio attachments into validated data URLs before storing them, enforce input limits, and emit `ThreadQueueChanged` events after mutations.

## Testing

- Cover queue mutations, automatic and explicit dispatch, interruption and failure behavior, hook rejection, invalid records, input limits, and local attachment snapshotting.

GitOrigin-RevId: 14f39d7c8cbaccb767a6da84b82cced0edfcb4b9
2026-08-06 03:11:42 +00:00
iceweasel-oai
4cb8676d3a Make Windows path URI comparisons ASCII-case-insensitive (#37129)
## What changed

- Make `PathUri` equality and hashing ignore ASCII case for inferred Windows
  drive and UNC paths while preserving case-sensitive POSIX behavior.
- Apply the same convention-aware comparison to `starts_with` and
  `relative_path_from`, including equivalent percent-encoded path spellings.
- Continue to fail closed for encoded path separators, opaque fallback URIs,
  and non-ASCII case differences.

## Testing

- Add unit coverage for equality and hash consistency, Windows containment and
  relative paths, POSIX case sensitivity, encoded separators, and non-ASCII
  case differences.

GitOrigin-RevId: cd828874686a9cd242a36262ee3e7a9a172bd5b7
2026-08-05 17:55:57 +00:00
Cam moten
f2d825533c Fall back to per-process MCP cleanup on macOS (#37068)
## Why

Signaling an MCP server's process group can fail with `EPERM` on macOS,
preventing owned descendants from being terminated.

## What changed

- When a group signal is denied, enumerate the group's processes and signal
  members that still belong to the expected process group.
- Apply the fallback to both `SIGTERM` and `SIGKILL` during MCP stdio server
  cleanup, while retaining the existing group signaling behavior elsewhere.
- Reject invalid process group IDs and avoid signaling processes that have
  moved to another group.

## Testing

Added macOS tests covering cleanup with a live or exited group leader,
`SIGTERM`-resistant descendants, escalation to `SIGKILL`, and unsafe group IDs.

GitOrigin-RevId: db722475b94dece74244ce8109b3e92f6cfb202a
2026-08-05 09:43:26 +00:00
Sean Huang
cc03518c36 Extract audio preparation into a utility crate (#36807)
## What changed

- Add `codex-utils-audio` as a workspace crate for canonicalizing audio inputs
  and estimating their token usage.
- Update `codex-core` to consume the new crate while preserving the existing
  audio preparation tests.

GitOrigin-RevId: d719ecc08363ef52778aa37f3df0ca14f7778324
2026-08-03 22:46:26 +00:00
Colin Young
3149fa4b99 Terminate timed-out Git process trees (#36793)
## Why

Timing out a Git metadata command must not leave helper processes running after
the command wrapper exits.

## What changed

- Run Git metadata commands in a dedicated process group on Unix and a Job
  Object on Windows so timeout cleanup terminates their full process trees.
- Start Windows commands suspended, assign them to the Job Object, and then
  resume them so immediate descendants cannot escape containment.
- Preserve descendants when a Git command completes normally, and retain the
  existing direct-spawn fallback if Windows Job Object setup fails.

## Testing

Added cross-platform regression tests for cleanup both while the command wrapper
is running and after it exits, plus Windows coverage for immediate-child Job
Object containment.

GitOrigin-RevId: 351851708e23ff06b89fe1894bd09a3558f67293
2026-08-03 20:00:49 +00:00
jacobzhou-oai
2b5bdcf675 Support portable Agent Plugins throughout installation (#36544)
## Why

Agent Plugins use a schema-declared root `plugin.json` and can have dotted names or versions that do not fit Codex's directory-safe version format. The packaging and installation paths still assumed the legacy manifest layout and identifier rules.

## What changed

- Recognize valid root Agent Plugin manifests when discovering, packing, and installing plugins, while leaving unrelated root manifests on the legacy path.
- Accept safe dotted plugin names, default missing Agent Plugin versions to `1.0.0`, and derive stable directory-safe versions when necessary without rewriting the portable manifest.
- Skip legacy command migration for Agent Plugins and reject symlinks or other unsupported file types while copying plugin sources.

## Testing

Add coverage for portable bundle round trips, manifest discovery, dotted names, version handling, command preservation, and symlink rejection.

GitOrigin-RevId: 61476c4c4100495842253d8b429c0b896490962d
2026-08-02 02:29:45 +00:00
Charlie Marsh
003ec63bba Avoid redundant filesystem probes (#36393)
## What changed

- Load `environments.toml` in one operation, falling back to the default
  environment provider only when the read reports that the file is missing.
- Attempt the default daemon socket connection directly instead of checking the
  socket path first.
- Preserve each file search entry's type from the directory walker, avoiding a
  second metadata lookup when producing matches and correctly classifying
  followed directory symlinks.
- Write atomic-file contents through the existing temporary-file handle rather
  than reopening its path.

## Testing

- Add Unix coverage for classifying a followed directory symlink as a
  directory in file search results.

GitOrigin-RevId: aa6739cac23953ca8b9a3fcb53e43e72c41cfdf9
2026-07-31 21:37:56 +00:00
Curtis 'Fjord' Hawthorne
1bef168976 Track image preparation details in turn analytics (#36388)
## What changed

- Record the effective detail setting and source and prepared dimensions for
  successfully decoded images.
- Associate message images with their role and tool-output images with their
  originating call ID.
- Include the collected image preparation metadata in the corresponding turn
  analytics event.

## Testing

- Cover image resize metadata, tool-output attribution, turn aggregation, event
  serialization, and app-server analytics output.

GitOrigin-RevId: dbfb5ba1ce7cb02dd93d9b579c5109817f16aef5
2026-07-31 20:34:41 +00:00
Dylan Hurd
b7a6106608 Add an --approve-for-me CLI flag (#36373)
## What changed

- Add `--approve-for-me` to interactive and exec commands to route approval requests through automatic review.
- Configure the mode with `approval_policy="on-request"` and the `workspace-write` sandbox.
- Propagate the option across root, `exec`, `resume`, and `fork` argument handling while preserving later subcommand permission overrides.

## Testing

- Cover parsing, permission conflicts, root/subcommand precedence, resume handling, and the effective exec approval and sandbox modes.

GitOrigin-RevId: ae969e8c18f925f943049fefff56255f10b25659
2026-07-31 18:26:04 +00:00
iceweasel-oai
a01a2d9146 Preserve executor paths in read command actions (#36223)
## Why

Read command actions were omitted when a selected environment used a path
convention foreign to the app-server host. Clients need these actions to refer
to files in the executor's filesystem, not paths interpreted on the host.

## What changed

- Resolve read paths against the executor's `PathUri` and serialize them using
  the executor's native POSIX, Windows drive, or UNC convention.
- Accept same-drive Windows-relative paths while continuing to reject paths
  that require another drive's executor-local current directory.
- Document the path convention used by `commandExecution` notifications.

## Testing

Cover native and cross-platform path serialization, Windows drive-relative
joins, and selected-environment `item/started` and `item/completed`
notifications.

GitOrigin-RevId: 3c5a9bb1caafd35e04a0a0cceab91fee590372b9
2026-07-30 21:12:41 +00:00
Celia Chen
7d5253d2b0 Route Ollama through the shared HTTP client (#36078)
## Why

Ollama requests need to honor Codex's configured outbound proxy policy and custom CA handling.

## What changed

- Replace Ollama's direct `reqwest` client with a route-aware client created by `codex-http-client`.
- Preserve the five-second connection timeout and legacy system-root fallback for default-routed requests.
- Reuse one Ollama client for connectivity, version, model discovery, and model-pull checks.
- Surface HTTP transport initialization errors instead of replacing them with the generic Ollama connection error.

## Testing

- Cover system-proxy routing and invalid `CODEX_CA_CERTIFICATE` and `SSL_CERT_FILE` values under both outbound proxy policies.
- Verify that version and model checks reuse the existing Ollama client.

GitOrigin-RevId: c7cc36845a9bceb57ce5524b9e1b3cbe317897a3
2026-07-30 04:26:36 +00:00
iceweasel-oai
8707a35113 Normalize Windows namespace paths in path URIs (#35851)
## What changed

- Convert Windows device-namespace drive paths such as `\\?\D:\reports` and
  `\\.\D:\reports` to canonical drive-based `file:` URIs.
- Convert device-namespace UNC paths to canonical hosted `file:` URIs.
- Preserve unsupported or ambiguous namespace paths as opaque path URIs instead
  of interpreting them as filesystem paths.

## Testing

Add coverage for namespace path conversion and joining, including malformed UNC
paths, reserved device names, and volume identifiers.

GitOrigin-RevId: 234f69bc2787e5d318bc0320b94e7392abfb5602
2026-07-29 00:13:06 +00:00
iceweasel-oai
6b23635a7e Terminate Windows non-TTY processes on interrupt (#35655)
## Why

Windows non-TTY exec sessions reported interrupts as unsupported, so sending
Ctrl-C through `write_stdin` did not stop the running process.

## What changed

- Route interrupt requests for Windows non-TTY processes through their existing
  termination callback, including pipe-backed processes.
- Track whether driver-backed Windows sessions use a TTY so PTY interrupts keep
  their existing behavior.
- Consume the terminator after a successful interrupt to avoid invoking it again
  when the process handle is dropped.

## Testing

Added coverage for local and remote exec-server sessions, unified exec, pipe
fallbacks, and legacy Windows sandbox processes.

GitOrigin-RevId: 34504d01f091ef57bb961e98ad5a8d9f1acee4ee
2026-07-27 18:37:11 +00:00
jameswt-oai
07fd04abb1 Propagate remote plugin IDs to skill metadata (#35261)
## What changed

- Carry a plugin's local and remote identities together from plugin loading into
  `SkillMetadata`.
- Resolve remote IDs from the installed-plugin snapshot when available, falling
  back to persisted install metadata only when no snapshot exists.
- Include plugin identity in skill cache keys so identity changes refresh cached
  skill metadata.

## Testing

- Cover snapshot and persisted identity resolution, local marketplace isolation,
  cached skill refreshes, and propagation through plugin skill snapshots.

GitOrigin-RevId: aabeeb631a43361fe817358ace7f1ea8ba5db708
2026-07-24 23:36:11 +00:00
jacobzhou-oai
a28374e0db Support Agent Plugins manifests (#35105)
## What changed

- Recognize root `plugin.json` files using the Agent Plugins 1.0 schema and map their portable metadata, `skills/`, and `mcp.json` into Codex plugin manifests.
- Apply Codex-specific apps, hooks, and interface settings from the inline `com.openai` extension, with `.codex-plugin/plugin.json` as a fallback overlay.
- Preserve legacy manifest precedence when a root `plugin.json` is unrelated, and reject unsupported Agent Plugins schema versions.
- Add a direct-child skill discovery mode that excludes nested skills and paths resolving outside the plugin root.

## Testing

- Cover manifest metadata, validation, extension precedence, legacy fallback, and direct-child skill path boundaries.

GitOrigin-RevId: eab24139f13a5cc5cb3ad3fb444d8e904511aca6
2026-07-24 05:59:16 +00:00
Adam Perry @ OpenAI
1823c13771 Render turn diffs for foreign environment paths (#34654)
## Why

Turn diffs need to render paths from remote environments whose path convention may differ from the Codex host.

## What changed

- Preserve `PathUri` values through applied patch deltas, display-root discovery, and turn-diff tracking.
- Add host-independent relative-path rendering and normalize Windows drive-letter case in `PathUri`.
- Render paths relative to each environment's repository root while keeping Git diff headers slash-separated.

## Testing

- Cover POSIX, Windows, UNC, encoded-separator, and opaque URI relative paths.
- Verify an applied patch in a remote Windows working directory emits a portable unified diff.

GitOrigin-RevId: 526f70ae36a40627de5496d375310d12295b69bb
2026-07-22 02:19:45 +00:00
Michael Bolin
bdd3118c71 Update Windows process-tree tests for inherited FDs (#34640)
## Why

The PTY and pipe spawn helpers now require callers to specify which file
descriptors should be inherited, following
https://github.com/openai/codex/pull/13644.

## What changed

Pass empty inherited-FD slices from the Windows process-tree tests, which do
not need to preserve any file descriptors.

GitOrigin-RevId: 5e578df34e195251490608a163f8aaee0a6e681c
2026-07-21 23:29:03 +00:00
iceweasel-oai
9b33613db6 Terminate Windows process trees with job objects (#34624)
## Why

Terminating a Windows execution session must also stop child processes, while a
normal root-process exit must continue to allow background descendants to run.

## What changed

- Assign Windows pipe, ConPTY, and sandbox processes to job objects and terminate
  the job when a session is cancelled, times out, or is explicitly stopped.
- Preserve descendants when the root process exits normally.
- Attach ConPTY and sandbox processes to their jobs atomically at creation; keep
  root-process termination as a fallback where job setup is unavailable.

## Testing

Added Windows coverage for descendant termination and preservation across pipe,
ConPTY, capture, cancellation, and legacy sandbox execution paths.

GitOrigin-RevId: 8f831f2fc4caaa7b79ce842a3ed7192bd02dd3b4
2026-07-21 22:07:09 +00:00
iceweasel-oai
35c2278dd5 Support Windows sandboxing in the exec server (#34423)
## Why

Sandboxed process launch through the exec server was unsupported on Windows.

## What changed

- Add a shared native process launcher that selects the Windows sandbox session backend when required and otherwise launches PTY or pipe-based processes.
- Pass Windows permission, workspace-root, proxy, filesystem-override, and desktop settings through exec-server process preparation.
- Preserve piped stdin and inherited file descriptors across the shared launch path.

## Testing

- Verify that a remote Windows sandbox process accepts stdin while blocking a write under a read-only policy.
- Enable workspace-root sandbox tests on native Windows while continuing to skip environments that cannot emulate Windows sandbox semantics.

GitOrigin-RevId: 6719ccbe87ad0d5a57af56503e3f23f894c60a71
2026-07-20 22:35:14 +00:00
nhamidi-oai
6f785632b0 Preserve audio across history and tool outputs (#34385)
## Why

Audio attachments could be dropped from tool outputs and reconstructed thread history, while inline base64 payload size could overstate their model context cost.

## What changed

- Preserve remote and local audio attachments in legacy user-message events and thread history.
- Keep audio from function and custom tool outputs when the model supports it and the output fits the truncation budget; otherwise replace it with an omission marker.
- Estimate inline audio cost from its duration, with a serialized-size fallback for malformed or unsupported data URLs, so compaction and truncation use model-visible cost instead of raw base64 size.
- Replace audio in messages and tool outputs with an explanatory placeholder for models without audio input support.

## Testing

Add coverage for history round trips, dynamic tool responses, modality filtering, duration-based context estimates, output-budget truncation, and remote compaction.

GitOrigin-RevId: 5ed4628850a668f8383b7cd73db71b144cc02cd1
2026-07-20 17:36:44 +00:00
Charlie Marsh
221a341029 Remove unused Rust helpers (#34345)
## What changed

- Remove unused APIs and test helpers across the Rust workspace.
- Route Linux sandbox test setup through the shared exec request path.
- Drop dependencies that became unnecessary after the cleanup.

GitOrigin-RevId: 48fd9b2b1575bad7add0819786b4d8ec88d8486f
2026-07-20 13:45:29 +00:00
nhamidi-oai
97dbd01a3d Add audio variants to user input protocols (#33923)
## What changed

- Add remote and local audio variants to core and app-server user inputs, including generated JSON and TypeScript schemas.
- Preserve audio fields when converting app-server inputs and response content into thread items.
- Keep unsupported audio out of model requests, TUI rendering, text extraction, and truncated tool output, using explicit text placeholders where audio is submitted as a model input.

## Testing

- Cover app-server media conversion, unsupported-input placeholders, TUI omission, and tool-output truncation.

GitOrigin-RevId: 16152bf3af674575ce569764a8b472e032e7569d
2026-07-17 23:14:37 +00:00
jif
7c4aaf28c2 Keep feature tests focused on behavior (#33864)
## What changed

Remove tests that only restate feature registry metadata or constant values. Keep coverage for behavioral contracts such as feature aliases, dependency normalization, deprecated settings, and ignored removed settings.

GitOrigin-RevId: 45e2919dc3d854da3192ad7057a0f1c5c60271b9
2026-07-17 16:17:29 +00:00
Bryan Ashley
08e30a2e4e Add batched executor capability discovery (#33852)
## Why

Selected capability roots can contribute plugins, MCP servers, connectors, and
skills. Discovering each contribution separately requires repeated access to the
executor filesystem.

## What changed

- Add the `capabilityRoots/discoverV1` exec-server RPC to scan selected roots and
  materialize recognized plugin manifests, configuration files, skill
  instructions, and skill metadata in one bounded request.
- Add the opt-in `executor_capability_discovery` feature, with a thread-scoped
  cache and per-step snapshot shared by MCP and skill discovery.
- Parse MCP, connector, and skill contributions from the materialized snapshot,
  including serving cached skill instructions without another filesystem read.

## Testing

- Cover discovery limits, manifest precedence, root-local failures, cache reuse,
  plugin contributions, and parity with the existing environment skill loader.

GitOrigin-RevId: f98fd2321cafb58c596db02da1f83c09d8eb375d
2026-07-17 15:45:48 +00:00
charlesgong-openai
1c4af96394 Add Cursor support to setup import (#33426)
## What changed

- Detect and import supported Cursor settings, sandbox permissions, MCP servers,
  project instructions, hooks, agents, commands, plugins, and recent chat
  sessions.
- Update the `/import` flow to check Claude Code and Cursor, prompting for a
  source when both have importable data.
- Add `migrationSource` to the app-server detect and import requests so each
  operation uses the selected adapter, while retaining `source` for import
  attribution and backwards compatibility.

## Testing

- Add coverage for Cursor config conversion, hooks, plugins, session discovery
  and conversion, app-server imports, and TUI source selection.

GitOrigin-RevId: a65a1511b6c1c2f9e3e0cfe4f816bb435807282e
2026-07-15 21:03:49 +00:00
Adam Perry @ OpenAI
0396f99cf1 Preserve special filesystem subpaths as wire strings (#33107)
## Why

Special filesystem subpaths can contain relative or foreign-platform path
spellings. Treating this wire text as a host-native path can reinterpret it.

## What changed

- Store special filesystem subpaths as strings in the core permissions model.
- Represent app-server subpaths as `LegacyAppPathString` and convert them at
  the protocol boundary without changing their spelling.
- Add `LegacyAppPathString::from_string` for callers that already own legacy
  app-server path text.

GitOrigin-RevId: 2214f03aa997fd0e6eb2ab60d425304bb4bd6132
2026-07-14 16:40:13 +00:00
Adam Perry @ OpenAI
81f340436c path-uri: normalize parent segments in absolute joins (#29903)
## Why

`PathUri::join` normalized `..` for relative paths, but its
absolute-path branch rebuilt URIs through `url::PathSegmentsMut::push`,
which skips dot segments. `/tmp/a/../b` therefore resolved to `/tmp/a/b`
instead of `/tmp/b`.

## What changed

Normalize absolute native path segments before constructing the file
URI. Parent traversal now clamps at POSIX roots, Windows drive roots,
and UNC share roots, including paths with repeated separators.

Add platform-independent coverage for POSIX, drive, UNC, root-clamping,
and repeated-separator cases.

## Manual validation

- `just test -p codex-utils-path-uri`
2026-06-24 22:33:18 +00:00
iceweasel-oai
a781761eda [codex] fix Windows ConPTY input handling (#29734)
## Why

Windows unified-exec TTY input did not behave like the non-Windows PTY
path. ConPTY sessions could receive the wrong line ending or mishandle
backspace, especially when sending input to a foreground program through
PowerShell or cmd. The local, legacy restricted, and elevated paths also
handled this normalization separately.

## What changed

- share one stateful Windows TTY input normalizer across local, legacy
restricted, and elevated runner paths
- translate LF and split CRLF into one Windows terminal Enter, encode
backspace as DEL, and preserve UTF-8 and control bytes such as Ctrl-C
- add Windows integration coverage for Unicode input, backspace, Enter,
and PowerShell foreground-child Ctrl-C behavior

## Validation

- `just test -p codex-utils-pty` (13 tests passed; the Unicode
integration test retried once)
- the Unicode integration test passed five consecutive runs with retries
disabled
- integration coverage sends `cafeé 漢字` through cmd and PowerShell and
verifies that Ctrl-C interrupts a running PowerShell foreground child
2026-06-24 11:27:44 -07:00
jif
390b73133b Cache plugin namespace during executor skill discovery (#29831)
## Why

Executor skill discovery runs before the remote skills catalog is
available. For a remote environment, each `ExecutorFileSystem` operation
becomes an exec-server RPC.

Previously, every discovered `SKILL.md` independently resolved its
plugin namespace by walking its ancestors and probing both supported
manifest locations. In the common `plugin/skills/<skill>/SKILL.md`
layout, that repeats 8 RPCs per skill even though every skill under the
plugin root uses the same namespace. These lookups happen while skills
are parsed, so their cost grows linearly with the skill count and adds
directly to first-turn latency.

A selected capability root can also contain standalone skills, multiple
sibling plugins, nested plugins, or symlinked directories. The
optimization therefore needs to retain the nearest-ancestor namespace
for each skill rather than assuming the selected root represents exactly
one plugin.

## What changed

- record plugin-root candidates from directory entries already returned
during skill discovery
- prune candidates that are not ancestors of any discovered `SKILL.md`
before reading manifests
- resolve each relevant plugin root once, with one fallback lookup per
canonical traversal root for symlinked directories
- select the nearest cached plugin namespace for each discovered skill
- avoid namespace lookup entirely when the root contains no skills

No additional directory traversal is required. Namespace work now scales
with the number of plugin roots that contain discovered skills, rather
than the total number of skills or unrelated sibling plugins. Standalone
and nested-plugin names keep their previous behavior.

## Benchmarks

I used a temporary counting `ExecutorFileSystem` around the real local
filesystem. Each filesystem operation was counted as one remote RPC and
given 1 ms of injected latency. Each variant ran three times; times
below are medians.

### One plugin with 100 skills

| Operation | Before | After | Delta |
| --- | ---: | ---: | ---: |
| `get_metadata` | 1,002 | 303 | -699 |
| `read_file` | 200 | 101 | -99 |
| `read_directory` | 102 | 102 | 0 |
| **Total filesystem RPCs** | **1,304** | **506** | **-798 (-61.2%)** |
| **Median load time** | **2.890 s** | **0.997 s** | **2.90× faster** |

The namespace-specific work drops from 800 RPCs to 2 in this layout.

### Multiple plugins under one selected root

These runs compare the correct pre-optimization implementation with the
final nearest-plugin-root cache. The total plugin skill count stays at
100 while the number of plugin roots changes.

| Layout | Before RPCs | After RPCs | Reduction | Before | After |
Speedup |
| --- | ---: | ---: | ---: | ---: | ---: | ---: |
| 2 plugins × 50 skills | 1,312 | 530 | 59.6% | 1,819 ms | 711 ms |
2.56× |
| 10 plugins × 10 skills | 1,344 | 578 | 57.0% | 1,850 ms | 778 ms |
2.38× |
| 50 plugins × 2 skills | 1,504 | 818 | 45.6% | 2,094 ms | 1,086 ms |
1.93× |
| 10 plugins × 10 skills + 10 standalone skills | 1,596 | 630 | 60.5% |
2,209 ms | 860 ms | 2.57× |

The remaining cost grows with the number of relevant plugin manifests.
Each relevant manifest is read once instead of once per skill, while
sibling plugins with no discovered skills are not read. Absolute latency
savings depend on the executor's real RPC latency.

## Tests

- `just test -p codex-core-skills` (109 passed across the library and
integration-test binaries)
- one integration test covers standalone, outer-plugin, nested-plugin,
and unused sibling-plugin layouts, and asserts the exact set of
manifests read
2026-06-24 17:14:34 +01:00
jif
220f5b76b2 Load executor skills without host path conversion (#29626)
## Why

After #28918, selected skill roots are `PathUri`, but the executor skill
provider still converts them to the app-server host's `AbsolutePathBuf`.
A foreign Windows root therefore cannot be discovered by a Unix host,
and the inverse has the same problem.

This PR keeps executor skill discovery and reads on the filesystem that
owns the selected root while reusing the existing skill rules.

## What changed

- Generalize the existing skill traversal to operate on `PathUri`
through `ExecutorFileSystem`, preserving its depth, directory, symlink,
and sibling-metadata concurrency behavior.
- Add a small environment skill loader that reuses the shared discovery,
frontmatter validation, dependency parsing, product policy, and
prompt-visibility rules.
- Keep the environment id and entrypoint `PathUri` in the skill catalog,
then route `skills.read` back through the same environment filesystem.
- Preserve the executor's path convention when deriving catalog handles,
including literal backslashes in POSIX filenames.
- Resolve plugin namespaces from nearby manifests through URI-native
filesystem reads.
- Cover foreign Windows roots, executor-owned reads, namespaces,
metadata, policy, and path identity.

```text
selected root (PathUri)
        |
        v
shared discovery over ExecutorFileSystem
        |
        v
environment-bound catalog entry --skills.read--> same ExecutorFileSystem
```

No second filesystem abstraction or duplicate traversal implementation
is introduced.

## Stack

1. #29614 — add lexical `PathUri` containment.
2. #29620 — share URI-native manifest path resolution.
3. #28918 — keep selected plugin roots and resources URI-native.
4. **This PR** — load executor skills without host path conversion.
5. #29628 — resolve executor MCP working directories without host path
conversion.
2026-06-23 23:26:06 +01:00
jif
2e69966cd8 Make selected plugin roots URI-native (#28918)
## Why

Selected capability roots belong to the executor filesystem, not the
app-server host. Converting their path strings into the host's native
`Path` breaks whenever the two machines use different path conventions,
such as a Windows executor behind a Unix app-server.

This PR establishes `PathUri` as the selected-plugin boundary so the
executor remains authoritative for its paths.

## What changed

- Require `selectedCapabilityRoots[].location.path` to be a canonical
`file:` URI and deserialize it directly as `PathUri`; native path
strings are rejected.
- Update the app-server schema, generated TypeScript, examples, and
request coverage for the URI contract.
- Keep selected roots, resolved plugin locations, manifest paths, and
manifest resources as `PathUri`.
- Inspect and read plugin roots and manifests only through the selected
environment's `ExecutorFileSystem`.
- Parse executor manifests with the shared URI-native parser from #29620
instead of projecting them onto the host filesystem.
- Enforce resource containment lexically and preserve the root URI's
POSIX or Windows path convention.
- Cover foreign Windows plugin roots and URI-native manifest resources.

```text
thread/start
  selectedCapabilityRoots[].location.path = "file:///C:/plugins/demo"
                              | PathUri
                              v
                    ExecutorFileSystem
                              |
                              +--> plugin.json
                              +--> manifest resources
```

This PR stops at the shared selected-plugin representation. The next two
PRs remove the remaining host-path projections in the skill and MCP
consumers.

## Stack

1. #29614 — add lexical `PathUri` containment.
2. #29620 — share URI-native manifest path resolution.
3. **This PR** — keep selected plugin roots and resources URI-native.
4. #29626 — load executor skills without host path conversion.
5. #29628 — resolve executor MCP working directories without host path
conversion.
2026-06-23 22:51:19 +01:00
Adam Perry @ OpenAI
c26f961b85 path-uri: remove legacy path deserialization (#29158)
## Why

I'd originally added `PathUri` legacy path deserialization thinking we'd
want it for having `PathUri` in public app-server APIs. Since then we've
added `LegacyAppPathString` to handle the messy conversions that we need
for backcompat. It's confusing for `PathUri` to support deserializing
legacy paths when we don't yet want to actually expose app-server
callers or rollout storage to the new URI format.

Stacked on top of #29472 to avoid breaking compatibility in case those
types ended up stored somewhere for someone.

## What changed

- Parse deserialized `PathUri` values exclusively as valid `file:` URIs.
- Replace legacy acceptance coverage with rejection coverage for
top-level filesystem paths and sandbox working directories.
- Serialize CWDs in hand-built exec-server process requests as `PathUri`
values.
2026-06-23 21:47:00 +00:00
jif
f6500886b7 Decouple plugin manifest path resolution (#29620)
## Why

Plugin manifests use the same schema whether the package lives on the
host or in an executor. Only the path representation differs: host
callers need native `Path` inputs and `AbsolutePathBuf` outputs, while
executor callers need `PathUri` throughout.

Maintaining separate parsing or resolver implementations would duplicate
the manifest rules and allow them to drift. This PR instead makes
URI-native resolution the single parsing path and keeps host conversion
at the boundary.

## What changed

- Make `parse_plugin_manifest_uri` the shared manifest parser and
resolve every path-bearing field as `PathUri`.
- Keep the existing host entrypoint as a thin adapter: convert its
native root and manifest path to `PathUri`, run the shared parser, then
map resources back to `AbsolutePathBuf`.
- Expose `PluginManifest::try_map_resources` so callers can convert the
generic resource type without duplicating manifest construction.
- Resolve relative manifest paths using the root URI's convention:
backslashes are separators for Windows roots and ordinary filename
characters for POSIX roots.
- Apply lexical containment after URI resolution, rejecting absolute
paths and parent traversal outside the plugin root.
- Make encoded backslashes fail containment only for Windows URIs;
encoded `/` remains unsafe for every convention.
- Use a host-native synthetic root for marketplace fallback manifests so
the host adapter also works on Windows.

```text
host Path --------> PathUri --\
                              +--> one manifest parser --> PluginManifest<PathUri>
executor PathUri -------------/

host result: PluginManifest<PathUri> --> PluginManifest<AbsolutePathBuf>
```

Existing host manifest behavior is preserved; #28918 is the first
executor consumer.

## Verification

- `just test -p codex-utils-path-uri`
- `just test -p codex-plugin`
- `just test -p codex-core-plugins`

## Stack

1. #29614 — add lexical `PathUri` containment.
2. **This PR** — share URI-native manifest path resolution.
3. #28918 — keep selected plugin roots and resources URI-native.
4. #29626 — load executor skills without host path conversion.
5. #29628 — resolve executor MCP working directories without host path
conversion.
2026-06-23 20:33:59 +00:00
Adam Perry @ OpenAI
510bce9927 core: resolve view_image paths in selected environment (#29526)
## Why

view_image needs to support foreign OS remote executors.

## What

- resolve image paths against the selected environment as `PathUri` and
read them through that environment's filesystem
- keep app-server's public path field wire-compatible as
`LegacyAppPathString`, with purpose-specific UI rendering
- cover relative and absolute target-native paths in the core
integration test and run the full `view_image` suite under wine-exec
without skips
2026-06-23 19:52:37 +00:00
Dylan Hurd
2cf2a6a844 chore(core) rm AskForApproval::OnFailure (#28418)
## Summary
Deletes the OnFailure variant of the `AskForApproval` enum. This option
has been deprecated since #11631.

## Testing
- [x] Tests pass
2026-06-23 12:13:54 -07:00
jif
4147824509 path-uri: add lexical containment (#29614)
## Why

Executor-owned paths must stay portable while the orchestrator reasons
about them. Converting a Windows or remote path to the orchestrator
host's native path just to check containment breaks that boundary.

## What changed

- Add lexical containment to `PathUri`.
- Compare URI authorities and complete path segments, so `plugin-other`
is not treated as a child of `plugin`.
- Fail closed for encoded path separators and opaque fallback URIs.

For example:

```text
file:///C:/plugins/foo/assets/icon.svg
  is below file:///C:/plugins/foo

file:///C:/plugins/foo2/icon.svg
  is not below file:///C:/plugins/foo
```

This is the shared foundation for keeping executor-owned plugin
resources URI-native without consulting the orchestrator filesystem.
2026-06-23 14:59:39 +01:00
Adam Perry @ OpenAI
67009bc53f mcp: accept foreign absolute cwd for remote stdio (#29493)
## Why

Remote stdio MCP servers can run in an environment whose path convention
differs from the Codex host. A Windows cwd such as
`C:\Users\openai\share` is absolute for the executor but was rejected by
a POSIX orchestrator.

Built on #29501, now merged, which only clarifies the host-native
`PathUri` constructor name.

## What changed

- Deserialize MCP cwd values as `LegacyAppPathString` so config does not
apply host path rules.
- Interpret that spelling as host-native for local launches and convert
it to `PathUri` at executor launch.
- Skip host filesystem and command resolution checks for remote stdio in
`codex doctor`.
- Add host-independent config and executor-boundary coverage using the
foreign path convention for each test platform.

## Validation

- `just test -p codex-utils-path-uri -p codex-config -p codex-mcp -p
codex-rmcp-client` (408 passed)
- `just test -p codex-cli -p codex-rmcp-client` (372 passed)
- `cargo check --workspace --tests`
- `just test` (11,311 passed; 43 unrelated environment/timing failures)
- `just fix -p codex-cli -p codex-config -p codex-core -p codex-mcp -p
codex-mcp-extension -p codex-rmcp-client -p codex-tui`
2026-06-23 01:33:51 +00:00
Adam Perry @ OpenAI
11fab432be path-uri: clarify host-native path conversion (#29501)
## Why

Downstream refactors are producing confusing code with this
functionality having a very generic name. Encoding the specific
conversion approach in the method name makes it clearer.

## What

Rename `PathUri::from_path` to `PathUri::from_host_native_path` and
update its Rust call sites.
2026-06-23 00:02:33 +00:00
Adam Perry @ OpenAI
dce673905a core: load AGENTS.md from foreign environments (#28958)
## Why

Make it possible to load AGENTS.md from remote exec-servers whose OS is
different than app-server.

## What

- keep `AGENTS.md` discovery and provenance as `PathUri`, with
root-aware parent and ancestor traversal
- expose lifecycle instruction sources as legacy app-server path strings
in events while retaining `PathUri` internally
- preserve and test mixed POSIX and Windows paths in model context and
TUI status output
- cover remote Windows loading end to end by seeding the Wine prefix
through host filesystem APIs
- fix bug in `PathUri`'s parent() implementation that would erase
Windows drive letters
2026-06-18 15:06:23 -07:00
Eric Ning
29eb434bc5 [codex] Remove hardcoded app ID filters (#28947)
## Summary

- remove the duplicated originator-specific connector ID denylists
- stop filtering connector directory/accessibility results and
live/cached Codex Apps MCP tools by hardcoded connector ID
- remove the now-unused `codex-login` dependency from
`codex-utils-plugins`
- update regression coverage so formerly blocked connector IDs are
preserved

## Why

The client-side policy was duplicated across crates, used opaque IDs
without ownership or expiry information, and could drift between app
listing and MCP tool behavior. Server-provided visibility,
authorization, plugin discoverability, accessibility, enabled-state
handling, and consequential-tool approval templates remain unchanged.

## Validation

- `just fmt`
- `just bazel-lock-update`
- `just bazel-lock-check`
- `git diff --check`
- confirmed the final diff contains no hardcoded denylist symbols

A targeted `codex-mcp` test build spent an unusually long time in local
compilation/linking. Its first attempt exposed a test-only `PartialEq`
assertion issue, which was corrected. A follow-up non-linking `cargo
check -p codex-mcp --tests` was still running when this draft was
opened; CI should provide the complete Rust validation.
2026-06-18 20:29:01 +00:00
Adam Perry @ OpenAI
0f89dd768c apply-patch: carry paths as PathUri (#28854)
## Why

Allows the model to edit files that are hosted on a different OS than
where app-server is running.

## What

* Use `PathUri` for apply_patch-internal data structures
* Limit `PathUri` -> `AbsolutePathBuf` conversion to cases where the
inferred path convention matches the host OS, allows requiring valid
paths to pass to perms check
* Adds `PathConvention::path_segments()` for iterating over path
segments regardless of OS
* Handle cross-platform relative paths in path filename parsing for
sniffing a shell
* Ensure we can apply patches in the wine e2e test
2026-06-18 19:31:19 +00:00
Matthew Zeng
c73296a0f0 [codex] Pass plugin namespace into skill loading (#28608)
## What changed

- retain the parsed plugin manifest namespace on loaded plugins
- carry that namespace through `PluginSkillRoot` and `SkillRoot`
- use the provided namespace when qualifying plugin skill names
- include the namespace in the skills cache key

## Why

Plugin loading has already parsed `plugin.json`, but skill parsing
currently walks every `SKILL.md` ancestor and probes/reads the manifest
again to reconstruct the same namespace. Passing the parsed namespace
removes those repeated filesystem calls, which are particularly costly
on remote filesystems.

Context:
https://openai.slack.com/archives/C0ARA9GF5D4/p1781639496496439?thread_ts=1781202444.891669&cid=C0ARA9GF5D4

## Impact

Plugin skill names remain unchanged. A regression test uses a
deliberately different on-disk manifest name to verify that plugin roots
use the provided parsed namespace.

## Validation

- `just test -p codex-core-skills -p codex-core-plugins -p codex-plugin
-p codex-utils-plugins` (352 passed)
- `just fix -p codex-core-skills -p codex-core-plugins -p codex-plugin
-p codex-utils-plugins`
- `just fmt`
2026-06-18 00:16:46 -07:00