cmux NEXT: Invite People copies the invite link; Invite and Remove run in turn
Finishes the owner side of chat-share account invites in the Invite People sheet (design chat-multiplayer.md 2, leo-workspace design/chat-multiplayer.md). It uses the daemon's invite link from #34634 and closes two #33746 follow-ups.
What changes
- Copy Invite Link. The sheet shows the chat's invite link (
<room>/i/<share_id>, read from the daemon'sinvite_urlon the chat's invite share) and a quiet Copy Invite Link button. A press puts the link on the pasteboard, and the button reads Copied for 1.5 s in place, with no toast. The button is sized to its longer title, so the confirmation moves nothing. The row is always laid out and is clear and off until someone is invited, so the card keeps its size. share list --jsonkeeps the invite link.AgentSessionSharedecodesinvite_url, and theagent.share.listresult carries it (the router-review follow-up on #34634).- Invite and Remove run in turn. Each step waits for the one pressed before it. A Remove pressed while an Invite of the same account runs now lands after it, so the account ends removed. Before, the two could finish in either order.
The link comes from the daemon's invite_url (#34634). Against a daemon without it, the row stays clear and off. The live refresh while the sheet is open (#33746) needs a new declared protocol event (spec, SDK schema and generated bindings), so it gets its own PR; see the follow-up on #33746.
Localization audit
Two new strings in AgentShare.xcstrings: agentShare.sheet.copyLink ("Copy Invite Link") and agentShare.sheet.copied ("Copied"). Both are translated for every app locale: en, de, fr, ar, es, zh-Hant, zh-Hans, ko, ja. scripts/lint-xcstrings.py passes. No other user-facing text changed.
Tests (red first: the first commit adds the model tests)
theSheetCopiesTheInviteLinkAndSaysCopiedInPlace: link after the read, copy, Copied, then back. A chat with only a guest link has no invite link.anInviteAndARemoveOfOneAccountRunInTheOrderPressed: the Remove waits for the Invite.theListShowsInvitees: the list result carriesinvite_url(red-test commit, then the fix).theCardsCopyInviteLinkConfirmsInPlace(AppKit card): off before a link exists, then copies and retitles to Copied.
Risk: contained to the Invite People sheet and its model. Screenshots are a follow-up; Leo tries the DEV build.
Agent session: agent session
š¤ Generated with Claude Code