nvrsion: Add: Reconnect Icon Update, fix mesh iPhone discovery for new Macs, fix session order adjustment to pin sidebar sessions for remote projects, fix session status synchronization for remote viewer Macs, fix session order adjustment for iOS app session list, fix session status synchronization for remote sessions, fix iOS app live activity height by removing the “<n> files changed” line, fix Tool Call Card Mesh so AI bash summaries transit the mesh layer to other Macs, replace “Resolved by mac-ui” in transcripts with device ID, fix Chat: Print Wait Message, fix Chat: Reconnect Icon Update, fix Chat: Activity Theme Adjustment for “attention needed” live activity theme.

Nucleic-Promote: 1
Co-authored-by: Nucleic <[email protected]>
This commit is contained in:
2026-07-05 04:24:25 -07:00
co-authored by Nucleic
parent c9cffa55ca
commit 5168198656
9 changed files with 83 additions and 53 deletions
@@ -201,6 +201,18 @@ final class HostConnection {
relayMembershipToken: nil, relayURL: nil)
}
/// Whether the dialable endpoints of a gossiped record differ from the one on file — the
/// signal that a known Mac must be re-dialed (its LAN port, tailnet IP, or relay room moved).
/// Ignores relay *credentials* (token/URL), which `mergePairedHost` preserves and which don't
/// change where the Mac is reached.
private static func dialableAddressChanged(from existing: PairedHost, to incoming: PairedHost) -> Bool {
existing.lanHost != incoming.lanHost
|| existing.lanPort != incoming.lanPort
|| existing.tailnetHost != incoming.tailnetHost
|| existing.tailnetPort != incoming.tailnetPort
|| existing.relayRoomID != incoming.relayRoomID
}
/// Split a "host:port" hint (last-colon split so a bracketed IPv6 host survives).
private static func splitHostPort(_ hint: String?) -> (String?, UInt16?) {
guard let hint, let colon = hint.lastIndex(of: ":"),
@@ -478,8 +490,18 @@ final class HostConnection {
else { continue }
let fingerprint = member.staticPublicKey.fingerprintHex
guard fingerprint != self.hostID else { continue } // that's the Mac we're on
if IdentityStore.pairedHost(id: fingerprint) == nil { changed = true }
IdentityStore.mergePairedHost(Self.pairedHost(from: member))
let incoming = Self.pairedHost(from: member)
let existing = IdentityStore.pairedHost(id: fingerprint)
// Re-dial not only when a Mac is brand-new, but also when a known Mac's dialable
// address changed — a Mac's LAN port is OS-assigned (`.any`), so it lands on a
// fresh one every relaunch and re-gossips it. `mergePairedHost` updates the
// registry in place, but a connection already retrying the dead old address won't
// pick that up on its own (its retry loop reuses the address it was last handed),
// so without forcing a fresh reconnect here the phone never reconnects to it.
if existing == nil || Self.dialableAddressChanged(from: existing!, to: incoming) {
changed = true
}
IdentityStore.mergePairedHost(incoming)
}
for tombstone in push.tombstones {
// fingerprint = first 16 hex of the hostID (sha256 prefix), the registry key.
@@ -498,6 +520,10 @@ final class HostConnection {
// `fetchTranscript` this device sent. A phone pulls full history on demand via a
// dedicated fetch path (not this subscribe stream), so nothing to do here yet.
break
case .toolSummaries:
// Collapsed Bash summary lines the owner pushes to peer *Macs* (mesh session sync).
// The phone renders its own deterministic command summaries, so it ignores these.
break
case .relayMembership(let membership):
// The host issued/refreshed this device's relay credential (mesh P2). Persist it
// in place (no reordering — this can arrive from a non-active Mac) so the relay