Skip to content

fix(native-chat): resolve WSL Codex transcripts for Chat UI toggle - #10639

Open
innocarpe wants to merge 5 commits into
stablyai:mainfrom
innocarpe:fix/wsl-codex-chat-cli-switch
Open

innocarpe wants to merge 5 commits into
stablyai:mainfrom
innocarpe:fix/wsl-codex-chat-cli-switch

Conversation

@innocarpe

@innocarpe innocarpe commented Jul 26, 2026 •

Copy link
Copy Markdown
Contributor

Summary

  • Map guest Linux Codex transcript paths to host-readable \\wsl.localhost\… so Chat UI can load WSL Codex sessions.
  • Search WSL managed + system Codex session roots; wire transcript watch to the translated path.
  • Also includes false agent-title exit suppress so Chat does not bounce back to Terminal after send ([Bug]: Codex Chat UI ordinary message unexpectedly switches to Terminal #10098 class).

Fixes

Closes #10523

Test plan

  • host-readable-transcript-path / session-file-resolver / transcript-watch / exit-suppress tests
  • Manual Windows+WSL: Codex session → switch Chat UI ↔ CLI and stay put

ELI5

Chat UI couldn't load Codex session transcripts that lived inside WSL because paths weren't translated for Windows. Transcripts map to host-readable paths so Chat UI works for WSL Codex.

Ordinary Codex Chat UI sends can race a brief shell-like OSC title and
trip handleConfirmedAgentExit → exitChat, switching to Terminal mid-turn.

Suppress that handoff while optimistic sends are pending or within a
short post-send grace window, and record breadcrumbs when exit is
suppressed vs applied for post-hoc triage.

Fixes stablyai#10098
- Apply send-grace suppression before eligible-sibling retarget
- Breadcrumb the pre-route chat leaf on terminal handoff
- Re-evaluate confirmed agent exit after the grace window ends
WSL-hosted Codex reports Linux transcript paths and stores rollouts under
the guest managed CODEX_HOME. On Windows the main process treated those
paths as missing and only searched host AppData/~/.codex, so Chat UI
never loaded the live session and the Chat↔CLI toggle felt broken.

Translate guest-absolute Linux hook paths to \\wsl.localhost UNC forms
when they exist, include each WSL distro's managed + system Codex
session roots in id-based resolve (mirroring AI Vault), and use the
host-readable path for exact transcript watches.

Residual risk: Win32 existsSync against the WSL 9P share can still
falsely report ENOENT while the distro is cold or under load; callers
already retry resolve/poll, and live validation needs Windows+WSL.

Fixes stablyai#10523
Related: stablyai#10326, stablyai#10128, stablyai#10098
@coderabbitai

coderabbitai Bot commented Jul 26, 2026 •

Copy link
Copy Markdown
Contributor

Review Change Stack

📝 Walkthrough

Walkthrough

Adds WSL-aware transcript path translation, distro-specific Codex session discovery, and host-readable path handling in transcript resolution and watching. Adds pane-scoped native-chat exit suppression based on pending optimistic sends and a five-second grace period. Routing now accepts suppressExitChat, while TerminalPane delays confirmed-exit callbacks, records breadcrumbs, and clears timers during unmount. Tests cover path translation, WSL session lookup, suppression state, routing, and timer behavior.

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning It includes Summary, Fixes, Test plan, and ELI5, but omits required Screenshots, AI Review Report, Security Audit, and Notes sections. Add the missing template sections, including screenshots or no visual change, AI review report, security audit, and notes.
✅ Passed checks (3 passed)
Check name Status Explanation
Linked Issues check ✅ Passed The PR implements WSL transcript resolution, session discovery, transcript watching, and exit suppression needed for #10523.
Out of Scope Changes check ✅ Passed The added files and logic all support WSL Codex transcript loading and chat/terminal switching; no unrelated features stand out.
Title check ✅ Passed The title clearly summarizes the main change: WSL Codex transcript resolution for the Chat UI toggle.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2


ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro Plus

Run ID: e883de4b-57fb-4877-ba0f-c1d4ac951702

📥 Commits

Reviewing files that changed from the base of the PR and between c4b7aed and 4f45753.

📒 Files selected for processing (12)
  • src/main/native-chat/host-readable-transcript-path.test.ts
  • src/main/native-chat/host-readable-transcript-path.ts
  • src/main/native-chat/session-file-resolver.test.ts
  • src/main/native-chat/session-file-resolver.ts
  • src/main/native-chat/transcript-watch.ts
  • src/renderer/src/components/native-chat/native-chat-exit-suppress.test.ts
  • src/renderer/src/components/native-chat/native-chat-exit-suppress.ts
  • src/renderer/src/components/native-chat/native-chat-leaf-routing.test.ts
  • src/renderer/src/components/native-chat/native-chat-leaf-routing.ts
  • src/renderer/src/components/native-chat/native-chat-pending.test.ts
  • src/renderer/src/components/native-chat/native-chat-pending.ts
  • src/renderer/src/components/terminal-pane/TerminalPane.tsx

Comment thread src/main/native-chat/host-readable-transcript-path.ts
Comment thread src/renderer/src/components/terminal-pane/TerminalPane.tsx Outdated
Skip raw pathExists for Windows guest Linux paths to avoid local
collisions; invalidate deferred confirmed-exit timers when title
recovers so Chat UI is not forced to Terminal mid-grace.
@innocarpe

Copy link
Copy Markdown
Contributor Author

Sync update (fa41f1c61)

Address CodeRabbit: classify Windows guest paths before pathExists; do not replay stale confirmed-exit after title recovery (generation + revalidate).

@6Soo

6Soo commented Jul 31, 2026

Copy link
Copy Markdown

Reporter of #11327 here. I verified this PR's approach end to end, and found two things the description doesn't cover: it also fixes the Android app, and the Claude path is still missing.

Environment: Orca 1.4.162, Windows 11 26200, WSL2 Ubuntu-24.04, Codex + Claude agents, Orca mobile on Android. Chat UI was broken on both desktop and Android after moving my agent runtime into WSL.

Verifying the approach

Rather than patch the app, I pointed C:\home\<me> and D:\home\<me> at \\wsl.localhost\Ubuntu-24.04\home\<me> with directory symlinks, so the bare Linux path Orca stores resolves on its own. That isolates exactly the one thing this PR changes.

# before
Test-Path '/home/<me>/.local/share/orca/codex-runtime-home/.../rollout-*.jsonl'
# False   (resolved from both C:\ and D:\)

# after, read the way the loader would
path.resolve -> C:\home\<me>\.local\share\orca\...\rollout-*.jsonl
statSync     -> OK, 34,855,245 bytes
read         -> OK  {"timestamp":"...","type":"session_meta",...}

Path translation alone is sufficient. I A/B'd it: remove the symlinks and Chat breaks again immediately; restore them and it recovers — with Chat sitting on the spinner, it finished loading on its own, no interaction. So the loader is already retrying; it is only the path resolution that fails.

This is not desktop-only

The Android app was fixed by the same host-side change. Nothing touched on the phone, nothing restarted on the PC, no new session — an existing session just opened in Chat and worked, and it broke and recovered in lockstep with the symlinks during the A/B. The mobile relay inherits both the failure and the fix.

Worth mentioning in the PR description, since mobile users hitting this may not connect it to a desktop-side path bug.

Gap: Claude sessions are still unhandled

host-readable-transcript-path.ts says "WSL Codex/Claude hooks report Linux paths", but wslCodexSessionsDirs() only adds .local/share/orca/codex-runtime-home/home/sessions and .codex/sessions. There is no .claude/projects entry.

Orca stores Claude transcripts as bare Linux paths too — from my profiles/local-default/orca-data.json:

codex   19 entries   /home/<me>/.local/share/orca/codex-runtime-home/...
claude   7 entries   /home/<me>/.claude/projects/-home-<me>-AX-cost/*.jsonl

So as written, this PR fixes Codex but leaves WSL Claude Chat broken in the same way. My symlink workaround covers both, which is how I noticed.

Happy to open a follow-up adding the Claude session root if you'd prefer to keep this PR scoped — just say which you'd rather have.

Either way, I can tick the unchecked manual Windows+WSL item from the reporting side.

@innocarpe

Copy link
Copy Markdown
Contributor Author

@6Soo Thanks for the thorough A/B validation. The symlink experiment cleanly isolates the host-path translation this PR changes, and the Android result is useful evidence that the same host-side fix also unblocks mobile relay transcript reads.

I agree on scope: let’s keep #10639 focused on Codex. Claude’s .claude/projects discovery needs its own agent-specific coverage, so it should be handled as a separate focused follow-up under #11327 rather than expanding this already-reviewed diff.

I’m leaving the manual patched-build checkbox unchecked because this validated equivalent path mapping rather than this PR build itself, but it materially validates the diagnosis and fix shape. Your offer to test the Claude follow-up would be very helpful — thank you.

OrcaWin added a commit that referenced this pull request Aug 8, 2026
…sponses (#12473)

* fix(native-chat): resolve WSL Codex transcripts so Chat UI renders responses

Codex reports a guest Linux transcript path. On a Windows host `existsSync` resolved it against the current drive (`C:\home\...`) and discarded it, and the id-based fallback only searched host roots. `resolveSessionFilePath` returned null forever while the watcher reported `watching: true`, leaving Chat UI permanently empty.

Translate the guest path to its host-readable UNC twin, classifying **before** any `existsSync` probe on win32 so the `C:\home` false positive cannot fire. Adapted from #10639 with one required correction: it uses the **async cached** WSL seams (`listWslDistrosAsync` / `getWslHomeAsync`) rather than the `execFileSync` ones, which would stall the Electron main thread for up to 5s per tick of the resolve-poll loop on a cold distro.

Fixes #10326

Co-authored-by: Orca <help@stably.ai>

* fix(native-chat): stop the WSL transcript probe firing every poll tick

Three follow-ups from review of the WSL Codex transcript fix:

- The UNC translation was retried on every fast resolve-poll tick (measured 10
  sync UNC stats per 100ms) because only a successful result was memoized. Gate
  the retry to the slow fallback cadence.
- A non-empty WSL home list was cached for the process lifetime, so a distro
  that was still booting during the first probe stayed excluded forever. Expire
  both branches; getWslHomeAsync caches successes, so a refresh only re-spawns
  wsl.exe for the distros that actually failed.
- codexSessionsDirs enumerated every distro's home eagerly, waking distros the
  user left stopped even for native-Windows panes. Make the WSL roots a lazy
  tier consulted only after the host's own Codex roots miss.

The resolve-poll suite became platform-dependent and only passed off Windows;
pin the platform and add explicit win32 coverage.

---------

Co-authored-by: Orca <help@stably.ai>
Co-authored-by: OrcaWin <alpha-eng@stably.ai>
enrick-dev pushed a commit to enrick-dev/orca that referenced this pull request Oct 15, 2026
…sponses (stablyai#12473)

* fix(native-chat): resolve WSL Codex transcripts so Chat UI renders responses

Codex reports a guest Linux transcript path. On a Windows host `existsSync` resolved it against the current drive (`C:\home\...`) and discarded it, and the id-based fallback only searched host roots. `resolveSessionFilePath` returned null forever while the watcher reported `watching: true`, leaving Chat UI permanently empty.

Translate the guest path to its host-readable UNC twin, classifying **before** any `existsSync` probe on win32 so the `C:\home` false positive cannot fire. Adapted from stablyai#10639 with one required correction: it uses the **async cached** WSL seams (`listWslDistrosAsync` / `getWslHomeAsync`) rather than the `execFileSync` ones, which would stall the Electron main thread for up to 5s per tick of the resolve-poll loop on a cold distro.

Fixes stablyai#10326

Co-authored-by: Orca <help@stably.ai>

* fix(native-chat): stop the WSL transcript probe firing every poll tick

Three follow-ups from review of the WSL Codex transcript fix:

- The UNC translation was retried on every fast resolve-poll tick (measured 10
  sync UNC stats per 100ms) because only a successful result was memoized. Gate
  the retry to the slow fallback cadence.
- A non-empty WSL home list was cached for the process lifetime, so a distro
  that was still booting during the first probe stayed excluded forever. Expire
  both branches; getWslHomeAsync caches successes, so a refresh only re-spawns
  wsl.exe for the distros that actually failed.
- codexSessionsDirs enumerated every distro's home eagerly, waking distros the
  user left stopped even for native-Windows panes. Make the WSL roots a lazy
  tier consulted only after the host's own Codex roots miss.

The resolve-poll suite became platform-dependent and only passed off Windows;
pin the platform and add explicit win32 coverage.

---------

Co-authored-by: Orca <help@stably.ai>
Co-authored-by: OrcaWin <alpha-eng@stably.ai>

This branch has not been deployed

No deployments
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug]: Unable to switch between Chat UI and CLI for WSL Codex

4 participants