openclaw/apps/macos/Sources/Clawdbot/OnboardingView+Actions.swift
Frederic Haddad de0665ab8b fix(macos): complete Clawd → Molt rename in Swift code and build scripts
Fix incomplete rename that broke macOS app builds:

- Update Package.swift to use ClawdbotKit package identifier (SPM uses path name)
- Fix argument order in ClawdbotKit Package.swift (dependencies before path)
- Add path properties to macos Package.swift targets pointing to Clawdbot* directories
- Update notification name references (.clawdbotSelectSettingsTab → .moltbotSelectSettingsTab)
- Update CommandResolver method calls (clawdbotCommand → moltbotCommand, etc.)
- Update self.clawdbotOAuthDirEnv → self.moltbotOAuthDirEnv
- Fix resource paths in package-mac-app.sh (Sources/Moltbot → Sources/Clawdbot)
- Fix icon filename reference (Moltbot.icns → Clawdbot.icns)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-27 23:24:19 +04:00

149 lines
5.5 KiB
Swift

import AppKit
import MoltbotDiscovery
import MoltbotIPC
import Foundation
import SwiftUI
extension OnboardingView {
func selectLocalGateway() {
self.state.connectionMode = .local
self.preferredGatewayID = nil
self.showAdvancedConnection = false
GatewayDiscoveryPreferences.setPreferredStableID(nil)
}
func selectUnconfiguredGateway() {
Task { await self.onboardingWizard.cancelIfRunning() }
self.state.connectionMode = .unconfigured
self.preferredGatewayID = nil
self.showAdvancedConnection = false
GatewayDiscoveryPreferences.setPreferredStableID(nil)
}
func selectRemoteGateway(_ gateway: GatewayDiscoveryModel.DiscoveredGateway) {
Task { await self.onboardingWizard.cancelIfRunning() }
self.preferredGatewayID = gateway.stableID
GatewayDiscoveryPreferences.setPreferredStableID(gateway.stableID)
if self.state.remoteTransport == .direct {
if let url = GatewayDiscoveryHelpers.directUrl(for: gateway) {
self.state.remoteUrl = url
}
} else if let host = GatewayDiscoveryHelpers.sanitizedTailnetHost(gateway.tailnetDns) ?? gateway.lanHost {
let user = NSUserName()
self.state.remoteTarget = GatewayDiscoveryModel.buildSSHTarget(
user: user,
host: host,
port: gateway.sshPort)
MoltbotConfigFile.setRemoteGatewayUrl(host: host, port: gateway.gatewayPort)
}
self.state.remoteCliPath = gateway.cliPath ?? ""
self.state.connectionMode = .remote
MacNodeModeCoordinator.shared.setPreferredGatewayStableID(gateway.stableID)
}
func openSettings(tab: SettingsTab) {
SettingsTabRouter.request(tab)
self.openSettings()
DispatchQueue.main.async {
NotificationCenter.default.post(name: .moltbotSelectSettingsTab, object: tab)
}
}
func handleBack() {
withAnimation {
self.currentPage = max(0, self.currentPage - 1)
}
}
func handleNext() {
if self.isWizardBlocking { return }
if self.currentPage < self.pageCount - 1 {
withAnimation { self.currentPage += 1 }
} else {
self.finish()
}
}
func finish() {
UserDefaults.standard.set(true, forKey: "moltbot.onboardingSeen")
UserDefaults.standard.set(currentOnboardingVersion, forKey: onboardingVersionKey)
OnboardingController.shared.close()
}
func copyToPasteboard(_ text: String) {
let pb = NSPasteboard.general
pb.clearContents()
pb.setString(text, forType: .string)
self.copied = true
DispatchQueue.main.asyncAfter(deadline: .now() + 1.2) { self.copied = false }
}
func startAnthropicOAuth() {
guard !self.anthropicAuthBusy else { return }
self.anthropicAuthBusy = true
defer { self.anthropicAuthBusy = false }
do {
let pkce = try AnthropicOAuth.generatePKCE()
self.anthropicAuthPKCE = pkce
let url = AnthropicOAuth.buildAuthorizeURL(pkce: pkce)
NSWorkspace.shared.open(url)
self.anthropicAuthStatus = "Browser opened. After approving, paste the `code#state` value here."
} catch {
self.anthropicAuthStatus = "Failed to start OAuth: \(error.localizedDescription)"
}
}
@MainActor
func finishAnthropicOAuth() async {
guard !self.anthropicAuthBusy else { return }
guard let pkce = self.anthropicAuthPKCE else { return }
self.anthropicAuthBusy = true
defer { self.anthropicAuthBusy = false }
guard let parsed = AnthropicOAuthCodeState.parse(from: self.anthropicAuthCode) else {
self.anthropicAuthStatus = "OAuth failed: missing or invalid code/state."
return
}
do {
let creds = try await AnthropicOAuth.exchangeCode(
code: parsed.code,
state: parsed.state,
verifier: pkce.verifier)
try MoltbotOAuthStore.saveAnthropicOAuth(creds)
self.refreshAnthropicOAuthStatus()
self.anthropicAuthStatus = "Connected. Moltbot can now use Claude."
} catch {
self.anthropicAuthStatus = "OAuth failed: \(error.localizedDescription)"
}
}
func pollAnthropicClipboardIfNeeded() {
guard self.currentPage == self.anthropicAuthPageIndex else { return }
guard self.anthropicAuthPKCE != nil else { return }
guard !self.anthropicAuthBusy else { return }
guard self.anthropicAuthAutoDetectClipboard else { return }
let pb = NSPasteboard.general
let changeCount = pb.changeCount
guard changeCount != self.anthropicAuthLastPasteboardChangeCount else { return }
self.anthropicAuthLastPasteboardChangeCount = changeCount
guard let raw = pb.string(forType: .string), !raw.isEmpty else { return }
guard let parsed = AnthropicOAuthCodeState.parse(from: raw) else { return }
guard let pkce = self.anthropicAuthPKCE, parsed.state == pkce.verifier else { return }
let next = "\(parsed.code)#\(parsed.state)"
if self.anthropicAuthCode != next {
self.anthropicAuthCode = next
self.anthropicAuthStatus = "Detected `code#state` from clipboard."
}
guard self.anthropicAuthAutoConnectClipboard else { return }
Task { await self.finishAnthropicOAuth() }
}
}