Files
openclaw/apps/macos/Sources/Clawdbot/ConnectionModeCoordinator.swift

67 lines
2.8 KiB
Swift
Raw Normal View History

2025-12-10 01:43:59 +01:00
import Foundation
import OSLog
@MainActor
final class ConnectionModeCoordinator {
static let shared = ConnectionModeCoordinator()
2026-01-04 14:32:47 +00:00
private let logger = Logger(subsystem: "com.clawdbot", category: "connection")
2025-12-10 01:43:59 +01:00
/// Apply the requested connection mode by starting/stopping local gateway,
/// managing the control-channel SSH tunnel, and cleaning up chat windows/panels.
2025-12-10 01:43:59 +01:00
func apply(mode: AppState.ConnectionMode, paused: Bool) async {
switch mode {
case .unconfigured:
await RemoteTunnelManager.shared.stopAll()
WebChatManager.shared.resetTunnels()
GatewayProcessManager.shared.stop()
await GatewayConnection.shared.shutdown()
await ControlChannel.shared.disconnect()
Task.detached { await PortGuardian.shared.sweep(mode: .unconfigured) }
2025-12-10 01:43:59 +01:00
case .local:
await RemoteTunnelManager.shared.stopAll()
WebChatManager.shared.resetTunnels()
2025-12-20 14:46:53 +00:00
let shouldStart = GatewayAutostartPolicy.shouldStartGateway(mode: .local, paused: paused)
if shouldStart {
2025-12-10 01:43:59 +01:00
GatewayProcessManager.shared.setActive(true)
2025-12-20 14:46:53 +00:00
if GatewayAutostartPolicy.shouldEnsureLaunchAgent(
mode: .local,
paused: paused,
attachExistingOnly: AppStateStore.attachExistingGatewayOnly)
{
Task { await GatewayProcessManager.shared.ensureLaunchAgentEnabledIfNeeded() }
}
_ = await GatewayProcessManager.shared.waitForGatewayReady()
2025-12-20 14:46:53 +00:00
} else {
GatewayProcessManager.shared.stop()
2025-12-10 01:43:59 +01:00
}
do {
try await ControlChannel.shared.configure(mode: .local)
} catch {
// Control channel will mark itself degraded; nothing else to do here.
self.logger.error(
"control channel local configure failed: \(error.localizedDescription, privacy: .public)")
}
2025-12-10 01:43:59 +01:00
Task.detached { await PortGuardian.shared.sweep(mode: .local) }
case .remote:
// Never run a local gateway in remote mode.
GatewayProcessManager.shared.stop()
WebChatManager.shared.resetTunnels()
do {
_ = try await GatewayEndpointStore.shared.ensureRemoteControlTunnel()
2025-12-10 01:43:59 +01:00
let settings = CommandResolver.connectionSettings()
try await ControlChannel.shared.configure(mode: .remote(
target: settings.target,
identity: settings.identity))
} catch {
self.logger.error("remote tunnel/configure failed: \(error.localizedDescription, privacy: .public)")
}
Task.detached { await PortGuardian.shared.sweep(mode: .remote) }
}
}
}