Skip to content

Add focused iOS MVP experience profile - #9454

Closed
samz406 wants to merge 1 commit into
manaflow-ai:mainfrom
samz406:copilot/cmux-ios-client-evaluation
Closed

samz406 wants to merge 1 commit into
manaflow-ai:mainfrom
samz406:copilot/cmux-ios-client-evaluation

Conversation

@samz406

@samz406 samz406 commented Aug 3, 2026 •

Copy link
Copy Markdown

Summary

  • What changed?
  • Why?

Testing

  • How did you test this change?
  • What did you verify manually?

Demo Video

For UI or behavior changes, include a short demo video (GitHub upload, Loom, or other direct link).

  • Video URL or attachment:

Review Trigger (Copy/Paste as PR comment)

@codex review
@coderabbitai review
@greptile-apps review
@cubic-dev-ai review

Checklist

  • I tested the change locally
  • I added or updated tests for behavior changes
  • I updated docs/changelog if needed
  • I requested bot reviews after my latest commit (copy/paste block above or equivalent)
  • All code review bot comments are resolved
  • All human review comments are resolved

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


Summary by cubic

Add an iOS experience profile system and ship the focused mvp profile for the first release. It filters host capabilities and hides advanced UI to center on remote agent control.

  • New Features

    • Introduced MobileExperienceProfile (full, mvp) and MobileExperiencePolicy that filter authenticated host capabilities and gate UI.
    • Wired capability filtering across the shell (auth, promotion, refresh) via applySupportedHostCapabilities; feature gates now use the filtered set; Mac update hint is suppressed in mvp.
    • UI gated by policy: Terminal Picker can hide the Mac Browser section and New Browser; Settings hides Team switching, Advanced Networking, and artifact-related toggles; workspace groups and related actions are disabled under mvp.
    • Build/config: CMUXExperienceProfile read from Info.plist (CMUX_IOS_EXPERIENCE_PROFILE); Release.xcconfig sets mvp; reload.sh adds --mvp; README documents the profile.
    • Tests added for profile parsing, capability filtering, and picker visibility.
  • Migration

    • No changes for local dev: default profile is full.
    • Release/TestFlight already use mvp. To verify locally: ios/scripts/reload.sh --tag <tag> --mvp or set CMUX_IOS_EXPERIENCE_PROFILE=mvp.

Written for commit ff5006c. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Added configurable Full and MVP experience profiles for iOS.
    • MVP mode focuses on core pairing, terminal control, notifications, and diagnostics while hiding advanced features.
    • Browser access, workspace management, artifacts, networking, and team switching now adapt to the selected profile.
    • Added support for selecting the MVP profile during release builds and reloads.
  • Documentation

    • Documented profile behavior, configuration, and reload commands.
  • Bug Fixes

    • Prevented unsupported capabilities and Mac update prompts from appearing in MVP mode.

@samz406
samz406 requested a review from lawrencecchen as a code owner August 3, 2026 11:25
@chatgpt-codex-connector

Copy link
Copy Markdown

To use Codex here, create an environment for this repo.

@coderabbitai

coderabbitai Bot commented Aug 3, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds configurable full and MVP experience profiles for iOS. The selected policy propagates from build configuration through shell state, filters host capabilities, and gates browser, workspace, artifact, networking, and team-switching UI surfaces.

Changes

Mobile experience policy

Layer / File(s) Summary
Profile and policy contract
Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileExperience*.swift, Packages/iOS/CmuxMobileShell/Tests/CmuxMobileShellTests/MobileExperience*Tests.swift
Adds full and mvp profiles, configuration parsing, feature permissions, host-capability filtering, and policy tests.
Profile configuration and startup propagation
ios/Config/*, ios/scripts/reload.sh, ios/cmux/cmuxApp.swift, ios/cmuxPackage/Sources/cmuxFeature/CMUXMobileRootScene.swift, ios/README.md
Adds build configuration, --mvp handling, profile validation, bundle loading, startup injection, and profile documentation.
Shell capability enforcement
Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite*
Injects MobileExperiencePolicy and applies filtered capabilities across host connections, promotions, resets, status refreshes, actions, and Mac-update hints.
Experience-gated mobile UI
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/*, Packages/iOS/CmuxMobileShellUI/Tests/CmuxMobileShellUITests/TerminalPickerMenuValueTests.swift
Gates browser menus, workspace groups and actions, team switching, advanced networking, and artifact-related settings. Tests cover hidden browser entry points.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant BuildConfiguration
  participant cmuxApp
  participant CMUXMobileRootScene
  participant CMUXMobileShellStore
  participant MobileShellComposite
  participant MobileExperiencePolicy
  BuildConfiguration->>cmuxApp: provide CMUXExperienceProfile
  cmuxApp->>MobileExperiencePolicy: create selected policy
  cmuxApp->>CMUXMobileRootScene: pass experiencePolicy
  CMUXMobileRootScene->>CMUXMobileShellStore: pass experiencePolicy
  CMUXMobileShellStore->>MobileShellComposite: initialize policy
  MobileShellComposite->>MobileExperiencePolicy: filter host capabilities
Loading

Possibly related PRs

Suggested reviewers: lawrencecchen, azooz2003-bit


Important

Pre-merge checks failed

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

❌ Failed checks (1 error, 2 warnings)

Check name Status Explanation Resolution
Cmux User-Facing Error Privacy ❌ Error The changed reload.sh command output exposes the environment variable name CMUX_IOS_EXPERIENCE_PROFILE in an error, which the rule explicitly prohibits. Change the error to generic product terms, such as “error: experience profile must be 'full' or 'mvp'”; keep the variable name in help or developer documentation.
Description check ⚠️ Warning The description includes the template but leaves the summary, testing, demo video, and checklist sections incomplete. Complete the summary and testing details, add a demo video or explain its absence, and update the checklist before requesting review.
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (22 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly identifies the main change: adding a focused iOS MVP experience profile.
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 New policy/profile types are immutable Sendable values without MainActor annotations; MobileShellComposite is explicitly @MainActor, and UI accesses remain in allowed SwiftUI types.
Cmux Swift Blocking Runtime ✅ Passed Added Swift lines contain no semaphore, wait, sleep, delayed-dispatch, polling, sync-queue, timer, or lock primitive; existing runtime match counts are unchanged from HEAD^.
Cmux Browser Automation Off-Main ✅ Passed The PR does not modify Sources/TerminalController.swift or ControlCommandExecutionPolicy.swift, and adds no browser socket worker command or routing change.
Cmux Expensive Synchronous Load ✅ Passed The Swift diff adds only policy filtering, capability assignment, UI gates, and bundle configuration parsing; it adds no agent-history loader, file/JSON scan, transcript read, or synchronous corpus...
Cmux Cache Substitution Correctness ✅ Passed The diff only filters live authenticated/status capability snapshots and adds UI gates; it does not replace any fresh persistence, history, undo, or snapshot read with a cached value.
Cmux No Hacky Sleeps ✅ Passed The non-Swift diff only adds experience-profile configuration, validation, and xcodebuild arguments; it introduces no sleeps, timers, polling, or wall-clock synchronization.
Cmux Algorithmic Complexity ✅ Passed The diff adds only linear Set capability filtering and boolean UI gates; it introduces no nested scans, per-target rescans, repeated sorting/filtering, or data-store joins.
Cmux Swift Concurrency ✅ Passed The PR adds policy and UI gating only; added Swift lines contain no Dispatch, Combine, completion-handler, async/await, or Task constructs. Existing Task callbacks are unchanged nearby code.
Cmux Swift @Concurrent ✅ Passed The diff adds no nonisolated async or @concurrent annotations. New capability filtering is synchronous, pure Set work, and changed shell call sites remain on @MainActor.
Cmux Swift Package Boundaries ✅ Passed MobileExperiencePolicy/Profile and unit tests are in the CmuxMobileShell SwiftPM target; app changes only load and inject the policy as lifecycle composition.
Cmux Swiftpm Lockfiles ✅ Passed The diff changes no Package.swift, Package.resolved, .gitignore, workflow, or Xcode package-reference files in Packages/iOS/CmuxMobileShell or ios/cmuxPackage; no dependency pin change requires a l...
Cmux Swift Logging ✅ Passed The Swift diff adds no print, debugPrint, dump, NSLog, file/stdout logging, or Logger declarations; existing logging statements are unchanged.
Cmux Full Internationalization ✅ Passed The diff adds no new user-facing copy or localization keys; moved UI strings remain L10n.string calls, while other English text is comments or operational docs/config tokens. No catalog or web loca...
Cmux Swiftui State Layout ✅ Passed The diff adds only immutable policy flags and value snapshots. It adds no observation wrappers, GeometryReader, lazy-row store references, or render-time state writes.
Cmux Architecture Rethink ✅ Passed The diff uses one immutable injected policy and one capability-filtering funnel; UI receives value snapshots and actions, with no new timing, blocking, observers, locks, or mutable state owners.
Cmux Swift Auxiliary Window Close Shortcuts ✅ Passed The Swift diff adds policy and capability gating only. It introduces no NSWindow, NSPanel, controller, Window, WindowGroup, identifier, or close-shortcut changes; the existing WindowGroup is unchan...
Cmux Source Artifacts ✅ Passed All 22 changed paths are Swift source/tests, iOS config, README, or reload script; no scratch directories, logs, binaries, caches, build outputs, or copied artifacts appear.
Cmux No Test Or Debug Seam In Production Source ✅ Passed The production Swift diff adds no test/debug guards or seam-named members; existing seams are unchanged, and MobileExperiencePolicy is used by production UI and shell code.
Cmux No Ambient Global State ✅ Passed The diff adds a constructable, injected MobileExperiencePolicy; its static members are immutable constants, and no new top-level API, mutable global, static-only namespace, or singleton appears.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

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: 4

🤖 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/CmuxMobileShell/Sources/CmuxMobileShell/MobileExperienceProfile.swift`:
- Around line 10-18: Update MobileExperienceProfile.init(configurationValue:) so
missing or malformed values fail closed by preserving an unavailable state or
selecting the restrictive .mvp policy for distribution builds, while retaining
an explicit development path for .full. In
Packages/iOS/CmuxMobileShell/Tests/CmuxMobileShellTests/MobileExperienceProfileTests.swift
lines 10-14, replace .full fallback assertions with tests verifying restrictive
unavailable-profile behavior. In ios/README.md lines 37-39, document fail-closed
handling and the explicit development-profile configuration path.

In
`@Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite.swift`:
- Line 1324: Require an explicit MobileExperiencePolicy when constructing
MobileShellComposite instead of defaulting omitted arguments to .full. Update
MobileShellComposite, MobileSettingsView settings construction, and
TerminalPickerMenuValue at
Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite.swift:1324-1324,
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/MobileSettingsView.swift:522-524,
and
Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/TerminalPickerMenuValue.swift:27-28
so production entry points pass the selected policy explicitly and no
constructor infers .full from missing input.

In
`@Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceShellView.swift`:
- Around line 599-601: Update the workspace-group action closures
renameWorkspaceGroupClosure, setWorkspaceGroupPinnedClosure,
ungroupWorkspaceGroupClosure, and deleteWorkspaceGroupClosure to also enforce
store.experiencePolicy.allowsAdvancedWorkspaceManagement, returning nil or
otherwise failing closed when the policy is disabled, consistent with the
existing groups list gating.

In
`@Packages/iOS/CmuxMobileShellUI/Tests/CmuxMobileShellUITests/TerminalPickerMenuValueTests.swift`:
- Around line 78-92: Extend firstReleasePolicyCanHideBothBrowserEntryPoints
beyond TerminalPickerMenuValue field assertions by testing the rendered
TerminalPickerMenu.menuContent, or extract its pure menu-item decision logic
into a testable helper. Assert that both the browser stream section and New
Browser action are absent when showsBrowserStreamSection and allowsLocalBrowser
are false.
🪄 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 Plus

Run ID: be60e8c1-f75d-4b8f-a89b-3a8c1c5cd918

📥 Commits

Reviewing files that changed from the base of the PR and between 6edf257 and ff5006c.

📒 Files selected for processing (22)
  • Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileExperiencePolicy.swift
  • Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileExperienceProfile.swift
  • Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite+Capabilities.swift
  • Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite+MacUpdateHint.swift
  • Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite+SecondaryPromotion.swift
  • Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileShellComposite.swift
  • Packages/iOS/CmuxMobileShell/Tests/CmuxMobileShellTests/MobileExperiencePolicyTests.swift
  • Packages/iOS/CmuxMobileShell/Tests/CmuxMobileShellTests/MobileExperienceProfileTests.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/MobileSettingsView.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/TerminalPickerMenu.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/TerminalPickerMenuValue.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceDetailView.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceShellView+WorkspaceActions.swift
  • Packages/iOS/CmuxMobileShellUI/Sources/CmuxMobileShellUI/WorkspaceShellView.swift
  • Packages/iOS/CmuxMobileShellUI/Tests/CmuxMobileShellUITests/TerminalPickerMenuValueTests.swift
  • ios/Config/Info.plist
  • ios/Config/Release.xcconfig
  • ios/Config/Shared.xcconfig
  • ios/README.md
  • ios/cmux/cmuxApp.swift
  • ios/cmuxPackage/Sources/cmuxFeature/CMUXMobileRootScene.swift
  • ios/scripts/reload.sh

Comment on lines +10 to +18
/// Creates a profile from an Info.plist or build-setting value.
///
/// Unknown and missing values resolve to ``full`` so local development
/// never loses tools because of a malformed optional setting.
public init(configurationValue: String?) {
let normalized = configurationValue?
.trimmingCharacters(in: .whitespacesAndNewlines)
.lowercased()
self = normalized == Self.mvp.rawValue ? .mvp : .full

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 | 🟠 Major | 🏗️ Heavy lift

Fail closed when the experience profile is unavailable.

A missing or malformed CMUXExperienceProfile currently selects .full. A Release/TestFlight configuration failure can then expose surfaces that the MVP policy must disable.

  • Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileExperienceProfile.swift#L10-L18: Preserve invalid or missing input as an unavailable profile, or select the restrictive MVP policy for distribution builds.
  • Packages/iOS/CmuxMobileShell/Tests/CmuxMobileShellTests/MobileExperienceProfileTests.swift#L10-L14: Replace the .full fallback assertions with coverage that verifies restrictive behavior for unavailable distribution configuration.
  • ios/README.md#L37-L39: Document the fail-closed behavior and the explicit development-profile path.

As per path instructions, required profile or capability data must fail closed and must not use guessed fallbacks that expose disabled MVP features.

📍 Affects 3 files
  • Packages/iOS/CmuxMobileShell/Sources/CmuxMobileShell/MobileExperienceProfile.swift#L10-L18 (this comment)
  • Packages/iOS/CmuxMobileShell/Tests/CmuxMobileShellTests/MobileExperienceProfileTests.swift#L10-L14
  • ios/README.md#L37-L39
🤖 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/CmuxMobileShell/Sources/CmuxMobileShell/MobileExperienceProfile.swift`
around lines 10 - 18, Update MobileExperienceProfile.init(configurationValue:)
so missing or malformed values fail closed by preserving an unavailable state or
selecting the restrictive .mvp policy for distribution builds, while retaining
an explicit development path for .full. In
Packages/iOS/CmuxMobileShell/Tests/CmuxMobileShellTests/MobileExperienceProfileTests.swift
lines 10-14, replace .full fallback assertions with tests verifying restrictive
unavailable-profile behavior. In ios/README.md lines 37-39, document fail-closed
handling and the explicit development-profile configuration path.

Source: Path instructions

@samz406 samz406 closed this Aug 3, 2026
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