diff --git a/apps/macos/Sources/Clawdis/GeneralSettings.swift b/apps/macos/Sources/Clawdis/GeneralSettings.swift index e428993cd..6f137694f 100644 --- a/apps/macos/Sources/Clawdis/GeneralSettings.swift +++ b/apps/macos/Sources/Clawdis/GeneralSettings.swift @@ -261,11 +261,16 @@ struct GeneralSettings: View { Button { Task { await self.installCLI() } } label: { - if self.isInstallingCLI { - ProgressView().controlSize(.small) - } else { - Text(self.cliInstalled ? "Reinstall CLI helper" : "Install CLI helper") + let title = self.cliInstalled ? "Reinstall CLI helper" : "Install CLI helper" + ZStack { + Text(title) + .opacity(self.isInstallingCLI ? 0 : 1) + if self.isInstallingCLI { + ProgressView() + .controlSize(.small) + } } + .frame(minWidth: 150, minHeight: 24) } .disabled(self.isInstallingCLI) diff --git a/apps/macos/Sources/Clawdis/Onboarding.swift b/apps/macos/Sources/Clawdis/Onboarding.swift index a1315ce91..c13a11694 100644 --- a/apps/macos/Sources/Clawdis/Onboarding.swift +++ b/apps/macos/Sources/Clawdis/Onboarding.swift @@ -86,8 +86,8 @@ struct OnboardingView: View { private static let clipboardPoll = Timer.publish(every: 0.4, on: .main, in: .common).autoconnect() private let permissionsPageIndex = 5 - private var pageOrder: [Int] { - switch self.state.connectionMode { + static func pageOrder(for mode: AppState.ConnectionMode) -> [Int] { + switch mode { case .remote: // Remote setup doesn't need local gateway/CLI/workspace setup pages, // and WhatsApp/Telegram setup is optional. @@ -95,10 +95,14 @@ struct OnboardingView: View { case .unconfigured: [0, 1, 9] case .local: - [0, 1, 2, 3, 5, 6, 7, 8, 9] + [0, 1, 2, 3, 5, 6, 8, 9] } } + private var pageOrder: [Int] { + Self.pageOrder(for: self.state.connectionMode) + } + private var pageCount: Int { self.pageOrder.count } private var activePageIndex: Int { self.activePageIndex(for: self.currentPage) @@ -175,6 +179,7 @@ struct OnboardingView: View { await self.refreshPerms() self.refreshCLIStatus() self.loadWorkspaceDefaults() + self.ensureDefaultWorkspace() self.refreshAnthropicOAuthStatus() self.loadIdentityDefaults() self.preferredGatewayID = BridgeDiscoveryPreferences.preferredStableID() @@ -214,8 +219,6 @@ struct OnboardingView: View { self.permissionsPage() case 6: self.cliPage() - case 7: - self.workspacePage() case 8: self.whatsappPage() case 9: @@ -849,11 +852,16 @@ struct OnboardingView: View { Button { Task { await self.installCLI() } } label: { - if self.installingCLI { - ProgressView() - } else { - Text(self.cliInstalled ? "Reinstall CLI" : "Install CLI") + let title = self.cliInstalled ? "Reinstall CLI" : "Install CLI" + ZStack { + Text(title) + .opacity(self.installingCLI ? 0 : 1) + if self.installingCLI { + ProgressView() + .controlSize(.small) + } } + .frame(minWidth: 120, minHeight: 28) } .buttonStyle(.borderedProminent) .disabled(self.installingCLI) @@ -1364,6 +1372,20 @@ struct OnboardingView: View { self.workspacePath = AgentWorkspace.displayPath(for: url) } + private func ensureDefaultWorkspace() { + guard self.state.connectionMode == .local else { return } + let configured = ClawdisConfigFile.inboundWorkspace() + let url = AgentWorkspace.resolveWorkspaceURL(from: configured) + do { + _ = try AgentWorkspace.bootstrap(workspaceURL: url) + if (configured ?? "").trimmingCharacters(in: .whitespacesAndNewlines).isEmpty { + ClawdisConfigFile.setInboundWorkspace(AgentWorkspace.displayPath(for: url)) + } + } catch { + self.workspaceStatus = "Failed to create workspace: \(error.localizedDescription)" + } + } + private func loadIdentityDefaults() { if let identity = ClawdisConfigFile.loadIdentity() { self.identityName = identity.name diff --git a/apps/macos/Tests/ClawdisIPCTests/OnboardingViewSmokeTests.swift b/apps/macos/Tests/ClawdisIPCTests/OnboardingViewSmokeTests.swift index 2f186bfbe..f42afff83 100644 --- a/apps/macos/Tests/ClawdisIPCTests/OnboardingViewSmokeTests.swift +++ b/apps/macos/Tests/ClawdisIPCTests/OnboardingViewSmokeTests.swift @@ -13,4 +13,9 @@ struct OnboardingViewSmokeTests { discoveryModel: GatewayDiscoveryModel()) _ = view.body } + + @Test func pageOrderOmitsWorkspaceStep() { + let order = OnboardingView.pageOrder(for: .local) + #expect(!order.contains(7)) + } }