fix(desktop): full-reset the thread runtime on a disjoint transcript swap

The incremental external-store runtime reconciles message repositories in place
(addOrUpdateMessage + prune-non-incoming). On a session switch the incoming
transcript shares no ids with the current one, and grafting the new chain onto
the old tree before pruning can strand a stale head/branch — the thread keeps
showing the previous session. When nothing carries over there's nothing to
preserve, so clear the tree first (leaves→root) then rebuild clean. Belt-and-
suspenders alongside the $messages-carryover fix.
This commit is contained in:
Brooklyn Nicholson 2026-07-14 17:20:35 -04:00
parent 7dc21f08a1
commit ec926ce89e

View file

@ -39,6 +39,17 @@ function syncRepositoryIncrementally(
): readonly ThreadMessage[] {
const repository = (runtime as unknown as { repository: ExternalStoreThreadRuntimeCore['repository'] }).repository
const incomingIds = new Set(messageRepository.messages.map(({ message }) => message.id))
const existing = repository.export().messages
// A thread switch swaps in a fully-DISJOINT transcript (no id carries over).
// Reconciling two unrelated trees in place — grafting the new chain onto the
// old one, then pruning — can strand a stale head/branch, so there's nothing
// to preserve: clear the tree first (leaves→root), then rebuild clean.
if (existing.length > 0 && !existing.some(({ message }) => incomingIds.has(message.id))) {
for (const { message } of [...existing].reverse()) {
repository.deleteMessage(message.id)
}
}
for (const { message, parentId } of messageRepository.messages) {
repository.addOrUpdateMessage(parentId, message)