fix(macos): disable gateway launchd job when switching to remote mode

Previously the stop() function had an early return when in remote mode,
which skipped disabling the launchd job. This caused the gateway daemon
to restart every 10 seconds due to KeepAlive, logging repeated 'Gateway
start blocked' messages.

Fixes #2433
This commit is contained in:
Kenny Lee 2026-01-26 15:17:17 -08:00
parent cd7be58b8e
commit e119cfb468
3 changed files with 7 additions and 5 deletions

View File

@ -52,6 +52,7 @@ Status: unreleased.
- **BREAKING:** Gateway auth mode "none" is removed; gateway now requires token/password (Tailscale Serve identity still allowed). - **BREAKING:** Gateway auth mode "none" is removed; gateway now requires token/password (Tailscale Serve identity still allowed).
### Fixes ### 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. - Security: pin npm overrides to keep tar@7.5.4 for install toolchains.
- BlueBubbles: coalesce inbound URL link preview messages. (#1981) Thanks @tyler6204. - BlueBubbles: coalesce inbound URL link preview messages. (#1981) Thanks @tyler6204.
- Agents: include memory.md when bootstrapping memory context. (#2318) Thanks @czekaj. - Agents: include memory.md when bootstrapping memory context. (#2318) Thanks @czekaj.

View File

@ -51,8 +51,10 @@ enum GatewayLaunchAgentManager {
static func set(enabled: Bool, bundlePath: String, port: Int) async -> String? { static func set(enabled: Bool, bundlePath: String, port: Int) async -> String? {
_ = bundlePath _ = bundlePath
guard !CommandResolver.connectionModeIsRemote() else { // In remote mode, skip enabling (the local gateway shouldn't run), but still
self.logger.info("launchd change skipped (remote mode)") // 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 return nil
} }
if enabled, self.isLaunchAgentWriteDisabled() { if enabled, self.isLaunchAgentWriteDisabled() {

View File

@ -129,9 +129,8 @@ final class GatewayProcessManager {
self.lastFailureReason = nil self.lastFailureReason = nil
self.status = .stopped self.status = .stopped
self.logger.info("gateway stop requested") self.logger.info("gateway stop requested")
if CommandResolver.connectionModeIsRemote() { // Always disable the launchd job, even in remote mode. Otherwise the job
return // keeps restarting the gateway daemon every 10 seconds (KeepAlive throttle).
}
let bundlePath = Bundle.main.bundleURL.path let bundlePath = Bundle.main.bundleURL.path
Task { Task {
_ = await GatewayLaunchAgentManager.set( _ = await GatewayLaunchAgentManager.set(