From dbfd6213366d9a7366556f8be41d03f41040993e Mon Sep 17 00:00:00 2001 From: Andrew Blakeslee Moore Date: Sun, 5 Jul 2026 04:30:57 -0700 Subject: [PATCH] Session Sync Repair Nucleic-Session: 0C7BC346-0002-4533-ADDD-3B4C92E58527 Co-authored-by: Nucleic --- .../NucleicRemote/Models/RemoteStore.swift | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/NucleicRemote/NucleicRemote/Models/RemoteStore.swift b/NucleicRemote/NucleicRemote/Models/RemoteStore.swift index 97e1d0e..f5016b2 100644 --- a/NucleicRemote/NucleicRemote/Models/RemoteStore.swift +++ b/NucleicRemote/NucleicRemote/Models/RemoteStore.swift @@ -560,6 +560,20 @@ final class RemoteStore: ObservableObject { } } + /// Merge transcript events by `seq` (monotonic, globally unique within a session), keeping the + /// union sorted. Lets a reconnect's snapshot fold its events into the transcript already on + /// screen without duplicating what's shown or dropping history outside the host's tail window. + /// A fresh open merges into `[]`, so it's just the tail — the same result as a plain replace. + private static func mergedEvents(_ existing: [AgentEvent], _ incoming: [AgentEvent]) -> [AgentEvent] { + guard !existing.isEmpty else { return incoming } + guard !incoming.isEmpty else { return existing } + var bySeq: [UInt64: AgentEvent] = [:] + bySeq.reserveCapacity(existing.count + incoming.count) + for e in existing { bySeq[e.seq] = e } + for e in incoming { bySeq[e.seq] = e } + return bySeq.values.sorted { $0.seq < $1.seq } + } + /// The flat sessions list: every connected Mac's sessions, deduped by id (ids are globally /// unique). Views handle sorting/grouping. private func aggregatedSessions() -> [WireSessionSummary] {