Skip to content

Feature-flag the Cloud VM UI (cloud-vm-ui-enabled-release) - #7592

Merged
lawrencecchen merged 7 commits into
mainfrom
feat-cloudvm-ui-flag
Jul 8, 2026
Merged

lawrencecchen merged 7 commits into
mainfrom
feat-cloudvm-ui-flag

Conversation

@lawrencecchen

@lawrencecchen lawrencecchen commented Jul 8, 2026 •

Copy link
Copy Markdown
Contributor

Adds a PostHog-backed feature flag cloud-vm-ui-enabled-release that hides every Cloud VM entrypoint, so the feature can be switched off from the dashboard without shipping a build. Requested: the Cloud VM items in the new-workspace dropdown (Open Cloud VM / Fork / Checkpoint / Restore / Advanced) need to be disable-able.

Defaults follow the existing pro-upgrade-ui pattern: Release OFF (hidden until the flag is enabled), DEBUG ON (visible for dogfood).

Gated at every surface (shared-behavior policy — one flag, all entrypoints):

  • AppDelegate+NewWorkspaceContextMenu — the dropdown's Cloud VM section is skipped when off
  • TitlebarCloudVMButton.showCloudVMMenu — the caret's direct Cloud VM menu no-ops
  • ContentView+AuthCommandPalette.commandPaletteCloudCommandContributions — returns [], hiding all palette Cloud VM commands
  • performCloudVMAction / performCurrentCloudVMCommand / performCloudVMRestoreCommand — the three shared actions return false, so shortcuts and any stale entrypoint can't reach Cloud VM either

Localized flag title/description (en + ja). scripts/lint-feature-flags.py passes (the macOS flag reads PostHog directly; no web-registry change needed).

Dogfood: in a Debug build the flag defaults ON. Open the Feature Flags window and toggle Cloud VM UI off — the dropdown Cloud VM items, palette commands, and shortcut all disappear; toggle on to restore.

🤖 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 gating with safe Release defaults; Cloud VM behavior is unchanged when the flag is on. Residual risk is non-gated paths (shortcuts, titlebar primary actions, RPC) still reaching Cloud VM while the flag is off.

Overview
Introduces PostHog flag cloud-vm-ui-enabled-release with isCloudVMUIEnabled, using the same pattern as other release flags: off in Release until PostHog enables it, on in DEBUG for dogfood. Localized title/description are added for the Feature Flags UI (en/ja).

When the flag is off, Cloud VM is hidden at the main entrypoints: the new-workspace menu skips the Cloud section, the command palette returns no Cloud VM commands, and TitlebarCloudVMButton.showCloudVMMenu no-ops. makeCloudVMMenu() is unchanged, so callers that build menus without the show helpers could still surface actions if not gated elsewhere.

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


Summary by cubic

Adds a PostHog feature flag cloud-vm-ui-enabled-release to hide Cloud VM UI entrypoints, defaulting OFF in Release and ON in Debug. Gating is applied only to UI entrypoints (dropdown, titlebar menu, command palette), not actions.

  • New Features

    • Adds isCloudVMUIEnabled and localized flag title/description (en/ja).
    • When off, hides the new‑workspace Cloud VM section, the titlebar Cloud VM menu, and all Command Palette Cloud VM commands.
  • Migration

    • Enable cloud-vm-ui-enabled-release in PostHog to show the UI in release builds.
    • In Debug builds, use the Feature Flags window to toggle “Cloud VM UI.”

Written for commit 04f43db. Summary will update on new commits.

Review in cubic

Summary by CodeRabbit

  • New Features

    • Introduced a new Cloud VM UI experience with updated workspace/layout management labels, dialogs, and related menu and command text.
  • Bug Fixes

    • Cloud VM commands and menus now only appear when the Cloud VM UI feature is enabled.
    • Improved Cloud VM-related error messaging for malformed and unreadable configurations.
    • Refined Cloud VM workspace/debug UI localization to ensure correct strings are shown.
  • Chores

    • Updated localization entries for Cloud VM, workspace layout, debug menu, dialogs, and agent chat notifications.

Adds a PostHog-backed flag that hides every Cloud VM entrypoint so the
feature can be turned off without shipping a build. Release builds default
OFF (hidden) until the flag is enabled; DEBUG defaults ON for dogfood,
matching the pro-upgrade-ui pattern.

Gated at every surface (shared-behavior policy): the new-workspace dropdown
Cloud VM section (Open/Fork/Checkpoint/Restore/Advanced), the caret's direct
Cloud VM menu, the command-palette Cloud VM commands, and the three shared
actions (performCloudVMAction, performCurrentCloudVMCommand,
performCloudVMRestoreCommand) — so no entrypoint can reach Cloud VM when the
flag is off. Localized flag title/description (en+ja).

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

vercel Bot commented Jul 8, 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 Jul 9, 2026 1:42am

@chatgpt-codex-connector

Copy link
Copy Markdown

You have reached your Codex usage limits for code reviews. You can see your limits in the Codex usage dashboard.
To continue using code reviews, add credits to your account and enable them for code reviews in your settings.

@coderabbitai

coderabbitai Bot commented Jul 8, 2026 •

Copy link
Copy Markdown

Review Change Stack

📝 Walkthrough

Walkthrough

Adds a Cloud VM UI feature flag, gates Cloud VM entrypoints behind it, and updates localization strings for CMUX, workspace layout, debug UI, notifications, and related menus.

Changes

Cloud VM feature flag and gating

Layer / File(s) Summary
Feature flag definition and accessor
Sources/FeatureFlags.swift
Adds the Cloud VM UI fallback default, registers the new flag, and exposes isCloudVMUIEnabled.
Cloud VM entrypoint and menu gating
Sources/AppDelegate+NewWorkspaceContextMenu.swift, Sources/ContentView+AuthCommandPalette.swift, Sources/Update/TitlebarCloudVMButton.swift
Skips Cloud VM context menu items, command palette contributions, and titlebar menu display when the flag is disabled.

Localization updates

Layer / File(s) Summary
Localization additions
Resources/Localizable.xcstrings
Adds EN/JA strings for CMUX commands, debug split-button layout UI, CMUX config disclosures, workspace layout dialogs, feature flag text, notifications, and related menu labels.
Localization relocations and removals
Resources/Localizable.xcstrings
Moves existing keys to new positions and removes prior duplicate or obsolete localization blocks.

Estimated code review effort: 2 (Simple) | ~12 minutes

Possibly related PRs


Important

Pre-merge checks failed

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

❌ Failed checks (7 errors, 1 warning)

Check name Status Explanation Resolution
Cmux Swift Blocking Runtime ❌ Error Production Swift adds an OSAllocatedUnfairLock gate and a 10s health-poll loop with 250ms sleeps in AppDelegate+AgentChat. Replace the lock with actor/main-actor ownership or an explicit signal, and avoid sleep-based polling; use async completion/notification or a single timeout callback.
Cmux No Hacky Sleeps ❌ Error FAIL: the new agent-chat/cmux-chat polls healthz with sleep 0.2, and agent-chat/src/session.ts reconnects with setTimeout(..., 800), both fixed runtime waits. Use a single readiness event/IPC from the server startup path and an event-driven reconnect/cancellation-aware retry helper instead of fixed sleeps/backoff.
Cmux Algorithmic Complexity ❌ Error CommandMenu sorts/filter-searches up to 5k file suggestions on every keystroke; that hot path lacks a smaller bound or cached index. Precompute or cache file suggestions, or cap/top-N them before per-keystroke sorting; avoid sorting the full 5k set on each query change.
Cmux Swift Logging ❌ Error Sources/AppDelegate+AgentChat.swift adds unguarded NSLog calls in runtime code, violating the Swift logging rule. Replace those NSLog calls with unified Logger (or remove them); keep any diagnostics debug-only or sanitized provider-only.
Cmux Full Internationalization ❌ Error New featureFlags.cloudVM title/description keys are only en/ja, but Localizable.xcstrings already supports 20 locales. Add localized values for the 18 missing catalog locales for both featureFlags.cloudVM.* entries.
Cmux Architecture Rethink ❌ Error The diff adds new production lock/polling/timer/observer guards (AgentChatActionInFlightGate, devtools close timers, health polling), matching the rule’s anti-patterns. Move the new behavior into an owned actor/coordinator with explicit lifecycle callbacks; avoid global lock/set guards and polling timers unless they’re test-only or required platform bridges.
Cmux Swift Auxiliary Window Close Shortcuts ❌ Error Detached inspector Cmd+W handling was added without a stable cmux.* identifier or cmuxAuxiliaryWindowIdentifiers registration. Assign the detached inspector window a stable cmux.* identifier, add it to cmuxAuxiliaryWindowIdentifiers, and route Cmd+W through cmuxWindowShouldOwnCloseShortcut.
Description check ⚠️ Warning The description covers summary and testing context, but it omits required template sections like Demo Video, Review Trigger, and Checklist. Add the missing template sections: Testing, Demo Video, Review Trigger, and Checklist, and format the description to match the repository template.
✅ Passed checks (17 passed)
Check name Status Explanation
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 The PR only gates @MainActor UI entrypoints; it adds no new nonisolated models/protocols or background access to shared stores.
Cmux Browser Automation Off-Main ✅ Passed No browser socket-routing or policy files changed; the new browser helpers are @MainActor UI code only.
Cmux Expensive Synchronous Load ✅ Passed Diff only gates Cloud VM UI/menu/flags; no new or moved RestorableAgentSessionIndex.load()/JSONL transcript work appears in touched interactive paths.
Cmux Cache Substitution Correctness ✅ Passed Only an in-memory PostHog feature-flag cache was added, and it gates transient Cloud VM UI entrypoints; no durable persistence/history/snapshot read was substituted.
Cmux Swift Concurrency ✅ Passed PR diff adds only feature-flag guards/UI plumbing; no new DispatchQueue, Combine, completion-handler, or Task-based async patterns appear in the Swift diff.
Cmux Swift @Concurrent ✅ Passed No changed Swift code introduces nonisolated async work or invalid @concurrent usage; new gates are sync/@mainactor and the only async hop stays explicitly on MainActor.
Cmux Swift File And Package Boundaries ✅ Passed Touched Swift files are small app-target/UI/flags glue; no new oversized file or package-boundary violation was introduced.
Cmux Swiftpm Lockfiles ✅ Passed No SwiftPM/Xcode/.gitignore/workflow/dependency files changed; diff only touches Swift sources, localization, and a budget TSV, so the lockfile rule isn’t implicated.
Cmux User-Facing Error Privacy ✅ Passed PASS — the only new user-facing error copy is a generic Agent Chat server-unavailable notification; it mentions a public config key and cmux-chat, with no vendor/secret leakage.
Cmux Swiftui State Layout ✅ Passed No new SwiftUI layout/state anti-patterns were added; the diff only adds a simple overlay view, bridge logic changes, and legacy @Published config fields.
Cmux Source Artifacts ✅ Passed Changed paths are source/config/docs/localization/test fixtures; the only scratch-dir addition is an empty .gitkeep with scratch contents ignored, not artifact output.
Cmux No Test Or Debug Seam In Production Source ✅ Passed PR only adds Cloud VM UI gating and a feature-flag default; no test-only or debug-observability accessor/seam was added in production Sources/.
Cmux No Ambient Global State ✅ Passed No new ambient global state was introduced; the diff only adds instance methods/private helpers, and the singleton usages were pre-existing.
Title check ✅ Passed The title is concise and accurately summarizes the main change: adding a feature flag for Cloud VM UI.
✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat-cloudvm-ui-flag

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 Jul 8, 2026 •

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR adds a feature flag for the Cloud VM UI. The main changes are:

  • Adds the cloud-vm-ui-enabled-release flag with release off and debug on defaults.
  • Hides the Cloud VM section in the new-workspace menu when the flag is off.
  • Hides Cloud VM command palette contributions when the flag is off.
  • Prevents the titlebar Cloud VM menu from opening when the flag is off.
  • Adds localized Feature Flags copy for the new flag.

Confidence Score: 4/5

This is close, but the stale palette path should be fixed before merging.

  • The flag hides freshly built palette entries.
  • A palette list built before the flag changes can still contain Cloud VM commands.
  • Those stale commands can invoke shared Cloud VM actions that do not check the flag.

Sources/ContentView+AuthCommandPalette.swift

Important Files Changed

Filename Overview
Sources/ContentView+AuthCommandPalette.swift Adds the Cloud VM palette guard, but cached palette entries can still run the unguarded action path after the flag changes.
Sources/FeatureFlags.swift Adds the Cloud VM UI feature flag definition, defaults, and typed accessor.
Sources/AppDelegate+NewWorkspaceContextMenu.swift Skips the Cloud VM menu section when the flag is off.
Sources/Update/TitlebarCloudVMButton.swift Adds flag checks before showing the Cloud VM menu.
Resources/Localizable.xcstrings Adds localized strings for the Cloud VM feature flag.

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

static func commandPaletteCloudCommandContributions() -> [CommandPaletteCommandContribution] {
// Feature-gated: hide every Cloud VM command from the palette when the
// Cloud VM UI flag is off, matching the dropdown and shortcut gates.
guard CmuxFeatureFlags.shared.isCloudVMUIEnabled else { return [] }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Palette Results Stay Stale

When the Cloud VM flag changes while the command palette is open, this guard only takes effect the next time the palette rebuilds its command corpus. A flag-off toggle can leave Cloud VM commands visible and selectable until the user refreshes or reopens the palette, where the handlers then silently return without doing anything.

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Comment on lines +98409 to +98426
"featureFlags.cloudVM.description": {
"extractionState": "manual",
"localizations": {
"en": {
"stringUnit": {
"state": "translated",
"value": "Shows Cloud VM entrypoints in the new-workspace dropdown and command palette."
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "新規ワークスペースのドロップダウンとコマンドパレットにクラウドVMのエントリーポイントを表示します。"
}
}
}
},
"featureFlags.cloudVM.title": {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Flag Copy Missing Locales

The new Cloud VM feature-flag title and description are shown in the Feature Flags window, but these catalog entries only include English and Japanese. This catalog already carries additional app locales on nearby production strings, so users in those locales will see fallback or missing localized copy for this new flag.

File Used: .github/review-bot-rules/full-internationalization.md (source)

@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 `@Sources/FeatureFlags.swift`:
- Around line 112-114: `isCloudVMUIEnabled` currently depends on a fragile
positional lookup in `FeatureFlags.allFlags`, so the accessor can silently point
to the wrong flag if the array order changes. Update the `isCloudVMUIEnabled`
implementation to resolve the flag by its unique key/name instead of using
`allFlags[2]`, following the same approach you choose for
`isProUpgradeUIEnabled` and `isMobileConnectButtonEnabled` so the accessor stays
stable even if `allFlags` is reordered.
🪄 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: 4de73274-9d61-4716-8cba-6f91481dd7d7

📥 Commits

Reviewing files that changed from the base of the PR and between def4098 and f3722ac.

📒 Files selected for processing (6)
  • Resources/Localizable.xcstrings
  • Sources/AppDelegate+NewWorkspaceContextMenu.swift
  • Sources/AppDelegate.swift
  • Sources/ContentView+AuthCommandPalette.swift
  • Sources/FeatureFlags.swift
  • Sources/Update/TitlebarCloudVMButton.swift

Comment on lines +112 to +114
var isCloudVMUIEnabled: Bool {
effectiveValue(for: Self.allFlags[2])
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

📐 Maintainability & Code Quality | 🔵 Trivial | 💤 Low value

Positional index into allFlags is fragile.

isCloudVMUIEnabled (and the existing isProUpgradeUIEnabled/isMobileConnectButtonEnabled) rely on allFlags[N] matching declaration order in the array literal. Reordering allFlags (e.g., inserting a flag earlier in the list, or a future merge conflict) silently breaks the wrong flag's accessor without a compiler error.

Since this follows the existing pattern rather than introducing new risk, consider a follow-up to look up by key (e.g., a dictionary or first(where:)) instead of index, but not blocking for this PR.

🤖 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 `@Sources/FeatureFlags.swift` around lines 112 - 114, `isCloudVMUIEnabled`
currently depends on a fragile positional lookup in `FeatureFlags.allFlags`, so
the accessor can silently point to the wrong flag if the array order changes.
Update the `isCloudVMUIEnabled` implementation to resolve the flag by its unique
key/name instead of using `allFlags[2]`, following the same approach you choose
for `isProUpgradeUIEnabled` and `isMobileConnectButtonEnabled` so the accessor
stays stable even if `allFlags` is reordered.

Co-Authored-By: Claude <noreply@anthropic.com>
Comment on lines 75 to +78
static func commandPaletteCloudCommandContributions() -> [CommandPaletteCommandContribution] {
// Feature-gated: hide every Cloud VM command from the palette when the
// Cloud VM UI flag is off, matching the dropdown and shortcut gates.
guard CmuxFeatureFlags.shared.isCloudVMUIEnabled else { return [] }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Palette Entries Stay Stale

This guard only runs when the command-palette command corpus is rebuilt. If the Cloud VM flag is turned off while the palette is already open, the existing search corpus can still contain the Cloud VM commands because the palette refresh fingerprint does not include isCloudVMUIEnabled. Those commands remain visible and selectable, then hit the new action guards and silently do nothing. Please include this flag in the palette invalidation path, or trigger a corpus rebuild when the feature flag changes.

Comment on lines 75 to +78
static func commandPaletteCloudCommandContributions() -> [CommandPaletteCommandContribution] {
// Feature-gated: hide every Cloud VM command from the palette when the
// Cloud VM UI flag is off, matching the dropdown and shortcut gates.
guard CmuxFeatureFlags.shared.isCloudVMUIEnabled else { return [] }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Palette Cache Stays Stale

This guard hides Cloud VM commands only when the palette corpus is rebuilt. If the palette is opened while Cloud VM is enabled, then the flag flips off, the cached corpus can keep the old Cloud VM entries because the palette fingerprint does not include isCloudVMUIEnabled. Those stale commands can remain visible and selectable until another path rebuilds the corpus. Please include this flag in the palette invalidation path, or force a corpus refresh when the feature flag changes.

Comment thread Sources/FeatureFlags.swift
# Conflicts:
#	.github/swift-file-length-budget.tsv
#	Resources/Localizable.xcstrings
#	Sources/AppDelegate+NewWorkspaceContextMenu.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 04f43db. Configure here.


@MainActor
static func showCloudVMMenu(anchorView: NSView, event: NSEvent) {
guard CmuxFeatureFlags.shared.isCloudVMUIEnabled else { return }

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Cloud caret still opens VM

Medium Severity

With cloud-vm-ui-enabled-release off, the titlebar split button’s caret segment stays visible and can still call performCloudVMAction (including the no-anchor fallback). Cloud VM is only hidden from the new-workspace menu and palette, not this entrypoint.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 04f43db. Configure here.

static func commandPaletteCloudCommandContributions() -> [CommandPaletteCommandContribution] {
// Feature-gated: hide every Cloud VM command from the palette when the
// Cloud VM UI flag is off, matching the dropdown and shortcut gates.
guard CmuxFeatureFlags.shared.isCloudVMUIEnabled else { return [] }

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

P1 Stale commands still launch

This guard only removes Cloud VM commands when the palette rebuilds its command list. If the palette was built while the flag was on, then isCloudVMUIEnabled flips off while that list is still live, the stale Cloud VM entries can still be selected. The handlers below call the shared Cloud VM actions, and those action methods do not check the flag, so selecting a stale entry can still launch Cloud VM while the UI flag is off. Please make the palette refresh when this flag changes, or fail closed in the registered handlers/shared action path.

@lawrencecchen
lawrencecchen merged commit ba2ffe3 into main Jul 8, 2026
32 of 34 checks passed

This branch was successfully deployed

1 active deployment
Preview – cmux — 04f43dbf Deployed Jul 9, 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