Skip to content

checkpoint: into wallentx/termux-target from release/0.140.0 @ 7ba55d754ec8 - #223

Merged
wallentx merged 37 commits into
wallentx/termux-targetfrom
checkpoint/wallentx_termux-target_from_release_0.140.0_7ba55d754ec8
Jun 13, 2026
Merged

checkpoint: into wallentx/termux-target from release/0.140.0 @ 7ba55d754ec8#223
wallentx merged 37 commits into
wallentx/termux-targetfrom
checkpoint/wallentx_termux-target_from_release_0.140.0_7ba55d754ec8

Conversation

@unemployabot

@unemployabot unemployabot Bot commented Jun 13, 2026

Copy link
Copy Markdown

Termux release checkpoint

  • Source branch: release/0.140.0
  • Source hash: 7ba55d754ec86158ed30b3841924454a6455e8eb
  • Destination branch: wallentx/termux-target
  • Remaining first-parent commits on source: 0

This PR carries release-train conflict fixes and follow-up changes back into the reusable Termux patch branch.

Release-only workflow files and metadata under .github were restored to the destination branch versions before opening this PR.

anp-oai and others added 30 commits June 12, 2026 11:38
## Why

Sandbox cwd values can cross app-server and exec-server host boundaries.
They should retain URI semantics until the receiving host validates them
instead of being interpreted early as native paths.

## What

- Carry `PathUri` through filesystem sandbox contexts, sandbox commands,
and transform inputs.
- Convert command and policy cwd once in `SandboxManager::transform`,
then keep launch requests native.
- Preserve sandbox cwd over remote filesystem transport and reject
non-native URIs without fallback.
- Cache paired native/URI turn-environment cwd values during migration,
with immutable access to keep them synchronized.
- Extend existing protocol, forwarding, transform, and core runtime
tests.
## Summary

- expose the remote plugin detail endpoint's `share_url` as nullable
`PluginDetail.shareUrl`
- preserve existing `PluginSummary.shareContext` behavior for local and
workspace sharing flows
- regenerate the app-server TypeScript and JSON schema fixtures

## Why

The remote plugin detail response already includes a canonical
`share_url`, but that value was not surfaced by `plugin/read` for global
plugins. Global plugins intentionally have no `shareContext`, so using
that model for the URL would change the semantics consumed by the
existing share modal.

## User impact

Codex clients can use `PluginDetail.shareUrl` for a remote plugin's
copy-link action, including when the plugin is disabled by an
administrator, without changing existing share-modal or ownership
behavior.

## Validation

- `cargo test -p codex-app-server
plugin_read_includes_share_url_for_admin_disabled_remote_plugin`
- `cargo test -p codex-app-server-protocol
typescript_schema_fixtures_match_generated`
- `cargo test -p codex-app-server-protocol
json_schema_fixtures_match_generated`
- `cargo fmt --all`
## Why

`apply_patch` maintained separate batch and streaming parsers for the
same patch grammar. That duplicated the parsing rules and allowed final
execution to disagree with the live streamed preview.

## What changed

- Make `StreamingPatchParser` the single owner of hunk and environment
ID parsing.
- Keep heredoc and outer patch-boundary normalization in the existing
`parse_patch` wrapper, preserving its public API.
- Reject non-whitespace content after `*** End Patch` and preserve
separator handling after `*** End of File`.
- Reject duplicate environment ID preambles explicitly.
- Remove the duplicate batch hunk parser and its implementation-specific
tests.

The change removes 201 net lines while retaining focused coverage for
the unified parser's boundary behavior.

## Validation

- `just test -p codex-apply-patch`
- Compared a 24-hour corpus of 2,788,059 observed `apply_patch` payloads
against the previous batch parser. All 2,779,502 accepted payloads
produced identical hunks, canonical patch text, and environment IDs; the
remaining 8,557 payloads were rejected by both parsers, with zero
acceptance or payload mismatches.
…#27920)

## Why

Standalone image generation emitted a started item but no terminal item
when the backend failed. Clients could leave the operation unresolved or
render it as successful.

## What changed

- Emit a terminal image-generation item with `status: "failed"` when
generation or editing fails.
- Skip image persistence for failed terminal items.
- Render failed image generation distinctly in TUI history.
- Preserve the status when handling live and replayed terminal items.

## Looks for TUI, App-Side change needed 

<img width="867" height="89" alt="image"
src="https://github.com/user-attachments/assets/9e32342f-a982-411e-8498-456639fc468a"
/>

## Validation

- `just test -p codex-image-generation-extension`
- App-server image-generation tests
- Core stream-event tests
- TUI image-generation lifecycle and snapshot tests
- Scoped Clippy and formatting
## Why

`ExecutorFileSystem::get_metadata` reports file kind and timestamps but
not size. Internal callers that need to enforce a size limit therefore
have to read the complete file first, which is especially wasteful for
remote filesystems.

This adds the missing internal metadata so consumers can reject
oversized files before transferring or buffering them. The field is
named `size`, matching VS Code's `FileStat.size` filesystem convention.

## What changed

- add `size: u64` to internal `FileMetadata`
- populate it from the underlying filesystem metadata
- carry it through sandbox-helper and remote exec-server responses
- cover files, directories, symlink targets, and sandboxed reads across
local and remote filesystem implementations

The new field is intentionally not exposed through the app-server API.

## Testing

- `just test -p codex-exec-server get_metadata`
- `just test -p codex-exec-server
file_system_sandboxed_metadata_and_read_allow_readable_root`
- `just test -p codex-core-plugins`
- `just test -p codex-skills-extension`
## Why

Windows Credential Manager limits generic credential blobs to 2,560
bytes. The encrypted local secrets backend avoids storing large
serialized auth payloads directly in the OS keyring, but selecting that
backend needs an independently reviewable feature/config layer before
the auth and secrets implementation is wired in.

## What Changed

- Added the stable `secret_auth_storage` feature, enabled by default on
Windows and disabled by default elsewhere.
- Added `AuthKeyringBackendKind` and config resolution for full and
bootstrap config loading.
- Applied managed feature requirements when resolving the bootstrap auth
backend.
- Updated the generated config schema and added focused tests.

This is the base PR for openai#17931. The auth, secrets, MCP, CLI, TUI, and
app-server implementation remains in that follow-up PR.

## Validation

- `just test -p codex-features`
- `just test -p codex-config`
- `just test -p codex-core
resolve_bootstrap_auth_keyring_backend_kind_uses_secret_auth_storage_feature`
- `just write-config-schema`
- `just fix -p codex-core`

The full `just test -p codex-core` run compiled successfully and ran
2,690 tests; 2,589 passed, one was flaky, and 101 environment-sensitive
tests failed because this shell injects a `pyenv` rehash warning into
command output or because sandboxed subprocesses timed out.
## Why

`codex login` previously persisted newly issued OAuth credentials and
only then attempted to revoke the superseded refresh token. The old
credential must be revoked before a replacement browser or device-code
flow starts, and successful login must not perform any post-login
revocation attempt.

## What changed

- Revoke and clear existing stored auth before browser or device-code
CLI login begins.
- Remove superseded-token detection and revocation from the shared token
persistence path; successful login now only saves the new credentials.
- Read the raw configured auth store during CLI cleanup so
environment-provided auth cannot mask the stored refresh token.
- Preserve `auto` storage fallback semantics when keyring deletion fails
by clearing the fallback auth file.
- Add a process-level CLI regression test that requires the revoke
request to precede every device-login request and occur exactly once.

If replacement login is canceled or fails, the previous local
credentials have already been cleared. Remote revocation remains best
effort, matching explicit logout behavior.

## Validation

### Process-level before/after reproduction

I compiled the real `codex` CLI from the pre-fix parent (`14df0e8833`)
and from the PR implementation (`25c002f23b`; the login behavior is
unchanged at the current head), then ran the same device-code flow
against a local HTTP mock OAuth authority.

Each run:

1. Used a fresh temporary `CODEX_HOME` configured with
`cli_auth_credentials_store = "file"`.
2. Seeded that temporary home with managed ChatGPT auth containing
`old-access` and `old-refresh` tokens.
3. Pointed `CODEX_REVOKE_TOKEN_URL_OVERRIDE` at the mock `/oauth/revoke`
endpoint.
4. Ran the compiled CLI as:

   ```shell
   CODEX_HOME=<temporary-home> \
     CODEX_REVOKE_TOKEN_URL_OVERRIDE=<mock-issuer>/oauth/revoke \
<compiled-codex> login --device-auth --experimental_issuer <mock-issuer>
   ```

5. Recorded every request received by the mock authority. The mock
marked `new-access` valid when `/oauth/token` issued it and invalidated
it if `/oauth/revoke` arrived afterward, reproducing the observed
session-invalidating failure mode. After login exited, the harness also
verified the persisted refresh token and probed a protected endpoint
with `new-access`.

| Build | Observed request order | CLI/persistence result | `new-access`
probe |
| --- | --- | --- | --- |
| Pre-fix | `usercode → device token → OAuth token →
revoke(old-refresh)` | Exit `0`; `new-refresh` persisted | `401` |
| PR | `revoke(old-refresh) → usercode → device token → OAuth token` |
Exit `0`; `new-refresh` persisted | `200` |

The PR run therefore issued exactly one revocation request, before any
request that initiated the replacement login, and issued no revocation
after token exchange.

### Regression coverage


`codex-rs/cli/tests/login.rs::device_login_revokes_existing_auth_before_requesting_new_tokens`
runs the real first-party `codex` binary against a `wiremock` OAuth
server with an isolated temporary `CODEX_HOME`. It asserts:

- the exact request sequence is `/oauth/revoke`,
`/api/accounts/deviceauth/usercode`, `/api/accounts/deviceauth/token`,
then `/oauth/token`;
- there is exactly one revoke request and its body contains
`old-refresh` with the `refresh_token` hint;
- the completed login persists `new-refresh`.

Local validation:

- `just test -p codex-login` — 130 passed
- `just test -p codex-cli` — 280 passed, including the new process-level
regression test
- `just bazel-lock-check`
## Why

CLI auth and MCP OAuth credentials should use separate encrypted files
while sharing the existing local-secrets implementation and
OS-keyring-backed encryption key mechanism.

This is the second PR in the encrypted-auth stack:

1. openai#27504 — feature and config selection
2. This PR — auth-specific local-secrets namespaces
3. CLI auth implementation and activation
4. MCP OAuth implementation and activation

## What Changed

- Added `LocalSecretsNamespace` variants for shared secrets, CLI auth,
and MCP OAuth.
- Selected `local.age`, `cli_auth.age`, or `mcp_oauth.age` from the
namespace.
- Made atomic temporary filenames derive from the selected secrets
filename.
- Added namespaced `SecretsManager` construction and coverage proving
the auth namespaces write separate encrypted files.
- Made the default keyring store clonable for downstream namespaced auth
backends.

This PR does not activate either auth backend or change existing
credential behavior.

## Validation

- `just test -p codex-secrets` — 7 passed
- `just test -p codex-keyring-store` — package has no test binaries
- `just fmt`
## Why

Review guidance should explicitly discourage widening crate APIs for
testing convenience. Keeping those boundaries narrow reduces accidental
coupling and prevents one-off test utilities from becoming durable
public surface area.

## What

- Add a crate API surface rule to `AGENTS.md`.
- Ask reviewers to keep crate APIs small and avoid proliferating
test-only helpers.

## Test plan

- Not run (documentation-only change).
## Summary
- reuse the shared shell read parser for implicit skill doc invocation
detection
- add regression coverage for `nl -ba .../SKILL.md`

## Why
Desktop could render `Read User Context skill` for reads recognized by
the shared command parser, while implicit `skill_invocation` analytics
used a separate reader allowlist and missed cases such as `nl`.

## Validation
- `HOME=/private/tmp/codex-core-skills-home-pr
PATH=/Users/alexsong/.cache/cargo-home/bin:$PATH
CARGO_HOME=/Users/alexsong/.cache/cargo-home just test -p
codex-core-skills`
- `git diff --cached --check`
- `just fmt` attempted; Rust formatting completed, but the Python
formatters could not download uncached Ruff wheels because
`files.pythonhosted.org` is blocked in this sandbox.
- `bazel mod deps --lockfile_mode=update/error
--repo_env=ASPECT_TOOLS_TELEMETRY= --repo_env=DO_NOT_TRACK=1` evaluated
the module graph and produced no `MODULE.bazel.lock` diff, but Bazel
crashed on sandboxed `sysctl` during exit.
## Summary
Removes Plugin descriptions from the dev message, since descriptions of
skills and MCPs cover the capabilities offered by the plugin.

## Testing
- [x] Updates unit tests
## Why

Multi-agent v2 `send_message` deliveries already reach the receiving
model as typed `agent_message` items with encrypted content.
Child-completion notifications are generated by Codex itself, so their
content is plaintext and previously fell back to a serialized JSON
envelope inside an assistant message.

With plaintext `input_text` supported for `agent_message`, both delivery
paths can use the same model-visible type while preserving explicit
author and recipient metadata.

## What changed

- add plaintext `input_text` support to `AgentMessageInputContent` and
regenerate the affected app-server schemas
- preserve `InterAgentCommunication` as structured mailbox input instead
of converting it to assistant text
- record delivered communications as typed `agent_message` history items
- persist a dedicated rollout item so local delivery metadata such as
`trigger_turn` remains available without leaking into the Responses
request
- reconstruct typed agent messages on resume and preserve fork-turn
truncation behavior
- remove request-time assistant-content parsing
- preserve plaintext and encrypted inter-agent deliveries in stage-one
memory inputs
- normalize and link plaintext and encrypted agent messages in rollout
traces without treating inbound messages as child results
- cover the real MultiAgent V2 child-completion path end to end with
deterministic mailbox synchronization

## Verification

- `just test -p codex-core
plaintext_multi_agent_v2_completion_sends_agent_message`
- `just test -p codex-core input_queue_drains_mailbox_in_delivery_order
record_initial_history_reconstructs_typed_inter_agent_message
fork_turn_positions_use_inter_agent_delivery_metadata`
- `just test -p codex-memories-write
serializes_inter_agent_communications_for_memory`
- `just test -p codex-rollout-trace
agent_messages_preserve_routing_and_content
sub_agent_started_activity_creates_spawn_edge`
- `just test -p codex-rollout-trace
agent_result_edge_falls_back_to_child_thread_without_result_message`
- `just test -p codex-protocol -p codex-rollout -p
codex-app-server-protocol`
## Why

Removes the realtime audio support from TUI.

## What Changed

- Removed the TUI `/realtime` and realtime `/settings` command paths.
- Deleted TUI voice capture/playback, WebRTC session handling,
audio-device selection UI, and recording-meter code.
- Removed TUI realtime tests and snapshots that covered the deleted
surfaces.
- Dropped the TUI-only `cpal` and `codex-realtime-webrtc` dependencies
and refreshed the Rust/Bazel locks.
## Why

Windows Credential Manager limits generic credential blobs to 2,560
bytes. Large serialized ChatGPT auth payloads can exceed that limit, so
keyring-mode CLI auth needs a backend that keeps only the encryption key
in the OS keyring and stores the payload in Codex's encrypted
local-secrets file.

This is the third PR in the encrypted-auth stack:

1. openai#27504 — feature and config selection
2. openai#27535 — auth-specific local-secrets namespaces
3. This PR — CLI auth implementation and activation
4. MCP OAuth implementation and activation

## What Changed

- Added encrypted CLI-auth storage using the `CliAuth` secrets
namespace.
- Preserved direct keyring storage for platforms/configurations where it
remains selected.
- Selected the backend consistently for login, logout, refresh,
device-code login, auth loading, and login restrictions.
- Threaded resolved bootstrap/full config through CLI, exec, TUI,
app-server account handling, cloud config, and cloud tasks.
- Removed stale `auth.json` fallback data after successful encrypted
saves and removed encrypted, direct-keyring, and fallback data during
logout.
- Added storage and integration coverage for both direct and encrypted
keyring modes.

MCP OAuth persistence is intentionally left to the next PR.

## Validation

- `just test -p codex-login` — 131 passed
- `just test -p codex-cli` — 280 passed
- `just test -p codex-app-server v2::account` — 25 passed
- `just test -p codex-cloud-config service` — 21 passed, 7 skipped
- `just fix -p codex-login`
- `just fix -p codex-cli`
- `just fmt`
## Summary
Startup warnings for under-development features only recognized bare
boolean toggles like `features.foo = true`. An upcoming feature will use
table-format config, so `features.foo = { enabled = true, ... }` needs
to count as an explicit opt-in too.

This updates the warning predicate to recognize structured tables with
`enabled = true`, while leaving tables without that field unwarned.

## Testing
- `just fmt`
- `just test -p codex-features
unstable_warning_event_mentions_enabled_structured_under_development_feature`
## Summary

- store MCP OAuth credentials in the configured auth credential backend
- support encrypted-local OAuth storage, including legacy keyring
migration
- propagate the credential backend through MCP refresh, session, CLI,
and app-server paths

## Stack

1. openai#27504 — config and feature flag
2. openai#27535 — auth-specific secret namespaces
3. openai#27539 — encrypted CLI auth storage
4. this PR — encrypted MCP OAuth storage

This is a parallel review stack; the original openai#17931 remains unchanged.

## Tests

- `just test -p codex-rmcp-client` (the transport round-trip test passed
after building the required `codex` binary and retrying)
- `just test -p codex-mcp`
- `just test -p codex-app-server
refresh_config_uses_latest_auth_keyring_backend`
- `just test -p codex-core
refresh_mcp_servers_is_deferred_until_next_turn`
- `just test -p codex-cli mcp`
- `just fix -p codex-rmcp-client -p codex-mcp -p codex-core -p codex-cli
-p codex-app-server -p codex-protocol`
- `just bazel-lock-check`
## Summary

Add an explicit `user` or `developer` role to
`thread/realtime/appendText` and propagate it through the realtime input
queue into `conversation.item.create`. Older JSON clients that omit the
field continue to default to `user`.

This lets app-provided context such as memory retain developer authority
without bypassing app-server through a renderer-owned data channel. The
app-server schemas, API documentation, and focused protocol and
websocket coverage are updated with the new contract.

The Codex Apps consumer is tracked in
[openai/openai#1025261](openai/openai#1025261).
## Stack

1. [1 of 3] Support long raw TUI goal objectives - openai#27508
2. **[2 of 3] Support long pasted text in TUI goals** - this PR
3. [3 of 3] Support images in TUI goals - openai#27510

## Why

Large text pasted into the TUI composer is represented as a paste
placeholder plus pending paste metadata. For `/goal`, preserving only
the visible placeholder is not enough: the agent would see a short
placeholder string instead of the actual pasted text, and the long-text
support from the first PR would never see the payload.

The TUI also needs to avoid writing stale sidecar files when a user
pastes a large block and then deletes its placeholder before submitting
the goal.

## What Changed

- Introduces a TUI `GoalDraft` for goal submissions so `/goal`, `/goal
edit`, and queued goal commands can carry objective text plus text
elements and pending paste payloads.
- Materializes active pasted-text placeholders to `pasted-text-N.txt`
files through the app-server filesystem path introduced in openai#27508.
- Rewrites active paste placeholders in the persisted objective to file
references, while leaving literal placeholder-looking text alone.
- Filters out deleted paste placeholders so otherwise-small goals do not
require `$CODEX_HOME` or remote filesystem writes.
- Preserves pending paste metadata when a `/goal` command is queued
before a thread exists.

## Verification

- Added goal materialization tests for active paste placeholders,
deleted paste placeholders, and whitespace-only paste payloads.
- Added/updated TUI slash-command tests for large pasted text, queued
`/goal` commands before thread start, and queued oversized goal
behavior.

## Manual Testing

- Used real terminal bracketed-paste sequences through a remote TUI
session. A 1,228-byte multiline paste became `pasted-text-1.txt`; its
first/last lines and byte count matched exactly, and the persisted
objective referenced the server-host path.
- Pasted a large block, deleted its placeholder, and submitted a small
replacement objective. No new directory or sidecar file was created.
- Added two same-length large pastes to one goal. The composer
disambiguated their visible placeholders, and materialization preserved
order and contents in `pasted-text-1.txt` and `pasted-text-2.txt`.
- Submitted a whitespace-only large paste and verified the goal was
rejected as empty without writing a file.
- Submitted a pasted-text replacement while another goal was active,
verified no file was written before confirmation, then canceled and
confirmed the original goal remained unchanged.
- Combined a large paste with enough raw text to exceed 4,000 characters
after placeholder rewriting. The paste sidecar and `goal-objective.md`
were created in the same remote attachment directory, and `/goal edit`
restored the rewritten objective with its sidecar reference.
## Why

We need request-level evidence for Guardian cases where
`codex-auto-review` is missing from the client-side model catalog and
the review falls back to the parent model.

## What changed

- Add `guardian_catalog_contains_auto_review` to Guardian Responses API
client metadata.
- Add `guardian_model_provider_id` to Guardian Responses API client
metadata.
- Keep review-session metadata optional so callers without metadata
preserve the existing `None` path.
- Add tests for override, normal preferred-model, and
missing-auto-review-catalog behavior.

## Validation

- `just test -p codex-core
guardian_review_records_missing_auto_review_model_in_request_metadata`
- `just test -p codex-core
guardian_review_uses_model_catalog_override_when_preferred_review_model_exists`
- `just test -p codex-core
guardian_review_uses_preferred_review_model_without_model_catalog_override`
- `git diff --check origin/main`
Codex seems to do interesting things with `cfg`'s sometimes and it seems
it would be good to give it guidance about how broadly our Rust needs to
work.

This adds a very brief section to AGENTS.md explaining that we target
the major desktop OSes and that we want the vast majority of our logic
to be portable across them.
Each Windows packaging job creates three compressed forms of five
binaries in sequence. This takes roughly two minutes and is on the
release critical path.

Use two xargs workers to compress independent binaries concurrently.
The workers only read the raw executables and write per-binary archive
names. The Codex zip can safely read the helper executables while their
own archives are generated.

On a 16-vCPU AMD EPYC 9V74 Windows x64 release runner, alternating
trials against artifacts from release run 27391514823 measured:

  serial:   121 s, 123 s, 121 s
  parallel:  73 s,  73 s,  74 s

This saves 47 to 50 seconds in the x64 packaging lane, reducing the
observed release critical path by about 48 seconds when x64 remains the
limiting lane.

https://github.com/openai/codex/actions/runs/27401905938
…penai#27499)

## Summary

This PR promotes Mentions 2.0 (unified TUI mention popup) to stable and
enables it by default.

- Keep `mentions_v2` as a temporary rollback path to the legacy split
popups (`--disable mentions_v2`).
- Add feature-default and snapshot coverage for the default experience.

## Prior work

- [openai#19068 — Unified mentions in
TUI](openai#19068)
- [openai#22375 — Use plugin/list to get plugins for
mentions](openai#22375)
- [openai#23363 — Unified mentions tweaks and rendering
polish](openai#23363)

## Test plan

- Launch Codex without any feature overrides.
- Type `@` in the TUI composer.
- Confirm the unified mentions menu opens and displays filesystem,
plugin, and skill results.
## Why

The paired thread-environment migration changed several generic test
turn helpers from supplying a fallback cwd to explicitly selecting the
local environment. That changes their meaning under
`build_with_remote_env()`: remote-only fixtures cannot resolve the
forced local selection, so the tests fail before exercising apply-patch,
RMCP, unified-exec, or view-image behavior.

Generic helpers should inherit the environment selected by their
fixture. Tests that intentionally exercise local routing continue to
select the local environment explicitly.

## What changed

- Remove forced `local_selections(...)` overrides from the generic
apply-patch, RMCP, unified-exec, and view-image turn helpers.
- Remove the imports made unused by those deletions.

## Testing

- Not run locally; this is a test-fixture-only change and the `full-ci`
branch will exercise the affected remote shards.
In the x64 packaging job from

https://github.com/openai/codex/actions/runs/27391514823

archiving and uploading PDBs took 65 seconds after signing. Release
packaging could not start until that work completed.

Windows code signing changes executables but not their PDBs. Package
the PDBs in a sibling Ubuntu job as soon as all binary artifacts are
available. Signing and release packaging can then proceed without
waiting for the symbols archive, reducing the critical path by about
one minute.
## Why

`PathUri::from_abs_path` can fail for absolute paths that do not have a
normal `file:` URI representation, forcing filesystem call sites to
handle a conversion error even though the original path can be preserved
losslessly.

## What

Make `from_abs_path` infallible and migrate its callers. Unrepresentable
paths use `file:///%00/bad/path/<base64>`, encoding Unix bytes or
Windows UTF-16LE; `to_abs_path` validates and decodes that fallback. The
leading encoded null reserves a namespace that cannot collide with a
real Unix or Windows path, and fallback URIs remain opaque to lexical
path operations.

## Validation

Added path-URI coverage for Unix null and non-UTF-8 paths, Windows
device/verbatim and non-Unicode paths, serialization, malformed
fallbacks, opaque lexical operations, invalid native payloads, and
literal `/bad/path` collision resistance.
In the Windows x64 packaging job from

https://github.com/openai/codex/actions/runs/27391514823

building the primary and app-server package archives serially took 116
seconds.

Both archives read the same signed-binary directory but write separate
package trees and output files. Run them concurrently with xargs -P2.

The package helper rewrites DotSlash executables under the process temp
directory. A naive concurrent run failed when one process tried to
replace an executable used by the other. Give each bundle separate TMP
and TEMP roots to keep those caches independent.

On Windows x64 in

https://github.com/openai/codex/actions/runs/27397197944

three serial trials took 127, 128, and 126 seconds. Concurrent trials
took 76, 74, and 74 seconds, saving 52 to 54 seconds. This removes about
50 seconds from the release critical path without changing the packaging
commands or output set.
In the release job from

https://github.com/openai/codex/actions/runs/27391514823

staging the nine npm release tarballs serially took 104 seconds.

Each package build writes to a separate staging directory, output path,
and npm cache. Run them through the script's existing thread pool,
bounded by the available CPU count. Delete each staging tree as its
build finishes so concurrency does not retain all copies until the end.

On ubuntu-24.04 in

https://github.com/openai/codex/actions/runs/27397232050

two serial trials took 103 and 101 seconds, while concurrent trials
both took 41 seconds. Comparing every extracted file from the first
serial and concurrent sets found no differences. This removes about one
minute from every release.
## Why

We have some large gaps in our thread start, resume, and pre-sampling
traces that make it hard to tell where latency is coming from.

## What Changed

- Added coarse spans around thread start/resume, turn context
construction, rollout reconstruction, skill/plugin loading, and tool
preparation.
- Added a breakdown of discoverable-tool preparation across connector
loading, plugin discovery, and local plugin details.

## Testing

- `cargo check -p codex-app-server -p codex-core -p codex-core-skills -p
codex-core-plugins`
- Built the app-server locally and exercised thread start, first turn,
follow-up turn, server restart, thread resume, and a resumed turn.
## Stack

1. [1 of 3] Support long raw TUI goal objectives - openai#27508
2. [2 of 3] Support long pasted text in TUI goals - openai#27509
3. **[3 of 3] Support images in TUI goals** - this PR

## Why

The first two PRs make goal definitions resilient to long text, but
`/goal` still dropped image inputs from the composer. That meant a user
could attach images while defining a goal and the resulting goal
continuation would not have any useful reference to those images.

Goal state still persists only objective text, so image inputs need to
become paths or URLs that the agent can read later.

## What Changed

- Extends TUI `GoalDraft` with local image attachments and remote image
URLs.
- Copies local goal images through the app-server filesystem layer into
the managed goal attachment directory, then rewrites active image
placeholders to file references.
- Appends unplaced local images and remote image URLs to the objective
as referenced image files or URLs.
- Preserves goal image metadata through live `/goal` submission and
queued `/goal` dispatch.

## Verification

- Added goal materialization coverage for local image files and remote
image URLs.
- Added/updated TUI slash-command coverage showing `/goal` drafts
include attached images instead of dropping them.

## Manual Testing

- Attached an image by bracketed-pasting its local path into a live
`/goal` composer. The `[Image #1]` placeholder became a server-host
`image-1.png` reference, copied bytes matched exactly, and no attachment
was written under the TUI's local home.
- Deleted an image placeholder before submitting a small goal and
verified no image was copied.
- Attached PNG and JPEG files to the same goal. Placeholder order was
preserved as `image-1.png` and `image-2.jpg`, and both remote copies
matched their source bytes.
- Tried extensionless, malformed-extension, and
extension/content-mismatched paths; the composer rejected them as image
attachments before goal dispatch rather than creating misleading managed
image files.
- Combined a local image, a large pasted block, and enough raw text to
exceed 4,000 characters. The remote attachment directory contained the
image, paste sidecar, and `goal-objective.md`; all embedded references
used server-host paths and both payloads matched their sources.
- Submitted an image replacement while a goal was active, verified no
image was copied before confirmation, then canceled and confirmed the
attachment count was unchanged.
## Why

[openai#25345](openai#25345) was approved,
green, and squash-merged into its stacked base branch,
`fcoury/tokenmaxxing-api`. Four minutes later, that base branch was
force-pushed back to an API-only rebased head while preparing
[openai#25344](openai#25344) for `main`. As a
result, the squash commit from openai#25345 was orphaned and the TUI command
never reached `main` or a release.

This PR relands the orphaned TUI change from
[`411410b8`](openai@411410b)
on current `main`.

## What changed

- Add `/usage`, `/usage daily`, `/usage weekly`, and `/usage cumulative`
for account token activity.
- Fetch account usage asynchronously through the existing
`account/usage/read` app-server RPC.
- Render daily, weekly, and cumulative activity with theme-aware
terminal palettes and bounded transient cards.
- Preserve transcript ordering while assistant streams, history
consolidations, active cells, and hooks complete.
- Hide `/usage` from completion when backend auth is unavailable while
keeping typed-command guidance.
- Carry current-main behavior forward for cwd-aware Markdown parsing,
Windows Terminal color detection, and personal access token auth.
- Clear pending usage cards on thread rollback and delay completed cards
until live hook output is committed.
- Add focused regression and snapshot coverage for loading, auth errors,
invalid views, rollback, hook ordering, layout, and charts.

## Prior review

The original implementation was approved by Eric Traut in openai#25345 after
testing multiple themes and light/dark terminals. This PR preserves that
reviewed implementation while adapting it to current `main` and adding
regression coverage for newer rollback and hook lifecycle behavior.

## Validation

- `just test -p codex-tui token_activity palette renderable
usage_command` — 37 passed.
- Focused rollback, hook-ordering, and error snapshot tests — 4 passed.
- `just fix -p codex-tui` — passed.
- `UV_CACHE_DIR=/private/tmp/codex-uv-cache just fmt` — passed.
- `cargo insta pending-snapshots` — no pending snapshots.
- `just test -p codex-tui` — 2,870 passed; two unrelated guardian
feature-flag tests failed because their expected `OverrideTurnContext`
event was absent:
-
`update_feature_flags_disabling_guardian_clears_manual_review_policy_without_history`
-
`update_feature_flags_disabling_guardian_clears_review_policy_and_restores_default`
- `just argument-comment-lint` could not complete because the local
Bazel LLVM `compiler-rt` repository is missing `include/sanitizer/*.h`.
The touched Rust diff was manually inspected and no missing
opaque-literal argument comments were found.
@unemployabot
unemployabot Bot requested a review from wallentx June 13, 2026 18:11
@unemployabot unemployabot Bot added checkpoint Checkpoint merge termux-release Termux release automation labels Jun 13, 2026
@wallentx
wallentx merged commit 34f40bd into wallentx/termux-target Jun 13, 2026
1 check passed
@wallentx
wallentx deleted the checkpoint/wallentx_termux-target_from_release_0.140.0_7ba55d754ec8 branch June 13, 2026 18:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

checkpoint Checkpoint merge termux-release Termux release automation

Projects

None yet

Development

Successfully merging this pull request may close these issues.