Sessions Integration Feature

Nucleic-Session: FC94353F-9F0D-4BCC-AD7C-0FB14E38C2E5
Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
2026-07-05 01:54:13 -07:00
co-authored by Nucleic
parent bf0d0a587e
commit e255ad18ba
@@ -614,25 +614,38 @@ final class RemoteStore: ObservableObject {
}
/// Unpair this device entirely — drop every paired Mac and its connection (the "Unpair this
/// device" button). Nothing left to show, so the app returns to the pairing intro.
func unpair() {
// Forget + drop the active Mac's connection specifically (the switcher may have made it not
// the last). Other Macs' connections keep running.
if let id = activeHostID {
connections[id]?.teardown()
connections[id] = nil
IdentityStore.removePairedHost(id: id)
for (id, conn) in connections { conn.teardown(); connections[id] = nil }
for host in IdentityStore.pairedHosts() { IdentityStore.removePairedHost(id: host.fingerprint) }
IdentityStore.clearPairedHost()
finishUnpairIfEmpty()
}
/// Forget one paired Mac (the Settings ▸ Mesh per-row remove): drop just its connection +
/// registry record. Other Macs keep running and stay in the merged view.
func unpair(_ hostID: String) {
connections[hostID]?.teardown()
connections[hostID] = nil
IdentityStore.removePairedHost(id: hostID)
if IdentityStore.pairedHosts().isEmpty {
finishUnpairIfEmpty()
} else {
IdentityStore.clearPairedHost()
}
activeHostID = nil
// Mesh P3: if other Macs remain paired, switch to one (already connected) rather than unpairing.
if let next = IdentityStore.pairedHosts().last {
activeHostID = next.fingerprint
reconnect()
return
rebuildAggregate()
refreshAggregate()
}
}
/// Wind the app back to the unpaired state once no Macs remain: clear the open transcript + flat
/// aggregate and spin the embedded Tailscale node down.
private func finishUnpairIfEmpty() {
openSessionID = nil
openSessionHostID = nil
openEvents = []; openApprovals = []; openDiff = nil; diffLoading = false
connectivity = .unpaired
sessions = []
dashboard = .empty
// Nothing left to dial — spin the embedded Tailscale node down if it was running.
Task { await TailnetNode.shared.stop() }
tailnetStatus = nil