Gateway lifecycle on macOS: launchd management and child process

This page explains how the macOS app manages the Gateway through launchd by default, including auto-start and crash recovery. It also covers child-process mode and unsigned dev builds for developers.

Read this when

  • Integrating the mac app with the gateway lifecycle

The macOS app manages the Gateway through launchd by default instead of spawning it as a child process. It first attempts to connect to an already running Gateway on the configured port. If none is reachable, it activates the launchd service using the external openclaw CLI (no embedded runtime). This provides reliable auto-start on login and automatic restart after crashes.

Child-process mode, where the Gateway is spawned directly by the app, is not used currently. If you require tighter integration with the UI, start the Gateway manually in a terminal.

Default behavior (launchd)

  • The app installs a per-user LaunchAgent labeled ai.openclaw.gateway (or ai.openclaw.<profile> when using --profile/OPENCLAW_PROFILE).
  • With Local mode enabled, the app ensures the LaunchAgent is loaded and starts the Gateway if necessary.
  • Logs are written to the launchd gateway log path (visible in Debug Settings).

Common commands:

launchctl kickstart -k gui/$UID/ai.openclaw.gateway
launchctl bootout gui/$UID/ai.openclaw.gateway

Replace the label with ai.openclaw.<profile> when using a named profile.

Unsigned dev builds

scripts/restart-mac.sh --no-sign is intended for fast local builds without signing keys. To prevent launchd from targeting an unsigned relay binary, it writes ~/.openclaw/disable-launchagent.

Signed runs of scripts/restart-mac.sh remove this override if the marker exists. To reset manually:

rm ~/.openclaw/disable-launchagent

Attach-only mode

To prevent the macOS app from installing or managing launchd, start it with --attach-only (or --no-launchd). This sets ~/.openclaw/disable-launchagent, so the app only connects to an already running Gateway. Toggle the same behavior in Debug Settings.

Remote mode

Remote mode never starts a local Gateway. The app uses an SSH tunnel to the remote host and connects through that tunnel.

Why we prefer launchd

  • Auto-start at login.
  • Built-in restart and KeepAlive semantics.
  • Predictable logs and supervision.

If a true child-process mode is ever required again, it should be documented as a separate, explicit dev-only mode.