Skip to content

Improve Simulator discoverability on macOS and iOS - #9888

Closed
azooz2003-bit wants to merge 26 commits into
mainfrom
task-improve-simulator-discoverability
Closed

azooz2003-bit wants to merge 26 commits into
mainfrom
task-improve-simulator-discoverability

Conversation

@azooz2003-bit

@azooz2003-bit azooz2003-bit commented Aug 10, 2026 •

Copy link
Copy Markdown
Collaborator

Summary

  • add Simulator to the default macOS surface-tab controls through the existing shared action
  • expose a one-tap Simulator control in iOS workspace chrome when the paired Mac and current workspace support it
  • add deterministic Simulator state fixtures and focused policy/config/UI coverage

Testing

  • ./scripts/reload.sh --tag simvis
  • Swift parse, package manifest, localization catalog, and test-wiring validation
  • focused hosted UI runs pending

Issues

  • Related: user-requested Simulator discoverability improvement

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


Note

Medium Risk
Changes span mobile stream lifecycle, cross-panel RPC ordering, and shared shell ownership; mistakes could cause stale streams or split Simulator state, but the area is heavily covered by new unit and UI tests.

Overview
iOS adds workspace chrome for Mac Simulator streaming: a one-tap Simulator toolbar control (hidden when unsupported or no panels), New Simulator Tab in the terminal picker when the Mac advertises create capability, and return navigation back to the prior terminal/browser surface.

Simulator selection and stream RPCs move into MobileShellComposite with a serialized MobileSimulatorStreamSelectionCoordinator, and the composite now owns a non-optional MobileSimulatorStreamStore so UI and RPC callbacks cannot drift onto different instances. Re-selecting a panel preserves locked / stalled / disconnected overlays instead of forcing a fresh “starting” state.

End-to-end mobile.simulator.create is added (capability id, Mac host handler, ticket/RPC client wiring, iOS client + composite refresh/create helpers).

App shell structure: MobileShellUISession holds the store plus browser/simulator/terminal environment graph; GhosttyRuntimeOwner initializes Ghostty once at app composition with a retryable failure UI instead of per-surface init.

macOS exposes create on the mobile RPC path, advertises the create capability with the simulator feature flag, renames user-facing strings from “pane” to tab, and speeds simulator device-picker label building. A config test asserts the default surface tab bar still omits a Simulator button when no explicit config exists.

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


Summary by cubic

Improves Simulator discoverability on iOS with a one‑tap control, adds in‑app Simulator tab creation and navigation, and keeps stream starts/stops ordered. Terminal rendering is now process‑lifetime with retry; iOS loads Ghostty config from an app‑owned path; macOS keeps the default tab bar without a Simulator button.

  • New Features

    • iOS: one‑tap Simulator control supports tab navigation and a “New Simulator Tab” action when capability simulator.stream.create.v1 is present.
    • Added mobile.simulator.create RPC and MobileSimulatorStreamCapability.createIdentifier; exposed via MobileHostService/MobileCoreRPCClient, with supportsSimulatorStreamCreate gating the UI and Terminal picker.
    • Unified UI ownership with MobileShellUISession; DEBUG adds SimulatorDiscoverabilityPreviewView via CmuxMobileShellDebugSupport. Terminal rendering moves to process‑lifetime GhosttyRuntimeOwner with retry; iOS Ghostty config loads from an app‑owned file; strings/docs use “Simulator Tab”.
  • Bug Fixes

    • Serialized selection via MobileSimulatorStreamSelectionCoordinator to prevent overlapping RPCs; reselecting preserves locked/stalled/disconnected overlays.
    • Stabilized environment lifetime by using the composite‑owned MobileSimulatorStreamStore everywhere so selection stays accurate during navigation.
    • macOS: device picker snapshotting is linear, and tests assert no default Simulator tab button.

Written for commit 9eedc37. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added Simulator panel selection to the iOS workspace toolbar.
    • Added support for switching between multiple Simulator panels.
    • Added a built-in Simulator button to default surface tab bars.
    • Added visual states for disconnected, locked, stalled, and unsupported Simulator streams.
    • Simulator controls are hidden when unavailable or no panels exist.
  • Bug Fixes

    • Improved reliability when rapidly switching or stopping Simulator streams.
  • Tests

    • Added coverage for picker visibility, selection, sizing, fallback behavior, and stream states.

@coderabbitai

coderabbitai Bot commented Aug 10, 2026 •

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

Adds Simulator picker controls, serialized stream selection, deterministic DEBUG preview fixtures, UI tests, shared store ownership, and the built-in Simulator surface-tab action.

Changes

Simulator discoverability

Layer / File(s) Summary
Simulator stream transition coordination
Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileSimulatorStreamSelectionCoordinator.swift, Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite*, Packages/iOS/CmuxMobileShell/Tests/CmuxMobileShellTests/*
Serializes Simulator stop/start transitions, coalesces pending selections, handles cancellation, uses a required shared stream store, and tests transition ordering.
Picker state and workspace control
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/SimulatorPicker*, Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceDetailView*, Packages/iOS/CmuxMobileShellUI/Tests/CmuxMobileShellUITests/*
Adds picker state normalization, toolbar rendering, accessibility metadata, target selection, and centralized stream transition calls.
Preview fixture and UI validation
Packages/iOS/CmuxMobileShellDebugSupport/*, Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/SimulatorDiscoverabilityPreviewView.swift, ios/cmuxPackage/Sources/cmuxFeature/CMUXMobileRootScene.swift, ios/cmuxUITests/cmuxUITests.swift
Adds deterministic Simulator workspace states, DEBUG preview routing, capability setup, shared store injection, and UI coverage for picker and stream states.
Surface tab Simulator default
Sources/CmuxConfig.swift, cmuxTests/CmuxConfigTests.swift
Adds newSimulator to default and fallback surface tab buttons and verifies explicit configurations remain authoritative.

Vendor pointer update

Layer / File(s) Summary
Bonsplit submodule reference
vendor/bonsplit
Updates the vendored bonsplit submodule commit reference.

Estimated code review effort: 4 (Complex) | ~60 minutes

Sequence Diagram(s)

sequenceDiagram
  participant WorkspaceDetailView
  participant SimulatorPickerControl
  participant MobileShellComposite
  participant MobileSimulatorStreamSelectionCoordinator
  WorkspaceDetailView->>SimulatorPickerControl: render simulator picker state
  SimulatorPickerControl->>WorkspaceDetailView: select target panel
  WorkspaceDetailView->>MobileShellComposite: request simulator transition
  MobileShellComposite->>MobileSimulatorStreamSelectionCoordinator: enqueue selection
  MobileSimulatorStreamSelectionCoordinator->>MobileShellComposite: stop previous and start target stream
Loading

Possibly related PRs

  • manaflow-ai/cmux#9401: Adds Simulator streaming infrastructure used by the picker and preview implementation.
  • manaflow-ai/cmux#9886: Changes Simulator stream lifecycle handling in the same composite while this PR adds coordinated panel selection transitions.

Important

Pre-merge checks failed

Please resolve all errors before merging. Addressing warnings is optional.

❌ Failed checks (3 errors, 2 warnings)

Check name Status Explanation Resolution
Cmux Algorithmic Complexity ❌ Error WorkspaceDetailView.swift:665-666 maps every Simulator panel into picker rows during SwiftUI view construction; host enumeration has no bound, so this rebuilds an unbounded collection on UI updates. Cache SimulatorPickerMenuValue or prebuilt SimulatorStreamPickerRow snapshots when workspace.simulators changes, and read the cached value from the toolbar body.
Cmux Architecture Rethink ❌ Error The coordinator adds a second mutable selection owner (activeSelection) beside the store’s activePanelByWorkspace, while onDisappear still directly deactivates and stops streams. Make one composite transition path own selection and cleanup; route surface disappearance through it and remove or derive coordinator selection state from the store.
Cmux Source Artifacts ❌ Error The diff changes the external dependency gitlink at vendor/bonsplit, with no Bonsplit source change or stated requirement tying that checkout update to this feature. Remove vendor/bonsplit from the diff, or document the required dependency change and keep only the narrow submodule update needed for the product fix.
Docstring Coverage ⚠️ Warning Docstring coverage is 6.45% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
Description check ⚠️ Warning The description explains the change and testing, but it omits the required Demo Video, Review Trigger, and Checklist sections, with hosted UI tests still pending. Add the Demo Video, Review Trigger, and Checklist sections, then report the results of the focused hosted UI runs.
✅ Passed checks (20 passed)
Check name Status Explanation
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 Changed simulator store access remains behind @MainActor MobileShellComposite/UI boundaries; the new coordinator is @MainActor, and picker models remain nonisolated like existing UI value models.
Cmux Swift Blocking Runtime ✅ Passed The feature diff adds no semaphore, sleep, delayed-dispatch, main-queue sync, timer, or manual-lock APIs; the new coordinator uses @MainActor and async task completion awaits.
Cmux Browser Automation Off-Main ✅ Passed The PR leaves TerminalController.swift, ControlCommandExecutionPolicy.swift, and policy tests unchanged; added browser references are UI imports/stores, not browser.* socket automation commands.
Cmux Expensive Synchronous Load ✅ Passed Production additions contain no agent-history loaders or large-file parsing; the changed AgentChat hunk only adds Simulator picker/layout, and simulator RPC transitions are async.
Cmux Cache Substitution Correctness ✅ Passed The PR changes only in-memory Simulator UI/RPC state and adds config defaults; no fresh disk/database/history/undo/snapshot read is replaced by a cache.
Cmux No Hacky Sleeps ✅ Passed The cumulative PR diff contains only Swift files plus a vendor submodule pointer; it introduces no TypeScript, JavaScript, shell, or non-Swift build/runtime changes covered by this rule.
Cmux Swift Concurrency ✅ Passed The PR adds no DispatchQueue, DispatchGroup, Combine, or completion-handler async APIs; its only new Task is stored as transitionTask and cancelled on cancel/deinit.
Cmux Swift @Concurrent ✅ Passed The diff adds no nonisolated async or @concurrent declarations; new async coordination is explicitly @MainActor, and composite RPC methods remain actor-isolated UI coordination.
Cmux Swift Package Boundaries ✅ Passed Simulator stream coordination and picker policy live in CmuxMobileShell/CmuxMobileShellUI SwiftPM targets with package-local tests; app changes are lifecycle composition and small surface-tab wiring.
Cmux Swiftpm Lockfiles ✅ Passed CmuxMobileShell and CmuxMobileShellUI only add local target/product wiring; no external pins, .gitignore, Xcode package references, or lockfiles changed. bonsplit remains vendored.
Cmux Swift Logging ✅ Passed The PR diff adds no print, debugPrint, dump, NSLog, ad hoc output, or Logger calls; existing production Logger declarations and call sites remain unchanged.
Cmux User-Facing Error Privacy ✅ Passed The diff adds only the generic user-facing label “Mac Simulators”; other sensitive-looking strings are DEBUG/UI-test fixture data, with no new user-facing errors or exposed diagnostics.
Cmux Full Internationalization ✅ Passed The new production label uses L10n.string with existing key mobile.simulatorStream.menuTitle, which already has translated en and ja entries; fixture text is DEBUG-only and tests are allowed.
Cmux Swiftui State Layout ✅ Passed Changed SwiftUI code uses @Observable models with @State or value snapshots; no new legacy observation, GeometryReader, lazy-row store reference, or render-time state mutation appears in the diff.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed The complete PR diff adds no NSWindow, NSPanel, NSWindowController, Window, or WindowGroup code; the new SwiftUI view is a DEBUG test fixture, and registry/lint files are unchanged.
Cmux No Test Or Debug Seam In Production Source ✅ Passed New DEBUG fixture code is isolated in a dedicated preview file and the capability extension is in CmuxMobileShellDebugSupport; no test/debug accessor was added to shipping product types.
Cmux No Ambient Global State ✅ Passed New production APIs are methods on MobileShellComposite or constructable coordinator/views; review found no new file-scope mutable state, static-only namespace, or runtime singleton.
Title check ✅ Passed The title clearly summarizes the primary Simulator discoverability changes across macOS and iOS.
✨ Finishing Touches 💡 1
📝 Generate docstrings 💡
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch task-improve-simulator-discoverability

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.

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceDetailView.swift (1)

959-970: 🩺 Stability & Availability | 🟠 Major | 🏗️ Heavy lift

Serialize simulator stream transitions.

Each selection starts an independent, unowned task. During rapid A → B → C selection, the B task can resume and start B after the C task has stopped B. The local store then shows C as active while B also runs remotely.

Move this transition into a caller-owned coordinator or store operation that serializes the latest intent and cancels or supersedes older requests.

As per coding guidelines, do not create fire-and-forget Task { ... } work with meaningful lifecycle unless it is stored, cancellable, or tied to a caller-owned operation.

🤖 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/WorkspaceDetailView.swift`
around lines 959 - 970, Replace the unowned Task transition around
stopMobileSimulatorStream and startMobileSimulatorStream with a caller-owned,
stored coordinator or store operation that serializes selection intents. Ensure
rapid selections cancel or supersede older transitions so only the latest
panel’s stream is active, and expose lifecycle cancellation rather than creating
fire-and-forget work.

Source: Coding guidelines

🤖 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 `@ios/cmuxUITests/cmuxUITests.swift`:
- Around line 7681-7684: Update the test lifecycle around setUpWithError and
tearDownWithError to restore XCUIDevice.shared.orientation to its prior/default
state and terminate the two application during teardown. Ensure cleanup runs
after every test, including failed tests, so shared device state and the fixture
process do not leak into later tests.

In
`@Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/SimulatorPickerMenuValue.swift`:
- Around line 11-14: Update the initializer logic in SimulatorPickerMenuValue so
activePanelID is validated against the filtered self.rows rather than the
original rows parameter, ensuring it becomes nil whenever
supportsSimulatorStream is false and preserving valid IDs only for available
panels.

---

Outside diff comments:
In
`@Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceDetailView.swift`:
- Around line 959-970: Replace the unowned Task transition around
stopMobileSimulatorStream and startMobileSimulatorStream with a caller-owned,
stored coordinator or store operation that serializes selection intents. Ensure
rapid selections cancel or supersede older transitions so only the latest
panel’s stream is active, and expose lifecycle cancellation rather than creating
fire-and-forget work.
🪄 Autofix

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 Plus

Run ID: 001c6a3c-0e17-4642-b11b-787ba3c1c596

📥 Commits

Reviewing files that changed from the base of the PR and between a5752bb and 445870a.

📒 Files selected for processing (11)
  • Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite+SimulatorPreview.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/SimulatorDiscoverabilityPreviewView.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/SimulatorPickerControl.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/SimulatorPickerMenuValue.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceDetailView+AgentChat.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceDetailView.swift
  • Packages/iOS/CmuxMobileShellUI/Tests/CmuxMobileShellUITests/SimulatorPickerMenuValueTests.swift
  • Sources/CmuxConfig.swift
  • cmuxTests/CmuxConfigTests.swift
  • ios/cmuxPackage/Sources/cmuxFeature/CMUXMobileRootScene.swift
  • ios/cmuxUITests/cmuxUITests.swift

Comment thread ios/cmuxUITests/cmuxUITests.swift

@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 `@vendor/bonsplit`:
- Line 1: Update the vendor/bonsplit submodule reference so it points to a
commit available on the configured submodule remote, either by pushing commit
8230030608931784878dc46b8b8581756e7a2d69 to the remote branch or changing the
superproject pointer to an already-pushed commit.
🪄 Autofix

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 Plus

Run ID: 4c1c33c9-825d-42da-9fe0-21770e061879

📥 Commits

Reviewing files that changed from the base of the PR and between 445870a and 290955b.

📒 Files selected for processing (13)
  • Packages/iOS/CmuxMobileShell/Package.swift
  • Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite+SimulatorStream.swift
  • Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite.swift
  • Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileSimulatorStreamSelectionCoordinator.swift
  • Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShellDebugSupport/MobileShellComposite+SimulatorPreview.swift
  • Packages/iOS/CmuxMobileShell/Tests/CmuxMobileShellTests/MobileSimulatorStreamSelectionCoordinatorTests.swift
  • Packages/iOS/CmuxMobileShellUI/Package.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/SimulatorDiscoverabilityPreviewView.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/SimulatorPickerMenuValue.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceDetailView+AgentChat.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceDetailView.swift
  • ios/cmuxUITests/cmuxUITests.swift
  • vendor/bonsplit

Comment thread vendor/bonsplit

@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.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
ios/cmuxUITests/cmuxUITests.swift (1)

7726-7727: 🩺 Stability & Availability | 🟡 Minor | ⚡ Quick win

Wait for the UI state before both assertions.

After panelB.tap(), Line 7727 can run before MobileSimulatorPicker receives the new value. The assertion can fail intermittently. At Line 7735, exists can be false before the workspace chrome finishes rendering, so the test can pass without proving that the picker is omitted. Wait for a value predicate after the tap and use a deadline-bounded absence check after the terminal picker is ready.

Proposed test synchronization
         panelB.tap()
+        let selectionExpectation = XCTNSPredicateExpectation(
+            predicate: NSPredicate(format: "value == %@", "iPhone B"),
+            object: twoPicker
+        )
+        wait(for: [selectionExpectation], timeout: 4)
         XCTAssertEqual(twoPicker.value as? String, "iPhone B")
...
-            XCTAssertFalse(app.buttons["MobileSimulatorPicker"].exists)
+            XCTAssertFalse(
+                app.buttons["MobileSimulatorPicker"].waitForExistence(timeout: 2)
+            )

As per coding guidelines, UI tests must await real completion signals or use deadline-bounded polls of real predicates before assertions.

Also applies to: 7734-7735

🤖 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 `@ios/cmuxUITests/cmuxUITests.swift` around lines 7726 - 7727, Update the UI
test around panelB.tap() and the terminal picker assertion to synchronize with
real UI state: wait for a value predicate confirming MobileSimulatorPicker has
changed to “iPhone B” before asserting it, then wait until the workspace chrome
is ready and perform a deadline-bounded poll confirming the picker’s exists
predicate remains false. Ensure both assertions only run after their
corresponding state transitions are complete.

Source: Coding guidelines

🤖 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.

Outside diff comments:
In `@ios/cmuxUITests/cmuxUITests.swift`:
- Around line 7726-7727: Update the UI test around panelB.tap() and the terminal
picker assertion to synchronize with real UI state: wait for a value predicate
confirming MobileSimulatorPicker has changed to “iPhone B” before asserting it,
then wait until the workspace chrome is ready and perform a deadline-bounded
poll confirming the picker’s exists predicate remains false. Ensure both
assertions only run after their corresponding state transitions are complete.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: ASSERTIVE

Plan: Pro Plus

Run ID: ef133c6f-b73f-48d4-97a5-ef539172bc8a

📥 Commits

Reviewing files that changed from the base of the PR and between 7a84690 and 9e77288.

📒 Files selected for processing (3)
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/CMUXMobileAppView.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/SimulatorDiscoverabilityPreviewView.swift
  • ios/cmuxUITests/cmuxUITests.swift

…r-discoverability

# Conflicts:
#	Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceDetailView+TerminalArtifacts.swift
#	ios/cmux/cmuxApp.swift
#	ios/cmuxPackage/Sources/cmuxFeature/CMUXMobileRootScene.swift

@cursor cursor 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.

Cursor Bugbot has reviewed your changes using default effort and found 1 potential issue.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9eedc37. Configure here.

}
pendingIntent = Intent(target: target)
startDrainIfNeeded()
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Coordinator breaks multi-workspace streams

High Severity

MobileSimulatorStreamSelectionCoordinator tracks one global activeSelection, while the store and restartActiveMobileSimulatorStreams keep per-workspace actives. After a selection in another workspace—or a clear whose from does not match the coordinator—the drain can stop the wrong panel. cancel also leaves activeSelection stale across disconnect/reconnect, so later UI actions diverge from the store.

Additional Locations (2)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9eedc37. Configure here.

@lawrencecchen lawrencecchen added the stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening. label Sep 23, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

stale-revisit Closed after 30+ days without activity; preserved for possible revisit or reopening.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants