- Loopback address per task instead of port blocks
Give each task its own loopback address (127.0.0.10, 127.0.0.11, …) where it runs servers on their usual ports, in place of the ten-port block it gets now. On macOS only 127.0.0.1 is configured on lo0: binding 127.0.0.10 fails with "Can't assign requested address" (errno 49) until an alias is added (`sudo ifconfig lo0 alias 127.0.0.10 up`), and aliases are gone after a reboot. So byre needs a root step that adds the aliases at every boot (a LaunchDaemon installed with the app, or the server's install step), and a check that they're there. Test it first: add an alias, bind a server to it on a common port while another task holds the same port on another address, and confirm the preview forwards and `expose_port` work with it.
A native client for the phone over the same API, sharing the macOS client's SwiftUI code where it can. Every surveyed tool has one (Claude, Codex, Cursor and Conductor apps, GitHub Mobile, Superset for iPhone); it needs its own layout, since two half-width panes don't fit a phone.