prompt:
Set up cmux (manaflow's terminal,
cmux.com) as my control plane for mac <> dev boxes <> iphone. Tailscale is on every device, phone is cabled to the Mac. Do all of it end to end:
1. Adaptive SSH. Make `ssh <box>` smart for each dev box: LAN when I'm home (probe with ~1s timeout), Tailscale everywhere else, one alias per box. Two gotchas:
- macOS Local Network privacy silently blocks non-Apple binaries (including homebrew ssh) from LAN IPs with "No route to host" unless the hosting app has the permission. Route the TCP connection through a ProxyCommand script built on Apple's /usr/bin/nc so it works in every app, and keep HostName pinned to the Tailscale IP so known_hosts stays stable.
- mDNS names take 1-2s to resolve, too slow to probe. Gate those on a subnet check instead.
2. cmux workspaces. One SSH workspace per box on the adaptive aliases (cmux ssh <alias> --name <box>). The remote PTY daemon survives sleep and network flips.
3. iPhone app. The official TestFlight build is paywalled, but the iOS app is GPL in the cmux repo. Build and sideload it with my free Apple ID (cable Xcode):
- run scripts/ensure-ghosttykit.sh first; it fetches the prebuilt GhosttyKit.xcframework. Do NOT zig-build it.
- ios/scripts/reload.sh --tag <me> --device-only --team <team id>
- free personal teams cannot sign Sign In with Apple, aps-environment, or time-sensitive notifications. Strip all three from ios/Config/cmux.entitlements and sign in with Google/email instead.
- CRITICAL: DEBUG builds auth against cmux's dev backend, and a release Mac app rejects the pairing with a "matching build" error. Force isDevelopmentBuild to false in ios/cmuxPackage/Sources/cmuxFeature/MobileAuthComposition.swift.
- device install needs the phone unlocked once while cabled (DDI mount). If pairingState goes "unpaired": re-trust, then `xcrun devicectl manage pair`.
4. Pairing. The Mac-side iOS pairing listener is OFF by default:
defaults write
com.cmuxterm.app "mobile.iOSPairingHost.enabled" -bool true
Relaunch cmux and verify a non-localhost listener with lsof. Pair from the phone via the command palette entry "Connect iPhone/iPad" (Cmd Shift P), same cmux account on both ends, Tailscale on. On the phone, the terminal icon in the nav bar switches between a workspace's terminals.
5. Self-renewal. Free-team signing profiles expire every 7 days. Install a launchd agent that checks the installed embedded.mobileprovision every 2h and silently re-signs via
reload.sh whenever expiry is <=3 days away and the phone happens to be cabled with developer services up. macOS notification on success/failure, daily nag if the deadline is close and the phone never showed up.
Verify every step with real commands (ssh round-trips, lsof on the listener, profile expiry parse) before calling it done.