From 12ae442975e4a041583362bce87e8c29a352a6b3 Mon Sep 17 00:00:00 2001 From: Joshua Rogers Date: Sat, 31 Oct 2026 00:47:27 +0000 Subject: [PATCH 1/2] chore: drop comments that justify #149 and fix connectPeripheral docs --- .hooks/pre-commit | 2 +- .../Store/BluetoothPeripheralStore.swift | 29 +++++-------------- 2 files changed, 8 insertions(+), 23 deletions(-) diff --git a/.hooks/pre-commit b/.hooks/pre-commit index 30151cd..3ddb647 100755 --- a/.hooks/pre-commit +++ b/.hooks/pre-commit @@ -1,5 +1,5 @@ #!/bin/bash -# Format the staged copy of each Swift file, so unstaged edits never enter the commit. +# Format the staged copy of each Swift file. export GIT_LITERAL_PATHSPECS=1 if ! swift format --version >/dev/null 2>&1; then diff --git a/Magic Switch/Model/Store/BluetoothPeripheralStore.swift b/Magic Switch/Model/Store/BluetoothPeripheralStore.swift index dbaad0a..a0b3107 100644 --- a/Magic Switch/Model/Store/BluetoothPeripheralStore.swift +++ b/Magic Switch/Model/Store/BluetoothPeripheralStore.swift @@ -925,9 +925,7 @@ final class BluetoothPeripheralStore: NSObject, ObservableObject, BluetoothPerip /// /// Falls back to a plain local pair if there's no trusted paired peer, if /// neither Bonjour nor the last reachability probe (which also tries BLE) - /// sees it, or if the release request can't reach it. Bonjour inactivity - /// alone doesn't imply unreachability: the authenticated command can also - /// travel over BLE. + /// sees it, or if the release request can't reach it. /// /// If the take fails — or the peer releases but the local connect doesn't /// take (a stuck device needing a power-cycle) — the auto-reconnect watcher @@ -1238,15 +1236,9 @@ final class BluetoothPeripheralStore: NSObject, ObservableObject, BluetoothPerip /// and re-paired within the same attempt. A record that says /// `paired=true` while the device refuses the bonded connect is the /// stale-bond signature: the device actually answers to the other Mac - /// (a handoff outside the app, or desynced state). Every caller - /// additionally requires a successful remote name request — a - /// healthy bond whose device is merely off or out of range must survive, - /// or the automatic reconnect macOS performs when it returns is lost, and - /// an unbonded Magic device stops answering entirely until it is power - /// cycled. An absent peer says nothing about whether the peripheral is - /// present. The watcher's reclaim - /// retries pass `false` and keep retrying the plain open, so a transient - /// link failure in a retry loop can't repeatedly tear bonds down. + /// (a handoff outside the app, or desynced state). The record is only + /// removed when the device answers a page (`answersPage`). The watcher's + /// reclaim retries pass `false` and keep retrying the plain open. private func connectPeripheral( _ peripheral: BluetoothPeripheral, announcePairTimeout: Bool, @@ -1342,10 +1334,8 @@ final class BluetoothPeripheralStore: NSObject, ObservableObject, BluetoothPerip ) return } - // A synchronous name request pages the device without requiring a - // bond. RSSI only works on a live connection and cannot prove a - // disconnected device is present. Preserve the bond if macOS - // reconnected it while the request was in flight. + // Preserve the bond if macOS reconnected it while the request was in + // flight. guard self.isCurrentAttempt(attempt, for: peripheral.id) else { return } if btDevice.isConnected() { self.setConnectionState(.connected, for: peripheral.id) @@ -1377,8 +1367,6 @@ final class BluetoothPeripheralStore: NSObject, ObservableObject, BluetoothPerip device: IOBluetoothDevice, attempt: UInt64 ) { - // Disconnected devices have no readable RSSI. Let pairing page them; - // the existing watchdog bounds an attempt when a device is absent. guard let devicePair = IOBluetoothDevicePair(device: device) else { Log.bluetooth.error("Failed to initialize pairing for \(peripheral.name)") failConnectAttempt( @@ -1457,8 +1445,6 @@ final class BluetoothPeripheralStore: NSObject, ObservableObject, BluetoothPerip completion(btDevice) return } - // Re-checked after the blocking name request the caller just ran: a - // cancel landing in that window must not lose the bond it can't re-pair. guard isCurrentAttempt(attempt, for: id) else { return } btDevice.perform(Selector(("remove"))) Log.bluetooth.notice("Removed stale local pairing before taking \(name)") @@ -2368,8 +2354,7 @@ final class BluetoothPeripheralStore: NSObject, ObservableObject, BluetoothPerip } /// Whether `device` answers a page within `Constants.presencePageTimeout`. - /// A remote name request needs no bond or live link, unlike `rssi()`, which - /// only reads a connected device. Blocks; call on `bluetoothQueue`. + /// Blocks; call on `bluetoothQueue`. private func answersPage(_ device: IOBluetoothDevice) -> Bool { device.remoteNameRequest(nil, withPageTimeout: Constants.presencePageTimeout) == kIOReturnSuccess From 2e3461f4ccf1e412fec07c0bcaeff6ac71a32dd0 Mon Sep 17 00:00:00 2001 From: Joshua Rogers Date: Sat, 31 Oct 2026 00:47:27 +0000 Subject: [PATCH 2/2] ci(release): let Verify release decide the release job semantic-release posts PR comments after publishing; if that step fails the job failed even though the release exists, skipping app-store and homebrew-tap. --- .github/workflows/release.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 339434e..b75f34d 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -345,6 +345,7 @@ jobs: run: pnpm install --frozen-lockfile - name: Release + continue-on-error: true env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} run: ./.github/release/node_modules/.bin/semantic-release