Skip to content

cmux NEXT: Invite People copies the invite link; Invite and Remove run in turn - #34656

Merged
teamleaderleo merged 9 commits into
feat-cmux-nextfrom
feat-next-share-invite-link-sheet
Nov 4, 2026
Merged

teamleaderleo merged 9 commits into
feat-cmux-nextfrom
feat-next-share-invite-link-sheet

Conversation

@teamleaderleo

@teamleaderleo teamleaderleo commented Nov 4, 2026 •

Copy link
Copy Markdown
Collaborator

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's invite_url on 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 --json keeps the invite link. AgentSessionShare decodes invite_url, and the agent.share.list result carries it (the router-review follow-up on cmux daemon: chat-share invites answer their invite link #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 carries invite_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

lawrencecchen and others added 4 commits November 4, 2026 01:39
The arch ratchet row app_lines is red on feat-cmux-next: CmuxNextApp
Swift lines +231 over the last green arch tip 3232840. The cause is
26fd471 (#33967), which added the Invite People sheet views to
CmuxNextApp (+361 lines). Later commits removed 130 App lines.

This change moves the sheet views to CmuxNextNotifications, a ui-layer
target that already declares CmuxNextDaemonService (the sheet model)
and CmuxNextDesign (the design kit), and that CmuxNextAppTests declares:
- AgentShareInviteCard (Share/AgentShareInviteCard.swift)
- AgentShareInviteRowView (Share/AgentShareInviteRowView.swift)

Only the presenter stays in CmuxNextApp, in the old file
Share/AgentShareInviteSheet.swift (AgentShareInviteSheetPresenter:
the overlay host, AppServices, the first load). CmuxNextNotifications
does not declare CmuxNextIcons, so the presenter gives the card its close
icon (the same NSImage.icon(.actionClose, size: 12) as before).

The card is package access: its init, onClose, focusField, and the
members that the compiler requires (the overrides, the required init and
the text field delegate methods). The row view stays internal. No
Package.swift change, no new target and no new dependency edge.

The behavior does not change. AgentShareTests imports
CmuxNextNotifications and gives the card an empty close image.

Takes back #33967: its Invite People views are in CmuxNextApp, which
made the app_lines arch ratchet red at the feat-cmux-next tip.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… share changes, runs steps in order

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-b443a4be4f9b3a1f457e
…hanges, runs Invite and Remove in order

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Agent-Session: https://cmux.com/deeplink/agent?id=aid-b443a4be4f9b3a1f457e
@github-actions

github-actions Bot commented Nov 4, 2026 •

Copy link
Copy Markdown
Contributor

cmux status (one comment, edited in place; each line is updated by the job that owns it)

Review 75ca4d9: HQ feed card · gallery before/after runs · checks

App of this head (app.zip, kept 1 day)

gh workflow run reload-build.yml -R manaflow-ai/cmux --ref feat-cmux-next -f tag=pr34656 -f ref=feat-next-share-invite-link-sheet -f platform=macos -f backend_mode=local

red: cmux-next checks (god files, concurrency, crash safety, l10n); NEW: red check: Main-thread concurrency is not red on the base 458fdc0; do not merge until green; see lane-rules

Shipped in:

@github-actions github-actions Bot added the risk:normal Risk tier (docs/ci/risk-tiers.md) label Nov 4, 2026
@blacksmith-sh

blacksmith-sh Bot commented Nov 4, 2026 •

Copy link
Copy Markdown

Found 6 test failures on Blacksmith runners:

Failures

Test View Logs
/tmp/tmp1s50ic7k/summary-missing.json (live):/summary-missing.json (live): View Logs
/tmp/tmpprp50dpr/summary-fail.json (live):/summary-fail.json (live): View Logs
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows/
[new_workspaces] debug.new_workspace timed 0 of 50 new workspace rows
View Logs
[new_workspaces] the window draws no frames/[new_workspaces] the window draws no frames View Logs
[tabs] debug.tab_switch timed 0 of 40 switches/
[tabs] debug.tab_switch timed 0 of 40 switches
View Logs
[tabs] the window draws no frames/[tabs] the window draws no frames View Logs

Fix with [code]smith
Need help on this PR? Tag @codesmith-bot with what you need.

@teamleaderleo teamleaderleo changed the title cmux NEXT: Invite People copies the invite link and refreshes while open cmux NEXT: Invite People copies the invite link; Invite and Remove run in turn Nov 4, 2026
…hare-invite-link-sheet

# Conflicts:
#	Packages/macOS/CmuxNext/Sources/CmuxNextNotifications/Share/AgentShareInviteCard.swift
@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent claude-opus-5-5 medium): SHIP at 664a8aa
Visual verdict: no images; Leo tries the build

I read the full diff and the card at the head.

  • Invite and Remove steps run in the order pressed. The chain can't deadlock, drops no step and leaks nothing.
  • The Copied reset holds the model weakly on the main actor, and a second press cancels the first timer.
  • invite_url is read with decodeIfPresent, so older daemons still decode.
  • The card picks up inviteLink and copied through observation tracking. Rows get values and a closure only.
  • The diff uses Swift 6.0 syntax.
  • The order test fails on the old behaviour.

Follow-ups (filed on #33746):

  1. [follow-up] AgentShareInviteCard.swift:122-123: with no link, the row is only at alpha 0, so VoiceOver still sees an empty label and a disabled button. Hide them from accessibility while there is no link.
  2. [follow-up] AgentShare.xcstrings: the new zh-Hans strings use 拷贝, but the existing strings in the file use 复制. Use 复制.
  3. [follow-up] theCardsCopyInviteLinkConfirmsInPlace doesn't check that the button keeps its width across Copy and Copied.
  4. [follow-up] AgentShareInviteSheetModel.swift:178-189: if the link goes away during the 1.5 s Copied window, copied stays true until the timer ends. The row is invisible then, so nothing shows.

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (subagent claude-opus-5-5 medium): SHIP at 75ca4d9
Visual verdict: unchanged by this diff

This head adds one commit on top of the SHIP at 664a8aa: the Copied reset uses the one-shot DemandTimer instead of Task.sleep, because the CI concurrency guard refused the sleep. Checked: CmuxNextDaemonService already depends on CmuxNextWakeups. The @ObservationIgnored let timer is valid on the @MainActor @Observable model. The @MainActor [weak self] action has the same shape the target already uses elsewhere. A re-press still resets the deadline, and the existing test still holds.

Follow-ups: none

@teamleaderleo

Copy link
Copy Markdown
Collaborator Author

Review (codex gpt-6.1-sol xhigh, router-review): SHIP at 75ca4d9
Visual verdict: no images supplied (range review); the visual verdict must come separately

  1. [P2] [follow-up] [category:correctness] [finding:F1] [outcome:pending] AgentShareInvites.swift:160: The bundled daemon’s LinkShare::shown() never emits invite_url, so this property always decodes as nil and Copy Invite Link remains unavailable after successful invites. Emit the field from the daemon or derive it from room and share_id; cover the real response path, since the added tests inject the URL directly.

Follow-ups:

  • F1: Connect the invite-link field to the daemon response and verify that path.

router-review: follow-up: F1: Connect the invite-link field to the daemon response and verify that path.
router-review: SHIP at 75ca4d9 (gpt-6.1-sol xhigh); 1 follow-up(s) to file as issues

F1 is already done: #34634 (merged, squash 3ec06b9) makes LinkShare::shown() and the invite answer emit invite_url (<room origin>/i/<share_id>), with daemon tests for invite, repeat invite and list. This range review's base predates that merge. (Posted by the PR's owner: router-review ran in range form because the shared GraphQL quota was spent.)

@teamleaderleo
teamleaderleo merged commit 8b17832 into feat-cmux-next Nov 4, 2026
155 of 160 checks passed
@lawrencecchen

Copy link
Copy Markdown
Contributor

Swift logic follow-up (tip watcher swift-logic row, STATUS 13027 "SWIFT LOGIC CULPRITS"; lead order).

This PR raised swift_logic_lines by +57 at its merge commit 8b17832: scripts/cmux-next/swift-logic-lines.py before and after the merge, with the same table (the tip's, c6be943). The largest declarations of the rise:

  • class AgentShareInviteSheetModel in Packages/macOS/CmuxNext/Sources/CmuxNextDaemonService/AgentShareInviteSheetModel.swift: +45 lines counted as Swift logic (no row in plans/cmux-next/swift-logic-classes.tsv)
  • enum AgentShareInvites in Packages/macOS/CmuxNext/Sources/CmuxNextDaemonService/AgentShareInvites.swift: +10 lines counted as Swift logic (no row in plans/cmux-next/swift-logic-classes.tsv)
  • enum AgentShareResults in Packages/macOS/CmuxNext/Sources/CmuxNextDaemonService/AgentShareResults.swift: +1 lines counted as Swift logic (its row counts it as logic)
  • extension AgentShareActions in Packages/macOS/CmuxNext/Sources/CmuxNextDaemonService/AgentShareInvites.swift: +1 lines counted as Swift logic (no row in plans/cmux-next/swift-logic-classes.tsv)

plans/cmux-next/layer-ownership.md says Rust owns every state, list and rule and Swift is the platform shell. Please move the new logic of this PR in a follow-up: to Rust (the crate that owns the area; the owner lists in STATUS 12147-12165 name the target per area), or at least out of the app into its package. If a declaration above is platform code (AppKit, Core Animation, OS calls, strings, tokens, DEBUG tooling), reply here and the table gets a PLATFORM row with your reason instead.

The swift-logic row is a report, not a gate: nothing blocks on this comment.

This branch was previously deployed

1 inactive deployment
ci-routing-agent — 75ca4d91 Deployed Nov 4, 2026 by teamleaderleo via cmux-tui tree preflight #110005
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

risk:normal Risk tier (docs/ci/risk-tiers.md)

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants