Commit Graph

15655 Commits

Author SHA1 Message Date
Michael Bolin
d3b8dc8a62 permissions: resolve profile identity with constraints 2026-05-14 12:33:05 -07:00
Michael Bolin
e8969d940d test: isolate exec review policy config test (#22512)
## Why


`thread_start_params_include_review_policy_when_review_policy_is_manual_only`
builds a `Config` with a temporary `CODEX_HOME`, but
`ConfigBuilder::default()` can still load host-managed configuration. On
local macOS machines with enterprise-managed Codex config, that host
state can leak into the test and change the resulting config, even
though CI does not have the same managed config source.

This makes the test environment-dependent: it can pass in CI while
failing locally for developers who have managed configuration installed.

## What Changed

- Updated `codex-rs/exec/src/lib_tests.rs` so the test calls
`LoaderOverrides::without_managed_config_for_tests()` through
`ConfigBuilder::loader_overrides(...)`.
- Left the rest of the test setup intact, including the temporary
`CODEX_HOME`, temporary cwd, and explicit `approvals_reviewer` harness
override.

## Verification

```shell
cargo test -p codex-exec thread_start_params_include_review_policy_when_review_policy_is_manual_only
```
2026-05-14 12:14:20 -07:00
Matthew Zeng
d8ddeb6869 Support explicit MCP OAuth client IDs (#22575)
## Why
Some MCP OAuth providers require a pre-registered public client ID and
cannot rely on dynamic client registration. Codex already supports MCP
OAuth, but it had no way to supply that client ID from config into the
PKCE flow.

## What changed
- add `oauth.client_id` under `[mcp_servers.<server>]` config, including
config editing and schema generation
- thread the configured client ID through CLI, app-server, plugin login,
and MCP skill dependency OAuth entrypoints
- configure RMCP authorization with the explicit client when present,
while preserving the existing dynamic-registration path when it is
absent
- add focused coverage for config parsing/serialization and OAuth URL
generation

## Verification
- `cargo test -p codex-config -p codex-rmcp-client -p codex-mcp -p
codex-core-plugins`
- `cargo test -p codex-core blocking_replace_mcp_servers_round_trips
--lib`
- `cargo test -p codex-core
replace_mcp_servers_streamable_http_serializes_oauth_resource --lib`
- `cargo test -p codex-core config_schema_matches_fixture --lib`

## Notes
Broader local package runs still hit unrelated pre-existing stack
overflows in:
- `codex-app-server::in_process_start_clamps_zero_channel_capacity`
-
`codex-core::resume_agent_from_rollout_uses_edge_data_when_descendant_metadata_source_is_stale`
2026-05-14 11:52:43 -07:00
Casey Chow
4a1f1df8ce [codex] fix plugin CLI active user layer compile (#22666)
## Why

PR #21396 merged after #17141 removed the old
`ConfigLayerStack::get_user_layer()` API. The new plugin CLI call sites
still used that stale API, which caused `main` to fail compilation.

## What Changed

- update `codex plugin marketplace list` to read configured marketplaces
through `get_active_user_layer()`
- update the plugin snapshot validation helper to use
`get_active_user_layer()`

This preserves the intended active writable user-layer behavior from the
profile-aware config API while fixing the stale call sites.

## Validation

- `cargo check -p codex-cli`
- `cargo test -p codex-cli --test plugin_cli`
- `git diff --check`
2026-05-14 18:41:04 +00:00
Michael Bolin
5ee2cb6e5f Merge 2a7104fdb2 into sapling-pr-archive-bolinfest 2026-05-14 11:39:55 -07:00
Michael Bolin
2a7104fdb2 tui/exec: show effective workspace roots in summaries 2026-05-14 11:39:36 -07:00
Michael Bolin
f42586d9aa app-server: use permission ids and runtime workspace roots 2026-05-14 11:39:36 -07:00
Michael Bolin
5e3f04da96 permissions: support workspace roots in profiles 2026-05-14 11:39:03 -07:00
Michael Bolin
c5d441d842 merge commit for archive created by Sapling 2026-05-14 11:28:08 -07:00
Michael Bolin
5416bbd4e8 tui/exec: show effective workspace roots in summaries 2026-05-14 11:27:48 -07:00
Michael Bolin
842662a4be app-server: use permission ids and runtime workspace roots 2026-05-14 11:27:48 -07:00
Michael Bolin
6589c9131f permissions: support workspace roots in profiles 2026-05-14 11:27:25 -07:00
Michael Bolin
9006cc3073 merge commit for archive created by Sapling 2026-05-14 11:06:44 -07:00
Michael Bolin
5cba401114 tui/exec: show effective workspace roots in summaries 2026-05-14 10:59:45 -07:00
Michael Bolin
247bbdaf05 app-server: use permission ids and runtime workspace roots 2026-05-14 10:59:10 -07:00
Michael Bolin
2fbcb8554e permissions: support workspace roots in profiles 2026-05-14 10:58:07 -07:00
Rajeev Nayak
f13e21ef43 Prefer the model list fetched from the backend for SIWC users (#22547)
## Summary
- For SIWC users, update the model list merging logic to prefer the
model list fetched from the backend over the bundled model list (this is
needed for special cases where users have a more limited set of models
they're allowed to use)
- Add or update tests covering the revised cache behavior

## Testing
- Added/updated unit tests in
`codex-rs/models-manager/src/manager_tests.rs`
- Not run (not requested)
2026-05-14 13:45:49 -04:00
Felipe Coury
5a02962519 fix(tui): render network approval history by target (#22229)
## Why

Network approval prompts are rendered without a command string on the
app-server path. After the user approves one of those prompts, the TUI
history cell previously fell back to command-oriented copy and produced
malformed lines such as:

```text
You approved codex to run  every time this session
```

That hid the network target the user actually approved and left a
visibly broken transcript entry.

## What changed

- Preserve the approval subject as either a command or a network target
when recording TUI approval decisions.
- Render target-aware history copy for network approval outcomes:
  - approve once
  - approve for the current session
  - cancel
- Include the approval protocol and preserve the managed-proxy
`network-access` target when present, including non-default ports such
as `https://example.com:8443`.
- Fall back to formatting the network approval context as
`protocol://host` when no generated target command is available.
- Keep ordinary command approval history, Guardian approval history, and
persisted network-rule history behavior unchanged.
- Add focused regression coverage and snapshots for the three
network-history cases.

## How to Test

1. Start Codex in a flow that triggers a network approval prompt.
2. Approve network access only for the current conversation.
3. Confirm the transcript records the approved network target, for
example:
- `You approved codex network access to https://example.com:8443 every
time this session`
4. Trigger the prompt again and verify the one-time approval and cancel
paths also record target-specific history text instead of an empty
command gap.

Targeted automated coverage:
- `cargo test -p codex-tui network_exec_approval_history`

## Additional verification

- `cargo insta pending-snapshots`
- `git diff --check`
- `just fix -p codex-tui`
- `just argument-comment-lint`

## Known unrelated local test noise

A full `cargo test -p codex-tui` run still hits a pre-existing stack
overflow outside this change:
- `tests::fork_last_filters_latest_session_by_cwd_unless_show_all`
aborts with a stack overflow
2026-05-14 14:33:54 -03:00
Michael Bolin
afbea8ab82 Merge 5a5197bc0e into sapling-pr-archive-bolinfest 2026-05-14 10:24:29 -07:00
Michael Bolin
5a5197bc0e tui/exec: show effective workspace roots in summaries 2026-05-14 10:24:07 -07:00
Michael Bolin
8429c8955a app-server: use permission ids and runtime workspace roots 2026-05-14 10:24:07 -07:00
Michael Bolin
9ccddb30a7 permissions: support workspace roots in profiles 2026-05-14 10:24:07 -07:00
Michael Bolin
f623d41222 Merge 4c8c508620 into sapling-pr-archive-bolinfest 2026-05-14 10:11:20 -07:00
Michael Bolin
96d85dc984 merge commit for archive created by Sapling 2026-05-14 10:11:05 -07:00
Michael Bolin
4c8c508620 tui/exec: show effective workspace roots in summaries 2026-05-14 10:10:39 -07:00
Michael Bolin
572a5c3ff7 app-server: use permission ids and runtime workspace roots 2026-05-14 10:10:39 -07:00
Michael Bolin
d9c6a91058 permissions: support workspace roots in profiles 2026-05-14 10:09:50 -07:00
Chris Bookholt
6ec8c4a6ec [codex] Ignore fsmonitor config in Git metadata reads (#22652)
## Summary
- keep Git metadata/status subprocesses independent of repository
`core.fsmonitor` configuration
- preserve existing working-tree state reporting while making the helper
behavior more predictable
- add regression coverage for `get_has_changes` when a repository
defines an fsmonitor command

## Validation
- `cargo fmt --all`
- `cargo test -p codex-core test_get_has_changes_`
- `cargo test -p codex-git-utils`
2026-05-14 10:07:43 -07:00
starr-openai
8736e32657 tests: avoid ambient temp sandbox roots (#22576)
## Why
Some sandboxed integration tests enabled both ambient temp roots
(`TMPDIR` and literal `/tmp`) even though they were not testing
temp-root behavior. On Linux bwrap, making `/tmp` writable causes
protected metadata mount targets such as `/tmp/.git`, `/tmp/.agents`,
and `/tmp/.codex` to be synthesized. If a run is interrupted, those
top-level markers can be left behind and contaminate later tests.

## What changed
For the incidental integration tests that do not need ambient temp-root
access, set `exclude_tmpdir_env_var` and `exclude_slash_tmp` to `true`.
Dedicated protected-metadata coverage remains in the lower-level sandbox
tests that use isolated temp roots.

## Verification
Focused remote devbox repros passed with a watcher polling `/tmp/.git`,
`/tmp/.agents`, and `/tmp/.codex`; no leaked markers were observed.
2026-05-14 10:04:24 -07:00
Michael Bolin
9ea1c57baa Merge f298b2d285 into sapling-pr-archive-bolinfest 2026-05-14 09:46:07 -07:00
Michael Bolin
ccf09df586 merge commit for archive created by Sapling 2026-05-14 09:45:54 -07:00
Michael Bolin
f298b2d285 tui/exec: show effective workspace roots in summaries 2026-05-14 09:45:35 -07:00
Michael Bolin
cd12cc2ab9 app-server: use permission ids and runtime workspace roots 2026-05-14 09:45:35 -07:00
Michael Bolin
1158c52e8b Merge f86711efa8 into sapling-pr-archive-bolinfest 2026-05-14 09:41:32 -07:00
Michael Bolin
c301e69150 Merge 5b6acbb6b5 into sapling-pr-archive-bolinfest 2026-05-14 09:41:15 -07:00
Michael Bolin
deac94bc66 merge commit for archive created by Sapling 2026-05-14 09:40:56 -07:00
Michael Bolin
f86711efa8 tui/exec: show effective workspace roots in summaries 2026-05-14 09:40:33 -07:00
Michael Bolin
5b6acbb6b5 app-server: use permission ids and runtime workspace roots 2026-05-14 09:40:33 -07:00
Michael Bolin
6803c35f38 permissions: support workspace roots in profiles 2026-05-14 09:40:32 -07:00
Michael Bolin
3a2406cc24 Merge a204e78e03 into sapling-pr-archive-bolinfest 2026-05-14 09:36:42 -07:00
Michael Bolin
c1cb6422e4 Merge 86bb110674 into sapling-pr-archive-bolinfest 2026-05-14 09:36:16 -07:00
Michael Bolin
a204e78e03 tui/exec: show effective workspace roots in summaries 2026-05-14 09:35:22 -07:00
Michael Bolin
86bb110674 app-server: use permission ids and runtime workspace roots 2026-05-14 09:35:22 -07:00
Michael Bolin
b1a17b6185 Merge 559afb6a59 into sapling-pr-archive-bolinfest 2026-05-14 09:34:42 -07:00
Michael Bolin
559afb6a59 permissions: support workspace roots in profiles 2026-05-14 09:34:27 -07:00
Casey Chow
74a1b46a00 [codex] add plugin marketplace CLI commands (#21396)
## Why

Plugin CLI installs should behave more like `apt-get install`:
configured marketplaces are the only install sources, the local
marketplace snapshot is the package index used at install time, and
`plugins/cache` is only a cache of already-downloaded plugin bytes.

That distinction matters once marketplaces and plugins have auth or
availability state. A repo-local marketplace manifest or leftover cached
plugin artifact should not silently become an install source unless the
marketplace was explicitly configured and its readable snapshot still
authorizes the plugin.

## What Changed

- add CLI commands to list configured marketplaces and add, list, or
remove marketplace plugins
- accept stable `plugin@marketplace` ids for add/remove while preserving
the explicit `--marketplace` form
- restrict `codex plugin add` and `codex plugin list` to configured
marketplaces instead of also discovering current-working-directory
marketplace roots
- fail `codex plugin add` and `codex plugin list` when a configured
marketplace snapshot is missing or malformed instead of treating it as
an empty source or a generic plugin miss
- preserve marketplace snapshot semantics: a configured local/Git
marketplace snapshot can authorize installs without consulting the
original upstream source
- allow `plugins/cache` reuse only after configured marketplace
resolution succeeds
- keep removal resilient after marketplace deletion or drift and ignore
malformed marketplace config entries in listing

## Commands Added

- `codex plugin add <plugin>@<marketplace>`
- `codex plugin add <plugin> --marketplace <marketplace>`
- `codex plugin list`
- `codex plugin list --marketplace <marketplace>`
- `codex plugin remove <plugin>@<marketplace>`
- `codex plugin remove <plugin> --marketplace <marketplace>`
- `codex plugin marketplace add <source>`
- `codex plugin marketplace add <source> --ref <ref>`
- `codex plugin marketplace add <source> --sparse <path>`
- `codex plugin marketplace list`
- `codex plugin marketplace upgrade`
- `codex plugin marketplace upgrade <marketplace>`
- `codex plugin marketplace remove <marketplace>`

## CLI Help Output

<details>
<summary><code>codex plugin --help</code></summary>

```text
Manage Codex plugins

Usage: codex plugin [OPTIONS] <COMMAND>

Commands:
  add          Install a plugin from a configured marketplace snapshot
  list         List plugins available from configured marketplace snapshots
  marketplace  Add, list, upgrade, or remove configured plugin marketplaces
  remove       Remove an installed plugin from local config and cache
  help         Print this message or the help of the given subcommand(s)
```

</details>

<details>
<summary><code>codex plugin add --help</code></summary>

```text
Install a plugin from a configured marketplace snapshot.

Pass either `PLUGIN@MARKETPLACE` or pass `PLUGIN` with `--marketplace MARKETPLACE`.

Usage: codex plugin add [OPTIONS] <PLUGIN[@MARKETPLACE]>

Arguments:
  <PLUGIN[@MARKETPLACE]>
          Plugin selector to install: either PLUGIN@MARKETPLACE or PLUGIN with --marketplace

Options:
  -m, --marketplace <MARKETPLACE>
          Configured marketplace name to use when PLUGIN does not include @MARKETPLACE

Examples:
  codex plugin add sample@debug
  codex plugin add sample --marketplace debug
```

</details>

<details>
<summary><code>codex plugin list --help</code></summary>

```text
List plugins available from configured marketplace snapshots

Usage: codex plugin list [OPTIONS]

Options:
  -m, --marketplace <MARKETPLACE>
          Only list plugins from this configured marketplace name

Examples:
  codex plugin list
  codex plugin list --marketplace debug
```

</details>

<details>
<summary><code>codex plugin remove --help</code></summary>

```text
Remove an installed plugin from local config and cache.

Pass either `PLUGIN@MARKETPLACE` or pass `PLUGIN` with `--marketplace MARKETPLACE`.

Usage: codex plugin remove [OPTIONS] <PLUGIN[@MARKETPLACE]>

Arguments:
  <PLUGIN[@MARKETPLACE]>
          Plugin selector to remove: either PLUGIN@MARKETPLACE or PLUGIN with --marketplace

Options:
  -m, --marketplace <MARKETPLACE>
          Marketplace name to use when PLUGIN does not include @MARKETPLACE

Examples:
  codex plugin remove sample@debug
  codex plugin remove sample --marketplace debug
```

</details>

<details>
<summary><code>codex plugin marketplace --help</code></summary>

```text
Add, list, upgrade, or remove configured plugin marketplaces

Usage: codex plugin marketplace [OPTIONS] <COMMAND>

Commands:
  add      Add a local or Git marketplace to the configured marketplace sources
  list     List configured marketplace names and their local snapshot roots
  upgrade  Refresh configured Git marketplace snapshots
  remove   Remove a configured marketplace source by name
```

</details>

<details>
<summary><code>codex plugin marketplace add --help</code></summary>

```text
Add a local or Git marketplace to the configured marketplace sources

Usage: codex plugin marketplace add [OPTIONS] <SOURCE>

Arguments:
  <SOURCE>
          Marketplace source: a local path, owner/repo[@ref], HTTPS Git URL, or SSH Git URL

Options:
      --ref <REF>
          Git ref to fetch for Git marketplace sources

      --sparse <PATH>
          Sparse checkout path for Git marketplace sources. Can be repeated

Examples:
  codex plugin marketplace add ./path/to/marketplace
  codex plugin marketplace add owner/repo --ref main
  codex plugin marketplace add https://github.com/owner/repo --sparse plugins/foo
```

</details>

<details>
<summary><code>codex plugin marketplace list --help</code></summary>

```text
List configured marketplace names and their local snapshot roots

Usage: codex plugin marketplace list [OPTIONS]
```

</details>

<details>
<summary><code>codex plugin marketplace upgrade --help</code></summary>

```text
Refresh configured Git marketplace snapshots.

Omit MARKETPLACE_NAME to upgrade all configured Git marketplaces.

Usage: codex plugin marketplace upgrade [OPTIONS] [MARKETPLACE_NAME]

Arguments:
  [MARKETPLACE_NAME]
          Optional configured marketplace name to upgrade. Omit to upgrade all Git marketplaces

Examples:
  codex plugin marketplace upgrade
  codex plugin marketplace upgrade debug
```

</details>

<details>
<summary><code>codex plugin marketplace remove --help</code></summary>

```text
Remove a configured marketplace source by name

Usage: codex plugin marketplace remove [OPTIONS] <MARKETPLACE_NAME>

Arguments:
  <MARKETPLACE_NAME>
          Configured marketplace name to remove

Example:
  codex plugin marketplace remove debug
```

</details>

## Public Semantics

- `codex plugin add <plugin>@<marketplace>` succeeds only when
`<marketplace>` is configured and its local marketplace snapshot
contains `<plugin>`
- repo-local marketplaces are not install sources until the user runs
`codex plugin marketplace add ...`
- configured marketplace snapshots must be readable; missing or
malformed snapshots fail the CLI operation rather than silently falling
through to cache or empty results
- cached plugin artifacts can satisfy reinstall only when the configured
marketplace snapshot still authorizes that plugin
- cached plugin artifacts alone never make a plugin installable

## Tests

- `cargo test -p codex-cli --test plugin_cli`
- `cargo clippy -p codex-cli --tests -- -D warnings`
- `cargo test -p codex-cli`
- `git diff --check`
- `just bazel-lock-update`
- `just bazel-lock-check`
2026-05-14 09:33:38 -07:00
Michael Bolin
dd6d5ba02e merge commit for archive created by Sapling 2026-05-14 09:09:50 -07:00
Michael Bolin
99a5efaa3c permissions: support workspace roots in profiles 2026-05-14 09:08:55 -07:00
Eric Traut
a5040d0b39 tui: split composer attachment and popup state (#22581)
## Why

`ChatComposer` currently owns text editing alongside attachment
bookkeeping and popup lifecycle state, while `BottomPane` still triggers
a couple of popup resyncs after composer methods that already do that
work internally. That blurs the ownership boundary and makes the
composer harder to simplify safely.

This PR is part 1 of a two-part cleanup. It peels off the composer state
that can move cleanly on its own, so the follow-up can tackle the
heavier draft/editing boundary without mixing every concern into one
diff.

## What changed

- Move local and remote image bookkeeping, placeholder relabeling, and
remote-image keyboard selection into `AttachmentState`.
- Move active-popup and popup-dismissal/query bookkeeping into
`PopupState`.
- Update composer and history-search paths to use those state owners
directly.
- Remove redundant `BottomPane` popup synchronization after paste
handling and `insert_str`.

## Part 2

The follow-up PR will finish the cleanup around the remaining composer
boundary: split out the draft/editing-oriented state and footer/status
presentation concerns that still live in `ChatComposer`, then revisit
the leftover `BottomPane` pass-throughs once those ownership lines are
explicit. The goal is for `ChatComposer` to coordinate a few focused
collaborators instead of continuing to be the landing zone for every
input-path concern.

## Verification

Did manual smoke tests.
2026-05-14 09:04:27 -07:00
Michael Bolin
dd27a756bb merge commit for archive created by Sapling 2026-05-14 09:00:00 -07:00