Repository navigation
Open chats move to the account you switch to, before their next message - #30955
brennanb2025 wants to merge 5 commits into
Conversation
|
No actionable comments were generated in the recent review. 🎉 ℹ️ Recent review info
📝 Walkthrough
Priority: ➖ Normal Merge Risk: 🟡 Moderate · up to
|
There was a problem hiding this comment.
Actionable comments posted: 1
ℹ️ Review info
⚙️ Run configuration
- Configuration used: Repository UI
- Review profile: CHILL
- Plan: Advanced
- Run ID:
eba12076-fbbc-4648-b565-ce58e12f4bd0
📒 Files selected for processing: 24
src/main/claude/claude-structured-launch-account-routing.test.tssrc/main/claude/claude-structured-session-acquisition.tssrc/main/claude/claude-structured-session-publication.tssrc/main/native-chat/agent-model-catalog/agent-model-catalog-fingerprint.tssrc/main/native-chat/agent-model-catalog/agent-model-catalog-prewarm.test.tssrc/main/native-chat/agent-model-catalog/agent-model-catalog-running-account.tssrc/main/native-chat/agent-model-catalog/agent-model-catalog-service.tssrc/main/native-chat/agent-session-wire/structured-agent-session-acquisition.tssrc/main/native-chat/agent-session-wire/structured-agent-session-adapter.tssrc/main/native-chat/agent-session-wire/structured-agent-session-attach-flow.tssrc/main/native-chat/agent-session-wire/structured-agent-session-attach-orchestration.tssrc/main/native-chat/agent-session-wire/structured-agent-session-attach-publish.tssrc/main/native-chat/agent-session-wire/structured-agent-session-host-delivery.tssrc/main/native-chat/agent-session-wire/structured-agent-session-host-types.tssrc/main/native-chat/agent-session-wire/structured-agent-session-host.tssrc/main/native-chat/agent-session-wire/structured-agent-session-outgrown-child.test.tssrc/main/native-chat/agent-session-wire/structured-agent-session-outgrown-child.tssrc/main/runtime/session-tabs/structured-session-account-home.tssrc/main/runtime/structured-agent-model-catalog-wiring.tssrc/main/runtime/structured-agent-runtime-metadata.tssrc/main/runtime/structured-agent-runtime-registration-types.tssrc/main/runtime/structured-agent-session-runtime.tssrc/main/runtime/workspaces/workspace-process-listing.tssrc/shared/agent-session-account-home.ts
Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 0 remain after this review.
| const accountHome = await deps.launchAccountHome?.(record).catch(() => null) | ||
| return accountHome ? { ...record, accountHome } : record |
There was a problem hiding this comment.
🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win
Do not use the saved account after a failed launch-account read.
If launchAccountHome rejects after an account switch, this catch selects record.accountHome. AgentModelCatalogService.read can then return the old account’s saved models or start a probe under that account. Keep null as the intentional “use the saved account” result, but distinguish a failed lookup and return an unknown catalog result instead.
…ore its next message A running chat's agent read its account only when it started, and nothing compared it with the account a start would use now, so open chats kept answering on the old account after a switch. The agent a chat runs now records the account its launch used, and the host's replace-before-the- next-send check replaces an idle one whose account is no longer what a start would use. A chat mid-reply finishes on the old account first. Claude chats follow; agents whose chats keep the account they were created on are never compared. A chat's model-list reads and saves now use the account it runs on, so a moved chat no longer writes its new account's list under its first account (STA-11281). Tracked in STA-11211.
8ef8f44 to
1f8beb9
Compare
…er that wires the host
ELI5
When you switch Claude to another account, Orca already offers to restart your Claude terminals on the new account. Your open chats were left out: they kept answering on the old account until something happened to restart them. Now each open chat moves to the account you switched to the next time you send it a message. It continues the same conversation, and a chat that's in the middle of a reply finishes that reply first.
What Changed
The problem. After a switch in Settings > Accounts or the status bar:
Why. An agent reads its account only when it starts. A chat's agent process is owned by the chat's host (this computer, or the server it runs on). Nothing on that host ever compared the account a running agent started on with the account a new start would use now. The restart offer runs in the window and walks its terminal panes, so the host-owned chats were invisible to it.
What you see now.
Mechanism.
What doesn't change, and why.
Why
The common pattern is to compare the settings a running agent was actually built with against the ones a start would use now, and rebuild it only before the next turn, never during one. Orca already had exactly that check for sign-in and permission-mode changes. It was missing the account. Adding the account to that check:
Considered and rejected: extending the window's terminal scan to chats and sending each chat a restart request. That needs a new message type that older servers don't know. It only works for switches made in a window on this computer and for chats open in a tab. And it keeps the decision away from the host that owns the process.
Linked Issue
Tracked in STA-11211 (and STA-11281 for the model list).
Visual Proof
Real-agent hidden-window QA on M4Air passed on
d95126414d5bagainst maine01a5392d42d: idle and previously busy Claude chats follow A→B→A with context retained, the busy reply completes, the terminal restart offer and model picker work, and Codex remains on its original account. A custom-folder chat gives the plain switch-back refusal on an account without its history and resumes the same conversation after returning to System default. Narrow real-agent verification also passed on merged heada9d0cba264ff: idle A→B→A with context, uninterrupted busy completion followed by B, custom-folder refusal and same-chat recovery, picker, terminal restart offer and pinned Codex.QA used real Claude and Codex through the load balancers, with fabricated account identities in isolated test homes. Both builds completed the same 120-second busy task. The first idle-chat model differed between builds; both busy chats used the same model, and an additional explicit-model control reproduced main staying on A. The custom-folder setup needed a harmless initial environment seed because the Environment editor is hidden until a value exists; the actual path and all account switches were then entered through the UI. Shared approval reprompts were observed on both builds. SSH, WSL, Windows, mixed hosts, folder workspaces and accepting the terminal restart action were not exercised by this macOS run.
Final-head verification
On
a9d0cba264ffd639854cc4876992459da5c48fd3, real-agent QA passed every required continuation and recovery path on the admitted M4Air after rebuilding that commit. The earlier main comparison remains the baseline; the final-head run repeated the normal and custom-folder main paths. The 45-second busy shell task finished on A without interruption, and its next turn used B. Full PR CI and the separate WSL workflow passed on this head.Readiness remains blocked on the pending chat-versus-terminal policy and OpenCode scope decisions. QA also confirmed the existing account-switch toast incorrectly says all running sessions keep their account; its wording and the terminal-only setting title await the same policy decision. No review completion marker has been posted.
Testing
Host flow: after a switch, the next message goes to a new agent on the new account, and later messages stay on it.
The outgrown check: it replaces an idle agent on another account and keeps it in these cases:
Claude contract: at each route (managed account, System default), the account the check reads equals the folder the launch uses. Without account routing, Claude chats are not compared.
Model list: a moved chat saves and reads under the account it runs on, and the account it was created on stays untouched.
Neighbouring host, Claude adapter and model-list suites pass.
Custom home: four routing tests pass. A source and filesystem reproduction verifies the initial custom-home resume, the plain refusal on the managed account, and resuming the same conversation after switching back, with the transcript unchanged. Real Electron QA also confirmed the plain refusal and same-conversation recovery. The byte-unchanged transcript result applies only to the source/filesystem reproduction; the real CLI writes its transcript during normal turns.
Real Electron QA on M4Air: all requested normal and custom-folder paths passed on d951264 against main e01a539; 51 full-window screenshots uploaded. Narrow final-head continuation QA passed on a9d0cba; 22 fresh full-window screenshots uploaded. The exact-head PR workflow aggregate and separate WSL workflow also passed.
I manually tested these changes locally (real-agent QA on the admitted M4Air)
Automated tests added/updated, or explained why not below
Review
Agent skill upstream boundary
Notes
CLAUDE_CONFIG_DIRoutside the shared history folders now gets the same refusal when it switches to an account that cannot see its transcript. Switching back to System default resumes the original conversation. Sharing history with those custom folders is temporary follow-up work tracked in STA-11300; this PR does not change users' folder links.Checklist
N/Awith reasonpnpm lint,pnpm typecheck,pnpm test, andpnpm buildpass (or CI will cover; local preferred)