Document how app-server clients can discover and attach to the active Codex Desktop thread

Open 💬 4 comments Opened Jun 2, 2026 by bakemocho

What feature would you like to see?

I would like a supported, documented app-server path for a local external client
to discover and attach to the currently active Codex Desktop thread/turn.

The goal is not to change model behavior. The goal is to let a local integration
safely answer:

  • which thread is the active Desktop UI session?
  • is there an in-flight turn?
  • can the client subscribe to that thread's live events?
  • can the client steer or interrupt that in-flight turn through a supported API?
  • if this is unsupported, how should clients detect that instead of guessing?

Problem

The documented app-server primitives work well for threads that the client
creates through app-server: a client can start a thread, start a turn, observe
events, and call turn/interrupt against a turn it owns.

The unclear case is an already-running Codex Desktop UI session. In local
experiments, an external client could see stored thread history, but could not
reliably bind that persisted thread to a loaded, controllable Desktop UI turn.

Observed shape:

  • thread/list can show stored threads.
  • thread/read with includeTurns:false can read a selected stored thread.
  • thread/loaded/list can return zero loaded threads from the client-visible

app-server surface.

  • a turn/interrupt attempt against the selected active-thread candidate

returned thread not found.

  • direct stdio against the active Desktop-bundled codex app-server can return

inventory, but still did not expose a loaded UI thread to control.

That leaves external clients with unsafe options: infer the current thread from
local session files, update times, or UI-visible labels, then try a control
method that may be targeting a persisted-but-not-loaded thread or the wrong
app-server process.

Environment from one local probe

  • Platform: macOS / Darwin arm64
  • Codex Desktop bundle: 26.527.60818 / build 3437
  • Desktop-bundled codex: codex-cli 0.136.0-alpha.2
  • Standalone current codex: codex-cli 0.135.0

Why this matters

This blocks safe local orchestration around Codex Desktop sessions.

Examples:

  • a local supervisor wants to notify or steer a long-running Desktop session;
  • a recovery tool wants to tell whether a Desktop turn is still running, lost,

interrupted, or only persisted;

  • a multi-agent/local automation layer wants to coordinate with a user-visible

Desktop session instead of creating detached hidden workers;

  • a client wants to avoid scraping local session files or guessing from file

modification times.

Without an official current-Desktop-thread discovery/attachment contract, a
client can prove that app-server control works for threads it created, but not
that it can safely control the existing Desktop UI thread the user is looking at.

Desired outcome

Any of these would address the gap:

  1. A documented API to read the current Desktop UI thread id and active turn id

for the local app instance.

  1. A documented way to attach/subscribe an external app-server client to an

already-loaded Desktop UI thread.

  1. A documented way to resume or load a persisted thread into a controllable

app-server process without starting a new unrelated UI session.

  1. Clear errors that distinguish:
  • unknown thread id,
  • persisted but not loaded,
  • loaded in another app-server process,
  • no active turn,
  • unsupported existing-UI-session control.
  1. Documentation stating that existing Desktop UI session control is not

supported, plus the recommended integration pattern.

Related issues

Related but not the same:

  • #20943 asks for clearer app-server turn lifecycle semantics for external

clients. This issue is about identifying and attaching to the active Desktop
thread before lifecycle handling begins.

  • #15299 asks for inbound notifications into an active CLI session. This issue

is about app-server clients and Codex Desktop.

  • #25482 asks for remote app-server threads in Desktop thread orchestration.

This issue is about the local active Desktop UI thread.

  • #25779 is a broader Desktop/session active-turn reliability meta issue. This

issue is narrower and asks for a supported external-client contract.

  • #24518 covers a TUI turn/interrupt failure path.
  • #25846 covers codex app-server proxy transport behavior; this request is

about active Desktop thread discovery/attachment, not proxy framing.

Additional notes

I am intentionally not including raw thread ids, turn ids, local session file
paths, or transcript text here. The public observation is the control-surface
shape: persisted thread visibility does not currently imply that an external
client has a supported loaded-turn target for the current Desktop UI session.

View original on GitHub ↗

4 Comments

bakemocho · 2 months ago

Update: After filing this, I found the 2026-05-29 Codex app 26.527 changelog
and the app docs for thread coordination/worktrees. I had not seen that feature
when I opened this issue; if I had, I may not have filed it in this exact form.

The remaining gap I meant to ask about is narrower: I still do not see a
documented app-server / external-client contract for discovering or attaching to
the thread/turn that is currently active in the Codex Desktop UI. So I think
this issue is better scoped as a request to document that boundary, not as a
request for general thread/worktree coordination.

One practical caveat: I am close to my current Codex quota limit, so I cannot
immediately verify the new Desktop thread-coordination behavior myself. For now
I am effectively blocked from testing the workflow end to end until quota is
available again.

bakemocho · 2 months ago

I have a more precise update after testing the app-server control path again.

The large-history part is no longer the main blocker in my local repro. With a
detached local app-server process, I can resume the current Desktop thread in a
low-payload shape and verify that the bounded first page
matches the active-turn candidate I found locally. That part did not hit the
2 MB reader limit.

The remaining gap is live-turn ownership or attachment:

  • In the detached app-server process, the current Desktop thread can be loaded

and resumed, but turn/steer for the discovered active turn returns
no active turn to steer.

  • Talking directly to the daemon control socket over WebSocket also works for

initialize, thread/loaded/list, and thread/resume with excludeTurns.
The selected Desktop thread is visible as loaded there too, but the same
turn/steer request still returns no active turn to steer.

  • Separately, codex app-server proxy --sock ... still times out for a minimal

WebSocket-framed initialize, while the raw socket route succeeds. I think
that is a different proxy/transport issue from the active-turn attachment
question here.

So the request I would find most useful is documentation for this boundary:

Can an external local app-server client attach to the live active turn that is
currently running in the Codex Desktop UI, or can it only load/read/resume the
persisted thread record in its own control context? If the latter is intended,
an explicit unsupported-boundary note and the supported alternative would be
enough.

hhy827 · 1 month ago

_Author's note: I'm a Korean speaker; I directed this and made the calls, and the English was written by the AI I operate (Claude and Codex)._

First, I'm writing to support this request — and to add one real-world data point from actual business use.

I'm not a software developer. I run a small renewable-energy company and handle real business work (permitting, economics, regulatory review) with AI. My tools are the GUI desktop apps, and the one relevant to this issue is the Codex app. The hypothetical examples you list — "a local supervisor that wants to notify or steer a long-running Desktop session," and "a local automation layer that wants to coordinate with a user-visible Desktop session instead of creating detached hidden workers" — I'm a real-world instance of both, so I'm here to add the weight of an actual need, not a hypothetical one, to your request.

Let me be honest about how I stumbled into this. At first I was the wire between several AI sessions: I copied one session's answer, pasted it into another's window, and carried the thread back by hand. Then I moved that exchange onto a shared channel (Slack) so they could see each other — but I still had to tell each session, by hand, to "go check the channel." Then I moved the work itself into a queue (Linear), so what/who/how-far lived in the queue instead of my head. The last manual thing left was exactly that "go check the channel."

I was only trying to remove that one chore — I was not trying to invent "waking a session." I just wanted the manual relaying gone. But while wiring that automation, I found that, in my setup, when the signal reaches the intended already-running session, it doesn't start fresh — it resumes with its context intact. It was a by-product of removing a chore, not a goal. And that by-product turned out to be exactly what lets multi-day business work continue without re-briefing it every morning.

Here's how I actually use it (shape only): a work signal in Slack/Linear → a durable routing queue → delivery targeted to a specific seat → the already-running desktop session picks up with its context intact. Waking the existing session, not spawning a new one. Across several of my own machines, at real business scale, over many days. For multi-day work, that context continuity is the whole point.

Consistent with your findings, I do not rely on a documented app-server attach path — because, as you show, there isn't one for the live Desktop UI turn. What I have is an unofficial local integration I prop up by hand, and it's fragile in exactly the ways that follow from there being no supported contract: the monitoring around a session can fail, sessions drop on app update/restart, and an idle session won't wake without an external trigger.

For that reason I deliberately do not publish the exact path (no thread ids, no session file paths, no method) — the same discipline you kept. I'm not withholding to be secretive; I'm withholding because an unsupported workaround is precisely the thing that shouldn't be relied on. That is the very reason a supported contract, which this issue asks for, is needed.

On legitimacy: official apps + my own paid subscription + my own machines only. I'm not trying to bypass usage limits or billing — routing the signal is the same instruction I would otherwise type into the session by hand. If OpenAI says this pattern is unsupported or inappropriate, I'll stop and use whatever supported path is available.

So here is my request. This need is already load-bearing in a real business. Please make this an official, documented capability — the things that map directly onto your desired outcomes:

  • a documented way to discover/attach to the active Desktop UI thread/turn;
  • provenance — external-channel input visibly distinguished from local user input;
  • approval preservation — delivery must not equal execution permission.

My hope is clear: not to be prevented from doing this, but to be able to do it safely. More non-developer domain operators will end up here. Please build this one supported, documented, governable boundary — so none of us has to reinvent the fragile wiring.

AstraVanX · 27 days ago

I independently tested this gap on native Windows using a one-shot, strictly read-only capability preflight.

Environment:

  • Codex Desktop AppX version: 26.727.6591.0
  • Platform: native Windows 11 x64
  • The Desktop-bundled codex.exe was identified by file size, Authenticode/AppX identity, and SHA-256.
  • The Desktop child process was observed running app-server --analytics-default-enabled.

Observed result:

  • The Desktop-launched app-server exposed no TCP listener or documented local control endpoint that an external client could safely associate with the current Desktop UI instance.
  • Because that association could not be proven, the