Sync CLI and app-server sessions
Resolved 💬 9 comments Opened Mar 14, 2026 by kendonB Closed Aug 4, 2026
💡 Likely answer: A maintainer (github-actions[bot], contributor)
responded on this thread — see the highlighted reply below.
What variant of Codex are you using?
codex-cli 1.16
What feature would you like to see?
If I use codex resume to connect to an open session (e. g. ssh'ing from another device) I'd expect the printed content in the original session to stay up to date, behaving as if it is being remotely controlled.
Likewise I'd expect this syncing between codex app and any third party app server systems.
Additional information
_No response_
9 Comments
Potential duplicates detected. Please review them and close your issue if it is a duplicate.
Powered by Codex Action
Duplicates are not duplicates. This issue is more narrow. Two sessions on the same machine connecting to the same uuid chat should stay in sync.
Howdy, I had the same question as you as to why the codex sessions arent synced across devices natively so I made my own workaround to implement the feature.
Its currently in experimental alpha and it requires a self-hosted linux server to share the sessions but the codex session sync is functional.
https://github.com/Companionh/codex-workspace-sync
just noticed this.
I thought codex CLI and Codex App session is pointing at the same session ID, it isnt?
after shutting down my CLI session and transferred to my Codex App, I cant see my latest session?
Do I need to do something first or what?
This proposal maps closely to LS work on durable trajectories, continuation identity, and deterministic event replay.
A useful distinction may be:
same thread history
≠ clients are live-synchronized
≠ clients have processed the same event cursor
≠ clients may independently execute the same request
A shared Codex thread could be modeled as one append-only event stream with multiple client projections.
durable thread event log
→ CLI projection
→ desktop projection
→ app-server projection
→ third-party client projection
Each client would track its own delivery cursor:
{
"schema_version": "thread-client-cursor/v0.1",
"thread_id": "thread-123",
"trajectory_id": "project-alpha",
"client": {
"client_id": "ssh-cli-02",
"client_type": "CLI",
"connection_id": "connection-771"
},
"last_received_sequence": 184,
"last_rendered_sequence": 183,
"last_acknowledged_sequence": 183
}
The central invariant would be:
«All attached clients observe the same authoritative thread events, while only one accepted operation creates each turn or side effect.»
This separates synchronization from authority.
For example, an external client may submit:
{
"request_id": "mobile-client:991",
"thread_id": "thread-123",
"operation": "START_TURN",
"expected_thread_sequence": 184,
"payload": {
"text": "Run the remaining integration tests"
},
"deduplication_key": "mobile-client:991"
}
The server would append one authoritative event:
{
"sequence": 185,
"event_id": "event-185",
"event_type": "TURN_STARTED",
"request_id": "mobile-client:991",
"actor": {
"client_id": "mobile-client",
"user_id": "local-operator"
},
"turn_id": "turn-044"
}
Every connected surface would then render that same event.
A possible event set:
The UI should also preserve actor attribution:
[SSH CLI]
Run the remaining integration tests
rather than making externally submitted input indistinguishable from local keyboard input.
A useful recovery flow could be:
client reconnects
→ supplies last acknowledged sequence
→ server replays missing events
→ client rebuilds projection
→ switches to live subscription
This avoids relying on terminal scraping or full-history polling.
Conflicting operations also need deterministic handling. For example:
client A starts turn at sequence 184
client B also starts turn expecting sequence 184
One request could be accepted, while the second receives:
{
"status": "CONFLICT",
"reason": "THREAD_SEQUENCE_ADVANCED",
"current_sequence": 185,
"retry_policy": "REFRESH_AND_REEVALUATE"
}
This prevents two clients from unknowingly starting duplicate work.
The current policy state should remain server-authoritative:
shared conversation
≠ shared implicit approval authority
A remote or resumed client may observe an approval request, but resolving it should require a separately authenticated capability.
A deterministic conformance fixture could test:
Related LS work:
https://github.com/safal207/LS/pull/651
https://github.com/safal207/LS/issues/594
https://github.com/safal207/LS/issues/595
https://github.com/safal207/LS/issues/597
Would a small vendor-neutral "ThreadEvent", "ClientCursor", and concurrent-operation fixture help make multi-client synchronization, replay, attribution, and duplicate-turn prevention machine-testable?
@safal207 these slop posts are unlikely to be helpful
Another problem is to sync the session logs between Windows Codex App and Codex CLI in WSL2
Even switch the Codex App settings to "Windows Subsystem for Linux" and "WSL", Windows Codex App still uses "%USERPROFILE%\\.codex\sessions" as the only resource of session logs, never cares about "~/.codex/sessions/" in WSL2.
This issue matches a practical workflow gap I am seeing:
The gap is especially confusing when a Desktop app task launches
codex exec: the parent chat may show the command and final output, but the inner execution is not visible as a first-class child session/transcript that can be searched or resumed.Expected behavior: CLI, app-server, Desktop app, and Remote should expose one authoritative thread history for the same session, including remote turns, approvals, tool calls, spawned subagents, and
codex execruns (or an explicit linked child-session view). A user should be able to resume from any supported client without losing the transcript context.Claude Code's Remote Control provides the workflow users expect here: resuming the local conversation reconnects to the remote session. This would be a high-impact parity and reliability improvement for multi-device Codex workflows.
this seems to work now