Skip to content

iOS Computers: add "Add Computer" row at end of list - #6802

Merged
lawrencecchen merged 4 commits into
mainfrom
feat-add-computer-row
Jun 26, 2026
Merged

lawrencecchen merged 4 commits into
mainfrom
feat-add-computer-row

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Jun 26, 2026 •

Copy link
Copy Markdown
Contributor

Adds an "Add Computer" row at the end of the Computers list (iOS), matching the existing top-left toolbar add button. Users who scroll past their Macs can add another without scrolling back up.

Both entrypoints call one shared addComputer() action (present pairing flow, then dismiss). The row reuses the existing localized mobile.computers.add string (en + ja), so no new strings. Only shows when the add affordance is enabled (showAddDevice != nil).

🤖 Generated with Claude Code


View with Codesmith Autofix with Codesmith
Need help on this PR? Tag /codesmith with what you need. Autofix is disabled.


Note

Low Risk
UI-only affordances and string updates; no changes to pairing logic, auth, or data handling.

Overview
Improves discoverability of pairing on iOS by adding Add Computer in two places when showAddDevice is set: an end-of-list row on the Computers screen (same behavior as the toolbar +) and an item in the workspace Choose Mac menu after a divider (opens pairing without dismissing the list).

The Computers toolbar and list row now share a single addComputer() path (invoke showAddDevice, then dismiss). New accessibility IDs: MobileComputersAddRow and MobileWorkspaceMacPickerAdd.

Copy is standardized from "Add device" to Add Computer across pairing, disconnected shell, connection status, setup help, and Localizable.xcstrings (English and Japanese); localization keys are unchanged.

Reviewed by Cursor Bugbot for commit 7a4a441. Bugbot is set up for automated code reviews on this repo. Configure here.


Summary by cubic

Adds an "Add Computer" row at the end of the iOS Computers list and an "Add Computer" option in the "Choose Mac" menu, mirroring the toolbar add button. Standardizes the UI copy to "Add Computer" across pairing and help.

  • New Features

    • Toolbar button and bottom row share addComputer() (calls showAddDevice, then dismiss).
    • "Choose Mac" menu adds "Add Computer" after a divider; calls showAddDevice() (no dismiss).
    • Only shows when showAddDevice != nil.
    • Reuses mobile.computers.add (en, ja); adds MobileComputersAddRow and MobileWorkspaceMacPickerAdd accessibility IDs.
  • Bug Fixes

    • Renamed UI text from "Add device" to "Add Computer" in titles, buttons, form label, and LAN help; updated Localizable.xcstrings (en, ja). Localization keys unchanged.

Written for commit 7a4a441. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features
    • Added a more prominent “Add Computer” option at the end of the device list.
    • Added an “Add Computer” button in the Mac picker menu when pairing is available.
  • Bug Fixes
    • Unified the “Add Computer” flow so the toolbar and list entry trigger the same behavior.
  • Localization
    • Updated iOS UI text across the app to consistently use “Add Computer” terminology instead of “Add device.”

Mirror the top-left toolbar add button as an end-of-list row so users
who scroll past their Macs can add another without scrolling back up.
Both entrypoints share one addComputer() action path. Reuses the
existing localized mobile.computers.add string (en + ja).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@vercel

vercel Bot commented Jun 26, 2026 •

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
cmux Ready Ready Preview, Comment Jun 26, 2026 8:00am
cmux-staging Building Building Preview, Comment Jun 26, 2026 8:00am

@coderabbitai

coderabbitai Bot commented Jun 26, 2026 •

Copy link
Copy Markdown

Review Change Stack

Warning

Review limit reached

@lawrencecchen, we couldn't start this review because you've reached your PR review rate limit.

More reviews will be available in 3 seconds. Learn how PR review limits work.

To continue reviewing without waiting, enable usage-based billing in the billing tab.

⌛ How to resolve this issue?

After more reviews become available, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based credits.

🚦 How do rate limits work?

CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability.

For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window.

Please see our Fair Usage Limits Policy for further information.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: 5b9c073e-490c-4e14-bae1-c0f7667ab242

📥 Commits

Reviewing files that changed from the base of the PR and between 53144ea and 7a4a441.

📒 Files selected for processing (1)
  • ios/cmux/Resources/Localizable.xcstrings
📝 Walkthrough

Walkthrough

DeviceTreeView and the Mac picker now add conditional Add Computer entry points. The add-device screens and localization resources also switch fallback text and copied labels from “device” to “Computer”.

Changes

Add computer entry points

Layer / File(s) Summary
DeviceTreeView add row and shared action
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/DeviceTreeView.swift, Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceListView+MacSelection.swift
DeviceTreeView conditionally renders an Add Computer row and shares its add-and-dismiss helper with the toolbar button, while the Mac picker menu adds a conditional Add Computer button with a divider and accessibility identifier.
Add Computer copy updates
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/DisconnectedWorkspaceShellView.swift, Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/MobileMacConnectionStatusRow.swift, Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/PairingView.swift, Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/SetupHelpView.swift, ios/cmux/Resources/Localizable.xcstrings
Fallback strings and localized values for the add-device button, pairing view titles, accessibility labels, and LAN guidance are updated to use Add Computer terminology in English and Japanese.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Possibly related PRs

  • manaflow-ai/cmux#5648: modifies the iOS device-tree UI in DeviceTreeView.swift, which is directly related to the new Add Computer row and shared action.
  • manaflow-ai/cmux#5714: touches SetupHelpView network/LAN guidance that this PR also updates for the Add Computer wording.

Poem

A little rabbit gave a hop,
And changed the labels at the top.
“Add Computer” now gleams with cheer,
In menus, rows, and strings held dear.
🐇✨

🚥 Pre-merge checks | ✅ 24 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Description check ⚠️ Warning The PR description covers the summary and rationale, but it omits the required Testing, Demo Video, Review Trigger, and Checklist sections. Add the missing template sections, especially testing details, a demo video link if applicable, the review trigger block, and the checklist items.
✅ Passed checks (24 passed)
Check name Status Explanation
Title check ✅ Passed The title is concise, specific, and matches the main change: adding an Add Computer row to the iOS Computers list.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.
Cmux Swift Actor Isolation ✅ Passed PR only adds SwiftUI view affordances and localized copy; no new actor annotations, Sendable references, or background store access were introduced.
Cmux Swift Blocking Runtime ✅ Passed No new waits, sleeps, locks, or main-thread syncs appear in the touched Swift files; the diff only adds UI actions and copy.
Cmux Browser Automation Off-Main ✅ Passed Touched files are iOS UI/localization only; no browser.*, WKWebView, processV2Command, or socketWorkerMethods changes appear in the diff.
Cmux Expensive Synchronous Load ✅ Passed The diff only adds UI affordances and label text; new actions call showAddDevice()/dismiss, with no new synchronous agent-history or JSON loads on interactive paths.
Cmux Cache Substitution Correctness ✅ Passed The diff only adds UI add-computer affordances and copy changes; it does not replace any fresh authoritative read in a persistence/snapshot path with cached data.
Cmux No Hacky Sleeps ✅ Passed PASS: This PR is Swift-only UI wiring/text changes; the touched files add no sleeps, timers, polling, or asyncAfter calls.
Cmux Algorithmic Complexity ✅ Passed The PR only adds constant-time UI affordances and copy changes; it introduces no new nested scans, repeated sorts, or batch rescans over scalable collections.
Cmux Swift Concurrency ✅ Passed The diff is UI/copy-only and adds no new DispatchQueue/Combine/completion-handler patterns; the only Task usage is a SwiftUI button-action boundary.
Cmux Swift @Concurrent ✅ Passed No changed file adds/alter @concurrent or nonisolated async; the new addComputer/button wiring is synchronous UI code, and existing async Task/.task paths are unchanged.
Cmux Swift File And Package Boundaries ✅ Passed Small UI-only changes in the CmuxMobileShellUI SwiftPM target; touched Swift files are 93–365 lines and add no mixed/responsibility or oversized-file growth.
Cmux Swiftpm Lockfiles ✅ Passed Only local path deps were removed from Package.swift; no external pins, xcodeproj refs, .gitignore, or Package.resolved files changed.
Cmux Swift Logging ✅ Passed Changed Swift files only add UI copy/affordances; no print/debugPrint/dump/NSLog or Logger changes appear in the diff.
Cmux User-Facing Error Privacy ✅ Passed Patch only renames add-device CTAs to Add Computer and adds UI affordances; no new vendor/internal secrets, raw errors, or payload details were introduced.
Cmux Full Internationalization ✅ Passed All new/changed user-facing Swift text uses localized APIs, and the touched string catalog has complete en/ja translations for every edited key.
Cmux Swiftui State Layout ✅ Passed No new ObservableObject/@published, GeometryReader, or render-time state writes; the added List row and menu button use only closures and existing state.
Cmux Architecture Rethink ✅ Passed The diff only adds UI affordances and copy changes; DeviceTreeView uses one shared addComputer() path, with no sleeps, locks, observers, or split ownership.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed PR only changes iOS SwiftUI views, rows, menus, and copy; no NSWindow/NSPanel/NSWindowController/WindowGroup or cmuxAuxiliaryWindowIdentifiers changes.
Cmux Source Artifacts ✅ Passed All changed paths are source/code, tests, config, localization, or a submodule pointer update; no logs, caches, build output, or scratch dirs appear in the diff.
Cmux No Test Or Debug Seam In Production Source ✅ Passed Touched production Swift files only add UI copy and addComputer wiring; no new DEBUG/test-only seam members or accessors were introduced.
Cmux No Ambient Global State ✅ Passed No prohibited ambient global state was added: addComputer() is a private DeviceTreeView method, and the other changes are instance-scoped or localization-only.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-add-computer-row

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@greptile-apps

greptile-apps Bot commented Jun 26, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

Adds an "Add Computer" end-of-list row to DeviceTreeView and an "Add Computer" entry in the workspace Mac-picker menu, both gated on showAddDevice != nil, so users who scroll past their Macs have a second entry point to the pairing flow without scrolling back up.

  • DeviceTreeView: Extracts a shared addComputer() action (calls showAddDevice?() then dismiss()) used by both the existing toolbar button and the new addComputerRow; the row appears only when the computers list is non-empty.
  • WorkspaceListView+MacSelection: Adds an "Add Computer" button after a Divider in the Mac-picker Menu; correctly omits the dismiss since WorkspaceListView is not a modal.
  • Copy + xcstrings: Renames "Add device" → "Add Computer" across five Swift files and updates all three affected string-catalog keys in both supported locales (en + ja).

Confidence Score: 5/5

Safe to merge — all changes are UI affordances and copy; the pairing flow itself is untouched.

The diff is scoped entirely to SwiftUI view layout, a shared action extracted from existing code, and defaultValue string updates. The showAddDevice nil-guard is correctly applied at every new call site, the xcstrings catalog covers both supported locales (en + ja) for every modified key, and no actor isolation, blocking primitive, or state-mutation issues were introduced.

No files require special attention.

Important Files Changed

Filename Overview
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/DeviceTreeView.swift Adds addComputerRow at the bottom of the non-empty computers section and extracts a shared addComputer() action used by both the toolbar button and the new row; logic is clean and the nil-guard on showAddDevice is respected at both call sites.
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceListView+MacSelection.swift Adds an Add Computer button after a Divider inside the Mac-picker Menu, guarded by if let showAddDevice; correctly omits the dismiss() call since WorkspaceListView is not a modal sheet.
ios/cmux/Resources/Localizable.xcstrings Updates three strings (mobile.addDevice.title, mobile.addDevice.formAccessibilityLabel, mobile.setupHelp.lanBody) in both supported locales (en + ja) from Add device to Add Computer; no locale left untranslated.
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/DisconnectedWorkspaceShellView.swift Copy-only: updates two defaultValue arguments for mobile.addDevice.title from Add device to Add Computer; no behavior change.
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/MobileMacConnectionStatusRow.swift Copy-only: updates defaultValue for mobile.addDevice.title from Add device to Add Computer.
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/PairingView.swift Copy-only: updates three defaultValue arguments (header, accessibility label, navigation title) from Add device to Add Computer.
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/SetupHelpView.swift Copy-only: updates the mobile.setupHelp.lanBody defaultValue to reference Add Computer instead of Add device.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[User opens Computers screen] --> B{showAddDevice set?}
    B -- Yes --> C[Toolbar plus button visible]
    B -- Yes --> D{computers empty?}
    D -- No --> E[Mac list rows rendered]
    E --> F[addComputerRow at bottom]
    D -- Yes --> G[emptySection shown only]
    C -- tap --> H[addComputer action]
    F -- tap --> H
    H --> I[showAddDevice called]
    H --> J[dismiss called]
    K[User opens Mac picker menu] --> L{showAddDevice set?}
    L -- Yes --> M[All Macs and per-Mac picker items]
    M --> N[Divider plus Add Computer button]
    N -- tap --> O[showAddDevice called - no dismiss]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[User opens Computers screen] --> B{showAddDevice set?}
    B -- Yes --> C[Toolbar plus button visible]
    B -- Yes --> D{computers empty?}
    D -- No --> E[Mac list rows rendered]
    E --> F[addComputerRow at bottom]
    D -- Yes --> G[emptySection shown only]
    C -- tap --> H[addComputer action]
    F -- tap --> H
    H --> I[showAddDevice called]
    H --> J[dismiss called]
    K[User opens Mac picker menu] --> L{showAddDevice set?}
    L -- Yes --> M[All Macs and per-Mac picker items]
    M --> N[Divider plus Add Computer button]
    N -- tap --> O[showAddDevice called - no dismiss]
Loading

Reviews (4): Last reviewed commit: "Merge remote-tracking branch 'origin/mai..." | Re-trigger Greptile

@blacksmith-sh

This comment has been minimized.

lawrencecchen and others added 3 commits June 25, 2026 23:15
The workspace title "Choose Mac" menu now has an "Add Computer" action
below the Mac list (after a divider), invoking the same showAddDevice
pairing flow. Shown only when the add affordance is available. Reuses
the existing localized mobile.computers.add string.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Pairing sheet title/nav title, form accessibility label, the
disconnected + connection-status add buttons, and the LAN setup-help
body now read "Add Computer" for consistency with the new entrypoints.
Updated both Swift defaultValues and the xcstrings catalog (en + ja).
Localization keys and code symbols are unchanged (not user-facing).

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In
`@Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/SetupHelpView.swift`:
- Around line 153-156: The help text in SetupHelpView uses a CTA label that may
not match what users actually see on the disconnected recovery screen. Update
the lanBody copy in SetupHelpView to use neutral wording, or make it accept a
caller-provided label so DisconnectedWorkspaceShellView can pass its actual CTA
text (“Add another Mac”) and keep the message consistent with the visible
control.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro

Run ID: e4435efe-435c-432c-8a1d-2710a5ce734b

📥 Commits

Reviewing files that changed from the base of the PR and between d48ae70 and 53144ea.

📒 Files selected for processing (5)
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/DisconnectedWorkspaceShellView.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/MobileMacConnectionStatusRow.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/PairingView.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/SetupHelpView.swift
  • ios/cmux/Resources/Localizable.xcstrings

Comment on lines 153 to 156
Text(L10n.string(
"mobile.setupHelp.lanBody",
defaultValue: "No Tailscale? On the same Wi-Fi you can still connect by typing the Mac's local address and port by hand in Add device. That link is unencrypted, so only use it on a network you trust."
defaultValue: "No Tailscale? On the same Wi-Fi you can still connect by typing the Mac's local address and port by hand in Add Computer. That link is unencrypted, so only use it on a network you trust."
))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Reference the control label users actually see.

Line 155 now tells users to enter the address in “Add Computer”, but the disconnected recovery screen still shows “Add another Mac” when paired Macs already exist (Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/DisconnectedWorkspaceShellView.swift Lines 91-95). In that path the help text points to a button name that is not on screen. Use neutral copy here, or pass in the caller-specific CTA label.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/SetupHelpView.swift`
around lines 153 - 156, The help text in SetupHelpView uses a CTA label that may
not match what users actually see on the disconnected recovery screen. Update
the lanBody copy in SetupHelpView to use neutral wording, or make it accept a
caller-provided label so DisconnectedWorkspaceShellView can pass its actual CTA
text (“Add another Mac”) and keep the message consistent with the visible
control.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 7a4a441a93

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

}
}
.navigationTitle(L10n.string("mobile.addDevice.title", defaultValue: "Add device"))
.navigationTitle(L10n.string("mobile.addDevice.title", defaultValue: "Add Computer"))

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Update Mac pairing instructions to match the renamed action

This rename makes the iOS pairing entry point read “Add Computer”, but the Mac-side QR pairing instructions still tell users to “Tap Add device” (Sources/Mobile/Pairing/MobilePairingView.swift:351, backed by Resources/Localizable.xcstrings). Users pairing from the Mac window now see instructions that name a control that no longer exists on the phone, so update that Mac string and its Japanese localization as part of the same terminology change.

Useful? React with 👍 / 👎.

@lawrencecchen
lawrencecchen merged commit bd6cbe9 into main Jun 26, 2026
37 of 39 checks passed
@lawrencecchen
lawrencecchen deleted the feat-add-computer-row branch June 26, 2026 07:53
@lawrencecchen
lawrencecchen restored the feat-add-computer-row branch July 18, 2026 10:17

This branch was successfully deployed

1 active deployment
Preview – cmux — 7a4a441a Deployed Jun 26, 2026 by vercel[bot]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant