WelcomeModel, CollaborationSession, and AuthFailure all hand-rolled
String(describing:) variants to dodge NSError bridging or the enum-case
form. With Frida.Error now formatting itself, these collapse to plain
localizedDescription / String(describing:).
Bootstrap and the token onChange both triggered refreshLabs on
launch; the second call cancelled the first, whose defer tore down
the shared remote device and closed the new fetch's transport.
A lab now always has a picture. The client fetches the
signed-in user's GitHub avatar before sending .create
/labs and submits its bytes as the initial picture; if
the avatar fetch fails, lab creation is aborted with an
error rather than producing a pictureless lab.
Drop the remove-picture flow on both sides — the owner
can still upload a replacement, but there's no way to
clear the picture, since the data model now requires
one. With the invariant in place, LabSummary's picture
fields and the welcome-screen lab rows no longer carry
fallback paths to the owner's avatar.
Replace the auto-reopen-last-document flow with a welcome
screen that lets the user start a new project, open one
from disk, or — after signing in with GitHub — pick from
a list of labs they're a member of. The list is fetched
via a new transient portal connection that issues
.list /labs and disconnects.
Token persistence on macOS now goes through a file under
~/Library/Application Support/re.frida.Luma/tokens/ to
avoid the per-launch keychain prompt that dev-signed
builds suffer; iOS keeps using the keychain. GitHubAuth
caches the load Task so concurrent waiters share one
keychain access, and now flips state to .authenticated
when a persisted token is loaded so the welcome view
shows the labs section right away. requestToken awaits
the load before falling through to a fresh sign-in.
Engine accepts an injected GitHubAuth so the welcome
window and any subsequently-opened document share one
auth instance — no second sign-in prompt when crossing
from welcome to a document.