From 5852ce04e7500e7683df28fc165bb74641906e26 Mon Sep 17 00:00:00 2001 From: Andrew Blakeslee Moore Date: Sun, 5 Jul 2026 01:52:57 -0700 Subject: [PATCH] Sessions Integration Feature Nucleic-Session: FC94353F-9F0D-4BCC-AD7C-0FB14E38C2E5 Co-authored-by: Nucleic --- .../NucleicRemote/Models/RemoteStore.swift | 15 ++++++++------- 1 file changed, 8 insertions(+), 7 deletions(-) diff --git a/NucleicRemote/NucleicRemote/Models/RemoteStore.swift b/NucleicRemote/NucleicRemote/Models/RemoteStore.swift index e957e25..710cd6c 100644 --- a/NucleicRemote/NucleicRemote/Models/RemoteStore.swift +++ b/NucleicRemote/NucleicRemote/Models/RemoteStore.swift @@ -461,13 +461,14 @@ final class RemoteStore: ObservableObject { } /// The callbacks one `HostConnection` uses to drive shared/aggregate state. `hostID` is captured - /// so a change updates the flat projection only for the active host, while badges, notifications, - /// and the single open transcript are handled globally across hosts. + /// so the open-transcript forwarding fires only for the Mac that owns the open session, while the + /// merged list/dashboard, badges, and notifications are rebuilt across every host on any change. private func callbacks(for hostID: String) -> HostConnection.Callbacks { var cb = HostConnection.Callbacks() cb.didUpdate = { [weak self] in guard let self else { return } - if hostID == self.activeHostID { self.mirrorActive() } + // Any host's change re-merges the aggregate the flat state binds to (mesh P3). + self.rebuildAggregate() self.refreshAggregate() self.flushPendingNotificationDecision() // A host that just connected (or reconnected) needs the current Live Activity token @@ -475,22 +476,22 @@ final class RemoteStore: ObservableObject { self.syncLiveActivityRegistration() } cb.openSnapshot = { [weak self] snap in - guard let self, hostID == self.activeHostID, snap.summary.sessionID == self.openSessionID else { return } + guard let self, hostID == self.openSessionHostID, snap.summary.sessionID == self.openSessionID else { return } self.openEvents = snap.recentEvents self.openApprovals = snap.pendingApprovals } cb.openEvents = { [weak self] batch in - guard let self, hostID == self.activeHostID, batch.sessionID == self.openSessionID else { return } + guard let self, hostID == self.openSessionHostID, batch.sessionID == self.openSessionID else { return } self.openEvents.append(contentsOf: batch.events) } cb.openDiff = { [weak self] diff in - guard let self, hostID == self.activeHostID, diff.sessionID == self.openSessionID else { return } + guard let self, hostID == self.openSessionHostID, diff.sessionID == self.openSessionID else { return } self.openDiff = diff self.diffLoading = false } cb.approvalRequested = { [weak self] req, title in guard let self else { return } - if hostID == self.activeHostID, req.sessionID == self.openSessionID, + if hostID == self.openSessionHostID, req.sessionID == self.openSessionID, !self.openApprovals.contains(where: { $0.id == req.id }) { self.openApprovals.append(req) }