Commit Graph

15774 Commits

Author SHA1 Message Date
Michael Bolin
d7e0135030 merge commit for archive created by Sapling 2026-05-14 21:14:27 -07:00
Michael Bolin
459198c2b4 tui/exec: show effective workspace roots in summaries 2026-05-14 21:14:17 -07:00
Michael Bolin
e4b24d987d app-server: use permission ids and runtime workspace roots 2026-05-14 21:14:17 -07:00
Michael Bolin
57e56fab6f merge commit for archive created by Sapling 2026-05-14 21:08:41 -07:00
Michael Bolin
b2d2a837fd tui/exec: show effective workspace roots in summaries 2026-05-14 21:08:33 -07:00
Michael Bolin
2391b44b3d app-server: use permission ids and runtime workspace roots 2026-05-14 21:08:33 -07:00
Michael Bolin
397c7ee4d8 merge commit for archive created by Sapling 2026-05-14 20:57:53 -07:00
Michael Bolin
25fb4bea5a tui/exec: show effective workspace roots in summaries 2026-05-14 20:57:42 -07:00
Michael Bolin
3d2cc251b2 app-server: use permission ids and runtime workspace roots 2026-05-14 20:57:42 -07:00
Eric Traut
d1235a0a78 Prevent Esc from dismissing or rewinding /side (#22710)
Addresses #22599

## Why
`/side` currently lets `Esc` return to the parent thread. Multiple users
reported that this collides with queued-steer UI that also advertises
`Esc`, so a timing-sensitive keypress can dismiss an ephemeral side chat
instead of sending the queued prompt.

After removing that dismissal shortcut, the same `Esc` path could fall
through to main-thread backtrack/edit-previous handling, which is not
valid for ephemeral side conversations. This keeps `/side` out of both
global `Esc` behaviors.

## What changed
- Remove `Esc` from the `/side` return shortcut matcher while keeping
the existing `Ctrl+C` and `Ctrl+D` behavior.
- Update side-conversation hints and blocked-command copy to advertise
`Ctrl+C` as the return shortcut.
- Rename the reserved `Esc` keymap label to describe backtracking only.
- Block backtrack/edit-previous handling while a side conversation is
active and report `Editing previous prompts is unavailable in side
conversations.` when that path would have fired.
- Keep composer-owned `Esc` behavior, such as Vim insert-mode escape,
routed locally.
- Refresh focused shortcut assertions and TUI snapshots for the updated
footer and new side-conversation error message.

## Verification
Manually tested `/side` use cases and `Esc`, `Ctrl+C`, `Ctrl+D`.
2026-05-14 20:51:08 -07:00
Michael Bolin
4b6dcdecc1 merge commit for archive created by Sapling 2026-05-14 20:46:37 -07:00
Michael Bolin
ea052f458d tui/exec: show effective workspace roots in summaries 2026-05-14 20:46:23 -07:00
Michael Bolin
98c9b9914b app-server: use permission ids and runtime workspace roots 2026-05-14 20:46:23 -07:00
Michael Bolin
1a80f332b2 merge commit for archive created by Sapling 2026-05-14 20:34:20 -07:00
Michael Bolin
e87d7c6e0c tui/exec: show effective workspace roots in summaries 2026-05-14 20:34:05 -07:00
Michael Bolin
7bdbbd80b1 app-server: use permission ids and runtime workspace roots 2026-05-14 20:34:05 -07:00
Michael Bolin
7dc538b407 merge commit for archive created by Sapling 2026-05-14 20:21:02 -07:00
Michael Bolin
b4e18af8be tui/exec: show effective workspace roots in summaries 2026-05-14 20:20:38 -07:00
Michael Bolin
fd1cc16bc5 app-server: use permission ids and runtime workspace roots 2026-05-14 20:20:31 -07:00
Michael Bolin
b3ecb3d9f6 Merge 4be47409e4 into sapling-pr-archive-bolinfest 2026-05-14 20:07:42 -07:00
Michael Bolin
4be47409e4 tui/exec: show effective workspace roots in summaries 2026-05-14 20:07:35 -07:00
Michael Bolin
49e6f6187a app-server: use permission ids and runtime workspace roots 2026-05-14 20:07:35 -07:00
Michael Bolin
25e75a4ed0 Merge 92b9e73f80 into sapling-pr-archive-bolinfest 2026-05-14 19:55:04 -07:00
Michael Bolin
92b9e73f80 tui/exec: show effective workspace roots in summaries 2026-05-14 19:51:29 -07:00
Michael Bolin
bc34cfa2c8 app-server: use permission ids and runtime workspace roots 2026-05-14 19:51:29 -07:00
Michael Bolin
94446fb2cd merge commit for archive created by Sapling 2026-05-14 19:44:00 -07:00
Michael Bolin
7d2eb93419 tui/exec: show effective workspace roots in summaries 2026-05-14 19:43:51 -07:00
Michael Bolin
1d605444d3 app-server: use permission ids and runtime workspace roots 2026-05-14 19:43:51 -07:00
Michael Bolin
0c6de5c438 merge commit for archive created by Sapling 2026-05-14 19:34:51 -07:00
Michael Bolin
1b90490673 tui/exec: show effective workspace roots in summaries 2026-05-14 19:34:40 -07:00
Michael Bolin
d525c4b9cd app-server: use permission ids and runtime workspace roots 2026-05-14 19:34:40 -07:00
guinness-oai
4f2918dd7f [codex] Add opaque desktop config namespace (#22584)
## Summary
- reserve an explicit opaque `desktop` namespace in `ConfigToml`
- expose `desktop` directly in the app-server v2 `config/read` response
- keep `config/value/write` and `config/batchWrite` as the only mutation
seam for paths like `desktop.someKey`
- regenerate the config/app-server schema outputs and document the new
contract

## Why
The desktop settings work wants one durable, user-editable home for
app-owned preferences in `~/.codex/config.toml`, without forcing Rust to
model every individual desktop setting key.

This PR is only the enabling Rust/app-server layer. It gives the
Electron app a first-class config namespace it can read and write
through the existing config APIs, while leaving the actual desktop
migration to the app PR.

## Behavior and design notes
- **Opaque but explicit:** `desktop` is first-class at the typed config
root, while its children remain app-owned and open-ended.
- **Strict validation still works:** arbitrary nested `desktop.*` keys
are accepted instead of being rejected as unknown config.
- **Existing config APIs stay the seam:** `config/read` returns the bag,
and dotted writes such as `desktop.someKey` continue to flow through
`config/value/write` / `config/batchWrite` rather than a bespoke RPC.
- **No new consumer behavior:** Core/TUI do not start depending on
desktop preferences. This only preserves and exposes the namespace for
callers that intentionally use it.
- **Same persistence machinery:** hand-edited `config.toml` keeps using
the existing TOML edit/write path; this PR does not introduce a second
serializer or side channel.
- **TOML-friendly values:** the namespace is intended for ordinary
JSON-shaped setting values that map cleanly into TOML: strings, numbers,
booleans, arrays, and nested object/table values. This PR does not add
special handling for TOML-only edge cases such as datetimes.

## Layering semantics
Reads keep using the ordinary effective config pipeline, so `desktop`
participates in the same layered `config/read` behavior as the rest of
`ConfigToml`. Writes still target user config through the existing
config service.

## Why this is the shape
The alternative would be teaching Rust about each desktop setting as it
is added. That would make ordinary app preferences into a cross-repo
change, which is exactly the coupling we want to avoid.

This keeps the contract small:
1. Rust owns one opaque `desktop` namespace in `config.toml`.
2. The desktop app owns the schema and meaning of individual keys inside
it.
3. The existing config APIs remain the transport and mutation surface.

That is the piece the desktop settings PR needs in order to move forward
cleanly.

## Verification
- `cargo test -p codex-config strict_config_accepts_opaque_desktop_keys`
- `cargo test -p codex-core
desktop_toml_round_trips_opaque_nested_values`
- `cargo test -p codex-core config_schema_matches_fixture`
- `cargo test -p codex-app-server-protocol`
- `cargo test -p codex-app-server --test all desktop_settings`
2026-05-15 02:34:21 +00:00
Michael Bolin
8188400e17 merge commit for archive created by Sapling 2026-05-14 19:27:57 -07:00
Michael Bolin
1925bcdb12 tui/exec: show effective workspace roots in summaries 2026-05-14 19:27:40 -07:00
Michael Bolin
923abf508c app-server: use permission ids and runtime workspace roots 2026-05-14 19:27:40 -07:00
Michael Bolin
720d8a8f7c Merge 365734c7d5 into sapling-pr-archive-bolinfest 2026-05-14 19:18:59 -07:00
Michael Bolin
365734c7d5 tui/exec: show effective workspace roots in summaries 2026-05-14 19:18:50 -07:00
Michael Bolin
cbe9413974 app-server: use permission ids and runtime workspace roots 2026-05-14 19:18:50 -07:00
Michael Bolin
e4a0b1410c merge commit for archive created by Sapling 2026-05-14 19:13:43 -07:00
Michael Bolin
2be2dbf6a5 tui/exec: show effective workspace roots in summaries 2026-05-14 19:13:21 -07:00
Michael Bolin
1a97dd8680 app-server: use permission ids and runtime workspace roots 2026-05-14 19:13:21 -07:00
Michael Bolin
5b38adb60e Merge e1395d8105 into sapling-pr-archive-bolinfest 2026-05-14 19:04:44 -07:00
Michael Bolin
e1395d8105 tui/exec: show effective workspace roots in summaries 2026-05-14 19:04:34 -07:00
Michael Bolin
298390315d app-server: use permission ids and runtime workspace roots 2026-05-14 19:04:34 -07:00
Michael Bolin
cbe7343386 merge commit for archive created by Sapling 2026-05-14 19:03:14 -07:00
Michael Bolin
c10ca6ea15 tui/exec: show effective workspace roots in summaries 2026-05-14 19:02:42 -07:00
Michael Bolin
51e493d1a4 app-server: use permission ids and runtime workspace roots 2026-05-14 19:02:42 -07:00
Eric Traut
3a23e87e20 tui: recover local state db startup failures (#22734)
## Why

#22580 made app-server startup fail when the local SQLite state database
cannot be initialized. Embedded/local TUI startup still continued on the
permissive path, which left the CLI inconsistent and could hide a real
startup problem behind unrelated UI. This brings local TUI startup onto
the same fail-closed behavior while keeping recovery humane for the two
failure modes we are seeing in practice: damaged database files and
startup stalls caused by another process holding the database write
lock.

## What changed

- Embedded TUI startup now uses `state_db::try_init(...)` and returns a
typed `LocalStateDbStartupError` that preserves the affected database
path plus the underlying failure detail.
- CLI startup handles that failure before entering the interactive TUI:
- lock-contention failures tell users to quit other Codex processes and
try again
- failures consistent with a broken local database offer a safe repair
that backs up Codex-owned SQLite files, rebuilds local database files,
and retries startup once
- declined or unsuccessful repairs print concise guidance plus technical
details
- Shared startup error plumbing lives in `tui/src/startup_error.rs`,
while CLI recovery policy and focused recovery tests live in
`cli/src/state_db_recovery.rs`.

## Verification

- `cargo test -p codex-tui
embedded_state_db_failure_is_typed_for_cli_recovery`
- `cargo test -p codex-cli state_db_recovery`
- Manually held an exclusive SQLite lock on `state_5.sqlite` and
confirmed the CLI shows lock-specific guidance without offering repair.
- Manually exercised the repair path with a deliberately invalid
`sqlite_home` and confirmed it backs up the blocking path and resumes
startup.
2026-05-14 18:51:36 -07:00
Michael Bolin
3c6d727810 permissions: resolve profile identity with constraints (#22683)
## Why

This PR is the invariant-cleanup layer that follows the workspace-roots
base merged in [#22610](https://github.com/openai/codex/pull/22610).

#22610 adds `[permissions.<id>.workspace_roots]` and keeps runtime
workspace roots separate from the raw permission profile, but its
in-memory representation is intentionally transitional: `Permissions`
still carries the selected profile identity next to a constrained
`PermissionProfile`. That makes APIs such as
`set_constrained_permission_profile_with_active_profile()` fragile
because the id and value only mean the right thing when every caller
keeps them in sync.

This PR introduces a single resolved profile state so profile identity,
`extends`, the profile value, and profile-declared workspace roots
travel together. The next PR,
[#22611](https://github.com/openai/codex/pull/22611), builds on this by
changing the app-server turn API to select permission profiles by id
plus runtime workspace roots.

## Stack Context

- #22610, now merged: adds profile-declared `workspace_roots`, runtime
workspace roots, and `:workspace_roots` materialization.
- This PR: replaces the parallel active-profile/profile-value fields
with `PermissionProfileState`.
- #22611: switches app-server turn updates toward profile ids plus
runtime workspace roots.
- #22612: updates TUI/exec summaries to show the effective workspace
roots.

Keeping this separate from #22611 is deliberate: reviewers can validate
the internal state invariant before reviewing the app-server protocol
migration.

## What Changed

- Added `ResolvedPermissionProfile::{Legacy, BuiltIn, Named}` and
`PermissionProfileState`.
- Typed built-in profile ids with `BuiltInPermissionProfileId`.
- Moved selected profile identity and profile-declared workspace roots
into the resolved state.
- Replaced `Permissions` parallel profile fields with one
`permission_profile_state`.
- Removed `set_constrained_permission_profile_with_active_profile()`
from session sync paths.
- Kept trusted session replay/`SessionConfigured` compatibility through
explicit session snapshot helpers.
- Updated session configuration, MCP initialization, app-server, exec,
TUI, and guardian call sites to consume `&PermissionProfile` directly.

## Review Guide

Start with `codex-rs/core/src/config/resolved_permission_profile.rs`; it
is the new invariant boundary. Then review
`codex-rs/core/src/config/mod.rs` to see how config loading records
active profile identity and profile workspace roots. The remaining
call-site changes are mostly mechanical fallout from
`Permissions::permission_profile()` returning `&PermissionProfile`
instead of `&Constrained<PermissionProfile>`.

## Verification

The existing config/session coverage now constructs and asserts through
`PermissionProfileState`. The workspace-root config test also asserts
that profile-declared roots are preserved in the resolved state, which
is the behavior #22611 relies on when runtime roots become mutable
through the app-server API.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/22683).
* #22612
* #22611
* __->__ #22683
2026-05-14 18:47:44 -07:00
Dylan Hurd
06bb508547 Stabilize compact rollback follow-up test (#22303)
## Summary
- add the missing response.created event to the mocked empty follow-up
response in the compact rollback test
- keep the fix scoped to the flaky mocked stream shape, without
increasing timeouts

## Recent flakes on main
- `snapshot_rollback_followup_turn_trims_context_updates` failed in
`rust-ci-full` on `main` in the Ubuntu remote test job on 2026-05-14:
https://github.com/openai/codex/actions/runs/25891434395/job/76095284830
- The same `compact_resume_fork` suite also failed recently on `main`
with `snapshot_rollback_past_compaction_replays_append_only_history`,
which has the same mocked Responses stream shape sensitivity this PR is
tightening:
https://github.com/openai/codex/actions/runs/25892437363/job/76098329098

## Verification
- env -u CODEX_SANDBOX_NETWORK_DISABLED cargo test -p codex-core --test
all snapshot_rollback_followup_turn_trims_context_updates -- --nocapture
- repeated the same focused test 3 consecutive times locally
- UV_CACHE_DIR=/private/tmp/uv-cache-codex-fmt just fmt
2026-05-14 18:43:18 -07:00