mirror of
https://github.com/pchuan98/codex.git
synced 2026-07-01 00:31:56 +08:00
fece9ce7455261bf8a158c350970984bfff581d1
248 Commits
-
tui: always restore the terminal on early exit (#15671)
## Summary Fixes early TUI exit paths that could leave the terminal in a dirty state and cause a stray `%` prompt marker after the app quit. ## Root cause Both `tui` and `tui_app_server` had early returns after `tui::init()` that did not guarantee terminal restore. When that happened, shells like `zsh` inherited the altered terminal state. ## Changes - Add a restore guard around `run_ratatui_app()` in both `tui` and `tui_app_server` - Route early exits through the guard instead of relying on scattered manual restore calls - Ensure terminal restore still happens on normal shutdown
Eric Traut ·
2026-03-24 14:29:29 -06:00 -
Initial plugins TUI menu - list and read only. tui + tui_app_server (#15215)
### Preliminary /plugins TUI menu - Adds a preliminary /plugins menu flow in both tui and tui_app_server. - Fetches plugin list data asynchronously and shows loading/error/cached states. - Limits this first pass to the curated ChatGPT marketplace. - Shows available plugins with installed/status metadata. - Supports in-menu search over plugin display name, plugin id, plugin name, and marketplace label. - Opens a plugin detail view on selection, including summaries for Skills, Apps, and MCP Servers, with back navigation. ### Testing - Launch codex-cli with plugins enabled (`--enable plugins`). - Run /plugins and verify: - loading state appears first - plugin list is shown - search filters results - selecting a plugin opens detail view, with a list of skills/connectors/MCP servers for the plugin - back action returns to the list. - Verify disabled behavior by running /plugins without plugins enabled (shows “Plugins are disabled” message). - Launch with `--enable tui_app_server` (and plugins enabled) and repeat the same /plugins flow; behavior should match.canvrno-oai ·
2026-03-19 21:28:33 -07:00 -
Use released DotSlash package for argument-comment lint (#15199)
## Why The argument-comment lint now has a packaged DotSlash artifact from [#15198](https://github.com/openai/codex/pull/15198), so the normal repo lint path should use that released payload instead of rebuilding the lint from source every time. That keeps `just clippy` and CI aligned with the shipped artifact while preserving a separate source-build path for people actively hacking on the lint crate. The current alpha package also exposed two integration wrinkles that the repo-side prebuilt wrapper needs to smooth over: - the bundled Dylint library filename includes the host triple, for example `@nightly-2025-09-18-aarch64-apple-darwin`, and Dylint derives `RUSTUP_TOOLCHAIN` from that filename - on Windows, Dylint's driver path also expects `RUSTUP_HOME` to be present in the environment Without those adjustments, the prebuilt CI jobs fail during `cargo metadata` or driver setup. This change makes the checked-in prebuilt wrapper normalize the packaged library name to the plain `nightly-2025-09-18` channel before invoking `cargo-dylint`, and it teaches both the wrapper and the packaged runner source to infer `RUSTUP_HOME` from `rustup show home` when the environment does not already provide it. After the prebuilt Windows lint job started running successfully, it also surfaced a handful of existing anonymous literal callsites in `windows-sandbox-rs`. This PR now annotates those callsites so the new cross-platform lint job is green on the current tree. ## What Changed - checked in the current `tools/argument-comment-lint/argument-comment-lint` DotSlash manifest - kept `tools/argument-comment-lint/run.sh` as the source-build wrapper for lint development - added `tools/argument-comment-lint/run-prebuilt-linter.sh` as the normal enforcement path, using the checked-in DotSlash package and bundled `cargo-dylint` - updated `just clippy` and `just argument-comment-lint` to use the prebuilt wrapper - split `.github/workflows/rust-ci.yml` so source-package checks live in a dedicated `argument_comment_lint_package` job, while the released lint runs in an `argument_comment_lint_prebuilt` matrix on Linux, macOS, and Windows - kept the pinned `nightly-2025-09-18` toolchain install in the prebuilt CI matrix, since the prebuilt package still relies on rustup-provided toolchain components - updated `tools/argument-comment-lint/run-prebuilt-linter.sh` to normalize host-qualified nightly library filenames, keep the `rustup` shim directory ahead of direct toolchain `cargo` binaries, and export `RUSTUP_HOME` when needed for Windows Dylint driver setup - updated `tools/argument-comment-lint/src/bin/argument-comment-lint.rs` so future published DotSlash artifacts apply the same nightly-filename normalization and `RUSTUP_HOME` inference internally - fixed the remaining Windows lint violations in `codex-rs/windows-sandbox-rs` by adding the required `/*param*/` comments at the reported callsites - documented the checked-in DotSlash file, wrapper split, archive layout, nightly prerequisite, and Windows `RUSTUP_HOME` requirement in `tools/argument-comment-lint/README.md`
Michael Bolin ·
2026-03-20 03:19:22 +00:00 -
Split features into codex-features crate (#15253)
- Split the feature system into a new `codex-features` crate. - Cut `codex-core` and workspace consumers over to the new config and warning APIs. Co-authored-by: Ahmed Ibrahim <219906144+aibrahim-oai@users.noreply.github.com> Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-19 20:12:07 -07:00 -
Move auth code into login crate (#15150)
- Move the auth implementation and token data into codex-login. - Keep codex-core re-exporting that surface from codex-login for existing callers. --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-19 18:58:17 -07:00 -
Move terminal module to terminal-detection crate (#15216)
- Move core/src/terminal.rs and its tests into a standalone terminal-detection workspace crate. - Update direct consumers to depend on codex-terminal-detection and import terminal APIs directly. --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-19 14:08:04 -07:00 -
feat(tui): add /title terminal title configuration (#12334)
## Problem When multiple Codex sessions are open at once, terminal tabs and windows are hard to distinguish from each other. The existing status line only helps once the TUI is already focused, so it does not solve the "which tab is this?" problem. This PR adds a first-class `/title` command so the terminal window or tab title can carry a short, configurable summary of the current session. ## Screenshot <img width="849" height="320" alt="image" src="https://github.com/user-attachments/assets/8b112927-7890-45ed-bb1e-adf2f584663d" /> ## Mental model `/statusline` and `/title` are separate status surfaces with different constraints. The status line is an in-app footer that can be denser and more detailed. The terminal title is external terminal metadata, so it needs short, stable segments that still make multiple sessions easy to tell apart. The `/title` configuration is an ordered list of compact items. By default it renders `spinner,project`, so active sessions show lightweight progress first while idle sessions still stay easy to disambiguate. Each configured item is omitted when its value is not currently available rather than forcing a placeholder. ## Non-goals This does not merge `/title` into `/statusline`, and it does not add an arbitrary free-form title string. The feature is intentionally limited to a small set of structured items so the title stays short and reviewable. This also does not attempt to restore whatever title the terminal or shell had before Codex started. When Codex clears the title, it clears the title Codex last wrote. ## Tradeoffs A separate `/title` command adds some conceptual overlap with `/statusline`, but it keeps title-specific constraints explicit instead of forcing the status line model to cover two different surfaces. Title refresh can happen frequently, so the implementation now shares parsing and git-branch orchestration between the status line and title paths, and caches the derived project-root name by cwd. That keeps the hot path cheap without introducing background polling. ## Architecture The TUI gets a new `/title` slash command and a dedicated picker UI for selecting and ordering terminal-title items. The chosen ids are persisted in `tui.terminal_title`, with `spinner` and `project` as the default when the config is unset. `status` remains available as a separate text item, so configurations like `spinner,status` render compact progress like `⠋ Working`. `ChatWidget` now refreshes both status surfaces through a shared `refresh_status_surfaces()` path. That shared path parses configured items once, warns on invalid ids once, synchronizes shared cached state such as git-branch lookup, then renders the footer status line and terminal title from the same snapshot. Low-level OSC title writes live in `codex-rs/tui/src/terminal_title.rs`, which owns the terminal write path and last-mile sanitization before emitting OSC 0. ## Security Terminal-title text is treated as untrusted display content before Codex emits it. The write path strips control characters, removes invisible and bidi formatting characters that can make the title visually misleading, normalizes whitespace, and caps the emitted length. References used while implementing this: - [xterm control sequences](https://invisible-island.net/xterm/ctlseqs/ctlseqs.html) - [WezTerm escape sequences](https://wezterm.org/escape-sequences.html) - [CWE-150: Improper Neutralization of Escape, Meta, or Control Sequences](https://cwe.mitre.org/data/definitions/150.html) - [CERT VU#999008 (Trojan Source)](https://kb.cert.org/vuls/id/999008) - [Trojan Source disclosure site](https://trojansource.codes/) - [Unicode Bidirectional Algorithm (UAX #9)](https://www.unicode.org/reports/tr9/) - [Unicode Security Considerations (UTR #36)](https://www.unicode.org/reports/tr36/) ## Observability Unknown configured title item ids are warned about once instead of repeatedly spamming the transcript. Live preview applies immediately while the `/title` picker is open, and cancel rolls the in-memory title selection back to the pre-picker value. If terminal title writes fail, the TUI emits debug logs around set and clear attempts. The rendered status label intentionally collapses richer internal states into compact title text such as `Starting...`, `Ready`, `Thinking...`, `Working...`, `Waiting...`, and `Undoing...` when `status` is configured. ## Tests Ran: - `just fmt` - `cargo test -p codex-tui` At the moment, the red Windows `rust-ci` failures are due to existing `codex-core` `apply_patch_cli` stack-overflow tests that also reproduce on `main`. The `/title`-specific `codex-tui` suite is green.
Yaroslav Volovich ·
2026-03-19 19:26:36 +00:00 -
feat: support product-scoped plugins. (#15041)
1. Added SessionSource::Custom(String) and --session-source. 2. Enforced plugin and skill products by session_source. 3. Applied the same filtering to curated background refresh.
xl-openai ·
2026-03-19 00:46:15 -07:00 -
Handle realtime conversation end in the TUI (#14903)
- close live realtime sessions on errors, ctrl-c, and active meter removal - centralize TUI realtime cleanup and avoid duplicate follow-up close info --------- Co-authored-by: Codex <noreply@openai.com> Co-authored-by: Ahmed Ibrahim <219906144+aibrahim-oai@users.noreply.github.com>
Ahmed Ibrahim ·
2026-03-17 21:04:58 -07:00 -
Gate realtime audio interruption logic to v2 (#14984)
- thread the realtime version into conversation start and app-server notifications - keep playback-aware mic gating and playback interruption behavior on v2 only, leaving v1 on the legacy path
Ahmed Ibrahim ·
2026-03-17 15:24:37 -07:00 -
Revert tui code so it does not rely on in-process app server (#14899)
PR https://github.com/openai/codex/pull/14512 added an in-process app server and started to wire up the tui to use it. We were originally planning to modify the `tui` code in place, converting it to use the app server a bit at a time using a hybrid adapter. We've since decided to create an entirely new parallel `tui_app_server` implementation and do the conversion all at once but retain the existing `tui` while we work the bugs out of the new implementation. This PR undoes the changes to the `tui` made in the PR #14512 and restores the old initialization to its previous state. This allows us to modify the `tui_app_server` without the risk of regressing the old `tui` code. For example, we can start to remove support for all legacy core events, like the ones that PR https://github.com/openai/codex/pull/14892 needed to ignore. Testing: * I manually verified that the old `tui` starts and shuts down without a problem.
Eric Traut ·
2026-03-17 00:56:32 -06:00 -
[stack 4/4] Reduce realtime self-interruptions during playback (#14827)
## Stack Position 4/4. Top-of-stack sibling built on #14830. ## Base - #14830 ## Sibling - #14829 ## Scope - Gate low-level mic chunks while speaker playback is active, while still allowing spoken barge-in. --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-03-17 05:19:51 +00:00 -
Apply argument comment lint across codex-rs (#14652)
## Why Once the repo-local lint exists, `codex-rs` needs to follow the checked-in convention and CI needs to keep it from drifting. This commit applies the fallback `/*param*/` style consistently across existing positional literal call sites without changing those APIs. The longer-term preference is still to avoid APIs that require comments by choosing clearer parameter types and call shapes. This PR is intentionally the mechanical follow-through for the places where the existing signatures stay in place. After rebasing onto newer `main`, the rollout also had to cover newly introduced `tui_app_server` call sites. That made it clear the first cut of the CI job was too expensive for the common path: it was spending almost as much time installing `cargo-dylint` and re-testing the lint crate as a representative test job spends running product tests. The CI update keeps the full workspace enforcement but trims that extra overhead from ordinary `codex-rs` PRs. ## What changed - keep a dedicated `argument_comment_lint` job in `rust-ci` - mechanically annotate remaining opaque positional literals across `codex-rs` with exact `/*param*/` comments, including the rebased `tui_app_server` call sites that now fall under the lint - keep the checked-in style aligned with the lint policy by using `/*param*/` and leaving string and char literals uncommented - cache `cargo-dylint`, `dylint-link`, and the relevant Cargo registry/git metadata in the lint job - split changed-path detection so the lint crate's own `cargo test` step runs only when `tools/argument-comment-lint/*` or `rust-ci.yml` changes - continue to run the repo wrapper over the `codex-rs` workspace, so product-code enforcement is unchanged Most of the code changes in this commit are intentionally mechanical comment rewrites or insertions driven by the lint itself. ## Verification - `./tools/argument-comment-lint/run.sh --workspace` - `cargo test -p codex-tui-app-server -p codex-tui` - parsed `.github/workflows/rust-ci.yml` locally with PyYAML --- * -> #14652 * #14651
Michael Bolin ·
2026-03-16 16:48:15 -07:00 -
Move TUI on top of app server (parallel code) (#14717)
This PR replicates the `tui` code directory and creates a temporary parallel `tui_app_server` directory. It also implements a new feature flag `tui_app_server` to select between the two tui implementations. Once the new app-server-based TUI is stabilized, we'll delete the old `tui` directory and feature flag.
Eric Traut ·
2026-03-16 10:49:19 -06:00 -
Start TUI on embedded app server (#14512)
This PR is part of the effort to move the TUI on top of the app server. In a previous PR, we introduced an in-process app server and moved `exec` on top of it. For the TUI, we want to do the migration in stages. The app server doesn't currently expose all of the functionality required by the TUI, so we're going to need to support a hybrid approach as we make the transition. This PR changes the TUI initialization to instantiate an in-process app server and access its `AuthManager` and `ThreadManager` rather than constructing its own copies. It also adds a placeholder TUI event handler that will eventually translate app server events into TUI events. App server notifications are accepted but ignored for now. It also adds proper shutdown of the app server when the TUI terminates.
Eric Traut ·
2026-03-13 12:04:41 -06:00 -
jif-oai ·
2026-03-07 03:48:36 -08:00 -
fix(tui) remove config check for trusted setting (#11874)
## Summary Simplify the trusted directory flow. This logic was originally designed several months ago, to determine if codex should start in read-only or workspace-write mode. However, that's no longer the purpose of directory trust - and therefore we should get rid of this logic. ## Testing - [x] Unit tests pass
Dylan Hurd ·
2026-03-05 22:29:34 -08:00 -
feat(core): persist trace_id for turns in RolloutItem::TurnContext (#13602)
This PR adds a durable trace linkage for each turn by storing the active trace ID on the rollout TurnContext record stored in session rollout files. Before this change, we propagated trace context at runtime but didn’t persist a stable per-turn trace key in rollout history. That made after-the-fact debugging harder (for example, mapping a historical turn to the corresponding trace in datadog). This sets us up for much easier debugging in the future. ### What changed - Added an optional `trace_id` to TurnContextItem (rollout schema). - Added a small OTEL helper to read the current span trace ID. - Captured `trace_id` when creating `TurnContext` and included it in `to_turn_context_item()`. - Updated tests and fixtures that construct TurnContextItem so older/no-trace cases still work. ### Why this approach TurnContext is already the canonical durable per-turn metadata in rollout. This keeps ownership clean: trace linkage lives with other persisted turn metadata.
Owen Lin ·
2026-03-05 13:26:48 -08:00 -
config: enforce enterprise feature requirements (#13388)
## Why Enterprises can already constrain approvals, sandboxing, and web search through `requirements.toml` and MDM, but feature flags were still only configurable as managed defaults. That meant an enterprise could suggest feature values, but it could not actually pin them. This change closes that gap and makes enterprise feature requirements behave like the other constrained settings. The effective feature set now stays consistent with enterprise requirements during config load, when config writes are validated, and when runtime code mutates feature flags later in the session. It also tightens the runtime API for managed features. `ManagedFeatures` now follows the same constraint-oriented shape as `Constrained<T>` instead of exposing panic-prone mutation helpers, and production code can no longer construct it through an unconstrained `From<Features>` path. The PR also hardens the `compact_resume_fork` integration coverage on Windows. After the feature-management changes, `compact_resume_after_second_compaction_preserves_history` was overflowing the libtest/Tokio thread stacks on Windows, so the test now uses an explicit larger-stack harness as a pragmatic mitigation. That may not be the ideal root-cause fix, and it merits a parallel investigation into whether part of the async future chain should be boxed to reduce stack pressure instead. ## What Changed Enterprises can now pin feature values in `requirements.toml` with the requirements-side `features` table: ```toml [features] personality = true unified_exec = false ``` Only canonical feature keys are allowed in the requirements `features` table; omitted keys remain unconstrained. - Added a requirements-side pinned feature map to `ConfigRequirementsToml`, threaded it through source-preserving requirements merge and normalization in `codex-config`, and made the TOML surface use `[features]` (while still accepting legacy `[feature_requirements]` for compatibility). - Exposed `featureRequirements` from `configRequirements/read`, regenerated the JSON/TypeScript schema artifacts, and updated the app-server README. - Wrapped the effective feature set in `ManagedFeatures`, backed by `ConstrainedWithSource<Features>`, and changed its API to mirror `Constrained<T>`: `can_set(...)`, `set(...) -> ConstraintResult<()>`, and result-returning `enable` / `disable` / `set_enabled` helpers. - Removed the legacy-usage and bulk-map passthroughs from `ManagedFeatures`; callers that need those behaviors now mutate a plain `Features` value and reapply it through `set(...)`, so the constrained wrapper remains the enforcement boundary. - Removed the production loophole for constructing unconstrained `ManagedFeatures`. Non-test code now creates it through the configured feature-loading path, and `impl From<Features> for ManagedFeatures` is restricted to `#[cfg(test)]`. - Rejected legacy feature aliases in enterprise feature requirements, and return a load error when a pinned combination cannot survive dependency normalization. - Validated config writes against enterprise feature requirements before persisting changes, including explicit conflicting writes and profile-specific feature states that normalize into invalid combinations. - Updated runtime and TUI feature-toggle paths to use the constrained setter API and to persist or apply the effective post-constraint value rather than the requested value. - Updated the `core_test_support` Bazel target to include the bundled core model-catalog fixtures in its runtime data, so helper code that resolves `core/models.json` through runfiles works in remote Bazel test environments. - Renamed the core config test coverage to emphasize that effective feature values are normalized at runtime, while conflicting persisted config writes are rejected. - Ran `compact_resume_after_second_compaction_preserves_history` inside an explicit 8 MiB test thread and Tokio runtime worker stack, following the existing larger-stack integration-test pattern, to keep the Windows `compact_resume_fork` test slice from aborting while a parallel investigation continues into whether some of the underlying async futures should be boxed. ## Verification - `cargo test -p codex-config` - `cargo test -p codex-core feature_requirements_ -- --nocapture` - `cargo test -p codex-core load_requirements_toml_produces_expected_constraints -- --nocapture` - `cargo test -p codex-core compact_resume_after_second_compaction_preserves_history -- --nocapture` - `cargo test -p codex-core compact_resume_fork -- --nocapture` - Re-ran the built `codex-core` `tests/all` binary with `RUST_MIN_STACK=262144` for `compact_resume_after_second_compaction_preserves_history` to confirm the explicit-stack harness fixes the deterministic low-stack repro. - `cargo test -p codex-core` - This still fails locally in unrelated integration areas that expect the `codex` / `test_stdio_server` binaries or hit existing `search_tool` wiremock mismatches. ## Docs `developers.openai.com/codex` should document the requirements-side `[features]` table for enterprise and MDM-managed configuration, including that it only accepts canonical feature keys and that conflicting config writes are rejected.
Michael Bolin ·
2026-03-04 04:40:22 +00:00 -
Record realtime close marker on replacement (#13058)
## Summary - record a realtime close developer message when a new realtime session replaces an active one - assert the replacement marker through the mocked responses request path --------- Co-authored-by: Codex <noreply@openai.com> Co-authored-by: Charles Cunningham <ccunningham@openai.com>
Ahmed Ibrahim ·
2026-03-01 13:54:12 -08:00 -
feat: add local date/timezone to turn environment context (#12947)
## Summary This PR includes the session's local date and timezone in the model-visible environment context and persists that data in `TurnContextItem`. ## What changed - captures the current local date and IANA timezone when building a turn context, with a UTC fallback if the timezone lookup fails - includes current_date and timezone in the serialized <environment_context> payload - stores those fields on TurnContextItem so they survive rollout/history handling, subagent review threads, and resume flows - treats date/timezone changes as environment updates, so prompt caching and context refresh logic do not silently reuse stale time context - updates tests to validate the new environment fields without depending on a single hardcoded environment-context string ## test built a local build and saw it in the rollout file: ``` {"timestamp":"2026-02-26T21:39:50.737Z","type":"response_item","payload":{"type":"message","role":"user","content":[{"type":"input_text","text":"<environment_context>\n <shell>zsh</shell>\n <current_date>2026-02-26</current_date>\n <timezone>America/Los_Angeles</timezone>\n</environment_context>"}]}} ```Celia Chen ·
2026-02-26 23:17:35 +00:00 -
Add realtime audio device config (#12849)
## Summary - add top-level realtime audio config for microphone and speaker selection - apply configured devices when starting realtime capture and playback - keep missing-device behavior on the system default fallback path ## Validation - just write-config-schema - cargo test -p codex-core realtime_audio - cargo test -p codex-tui - just fix -p codex-core - just fix -p codex-tui - just fmt --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-02-26 15:08:21 -08:00 -
tui: use thread_id for resume/fork cwd resolution (#12727)
## Summary - make resume/fork targets explicit and typed as `SessionTarget { path, thread_id }` (non-optional `thread_id`) - resolve `thread_id` centrally via `resolve_session_thread_id(...)`: - use CLI input directly when it is a UUID (`--resume <uuid>` / `--fork <uuid>`) - otherwise read `thread_id` from rollout `SessionMeta` for path-based selections (picker, `--resume-last`, name-based resume/fork) - use `thread_id` to read cwd from SQLite first during resume/fork cwd resolution - keep rollout fallback for cwd resolution when SQLite is unavailable or does not return thread metadata (`TurnContext` tail, then `SessionMeta`) - keep the resume picker open when a selected row has unreadable session metadata, and show an inline recoverable error instead of aborting the TUI ## Why This removes ad-hoc rollout filename parsing and makes resume/fork target identity explicit. The resume/fork cwd check can use indexed SQLite lookup by `thread_id` in the common path, while preserving rollout-based fallback behavior. It also keeps malformed legacy rows recoverable in the picker instead of letting a selection failure unwind the app. ## Notes - minimal TUI-only change; no schema/protocol changes - includes TUI test coverage for SQLite cwd precedence when `thread_id` is available - includes TUI regression coverage for picker inline error rendering / non-fatal unreadable session rows ## Codex author `codex resume 019c9205-7f8b-7173-a2a2-f082d4df3de3`Charley Cunningham ·
2026-02-26 12:52:31 -08:00 -
Use model catalog default for reasoning summary fallback (#12873)
## Summary - make `Config.model_reasoning_summary` optional so unset means use model default - resolve the optional config value to a concrete summary when building `TurnContext` - add protocol support for `default_reasoning_summary` in model metadata ## Validation - `cargo test -p codex-core --lib client::tests -- --nocapture` --------- Co-authored-by: Codex <noreply@openai.com>
pakrym-oai ·
2026-02-26 09:31:13 -08:00 -
feat: add search term to thread list (#12578)
Add `searchTerm` to `thread/list` that will search for a match in the titles (the condition being `searchTerm` $$\in$$ `title`)
jif-oai ·
2026-02-25 09:59:41 +00:00 -
feat: pass helper executable paths via Arg0DispatchPaths (#12719)
## Why `codex-rs/core/src/tools/runtimes/shell/unix_escalation.rs` previously located `codex-execve-wrapper` by scanning `PATH` and sibling directories. That lookup is brittle and can select the wrong binary when the runtime environment differs from startup assumptions. We already pass `codex-linux-sandbox` from `codex-arg0`; `codex-execve-wrapper` should use the same startup-driven path plumbing. ## What changed - Introduced `Arg0DispatchPaths` in `codex-arg0` to carry both helper executable paths: - `codex_linux_sandbox_exe` - `main_execve_wrapper_exe` - Updated `arg0_dispatch_or_else()` to pass `Arg0DispatchPaths` to top-level binaries and preserve helper paths created in `prepend_path_entry_for_codex_aliases()`. - Threaded `Arg0DispatchPaths` through entrypoints in `cli`, `exec`, `tui`, `app-server`, and `mcp-server`. - Added `main_execve_wrapper_exe` to core configuration plumbing (`Config`, `ConfigOverrides`, and `SessionServices`). - Updated zsh-fork shell escalation to consume the configured `main_execve_wrapper_exe` and removed path-sniffing fallback logic. - Updated app-server config reload paths so reloaded configs keep the same startup-provided helper executable paths. ## References - [`Arg0DispatchPaths` definition](https://github.com/openai/codex/blob/e355b43d5c2a771f045296a6deae10d7c9c36ec6/codex-rs/arg0/src/lib.rs#L20-L24) - [`arg0_dispatch_or_else()` forwarding both paths](https://github.com/openai/codex/blob/e355b43d5c2a771f045296a6deae10d7c9c36ec6/codex-rs/arg0/src/lib.rs#L145-L176) - [zsh-fork escalation using configured wrapper path](https://github.com/openai/codex/blob/e355b43d5c2a771f045296a6deae10d7c9c36ec6/codex-rs/core/src/tools/runtimes/shell/unix_escalation.rs#L109-L150) ## Testing - `cargo check -p codex-arg0 -p codex-core -p codex-exec -p codex-tui -p codex-mcp-server -p codex-app-server` - `cargo test -p codex-arg0` - `cargo test -p codex-core tools::runtimes::shell::unix_escalation:: -- --nocapture`
Michael Bolin ·
2026-02-24 17:44:38 -08:00 -
feat(tui) - /copy (#12613)
# /copy! /copy allows you to copy the latest **complete** message from Codex on the TUI.
Won Park ·
2026-02-24 14:17:01 -08:00 -
Add TUI realtime conversation mode (#12687)
- Add a hidden `realtime_conversation` feature flag and `/realtime` slash command for start/stop live voice sessions. - Reuse transcription composer/footer UI for live metering, stream mic audio, play assistant audio, render realtime user text events, and force-close on feature disable. --------- Co-authored-by: Codex <noreply@openai.com>
Ahmed Ibrahim ·
2026-02-24 12:54:30 -08:00 -
voice transcription (#3381)
Adds voice transcription on press-and-hold of spacebar. https://github.com/user-attachments/assets/85039314-26f3-46d1-a83b-8c4a4a1ecc21 --------- Co-authored-by: Codex <199175422+chatgpt-codex-connector[bot]@users.noreply.github.com> Co-authored-by: David Zbarsky <zbarsky@openai.com>
Jeremy Rose ·
2026-02-23 22:15:18 +00:00 -
fix: add ellipsis for truncated status indicator (#12540)
#### What - Add ellipsis truncation of the status indicator, similar to equivalent truncation done in the footer. - Extract truncation helpers into separate file https://github.com/user-attachments/assets/a2d5f22f-8adc-456e-8059-97359194c25c #### Tests Updated relevant snapshot tests
sayan-oai ·
2026-02-23 11:45:46 -08:00 -
feat(tui): syntax highlighting via syntect with theme picker (#11447)
## Summary Adds syntax highlighting to the TUI for fenced code blocks in markdown responses and file diffs, plus a `/theme` command with live preview and persistent theme selection. Uses syntect (~250 grammars, 32 bundled themes, ~1 MB binary cost) — the same engine behind `bat`, `delta`, and `xi-editor`. Includes guardrails for large inputs, graceful fallback to plain text, and SSH-aware clipboard integration for the `/copy` command. <img width="1554" height="1014" alt="image" src="https://github.com/user-attachments/assets/38737a79-8717-4715-b857-94cf1ba59b85" /> <img width="2354" height="1374" alt="image" src="https://github.com/user-attachments/assets/25d30a00-c487-4af8-9cb6-63b0695a4be7" /> ## Problem Code blocks in the TUI (markdown responses and file diffs) render without syntax highlighting, making it hard to scan code at a glance. Users also have no way to pick a color theme that matches their terminal aesthetic. ## Mental model The highlighting system has three layers: 1. **Syntax engine** (`render::highlight`) -- a thin wrapper around syntect + two-face. It owns a process-global `SyntaxSet` (~250 grammars) and a `RwLock<Theme>` that can be swapped at runtime. All public entry points accept `(code, lang)` and return ratatui `Span`/`Line` vectors or `None` when the language is unrecognized or the input exceeds safety guardrails. 2. **Rendering consumers** -- `markdown_render` feeds fenced code blocks through the engine; `diff_render` highlights Add/Delete content as a whole file and Update hunks per-hunk (preserving parser state across hunk lines). Both callers fall back to plain unstyled text when the engine returns `None`. 3. **Theme lifecycle** -- at startup the config's `tui.theme` is resolved to a syntect `Theme` via `set_theme_override`. At runtime the `/theme` picker calls `set_syntax_theme` to swap themes live; on cancel it restores the snapshot taken at open. On confirm it persists `[tui] theme = "..."` to config.toml. ## Non-goals - Inline diff highlighting (word-level change detection within a line). - Semantic / LSP-backed highlighting. - Theme authoring tooling; users supply standard `.tmTheme` files. ## Tradeoffs | Decision | Upside | Downside | | ------------------------------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------- | | syntect over tree-sitter / arborium | ~1 MB binary increase for ~250 grammars + 32 themes; battle-tested crate powering widely-used tools (`bat`, `delta`, `xi-editor`). tree-sitter would add ~12 MB for 20-30 languages or ~35 MB for full coverage. | Regex-based; less structurally accurate than tree-sitter for some languages (e.g. language injections like JS-in-HTML). | | Global `RwLock<Theme>` | Enables live `/theme` preview without threading Theme through every call site | Lock contention risk (mitigated: reads vastly outnumber writes, single UI thread) | | Skip background / italic / underline from themes | Terminal BG preserved, avoids ugly rendering on some themes | Themes that rely on these properties lose fidelity | | Guardrails: 512 KB / 10k lines | Prevents pathological stalls on huge diffs or pastes | Very large files render without color | ## Architecture ``` config.toml ─[tui.theme]─> set_theme_override() ─> THEME (RwLock) │ ┌───────────────────────────────────────────┘ │ markdown_render ─── highlight_code_to_lines(code, lang) ─> Vec<Line> diff_render ─── highlight_code_to_styled_spans(code, lang) ─> Option<Vec<Vec<Span>>> │ │ (None ⇒ plain text fallback) │ /theme picker ─── set_syntax_theme(theme) // live preview swap ─── current_syntax_theme() // snapshot for cancel ─── resolve_theme_by_name(name) // lookup by kebab-case ``` Key files: - `tui/src/render/highlight.rs` -- engine, theme management, guardrails - `tui/src/diff_render.rs` -- syntax-aware diff line wrapping - `tui/src/theme_picker.rs` -- `/theme` command builder - `tui/src/bottom_pane/list_selection_view.rs` -- side content panel, callbacks - `core/src/config/types.rs` -- `Tui::theme` field - `core/src/config/edit.rs` -- `syntax_theme_edit()` helper ## Observability - `tracing::warn` when a configured theme name cannot be resolved. - `Config::startup_warnings` surfaces the same message as a TUI banner. - `tracing::error` when persisting theme selection fails. ## Tests - Unit tests in `highlight.rs`: language coverage, fallback behavior, CRLF stripping, style conversion, guardrail enforcement, theme name mapping exhaustiveness. - Unit tests in `diff_render.rs`: snapshot gallery at multiple terminal sizes (80x24, 94x35, 120x40), syntax-highlighted wrapping, large-diff guardrail, rename-to-different-extension highlighting, parser state preservation across hunk lines. - Unit tests in `theme_picker.rs`: preview rendering (wide + narrow), dim overlay on deletions, subtitle truncation, cancel-restore, fallback for unavailable configured theme. - Unit tests in `list_selection_view.rs`: side layout geometry, stacked fallback, buffer clearing, cancel/selection-changed callbacks. - Integration test in `lib.rs`: theme warning uses the final (post-resume) config. ## Cargo Deny: Unmaintained Dependency Exceptions This PR adds two `cargo deny` advisory exceptions for transitive dependencies pulled in by `syntect v5.3.0`: | Advisory | Crate | Status | |----------|-------|--------| | RUSTSEC-2024-0320 | `yaml-rust` | Unmaintained (maintainer unreachable) | | RUSTSEC-2025-0141 | `bincode` | Unmaintained (development ceased; v1.3.3 considered complete) | **Why this is safe in our usage:** - Neither advisory describes a known security vulnerability. Both are "unmaintained" notices only. - `bincode` is used by syntect to deserialize pre-compiled syntax sets. Again, these are **static vendored artifacts** baked into the binary at build time. No user-supplied bincode data is ever deserialized. - Attack surface is zero for both crates; exploitation would require a supply-chain compromise of our own build artifacts. - These exceptions can be removed when syntect migrates to `yaml-rust2` and drops `bincode`, or when alternative crates are available upstream.
Felipe Coury ·
2026-02-21 20:26:58 -08:00 -
chore: remove codex-core public protocol/shell re-exports (#12432)
## Why `codex-rs/core/src/lib.rs` re-exported a broad set of types and modules from `codex-protocol` and `codex-shell-command`. That made it easy for workspace crates to import those APIs through `codex-core`, which in turn hides dependency edges and makes it harder to reduce compile-time coupling over time. This change removes those public re-exports so call sites must import from the source crates directly. Even when a crate still depends on `codex-core` today, this makes dependency boundaries explicit and unblocks future work to drop `codex-core` dependencies where possible. ## What Changed - Removed public re-exports from `codex-rs/core/src/lib.rs` for: - `codex_protocol::protocol` and related protocol/model types (including `InitialHistory`) - `codex_protocol::config_types` (`protocol_config_types`) - `codex_shell_command::{bash, is_dangerous_command, is_safe_command, parse_command, powershell}` - Migrated workspace Rust call sites to import directly from: - `codex_protocol::protocol` - `codex_protocol::config_types` - `codex_protocol::models` - `codex_shell_command` - Added explicit `Cargo.toml` dependencies (`codex-protocol` / `codex-shell-command`) in crates that now import those crates directly. - Kept `codex-core` internal modules compiling by using `pub(crate)` aliases in `core/src/lib.rs` (internal-only, not part of the public API). - Updated the two utility crates that can already drop a `codex-core` dependency edge entirely: - `codex-utils-approval-presets` - `codex-utils-cli` ## Verification - `cargo test -p codex-utils-approval-presets` - `cargo test -p codex-utils-cli` - `cargo check --workspace --all-targets` - `just clippy`Michael Bolin ·
2026-02-20 23:45:35 -08:00 -
tui: exit session on Ctrl+C in cwd change prompt (#12040)
## Summary - change the cwd-change prompt (shown when resuming/forking across different directories) so `Ctrl+C`/`Ctrl+D` exits the session instead of implicitly selecting "Use session directory" - introduce explicit prompt and resolver exit outcomes so this intent is propagated cleanly through both startup resume/fork and in-app `/resume` flows - add a unit test that verifies `Ctrl+C` exits rather than selecting an option ## Why Previously, pressing `Ctrl+C` on this prompt silently picked one of the options, which made it hard to abort. This aligns the prompt with the expected quit behavior. ## Codex author `codex resume 019c6d39-bbfb-7dc3-8008-1388a054e86d`
Charley Cunningham ·
2026-02-17 14:48:12 -08:00 -
Rename collab modules to multi agents (#11939)
Summary - rename the `collab` handlers and UI files to `multi_agents` to match the new naming - update module references and specs so the handlers and TUI widgets consistently use the renamed files - keep the existing functionality while aligning file and module names with the multi-agent terminology
jif-oai ·
2026-02-16 19:05:13 +00:00 -
Report syntax errors in rules file (#11686)
Currently, if there are syntax errors detected in the starlark rules file, the entire policy is silently ignored by the CLI. The app server correctly emits a message that can be displayed in a GUI. This PR changes the CLI (both the TUI and non-interactive exec) to fail when the rules file can't be parsed. It then prints out an error message and exits with a non-zero exit code. This is consistent with the handling of errors in the config file. This addresses #11603
Eric Traut ·
2026-02-13 10:33:40 -08:00 -
Persist complete TurnContextItem state via canonical conversion (#11656)
## Summary This PR delivers the first small, shippable step toward model-visible state diffing by making `TurnContextItem` more complete and standardizing how it is built. Specifically, it: - Adds persisted network context to `TurnContextItem`. - Introduces a single canonical `TurnContext -> TurnContextItem` conversion path. - Routes existing rollout write sites through that canonical conversion helper. No context injection/diff behavior changes are included in this PR. ## Why this change The design goal is to make `TurnContextItem` the canonical source of truth for context-diff decisions. Before this PR: - `TurnContextItem` did not include all TurnContext-derived environment inputs needed for v1 completeness. - Construction was duplicated at multiple write sites. This PR addresses both with a minimal, reviewable change. ## Changes ### 1) Extend `TurnContextItem` with network state - Added `TurnContextNetworkItem { allowed_domains, denied_domains }`. - Added `network: Option<TurnContextNetworkItem>` to `TurnContextItem`. - Kept backward compatibility by making the new field optional and skipped when absent. Files: - `codex-rs/protocol/src/protocol.rs` ### 2) Canonical conversion helper - Added `TurnContext::to_turn_context_item(collaboration_mode)` in core. - Added internal helper to derive network fields from `config_layer_stack.requirements().network`. Files: - `codex-rs/core/src/codex.rs` ### 3) Use canonical conversion at rollout write sites - Replaced ad hoc `TurnContextItem { ... }` construction with `to_turn_context_item(...)` in: - sampling request path - compaction path Files: - `codex-rs/core/src/codex.rs` - `codex-rs/core/src/compact.rs` ### 4) Update fixtures/tests for new optional field - Updated existing `TurnContextItem` literals in tests to include `network: None`. - Added protocol tests for: - deserializing old payloads with no `network` - serializing when `network` is present Files: - `codex-rs/core/tests/suite/resume_warning.rs` - No replay/diff logic changes. - Persisted rollout `TurnContextItem` now carries additional network context when available. - Older rollout lines without `network` remain readable.Charley Cunningham ·
2026-02-12 17:22:44 -08:00 -
feat: introduce Permissions (#11633)
## Why We currently carry multiple permission-related concepts directly on `Config` for shell/unified-exec behavior (`approval_policy`, `sandbox_policy`, `network`, `shell_environment_policy`, `windows_sandbox_mode`). Consolidating these into one in-memory struct makes permission handling easier to reason about and sets up the next step: supporting named permission profiles (`[permissions.PROFILE_NAME]`) without changing behavior now. This change is mostly mechanical: it updates existing callsites to go through `config.permissions`, but it does not yet refactor those callsites to take a single `Permissions` value in places where multiple permission fields are still threaded separately. This PR intentionally **does not** change the on-disk `config.toml` format yet and keeps compatibility with legacy config keys. ## What Changed - Introduced `Permissions` in `core/src/config/mod.rs`. - Added `Config::permissions` and moved effective runtime permission fields under it: - `approval_policy` - `sandbox_policy` - `network` - `shell_environment_policy` - `windows_sandbox_mode` - Updated config loading/building so these effective values are still derived from the same existing config inputs and constraints. - Updated Windows sandbox helpers/resolution to read/write via `permissions`. - Threaded the new field through all permission consumers across core runtime, app-server, CLI/exec, TUI, and sandbox summary code. - Updated affected tests to reference `config.permissions.*`. - Renamed the struct/field from `EffectivePermissions`/`effective_permissions` to `Permissions`/`permissions` and aligned variable naming accordingly. ## Verification - `just fix -p codex-core -p codex-tui -p codex-cli -p codex-app-server -p codex-exec -p codex-utils-sandbox-summary` - `cargo build -p codex-core -p codex-tui -p codex-cli -p codex-app-server -p codex-exec -p codex-utils-sandbox-summary`
Michael Bolin ·
2026-02-12 14:42:54 -08:00 -
Promote Windows Sandbox (#11341)
1. Move Windows Sandbox NUX to right after trust directory screen 2. Don't offer read-only as an option in Sandbox NUX. Elevated/Legacy/Quit 3. Don't allow new untrusted directories. It's trust or quit 4. move experimental sandbox features to `[windows] sandbox="elevated|unelevatd"` 5. Copy tweaks = elevated -> default, non-elevated -> non-admin
iceweasel-oai ·
2026-02-11 11:48:33 -08:00 -
Cache cloud requirements (#11305)
We're loading these from the web on every startup. This puts them in a local file with a 1hr TTL. We sign the downloaded requirements with a key compiled into the Codex CLI to prevent unsophisticated tampering (determined circumvention is outside of our threat model: after all, one could just compile Codex without any of these checks). If any of the following are true, we ignore the local cache and re-fetch from Cloud: * The signature is invalid for the payload (== requirements, sign time, ttl, user identity) * The identity does not match the auth'd user's identity * The TTL has expired * We cannot parse requirements.toml from the payload
gt-oai ·
2026-02-11 14:06:41 +00:00 -
feat: split codex-common into smaller utils crates (#11422)
We are removing feature-gated shared crates from the `codex-rs` workspace. `codex-common` grouped several unrelated utilities behind `[features]`, which made dependency boundaries harder to reason about and worked against the ongoing effort to eliminate feature flags from workspace crates. Splitting these utilities into dedicated crates under `utils/` aligns this area with existing workspace structure and keeps each dependency explicit at the crate boundary. ## What changed - Removed `codex-rs/common` (`codex-common`) from workspace members and workspace dependencies. - Added six new utility crates under `codex-rs/utils/`: - `codex-utils-cli` - `codex-utils-elapsed` - `codex-utils-sandbox-summary` - `codex-utils-approval-presets` - `codex-utils-oss` - `codex-utils-fuzzy-match` - Migrated the corresponding modules out of `codex-common` into these crates (with tests), and added matching `BUILD.bazel` targets. - Updated direct consumers to use the new crates instead of `codex-common`: - `codex-rs/cli` - `codex-rs/tui` - `codex-rs/exec` - `codex-rs/app-server` - `codex-rs/mcp-server` - `codex-rs/chatgpt` - `codex-rs/cloud-tasks` - Updated workspace lockfile entries to reflect the new dependency graph and removal of `codex-common`.
Michael Bolin ·
2026-02-11 12:59:24 +00:00 -
chore: persist turn_id in rollout session and make turn_id uuid based (#11246)
Problem: 1. turn id is constructed in-memory; 2. on resuming threads, turn_id might not be unique; 3. client cannot no the boundary of a turn from rollout files easily. This PR does three things: 1. persist `task_started` and `task_complete` events; 1. persist `turn_id` in rollout turn events; 5. generate turn_id as unique uuids instead of incrementing it in memory. This helps us resolve the issue of clients wanting to have unique turn ids for resuming a thread, and knowing the boundry of each turn in rollout files. example debug logs ``` 2026-02-11T00:32:10.746876Z DEBUG codex_app_server_protocol::protocol::thread_history: built turn from rollout items turn_index=8 turn=Turn { id: "019c4a07-d809-74c3-bc4b-fd9618487b4b", items: [UserMessage { id: "item-24", content: [Text { text: "hi", text_elements: [] }] }, AgentMessage { id: "item-25", text: "Hi. I’m in the workspace with your current changes loaded and ready. Send the next task and I’ll execute it end-to-end." }], status: Completed, error: None } 2026-02-11T00:32:10.746888Z DEBUG codex_app_server_protocol::protocol::thread_history: built turn from rollout items turn_index=9 turn=Turn { id: "019c4a18-1004-76c0-a0fb-a77610f6a9b8", items: [UserMessage { id: "item-26", content: [Text { text: "hello", text_elements: [] }] }, AgentMessage { id: "item-27", text: "Hello. Ready for the next change in `codex-rs`; I can continue from the current in-progress diff or start a new task." }], status: Completed, error: None } 2026-02-11T00:32:10.746899Z DEBUG codex_app_server_protocol::protocol::thread_history: built turn from rollout items turn_index=10 turn=Turn { id: "019c4a19-41f0-7db0-ad78-74f1503baeb8", items: [UserMessage { id: "item-28", content: [Text { text: "hello", text_elements: [] }] }, AgentMessage { id: "item-29", text: "Hello. Send the specific change you want in `codex-rs`, and I’ll implement it and run the required checks." }], status: Completed, error: None } ``` backward compatibility: if you try to resume an old session without task_started and task_complete event populated, the following happens: - If you resume and do nothing: those reconstructed historical IDs can differ next time you resume. - If you resume and send a new turn: the new turn gets a fresh UUID from live submission flow and is persisted, so that new turn’s ID is stable on later resumes. I think this behavior is fine, because we only care about deterministic turn id once a turn is triggered.Celia Chen ·
2026-02-11 03:56:01 +00:00 -
jif-oai ·
2026-02-10 19:25:07 +00:00 -
TUI/Core: preserve duplicate skill/app mention selection across submit + resume (#10855)
## What changed - In `codex-rs/core/src/skills/injection.rs`, we now honor explicit `UserInput::Skill { name, path }` first, then fall back to text mentions only when safe. - In `codex-rs/tui/src/bottom_pane/chat_composer.rs`, mention selection is now token-bound (selected mention is tied to the specific inserted `$token`), and we snapshot bindings at submit time so selection is not lost. - In `codex-rs/tui/src/chatwidget.rs` and `codex-rs/tui/src/bottom_pane/mod.rs`, submit/queue paths now consume the submit-time mention snapshot (instead of rereading cleared composer state). - In `codex-rs/tui/src/mention_codec.rs` and `codex-rs/tui/src/bottom_pane/chat_composer_history.rs`, history now round-trips mention targets so resume restores the same selected duplicate. - In `codex-rs/tui/src/bottom_pane/skill_popup.rs` and `codex-rs/tui/src/bottom_pane/chat_composer.rs`, duplicate labels are normalized to `[Repo]` / `[App]`, app rows no longer show `Connected -`, and description space is a bit wider. <img width="550" height="163" alt="Screenshot 2026-02-05 at 9 56 56 PM" src="https://github.com/user-attachments/assets/346a7eb2-a342-4a49-aec8-68dfec0c7d89" /> <img width="550" height="163" alt="Screenshot 2026-02-05 at 9 57 09 PM" src="https://github.com/user-attachments/assets/5e04d9af-cccf-4932-98b3-c37183e445ed" /> ## Before vs now - Before: selecting a duplicate could still submit the default/repo match, and resume could lose which duplicate was originally selected. - Now: the exact selected target (skill path or app id) is preserved through submit, queue/restore, and resume. ## Manual test 1. Build and run this branch locally: - `cd /Users/daniels/code/codex/codex-rs` - `cargo build -p codex-cli --bin codex` - `./target/debug/codex` 2. Open mention picker with `$` and pick a duplicate entry (not the first one). 3. Confirm duplicate UI: - repo duplicate rows show `[Repo]` - app duplicate rows show `[App]` - app description does **not** start with `Connected -` 4. Submit the prompt, then press Up to restore draft and submit again. Expected: it keeps the same selected duplicate target. 5. Use `/resume` to reopen the session and send again. Expected: restored mention still resolves to the same duplicate target.daniel-oai ·
2026-02-06 15:59:00 -08:00 -
fix(auth): isolate chatgptAuthTokens concept to auth manager and app-server (#10423)
So that the rest of the codebase (like TUI) don't need to be concerned whether ChatGPT auth was handled by Codex itself or passed in via app-server's external auth mode.
Owen Lin ·
2026-02-05 10:46:06 -08:00 -
Reload cloud requirements after user login (#10725)
Reload cloud requirements after user login so it could take effect immediately.
xl-openai ·
2026-02-05 00:27:16 -08:00 -
Add /debug-config slash command (#10642)
<img width="409" height="175" alt="image" src="https://github.com/user-attachments/assets/76efe9c5-8375-4af3-b6af-bd9e162c1bc3" />
gt-oai ·
2026-02-04 22:26:17 +00:00 -
jif-oai ·
2026-02-03 11:31:57 +00:00 -
Fixed sandbox mode inconsistency if untrusted is selected (#10415)
This PR addresses #10395 When a user is asked to pick the trust level of a project, the code currently reloads the config if they select "trusted". It doesn't reload the config in the "untrusted" case but should. This causes the sandbox mode to be reported incorrectly in `/status` during the first run (it's displayed as `read-only` even though it acts as though it's `workspace-write`).
Eric Traut ·
2026-02-03 02:00:35 +00:00 -
feat(core,tui,app-server) personality migration (#10307)
## Summary Keep existing users on Pragmatic, to preserve behavior while new users default to Friendly ## Testing - [x] Tested locally - [x] add integration tests
Dylan Hurd ·
2026-01-31 17:25:14 -07:00 -
Add enforce_residency to requirements (#10263)
Add `enforce_residency` to requirements.toml and thread it through to a header on `default_client`.
gt-oai ·
2026-01-31 00:26:25 +00:00