Skip to content

fix: pair-first Setup order and an actionable Add by Address failure message (#95) - #97

Merged
MegaManSec merged 4 commits into
docs/readme-screenshot-refreshfrom
fix/pair-first-setup
Aug 6, 2026
Merged

fix: pair-first Setup order and an actionable Add by Address failure message (#95)#97
MegaManSec merged 4 commits into
docs/readme-screenshot-refreshfrom
fix/pair-first-setup

Conversation

@MegaManSec

@MegaManSec MegaManSec commented Aug 6, 2026

Copy link
Copy Markdown
Owner

Follow-ups from #95. Stacked on #96 (both edit the same Setup sections) — merge #96 first, then re-target this to main.

docs: Add by Address can't work before pairing — an unpaired Mac refuses every connection before the handshake (IncomingConnection.start()), so the add fails — yet Setup ordered the Macs tab before the Pairing tab. Swap steps 3 and 4 (pairing needs no connectivity, so pair-first is safe in every flow), state the prerequisite in both sections, and add a Troubleshooting bullet for the one case the INTRODUCE exchange can't heal: both Macs changing IP at once on a Bonjour-blocked network.

fix: the dialing side can't distinguish an unpaired peer from a firewall drop, a dead host, or a different service answering on the port — and "didn't respond" steered #95's reporter at the network when the fix was pairing. Every unreachable-shaped failure (connect timeout/failure; handshake timeout, close, send failure, framing garbage) now shares one Add-by-Address message naming the causes: "Couldn't reach the other Mac securely. Check that it's running Magic Switch and paired with the same code (Settings → Pairing), and that no firewall is blocking the port." Auth failures keep their precise wording, and dialing before this Mac's own listener is bound now says so (.listenerNotReady) instead of blaming the peer. Scoped to ManualAddError — switch-notification messages untouched.

Not built in Xcode here, but swiftc -typecheck against the macOS SDK passes — please build before merging.

…d 4 (#95)

An unpaired Mac refuses incoming connections outright, so Add by Address
can only ever time out until both sides hold the pairing key — yet Setup
walked through the Macs tab (including Add by Address) before the Pairing
tab. Pairing needs no connectivity, so pairing-first is safe in every
flow. Say so explicitly in both sections, and document the one endpoint
staleness case the INTRODUCE exchange can't heal: both Macs changing IP
at once on a Bonjour-blocked network.
…95)

An unpaired peer cancels the connection before the handshake, which the
dialing side can't tell apart from a firewall drop or a dead host — the
sheet just said the other Mac "didn't respond", steering users at the
network when the actual fix is usually pairing first. Give the four
unreachable-shaped failures one message naming all three causes; auth
failures keep their precise wording.
- A peer reset can land while the handshake nonce send is in flight
  (handshakeFailed(.sendFailed)), and a non-Magic-Switch service
  answering on the port yields framingFailed/frameTooLarge — the same
  unreachable shape, previously falling through to the generic
  secure-connection message. Fold all three into the lumped case.
- Point at Settings → Pairing in that message, matching .notPaired.
- Dialing before this Mac's own listener is bound reported the local
  condition as a peer-shaped connection failure; fail early with a
  dedicated .listenerNotReady message instead.
- README: an unpaired Mac refuses the connection immediately, so say
  the add fails rather than times out.
@MegaManSec
MegaManSec merged commit eaf6b6b into docs/readme-screenshot-refresh Aug 6, 2026
@MegaManSec
MegaManSec deleted the fix/pair-first-setup branch August 6, 2026 23:16
MegaManSec added a commit that referenced this pull request Aug 6, 2026
* docs: recapture README screenshots against the Macs-era UI

Every annotated screenshot predated the July/August UI work: the Device
tab rename to Macs (with Sync and Add by Address), battery levels in the
menu and peripheral rows, the uniform action pills, the keyboard-shortcut
recorders, and the display-connect list. Recapture all of them, add the
previously unillustrated Add a Mac by Address sheet, and update the
annotation script's coordinates and legends to match (device-tab becomes
macs-tab; sections without a raw capture are now skipped instead of
aborting). README captions follow: battery levels in the hero and
Peripheral tab, the new sheet figure in Setup, and an Other-tab caption
that matches the scrolled capture.

The four Pairing screenshots are still the old captures.

* docs: stitch the full Other tab and keep the icon'd type-picker capture

The Other tab outgrew the window, so one scrolled capture hid either the
top or the bottom. Stitch three scrolled captures into a single
full-height raw — slices cut on flat background between sections, aligned
by crop offset, overlay scrollbar painted out — and re-badge all six
affordances. Revert peripheral-type-picker.png to the previous capture:
menu-item icons only render on macOS 26, and the recapture came from a
Sequoia Mac, so its picker menu was text-only.

* docs: recapture the menu in its reachable state, badge the display row itself

- menu.png previously showed every row greyed out (peer unreachable) —
  the state Troubleshooting teaches as "can't switch" — under a caption
  inviting clicks. Recaptured with the other Mac online; legend background
  re-matched to the new capture's material.
- The Other tab's badge 5 pointed at the marked display's trash button
  while its legend line describes the row; aim it at the row title.
- docs/assets/raw/ is local input to annotate-screenshots.sh — gitignore
  it so stray git add -A can't commit raw captures.

* Pair-first Setup order and an actionable Add by Address failure message (#95) (#97)

* docs: pair the Macs before connecting them — reorder Setup steps 3 and 4 (#95)

An unpaired Mac refuses incoming connections outright, so Add by Address
can only ever time out until both sides hold the pairing key — yet Setup
walked through the Macs tab (including Add by Address) before the Pairing
tab. Pairing needs no connectivity, so pairing-first is safe in every
flow. Say so explicitly in both sections, and document the one endpoint
staleness case the INTRODUCE exchange can't heal: both Macs changing IP
at once on a Bonjour-blocked network.

* fix: name the likely causes when Add by Address can't reach the peer (#95)

An unpaired peer cancels the connection before the handshake, which the
dialing side can't tell apart from a firewall drop or a dead host — the
sheet just said the other Mac "didn't respond", steering users at the
network when the actual fix is usually pairing first. Give the four
unreachable-shaped failures one message naming all three causes; auth
failures keep their precise wording.

* fix: cover every unreachable-shaped Add by Address failure (#95)

- A peer reset can land while the handshake nonce send is in flight
  (handshakeFailed(.sendFailed)), and a non-Magic-Switch service
  answering on the port yields framingFailed/frameTooLarge — the same
  unreachable shape, previously falling through to the generic
  secure-connection message. Fold all three into the lumped case.
- Point at Settings → Pairing in that message, matching .notPaired.
- Dialing before this Mac's own listener is bound reported the local
  condition as a peer-shaped connection failure; fail early with a
  dedicated .listenerNotReady message instead.
- README: an unpaired Mac refuses the connection immediately, so say
  the add fails rather than times out.
@MegaManSec MegaManSec changed the title Pair-first Setup order and an actionable Add by Address failure message (#95) fix: pair-first Setup order and an actionable Add by Address failure message (#95) Aug 7, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant