{
  "schemaVersion": "1.0",
  "item": {
    "slug": "openclaw-macos-always-on",
    "name": "OpenClaw macOS Always-On",
    "source": "tencent",
    "type": "skill",
    "category": "开发工具",
    "sourceUrl": "https://clawhub.ai/happydog-intj/openclaw-macos-always-on",
    "canonicalUrl": "https://clawhub.ai/happydog-intj/openclaw-macos-always-on",
    "targetPlatform": "OpenClaw"
  },
  "install": {
    "downloadMode": "redirect",
    "downloadUrl": "/downloads/openclaw-macos-always-on",
    "sourceDownloadUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=openclaw-macos-always-on",
    "sourcePlatform": "tencent",
    "targetPlatform": "OpenClaw",
    "installMethod": "Manual import",
    "extraction": "Extract archive",
    "prerequisites": [
      "OpenClaw"
    ],
    "packageFormat": "ZIP package",
    "includedAssets": [
      "README.md",
      "README.zh-CN.md",
      "SKILL.md",
      "install.sh"
    ],
    "primaryDoc": "SKILL.md",
    "quickSetup": [
      "Download the package from Yavira.",
      "Extract the archive and review SKILL.md first.",
      "Import or place the package into your OpenClaw setup."
    ],
    "agentAssist": {
      "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
      "steps": [
        "Download the package from Yavira.",
        "Extract it into a folder your agent can access.",
        "Paste one of the prompts below and point your agent at the extracted folder."
      ],
      "prompts": [
        {
          "label": "New install",
          "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
        },
        {
          "label": "Upgrade existing",
          "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
        }
      ]
    },
    "sourceHealth": {
      "source": "tencent",
      "status": "healthy",
      "reason": "direct_download_ok",
      "recommendedAction": "download",
      "checkedAt": "2026-04-30T16:55:25.780Z",
      "expiresAt": "2026-05-07T16:55:25.780Z",
      "httpStatus": 200,
      "finalUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
      "contentType": "application/zip",
      "probeMethod": "head",
      "details": {
        "probeUrl": "https://wry-manatee-359.convex.site/api/v1/download?slug=network",
        "contentDisposition": "attachment; filename=\"network-1.0.0.zip\"",
        "redirectLocation": null,
        "bodySnippet": null
      },
      "scope": "source",
      "summary": "Source download looks usable.",
      "detail": "Yavira can redirect you to the upstream package for this source.",
      "primaryActionLabel": "Download for OpenClaw",
      "primaryActionHref": "/downloads/openclaw-macos-always-on"
    },
    "validation": {
      "installChecklist": [
        "Use the Yavira download entry.",
        "Review SKILL.md after the package is downloaded.",
        "Confirm the extracted package contains the expected setup assets."
      ],
      "postInstallChecks": [
        "Confirm the extracted package includes the expected docs or setup files.",
        "Validate the skill or prompts are available in your target agent workspace.",
        "Capture any manual follow-up steps the agent could not complete."
      ]
    },
    "downloadPageUrl": "https://openagent3.xyz/downloads/openclaw-macos-always-on",
    "agentPageUrl": "https://openagent3.xyz/skills/openclaw-macos-always-on/agent",
    "manifestUrl": "https://openagent3.xyz/skills/openclaw-macos-always-on/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/openclaw-macos-always-on/agent.md"
  },
  "agentAssist": {
    "summary": "Hand the extracted package to your coding agent with a concrete install brief instead of figuring it out manually.",
    "steps": [
      "Download the package from Yavira.",
      "Extract it into a folder your agent can access.",
      "Paste one of the prompts below and point your agent at the extracted folder."
    ],
    "prompts": [
      {
        "label": "New install",
        "body": "I downloaded a skill package from Yavira. Read SKILL.md from the extracted folder and install it by following the included instructions. Then review README.md for any prerequisites, environment setup, or post-install checks. Tell me what you changed and call out any manual steps you could not complete."
      },
      {
        "label": "Upgrade existing",
        "body": "I downloaded an updated skill package from Yavira. Read SKILL.md from the extracted folder, compare it with my current installation, and upgrade it while preserving any custom configuration unless the package docs explicitly say otherwise. Then review README.md for any prerequisites, environment setup, or post-install checks. Summarize what changed and any follow-up checks I should run."
      }
    ]
  },
  "documentation": {
    "source": "clawhub",
    "primaryDoc": "SKILL.md",
    "sections": [
      {
        "title": "macOS LaunchDaemon Setup for OpenClaw",
        "body": "Run OpenClaw as a system-level service (LaunchDaemon) with caffeinate to ensure 24/7 operation. This configuration has been tested and verified to work even after extended screen lock periods (30+ minutes).\n\nEnsures OpenClaw continues running when:\n\n🔒 Screen is locked (short or long duration)\n👤 User is logged out\n🔄 Switching between user accounts\n💤 Display sleeps (system stays awake)"
      },
      {
        "title": "When to Use This",
        "body": "Use LaunchDaemon if:\n\nYou need 24/7 bot availability\nYou lock your Mac regularly but want messages to still work\nMultiple users on the same Mac need to access the bot\nRunning on a home server/always-on Mac\n\nUse LaunchAgent if:\n\nOnly need bot while logged in\nPrefer simpler setup (no sudo)\nSecurity-conscious about system-level services"
      },
      {
        "title": "One-Command Installation",
        "body": "curl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/clawd/master/skills/macos-launchdaemon/install.sh | bash\n\nOr manual setup below ⬇️"
      },
      {
        "title": "Step 1: Create LaunchDaemon Configuration",
        "body": "Create the plist file with your actual username. This configuration uses caffeinate and has been tested and verified to work even after 30+ minutes of screen lock:\n\ncat > /tmp/ai.openclaw.gateway.plist << 'EOF'\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n  <dict>\n    <key>Label</key>\n    <string>ai.openclaw.gateway</string>\n    \n    <key>Comment</key>\n    <string>OpenClaw Gateway (System Daemon - Network Always On)</string>\n    \n    <key>RunAtLoad</key>\n    <true/>\n    \n    <!-- Enhanced KeepAlive for network services -->\n    <key>KeepAlive</key>\n    <dict>\n      <key>SuccessfulExit</key>\n      <false/>\n      <key>NetworkState</key>\n      <true/>\n      <key>Crashed</key>\n      <true/>\n    </dict>\n    \n    <!-- Prevent ANY throttling -->\n    <key>ThrottleInterval</key>\n    <integer>0</integer>\n    \n    <!-- Interactive process - highest priority -->\n    <key>ProcessType</key>\n    <string>Interactive</string>\n    \n    <!-- Enable network transactions -->\n    <key>EnableTransactions</key>\n    <true/>\n    \n    <key>UserName</key>\n    <string>YOUR_USERNAME</string>\n    \n    <key>GroupName</key>\n    <string>staff</string>\n    \n    <!-- Wrap with caffeinate to prevent sleep -->\n    <key>ProgramArguments</key>\n    <array>\n      <string>/usr/bin/caffeinate</string>\n      <string>-s</string>\n      <string>/opt/homebrew/bin/node</string>\n      <string>/opt/homebrew/lib/node_modules/openclaw/dist/index.js</string>\n      <string>gateway</string>\n      <string>--port</string>\n      <string>18789</string>\n    </array>\n    \n    <key>StandardOutPath</key>\n    <string>/Users/YOUR_USERNAME/.openclaw/logs/gateway.log</string>\n    \n    <key>StandardErrorPath</key>\n    <string>/Users/YOUR_USERNAME/.openclaw/logs/gateway.err.log</string>\n    \n    <key>EnvironmentVariables</key>\n    <dict>\n      <key>HOME</key>\n      <string>/Users/YOUR_USERNAME</string>\n      <key>PATH</key>\n      <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>\n    </dict>\n  </dict>\n</plist>\nEOF\n\n# Replace YOUR_USERNAME with your actual username\nsed -i '' \"s/YOUR_USERNAME/$(whoami)/g\" /tmp/ai.openclaw.gateway.plist\n\n🔑 Key Configuration for Lock Screen Persistence:\n\n/usr/bin/caffeinate -s - Prevents system sleep (display can sleep, network stays active)\nNetworkState: true - Ensures service stays active when network is available\nProcessType: Interactive - Prevents macOS from suspending the process\nThrottleInterval: 0 - Disables any throttling\nCrashed: true - Auto-restarts on crashes\n\n✅ Verified working after 30+ minutes of screen lock on macOS 14.4"
      },
      {
        "title": "Step 2: Stop Existing LaunchAgent",
        "body": "# Stop user-level service\nlaunchctl bootout gui/$(id -u)/ai.openclaw.gateway 2>/dev/null\n\n# Backup and disable LaunchAgent plist\nmv ~/Library/LaunchAgents/ai.openclaw.gateway.plist ~/Library/LaunchAgents/ai.openclaw.gateway.plist.disabled 2>/dev/null"
      },
      {
        "title": "Step 3: Install LaunchDaemon (requires sudo)",
        "body": "# Copy to system location\nsudo cp /tmp/ai.openclaw.gateway.plist /Library/LaunchDaemons/\n\n# Set correct permissions\nsudo chown root:wheel /Library/LaunchDaemons/ai.openclaw.gateway.plist\nsudo chmod 644 /Library/LaunchDaemons/ai.openclaw.gateway.plist\n\n# Load and start service\nsudo launchctl bootstrap system /Library/LaunchDaemons/ai.openclaw.gateway.plist"
      },
      {
        "title": "Step 4: Verify Installation",
        "body": "# Check process is running\nps aux | grep openclaw-gateway | grep -v grep\n\n# Verify PPID = 1 (launched by system launchd)\nps -p $(pgrep -f openclaw-gateway) -o pid,ppid,user,command\n\n# Check service status\nsudo launchctl print system/ai.openclaw.gateway | head -10\n\n# Test with OpenClaw\nopenclaw status\n\nExpected output:\n\nPID   PPID  USER       COMMAND\n12345 1     youruser   openclaw-gateway\n\nPPID=1 confirms it's running as LaunchDaemon (parent is system launchd)."
      },
      {
        "title": "Test Script",
        "body": "#!/bin/bash\necho \"🧪 Testing LaunchDaemon lock screen behavior...\"\necho \"\"\necho \"1. Lock your Mac in 5 seconds...\"\nsleep 5\npmset displaysleepnow\n\necho \"2. Use your phone to send 'ping' to your bot\"\necho \"3. Bot should reply 'pong! 🎉' even while locked\"\necho \"\"\necho \"Unlock your Mac after testing.\""
      },
      {
        "title": "Manual Test Steps",
        "body": "Lock your Mac: ⌘ + Control + Q\nSend from phone: Message your bot (Telegram/Feishu/etc.) with \"ping\"\nExpected: Bot replies \"pong! 🎉\" immediately\nUnlock and verify logs show the message was processed"
      },
      {
        "title": "View Logs",
        "body": "# Real-time logs\ntail -f ~/.openclaw/logs/gateway.log\n\n# Error logs\ntail -f ~/.openclaw/logs/gateway.err.log\n\n# Last 100 lines\ntail -100 ~/.openclaw/logs/gateway.log"
      },
      {
        "title": "Restart Service",
        "body": "# Unload and reload\nsudo launchctl bootout system/ai.openclaw.gateway\nsudo launchctl bootstrap system /Library/LaunchDaemons/ai.openclaw.gateway.plist\n\n# Or use kickstart (restarts without unloading)\nsudo launchctl kickstart -k system/ai.openclaw.gateway"
      },
      {
        "title": "Stop Service",
        "body": "# Stop service\nsudo launchctl bootout system/ai.openclaw.gateway\n\n# Prevent auto-start\nsudo launchctl disable system/ai.openclaw.gateway"
      },
      {
        "title": "Start Service",
        "body": "# Enable and start\nsudo launchctl enable system/ai.openclaw.gateway\nsudo launchctl bootstrap system /Library/LaunchDaemons/ai.openclaw.gateway.plist"
      },
      {
        "title": "Check Status",
        "body": "# Full service details\nsudo launchctl print system/ai.openclaw.gateway\n\n# Quick status check\nsudo launchctl list | grep openclaw\n\n# Process info\nps aux | grep openclaw-gateway | grep -v grep"
      },
      {
        "title": "Complete Removal",
        "body": "# 1. Stop service\nsudo launchctl bootout system/ai.openclaw.gateway\n\n# 2. Remove plist\nsudo rm /Library/LaunchDaemons/ai.openclaw.gateway.plist\n\n# 3. Restore LaunchAgent (optional)\nmv ~/Library/LaunchAgents/ai.openclaw.gateway.plist.disabled ~/Library/LaunchAgents/ai.openclaw.gateway.plist 2>/dev/null\nlaunchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist\n\n# 4. Verify\nps aux | grep openclaw | grep -v grep"
      },
      {
        "title": "Automated Install Script",
        "body": "Save this as install-launchdaemon.sh:\n\n#!/bin/bash\nset -e\n\necho \"🚀 OpenClaw LaunchDaemon Installer\"\necho \"==================================\"\necho \"\"\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nNC='\\033[0m' # No Color\n\nUSERNAME=$(whoami)\nPLIST_PATH=\"/Library/LaunchDaemons/ai.openclaw.gateway.plist\"\nTEMP_PLIST=\"/tmp/ai.openclaw.gateway.plist\"\n\n# Check if running as root\nif [ \"$EUID\" -eq 0 ]; then \n   echo -e \"${RED}❌ Don't run this script with sudo${NC}\"\n   echo \"The script will ask for sudo password when needed.\"\n   exit 1\nfi\n\n# Check if OpenClaw is installed\nif ! command -v openclaw &> /dev/null; then\n    echo -e \"${RED}❌ OpenClaw not found. Install it first:${NC}\"\n    echo \"   npm install -g openclaw\"\n    exit 1\nfi\n\necho -e \"${YELLOW}📋 Creating LaunchDaemon configuration...${NC}\"\n\n# Get OpenClaw gateway token\nGATEWAY_TOKEN=$(openclaw config get gateway.auth.token 2>/dev/null | tr -d '\"' || echo \"\")\n\ncat > \"$TEMP_PLIST\" << EOF\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n  <dict>\n    <key>Label</key>\n    <string>ai.openclaw.gateway</string>\n    \n    <key>Comment</key>\n    <string>OpenClaw Gateway (System Daemon)</string>\n    \n    <key>RunAtLoad</key>\n    <true/>\n    \n    <key>KeepAlive</key>\n    <true/>\n    \n    <key>UserName</key>\n    <string>$USERNAME</string>\n    \n    <key>GroupName</key>\n    <string>staff</string>\n    \n    <key>ProgramArguments</key>\n    <array>\n      <string>/opt/homebrew/bin/node</string>\n      <string>/opt/homebrew/lib/node_modules/openclaw/dist/index.js</string>\n      <string>gateway</string>\n      <string>--port</string>\n      <string>18789</string>\n    </array>\n    \n    <key>StandardOutPath</key>\n    <string>/Users/$USERNAME/.openclaw/logs/gateway.log</string>\n    \n    <key>StandardErrorPath</key>\n    <string>/Users/$USERNAME/.openclaw/logs/gateway.err.log</string>\n    \n    <key>EnvironmentVariables</key>\n    <dict>\n      <key>HOME</key>\n      <string>/Users/$USERNAME</string>\n      <key>PATH</key>\n      <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>\n      <key>OPENCLAW_GATEWAY_PORT</key>\n      <string>18789</string>\n      <key>OPENCLAW_GATEWAY_TOKEN</key>\n      <string>$GATEWAY_TOKEN</string>\n    </dict>\n  </dict>\n</plist>\nEOF\n\necho -e \"${YELLOW}🛑 Stopping existing services...${NC}\"\n\n# Stop LaunchAgent\nlaunchctl bootout gui/$(id -u)/ai.openclaw.gateway 2>/dev/null || true\n\n# Backup LaunchAgent plist\nif [ -f ~/Library/LaunchAgents/ai.openclaw.gateway.plist ]; then\n    mv ~/Library/LaunchAgents/ai.openclaw.gateway.plist ~/Library/LaunchAgents/ai.openclaw.gateway.plist.backup\n    echo -e \"${GREEN}✅ Backed up LaunchAgent plist${NC}\"\nfi\n\n# Stop existing LaunchDaemon\nsudo launchctl bootout system/ai.openclaw.gateway 2>/dev/null || true\n\necho -e \"${YELLOW}📦 Installing LaunchDaemon...${NC}\"\n\n# Install plist\nsudo cp \"$TEMP_PLIST\" \"$PLIST_PATH\"\nsudo chown root:wheel \"$PLIST_PATH\"\nsudo chmod 644 \"$PLIST_PATH\"\n\necho -e \"${YELLOW}🚀 Starting service...${NC}\"\n\n# Start service\nsudo launchctl bootstrap system \"$PLIST_PATH\"\nsleep 3\n\n# Verify\nif ps aux | grep -q \"[o]penclaw-gateway\"; then\n    echo \"\"\n    echo -e \"${GREEN}✅ LaunchDaemon installed successfully!${NC}\"\n    echo \"\"\n    echo \"📊 Service Status:\"\n    ps aux | grep \"[o]penclaw-gateway\" | awk '{print \"   PID: \"$2\", User: \"$1}'\n    echo \"\"\n    echo \"🧪 Test it:\"\n    echo \"   1. Lock your Mac: ⌘ + Control + Q\"\n    echo \"   2. Send 'ping' from your phone\"\n    echo \"   3. Bot should reply even while locked!\"\n    echo \"\"\n    echo \"📋 Management:\"\n    echo \"   Logs:    tail -f ~/.openclaw/logs/gateway.log\"\n    echo \"   Restart: sudo launchctl kickstart -k system/ai.openclaw.gateway\"\n    echo \"   Stop:    sudo launchctl bootout system/ai.openclaw.gateway\"\n    echo \"   Status:  sudo launchctl print system/ai.openclaw.gateway\"\nelse\n    echo -e \"${RED}❌ Service failed to start${NC}\"\n    echo \"Check logs: tail -50 ~/.openclaw/logs/gateway.err.log\"\n    exit 1\nfi\n\nMake it executable:\n\nchmod +x install-launchdaemon.sh\n./install-launchdaemon.sh"
      },
      {
        "title": "Service Won't Start",
        "body": "Check logs:\n\ntail -50 ~/.openclaw/logs/gateway.err.log\n\nCommon issues:\n\nWrong username in plist\n# Verify username matches\ngrep UserName /Library/LaunchDaemons/ai.openclaw.gateway.plist\nwhoami\n\n\n\nWrong node path\n# Check node location\nwhich node\n\n# Update plist if needed (change /opt/homebrew/bin/node to your path)\n\n\n\nPermissions issues\n# Fix log directory permissions\nmkdir -p ~/.openclaw/logs\nchmod 755 ~/.openclaw/logs"
      },
      {
        "title": "Still Suspends After Lock",
        "body": "If using older macOS or specific hardware:\n\n# Prevent system sleep\nsudo pmset -a sleep 0\nsudo pmset -a disksleep 0\nsudo pmset -a displaysleep 10  # Screen off but system awake\n\nOr use caffeinate (not recommended for laptops):\n\n# Modify ProgramArguments in plist to wrap with caffeinate\n<string>/usr/bin/caffeinate</string>\n<string>-s</string>  <!-- prevent sleep -->\n<string>/opt/homebrew/bin/node</string>\n..."
      },
      {
        "title": "Port Already in Use",
        "body": "# Find what's using port 18789\nlsof -i :18789\n\n# Kill the process\nkill -9 <PID>\n\n# Or change port in config and plist\nopenclaw config set gateway.port 18790"
      },
      {
        "title": "Logs Not Writing",
        "body": "# Create log directory\nmkdir -p ~/.openclaw/logs\n\n# Test permissions\ntouch ~/.openclaw/logs/test.log\nls -la ~/.openclaw/logs/\n\n# Check plist paths match\ngrep Path /Library/LaunchDaemons/ai.openclaw.gateway.plist"
      },
      {
        "title": "Running as User vs Root",
        "body": "✅ This setup runs as your user (specified in <key>UserName</key>)\n\nNot running as root\nSame permissions as when you run OpenClaw manually\nSafer than true root daemons"
      },
      {
        "title": "File Permissions",
        "body": "# LaunchDaemon plist should be owned by root\nls -l /Library/LaunchDaemons/ai.openclaw.gateway.plist\n# Should show: -rw-r--r--  1 root  wheel\n\n# Log directory owned by you\nls -ld ~/.openclaw/logs\n# Should show: drwxr-xr-x ... youruser staff"
      },
      {
        "title": "Token Security",
        "body": "The Gateway token is stored in the plist environment variables. While readable only by root and your user, consider:\n\n# Check who can read the plist\nls -l /Library/LaunchDaemons/ai.openclaw.gateway.plist\n\n# More secure: use macOS Keychain (advanced)\n# Store token in keychain and retrieve at runtime"
      },
      {
        "title": "Performance Impact",
        "body": "LaunchDaemon has minimal performance impact:\n\nSame process as LaunchAgent\nRuns only when needed (KeepAlive handles crashes)\nIdle resource usage: ~50MB RAM, <1% CPU\nActive (processing messages): ~100MB RAM, varies by task"
      },
      {
        "title": "macOS Version Compatibility",
        "body": "Tested on:\n\n✅ macOS 10.15 (Catalina)\n✅ macOS 11 (Big Sur)\n✅ macOS 12 (Monterey)\n✅ macOS 13 (Ventura)\n✅ macOS 14 (Sonoma)\n✅ macOS 15 (Sequoia)\n\nNote: LaunchDaemon syntax changed slightly in macOS 11+, but backwards compatible."
      },
      {
        "title": "Comparison: LaunchAgent vs LaunchDaemon",
        "body": "FeatureLaunchAgentLaunchDaemonRuns when locked❌ May suspend✅ Always runsRuns when logged out❌ Stops✅ ContinuesSetup complexitySimpleRequires sudoRequires sudo❌ No✅ YesBest forPersonal use, logged-in only24/7 server, multi-userSecurityUser-levelSystem-level (still runs as user)Auto-startAt loginAt boot"
      },
      {
        "title": "From LaunchAgent to LaunchDaemon",
        "body": "Use the install script above, or:\n\n# Automatic migration\nlaunchctl bootout gui/$(id -u)/ai.openclaw.gateway\nmv ~/Library/LaunchAgents/ai.openclaw.gateway.plist ~/Library/LaunchAgents/ai.openclaw.gateway.plist.backup\n# Then follow installation steps"
      },
      {
        "title": "From LaunchDaemon back to LaunchAgent",
        "body": "# Stop daemon\nsudo launchctl bootout system/ai.openclaw.gateway\nsudo rm /Library/LaunchDaemons/ai.openclaw.gateway.plist\n\n# Restore agent\nmv ~/Library/LaunchAgents/ai.openclaw.gateway.plist.backup ~/Library/LaunchAgents/ai.openclaw.gateway.plist\nlaunchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist"
      },
      {
        "title": "FAQ",
        "body": "Q: Will this drain my battery?\nA: Minimal impact. OpenClaw idles at <1% CPU when not processing messages.\n\nQ: Can I still update OpenClaw?\nA: Yes. After updating, restart the service:\n\nsudo launchctl kickstart -k system/ai.openclaw.gateway\n\nQ: What if I upgrade macOS?\nA: LaunchDaemon survives OS upgrades. Verify it's still running after update:\n\nsudo launchctl print system/ai.openclaw.gateway\n\nQ: Can I run multiple instances?\nA: Not recommended. Use one LaunchDaemon with multiple channel accounts instead.\n\nQ: Does this work on M1/M2 Macs?\nA: Yes! Works on both Intel and Apple Silicon Macs."
      },
      {
        "title": "Related Skills",
        "body": "macos-lock-screen-fix - Alternative LaunchAgent fix (simpler but may not work on all Macs)\nhealthcheck - Monitor OpenClaw health and uptime"
      },
      {
        "title": "Contributing",
        "body": "Found issues or improvements?\n\nGitHub: https://github.com/openclaw/openclaw/issues\nPull requests welcome!\n\nQuick Commands Reference:\n\n# Status\nsudo launchctl print system/ai.openclaw.gateway\n\n# Restart\nsudo launchctl kickstart -k system/ai.openclaw.gateway\n\n# Logs\ntail -f ~/.openclaw/logs/gateway.log\n\n# Uninstall\nsudo launchctl bootout system/ai.openclaw.gateway\nsudo rm /Library/LaunchDaemons/ai.openclaw.gateway.plist"
      }
    ],
    "body": "macOS LaunchDaemon Setup for OpenClaw\n\nRun OpenClaw as a system-level service (LaunchDaemon) with caffeinate to ensure 24/7 operation. This configuration has been tested and verified to work even after extended screen lock periods (30+ minutes).\n\nEnsures OpenClaw continues running when:\n\n🔒 Screen is locked (short or long duration)\n👤 User is logged out\n🔄 Switching between user accounts\n💤 Display sleeps (system stays awake)\nWhen to Use This\n\nUse LaunchDaemon if:\n\nYou need 24/7 bot availability\nYou lock your Mac regularly but want messages to still work\nMultiple users on the same Mac need to access the bot\nRunning on a home server/always-on Mac\n\nUse LaunchAgent if:\n\nOnly need bot while logged in\nPrefer simpler setup (no sudo)\nSecurity-conscious about system-level services\nQuick Setup\nOne-Command Installation\ncurl -fsSL https://raw.githubusercontent.com/YOUR_USERNAME/clawd/master/skills/macos-launchdaemon/install.sh | bash\n\n\nOr manual setup below ⬇️\n\nManual Setup\nStep 1: Create LaunchDaemon Configuration\n\nCreate the plist file with your actual username. This configuration uses caffeinate and has been tested and verified to work even after 30+ minutes of screen lock:\n\ncat > /tmp/ai.openclaw.gateway.plist << 'EOF'\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n  <dict>\n    <key>Label</key>\n    <string>ai.openclaw.gateway</string>\n    \n    <key>Comment</key>\n    <string>OpenClaw Gateway (System Daemon - Network Always On)</string>\n    \n    <key>RunAtLoad</key>\n    <true/>\n    \n    <!-- Enhanced KeepAlive for network services -->\n    <key>KeepAlive</key>\n    <dict>\n      <key>SuccessfulExit</key>\n      <false/>\n      <key>NetworkState</key>\n      <true/>\n      <key>Crashed</key>\n      <true/>\n    </dict>\n    \n    <!-- Prevent ANY throttling -->\n    <key>ThrottleInterval</key>\n    <integer>0</integer>\n    \n    <!-- Interactive process - highest priority -->\n    <key>ProcessType</key>\n    <string>Interactive</string>\n    \n    <!-- Enable network transactions -->\n    <key>EnableTransactions</key>\n    <true/>\n    \n    <key>UserName</key>\n    <string>YOUR_USERNAME</string>\n    \n    <key>GroupName</key>\n    <string>staff</string>\n    \n    <!-- Wrap with caffeinate to prevent sleep -->\n    <key>ProgramArguments</key>\n    <array>\n      <string>/usr/bin/caffeinate</string>\n      <string>-s</string>\n      <string>/opt/homebrew/bin/node</string>\n      <string>/opt/homebrew/lib/node_modules/openclaw/dist/index.js</string>\n      <string>gateway</string>\n      <string>--port</string>\n      <string>18789</string>\n    </array>\n    \n    <key>StandardOutPath</key>\n    <string>/Users/YOUR_USERNAME/.openclaw/logs/gateway.log</string>\n    \n    <key>StandardErrorPath</key>\n    <string>/Users/YOUR_USERNAME/.openclaw/logs/gateway.err.log</string>\n    \n    <key>EnvironmentVariables</key>\n    <dict>\n      <key>HOME</key>\n      <string>/Users/YOUR_USERNAME</string>\n      <key>PATH</key>\n      <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>\n    </dict>\n  </dict>\n</plist>\nEOF\n\n# Replace YOUR_USERNAME with your actual username\nsed -i '' \"s/YOUR_USERNAME/$(whoami)/g\" /tmp/ai.openclaw.gateway.plist\n\n\n🔑 Key Configuration for Lock Screen Persistence:\n\n/usr/bin/caffeinate -s - Prevents system sleep (display can sleep, network stays active)\nNetworkState: true - Ensures service stays active when network is available\nProcessType: Interactive - Prevents macOS from suspending the process\nThrottleInterval: 0 - Disables any throttling\nCrashed: true - Auto-restarts on crashes\n\n✅ Verified working after 30+ minutes of screen lock on macOS 14.4\n\nStep 2: Stop Existing LaunchAgent\n# Stop user-level service\nlaunchctl bootout gui/$(id -u)/ai.openclaw.gateway 2>/dev/null\n\n# Backup and disable LaunchAgent plist\nmv ~/Library/LaunchAgents/ai.openclaw.gateway.plist ~/Library/LaunchAgents/ai.openclaw.gateway.plist.disabled 2>/dev/null\n\nStep 3: Install LaunchDaemon (requires sudo)\n# Copy to system location\nsudo cp /tmp/ai.openclaw.gateway.plist /Library/LaunchDaemons/\n\n# Set correct permissions\nsudo chown root:wheel /Library/LaunchDaemons/ai.openclaw.gateway.plist\nsudo chmod 644 /Library/LaunchDaemons/ai.openclaw.gateway.plist\n\n# Load and start service\nsudo launchctl bootstrap system /Library/LaunchDaemons/ai.openclaw.gateway.plist\n\nStep 4: Verify Installation\n# Check process is running\nps aux | grep openclaw-gateway | grep -v grep\n\n# Verify PPID = 1 (launched by system launchd)\nps -p $(pgrep -f openclaw-gateway) -o pid,ppid,user,command\n\n# Check service status\nsudo launchctl print system/ai.openclaw.gateway | head -10\n\n# Test with OpenClaw\nopenclaw status\n\n\nExpected output:\n\nPID   PPID  USER       COMMAND\n12345 1     youruser   openclaw-gateway\n\n\nPPID=1 confirms it's running as LaunchDaemon (parent is system launchd).\n\nTesting Lock Screen Behavior\nTest Script\n#!/bin/bash\necho \"🧪 Testing LaunchDaemon lock screen behavior...\"\necho \"\"\necho \"1. Lock your Mac in 5 seconds...\"\nsleep 5\npmset displaysleepnow\n\necho \"2. Use your phone to send 'ping' to your bot\"\necho \"3. Bot should reply 'pong! 🎉' even while locked\"\necho \"\"\necho \"Unlock your Mac after testing.\"\n\nManual Test Steps\nLock your Mac: ⌘ + Control + Q\nSend from phone: Message your bot (Telegram/Feishu/etc.) with \"ping\"\nExpected: Bot replies \"pong! 🎉\" immediately\nUnlock and verify logs show the message was processed\nManagement Commands\nView Logs\n# Real-time logs\ntail -f ~/.openclaw/logs/gateway.log\n\n# Error logs\ntail -f ~/.openclaw/logs/gateway.err.log\n\n# Last 100 lines\ntail -100 ~/.openclaw/logs/gateway.log\n\nRestart Service\n# Unload and reload\nsudo launchctl bootout system/ai.openclaw.gateway\nsudo launchctl bootstrap system /Library/LaunchDaemons/ai.openclaw.gateway.plist\n\n# Or use kickstart (restarts without unloading)\nsudo launchctl kickstart -k system/ai.openclaw.gateway\n\nStop Service\n# Stop service\nsudo launchctl bootout system/ai.openclaw.gateway\n\n# Prevent auto-start\nsudo launchctl disable system/ai.openclaw.gateway\n\nStart Service\n# Enable and start\nsudo launchctl enable system/ai.openclaw.gateway\nsudo launchctl bootstrap system /Library/LaunchDaemons/ai.openclaw.gateway.plist\n\nCheck Status\n# Full service details\nsudo launchctl print system/ai.openclaw.gateway\n\n# Quick status check\nsudo launchctl list | grep openclaw\n\n# Process info\nps aux | grep openclaw-gateway | grep -v grep\n\nUninstallation\nComplete Removal\n# 1. Stop service\nsudo launchctl bootout system/ai.openclaw.gateway\n\n# 2. Remove plist\nsudo rm /Library/LaunchDaemons/ai.openclaw.gateway.plist\n\n# 3. Restore LaunchAgent (optional)\nmv ~/Library/LaunchAgents/ai.openclaw.gateway.plist.disabled ~/Library/LaunchAgents/ai.openclaw.gateway.plist 2>/dev/null\nlaunchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist\n\n# 4. Verify\nps aux | grep openclaw | grep -v grep\n\nAutomated Install Script\n\nSave this as install-launchdaemon.sh:\n\n#!/bin/bash\nset -e\n\necho \"🚀 OpenClaw LaunchDaemon Installer\"\necho \"==================================\"\necho \"\"\n\n# Colors\nRED='\\033[0;31m'\nGREEN='\\033[0;32m'\nYELLOW='\\033[1;33m'\nNC='\\033[0m' # No Color\n\nUSERNAME=$(whoami)\nPLIST_PATH=\"/Library/LaunchDaemons/ai.openclaw.gateway.plist\"\nTEMP_PLIST=\"/tmp/ai.openclaw.gateway.plist\"\n\n# Check if running as root\nif [ \"$EUID\" -eq 0 ]; then \n   echo -e \"${RED}❌ Don't run this script with sudo${NC}\"\n   echo \"The script will ask for sudo password when needed.\"\n   exit 1\nfi\n\n# Check if OpenClaw is installed\nif ! command -v openclaw &> /dev/null; then\n    echo -e \"${RED}❌ OpenClaw not found. Install it first:${NC}\"\n    echo \"   npm install -g openclaw\"\n    exit 1\nfi\n\necho -e \"${YELLOW}📋 Creating LaunchDaemon configuration...${NC}\"\n\n# Get OpenClaw gateway token\nGATEWAY_TOKEN=$(openclaw config get gateway.auth.token 2>/dev/null | tr -d '\"' || echo \"\")\n\ncat > \"$TEMP_PLIST\" << EOF\n<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n<!DOCTYPE plist PUBLIC \"-//Apple//DTD PLIST 1.0//EN\" \"http://www.apple.com/DTDs/PropertyList-1.0.dtd\">\n<plist version=\"1.0\">\n  <dict>\n    <key>Label</key>\n    <string>ai.openclaw.gateway</string>\n    \n    <key>Comment</key>\n    <string>OpenClaw Gateway (System Daemon)</string>\n    \n    <key>RunAtLoad</key>\n    <true/>\n    \n    <key>KeepAlive</key>\n    <true/>\n    \n    <key>UserName</key>\n    <string>$USERNAME</string>\n    \n    <key>GroupName</key>\n    <string>staff</string>\n    \n    <key>ProgramArguments</key>\n    <array>\n      <string>/opt/homebrew/bin/node</string>\n      <string>/opt/homebrew/lib/node_modules/openclaw/dist/index.js</string>\n      <string>gateway</string>\n      <string>--port</string>\n      <string>18789</string>\n    </array>\n    \n    <key>StandardOutPath</key>\n    <string>/Users/$USERNAME/.openclaw/logs/gateway.log</string>\n    \n    <key>StandardErrorPath</key>\n    <string>/Users/$USERNAME/.openclaw/logs/gateway.err.log</string>\n    \n    <key>EnvironmentVariables</key>\n    <dict>\n      <key>HOME</key>\n      <string>/Users/$USERNAME</string>\n      <key>PATH</key>\n      <string>/opt/homebrew/bin:/usr/local/bin:/usr/bin:/bin</string>\n      <key>OPENCLAW_GATEWAY_PORT</key>\n      <string>18789</string>\n      <key>OPENCLAW_GATEWAY_TOKEN</key>\n      <string>$GATEWAY_TOKEN</string>\n    </dict>\n  </dict>\n</plist>\nEOF\n\necho -e \"${YELLOW}🛑 Stopping existing services...${NC}\"\n\n# Stop LaunchAgent\nlaunchctl bootout gui/$(id -u)/ai.openclaw.gateway 2>/dev/null || true\n\n# Backup LaunchAgent plist\nif [ -f ~/Library/LaunchAgents/ai.openclaw.gateway.plist ]; then\n    mv ~/Library/LaunchAgents/ai.openclaw.gateway.plist ~/Library/LaunchAgents/ai.openclaw.gateway.plist.backup\n    echo -e \"${GREEN}✅ Backed up LaunchAgent plist${NC}\"\nfi\n\n# Stop existing LaunchDaemon\nsudo launchctl bootout system/ai.openclaw.gateway 2>/dev/null || true\n\necho -e \"${YELLOW}📦 Installing LaunchDaemon...${NC}\"\n\n# Install plist\nsudo cp \"$TEMP_PLIST\" \"$PLIST_PATH\"\nsudo chown root:wheel \"$PLIST_PATH\"\nsudo chmod 644 \"$PLIST_PATH\"\n\necho -e \"${YELLOW}🚀 Starting service...${NC}\"\n\n# Start service\nsudo launchctl bootstrap system \"$PLIST_PATH\"\nsleep 3\n\n# Verify\nif ps aux | grep -q \"[o]penclaw-gateway\"; then\n    echo \"\"\n    echo -e \"${GREEN}✅ LaunchDaemon installed successfully!${NC}\"\n    echo \"\"\n    echo \"📊 Service Status:\"\n    ps aux | grep \"[o]penclaw-gateway\" | awk '{print \"   PID: \"$2\", User: \"$1}'\n    echo \"\"\n    echo \"🧪 Test it:\"\n    echo \"   1. Lock your Mac: ⌘ + Control + Q\"\n    echo \"   2. Send 'ping' from your phone\"\n    echo \"   3. Bot should reply even while locked!\"\n    echo \"\"\n    echo \"📋 Management:\"\n    echo \"   Logs:    tail -f ~/.openclaw/logs/gateway.log\"\n    echo \"   Restart: sudo launchctl kickstart -k system/ai.openclaw.gateway\"\n    echo \"   Stop:    sudo launchctl bootout system/ai.openclaw.gateway\"\n    echo \"   Status:  sudo launchctl print system/ai.openclaw.gateway\"\nelse\n    echo -e \"${RED}❌ Service failed to start${NC}\"\n    echo \"Check logs: tail -50 ~/.openclaw/logs/gateway.err.log\"\n    exit 1\nfi\n\n\nMake it executable:\n\nchmod +x install-launchdaemon.sh\n./install-launchdaemon.sh\n\nTroubleshooting\nService Won't Start\n\nCheck logs:\n\ntail -50 ~/.openclaw/logs/gateway.err.log\n\n\nCommon issues:\n\nWrong username in plist\n\n# Verify username matches\ngrep UserName /Library/LaunchDaemons/ai.openclaw.gateway.plist\nwhoami\n\n\nWrong node path\n\n# Check node location\nwhich node\n\n# Update plist if needed (change /opt/homebrew/bin/node to your path)\n\n\nPermissions issues\n\n# Fix log directory permissions\nmkdir -p ~/.openclaw/logs\nchmod 755 ~/.openclaw/logs\n\nStill Suspends After Lock\n\nIf using older macOS or specific hardware:\n\n# Prevent system sleep\nsudo pmset -a sleep 0\nsudo pmset -a disksleep 0\nsudo pmset -a displaysleep 10  # Screen off but system awake\n\n\nOr use caffeinate (not recommended for laptops):\n\n# Modify ProgramArguments in plist to wrap with caffeinate\n<string>/usr/bin/caffeinate</string>\n<string>-s</string>  <!-- prevent sleep -->\n<string>/opt/homebrew/bin/node</string>\n...\n\nPort Already in Use\n# Find what's using port 18789\nlsof -i :18789\n\n# Kill the process\nkill -9 <PID>\n\n# Or change port in config and plist\nopenclaw config set gateway.port 18790\n\nLogs Not Writing\n# Create log directory\nmkdir -p ~/.openclaw/logs\n\n# Test permissions\ntouch ~/.openclaw/logs/test.log\nls -la ~/.openclaw/logs/\n\n# Check plist paths match\ngrep Path /Library/LaunchDaemons/ai.openclaw.gateway.plist\n\nSecurity Considerations\nRunning as User vs Root\n\n✅ This setup runs as your user (specified in <key>UserName</key>)\n\nNot running as root\nSame permissions as when you run OpenClaw manually\nSafer than true root daemons\nFile Permissions\n# LaunchDaemon plist should be owned by root\nls -l /Library/LaunchDaemons/ai.openclaw.gateway.plist\n# Should show: -rw-r--r--  1 root  wheel\n\n# Log directory owned by you\nls -ld ~/.openclaw/logs\n# Should show: drwxr-xr-x ... youruser staff\n\nToken Security\n\nThe Gateway token is stored in the plist environment variables. While readable only by root and your user, consider:\n\n# Check who can read the plist\nls -l /Library/LaunchDaemons/ai.openclaw.gateway.plist\n\n# More secure: use macOS Keychain (advanced)\n# Store token in keychain and retrieve at runtime\n\nPerformance Impact\n\nLaunchDaemon has minimal performance impact:\n\nSame process as LaunchAgent\nRuns only when needed (KeepAlive handles crashes)\nIdle resource usage: ~50MB RAM, <1% CPU\nActive (processing messages): ~100MB RAM, varies by task\nmacOS Version Compatibility\n\nTested on:\n\n✅ macOS 10.15 (Catalina)\n✅ macOS 11 (Big Sur)\n✅ macOS 12 (Monterey)\n✅ macOS 13 (Ventura)\n✅ macOS 14 (Sonoma)\n✅ macOS 15 (Sequoia)\n\nNote: LaunchDaemon syntax changed slightly in macOS 11+, but backwards compatible.\n\nComparison: LaunchAgent vs LaunchDaemon\nFeature\tLaunchAgent\tLaunchDaemon\nRuns when locked\t❌ May suspend\t✅ Always runs\nRuns when logged out\t❌ Stops\t✅ Continues\nSetup complexity\tSimple\tRequires sudo\nRequires sudo\t❌ No\t✅ Yes\nBest for\tPersonal use, logged-in only\t24/7 server, multi-user\nSecurity\tUser-level\tSystem-level (still runs as user)\nAuto-start\tAt login\tAt boot\nMigration\nFrom LaunchAgent to LaunchDaemon\n\nUse the install script above, or:\n\n# Automatic migration\nlaunchctl bootout gui/$(id -u)/ai.openclaw.gateway\nmv ~/Library/LaunchAgents/ai.openclaw.gateway.plist ~/Library/LaunchAgents/ai.openclaw.gateway.plist.backup\n# Then follow installation steps\n\nFrom LaunchDaemon back to LaunchAgent\n# Stop daemon\nsudo launchctl bootout system/ai.openclaw.gateway\nsudo rm /Library/LaunchDaemons/ai.openclaw.gateway.plist\n\n# Restore agent\nmv ~/Library/LaunchAgents/ai.openclaw.gateway.plist.backup ~/Library/LaunchAgents/ai.openclaw.gateway.plist\nlaunchctl bootstrap gui/$(id -u) ~/Library/LaunchAgents/ai.openclaw.gateway.plist\n\nFAQ\n\nQ: Will this drain my battery?\nA: Minimal impact. OpenClaw idles at <1% CPU when not processing messages.\n\nQ: Can I still update OpenClaw?\nA: Yes. After updating, restart the service:\n\nsudo launchctl kickstart -k system/ai.openclaw.gateway\n\n\nQ: What if I upgrade macOS?\nA: LaunchDaemon survives OS upgrades. Verify it's still running after update:\n\nsudo launchctl print system/ai.openclaw.gateway\n\n\nQ: Can I run multiple instances?\nA: Not recommended. Use one LaunchDaemon with multiple channel accounts instead.\n\nQ: Does this work on M1/M2 Macs?\nA: Yes! Works on both Intel and Apple Silicon Macs.\n\nRelated Skills\nmacos-lock-screen-fix - Alternative LaunchAgent fix (simpler but may not work on all Macs)\nhealthcheck - Monitor OpenClaw health and uptime\nContributing\n\nFound issues or improvements?\n\nGitHub: https://github.com/openclaw/openclaw/issues\nPull requests welcome!\n\nQuick Commands Reference:\n\n# Status\nsudo launchctl print system/ai.openclaw.gateway\n\n# Restart\nsudo launchctl kickstart -k system/ai.openclaw.gateway\n\n# Logs\ntail -f ~/.openclaw/logs/gateway.log\n\n# Uninstall\nsudo launchctl bootout system/ai.openclaw.gateway\nsudo rm /Library/LaunchDaemons/ai.openclaw.gateway.plist"
  },
  "trust": {
    "sourceLabel": "tencent",
    "provenanceUrl": "https://clawhub.ai/happydog-intj/openclaw-macos-always-on",
    "publisherUrl": "https://clawhub.ai/happydog-intj/openclaw-macos-always-on",
    "owner": "happydog-intj",
    "version": "1.0.1",
    "license": null,
    "verificationStatus": "Indexed source record"
  },
  "links": {
    "detailUrl": "https://openagent3.xyz/skills/openclaw-macos-always-on",
    "downloadUrl": "https://openagent3.xyz/downloads/openclaw-macos-always-on",
    "agentUrl": "https://openagent3.xyz/skills/openclaw-macos-always-on/agent",
    "manifestUrl": "https://openagent3.xyz/skills/openclaw-macos-always-on/agent.json",
    "briefUrl": "https://openagent3.xyz/skills/openclaw-macos-always-on/agent.md"
  }
}