Skip to content

Fix Termux/Android compatibility issues (DNS, locking, Android target support)#5

Draft
wallentx wants to merge 541 commits into
mainfrom
wallentx/termux-target
Draft

Fix Termux/Android compatibility issues (DNS, locking, Android target support)#5
wallentx wants to merge 541 commits into
mainfrom
wallentx/termux-target

Conversation

@wallentx

@wallentx wallentx commented Feb 14, 2026

Copy link
Copy Markdown
Owner

Codex CLI currently fails on native Termux/Android due to DNS resolution and unsupported lock semantics in this environment. This PR adds compatibility adjustments that allow:

  • Authentication and request execution to succeed on Termux/Android.
  • Lock-based session persistence to work without runtime errors.
  • Reproducible Android build artifacts in CI for easier validation and testing.

The changes preserve existing behavior on non-Android platforms.


Changes

DNS/Resolver fixes

  • Apply Android/Termux-specific resolver fallback path while preserving normal resolver behavior elsewhere.
  • Fallback chain for resolver config:
    1. system config,
    2. $PREFIX/etc/resolv.conf,
    3. a deterministic fallback.
  • Register both UDP and TCP entries for nameservers.
  • Add tests covering parsing, protocol registration, and environment detection.

Graceful handling of unsupported locks

  • Detect and handle std::io::ErrorKind::Unsupported from try_lock() without failing.
  • Allow session preference flows (e.g., “press p” to auto-accept) to proceed when locks are unavailable.
  • Adjust affected unit tests to consider environments without file-locking support.

Android build target support in CI

To produce and validate builds targeting Android (e.g. native Termux):

  • Add aarch64-linux-android target in GitHub Actions.
  • Install and configure Android NDK in CI workflow.
  • Configure Cargo linker, CC, and AR for the Android target.
  • Enable vendored OpenSSL for Android builds.
  • Adjust keyring target dependencies for Android.

This enables CI to build Android artifacts that include the compatibility adjustments above, which aids testing and validation.


Validation

  • just fmt
  • cargo test
  • Verified on a real native Termux/Android device (no proot/chroot):
    • Authentication succeeds.
    • Interactive requests complete.
    • Session preference persistence works.
    • No regressions observed on existing targets.

@wallentx wallentx changed the title Wallentx/termux target Fix Termux/Android compatibility issues (DNS, locking, Android target support) Feb 14, 2026
@wallentx wallentx force-pushed the wallentx/termux-target branch from d61ca4b to 6c3d14b Compare February 15, 2026 16:17
@robertkirkman

robertkirkman commented Feb 19, 2026

Copy link
Copy Markdown

Hi, do you know if this will continue to work with, and maybe improve, https://github.com/termux-user-repository/tur/blob/cf26feef42820d03b7061866ee5f456324657a7a/tur/codex/build.sh ?

@wallentx

Copy link
Copy Markdown
Owner Author

Hi, do you know if this will continue to work with, and maybe improve, https://github.com/termux-user-repository/tur/blob/cf26feef42820d03b7061866ee5f456324657a7a/tur/codex/build.sh ?

Screenshot_20260219-225637

AddText_02-20-11 01 35~2

The current TUR provided codex is impacted by the issue that my PR resolves, so if I get an invite to PR upstream, this should fix at least the locking issues.
I'll need to fork TUR and point it here to see what the build produces.

I had some code change logic to handle the absence of /etc/resolve.conf on android, but found that simply adding an aarch64-linux-android target made all of that unnecessary.. but if this never gets merged upstream, I could provide a patch with that original conditional logic so that this can be fully solved via patches in the TUR. Are you a maintainer, @robertkirkman ?

@robertkirkman

Copy link
Copy Markdown

I had some code change logic to handle the absence of /etc/resolve.conf on android, but found that simply adding an aarch64-linux-android target made all of that unnecessary.. but if this never gets merged upstream, I could provide a patch with that original conditional logic so that this can be fully solved via patches in the TUR. Are you a maintainer, @robertkirkman ?

Yes, I have merge permission for TUR. If you want users of Codex on TUR to get this fix, you could also submit this to https://github.com/termux-user-repository/tur/pulls and I would be able to approve it there, and then whenever this version gets merged the patch could be removed from the TUR version when it gets updated.

Comment thread codex-rs/utils/pty/src/pty.rs Outdated
@wallentx

wallentx commented May 9, 2026

Copy link
Copy Markdown
Owner Author

Upstream, they have made a prerelease for rusty-v8 that they are using to test artifacts against their release binaries https://github.com/openai/codex/releases/tag/rusty-v8-v147.4.0
I am going to see if I can bring in that workflow to mirror their pre-release, and put the logic that builds the android artifacts on top of that that I have from https://github.com/wallentx/rusty_v8/releases/tag/v146.9.0

Then I can mirror their upstream prerelease for rust-v8-v147.4.0 which will also include my android artifacts, and this PR might actually be suitable for upstream merging.

@wallentx wallentx force-pushed the wallentx/termux-target branch from 438ac09 to 7ead295 Compare May 20, 2026 02:56
marksteinbrick-oai and others added 18 commits June 9, 2026 18:45
## Why
- Currently, there is no analytics event for `/goal` behavior
- Existing events cannot identify goal execution or its resulting
outcome
- The original update in
[openai#26182](openai#26182) was implemented
before `/goal` moved into `codex-goal-extension`.

## What Changed
- Adds `codex_goal_event` serialization and enrichment to
`codex-analytics`
- Emits goal events from the canonical `codex-goal-extension` mutation
and accounting paths:
  - `created` when a new logical goal is persisted
  - `usage_accounted` when cumulative goal usage is persisted
  - `status_changed` when the stored goal status changes
  - `cleared` when the goal is deleted
- Preserves causal `turn_id` for turn driven events and uses null
attribution for external or idle lifecycle events
- Changes goal deletion to return the deleted row so `cleared` retains
the stable goal ID

## Event Details

Includes standard analytics metadata along with goal specific fields:
- `goal_id`: Stable ID stored in the local SQLite goal row and shared
across the goal's events
- `event_kind`: Observed operation (see the 4 lifecycle events cited in
the above bullet)
- `goal_status`: Resulting or last stored status: `active`, `paused`,
`blocked`, `usage_limited`, etc.
  - `has_token_budget`: Indicates whether a token budget is configured
  - `turn_id`: Causal turn ID, or null when no causal turn exists
- `cumulative_tokens_accounted`: Cumulative tokens on `usage_accounted`
events; null otherwise
- `cumulative_time_accounted_seconds`: Cumulative active time on
`usage_accounted` events; null otherwise

## Validation
- `just test -p codex-analytics -p codex-state -p codex-goal-extension`
- `just test -p codex-core -E 'test(/goal/)'`
- `just test -p codex-app-server`
- `cargo build -p codex-analytics -p codex-core -p codex-state -p
codex-app-server`
…nt/wallentx_termux-target_from_release_0.139.0_746530165eed
…et_from_release_0.139.0_746530165eed

checkpoint: into wallentx/termux-target from release/0.139.0 @ 7465301
## Why

Recent merges left `main` with analytics integration build failures.
Local Cargo runs also made the trimmed-skills test depend on
developer-installed skills, while Bazel used an isolated home.

## What changed

- Clone `thread_metadata.thread_source` when constructing goal analytics
event parameters.
- Group app-server thread extension inputs into
`ThreadExtensionDependencies`.
- Isolate the trimmed-skills test home so its exact fixture count is
stable across Cargo and Bazel.

## Validation

- `cargo check -p codex-analytics`
- `just test -p codex-analytics` (71 tests)
- `just test -p codex-app-server` (837 tests; one unrelated zsh-fork
timeout passed on retry)
## Why
Codex app-server latency traces do not granularly cover turn
orchestration, sampling-request preparation, and tool-loading work.
These spans help separate local coordination/setup costs from model
streaming and tool execution.

## What changed
- Add `run_turn.*` spans around sampling-request input preparation and
post-sampling state collection
- Add function-level trace spans around turn setup, hook execution,
compaction, prompt construction, and MCP tool exposure
- Add `built_tools.*` spans around plugin loading and discoverable-tool
loading

## Verification
Trigger Codex rollout and observe new spans are included
…nt/wallentx_termux-target_from_release_0.140.0_f88907c1fa2c
…et_from_release_0.140.0_f88907c1fa2c

checkpoint: into wallentx/termux-target from release/0.140.0 @ f88907c
## Why

Required MCP server startup was enforced in `Session::new` after
`McpConnectionManager` had already created the clients. That split let
other manager construction paths bypass the same requirement and exposed
manager internals solely so the session could validate them. Keeping
required-server readiness in the constructor gives every caller one
consistent startup contract.

## What changed

- make `McpConnectionManager::new` return `anyhow::Result<Self>` and
fail when an enabled, required server cannot initialize
- pass the startup cancellation token into the constructor so
required-server waits remain cancellable
- propagate constructor failures through resource reads, connector
discovery, and MCP status collection
- preserve the active manager and cancellation token when a refreshed
replacement fails
- keep required-startup failure collection private and cover the
constructor error contract directly

## Validation

- updated the focused connection-manager test to assert the complete
required-server startup error
- local tests not run; relying on CI
## Why

MCP startup status notifications are thread-owned, but `ChatWidget`
trusted upstream routing. If routing state delivered a tagged child
notification to the active parent widget, the child MCP failure could
still mutate the parent's startup state and transcript. Rejecting it
only inside the MCP handler was also too late because shared
notification handling could already restore and consume the parent's
retry status.

## What changed

- Validate a tagged MCP status notification against the visible
`ChatWidget` thread before shared notification handling mutates any
parent state.
- Cover child `Starting` and `Failed` notifications delivered to a
retrying parent widget, asserting that they preserve its visible retry
error and saved status header while producing no history or MCP status
mutation.

## User impact

Subagent MCP startup failures remain scoped to the child transcript
instead of appearing as duplicate warnings in the parent transcript.

## Testing

- `just test -p codex-tui mcp_startup_ignores_status_for_other_thread`
- `just test -p codex-tui
primary_thread_ignores_child_mcp_startup_notifications`
- `just fmt`
## Stack

- Base: openai#27191
- This PR is the third vertical and should be reviewed against
`jif/external-plugins-2`, not `main`.

## Why

openai#27191 moves the host-owned Apps MCP registration behind an extension
contributor, but deliberately preserves the existing endpoint-selection
feature while that contribution contract lands. App-server can therefore
resolve the server through extensions, yet the hosted plugin endpoint is
still selected through temporary `apps_mcp_path_override` plumbing.

That is not the long-term plugin model. A plugin can bundle skills,
connectors, MCP servers, and hooks, and those components do not all need
the same source or execution environment. In particular, an
authenticated HTTP MCP server can expose plugin capabilities directly
from a backend without an executor or an orchestrator filesystem.

This PR completes that hosted vertical. App-server's MCP extension now
owns the aggregate hosted plugin runtime at `/ps/mcp`. Connector actions
continue to arrive as MCP tools, while backend-provided skills arrive as
MCP resources and use Codex's existing resource list/read paths. No
second backend client, skill filesystem, or generic plugin activation
framework is introduced.

The backend route remains the hosted implementation. This change
replaces Codex's temporary endpoint-selection mechanism, not the service
behind the endpoint.

## What changed

### Hosted plugin runtime

The MCP extension now contributes `codex_apps` as the hosted plugin
runtime rather than as a configurable Apps endpoint:

- `https://chatgpt.com` resolves to
`https://chatgpt.com/backend-api/ps/mcp`;
- a bare custom ChatGPT base resolves to `/api/codex/ps/mcp`;
- the existing product-SKU header and ChatGPT authentication behavior
are preserved;
- executor availability is never consulted for this streamable HTTP
transport.

The same MCP connection carries both component shapes supported by the
hosted endpoint:

- connector actions are discovered and invoked as MCP tools;
- hosted skills are enumerated and read as MCP resources through the
existing `list_mcp_resources` and `read_mcp_resource` paths.

This keeps component access in the subsystem that already owns the
protocol instead of downloading backend skills into an orchestrator
filesystem or inventing a parallel hosted-skill client.

### Explicit runtime ordering

`McpManager` now resolves the reserved `codex_apps` entry in three
ordered phases:

1. install the legacy Apps fallback for compatibility;
2. apply ordered extension `Set` or `Remove` overlays;
3. apply the final ChatGPT-auth gate without synthesizing the server
again.

This ordering is important:

- an ordinary configured or plugin MCP server cannot claim the
auth-bearing `codex_apps` name;
- an extension-contributed hosted runtime wins over the fallback;
- an extension `Remove` remains authoritative;
- a host without the MCP extension retains the legacy Apps endpoint and
current local-only behavior.

The temporary `legacy_apps_mcp_loader_enabled` coordination flag is no
longer needed.

### Remove the path override

The `apps_mcp_path_override` feature and its runtime plumbing are
removed, including:

- the feature registry entry and structured feature config;
- `Config` and `McpConfig` fields;
- config schema output;
- config-lock materialization;
- URL override handling in `codex-mcp`.

Existing boolean and structured forms still deserialize as ignored
compatibility input. They are omitted from new serialized config, and
config-lock comparison normalizes the removed input so older locks
remain replayable.

### App-server coverage

App-server MCP fixtures now serve the hosted route at
`/api/codex/ps/mcp`. Existing resource-read and tool/elicitation flows
therefore exercise the extension-owned endpoint rather than succeeding
through the legacy fallback.

The stack also adds the missing `codex_chatgpt::connectors` re-export
for the manager-backed connector helper introduced in openai#27191.

## Compatibility

- App-server installs the extension and uses `/ps/mcp` for the hosted
runtime.
- CLI and other hosts that do not install the extension retain the
legacy Apps endpoint.
- Apps disabled or non-ChatGPT authentication removes `codex_apps` from
the effective runtime view.
- Existing local plugins, local skills, executor-selected skills,
configured MCP servers, and MCP OAuth behavior are otherwise unchanged.
- Backend plugin enablement remains account/workspace state owned by the
hosted endpoint; this PR does not add thread-local backend plugin
selection.

## Architectural fit

The stack now proves two independent runtime shapes:

1. openai#27184 resolves filesystem-backed skills through the executor that
owns a selected root.
2. openai#27191 and this PR resolve a backend-hosted HTTP MCP through an
extension with no executor.

Together they preserve the intended separation:

- selection identifies a plugin/root when explicit selection is needed;
- each component's owning extension resolves its concrete access
mechanism;
- execution stays with the runtime required by that component;
- existing skills, MCP, connector, and hook subsystems remain the
downstream consumers.

## Planned follow-ups

1. **Executor stdio MCP:** selecting an executor plugin registers a
manifest-declared stdio MCP server and executes it in the environment
that owns the plugin.
2. **Optional backend selection:** only if CCA needs thread-local
selection distinct from backend account/workspace enablement, add a
concrete backend-owned capability location and surface those selected
skills through the skills catalog.
3. **Connector metadata and hooks:** activate those plugin components
through their existing owning subsystems, with executor hooks remaining
environment-bound.
4. **Propagation and persistence:** define explicit resume, fork,
subagent, refresh, and environment-removal semantics once selected roots
have multiple real consumers.
5. **Local convergence:** migrate legacy local skill, MCP, connector,
and hook paths behind their owning extensions one vertical at a time,
then remove duplicate core managers and compatibility plumbing after
parity.

## Verification

Coverage in this change exercises:

- extension-owned `/backend-api/ps/mcp` registration without an
executor;
- preservation of the legacy endpoint in hosts without the extension;
- extension `Set` and `Remove` precedence over the legacy fallback;
- ChatGPT-auth gating for the reserved server;
- hosted MCP resource reads with and without an active thread;
- connector tool invocation and MCP elicitation through the hosted
route;
- ignored boolean and structured forms of the removed path override;
- config-lock replay compatibility for the removed feature.

`cargo check -p codex-features -p codex-mcp-extension -p
codex-app-server` passes. Tests and Clippy were not run locally under
the current development instruction; CI provides the full validation
pass.
## Summary
- tag legacy multi-agent spawn metrics with `version=v1`
- tag multi-agent v2 spawn metrics with `version=v2`

## Why
`codex.multi_agent.spawn` is emitted by both runtimes, so the existing
metric cannot distinguish v2 adoption from aggregate multi-agent
spawning. The bounded version tag makes that breakdown directly
queryable without changing the counter's success-only semantics.

## Validation
- `just fmt`
- `git diff --check`
- Tests and Clippy were intentionally left to CI.
## Why

Extension contributors are registered behind `dyn Trait` objects, so
native `async fn`/RPITIT methods would make these traits
non-object-safe. Spell out the boxed, `Send` future contract directly so
`extension-api` no longer needs `async-trait` while retaining the
existing runtime model.

## What changed

- add a shared `ExtensionFuture` alias and use it for asynchronous
contributor methods
- migrate production and test implementations to return `Box::pin(async
move { ... })`
- remove `async-trait` dependencies where they are no longer used,
keeping it dev-only where unrelated test executors still require it

## Behavior

No behavior change is intended. Contributor futures remain boxed,
`Send`, dynamically dispatched, and lazily executed; cancellation and
callback ordering stay unchanged.

## Testing

- `just test -p codex-extension-api` (11 passed)
- affected extension crates (64 passed)
- targeted `codex-core` contributor tests (14 passed)
- `just fmt`
- `just bazel-lock-update`
- `just bazel-lock-check`

A broad local `codex-core` run compiled successfully but encountered
unrelated sandbox and missing test-binary fixture failures; CI will run
the full checks.
## Summary

We originally addressed startup prewarming holding the read side of
`RwLock<McpConnectionManager>` by snapshotting tool-list state. Review
feedback identified the broader ownership problem: the outer
synchronization should only publish or retrieve the current manager,
while MCP operations rely on the manager's internal synchronization. A
follow-up preserved operation retirement with a separate gate, but
further review questioned whether that synchronization was actually
required and whether we could support latest-wins replacement instead.

This PR now stores the current MCP manager in `ArcSwap`. Each operation
uses `load_full()` to obtain an owned `Arc<McpConnectionManager>`, then
performs MCP I/O without retaining the publication mechanism. Refresh
cancels obsolete startup work, constructs a replacement, and atomically
publishes it. New operations see the latest manager, while operations
that already loaded the previous manager retain a valid handle. Refresh
happens at a turn boundary, so there should be no active user tool calls
to drain.

Git history supports dropping the outer `RwLock`. It was introduced in
`03ffe4d595` on November 17, 2025 for non-blocking MCP startup: the
session published an empty manager, startup initialized that same object
while holding the write lock, and readers waited for initialization.
`7cd2e84026` on February 19, 2026 removed that two-phase initialization
in favor of constructing a fresh manager and swapping it in, explicitly
noting that `Option` or `OnceCell` could replace the placeholder design.
Hot reload later reused the existing lock to publish a replacement, but
I found no indication that the lock was introduced to guarantee
in-flight tool calls finish before refresh or shutdown.

Terminal shutdown remains separate from refresh: it aborts startup
prewarming and active tasks before shutting down the current manager, so
tool calls may be interrupted and no model WebSocket work continues
after shutdown. Focused regression coverage exercises pending tool-list
cancellation, deferred refresh, and startup-prewarm shutdown.
## Why

Compaction window identity is part of session history, not model-client
transport state. Persisting it with the compacted rollout item lets
resumed threads continue from the reconstructed window without keeping
mutable window state on `ModelClient`.

## What changed

- Added `window_id` to `CompactedItem` and stamp it when
`replace_compacted_history` installs compacted history.
- Moved auto-compact window id ownership into `AutoCompactWindow` /
`SessionState`; `ModelClient` now receives the request window id from
callers instead of storing it.
- Returned `window_id` from rollout reconstruction for resume.
Reconstruction uses the newest surviving compacted item's stored
`window_id` when present, and falls back to the legacy compacted-item
count when it is absent.
- Kept fork startup at the fresh default window id and updated direct
model-client tests to pass explicit test window ids.

## Validation

- `cargo check -p codex-core --tests`
apanasenko-oai and others added 30 commits June 12, 2026 20:10
## Why

Managed deployments need a reliable deny gate for remote control.
Persisted enablement and explicit startup requests currently remain able
to start the transport, while the removed `features.remote_control` key
is intentionally only a compatibility no-op.

This adds a dedicated requirement that administrators can use to force
remote control off without deleting the user's persisted preference.
Removing the requirement and restarting restores the prior choice.

## What Changed

- Added top-level `allow_remote_control` requirements parsing, sourced
layer precedence, debug output, and `configRequirements/read` exposure
as `allowRemoteControl`.
- Added a typed transport policy captured from the startup requirements
snapshot. Managed disable forces the initial state to disabled and
prevents enrollment, refresh, connection, and persisted-preference
mutation.
- Rejected every `remoteControl/*` RPC before parameter deserialization
with JSON-RPC `-32600` and `remote control is disabled by managed
requirements`.
- Preserved the existing disabled status notification and the previous
behavior when the requirement is `true` or omitted.
- Regenerated app-server protocol schemas and documented the new
requirement.

## Verification

- Confirmed all remote-control RPCs, including a malformed request,
return the managed-policy error while the initial status notification
remains `disabled`.
- Confirmed explicit ephemeral startup and persisted enablement make no
backend connection and leave the SQLite preference unchanged.
- Confirmed `allow_remote_control = true` does not enable or block
remote control and `configRequirements/read` returns
`allowRemoteControl: false` for the deny policy.

Related issue: N/A (managed-policy hardening).
## Why

We want to make it possible for an app-server orchestrator on one OS to
control an exec-server on another host running a different OS. In
practice this kinda already works if you get lucky and the two hosts
have the same path format, but we mangle quite a lot of operations if
either end is Windows.

This test starts exercising that interaction, although right now the
initial bootstrap fails. Future changes will expand the test's
assertions to match improved support.

## What

Stacked on openai#27964. This adds a small Windows exec-server fixture and a
Linux protocol smoke test using the reusable Wine harness, covering
Windows environment discovery, non-TTY `cmd.exe` execution, output, exit
status, and working directory.

Once we've got the full codex binary cross-building under Bazel we could
consider moving to the real binary instead of the stripped down
exec-server-only binary used here.
## Context

Turn state is scoped to one logical turn, but the WebSocket path
currently exchanges it through upgrade headers, which are scoped to the
physical connection. A connection may be reused across turns, so its
handshake cannot represent the turn lifecycle reliably.

## Change

Exchange turn state on each WebSocket response request instead:

- send an established value in `response.create.client_metadata`
- read the returned value from the existing `response.metadata` event
- retain the first value in the turn-scoped `ModelClientSession`
`OnceLock`
- start the next logical turn without state, even when it reuses the
same WebSocket connection

This gives WebSocket requests the same first-value-wins contract as the
existing HTTP path.

## Test plan

Integration coverage verifies that:

- WebSocket replays returned state on same-turn follow-ups
- later response metadata does not replace the first value
- state resets at the logical turn boundary without requiring a
reconnect

CI validates the full change.

## Stack

This is 1/2. openai#28002 builds on this request-scoped transport to carry
established state through compact requests.
## Context

Inline compaction is part of the active logical turn. Compact requests
and the sampling requests around them should use the same turn state,
including when compaction is the first request to establish it.

## Change

Pass the turn-scoped `OnceLock` directly to inline v1 compaction so
`/responses/compact` includes an established value in the existing HTTP
header. Capture `x-codex-turn-state` from the compact response into that
same lock, allowing pre-turn compact to establish the value that
subsequent sampling reuses.

V2 compact already uses the normal Responses HTTP/WebSocket path and
continues to share the same `OnceLock` without separate plumbing. The
first returned value wins for the logical turn.

## Test plan

Integration coverage verifies that:

- pre-turn v1 compact can establish state for the first sampling request
- inline v1 compact receives established state over HTTP
- inline v2 compact reuses established state over HTTP
- inline v2 compact reuses established state over WebSocket

CI validates the full change.
…nt/wallentx_termux-target_from_release_0.140.0_7ba55d754ec8
…et_from_release_0.140.0_7ba55d754ec8

checkpoint: into wallentx/termux-target from release/0.140.0 @ 7ba55d7
The first release after parallelizing Windows packaging moved the
critical path to the ARM64 packaging job:

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

The x64 job started immediately and finished in 5m29s. The ARM64
job waited 76s for its runner and then took 5m56s, holding the
release for 1m43s after x64 had finished.

Packaging only downloads, signs, archives, and compresses already
built binaries. It does not execute target code. Run both packaging
jobs on x64 runners, keeping ARM64 hardware for compilation.
## Why

This is the second-to-last place in the exec-server protocol that needs
to migrate to URIs to support cross-OS operation.

## What

- Change `ExecParams.cwd` to `PathUri`.
- Keep the cwd URI-shaped through core and rmcp producers, converting it
to `AbsolutePathBuf` only in `LocalProcess::start_process`.
- Reject non-native cwd URIs before launch and update the affected
protocol documentation and call sites.
…nt/wallentx_termux-target_from_release_0.140.0_65bbffdef9fc
…et_from_release_0.140.0_65bbffdef9fc

checkpoint: into wallentx/termux-target from release/0.140.0 @ 65bbffd
## Context

This is the next step in the plugin auth-routing stack. The earlier PRs
make `PluginsManager` auth-aware and move the broad App/MCP surface
decision into that layer. This PR narrows the ChatGPT/SIWC behavior so
we only hide a plugin MCP server when it conflicts with an App
declaration of the same name.

In product terms: if a plugin exposes both an App route and MCP route
for `foo`, ChatGPT/SIWC sessions should use the App route for `foo`. If
the same plugin also exposes a separate MCP server like `foo2`, that MCP
server should remain available.

```json
// .app.json
{
  "apps": {
    "foo": {
      "id": "connector_abc"
    }
  }
}
```

```json
// .mcp.json
{
  "mcpServers": {
    "foo": {
      "url": "https://mcp.foo.com/mcp"
    },
    "foo2": {
      "url": "https://mcp.foo2.com/mcp"
    }
  }
}
```

## Stack

- PR1: openai#27652 seed plugin manager auth at construction.
- PR2: openai#27459 route plugin surfaces by auth mode.
- PR3: openai#27607 dedupe plugin MCP servers by App declaration name.
- PR4: openai#27602 preserve plugin Apps in connector listings.
- PR5: openai#27461 skip install-time plugin MCP OAuth for matching App
routes.

## Summary

- Preserve App declaration names in loaded plugin metadata.
- Keep public effective App outputs as deduped connector IDs for
existing callers.
- For ChatGPT/SIWC, suppress only plugin MCP servers whose names match
declared App names.

## Validation

```bash
cargo fmt --all
cargo test -p codex-core-plugins plugin_auth_projection
cargo test -p codex-core-plugins effective_apps
cargo test -p codex-core-plugins read_plugin_for_config_installed_git_source_reads_from_cache_without_cloning
cargo test -p codex-core explicit_plugin_mentions_use_apps_for_chatgpt_dual_surface_plugins
cargo test -p codex-core explicit_plugin_mentions_keep_non_conflicting_mcp_for_chatgpt_auth
cargo test -p codex-app-server --test all plugin_install_filters_disallowed_apps_needing_auth
git diff --check
```

---------

Co-authored-by: Xin Lin <xl@openai.com>
…nt/wallentx_termux-target_from_release_0.140.0_b24d8ce1ef74
…et_from_release_0.140.0_b24d8ce1ef74

checkpoint: into wallentx/termux-target from release/0.140.0 @ b24d8ce
- Added `/usage` views for daily, weekly, and cumulative account token activity. (openai#27925)
- `/goal` now preserves oversized text, large pasted blocks, and image attachments, including in remote app-server sessions. (openai#27508, openai#27509, openai#27510)
- Added permanent session deletion through `codex delete`, `/delete`, and app-server `thread/delete`, with confirmation safeguards and subagent cleanup. (openai#25018, openai#27476)
- Added `/import` for selectively importing setup, project configuration, and recent chats from Claude Code. (openai#27070, openai#27071, openai#27703)
- Typing `@` now opens the unified mentions menu for files, plugins, and skills by default. (openai#27499)
- Added managed Amazon Bedrock API-key authentication and encrypted local storage for CLI and MCP OAuth credentials. (openai#27443, openai#27689, openai#27504, openai#27535, openai#27539, openai#27541)

## Bug Fixes

- Corrupted SQLite state databases are now backed up and rebuilt automatically from rollout data, including malformed database-directory cases. (openai#26859, openai#27719)
- Prevented `/review` from crashing when `Esc` is pressed with queued guidance, while preserving that guidance when the review is canceled. (openai#22879)
- Improved MCP reliability by retrying transient startup failures, reporting unusable OAuth credentials as logged out, and preserving explicitly disabled servers. (openai#25147, openai#26713, openai#27414)
- Fixed remote plugin uninstall requests and correctly surfaced apps requiring authentication during installation. (openai#27085, openai#27223)
- Persisted “Don’t remind me” update dismissals reliably and cleared stale running-hook indicators after completed turns. (openai#27619, openai#27783)
- Non-TTY background commands can now be interrupted with Ctrl-C while preserving their final output and exit status. (openai#26734)

## Documentation

- Clarified contributor guidance around keeping crate APIs narrow and supporting Linux, macOS, and Windows. (openai#27939, openai#27966)

## Chores

- Improved responsiveness for large repositories and long sessions by preserving Git’s built-in filesystem monitor, avoiding duplicate history reads, accelerating archive lookup, and caching turn-diff rendering. (openai#26880, openai#27031, openai#27276, openai#27489)
- Removed the experimental `/realtime` voice controls and related audio dependencies from the TUI. (openai#27801)

## Changelog

Full Changelog: openai/codex@rust-v0.139.0...rust-v0.140.0

- openai#26880 [codex] preserve fsmonitor for worktree Git reads @tamird
- openai#27085 Use server app auth requirements for remote plugin install @xl-openai
- openai#27098 [codex] Return workspace directory installed plugins @xl-openai
- openai#27007 multi-agent: add path-based v2 activity tracking @jif-oai
- openai#27166 app-server: clear stale thread watches after v2 agent interruption @jif-oai
- openai#27080 [codex] Ignore pending PR review comments @anp-oai
- openai#26420 Avoid no-op backfill state writes @zanie-oai
- openai#27031 Avoid rereading rollout history during cold resume @zanie-oai
- openai#22879 fix: Prevent /review crash when entering Esc on steer message @canvrno-oai
- openai#27173 app-server: reject direct input to multi-agent v2 sub-agents @jif-oai
- openai#27184 Load selected executor skills through extensions @jif-oai
- openai#26835 [codex] Test extension API contracts @anp-oai
- openai#27063 [codex-analytics] add extensible feature thread sources @marksteinbrick-oai
- openai#26479 [codex] Speed up local nextest runs @anp-oai
- openai#27223 fix: use plugin service route for remote uninstall @ericning-o
- openai#22685 Add SOCKS5 TCP MITM coverage @winston-openai
- openai#26681 Allow creating a new goal after completion @etraut-openai
- openai#26711 Reduce TUI legacy core dependencies @etraut-openai
- openai#27110 [1/6] Add Python goal routing foundation @aibrahim-oai
- openai#27191 Route hosted Apps MCP through extensions @jif-oai
- openai#26830 [codex] Characterize global instruction lifecycle @anp-oai
- openai#26713 [codex] Report unusable MCP OAuth credentials as logged out @anp-oai
- openai#26734 [codex] Handle Ctrl-C for non-TTY unified exec @pakrym-oai
- openai#27116 Stop mirroring Codex user input into realtime @guinness-oai
- openai#27111 [2/6] Add private Python goal operations @aibrahim-oai
- openai#25147 [codex] Retry streamable HTTP initialize failures @ssetty-oai
- openai#27257 [codex] Tighten MCP connection manager API visibility and order @aibrahim-oai
- openai#26701 TUI Plugin Sharing 1 - add remote plugin identity @canvrno-oai
- openai#27129 feat: use provider defaults for memory models @celia-oai
- openai#27094 Add spans to build_tool_router @mchen-oai
- openai#24999 Add per-session realtime model and version overrides @guinness-oai
- openai#27078 [codex-analytics] emit goal lifecycle analytics @marksteinbrick-oai
- openai#27285 [codex] Fix post-merge analytics integration failures @anp-oai
- openai#27107 Add spans to run_turn @mchen-oai
- openai#27261 [codex] Make MCP connection startup fallible @aibrahim-oai
- openai#27174 feat: keep child MCP warnings out of parent transcript @jif-oai
- openai#27198 Use plugin-service MCP as the hosted plugin runtime @jif-oai
- openai#27375 [codex] Tag multi-agent spawn metrics with version @jif-oai
- openai#27383 Remove async-trait from extension contributors @jif-oai
- openai#27259 Use latest-wins MCP manager replacement @charliemarsh-oai
- openai#27264 [codex] Store compact window id in rollout @pakrym-oai
- openai#27280 [codex] add io PathUri native conversion APIs @anp-oai
- openai#27315 [codex] link Windows releases with LLD @tamird
- openai#27276 Reduce archive rollout lookup CPU @etraut-openai
- openai#27299 [codex] Outline ToolExecutor handler bodies @anp-oai
- openai#27391 Index visible thread list ordering @zanie-oai
- openai#27407 Fix compressed rollout search path matching @jif-oai
- openai#27304 [codex] Remove async_trait from ToolExecutor @anp-oai
- openai#26041 Add app-server background terminal process APIs @etraut-openai
- openai#25018 Add app-server `thread/delete` API @etraut-openai
- openai#26859 fix: Auto-recover from corrupted sqlite databases @ddr-oai
- openai#27064 [codex] remove blocking external agent migration flow @stefanstokic-oai
- openai#27421 [codex] Raise app-server recursion limit @anp-oai
- openai#27062 [codex] Retry transient Guardian review failures @kbazzi
- openai#27065 [codex] extract external agent import picker renderer @stefanstokic-oai
- openai#26409 [plugins] Inject remote_plugin_id into install elicitations @adaley-openai
- openai#27439 feat: make ThreadStore available on ThreadExtensionDependencies @bolinfest
- openai#27343 Guard core test subprocess cleanup @etraut-openai
- openai#27070 [codex] add external agent import picker UX @stefanstokic-oai
- openai#27321 [codex] Move release platform rules into bazel package @anp-oai
- openai#27071 [codex] add /import for external agents @stefanstokic-oai
- openai#27311 [codex] Skip local curated discovery for remote plugins @xl-openai
- openai#27414 [codex] Preserve disabled MCP servers across runtime overlays @e-provencher
- openai#27312 [codex] reuse release artifacts for npm staging @tamird
- openai#27319 Forward standalone assistant output to realtime @guinness-oai
- openai#27057 [codex] Add reusable OTEL gauge instruments @richardopenai
- openai#27245 image: add shared data URL preparation utilities @fjord-oai
- openai#27392 [codex-analytics] emit internally started turn events @marksteinbrick-oai
- openai#27322 [codex] Preserve build-script dependencies in rules_rs annotations @anp-oai
- openai#27489 core: cache turn diff rendering @nornagon-openai
- openai#27465 [codex] Remove redundant plugin app auth state @xl-openai
- openai#27484 Remove TUI legacy core test_support dependencies @etraut-openai
- openai#27476 Add session delete commands in CLI and TUI @etraut-openai
- openai#27247 core: resize all history images behind a feature flag @fjord-oai
- openai#27487 Trim TUI legacy telemetry and migration dependencies @etraut-openai
- openai#27438 [codex] Add token budget context feature @pakrym-oai
- openai#27501 [codex] Expand hosted web search citation guidance @yuning-oai
- openai#27526 tools: simplify default tool search text @sayan-oai
- openai#27488 [codex] Add new context window tool @pakrym-oai
- openai#27443 feat: add Bedrock API key as a managed auth mode @celia-oai
- openai#27532 [codex] Add comp_hash to model metadata @aibrahim-oai
- openai#27246 core: strip image detail from Responses Lite requests @fjord-oai
- openai#27517 [codex] Pass auth mode to plugin manager @xl-openai
- openai#27520 [codex] Compact when comp_hash changes @aibrahim-oai
- openai#27518 [codex] Add context remaining tool @pakrym-oai
- openai#27266 image: preserve metadata when resizing prompt images @fjord-oai
- openai#27103 [codex-analytics] report cached input tokens for v2 compaction @rhan-oai
- openai#27356 Use generic search metadata for dynamic tools @sayan-oai
- openai#27082 [codex-analytics] Emit structured compaction codex errors @rhan-oai
- openai#26513 [codex] Tune cloud config cache intervals @alexsong-oai
- openai#27387 skills: make backend plugin skills invocable without an executor @jif-oai
- openai#27403 skills: cache remote catalog failures per thread @jif-oai
- openai#27573 core: enable remote compaction v2 by default @jif-oai
- openai#27388 skills: expose remote skill resource tools @jif-oai
- openai#27569 multi-agent: move concurrency guidance into v2 usage hints @jif-oai
- openai#27585 nit: cap error @jif-oai
- openai#27404 test: cover referenced backend skill reads without an executor @jif-oai
- openai#27591 skills: render catalog locators by authority @jif-oai
- openai#27413 skills: decouple the skills extension from core @jif-oai
- openai#27527 [codex] publish npm packages concurrently @tamird
- openai#27528 [codex] publish DotSlash alongside npm @tamird
- openai#27529 [codex] download only release artifacts @tamird
- openai#27490 Remove TUI legacy Windows sandbox dependency @etraut-openai
- openai#27483 Emit plugin ID on MCP tool call analytics events @chrisdong-oai
- openai#27417 Print TUI session info on fatal exits @etraut-openai
- openai#27507 lint: allow self-documenting builder arguments @anp-oai
- openai#27420 [codex] Propagate plugin app categories @charlesgong-openai
- openai#27454 [codex] add cross-platform filesystem adapter coverage @anp-oai
- openai#27415 [codex] Surface runtime warnings in codex exec @anp-oai
- openai#27639 [codex] revert concurrent npm publishing @tamird
- openai#27646 feat: disable orchestrator skills for now @jif-oai
- openai#27323 [codex] Provide ARM64 MinGW powl compatibility support @anp-oai
- openai#27433 [codex] remove EnvironmentPathRef @anp-oai
- openai#27424 [codex] migrate ExecutorFileSystem paths to PathUri @anp-oai
- openai#27101 [codex] Load user instructions through an injected provider @anp-oai
- openai#27634 Resolve MCP server registrations through a catalog @jif-oai
- openai#27122 core: Consolidate Responses API Codex metadata @owenlin0
- openai#27450 [codex-rs] enforce PAT workspace restrictions @cooper-oai
- openai#27653 [codex] migrate exec-server filesystem protocol to PathUri @anp-oai
- openai#27663 Include thread id in token budget context @pakrym-oai
- openai#26418 [codex] Avoid duplicate hooks.json discovery with profiles @abhinav-oai
- openai#27689 feat: prefer managed Bedrock auth in model provider @celia-oai
- openai#27700 Remove fs/join and fs/parent from exec-server protocol @anp-oai
- openai#26426 Warn when hooks.json has unsupported top-level fields @abhinav-oai
- openai#27318 [codex] Move persistence policy application into ThreadStore @wiltzius-openai
- openai#27498 Route image extension reads through turn environments v2 @won-openai
- openai#27623 Add spans to turn lifecycle gaps @mchen-oai
- openai#27619 tui: clear stale hook row after turn completion @kotakem-openai
- openai#27711 Fix image extension PathUri conversion @anp-oai
- openai#27475 [codex] Remove async_trait from first-party code @anp-oai
- openai#27719 fix: Recover from sqlite directory being a file @ddr-oai
- openai#27715 ci(v8): gate Windows source builds on relevant changes @cconger
- openai#27702 [codex] parallelize release code generation @tamird
- openai#27709 [codex] resolve environment shell metadata eagerly @pakrym-oai
- openai#27445 feat(app-server): persist remote-control desired state @apanasenko-oai
- openai#27508 [1 of 3] Support long raw TUI goal objectives @etraut-openai
- openai#27256 Add request_user_input auto-resolution window contract @shijie-oai
- openai#27724 code-mode standalone: extract protocol and add host crate @cconger
- openai#27778 Translate non-English issues @etraut-openai
- openai#27316 Keep request_user_input direct-model only @shijie-oai
- openai#27696 [codex] Load AGENTS.md from all bound environments @anp-oai
- openai#27670 Make MCP server contributions thread-scoped @jif-oai
- openai#27732 [code-mode] Reject remote image URLs from output helpers @rka-oai
- openai#27692 Add executor-owned plugin resolution @jif-oai
- openai#27863 Extract shared plugin MCP config parsing @jif-oai
- openai#27703 [codex] restore source-specific import copy @stefanstokic-oai
- openai#27879 fix: serialize auth environment tests @jif-oai
- openai#27791 Reject transcript backtrack in side conversations @etraut-openai
- openai#27075 [ez][codex-rs] Support approvals reviewer in app defaults @zamoshchin-openai
- openai#27538 Use dependency groups for Python SDK tooling @charliemarsh-oai
- openai#27783 Persist update dismissal without cache @etraut-openai
- openai#27814 tui: Allow extra o's in /goal command @btraut-openai
- openai#27901 Use uv as Python SDK build backend @charliemarsh-oai
- openai#27720 realtime: add AVAS architecture override @bakks
- openai#27919 chore: prompt MAv2 @jif-oai
- openai#27816 sandboxing: migrate cwd inputs to PathUri @anp-oai
- openai#27890 [codex] expose remote plugin share URL @ericning-o
- openai#27913 [codex] unify apply patch parsing @pakrym-oai
- openai#27920 Handle standalone image generation failures as terminal items @won-openai
- openai#27927 [codex] Add size to internal filesystem metadata @pakrym-oai
- openai#27504 feat: add secret auth storage configuration @celia-oai
- openai#27674 [login] revoke existing auth before starting login @cooper-oai
- openai#27535 feat: add auth-specific encrypted secret namespaces @celia-oai
- openai#27939 [codex] Add crate API surface review rule @pakrym-oai
- openai#27926 [codex] Align implicit skill reads with parser @alexsong-oai
- openai#23254 fix(plugins) rm plugin descriptions @dylan-hurd-oai
- openai#27830 Support plaintext agent messages @jif-oai
- openai#27801 Remove TUI realtime voice support @etraut-openai
- openai#27539 feat: use encrypted local secrets for CLI auth @celia-oai
- openai#27076 Warn for structured feature toggles @canvrno-oai
- openai#27541 feat: use encrypted local secrets for MCP OAuth @celia-oai
- openai#27936 [codex] add roles to realtime append text @agamble-oai
- openai#27509 [2 of 3] Support long pasted text in TUI goals @etraut-openai
- openai#27109 Add Guardian catalog diagnostics metadata @won-openai
- openai#27966 Specify platform support in AGENTS.md @anp-oai
- openai#27855 [codex] parallelize Windows compression @tamird
- openai#27499 Promote TUI unified mentions in composer to default mentions feature @canvrno-oai
- openai#27972 [codex] Let generic test turns inherit their environment @pakrym-oai
- openai#27856 [codex] package Windows symbols in parallel @tamird
- openai#27976 [codex] make PathUri::from_abs_path infallible @anp-oai
- openai#27854 [codex] parallelize Windows package archives @tamird
- openai#27853 [codex] stage npm packages concurrently @tamird
- openai#27710 [codex] add latency tracing spans @rphilizaire-openai
- openai#27510 [3 of 3] Support images in TUI goals @etraut-openai
- openai#27925 feat(tui): reland token activity command @fcoury-oai
- openai#27988 [codex] Limit app-based plugin suggestions to remote catalogs @xl-openai
- openai#27652 [codex] Add auth mode to plugin manager constructor @felixxia-oai
- openai#27964 [codex] Add hermetic Wine test support @anp-oai
- openai#27459 [codex] Gate plugin MCP servers by auth route @felixxia-oai
- openai#27961 feat(app-server): enforce managed remote control disable @apanasenko-oai
- openai#27937 [codex] Add hermetic Wine exec-server test @anp-oai
- openai#27996 [codex] Send request-scoped turn state over WebSocket @aibrahim-oai
- openai#28002 [codex] Send turn state through compact requests @aibrahim-oai
…nt/wallentx_termux-target_from_release_0.140.0_51871f5ca833
…et_from_release_0.140.0_51871f5ca833

checkpoint: into wallentx/termux-target from release/0.140.0 @ 51871f5
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.