Commit Graph

4254 Commits

Author SHA1 Message Date
pash-openai
9a96b6f509 Hide local file link destinations in TUI markdown (#12705)
## Summary
- hide appended destinations for local path-style markdown links in the
TUI renderer
- keep web links rendering with their visible destination and style link
labels consistently
- add markdown renderer tests and a snapshot for the new file-link
output

## Testing
- just fmt
- cargo test -p codex-tui
<img width="1120" height="968" alt="image"
src="https://github.com/user-attachments/assets/490e8eda-ae47-4231-89fa-b254a1f83eed"
/>
2026-02-26 05:28:37 +00:00
pakrym-oai
cbbf302f5f Fix release build take (#12865) 2026-02-25 20:59:07 -08:00
Curtis 'Fjord' Hawthorne
7326c097e3 Reduce js_repl Node version requirement to 22.22.0 (#12857)
## Summary

Lower the `js_repl` minimum Node version from `24.13.1` to `22.22.0`.

This updates the enforced minimum in `codex-rs/node-version.txt` and the
corresponding user-facing `/experimental` description for the JavaScript
REPL feature.

## Rationale

The previous `24.13.1` floor was stricter than necessary for `js_repl`.
I validated the REPL kernel behavior under Node `22.22.0` still works.

## Why `22.22.0`

`22.22.0` is a current, widely packaged Node 22 release across common
developer environments and distros, including Homebrew `node@22`, Fedora
`nodejs22`, Arch `nodejs-lts-jod`, and Debian testing. That makes it a
better exact floor than guessing at an older `22.x` patch we have not
validated.

`22.x` is also a maintenance branch that will be supported through April
2027, where the previous maintenance branch of `20.x` is only supported
through April of this year.

## Changes

- Update `codex-rs/node-version.txt` from `24.13.1` to `22.22.0`
- Update the `/experimental` JavaScript REPL description to say
`Requires Node >= v22.22.0 installed.`
2026-02-26 04:09:30 +00:00
xl-openai
8cdee988f9 Skip system skills for extra roots (#12744)
When extra roots is set do not load system skills.
2026-02-25 19:55:28 -08:00
pakrym-oai
b65205fb3d Attempt 2 to fix release (#12856) 2026-02-25 19:12:19 -08:00
pakrym-oai
ea621ae152 Try fixing windows pipeline (#12848)
# External (non-OpenAI) Pull Request Requirements

Before opening this Pull Request, please read the dedicated
"Contributing" markdown file or your PR may be closed:
https://github.com/openai/codex/blob/main/docs/contributing.md

If your PR conforms to our contribution guidelines, replace this text
with a detailed and high quality description of your changes.

Include a link to a bug report or enhancement request.
2026-02-25 18:18:00 -08:00
xl-openai
2c1f225427 Clarify device auth login hint (#12813)
Mention device auth for remote login
2026-02-25 18:15:27 -08:00
Curtis 'Fjord' Hawthorne
40ab71a985 Disable js_repl when Node is incompatible at startup (#12824)
## Summary
- validate `js_repl` Node compatibility during session startup when the
experiment is enabled
- if Node is missing or too old, disable `js_repl` and
`js_repl_tools_only` for the session before tools and instructions are
built
- surface that startup disablement to users through the existing startup
warning flow instead of only logging it
- reuse the same compatibility check in js_repl kernel startup so
startup gating and runtime behavior stay aligned
- add a regression test that verifies the warning is emitted and that
the first advertised tool list omits `js_repl` and `js_repl_reset` when
Node is incompatible

## Why
Today `js_repl` can be advertised based only on the feature flag, then
fail later when the kernel starts. That makes the available tool list
inaccurate at the start of a conversation, and users do not get a clear
explanation for why the tool is unavailable.

This change makes tool availability reflect real startup checks, keeps
the advertised tool set stable for the lifetime of the session, and
gives users a visible warning when `js_repl` is disabled.

## Testing
- `just fmt`
- `cargo test -p codex-core --test all
js_repl_is_not_advertised_when_startup_node_is_incompatible`
2026-02-26 01:14:51 +00:00
Michael Bolin
14116ade8d feat: include available decisions in command approval requests (#12758)
Command-approval clients currently infer which choices to show from
side-channel fields like `networkApprovalContext`,
`proposedExecpolicyAmendment`, and `additionalPermissions`. That makes
the request shape harder to evolve, and it forces each client to
replicate the server's heuristics instead of receiving the exact
decision list for the prompt.

This PR introduces a mapping between `CommandExecutionApprovalDecision`
and `codex_protocol::protocol::ReviewDecision`:

```rust
impl From<CoreReviewDecision> for CommandExecutionApprovalDecision {
    fn from(value: CoreReviewDecision) -> Self {
        match value {
            CoreReviewDecision::Approved => Self::Accept,
            CoreReviewDecision::ApprovedExecpolicyAmendment {
                proposed_execpolicy_amendment,
            } => Self::AcceptWithExecpolicyAmendment {
                execpolicy_amendment: proposed_execpolicy_amendment.into(),
            },
            CoreReviewDecision::ApprovedForSession => Self::AcceptForSession,
            CoreReviewDecision::NetworkPolicyAmendment {
                network_policy_amendment,
            } => Self::ApplyNetworkPolicyAmendment {
                network_policy_amendment: network_policy_amendment.into(),
            },
            CoreReviewDecision::Abort => Self::Cancel,
            CoreReviewDecision::Denied => Self::Decline,
        }
    }
}
```

And updates `CommandExecutionRequestApprovalParams` to have a new field:

```rust
available_decisions: Option<Vec<CommandExecutionApprovalDecision>>
```

when, if specified, should make it easier for clients to display an
appropriate list of options in the UI.

This makes it possible for `CoreShellActionProvider::prompt()` in
`unix_escalation.rs` to specify the `Vec<ReviewDecision>` directly,
adding support for `ApprovedForSession` when approving a skill script,
which was previously missing in the TUI.

Note this results in a significant change to `exec_options()` in
`approval_overlay.rs`, as the displayed options are now derived from
`available_decisions: &[ReviewDecision]`.

## What Changed

- Add `available_decisions` to
[`ExecApprovalRequestEvent`](de00e932dd/codex-rs/protocol/src/approvals.rs (L111-L175)),
including helpers to derive the legacy default choices when older
senders omit the field.
- Map `codex_protocol::protocol::ReviewDecision` to app-server
`CommandExecutionApprovalDecision` and expose the ordered list as
experimental `availableDecisions` in
[`CommandExecutionRequestApprovalParams`](de00e932dd/codex-rs/app-server-protocol/src/protocol/v2.rs (L3798-L3807)).
- Thread optional `available_decisions` through the core approval path
so Unix shell escalation can explicitly request `ApprovedForSession` for
session-scoped approvals instead of relying on client heuristics.
[`unix_escalation.rs`](de00e932dd/codex-rs/core/src/tools/runtimes/shell/unix_escalation.rs (L194-L214))
- Update the TUI approval overlay to build its buttons from the ordered
decision list, while preserving the legacy fallback when
`available_decisions` is missing.
- Update the app-server README, test client output, and generated schema
artifacts to document and surface the new field.

## Testing

- Add `approval_overlay.rs` coverage for explicit decision lists,
including the generic `ApprovedForSession` path and network approval
options.
- Update `chatwidget/tests.rs` and app-server protocol tests to populate
the new optional field and keep older event shapes working.

## Developers Docs

- If we document `item/commandExecution/requestApproval` on
[developers.openai.com/codex](https://developers.openai.com/codex), add
experimental `availableDecisions` as the preferred source of approval
choices and note that older servers may omit it.
2026-02-26 01:10:46 +00:00
Celia Chen
4f45668106 Revert "Add skill approval event/response (#12633)" (#12811)
This reverts commit https://github.com/openai/codex/pull/12633. We no
longer need this PR, because we favor sending normal exec command
approval server request with `additional_permissions` of skill
permissions instead
2026-02-26 01:02:42 +00:00
pakrym-oai
4fedef88e0 Use websocket v2 as model-preferred websocket protocol (#12838) 2026-02-25 16:35:53 -08:00
EFRAZER-oai
a1cd78c818 Add macOS and Linux direct install script (#12740)
## Summary
- add a direct install script for macOS and Linux at
`scripts/install/install.sh`
- stage `install.sh` into `dist/` during release so it is published as a
GitHub release asset
- reuse the existing platform npm payload so the installer includes both
`codex` and `rg`

## Testing
- `bash -n scripts/install/install.sh`
- local macOS `curl | sh` smoke test against a locally served copy of
the script
2026-02-26 00:33:50 +00:00
Ahmed Ibrahim
e76b1a2853 Remove steer feature flag (#12026)
All code should go in the direction that steer is enabled

---------

Co-authored-by: Codex <noreply@openai.com>
2026-02-25 15:41:42 -08:00
Michael Bolin
a6a5976c5a feat: scope execve session approvals by approved skill metadata (#12814)
Previous to this change, `determine_action()` would

1. check if `program` is associated with a skill
2. if so, check if `program` is in `execve_session_approvals` to see
whether the user needs to be prompted

This PR flips the order of these checks to try to set us up so that
"session approvals" are always consulted first (which should soon extend
to include session approvals derived from `prefix_rule()`s, as well).

Though to make the new ordering work, we need to record any relevant
metadata to associate with the approval, which in the case of a
skill-based approval is the `SkillMetadata` so that we can derive the
`PermissionProfile` to include with the escalation. (Though as noted by
the `TODO`, this `PermissionProfile` is not honored yet.)

The new `ExecveSessionApproval` struct is used to retain the necessary
metadata.

## What Changed

- Replace the `execve_session_approvals` `HashSet` with a map that
stores an `ExecveSessionApproval` alongside each approved `program`.
- When a user chooses `ApprovedForSession` for a skill script, capture
the matched `SkillMetadata` in the session approval entry.
- Consult that cache before re-running `find_skill()`, and reuse the
originally approved skill metadata and permission profile when allowing
later execve callbacks in the same session.
2026-02-25 15:30:24 -08:00
Charley Cunningham
2f4d6ded1d Enable request_user_input in Default mode (#12735)
## Summary
- allow `request_user_input` in Default collaboration mode as well as
Plan
- update the Default-mode instructions to prefer assumptions first and
use `request_user_input` only when a question is unavoidable
- update request_user_input and app-server tests to match the new
Default-mode behavior
- refactor collaboration-mode availability plumbing into
`CollaborationModesConfig` for future mode-related flags

## Codex author
`codex resume 019c9124-ed28-7c13-96c6-b916b1c97d49`
2026-02-25 15:20:46 -08:00
Ahmed Ibrahim
2bd87d1a75 only use preambles for realtime (#12831)
Reverts openai/codex#12830
2026-02-25 14:54:54 -08:00
Celia Chen
b6d20748e0 Revert "Ensure shell command skills trigger approval (#12697)" (#12721)
This reverts commit daf0f03ac8.

# External (non-OpenAI) Pull Request Requirements

Before opening this Pull Request, please read the dedicated
"Contributing" markdown file or your PR may be closed:
https://github.com/openai/codex/blob/main/docs/contributing.md

If your PR conforms to our contribution guidelines, replace this text
with a detailed and high quality description of your changes.

Include a link to a bug report or enhancement request.
2026-02-25 22:49:53 +00:00
Ahmed Ibrahim
f86087eaa8 Revert "only use preambles for realtime" (#12830)
Reverts openai/codex#12806
2026-02-25 14:30:48 -08:00
Ahmed Ibrahim
c1851be1ed only use preambles for realtime (#12806)
# External (non-OpenAI) Pull Request Requirements

Before opening this Pull Request, please read the dedicated
"Contributing" markdown file or your PR may be closed:
https://github.com/openai/codex/blob/main/docs/contributing.md

If your PR conforms to our contribution guidelines, replace this text
with a detailed and high quality description of your changes.

Include a link to a bug report or enhancement request.

---------

Co-authored-by: Codex <noreply@openai.com>
2026-02-25 13:41:54 -08:00
Owen Lin
21f7032dbb feat(app-server): thread/unsubscribe API (#10954)
Adds a new v2 app-server API for a client to be able to unsubscribe to a
thread:
- New RPC method: `thread/unsubscribe`
- New server notification: `thread/closed`

Today clients can start/resume/archive threads, but there wasn’t a way
to explicitly unload a live thread from memory without archiving it.
With `thread/unsubscribe`, a client can indicate it is no longer
actively working with a live Thread. If this is the only client
subscribed to that given thread, the thread will be automatically closed
by app-server, at which point the server will send `thread/closed` and
`thread/status/changed` with `status: notLoaded` notifications.

This gives clients a way to prevent long-running app-server processes
from accumulating too many thread (and related) objects in memory.

Closed threads will also be removed from `thread/loaded/list`.
2026-02-25 13:14:30 -08:00
sayan-oai
d45ffd5830 make 5.3-codex visible in cli for api users (#12808)
5.3-codex released in api, mark it visible for API users via bundled
`models.json`.
2026-02-25 13:01:40 -08:00
Michael Bolin
be5bca6f8d fix: harden zsh fork tests and keep subcommand approvals deterministic (#12809)
## Why
The prior
`turn_start_shell_zsh_fork_subcommand_decline_marks_parent_declined_v2`
assertion was brittle under Bazel: command approval payloads in the test
could include environment-dependent wrapper/command formatting
differences, which makes exact command-string matching flaky even when
behavior is correct.

(This regression was knowingly introduced in
https://github.com/openai/codex/pull/12800, but it was urgent to land
that PR.)

## What changed
- Hardened
`turn_start_shell_zsh_fork_subcommand_decline_marks_parent_declined_v2`
in
[`turn_start_zsh_fork.rs`](https://github.com/openai/codex/blob/main/codex-rs/app-server/tests/suite/v2/turn_start_zsh_fork.rs):
- Replaced strict `approval_command.starts_with("/bin/rm")` checks with
intent-based subcommand matching.
- Subcommand approvals are now recognized by file-target semantics
(`first.txt` or `second.txt`) plus `rm` intent.
- Parent approval recognition is now more tolerant of command-format
differences while still requiring a definitive parent command context.
- Uses a defensive loop that waits for all target subcommand decisions
and the parent approval request.
- Preserved the existing regression and unit test fixes from earlier
commits in `unix_escalation.rs` and `skill_approval.rs`.

## Verification
- Ran the zsh fork subcommand decline regression under this change:
-
`turn_start_shell_zsh_fork_subcommand_decline_marks_parent_declined_v2`
- Confirmed the test is now robust against approval-command-string
variation instead of hardcoding one expected command shape.
2026-02-25 12:23:30 -08:00
Eric Traut
f6fdfbeb98 Update Codex docs success link (#12805)
Fix a stale documentation link in the sign-in flow
2026-02-25 12:02:41 -08:00
Ahmed Ibrahim
3f30746237 Add simple realtime text logs (#12807)
Update realtime debug logs to include the actual text payloads in both
input and output paths.

- In `core/src/realtime_conversation.rs`:
- `handle_start`: add extracted assistant text output to the
`[realtime-text]` debug log.
- `handle_text`: add incoming text input (`params.text`) to the
`[realtime-text]` debug log.

No tests were run (per request).
2026-02-25 12:01:48 -08:00
Owen Lin
a0fd94bde6 feat(app-server): add ThreadItem::DynamicToolCall (#12732)
Previously, clients would call `thread/start` with dynamic_tools set,
and when a model invokes a dynamic tool, it would just make the
server->client `item/tool/call` request and wait for the client's
response to complete the tool call. This works, but it doesn't have an
`item/started` or `item/completed` event.

Now we are doing this:
- [new] emit `item/started` with `DynamicToolCall` populated with the
call arguments
- send an `item/tool/call` server request
- [new] once the client responds, emit `item/completed` with
`DynamicToolCall` populated with the response.

Also, with `persistExtendedHistory: true`, dynamic tool calls are now
reconstructable in `thread/read` and `thread/resume` as
`ThreadItem::DynamicToolCall`.
2026-02-25 12:00:10 -08:00
Rasmus Rygaard
73eaebbd1c Propagate session ID when compacting (#12802)
We propagate the session ID when sending requests for inference but we
don't do the same for compaction requests. This makes it hard to link
compaction requests to their session for debugging purposes
2026-02-25 19:17:38 +00:00
Michael Bolin
648a420cbf fix: enforce sandbox envelope for zsh fork execution (#12800)
## Why
Zsh fork execution was still able to bypass the `WorkspaceWrite` model
in edge cases because the fork path reconstructed command execution
without preserving sandbox wrappers, and command extraction only
accepted shell invocations in a narrow positional shape. This can allow
commands to run with broader filesystem access than expected, which
breaks the sandbox safety model.

## What changed
- Preserved the sandboxed `ExecRequest` produced by
`attempt.env_for(...)` when entering the zsh fork path in
[`unix_escalation.rs`](https://github.com/openai/codex/blob/main/codex-rs/core/src/tools/runtimes/shell/unix_escalation.rs).
- Updated `CoreShellCommandExecutor` to execute the sandboxed command
and working directory captured from `attempt.env_for(...)`, instead of
re-running a freshly reconstructed shell command.
- Made zsh-fork script extraction robust to wrapped invocations by
scanning command arguments for `-c`/`-lc` rather than only matching the
first positional form.
- Added unit tests in `unix_escalation.rs` to lock in wrapper-tolerant
parsing behavior and keep unsupported shell forms rejected.
- Tightened the regression in
[`skill_approval.rs`](https://github.com/openai/codex/blob/main/codex-rs/core/tests/suite/skill_approval.rs):
- `shell_zsh_fork_still_enforces_workspace_write_sandbox` now uses an
explicit `WorkspaceWrite` policy with `exclude_tmpdir_env_var: true` and
`exclude_slash_tmp: true`.
- The test attempts to write to `/tmp/...`, which is only reliably
outside writable roots with those explicit exclusions set.

## Verification
- Added and passed the new unit tests around `extract_shell_script`
parsing behavior with wrapped command shapes.
  - `extract_shell_script_supports_wrapped_command_prefixes`
  - `extract_shell_script_rejects_unsupported_shell_invocation`
- Verified the regression with the focused integration test:
`shell_zsh_fork_still_enforces_workspace_write_sandbox`.

## Manual Testing

Prior to this change, if I ran Codex via:

```
just codex --config zsh_path=/Users/mbolin/code/codex2/codex-rs/app-server/tests/suite/zsh --enable shell_zsh_fork
```

and asked:

```
what is the output of /bin/ps
```

it would run it, even though the default sandbox should prevent the
agent from running `/bin/ps` because it is setuid on MacOS.

But with this change, I now see the expected failure because it is
blocked by the sandbox:

```
/bin/ps exited with status 1 and produced no output in this environment.
```
2026-02-25 11:05:27 -08:00
pakrym-oai
9d7013eab0 Handle websocket timeout (#12791)
Sometimes websockets will timeout with 400 error, ensure we retry it.
2026-02-25 10:31:37 -08:00
jif-oai
7b39e76a66 Revert "fix(bazel): replace askama templates with include_str! in memories" (#12795)
Reverts openai/codex#11778
2026-02-25 18:06:17 +00:00
Ahmed Ibrahim
947092283a Add app-server v2 thread realtime API (#12715)
Add experimental `thread/realtime/*` v2 requests and notifications, then
route app-server realtime events through that thread-scoped surface with
integration coverage.

---------

Co-authored-by: Codex <noreply@openai.com>
2026-02-25 09:59:10 -08:00
Curtis 'Fjord' Hawthorne
0543d0a022 Promote js_repl to experimental with Node requirement (#12712)
## Summary

- Promote `js_repl` to an experimental feature that users can enable
from `/experimental`.
- Add `js_repl` experimental metadata, including the Node prerequisite
and activation guidance.
- Add regression coverage for the feature metadata and the
`/experimental` popup.

## What Changed

- Changed `Feature::JsRepl` from `Stage::UnderDevelopment` to
`Stage::Experimental`.
- Added experimental metadata for `js_repl` in `core/src/features.rs`:
  - name: `JavaScript REPL`
- description: calls out interactive website debugging, inline
JavaScript execution, and the required Node version (`>= v24.13.1`)
- announcement: tells users to enable it, then start a new chat or
restart Codex
- Added a core unit test that verifies:
  - `js_repl` is experimental
  - `js_repl` is disabled by default
- the hardcoded Node version in the description matches
`node-version.txt`
- Added a TUI test that opens the `/experimental` popup and verifies the
rendered `js_repl` entry includes the Node requirement text.

## Testing

- `just fmt`
- `cargo test -p codex-tui`
- `cargo test -p codex-core` (unit-test phase passed; stopped during the
long `tests/all.rs` integration suite)
2026-02-25 09:44:52 -08:00
mcgrew-oai
9a393c9b6f feat(network-proxy): add embedded OTEL policy audit logging (#12046)
**PR Summary**

This PR adds embedded-only OTEL policy audit logging for
`codex-network-proxy` and threads audit metadata from `codex-core` into
managed proxy startup.

### What changed
- Added structured audit event emission in `network_policy.rs` with
target `codex_otel.network_proxy`.
- Emitted:
- `codex.network_proxy.domain_policy_decision` once per domain-policy
evaluation.
  - `codex.network_proxy.block_decision` for non-domain denies.
- Added required policy/network fields, RFC3339 UTC millisecond
`event.timestamp`, and fallback defaults (`http.request.method="none"`,
`client.address="unknown"`).
- Added non-domain deny audit emission in HTTP/SOCKS handlers for
mode-guard and proxy-state denies, including unix-socket deny paths.
- Added `REASON_UNIX_SOCKET_UNSUPPORTED` and used it for unsupported
unix-socket auditing.
- Added `NetworkProxyAuditMetadata` to runtime/state, re-exported from
`lib.rs` and `state.rs`.
- Added `start_proxy_with_audit_metadata(...)` in core config, with
`start_proxy()` delegating to default metadata.
- Wired metadata construction in `codex.rs` from session/auth context,
including originator sanitization for OTEL-safe tagging.
- Updated `network-proxy/README.md` with embedded-mode audit schema and
behavior notes.
- Refactored HTTP block-audit emission to a small local helper to reduce
duplication.
- Preserved existing unix-socket proxy-disabled host/path behavior for
responses and blocked history while using an audit-only endpoint
override (`server.address="unix-socket"`, `server.port=0`).

### Explicit exclusions
- No standalone proxy OTEL startup work.
- No `main.rs` binary wiring.
- No `standalone_otel.rs`.
- No standalone docs/tests.

### Tests
- Extended `network_policy.rs` tests for event mapping, metadata
propagation, fallbacks, timestamp format, and target prefix.
- Extended HTTP tests to assert unix-socket deny block audit events.
- Extended SOCKS tests to cover deny emission from handler deny
branches.
- Added/updated core tests to verify audit metadata threading into
managed proxy state.

### Validation run
- `just fmt`
- `cargo test -p codex-network-proxy` 
- `cargo test -p codex-core` ran with one unrelated flaky timeout
(`shell_snapshot::tests::snapshot_shell_does_not_inherit_stdin`), and
the test passed when rerun directly 

---------

Co-authored-by: viyatb-oai <viyatb@openai.com>
2026-02-25 11:46:37 -05:00
jif-oai
8362b79cb4 feat: fix sqlite home (#12787) 2026-02-25 15:52:55 +00:00
jif-oai
01f25a7b96 chore: unify max depth parameter (#12770)
Users were confused
2026-02-25 15:20:24 +00:00
mcgrew-oai
bccce0d75f otel: add host.name resource attribute to logs/traces via gethostname (#12352)
**PR Summary**

This PR adds the OpenTelemetry `host.name` resource attribute to Codex
OTEL exports so every OTEL log (and trace, via the shared resource)
carries the machine hostname.

**What changed**

- Added `host.name` to the shared OTEL `Resource` in
`/Users/michael.mcgrew/code/codex/codex-rs/otel/src/otel_provider.rs`
  - This applies to both:
    - OTEL logs (`SdkLoggerProvider`)
    - OTEL traces (`SdkTracerProvider`)
- Hostname is now resolved via `gethostname::gethostname()`
(best-effort)
  - Value is trimmed
  - Empty values are omitted (non-fatal)
- Added focused unit tests for:
  - including `host.name` when present
  - omitting `host.name` when missing/empty

**Why**

- `host.name` is host/process metadata and belongs on the OTEL
`resource`, not per-event attributes.
- Attaching it in the shared resource is the smallest change that
guarantees coverage across all exported OTEL logs/traces.

**Scope / Non-goals**

- No public API changes
- No changes to metrics behavior (this PR only updates log/trace
resource metadata)

**Dependency updates**

- Added `gethostname` as a workspace dependency and `codex-otel`
dependency
- `Cargo.lock` updated accordingly
- `MODULE.bazel.lock` unchanged after refresh/check

**Validation**

- `just fmt`
- `cargo test -p codex-otel`
- `just bazel-lock-update`
- `just bazel-lock-check`
2026-02-25 09:54:45 -05:00
jif-oai
8d49e0d0c4 nit: migration (#12772) 2026-02-25 13:56:52 +00:00
jif-oai
e4bfa763f6 feat: record memory usage (#12761) 2026-02-25 13:48:40 +00:00
jif-oai
5441130e0a feat: adding stream parser (#12666)
Add a stream parser to extract citations (and others) from a stream.
This support cases where markers are split in differen tokens.

Codex never manage to make this code work so everything was done
manually. Please review correctly and do not touch this part of the code
without a very clear understanding of it
2026-02-25 13:27:58 +00:00
jif-oai
5a9a5b51b2 feat: add large stack test macro (#12768)
This PR adds the macro `#[large_stack_test]`

This spawns the tests in a dedicated tokio runtime with a larger stack.
It is useful for tests that needs the full recursion on the harness
(which is now too deep for windows for example)
2026-02-25 13:19:21 +00:00
jif-oai
bcd6e68054 Display pending child-thread approvals in TUI (#12767)
Summary
- propagate approval policy from parent to spawned agents and drop the
Never override so sub-agents respect the caller’s request
- refresh the pending-approval list whenever events arrive or the active
thread changes and surface the list above the composer for inactive
threads
- add widgets, helpers, and tests covering the new pending-thread
approval UI state

![Uploading Screenshot 2026-02-25 at 11.02.18.png…]()
2026-02-25 11:40:11 +00:00
Michael Bolin
93efcfd50d feat: record whether a skill script is approved for the session (#12756)
## Why

`unix_escalation.rs` checks a session-scoped approval cache before
prompting again for an execve-intercepted skill script. Without also
recording `ReviewDecision::ApprovedForSession`, that cache never gets
populated, so the same skill script can still trigger repeated approval
prompts within one session.

## What Changed

- Add `execve_session_approvals` to `SessionServices` so the session can
track approved skill script paths.
- Record the script path when a skill-script prompt returns
`ReviewDecision::ApprovedForSession`, but only for the skill-script path
rather than broader prefix-rule approvals.
- Reuse the cached approval on later execve callbacks by treating an
already-approved skill script as `Decision::Allow`.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/12756).
* #12758
* __->__ #12756
2026-02-25 10:17:22 +00:00
alexsong-oai
6d6570d89d Support external agent config detect and import (#12660)
Migration Behavior

* Config
  *  Migrates settings.json into config.toml
* Only adds fields when config.toml is missing, or when those fields are
missing from the existing file
  *  Supported mappings:
    env -> shell_environment_policy
     sandbox.enabled = true -> sandbox_mode = "workspace-write"

* Skills
  *  Copies home and repo .claude/skills into .agents/skills
  *  Existing skill directories are not overwritten
  *  SKILL.md content is rewritten from Claude-related terms to Codex

* AgentsMd
  *  Repo only
  *  Migrates CLAUDE.md into AGENTS.md
* Detect/import only proceed when AGENTS.md is missing or present but
empty
  *  Content is rewritten from Claude-related terms to Codex
2026-02-25 02:11:51 -08:00
jif-oai
f46b767b7e 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`)
2026-02-25 09:59:41 +00:00
jif-oai
a046849438 fix: flaky test due to second-resolution for thread ordering (#12692) 2026-02-25 09:59:25 +00:00
jif-oai
10c04e11b8 feat: add service name to app-server (#12319)
Add service name to the app-server so that the app can use it's own
service name

This is on thread level because later we might plan the app-server to
become a singleton on the computer
2026-02-25 09:51:42 +00:00
Celia Chen
6a3233da64 Surface skill permission profiles in zsh-fork exec approvals (#12753)
## Summary

- Preserve each skill’s raw permissions block as a permission_profile on
SkillMetadata during skill loading.
- Keep compiling that same metadata into the existing runtime
Permissions object, so current enforcement
    behavior stays intact.
- When zsh-fork intercepts execution of a script that belongs to a
skill, include the skill’s
    permission_profile in the exec approval request.
- This lets approval UIs show the extra filesystem access the skill
declared when prompting for approval.
2026-02-25 01:23:10 -08:00
Michael Bolin
c4ec6be4ab fix: keep shell escalation exec paths absolute (#12750)
## Why

In the `shell_zsh_fork` flow, `codex-shell-escalation` receives the
executable path exactly as the shell passed it to `execve()`. That path
is not guaranteed to be absolute.

For commands such as `./scripts/hello-mbolin.sh`, if the shell was
launched with a different `workdir`, resolving the intercepted `file`
against the server process working directory makes policy checks and
skill matching inspect the wrong executable. This change pushes that fix
a step further by keeping the normalized path typed as `AbsolutePathBuf`
throughout the rest of the escalation pipeline.

That makes the absolute-path invariant explicit, so later code cannot
accidentally treat the resolved executable path as an arbitrary
`PathBuf`.

## What Changed

- record the wrapper process working directory as an `AbsolutePathBuf`
- update the escalation protocol so `workdir` is explicitly absolute
while `file` remains the raw intercepted exec path
- resolve a relative intercepted `file` against the request `workdir` as
soon as the server receives the request
- thread `AbsolutePathBuf` through `EscalationPolicy`,
`CoreShellActionProvider`, and command normalization helpers so the
resolved executable path stays type-checked as absolute
- replace the `path-absolutize` dependency in `codex-shell-escalation`
with `codex-utils-absolute-path`
- add a regression test that covers a relative `file` with a distinct
`workdir`

## Verification

- `cargo test -p codex-shell-escalation`
2026-02-24 23:52:36 -08:00
Michael Bolin
59398125f6 feat: zsh-fork forces scripts/**/* for skills to trigger a prompt (#12730)
Direct skill-script matches force `Decision::Prompt`, so skill-backed
scripts require explicit approval before they run. (Note "allow for
session" is not supported in this PR, but will be done in a follow-up.)

In the process of implementing this, I fixed an important bug:
`ShellZshFork` is supposed to keep ordinary allowed execs on the
client-side `Run` path so later `execve()` calls are still intercepted
and reviewed. After the shell-escalation port, `Decision::Allow` still
mapped to `Escalate`, which moved `zsh` to server-side execution too
early. That broke the intended flow for skill-backed scripts and made
the approval prompt depend on the wrong execution path.

## What changed
- In `codex-rs/core/src/tools/runtimes/shell/unix_escalation.rs`,
`Decision::Allow` now returns `Run` unless escalation is actually
required.
- Removed the zsh-specific `argv[0]` fallback. With the `Allow -> Run`
fix in place, zsh's later `execve()` of the script is intercepted
normally, so the skill match happens on the script path itself.
- Kept the skill-path handling in `determine_action()` focused on the
direct `program` match path.

## Verification
- Updated `shell_zsh_fork_prompts_for_skill_script_execution` in
`codex-rs/core/tests/suite/skill_approval.rs` (gated behind `cfg(unix)`)
to:
- run under `SandboxPolicy::new_workspace_write_policy()` instead of
`DangerFullAccess`
  - assert the approval command contains only the script path
- assert the approved run returns both stdout and stderr markers in the
shell output
- Ran `cargo test -p codex-core
shell_zsh_fork_prompts_for_skill_script_execution -- --nocapture`

## Manual Testing

Run the dev build:

```
just codex --config zsh_path=/Users/mbolin/code/codex2/codex-rs/app-server/tests/suite/zsh --enable shell_zsh_fork
```

I have created `/Users/mbolin/.agents/skills/mbolin-test-skill` with:

```
├── scripts
│   └── hello-mbolin.sh
└── SKILL.md
```

The skill:

```
---
name: mbolin-test-skill
description: Used to exercise various features of skills.
---

When this skill is invoked, run the `hello-mbolin.sh` script and report the output.
```

The script:

```
set -e

# Note this script will fail if run with network disabled.
curl --location openai.com
```

Use `$mbolin-test-skill` to invoke the skill manually and verify that I
get prompted to run `hello-mbolin.sh`.

---
[//]: # (BEGIN SAPLING FOOTER)
Stack created with [Sapling](https://sapling-scm.com). Best reviewed
with [ReviewStack](https://reviewstack.dev/openai/codex/pull/12730).
* #12750
* __->__ #12730
2026-02-24 23:51:26 -08:00
viyatb-oai
c086b36b58 feat(ui): add network approval persistence plumbing (#12358)
## Summary
- add TUI approval options for persistent network host rules
- add app-server v2 approval payload plumbing for network approval
context + proposed network policy amendments
- add app-server handling to translate `applyNetworkPolicyAmendment`
decisions back into core review decisions
- update docs/test client output and generated app-server schemas/types
2026-02-25 07:06:19 +00:00
Curtis 'Fjord' Hawthorne
9501669a24 tests(js_repl): remove node-related skip paths from js_repl tests (#12185)
## Summary
Remove js_repl/node test-skip paths and make Node setup explicit in CI
so js_repl tests always run instead of silently skipping.

## Why
We had multiple “expediency” skip paths that let js_repl tests pass
without actually exercising Node-backed behavior. This reduced CI signal
and hid runtime/environment regressions.

## What changed

### CI
- Added Node setup using `codex-rs/node-version.txt` in:
  - `.github/workflows/rust-ci.yml`
  - `.github/workflows/bazel.yml`
- Added a Unix PATH copy step in Bazel workflow to expose the setup-node
binary in common paths.

### js_repl test harness
- Added explicit js_repl sandbox test configuration helpers in:
  - `codex-rs/core/src/tools/js_repl/mod.rs`
  - `codex-rs/core/src/tools/handlers/js_repl.rs`
- Added Linux arg0 dispatch glue for js_repl tests so sandbox subprocess
entrypoint behavior is correct under Linux test execution.

### Removed skip behavior
- Deleted runtime guard function and early-return skips in js_repl tests
(`can_run_js_repl_runtime_tests` and related per-test short-circuits).
- Removed view_image integration test skip behavior:
  - dropped `skip_if_no_network!(Ok(()))`
- removed “skip on Node missing/too old” branch after js_repl output
inspection.

## Impact
- js_repl/node tests now consistently execute and fail loudly when the
environment is not correctly provisioned.
- CI has stronger signal for js_repl regressions instead of false green
from conditional skips.

## Testing
- `cargo test -p codex-core` (locally) to validate js_repl
unit/integration behavior with skips removed.
- CI expected to surface any remaining environment/runtime gaps directly
(rather than masking them).


#### [git stack](https://github.com/magus/git-stack-cli)
-  `1` https://github.com/openai/codex/pull/12300
-  `2` https://github.com/openai/codex/pull/12275
-  `3` https://github.com/openai/codex/pull/12205
-  `4` https://github.com/openai/codex/pull/12407
-  `5` https://github.com/openai/codex/pull/12372
- 👉 `6` https://github.com/openai/codex/pull/12185
-  `7` https://github.com/openai/codex/pull/10673
2026-02-24 22:52:14 -08:00