Repository navigation
feat: mark provider switches in the timeline and stack thread provider icons - #2275
Merged
Merged
Conversation
… and handoff.read
Moves the append-once-loaded helper into the thread store so the switch marker, like a revert receipt, shows once whether the push or the load wins. Adds readHandoff for handoff.read.
…to their provider
The sidebar stack draws the provider before the current one from the newest other entry. First-use order picked the wrong provider after a return trip such as Claude to Codex to Cursor and back to Codex.
…andoff and gutter reply icons
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
Closes #2234.
Before this change, a provider switch left no trace in the timeline, and the thread kept one provider icon.
Now a switched thread shows the following:
A thread that never switched renders exactly as before.
The marker's sequence is reserved when the switch is armed, so it stays before the reply even when the save lands after the reply was accepted. The handoff audit is still written to disk under the id the marker carries, for debugging.
Verified live in Electron with a real Claude Haiku turn followed by a GPT-6 Astra turn in
.dev/fixture-repo. The marker reads "Claude→Codex" and the thread row stacks both icons. A thread switched on the base build, which has noproviders_used, still shows no marker and one icon. Targeted tests pass: the server handoff and switch suites at 104 of 104, the web conversation and store suites at 1405 of 1405, and shared at 162 of 162, withbun run typecheckat 10 of 10 tasks.Why
When a user moves a running thread from one provider to another, they need to see where the switch happened. Without that, a reply from Codex reads as if Claude wrote it. The sidebar stack lets users spot mixed-provider threads without opening them.
UI Changes
Before: a Claude to Codex switch on
main. There is no marker, replies carry no provider, and the sidebar shows one icon.After: the same flow on this branch, with the marker and the stacked sidebar icon.
Review Notes
0096adds two nullable columns:messages.provider_switchandthreads.providers_used. Stable and nightly builds share the database. The marker is a plainrole: "system"message rather than a newsystemNoticekind because older builds parsesystemNoticestrictly. Older builds show the marker as plain text and ignore both columns.validateThreadId, which rejects any.., and a handoff directory name must be a ULID. Tests cover traversal attempts.providers_used.agent.send.