{ config, lib, pkgs, ... }: let cfg = config.services.openclaw-node; openclawPkg = pkgs.openclaw; in { options.services.openclaw-node = { enable = lib.mkEnableOption "OpenClaw Node service"; user = lib.mkOption { type = lib.types.str; default = "ai-worker"; description = "User to run the OpenClaw headless node as."; }; gatewayHost = lib.mkOption { type = lib.types.str; default = "127.0.0.1"; description = "Gateway host (IP or hostname)."; }; gatewayPort = lib.mkOption { type = lib.types.int; default = 18789; description = "Gateway WebSocket port."; }; gatewayTokenFile = lib.mkOption { type = lib.types.str; default = ""; description = "Path to file containing the gateway auth token."; }; displayName = lib.mkOption { type = lib.types.str; default = "lazyworkhorse-host"; description = "Display name for this node (shown in pairing)."; }; }; config = lib.mkIf cfg.enable { systemd.services.openclaw-node = { description = "OpenClaw Headless Node Service"; after = [ "network.target" ]; wantedBy = [ "multi-user.target" ]; serviceConfig = { Type = "exec"; User = cfg.user; Group = cfg.user; WorkingDirectory = "/home/${cfg.user}"; ExecStart = '' ${pkgs.bash}/bin/bash -c 'export OPENCLAW_GATEWAY_TOKEN=$(cat ${cfg.gatewayTokenFile}) && exec ${openclawPkg}/bin/openclaw node run --host ${cfg.gatewayHost} --port ${toString cfg.gatewayPort} --display-name "${cfg.displayName}"' ''; Restart = "always"; RestartSec = 5; }; environment = { NODE_ENV = "production"; }; }; }; }