Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
81 commits
Select commit Hold shift + click to select a range
9bffba2
cloud sidebar: hide link tabs while a machine connects, line its conn…
lucasr1b Oct 2, 2026
29e9610
test: clicking a ports status row's text should not refresh or wake
lucasr1b Oct 2, 2026
ec601a1
cloud sidebar: only the ports status button acts, clicking the row's …
lucasr1b Oct 2, 2026
687e3f9
test: machines under the cloud machines section reorder by drag
lucasr1b Oct 3, 2026
49bf865
cloud sidebar: continuous machine and tab reorder, refresh icons in t…
lucasr1b Oct 3, 2026
974de84
move the header refresh icons and tab switch highlight to the follow-…
lucasr1b Oct 3, 2026
712b24e
cloud sidebar: refresh icons in the section headers, sliding tab high…
lucasr1b Oct 3, 2026
fba5a8d
machine lift: closing machines above the held one is not a move
lucasr1b Oct 3, 2026
9cc463c
Merge branch 'cloud-machine-reorder' into cloud-sidebar-polish
lucasr1b Oct 3, 2026
bf080de
cloud sidebar polish: ports alignment, empty states, pane button, ful…
lucasr1b Oct 3, 2026
856abd3
right sidebar width fits the selected tab's name with the others as i…
lucasr1b Oct 3, 2026
e0ba72b
cloud sidebar: refresh icons sit after the section counts; a failed c…
lucasr1b Oct 3, 2026
0f1853f
Resolve PR 17070 review feedback and merge main
austinywang Oct 3, 2026
b9c46ed
Unify machine drag release cleanup
austinywang Oct 3, 2026
e03ae8c
cloud sidebar: refresh icon hover fill, a quieter tab switch, "Discov…
lucasr1b Oct 3, 2026
9cb17b6
Fix Swift 6 drag cleanup build errors
austinywang Oct 3, 2026
b094c04
Merge branch 'cloud-sidebar-connecting' (#16812) into cloud-sidebar-p…
lucasr1b Oct 3, 2026
bf9dea6
cloud sidebar: a failed create's row is just its notice
lucasr1b Oct 3, 2026
becd460
cloud sidebar: clicking a header's refresh icon refreshes instead of …
lucasr1b Oct 3, 2026
d5f0b94
Merge branch 'cloud-machine-reorder' into cloud-sidebar-polish
lucasr1b Oct 3, 2026
c099968
cloud sidebar polish: fit the merge under the line budgets
lucasr1b Oct 3, 2026
ef643c7
refactor cloud tree coordinator for line budget
austinywang Oct 3, 2026
ddb9c92
Merge main (db43cdb42777) into repair-pr-17070
austinywang Oct 3, 2026
2b86ac4
Merge remote-tracking branch 'origin/main' into cloud-machine-reorder
austinywang Oct 3, 2026
abb83ce
Merge remote-tracking branch 'origin/cloud-machine-reorder' into clou…
austinywang Oct 3, 2026
31ca1c9
Merge main (d2adb1b734b6) into repair-pr-17070
austinywang Oct 3, 2026
1dd8bd3
Fix namespace type convention lint
austinywang Oct 3, 2026
cced903
Merge remote-tracking branch 'origin/cloud-machine-reorder' into repa…
austinywang Oct 3, 2026
253d057
Document stateless namespace lint exceptions
austinywang Oct 3, 2026
5530189
Retry CI after transient macOS runner failures
austinywang Oct 3, 2026
d849aff
fix cloud tree machine lookup imports
austinywang Oct 3, 2026
3db7160
fix right sidebar drag test module import
austinywang Oct 3, 2026
327c3fe
Merge main (34348eafcd9e) into cloud-sidebar-polish
austinywang Oct 3, 2026
824577f
ci: isolate owned macOS canonical roots by runner
austinywang Oct 3, 2026
bd6be7b
Merge remote-tracking branch 'origin/cloud-machine-reorder' into clou…
austinywang Oct 3, 2026
1c326ce
Merge commit 'f296dc6f09e6ec14d247f9997e8634aa48dd2476' into cloud-si…
austinywang Oct 3, 2026
77b545d
resolve current main cloud sidebar merge
austinywang Oct 3, 2026
aa6191c
Merge main (3ebb0f255714) into cloud-sidebar-polish
austinywang Oct 3, 2026
0b9d070
fix review findings and hold canonical roots
austinywang Oct 3, 2026
63bae4c
Merge main (68bb2f15cd08) into cloud-sidebar-polish
austinywang Oct 3, 2026
ac19025
ci: keep owned pool picks on the pinned Xcode
austinywang Oct 3, 2026
b9af469
fix: remove deleted cloud refresh source from project
austinywang Oct 3, 2026
8e4d1f0
fix: label machine create failure test outputs
austinywang Oct 3, 2026
c506417
fix: split throwing ordering assertions
austinywang Oct 3, 2026
5298e3d
fix: keep scoped cloud usage visible during refresh
austinywang Oct 3, 2026
3b9e036
fix: eliminate new Swift isolation warnings
austinywang Oct 3, 2026
0029d22
fix: stabilize cloud sidebar layout assertions
austinywang Oct 3, 2026
c76f3a0
Merge main (ab02781c54e5) into cloud-sidebar-polish
austinywang Oct 3, 2026
ccbe4cc
fix: complete cloud plan localization
austinywang Oct 3, 2026
b462c22
Merge main (1a7d5cd08ad6) into cloud-sidebar-polish
austinywang Oct 3, 2026
38538a3
fix: isolate sidebar catalog defaults
austinywang Oct 3, 2026
b8f9849
fix: return sidebar device label
austinywang Oct 3, 2026
960608c
fix: preserve sidebar catalog default semantics
austinywang Oct 3, 2026
414d9f8
fix: preserve catalog injection semantics
austinywang Oct 3, 2026
7574faf
fix: avoid duplicate cloud display rejection
austinywang Oct 3, 2026
e3702aa
fix: hide synthetic resources while connecting
austinywang Oct 3, 2026
0d71490
fix: preserve sidebar catalog projections
austinywang Oct 3, 2026
31da58e
test: model cloud loading and adoption states
austinywang Oct 3, 2026
3145992
Merge main into cloud sidebar polish
austinywang Oct 4, 2026
548d1e4
Fix dogfood workflow guard routing
austinywang Oct 4, 2026
6fad752
Merge latest main into cloud sidebar polish
austinywang Oct 4, 2026
7d48dfc
Update owned state guards for current CI workflow
austinywang Oct 4, 2026
7251a94
Stabilize merged Cloud ordering assertions
austinywang Oct 4, 2026
60288ca
Allow row layout rounding in reachability check
austinywang Oct 4, 2026
e14ea3d
Merge remote-tracking branch 'origin/main' into pr-17074-cloud-sideba…
austinywang Oct 4, 2026
7dfac43
fix(cloud): refresh visible port counts before tab open
austinywang Oct 4, 2026
8dfc69a
Merge remote-tracking branch 'origin/main' into pr-17074-cloud-sideba…
austinywang Oct 4, 2026
47b3c5e
fix(cloud): keep empty port state concise
austinywang Oct 4, 2026
437f18f
fix(cloud): hide request label on failed machine rows
austinywang Oct 4, 2026
099a42f
fix(cloud): keep detail tabs while machine reconnects
austinywang Oct 4, 2026
1f3f452
Merge remote-tracking branch 'origin/cloud-sidebar-polish' into pr-17…
austinywang Oct 4, 2026
968a827
Merge origin/main into cloud-sidebar-polish
austinywang Oct 4, 2026
68ca4fe
Merge remote-tracking branch 'origin/cloud-sidebar-polish' into issue…
austinywang Oct 4, 2026
7d443e6
chore: wire merged test sources
austinywang Oct 4, 2026
221b793
fix(ci): wire merged browser repl sources
austinywang Oct 5, 2026
f6a5000
fix(ci): paginate live runner reads
austinywang Oct 5, 2026
7876bb9
fix: wire browser repl CLI sources
austinywang Oct 5, 2026
bf7d1b5
fix(cloud): preserve connecting machine controls
austinywang Oct 5, 2026
50ac9fb
Merge origin/main into cloud-sidebar-polish
austinywang Oct 5, 2026
8661ff6
chore: trim unrelated localization changes
austinywang Oct 5, 2026
abae4be
Merge origin/main into cloud-sidebar-polish
austinywang Oct 5, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions .github/workflows/ci-guards.yml
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,10 @@ jobs:
if: ${{ matrix.group == 'ci' && steps.fast-guard.outputs.skip != 'true' }}
run: python3 tests/test_ci_owned_build_state.py

- name: Validate canonical root ownership boundary
if: ${{ matrix.group == 'ci' && steps.fast-guard.outputs.skip != 'true' }}
run: python3 tests/test_ci_take_canonical_root.py

- name: Validate warm-state distance recording and routing
if: ${{ matrix.group == 'ci' && steps.fast-guard.outputs.skip != 'true' }}
run: python3 tests/test_ci_warm_distance.py
Expand Down
5 changes: 4 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -1719,7 +1719,7 @@ jobs:
name: "Dogfood build #${{ github.event.pull_request.number }}"
needs: [changes, static-preflight]
if: ${{ github.event_name == 'pull_request' && github.event.pull_request.base.ref != 'feat-cmux-next' && contains(github.event.pull_request.labels.*.name, 'dev-build') && github.event.action != 'unlabeled' && (github.event.action != 'labeled' || github.event.label.name == 'dev-build') && github.repository_owner == 'manaflow-ai' && github.event.pull_request.head.repo.full_name == github.repository && (github.event.pull_request.author_association == 'MEMBER' || github.event.pull_request.author_association == 'OWNER') && needs.changes.result == 'success' && needs.static-preflight.result == 'success' && needs.changes.outputs.macos != 'false' }}
runs-on: ${{ github.repository_owner != 'manaflow-ai' && 'ubuntu-24.04' || github.repository_owner != 'manaflow-ai' && 'macos-26' || 'blacksmith-6vcpu-macos-26' }}
runs-on: ${{ github.repository_owner != 'manaflow-ai' && 'macos-26' || github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository && 'blacksmith-6vcpu-macos-26' || vars.MACOS_RUNNER_PR || 'blacksmith-6vcpu-macos-26' }}
timeout-minutes: 45
# This job is intentionally outside ci-status, so a build or publication
# failure is visible without becoming a merge requirement.
Expand All @@ -1735,6 +1735,9 @@ jobs:
submodules: recursive
persist-credentials: false

- name: Select Xcode
run: ./scripts/select-ci-xcode.sh

- name: Download the pinned GhosttyKit
run: ./scripts/download-prebuilt-ghosttykit.sh

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ public enum ProUpgradeSource: String, CaseIterable, Sendable {
case machinesPanelMachineAction = "mac_machines_panel_machine_action"
/// New machine sheet refused because the free plan is at its limit.
case newMachineAtLimit = "mac_new_machine_at_limit"
/// "Upgrade Plan" on a create that failed at the plan's machine limit.
case createFailedAtLimit = "mac_create_failed_at_limit"
/// New machine sheet "Upgrade to Max" under the locked 32 GB / 64 GB sizes.
case newMachineSheetMaxUpgrade = "mac_new_machine_sheet_max_upgrade"
/// Link inside the `vm_memory_requires_plan` error text (`VMClient`).
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,16 @@ public struct MachinePlanSnapshot: Equatable, Sendable {
/// upgrade affordance after the server returns `vm_requires_pro`.
public var isPaidPlan: Bool { Self.isPaidPlanID(planId) }

/// Whether a plan with more machines exists to upgrade to. Max, Team and
/// Founders are the top of the ladder; everything else (free, Go, Pro, an
/// unknown id) can move up.
public var hasHigherPlan: Bool {
switch planId.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() {
case "max", "team", "founders": return false
default: return true
}
}

public static func isPaidPlanID(_ planId: String) -> Bool {
switch planId.trimmingCharacters(in: .whitespacesAndNewlines).lowercased() {
case "go", "pro", "max", "team", "founders":
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,16 @@ public struct CloudTreeDevicesSection: Equatable, Sendable {
incomingAccessEnabled: Bool = false,
discoveryManaged: Bool = false,
incomingAccessManaged: Bool = false,
available: Bool = true
available: Bool = true,
isRefreshing: Bool = false
) {
self.count = count
self.discoveryEnabled = discoveryEnabled
self.incomingAccessEnabled = incomingAccessEnabled
self.discoveryManaged = discoveryManaged
self.incomingAccessManaged = incomingAccessManaged
self.available = available
self.isRefreshing = isRefreshing
}

public var count: Int = 0
Expand All @@ -25,9 +27,11 @@ public struct CloudTreeDevicesSection: Equatable, Sendable {
public var incomingAccessManaged: Bool = false
/// Whether Cloud availability permits either device preference.
public var available: Bool = true
/// A refresh of the devices list is running; the header's refresh icon spins.
public var isRefreshing: Bool = false

/// Both independent actions stay visible below the devices, preceded by
/// "No other Macs yet" when the list is empty.
/// "No other devices yet" when the list is empty.
public var inlineRowCount: Int {
(count == 0 ? 1 : 0) + 2
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,10 @@ public struct CloudTreePlaceholder: Equatable, Sendable {
case dimmed
case connecting
case error
/// An action row that opens the New Machine sheet: the empty state of
/// the Cloud Machines section.
/// An action row that opens the New Machine sheet.
case createMachine
/// Plain guidance with no icon or action, like "No cloud machines yet".
case empty
}

public let text: String
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
import Foundation

/// A section header's refresh icon: present while the section has something
/// to refresh, with a spinner in its place while a refresh runs.
public struct CloudTreeSectionRefresh: Equatable, Sendable {
public var isRefreshing: Bool

public init(isRefreshing: Bool = false) {
self.isRefreshing = isRefreshing
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,8 @@ public struct DeviceAccessControl {
switch preference {
case .discovery:
return isOn
? String(localized: "devices.discovery.stop", defaultValue: "Stop discovering other Macs", bundle: .module)
: String(localized: "devices.discovery.toggle", defaultValue: "Discover other Macs")
? String(localized: "devices.discovery.stop", defaultValue: "Stop discovering other devices", bundle: .module)
: String(localized: "devices.discovery.toggle", defaultValue: "Discover other devices")
case .incomingAccess:
return isOn
? String(localized: "devices.incoming.hide", defaultValue: "Hide this Mac from My Devices", bundle: .module)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@ extension Array where Element == CuratedSettingEntry {
.init(
section: .computers,
id: "discovery",
title: String(localized: "devices.discovery.toggle", defaultValue: "Discover other Macs"),
title: String(localized: "devices.discovery.toggle", defaultValue: "Discover other devices"),
detailText: String(localized: "devices.discovery.help", defaultValue: "Find and connect to other Macs signed in to your account. Turning this off disconnects their panes without closing their terminals."),
synonyms: "Discover other Macs discovery find connect other computers my devices"
)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7101,55 +7101,55 @@
"en": {
"stringUnit": {
"state": "translated",
"value": "Stop discovering other Macs"
"value": "Stop discovering other devices"
}
},
"ar": {
"stringUnit": {
"state": "translated",
"value": "إيقاف اكتشاف أجهزة Mac الأخرى"
"value": "إيقاف اكتشاف الأجهزة الأخرى"
}
},
"de": {
"stringUnit": {
"state": "translated",
"value": "Andere Macs nicht mehr finden"
"value": "Andere Geräte nicht mehr finden"
}
},
"es": {
"stringUnit": {
"state": "translated",
"value": "Dejar de descubrir otros Mac"
"value": "Dejar de descubrir otros dispositivos"
}
},
"fr": {
"stringUnit": {
"state": "translated",
"value": "Arrêter de rechercher d’autres Mac"
"value": "Arrêter de rechercher d’autres appareils"
}
},
"ja": {
"stringUnit": {
"state": "translated",
"value": "ほかのMacの検出を停止"
"value": "ほかのデバイスの検出を停止"
}
},
"ko": {
"stringUnit": {
"state": "translated",
"value": "다른 Mac 검색 중지"
"value": "다른 기기 검색 중지"
}
},
"zh-Hans": {
"stringUnit": {
"state": "translated",
"value": "停止发现其他 Mac"
"value": "停止发现其他设备"
}
},
"zh-Hant": {
"stringUnit": {
"state": "translated",
"value": "停止尋找其他 Mac"
"value": "停止尋找其他裝置"
}
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -64,10 +64,10 @@ public struct ComputersSection: View {
} else if discoveryManaged {
SettingsCardNote(String(localized: "devices.managed", defaultValue: "Disabled by your administrator."))
} else if !discoveryEnabled {
SettingsCardNote(String(localized: "devices.discovery.settingsDisabled", defaultValue: "Turn on Discover other Macs to see your devices."))
SettingsCardNote(String(localized: "devices.discovery.settingsDisabled", defaultValue: "Turn on Discover other devices to see your devices."))
} else if snapshot.computers.isEmpty {
VStack(alignment: .leading, spacing: 6) {
Label(String(localized: "devices.empty.title", defaultValue: "No other Macs yet"), systemImage: "desktopcomputer")
Label(String(localized: "devices.empty.title", defaultValue: "No other devices yet"), systemImage: "desktopcomputer")
.font(.callout.weight(.medium))
Text(String(localized: "devices.empty.help", defaultValue: "Sign in to cmux on another Mac and make it discoverable in Settings › Devices."))
.font(.callout)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ struct DeviceAccessControlTests {
let incoming = DeviceAccessControl(.incomingAccess, enabled: enabled, managed: false)
let discovery = DeviceAccessControl(.discovery, enabled: enabled, managed: false)
#expect(incoming.title == (enabled ? "Hide this Mac from My Devices" : "Make this Mac discoverable"))
#expect(discovery.title == (enabled ? "Stop discovering other Macs" : "Discover other Macs"))
#expect(discovery.title == (enabled ? "Stop discovering other devices" : "Discover other devices"))
#expect(incoming.isOn == enabled)
#expect(discovery.isOn == enabled)
#expect(incoming.isEnabled && discovery.isEnabled)
Expand All @@ -20,7 +20,7 @@ struct DeviceAccessControlTests {
let control = DeviceAccessControl(preference, enabled: true, managed: managed, unavailable: !managed)
#expect(!control.isOn)
#expect(!control.isEnabled)
#expect(control.title == (preference == .incomingAccess ? "Make this Mac discoverable" : "Discover other Macs"))
#expect(control.title == (preference == .incomingAccess ? "Make this Mac discoverable" : "Discover other devices"))
if managed { #expect(control.help == "Disabled by your administrator.") }
}
}
Loading
Loading