diff --git a/CHANGELOG.md b/CHANGELOG.md index a45315b20..614a47cca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -52,6 +52,7 @@ Status: unreleased. - **BREAKING:** Gateway auth mode "none" is removed; gateway now requires token/password (Tailscale Serve identity still allowed). ### Fixes +- macOS: disable gateway launchd job when switching to remote mode. (#2433) - Security: pin npm overrides to keep tar@7.5.4 for install toolchains. - BlueBubbles: coalesce inbound URL link preview messages. (#1981) Thanks @tyler6204. - Agents: include memory.md when bootstrapping memory context. (#2318) Thanks @czekaj. diff --git a/apps/macos/Sources/Clawdbot/GatewayLaunchAgentManager.swift b/apps/macos/Sources/Clawdbot/GatewayLaunchAgentManager.swift index f0896e691..400aa43e6 100644 --- a/apps/macos/Sources/Clawdbot/GatewayLaunchAgentManager.swift +++ b/apps/macos/Sources/Clawdbot/GatewayLaunchAgentManager.swift @@ -51,8 +51,10 @@ enum GatewayLaunchAgentManager { static func set(enabled: Bool, bundlePath: String, port: Int) async -> String? { _ = bundlePath - guard !CommandResolver.connectionModeIsRemote() else { - self.logger.info("launchd change skipped (remote mode)") + // In remote mode, skip enabling (the local gateway shouldn't run), but still + // allow disabling so the launchd job stops retrying every 10 seconds. + if enabled, CommandResolver.connectionModeIsRemote() { + self.logger.info("launchd enable skipped (remote mode)") return nil } if enabled, self.isLaunchAgentWriteDisabled() { diff --git a/apps/macos/Sources/Clawdbot/GatewayProcessManager.swift b/apps/macos/Sources/Clawdbot/GatewayProcessManager.swift index 60964fa39..1356851bd 100644 --- a/apps/macos/Sources/Clawdbot/GatewayProcessManager.swift +++ b/apps/macos/Sources/Clawdbot/GatewayProcessManager.swift @@ -129,9 +129,8 @@ final class GatewayProcessManager { self.lastFailureReason = nil self.status = .stopped self.logger.info("gateway stop requested") - if CommandResolver.connectionModeIsRemote() { - return - } + // Always disable the launchd job, even in remote mode. Otherwise the job + // keeps restarting the gateway daemon every 10 seconds (KeepAlive throttle). let bundlePath = Bundle.main.bundleURL.path Task { _ = await GatewayLaunchAgentManager.set(