Skip to content

Latest commit

 

History

History
159 lines (127 loc) · 5.41 KB

File metadata and controls

159 lines (127 loc) · 5.41 KB

OpenClaw: Transition to Declarative nix-openclaw Module

Current State

OpenClaw on floe is partially declarative:

  • Nix manages: package (openclaw-gateway), systemd system service, env vars
  • Manual: ~/.openclaw/openclaw.json (models, channels, tokens, plugins, tools, hooks)

The nix-openclaw flake provides a Home Manager module (programs.openclaw) that generates the config, manages the service, and wires plugins — making everything fully declarative.

Why Migrate

  • Config reproducibility: openclaw.json is currently hand-edited and not in version control
  • Nix mode (OPENCLAW_NIX_MODE=1) treats config as read-only — the module should own it
  • Plugin/skill management via Nix instead of manual file placement
  • Secrets via file references (agenix-compatible) instead of inline JSON
  • Atomic rollback of config + package together

Prerequisites

  1. Home Manager on floe — the nix-openclaw module is Home Manager, not NixOS. Either extend the homemanager repo to cover floe, or add Home Manager as a NixOS module in this repo's flake (home-manager.nixosModules.home-manager).
  2. Secrets as files — move bot tokens and API keys from inline JSON to files in /run/agenix/ or ~/.secrets/ (plain files work, agenix is optional).

Migration Plan

Phase 1: Home Manager on floe

Option A — standalone Home Manager in homemanager repo:

  • Add floe host config alongside madrush
  • Add nix-openclaw as flake input
  • home-manager switch --flake .#user@floe

Option B — Home Manager as NixOS module (keeps everything in this repo):

  • Add home-manager.url = "github:nix-community/home-manager/release-24.11" to flake.nix
  • Import home-manager.nixosModules.home-manager in configuration.nix
  • Configure home-manager.users.user inline

Phase 2: Declare OpenClaw config

Map the current openclaw.json to programs.openclaw.config:

programs.openclaw = {
  enable = true;

  config = {
    gateway = {
      port = 18789;
      mode = "local";
      bind = "loopback";
      auth = {
        mode = "token";
        # token via file or env var, not inline
      };
      tailscale.mode = "off";
    };

    agents.defaults = {
      model = {
        primary = "anthropic/claude-sonnet-4-6";
        fallbacks = [ "anthropic/claude-opus-4-6" ];
      };
      workspace = "/home/user/.openclaw/workspace";
      memorySearch.enabled = false;
      contextPruning = { mode = "cache-ttl"; ttl = "1h"; };
      compaction.mode = "safeguard";
      heartbeat.every = "1h";
      maxConcurrent = 4;
      subagents.maxConcurrent = 8;
    };

    tools.web = {
      search = {
        enabled = true;
        provider = "brave";
        # apiKey via secrets file
      };
      fetch.enabled = true;
    };

    messages.ackReactionScope = "group-mentions";
    commands = { native = "auto"; nativeSkills = "auto"; restart = true; ownerDisplay = "raw"; };
    session.dmScope = "per-channel-peer";

    channels.telegram = {
      enabled = true;
      dmPolicy = "pairing";
      tokenFile = "~/.secrets/openclaw-telegram-token";  # or /run/agenix/...
      groupPolicy = "disabled";
      streaming = "off";
    };

    channels.discord = {
      enabled = true;
      tokenFile = "~/.secrets/openclaw-discord-token";
      groupPolicy = "open";
      streaming = "off";
    };
  };

  # Workspace documents (already exist on floe)
  documents = {
    # Point to files in this repo or manage separately
  };
};

Phase 3: Migrate secrets to files

Create secret files on floe (or use agenix for encrypted secrets in git):

mkdir -p ~/.secrets && chmod 700 ~/.secrets
# Telegram bot token
echo -n "8764994861:AAG..." > ~/.secrets/openclaw-telegram-token
# Discord bot token
echo -n "MTQ3NjE4NTY..." > ~/.secrets/openclaw-discord-token
# Brave search API key
echo -n "BSA2qa..." > ~/.secrets/openclaw-brave-api-key
# Gateway auth token
echo -n "b094db..." > ~/.secrets/openclaw-gateway-token
# Anthropic API key (if not already in env)

Phase 4: Remove manual config

  1. Remove services/openclaw.nix from this repo (module handles the service)
  2. Remove the import from configuration.nix
  3. Back up and remove ~/.openclaw/openclaw.json (module generates it)
  4. Rebuild and verify: openclaw doctor, openclaw status

Phase 5: Plugins and skills

  • Zoho WorkDrive skill: migrate to customPlugins if a flake exists, otherwise keep manual
  • Workspace docs (SOUL.md, IDENTITY.md, etc.): manage via documents option or keep in workspace

Config Mapping Reference

openclaw.json path nix-openclaw option
gateway.* config.gateway.*
agents.defaults.* config.agents.defaults.*
channels.telegram.botToken config.channels.telegram.tokenFile (file path)
channels.discord.token config.channels.discord.tokenFile (file path)
tools.web.search.apiKey config.tools.web.search.apiKeyFile or config.env
hooks.* config.hooks.*
plugins.* plugins / customPlugins / bundledPlugins.*

Open Questions

  • Does nix-openclaw NixOS module exist, or only Home Manager? (README shows HM only)
  • Can programs.openclaw be enabled without starting the gateway? (for madrush)
  • How are workspace docs (SOUL.md, USER.md, etc.) versioned — in this repo or separate?
  • Agenix vs plain secret files — worth the complexity for a single-user homelab?
  • WorkDrive custom plugin: does it have a flake, or does it need wrapping?