Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:Openclaw Openclaw RunDaemonRestart

From Leeroopedia


RunDaemonRestart

This page documents the implementation of Gateway Restart in the OpenClaw gateway. It covers the runDaemonRestart function for programmatic service restart and the scripts/restart-mac.sh script for full macOS development restart cycles.

Source Locations

Function/Script File Lines
runDaemonRestart src/cli/daemon-cli/lifecycle.ts L239-319
restart-mac.sh scripts/restart-mac.sh L1-270

runDaemonRestart

Signature

export async function runDaemonRestart(opts: DaemonLifecycleOptions = {}): Promise<boolean>

Purpose

Restarts the gateway service via the OS service manager. Returns true if the restart succeeded, false if the service was not loaded. Throws or exits the process on check or restart failures.

Parameters

type DaemonLifecycleOptions = {
  json?: boolean;
};
Option Type Description
json boolean (optional) When true, emit structured JSON output instead of human-readable text. Default: false.

Behavior

Step 1: Setup

  • Resolves output mode: if json is true, creates a null writer to suppress stdout text and prepares a JSON emitter; otherwise uses process.stdout.
  • Defines a fail helper that either emits a JSON error payload or writes to stderr, then exits with code 1.

Step 2: Service state check

const service = resolveGatewayService();
let loaded = false;
try {
  loaded = await service.isLoaded({ env: process.env });
} catch (err) {
  fail(`Gateway service check failed: ${String(err)}`);
  return false;
}

Resolves the platform-appropriate gateway service and checks whether it is loaded. On check failure, reports the error and exits.

Step 3: Not loaded handling

If the service is not loaded:

  • Generates start hints via renderGatewayServiceStartHints().
  • On Linux, additionally checks isSystemdUserServiceAvailable() and adds systemd-specific hints (including WSL-aware guidance).
  • Emits a JSON payload (if JSON mode) or prints "Gateway service not loaded" with hints.
  • Returns false.

Step 4: Restart

If the service is loaded:

try {
  await service.restart({ env: process.env, stdout });
  let restarted = true;
  try {
    restarted = await service.isLoaded({ env: process.env });
  } catch {
    restarted = true;
  }
  emit({
    ok: true,
    result: "restarted",
    service: buildDaemonServiceSnapshot(service, restarted),
  });
  return true;
} catch (err) {
  const hints = renderGatewayServiceStartHints();
  fail(`Gateway restart failed: ${String(err)}`, hints);
  return false;
}
  • Calls service.restart() which delegates to the platform service manager (launchd or systemd).
  • After restart, verifies the service is still loaded (detecting crash-on-start).
  • Emits a success JSON payload or returns true.
  • On failure, reports the error with hints and exits.

Return Value

Value Meaning
true Restart succeeded; the service is running.
false The service was not loaded (not an error; the caller should decide how to proceed).

The function may also exit the process (via defaultRuntime.exit(1)) on service check or restart failures.

JSON Output Schema

When json: true, the function emits payloads via emitDaemonActionJson:

// Success
{
  action: "restart",
  ok: true,
  result: "restarted",
  service: {
    label: string,        // e.g., "ai.openclaw.mac"
    loaded: boolean,
    loadedText: string,    // e.g., "loaded"
    notLoadedText: string  // e.g., "not loaded"
  }
}

// Not loaded
{
  action: "restart",
  ok: true,
  result: "not-loaded",
  message: "Gateway service not loaded.",
  hints: string[],
  service: { ... }
}

// Failure
{
  action: "restart",
  ok: false,
  error: "Gateway restart failed: ...",
  hints: string[]
}

Related Lifecycle Functions

The same file (src/cli/daemon-cli/lifecycle.ts) contains sibling functions that share the same pattern:

Function Lines Purpose
runDaemonUninstall L11-81 Stops and uninstalls the gateway service.
runDaemonStart L83-163 Starts the gateway service (restarts if already loaded).
runDaemonStop L165-232 Stops the gateway service.
runDaemonRestart L239-319 Restarts the gateway service (documented above).

All four functions follow the same structure: resolve service, check loaded state, perform action, verify post-state, emit result.

scripts/restart-mac.sh

Purpose

A comprehensive macOS development restart script that performs a full kill-rebuild-package-relaunch cycle. Used during development when changes span both the TypeScript gateway and the Swift macOS app.

Usage

scripts/restart-mac.sh [--wait] [--no-sign] [--sign] [--attach-only|--no-attach-only]
Flag Description
--wait Wait for another running restart to complete instead of exiting.
--no-sign Force ad-hoc code signing (fastest for development).
--sign Force proper code signing (fails if no signing key is available).
--attach-only Launch the app with --attach-only (skip launchd install). Default.
--no-attach-only Launch the app without the attach-only override.

Behavior

1. Lock acquisition -- Uses a directory-based lock (/tmp/openclaw-restart-<hash>) to prevent concurrent restart runs. The lock holder's PID is recorded; stale locks from dead processes are automatically cleaned.

2. Kill all instances -- Iterates up to 10 times, killing all OpenClaw processes matching app bundle, debug build, local build, and release build patterns. Waits 300ms between attempts.

3. Stop LaunchAgent -- Runs launchctl bootout gui/$UID/ai.openclaw.mac.

4. Canvas A2UI bundle -- Runs pnpm canvas:a2ui:bundle to bundle the Canvas A2UI assets.

5. Clean and rebuild -- Removes the Swift build cache and runs swift build -q --product OpenClaw.

6. Code signing resolution -- Auto-detects signing keys via security find-identity -p codesigning. Falls back to ad-hoc signing if no keys are found.

7. Package -- Runs scripts/package-mac-app.sh to create the app bundle.

8. Unsigned flow (optional) -- When unsigned:

  • Writes a disable-launchagent marker to prevent the app from managing the LaunchAgent.
  • Installs the gateway daemon via node openclaw.mjs daemon install --force --runtime node.
  • Restarts the gateway daemon.
  • Verifies the gateway port is listening via lsof.

9. Launch -- Opens the app bundle via /usr/bin/open with a sanitized environment (env -i with only essential variables: HOME, USER, LOGNAME, TMPDIR, PATH, LANG).

10. Verification -- Waits 1.5 seconds and checks for the running process via pgrep.

Environment Variables

Variable Description
OPENCLAW_APP_BUNDLE Override the app bundle path (default: auto-detected from /Applications or dist/).
OPENCLAW_GATEWAY_WAIT_SECONDS Wait time before gateway port check in unsigned mode (default: 0).
OPENCLAW_RESTART_LOG Log file path (default: /tmp/openclaw-restart.log).

Dependencies

Module Purpose
src/daemon/service.ts resolveGatewayService for platform-specific service abstraction.
src/daemon/systemd.ts isSystemdUserServiceAvailable for Linux systemd detection.
src/daemon/systemd-hints.ts renderSystemdUnavailableHints for Linux-specific guidance.
src/infra/wsl.ts isWSL for Windows Subsystem for Linux detection.
src/cli/daemon-cli/response.ts buildDaemonServiceSnapshot, createNullWriter, emitDaemonActionJson.
src/cli/daemon-cli/shared.ts renderGatewayServiceStartHints for start hint generation.

Principle:Openclaw_Openclaw_Gateway_Restart

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment