Commit Graph

245 Commits

Author SHA1 Message Date
Felipe Coury
637c3227b3 Avoid executing PATH helpers before workspace trust (#42324)
## Why

Automatic startup work and `codex doctor` can run before a workspace is
trusted. A repository-controlled `PATH` must not be able to make those flows
execute workspace-provided helpers.

## What changed

- Resolve helpers used by automatic startup from trusted system installation
  directories, and give plugin-sync Git subprocesses a sanitized environment.
- Make terminal detection environment-only and have doctor inspect executable
  locations without running them. Fetch update metadata with the HTTP client
  instead of `curl`.
- Fall back conservatively when trusted terminal helpers are unavailable,
  including for tmux keyboard enhancement flags.

## Testing

Add black-box coverage with hostile workspace `PATH` entries for startup,
interactive tmux startup, support log collection, doctor, and curated plugin
sync. Add unit coverage for trusted executable resolution and bounded update
HTTP responses.

GitOrigin-RevId: 3b8995eb422b60ed53b0386951de59e8f9bfc542
2026-09-02 18:34:27 +00:00
jif
50fffd5ed3 Refresh plugin skills after out-of-process version changes (#42284)
## Why

Another process sharing `CODEX_HOME` can replace an installed plugin version
without invalidating the current process's caches. This could leave skill
listings tied to stale plugin paths and retain obsolete plugin generations.

## What changed

- Reject cached plugin loads when their roots no longer match the active
  installation, so skills are reloaded after upgrades or rollbacks.
- Keep the 32 most recently used configuration-based skill snapshots while
  allowing callers to continue using snapshots that have been evicted.

## Testing

- Cover external plugin upgrades and rollbacks through `skills/list`, including
  a subsequent warm-cache read.
- Cover cache eviction, reuse, and the lifetime of caller-held snapshots.

GitOrigin-RevId: ca00f9539c01461e3945d340bf63f8436665220b
2026-09-02 14:14:44 +00:00
willwang-openai
6b59cefcbb Support remote marketplaces in the plugin CLI (#42150)
## What changed

- Include remote catalog entries in `codex plugin list`, including their source,
  version, install policy, and authentication policy in JSON output.
- Support adding and removing remote plugins through the existing plugin CLI.
- Cache remote catalogs by scope and collection. Prefer fresh cached results, and
  refetch once when an add request misses a plugin in the cache.
- Preserve the local curated catalog when an unfiltered remote listing fails,
  while surfacing errors for explicitly selected remote marketplaces.

## Testing

- Cover remote listing, installation, removal, catalog fallback, cache refresh,
  collection isolation, and install failure behavior.

GitOrigin-RevId: 09796b2c393d102e00ba9289f784d78a2e166a54
2026-09-01 22:51:14 +00:00
willwang-openai
68c9556cdf Upgrade Git marketplaces from merged configuration (#42149)
## Why

Configured Git marketplaces may be defined outside the user config, but those definitions could not download or update their snapshots.

## What changed

- Select marketplace source, ref, and sparse-path settings from the effective merged configuration for startup synchronization and explicit upgrades.
- Preserve the initiating operation's configuration loader and overrides when reloading before activation.
- Roll back activation if the marketplace definition changed or configuration can no longer be loaded, without copying settings into the user config.

## Testing

- Cover system-defined marketplaces, CLI overrides, startup fallback after invalid user configuration, and rollback after configuration changes.

GitOrigin-RevId: 53d1eecf68a91ce2aa8430e5749d78697bfcd821
2026-09-01 22:37:26 +00:00
willwang-openai
ef76e6ac30 Centralize remote plugin mutations in PluginsManager (#42114)
## What changed

- Move remote plugin install and uninstall orchestration from the app server into shared `PluginsManager` APIs.
- Keep cache and backend mutations coordinated by the installed-plugin sync gate, and retain install outcomes long enough to protect newly materialized bundles during downstream setup.
- Return structured operation errors and outcomes so callers can preserve JSON-RPC error mapping, telemetry, cache refreshes, and OAuth setup.

## Testing

- Add regression coverage that verifies uninstall holds the mutation gate, preserves the local cache when the backend operation fails, and refreshes installed state after a successful uninstall.

GitOrigin-RevId: de39f19a4e61c6e9c76ddc2c65d2ac130a4b7f88
2026-09-01 18:35:00 +00:00
teddywyly-oai
c7c824dce4 Treat bundled cleanup hooks as built-ins (#42110)
## What changed

- Centralize the allowlist for bundled MCP cleanup hooks and use it for both local and executor-discovered plugins, including `unified-computer-use` cleanup through `cua_repl`.
- Mark matching cleanup hooks as trusted built-ins so they run without saved hook trust and remain active when regular hooks or their per-hook state are disabled. Plugin enablement and managed-only policy still apply.
- Hide built-in cleanup hooks from hook listings and lifecycle notifications while retaining their metrics. Keep the built-in classification out of serialized protocol data.

## Testing

- Cover allowlist boundaries, trust and enablement behavior, inline and file-based hook declarations, MCP success and error responses, hook listing, lifecycle notifications, metrics, and protocol serialization.

GitOrigin-RevId: f93b7bc99f4ed9694f529def8ec383b45f31430e
2026-09-01 18:02:27 +00:00
Jiwon Kim
b6ab99ed87 Prefer remote Sites over the bundled plugin (#42100)
## Why

When the remote Sites plugin is installed and its local bundle is available, exposing the bundled copy as well creates duplicate catalog entries and can load the wrong skills.

## What changed

- Persist an account- and backend-scoped exclusion for `sites@openai-bundled` once the remote replacement is installed and loadable.
- Apply the exclusion to plugin catalogs, search, direct reads and installs, runtime loading, hooks, and skill caches while preserving the remote plugin's server-owned enabled state.
- Restore the bundled fallback when the remote plugin is absent or its local files are unavailable, and throttle repeated availability checks for 60 seconds.

## Testing

- Added manager tests for persistence across restarts, account/backend isolation, fallback restoration, concurrent checks, and refresh throttling.
- Added app-server and agent-turn tests confirming that catalog, search, and skill loading prefer remote Sites.

GitOrigin-RevId: bc1154f79d3107910fee9fa27389a0ddb48ce6cf
2026-09-01 16:58:54 +00:00
willwang-openai
633ab199cf Enforce marketplace source policy for curated plugins (#41953)
## Why

Marketplace source restrictions should cover curated plugins backed by the OpenAI plugins repository, not only user-configured marketplaces.

## What changed

- Validate both local curated catalogs against the existing OpenAI plugins Git source allowlist.
- Apply that policy to catalog discovery, installation, cached plugin and skill loading, and startup repository sync.
- Keep bundled and remote installed plugins independent of the curated Git source policy.

## Testing

Added coverage for exact and shorthand Git allowlist entries, host patterns, blocked and invalid rules, curated catalog variants, plugin skills, startup sync, and remote installed plugins.

GitOrigin-RevId: 04617acb4a93040c70a13759eb4ce872877ba211
2026-09-01 01:37:15 +00:00
Samuel Yuan
2181224dad Support app targets in executor plugin hooks (#41456)
## What changed

- Admit the curated remote Browser plugin's `Stop` and `SubagentStop` hooks when its listed `browser.turn_ended` tool matches the expected connector and is enabled by app policy.
- Carry trusted app routing metadata and the MCP environment through hook registration and execution.
- Register hooks from multiple executor environments, while deduplicating cleanup calls that share an event, MCP environment, server, and tool.

## Testing

- Cover Browser and Computer Use cleanup through separate MCP routes, including user- and managed-policy disablement.
- Verify routing metadata, environment selection, multi-environment registration, and target deduplication.

GitOrigin-RevId: 66de088fd201b9ed0db8b97c23d33de88135120d
2026-08-29 03:14:35 +00:00
Krish Chainani
c6bf330b42 Allow bundled browser cleanup hooks on subagent stop (#41435)
## What changed

Allow bundled browser and computer-use plugins to invoke the existing
`node_repl.turn_ended` cleanup hook for `SubagentStop` events, matching the
allowlist behavior for `Stop` and `Interrupt` events.

GitOrigin-RevId: 0fe1784321e793e9861e728b40a48662625b7dca
2026-08-28 23:19:01 +00:00
Krish Chainani
c2abf869d5 Run executor hooks for interrupted turns (#41432)
## Why

Executor-scoped cleanup hooks need to observe an interrupted turn as well as a
normally completed one.

## What changed

- Allow bundled executor plugins to register the allowlisted `Interrupt` hook
  alongside `Stop`, while preserving multiple allowed hook entries from the
  selected executor environment.
- Run interrupt hooks with the interrupted turn's last step discovery and turn
  metadata. Turns without a step context do not reuse discovery from an earlier
  turn.
- Keep executor-scoped interrupt hooks asynchronous and omit public hook
  lifecycle events for them, matching executor `Stop` hook behavior.

## Testing

Added coverage for hook filtering and registration, interrupt execution and
metadata propagation, environment selection, and turns without a step context.

GitOrigin-RevId: f0c536b3382a37cf3bf693c4573d21f6f66ace4e
2026-08-28 23:03:05 +00:00
pakrym-oai
f742dabc6f Support per-tool MCP output limits (#41421)
## What changed

- Add a positive `output_token_limit` setting to each entry under an MCP server's `tools` configuration.
- Apply the most restrictive limit when plugin and user policies overlap, while keeping approval policy independent.
- Carry the effective MCP output budget in conversation history so tool output, post-tool hook responses, and resumed sessions use the same truncation limit.

## Testing

- Cover configuration parsing, serialization, schema validation, and plugin policy merging.
- Cover MCP output below and above the configured limit, post-tool hook responses, and session resume.

GitOrigin-RevId: d0beb4fca9ba6055d9e1d31c137373b465d50d61
2026-08-28 21:40:23 +00:00
Matthew Zeng
bb998aeb8e Refresh runtimes for remote plugin state changes (#41396)
## Why

Enabling, disabling, or reinstalling a cached remote plugin can change its
effective MCP servers, hooks, and skills without materializing a new bundle.
These transitions need to invalidate plugin consumers just like bundle updates
and removals do.

## What changed

- Report a unified set of changed remote plugins and their affected
  capabilities for materializations, removals, and installed-state changes.
- Derive enablement and reinstall changes by comparing installed snapshots,
  while keeping materialization metadata separate for hook trust handling.
- Preserve removal notifications even when stale cache cleanup fails, and use
  all reported changes to refresh loaded plugin state and runtime consumers.

## Testing

Added coverage for cached plugin enablement, disablement, removal, and
reinstallation, including removal when cache cleanup cannot complete.

GitOrigin-RevId: 86d9c1356f7cf70b3c85effebc3e5986b931bdba
2026-08-28 19:12:34 +00:00
Matthew Zeng
8bcac28f93 Preload plugin recommendations during session startup (#41375)
## Why

Fetching plugin recommendations while building the first-turn context delays that
context when the recommendation catalog is not already cached.

## What changed

- Start fetching recommendations during session initialization, in parallel with
  MCP and plugin setup, and reuse the in-flight request when building context.
- Centralize the feature checks that enable plugin recommendations.
- Prevent an invalidated recommendation request from repopulating the cache after
  a newer request has completed.

## Testing

Added coverage for startup feature gating, reuse of the in-flight fetch, legacy
behavior when recommendations are unavailable, and cache invalidation races.

GitOrigin-RevId: 708774b9bfc472c9847973ae8b2774b66e7321e4
2026-08-28 17:33:10 +00:00
willwang-openai
91c66024c7 Instrument the loaded plugin cache (#41231)
## What changed

- Count loaded-plugin cache requests by `hit`, `hit_after_wait`, or `load` outcome.
- Record time spent waiting for the load semaphore and loading plugins.
- Count cache clears and capacity evictions.
- Remove the unused force-reload path from `PluginsManager::plugins_for_config`.

GitOrigin-RevId: db7829e7bd9b1414a263d9a7100c05dfdd832777
2026-08-28 00:17:08 +00:00
willwang-openai
e9a6d731b7 Apply app routing policy to unauthenticated plugin reads (#41230)
## What changed

Apply the legacy plugin app/MCP routing policy even when no authentication mode is available. Unauthenticated plugin reads now omit unavailable app declarations while retaining their MCP server alternatives.

## Testing

Extend plugin manager coverage for unauthenticated reads and provide ChatGPT authentication in the app-server bundle-details test.

GitOrigin-RevId: d90d29d0702488eb7413c6779254a9e6aae615c0
2026-08-28 00:07:32 +00:00
willwang-openai
c4c51c56e4 Honor per-repository plugin configuration in catalog requests (#41208)
## What changed

- Load the effective plugin configuration for every requested `cwd` in
  `plugin/list` and `plugin/installed`.
- Combine local marketplaces in request order, keeping the first source for
  duplicates while merging installed and enabled state across repositories.
- Report invalid project configurations through `marketplaceLoadErrors` without
  dropping valid local catalogs or globally enabled remote catalogs.
- Use the combined marketplace context for forced and background cache refreshes,
  while keeping remote plugin feature gating request-wide.

## Testing

- Cover distinct and duplicate marketplaces, cross-repository enabled state,
  invalid project configuration, local cache refresh, and global versus
  project-local feature flags.

GitOrigin-RevId: 53c8e0e9c760dc2b969ab10d0e63fb439673c230
2026-08-27 21:10:10 +00:00
Matthew Zeng
56239d7a61 Report affected capabilities from remote plugin syncs (#41193)
## Why

Remote plugin sync results need to identify which runtime categories may require
invalidation when a cached bundle changes.

## What changed

- Add `RemotePluginCapabilities` hints for MCP servers, Apps, hooks, and skills.
- Attach capability hints to materialized and removed plugins. Updates union the
  declarations from the old and new bundles, while removals inspect the active
  bundle before deleting its cache.
- Discover declarations without applying runtime policy or creating runtime
  data directories.

## Testing

- Cover Agent Plugin capability discovery with an unavailable runtime data
  directory.
- Cover capability accumulation across bundle versions and removal reporting.

GitOrigin-RevId: 338075d22d86f30f52be5785a2d87c77b33609c6
2026-08-27 19:54:40 +00:00
Krish Chainani
0340e12f5d Allow bundled browser plugins to run executor cleanup hooks (#40993)
## Why

Executor plugin manifests are unsigned, so cleanup hooks must remain limited to
explicitly trusted plugin identities and MCP targets.

## What changed

- Allow the bundled Browser, Chrome, Chrome Dev, and Chrome Internal plugins to
  run the existing `Stop` hook for `node_repl.turn_ended`.
- Continue allowing the bundled Computer Use plugin and rejecting unlisted or
  lookalike marketplace identities.

## Testing

- Extend manifest-filtering coverage for unlisted bundled plugins and marketplace
  name variants.

GitOrigin-RevId: 1ad5d679a1530994df5a9628c2117ce509fec9ad
2026-08-26 22:58:54 +00:00
willwang-openai
6ac012a0d4 Honor layered configuration when loading plugins (#40954)
## What changed

- Resolve plugin activation, MCP server policy, and marketplace definitions from the effective configuration stack, including system settings and trusted project overrides.
- Load plugin skills independently for each working directory passed to `skills/list`.
- Exclude project configuration from catalog requests whose `cwds` are omitted or empty.
- Cache up to eight loaded plugin configurations with least-recently-used eviction so requests for different working directories can reuse their results.

## Testing

- Cover layered plugin and MCP policy across trusted and untrusted projects.
- Cover per-directory skill and plugin catalog results, cache reuse and eviction, and system-defined marketplaces.

GitOrigin-RevId: cb68b2b1bdab1da48e05ca7562bc05014431fc71
2026-08-26 19:02:02 +00:00
stevenlee-oai
9be8d6e1c3 Harden MCP OAuth callback handling (#40691)
## Why

MCP servers can share an OAuth callback URL. Without a validated issuer or a
server-specific callback path, an authorization response could be associated
with the wrong server.

## What changed

- Use stable callbacks when authorization metadata advertises issuer-bound
  responses, and validate the returned issuer before exchanging the code.
- Retain server-specific callback IDs for providers without issuer support,
  including fallback to the global or default callback for legacy registered
  clients.
- Persist registered callback URLs for MCP servers and plugins, and insert the
  active listener port into portless loopback redirects.

## Testing

Add coverage for issuer validation, callback-mode discovery, registered and
legacy clients, plugin OAuth, CLI persistence, and loopback listener ports.

GitOrigin-RevId: 2878c92e237fc17fd3def0bd2e1cce3e104a3db8
2026-08-25 20:26:23 +00:00
willwang-openai
a6e63f9f32 Respect config layers when removing plugin marketplaces (#40683)
## Why

Removing a base-user marketplace must not delete a snapshot that is still
referenced by another enabled configuration layer.

## What changed

- Load the current configuration stack for marketplace commands in the CLI and
  app server.
- Reject removal when a matching marketplace is defined by another enabled
  layer, and identify the configuration source that must be updated instead.
- Allow cleanup of an installed marketplace snapshot even when no base-user
  entry exists.

## Testing

Cover project, enterprise-managed, system, and session-flag configurations, as
well as snapshot-only removal through the CLI and app server.

GitOrigin-RevId: 4f0853a40c2b5fae0410696b79eee4284239c7a9
2026-08-25 19:38:39 +00:00
alexsong-oai
4f6d43c267 Support managed AWS access keys for Amazon Bedrock (#40481)
## What changed

- Add the experimental `amazonBedrockAccessKeys` app-server login flow, persist its credentials in the configured auth store, and use them for SigV4-signed Bedrock requests.
- Report `bedrockAccessKeys` as a distinct auth mode and document access-key login alongside AWS profile and environment credential setup.
- Clear the selected Bedrock provider, AWS settings, and Bedrock-specific model on logout while leaving external AWS credentials and `.env` untouched.
- Reject managed access-key login when higher-precedence configuration would prevent its region or profile settings from taking effect.

## Testing

- Cover access-key login, storage, request signing, configuration conflicts, status reporting, and logout cleanup.

GitOrigin-RevId: bbf297887c6503d3651ceb2aad85c4d626e32723
2026-08-24 21:39:48 +00:00
jif
cd25b81c65 Strengthen Agent Plugin MCP environment overlay tests (#40410)
## What changed

- Cover forwarding a legacy `env_vars` entry when the portable MCP server has no `env` map.
- Use the test workspace variable instead of `PATH` in the stdio round-trip test, keeping overlay forwarding distinct from portable environment expansion.

GitOrigin-RevId: c5cfb333e553581fc856d43a04e5be0abd9f65ef
2026-08-24 14:37:48 +00:00
jif
40b7560169 Forward local env vars to Agent Plugin MCP servers (#40363)
## What changed

- Apply local `env_vars` declarations from `.codex-plugin/plugin.json` to matching stdio servers loaded from an Agent Plugin manifest.
- Replace matching `${NAME}` entries in the portable server environment with host environment forwarding while preserving the portable command, arguments, and unrelated servers.
- Ignore remote-sourced environment variables and support both inline and file-based Codex MCP declarations.

## Testing

- Cover matching-server filtering, local and remote sources, inline declarations, and an end-to-end `PATH` forwarding round trip.

GitOrigin-RevId: 843e1232a084fa5f571fe56e07266995b87fd53d
2026-08-24 08:43:25 +00:00
Matthew Zeng
e6a3877e95 Harden remote installed plugin cache reconciliation (#40015)
## What changed

- Scope remote installed-plugin and loaded-plugin snapshots to the active account, and discard in-flight loads when the account changes.
- Serialize bundle reconciliation with direct installs and uninstalls, and use cache generations to prevent stale refreshes from overwriting newer state.
- Validate the complete installed-plugin snapshot before downloading bundles or removing stale cache entries, while retaining valid installed metadata when materialization fails.

## Testing

- Cover account changes during plugin loading, incomplete snapshots, refresh/reconciliation races, and reconciliation cancellation recovery.

GitOrigin-RevId: 694c25577b420b93dacc6c65e3c0ecb7b8cc64c3
2026-08-21 21:28:16 +00:00
Krish Chainani
8b61c50ebe Run allowlisted executor plugin stop hooks (#40009)
## What changed

- Discover inline hooks from executor-provided plugin manifests and accept only
  the bundled Computer Use `Stop` hook for `node_repl.turn_ended`.
- Add the accepted hook to the current step's hook engine with
  executor-scoped provenance.
- Run executor-scoped hooks in the background after regular stop-hook
  decisions, without delaying turn completion, applying control effects, or
  exposing them in hook summaries. Skip them when regular hooks only block
  continuation.

## Testing

- Added coverage for manifest filtering and option preservation.
- Added coverage for background execution, interaction with regular stop
  hooks, and non-blocking turn completion.

GitOrigin-RevId: c0f75f83a23ba8a83bb3a5d5997c4882aacc32d6
2026-08-21 21:01:59 +00:00
cgst-oai
a26d50852a Require filesystem backends to implement directory walks (#39749)
## What changed

- Make `ExecutorFileSystem::walk` a required backend operation instead of
  providing a fallback built from directory reads and metadata requests.
- Implement bounded local walks on a blocking task with cancellation, symlink
  cycle detection, deterministic ordering, error collection, and response-size
  limits.
- Have remote filesystems use the server's walk operation directly.

## Testing

- Cover local and remote handling of invalid roots and limits, directory
  symlinks, non-UTF-8 names, cancellation, sandbox contexts, and response
  budgets.

GitOrigin-RevId: 7499bf05080c3f9965a5eb7ffd593de604d62c2a
2026-08-20 17:16:52 +00:00
rhan-oai
8c828b18d6 Remove private executor directory creation (#39736)
## What changed

- Create remote plugin metrics directories through the standard executor filesystem API.
- Remove the `private` directory-creation protocol option and its platform-specific handling.
- Update the executor temporary-directory documentation to describe child-visible sidecars without an owner-private guarantee.

GitOrigin-RevId: 9a8532403a3ad2bf998281735be0b668893918c9
2026-08-20 16:22:45 +00:00
pakrym-oai
e3e5ad2847 Harden unsandboxed patch filesystem access (#39659)
## Why

An `apply_patch` path can be replaced with a symlink after verification, allowing an unsandboxed patch operation to reach a different file than the one that was approved.

## What changed

- Add `follow_symlinks` options to executor filesystem reads, writes, metadata lookups, directory creation, and removal, including the corresponding `followSymlinks` protocol fields.
- Implement no-follow filesystem operations on Unix and Windows that reject links in any path component and restrict file access to regular files.
- Run `apply_patch` with symlink traversal disabled when an otherwise-required sandbox is bypassed, while retaining the existing follow-symlink default for standalone callers.

## Testing

- Cover leaf and ancestor symlinks across patch add, update, delete, and move operations, including a path swap after verification.
- Exercise local and remote no-follow filesystem behavior, concurrent directory creation, special-file rejection, and Windows reparse points.

GitOrigin-RevId: 43fd479084891493ce13564fbd894b98f329c6dd
2026-08-20 08:10:08 +00:00
willwang-openai
8f4a48a6ad Keep marketplace upgrade state out of config (#39595)
## What changed

- Stop writing `last_updated` and `last_revision` to marketplace entries in
  `config.toml`; keep the activated revision in
  `.codex-marketplace-install.json` instead.
- Use installed marketplace metadata to detect up-to-date checkouts.
- Snapshot the installed marketplace before activation and roll back a stale
  upgrade if another installation changed the destination concurrently.

## Testing

- Verify marketplace add and upgrade operations leave `config.toml` unchanged.
- Cover restoring a newer concurrently installed marketplace when a stale
  activation is rejected.

GitOrigin-RevId: 10942c3fc7c6c3f68b7d5953e8c1b5e86bf71866
2026-08-20 05:24:56 +00:00
xli-oai
e7c0e8eb9f Harden plugin manifest handling during installation (#39590)
## Why

Plugin installation skips symlinks while copying a plugin into the cache. A
symlinked manifest could therefore be used during source validation but omitted
from the staged copy, allowing a lower-precedence manifest to take its place.

## What changed

- Require discoverable manifests and their parent directories to be regular
  files and directories, rejecting symlinks and other non-regular entries at a
  higher-precedence manifest path.
- Verify that staging preserves the selected manifest path and contents before
  activating the cached plugin.
- Preserve generated fallback manifests by injecting and validating them in the
  staged plugin.

## Testing

Add coverage for symlinked manifest files and directories, precedence changes,
and fallback-manifest staging.

GitOrigin-RevId: 1b69c1e75cdfecb8cab4070a32aa9739833a70de
2026-08-20 05:10:57 +00:00
jif
6141747444 Test plugin sync isolation from repository Git config (#39585)
## Why

The pre-trust remote lookup must not inherit Git configuration from the
repository that launched Codex, where URL rewrites can invoke custom transport
helpers during an automatic plugin sync.

## What changed

- Add a Unix regression test that runs the startup lookup from a repository
  with a local `insteadOf` rewrite to an `ext` transport and verifies that the
  helper is not executed.
- Reuse `OPENAI_PLUGINS_GIT_URL` for the lookup so the production command and
  regression fixture target the same remote.

GitOrigin-RevId: e53af4a82a4206c31bf0f4733f908dcc064a4795
2026-08-20 04:59:20 +00:00
Charlie Marsh
ffad922340 Isolate automatic plugin Git operations (#39520)
## Why

Background marketplace and plugin refreshes can otherwise inherit repository-local or command-scoped Git configuration from the project that launched Codex. That configuration can redirect remotes or invoke Git helpers during an automatic operation.

## What changed

- Run automatic marketplace upgrades, plugin cache refreshes, and curated marketplace lookups with repository-scoped Git environment variables removed and a temporary trusted repository under the Codex home.
- Carry the automatic/manual trust mode through marketplace upgrades and plugin materialization.
- Preserve the caller's Git configuration for explicit marketplace upgrades, plugin installs, and refreshes.

## Testing

- Add regression coverage for repository URL rewrites, protocol helpers, command-scoped configuration, and manual Git filters.

GitOrigin-RevId: 957f45fa3bd7ce7e1b83355f276cf65dc5e99c8e
2026-08-19 17:34:00 +00:00
Matthew Zeng
a998c7a1ce Deduplicate remote plugin bundle syncs with shared semaphores (#39240)
## What changed

- Give plugin managers for the same cache root a shared semaphore that permits
  only one background installed-plugin bundle sync at a time.
- Hold the permit for the lifetime of the spawned sync task and refresh the
  installed-plugin cache after a successful local cache change.

## Testing

- Add a test that starts bundle syncs from two plugin managers sharing a Codex
  home and verifies that only one request is made.

GitOrigin-RevId: 86c39476c3a9015b9862ab75e8f11f110b0284fc
2026-08-18 17:42:48 +00:00
Eric Traut
0acf302db5 Prevent marketplace identity spoofing (#39165)
## Why

Repository manifests and user-configured sources must not be able to claim names reserved for managed or remote marketplaces.

## What changed

- Reject reserved marketplace names from unmanaged sources during discovery, installation, configuration projection, and configured marketplace upgrades, even when source restrictions are disabled.
- Recognize managed marketplaces only at their expected paths. Preserve the required macOS and Windows path equivalences without allowing symlink aliases to inherit managed provenance.

## Testing

- Cover reserved-name rejection for plugin list and install RPCs, configured upgrades, unrestricted policy, and remote marketplace names.
- Cover symlink spoofing and Windows managed-path normalization.

GitOrigin-RevId: a610bdc382857f306dd3e244f0992de2ec279673
2026-08-18 07:56:41 +00:00
Dylan Hurd
4216123b3d Require approval for commands with dynamic shell words (#39159)
## Why

Tree-sitter can represent brace expansions, globs, and escaped text as plain
words even though the shell changes them at runtime. Treating their source text
as literal argv could let a command match a safe-command check or allow rule
that does not match what will actually execute.

## What changed

- Reject unquoted Bash and Zsh words containing expansion, glob, or escape
  syntax from literal command parsing, including heredoc command prefixes.
- Reject double-quoted escape sequences that the shell removes or interprets,
  while continuing to accept quoted metacharacters that remain literal.
- Require approval for affected commands under `UnlessTrusted`, even when a
  policy contains an allow rule for the unexpanded source text.

## Testing

Add parser and approval scenarios covering brace expansion, globs, escapes,
Zsh-specific syntax, heredocs, and quoted literals.

GitOrigin-RevId: 31f2c6062680c42ac65362e3f3eebfaaf4eb71da
2026-08-18 07:26:21 +00:00
Matthew Zeng
de7bbb0481 Hydrate recommended plugin metadata on selection (#39143)
## What changed

- Fetch recommendations from the Codex-specific `/ps/plugins/suggested/codex` endpoint and parse its compact response shape.
- Fetch the selected plugin's details before presenting an install request, using them to verify availability and populate connector metadata.
- Skip install elicitation when the selected recommendation is no longer available, and return a retryable response when its metadata cannot be verified.

## Testing

- Cover the new recommendation route and response shape.
- Cover metadata hydration for available plugins and rejection of unavailable plugins.

GitOrigin-RevId: 2b0e2d70572aae2b7cd8e458b42e9dd14be3dbaf
2026-08-18 05:42:39 +00:00
willwang-openai
fc6268ad38 Read plugin authentication state from AuthManager (#39087)
## What changed

- Give `PluginsManager` a shared `AuthManager` instead of a separately mutable authentication-mode snapshot.
- Read the current authentication mode and credentials from that shared manager for plugin discovery, startup tasks, CLI commands, MCP setup, and external-agent migration.
- Update test helpers and coverage to exercise plugin projections and curated marketplace selection as authentication changes.

GitOrigin-RevId: 600c94de5130eda2da5727e1a0b4d39083fefc56
2026-08-17 22:26:27 +00:00
jif
8ef139667f Apply user MCP policy to selected executor plugins (#39079)
## What changed

- Resolve MCP server policy directly from the effective user configuration for selected executor-plugin roots.
- Apply server enablement, tool allow/deny lists, and default and per-tool approval modes while preserving stricter plugin-declared restrictions.
- Cover policy merging and opaque selected-root IDs in the executor-plugin MCP integration tests.

GitOrigin-RevId: dce3021969ba71e642de52312449cab6277515c3
2026-08-17 20:55:04 +00:00
felixxia-oai
d24507a59b Remove skill model delegation support (#39068)
## What changed

- Stop parsing and exposing the `model` field from skill frontmatter.
- Remove the skill model delegation types and instruction generation.

GitOrigin-RevId: 01198c68c095da5062e8abec417cc3539099d9d5
2026-08-17 20:19:04 +00:00
Abhinav
e5470f1bce Refresh hook runtimes after plugin changes (#38703)
## What changed

- Rebuild hook runtimes for loaded sessions when effective plugins change or a marketplace upgrade installs new plugin content.
- Refresh plugin-related caches and MCP runtimes alongside hooks after plugin mutations.
- Preserve each loaded session's current configuration while rebuilding its hooks.

## Testing

- Cover direct plugin upgrades, including subsequent turn and session-end hooks.
- Cover automatic marketplace upgrades for an already loaded session.

GitOrigin-RevId: fef64c68d652f300c7f3d88e81c5017459aa9a18
2026-08-15 05:28:53 +00:00
felixxia-oai
3711943d11 Parse model annotations from skill frontmatter (#38467)
## What changed

- Add an optional `model` field to parsed and loaded skill metadata.
- Recognize `model: luna` while ignoring unsupported model values without
  preventing the rest of the skill metadata from loading.

## Testing

- Cover supported, absent, unsupported, and repaired frontmatter model values.

GitOrigin-RevId: 376b65555e81d29a5eae93cc4c2633aacf7cd7c8
2026-08-14 00:54:45 +00:00
willwang-openai
1da59ad257 Support per-server MCP OAuth callback ports (#38448)
## What changed

- Add `oauth.callback_port` to MCP server configuration and preserve it when
  serializing configuration edits.
- Accept `oauth.callbackPort` from plugin MCP declarations and skill dependency
  metadata.
- Prefer the server-specific callback port over `mcp_oauth_callback_port` for
  CLI login, app-server, plugin installation, executor, and skill dependency
  OAuth flows.

## Testing

- Cover configuration parsing, serialization, and fallback behavior.
- Verify plugin, executor, and skill OAuth registrations use their configured
  callback ports instead of the global port.

GitOrigin-RevId: 7f65e5e7869358307e49779f1b75e8672b607736
2026-08-13 22:42:12 +00:00
willwang-openai
f898ebcafd Route curated plugin catalogs by authentication mode (#38429)
## Why

The model provider does not reliably identify which curated plugin catalog is
available. ChatGPT authentication can be used with a custom provider, while an
unauthenticated session should use the API-compatible catalog regardless of its
provider.

## What changed

- Select the ChatGPT curated catalog only for authentication modes that use the
  Codex backend; use the API curated catalog for API-key and unauthenticated
  sessions.
- Initialize standalone plugin managers with the current authentication mode
  across CLI, app-server, MCP, and external-agent migration paths.
- Preserve authentication mode while detecting and importing migrated plugins.

## Testing

- Cover catalog and skill routing across ChatGPT, API-key, unauthenticated,
  Bedrock, and custom-provider configurations.
- Verify authenticated plugin migration uses the ChatGPT curated marketplace.

GitOrigin-RevId: 660a339ee8891c33aad961078d3a979242a6a166
2026-08-13 20:20:01 +00:00
Kyle Brown
9579479d28 Collect plugin metrics from remote executors (#38283)
## What changed

- Resolve manifest-declared metric operations against the executor filesystem for remote plugin commands.
- Create the measurement sidecar in an executor-native, owner-private temporary directory, stream its bounded output back for validation, and clean up the directory afterward.
- Extend the exec-server protocol with the executor temporary directory and atomic private-directory creation.

## Testing

- Cover remote unified-exec measurements for foreground and background commands.
- Verify private directories use owner-only permissions on Unix and fail closed on unsupported platforms.

GitOrigin-RevId: dbbd0a84717b91237fc5728e510e18994eb46dd4
2026-08-13 00:39:04 +00:00
Kyle Brown
9ca0337dbf Collect metrics from plugin shell commands (#38252)
## What changed

- Provide matching local plugin commands with a sandbox-writable temporary output file through `CODEX_PLUGIN_METRICS_OUTPUT` when analytics is enabled.
- Validate successful command output against the plugin's `analytics.yaml` declaration, including measurement names, enum dimensions, finite values, duplicate rows, and size limits, before publishing analytics events.
- Keep the output path reserved from user overrides and clean up the temporary file after execution.

## Testing

- Cover output validation, limits, cleanup, sandbox permissions, environment handling, and path replacement.
- Verify measurement collection through both classic and zsh-fork shell runtimes.

GitOrigin-RevId: 88af0f87dc2f207fcbcca6af498f5c940d79349d
2026-08-12 21:23:21 +00:00
xl-openai
379cb68444 Add dynamic HTTP header helpers for MCP servers (#38245)
## What changed

- Add `http_headers_helper` configuration for local streamable HTTP MCP servers. The configured shell command runs once per connection and returns a JSON object of headers that is cached across requests.
- Apply helper headers to MCP startup and OAuth flows while restricting them to the server origin, stopping redirects, rejecting reserved or duplicate headers, and enforcing output and execution limits.
- Reject helpers for remote or managed-disabled servers, use the local environment working directory, and redact helper commands from `codex mcp list` and `codex mcp get` output.

## Testing

- Cover configuration validation, helper lifecycle and output parsing, origin isolation, OAuth discovery and token refresh, managed requirements, environment selection, and CLI redaction.

GitOrigin-RevId: 84e0e26ce75520b0869d37c72b1678e033bd6818
2026-08-12 20:36:32 +00:00
Kyle Brown
dc8562d672 Add manifest-defined metrics for trusted plugin scripts (#38238)
## What changed

- Load version 1 `analytics.yaml` manifests from trusted plugin roots and map declared operations, measurements, and enum dimensions to exact script paths.
- Expose resolution types and bind a declared operation to the plugin identity returned by fresh command attribution.
- Reject malformed, oversized, ambiguous, or unsafe manifests without disabling normal script attribution.

## Testing

- Cover exact script resolution, measurement names shared across operations, and invalid manifests including duplicate keys, path traversal, symlink escapes, invalid identifiers, and oversized files.

GitOrigin-RevId: 1e2f221b9f2c3d7faffe578c7a8499ad4ed933ca
2026-08-12 19:09:48 +00:00
edwardysun3
44d992c14e Track artifact operations from trusted plugin markers (#38057)
## What changed

- Recognize validated create and edit marker commands from the trusted presentations, documents, spreadsheets, and PDF plugins.
- Emit a `codex_artifact_operation` analytics event plus started-count and expected-output-count metrics when a recognized marker starts through unified exec.
- Attribute remote executor commands only when their plugin cache path and script contents match a trusted local plugin, including primary-runtime plugins.

## Testing

- Cover supported marker combinations and reject mismatched plugins, paths, arguments, counts, and output formats.
- Cover local, relocated remote, and Windows-style plugin attribution, including rejection of modified remote scripts.

GitOrigin-RevId: 475cc1689aa7f371a24dec0a8bdb6f7fd5a2e922
2026-08-11 19:26:41 +00:00