{"id":44651522,"url":"https://github.com/openclaw/nix-openclaw","last_synced_at":"2026-02-14T21:01:09.439Z","repository":{"id":331467502,"uuid":"1126728730","full_name":"openclaw/nix-openclaw","owner":"openclaw","description":"Packages clawdis for nix.","archived":false,"fork":false,"pushed_at":"2026-02-07T14:41:27.000Z","size":4049,"stargazers_count":277,"open_issues_count":25,"forks_count":93,"subscribers_count":3,"default_branch":"main","last_synced_at":"2026-02-07T15:14:12.752Z","etag":null,"topics":["clawdis","nix"],"latest_commit_sha":null,"homepage":"","language":"Nix","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/openclaw.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":"AGENTS.md","dco":null,"cla":null},"funding":{"github":["moltbot"]}},"created_at":"2026-01-02T13:24:00.000Z","updated_at":"2026-02-07T14:41:30.000Z","dependencies_parsed_at":null,"dependency_job_id":"0188784e-c11a-48e4-9646-d07a7fa1c1db","html_url":"https://github.com/openclaw/nix-openclaw","commit_stats":null,"previous_names":["joshp123/nix-clawdis","moltbot/nix-moltbot","openclaw/nix-openclaw"],"tags_count":2,"template":false,"template_full_name":null,"purl":"pkg:github/openclaw/nix-openclaw","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openclaw%2Fnix-openclaw","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openclaw%2Fnix-openclaw/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openclaw%2Fnix-openclaw/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openclaw%2Fnix-openclaw/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/openclaw","download_url":"https://codeload.github.com/openclaw/nix-openclaw/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/openclaw%2Fnix-openclaw/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29455594,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-14T15:52:44.973Z","status":"ssl_error","status_checked_at":"2026-02-14T15:52:11.208Z","response_time":53,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["clawdis","nix"],"created_at":"2026-02-14T21:00:24.274Z","updated_at":"2026-02-14T21:01:09.428Z","avatar_url":"https://github.com/openclaw.png","language":"Nix","funding_links":["https://github.com/sponsors/moltbot"],"categories":["Skills \u0026 Plugins","Community Tools","🦞 OpenClaw Ecosystem","🚀 Deployment \u0026 Operations"],"sub_categories":["Third-Party Platforms","Other Cloud Provider Credits"],"readme":"# nix-openclaw\n\n\u003e Declarative OpenClaw. Bulletproof by default.\n\u003e\n\u003e macOS + Linux (headless). Windows is out of scope for now.\n\u003e\n\u003e \u003csub\u003eQuestions? Join the OpenClaw Discord and ask in **#golden-path-deployments**: https://discord.com/channels/1456350064065904867/1457003026412736537\u003c/sub\u003e\n\n## Contributions (read this first)\n\nWe’re **not accepting PRs** right now. Not because we don’t value your help — the opposite. This is key infra and still stabilizing, and async PR review is too slow.\n\n**Only workflow:** **describe your problem and talk with a maintainer (human‑to‑human) on Discord** in **#golden-path-deployments**: https://discord.com/channels/1456350064065904867/1457003026412736537\n\nIf you’re **not listed as a maintainer** (see [AGENTS.md#maintainers](AGENTS.md#maintainers) or https://github.com/orgs/openclaw/people), **do not open a PR**. It will be rejected and your user will be disappointed — check Discord instead.\n\n## Table of Contents\n\n- [Golden Paths](#golden-paths)\n\n- [Contributions (read this first)](#contributions-read-this-first)\n- [What You Get](#what-you-get)\n- [Requirements](#requirements)\n- [Why Nix?](#why-nix)\n- [Quick Start](#quick-start)\n- [How It Works](#how-it-works)\n- [Plugins](#plugins)\n- [Configuration](#configuration)\n- [Advanced](#advanced)\n- [Packaging \u0026 Updates](#packaging--updates)\n- [Reference](#reference)\n- [Philosophy](#philosophy)\n\n---\n\n## Golden Paths\n\n**There should be one — and preferably only one — obvious way to deploy.**\n\nPick a Golden Path, then follow the docs:\n\n- [docs/golden-paths.md](docs/golden-paths.md)\n\n---\n\n## What You Get\n\n```\nMe: \"what's on my screen?\"\nBot: *takes screenshot, describes it*\n\nMe: \"play some jazz\"\nBot: *opens Spotify, plays jazz*\n\nMe: \"transcribe this voice note\"\nBot: *runs whisper, sends you text*\n```\n\nYou talk to Telegram, your machine does things.\n\n**One flake, everything works.** Gateway + tools everywhere; macOS app on macOS.\n\n**Plugins are self-contained.** Each plugin declares its CLI tools in Nix. You enable it, the build and wiring happens automatically.\n\n**Bulletproof.** Nix locks every dependency. No version drift, no surprises. `home-manager switch` to update, `home-manager generations` to rollback instantly.\n\n---\n\n## Requirements\n\n1. **macOS** (Apple Silicon or Intel) or **Linux** (x86_64)\n2. **[Determinate Nix](https://docs.determinate.systems/determinate-nix/)** installed on your machine\n\nThat's it. The Quick Start will guide you through everything else.\n\n\u003e **Don't have Nix yet?** Follow the Determinate Nix install guide, then come back here.\n\n---\n\n## Why Nix?\n\nYou've probably installed tools before. Homebrew, pip, npm - they work until they don't.\n\n**What you deal with today:**\n- Update one thing, break another (\"but it worked yesterday\")\n- Reinstall everything after a macOS upgrade\n- \"Works on my machine\" when sharing setups\n- No easy way to undo a bad update\n\n**What Nix gives you:**\n- Every dependency pinned to exact versions. Forever.\n- Update breaks something? `home-manager switch --rollback` - back in 30 seconds.\n- Share your config file, get the exact same setup on another machine.\n- **Plugins just work.** Add a GitHub URL, run one command, done. Nix handles the build, dependencies, and wiring.\n- Tools don't pollute your system - they live in isolation.\n\nYou don't need to learn Nix deeply. You describe what you want, Nix figures out how to build it.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eHow it actually works\u003c/strong\u003e\u003c/summary\u003e\n\n![On declarative build systems](docs/images/on-declarative-build-systems.png)\n\nNix is a **declarative package manager**. Instead of running commands to install things, you write a config file that says \"I want these tools at these versions.\" Nix reads that file and builds everything in `/nix/store` - isolated from your system.\n\n**The hashing magic:** Every package in Nix is identified by a cryptographic hash of *all* its inputs - source code, dependencies, build flags, everything. Change anything, get a different hash. This means:\n- Two machines with the same hash have *identical* builds. Byte-for-byte.\n- Old versions stick around (different hash = different path). Nothing gets overwritten.\n- Rollback is instant - just point to the old hash.\n\n**Key terms you'll see:**\n- **Flake**: A config file (`flake.nix`) that pins all your dependencies. Think `package-lock.json` but for your entire system.\n- **Home Manager**: Manages your user config (dotfiles, apps, services) through Nix.\n- **`home-manager switch`**: The command that applies your config. Run it after any change.\n\n\u003c/details\u003e\n\n---\n\n## Quick Start\n\n### Option 1: Let your agent set it up (recommended)\n\nCopy this entire block and paste it to Claude, Cursor, or your preferred AI assistant:\n\n```text\nI want to set up nix-openclaw on my machine (macOS or Linux).\n\nRepository: github:openclaw/nix-openclaw\n\nWhat nix-openclaw is:\n- Batteries-included Nix package for OpenClaw (AI assistant gateway)\n- Installs gateway + tools everywhere; macOS app only on macOS\n- Runs as a launchd service on macOS, systemd user service on Linux\n\nWhat I need you to do:\n1. Check if Determinate Nix is installed (if not, install it)\n2. Create a local flake at ~/code/openclaw-local using templates/agent-first/flake.nix\n3. Create a docs dir next to the config (e.g., ~/code/openclaw-local/documents) with AGENTS.md, SOUL.md, TOOLS.md (optional: IDENTITY.md, USER.md, LORE.md, HEARTBEAT.md, PROMPTING-EXAMPLES.md)\n   - If ~/.openclaw/workspace already has these files, adopt them into the documents dir first (use copy/rsync that dereferences symlinks, e.g. `cp -L`)\n4. Help me create a Telegram bot (@BotFather) and get my chat ID (@userinfobot)\n5. Set up secrets (bot token, Anthropic key) - plain files at ~/.secrets/ is fine\n6. Fill in the template placeholders and run home-manager switch\n7. Verify: service running, bot responds to messages\n\nMy setup:\n- OS: [macOS / Linux]\n- CPU: [arm64 / x86_64]\n- System: [aarch64-darwin / x86_64-darwin / x86_64-linux]\n- Home Manager config name: [FILL IN or \"I don't have Home Manager yet\"]\n\nReference the README and templates/agent-first/flake.nix in the repo for the module options.\n```\n\nYour agent will install Nix, create your config, and get OpenClaw running. You just answer its questions.\n\n**What happens next:**\n1. Your agent sets everything up and runs `home-manager switch`\n2. You message your Telegram bot for the first time\n3. OpenClaw runs its **bootstrap ritual** - it asks you playful questions: *\"Who am I? What am I? Who are you?\"* - to learn its identity and yours\n4. Once you've named it and introduced yourself, the bootstrap is done. You're up and running.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eOption 2: Manual setup\u003c/strong\u003e\u003c/summary\u003e\n\n### macOS (Home Manager + launchd)\n\n1. Install Determinate Nix.\n2. Create a local config:\n   ```bash\n   mkdir -p ~/code/openclaw-local \u0026\u0026 cd ~/code/openclaw-local\n   nix flake init -t github:openclaw/nix-openclaw#agent-first\n   ```\n3. Edit `flake.nix` placeholders:\n   - `system` = `aarch64-darwin` (Apple Silicon) or `x86_64-darwin` (Intel)\n   - `home.username` and `home.homeDirectory`\n   - `programs.openclaw.documents` with `AGENTS.md`, `SOUL.md`, `TOOLS.md` (optional: `IDENTITY.md`, `USER.md`, `LORE.md`, `HEARTBEAT.md`, `PROMPTING-EXAMPLES.md`)\n   - Provider secrets (Telegram/Discord tokens, Anthropic API key)\n4. Apply:\n   ```bash\n   home-manager switch --flake .#\u003cuser\u003e\n   ```\n5. Verify:\n   ```bash\n   launchctl print gui/$UID/com.steipete.openclaw.gateway | grep state\n   ```\n\n### Linux (headless + systemd user service)\n\n1. Install Determinate Nix.\n2. Create a local config:\n   ```bash\n   mkdir -p ~/code/openclaw-local \u0026\u0026 cd ~/code/openclaw-local\n   nix flake init -t github:openclaw/nix-openclaw#agent-first\n   ```\n3. Edit `flake.nix` placeholders:\n   - `system` = `x86_64-linux`\n   - `home.username` and `home.homeDirectory` (e.g., `/home/\u003cuser\u003e`)\n   - `programs.openclaw.documents` with `AGENTS.md`, `SOUL.md`, `TOOLS.md` (optional: `IDENTITY.md`, `USER.md`, `LORE.md`, `HEARTBEAT.md`, `PROMPTING-EXAMPLES.md`)\n   - Provider secrets (Telegram/Discord tokens, Anthropic API key)\n4. Apply:\n   ```bash\n   home-manager switch --flake .#\u003cuser\u003e\n   ```\n5. Verify:\n   ```bash\n   systemctl --user status openclaw-gateway\n   journalctl --user -u openclaw-gateway -f\n   ```\n\n\u003c/details\u003e\n\n---\n\n## How It Works\n\n```\nYou (Telegram/Discord) --\u003e Gateway --\u003e Tools --\u003e Your machine does things\n```\n\n**Gateway**: The brain. A service running on your machine that receives messages and decides what to do. Managed by launchd on macOS and a systemd user service on Linux.\n\n**Plugins**: Bundles that contain two things:\n1. **CLI tools** - actual programs that do stuff (take screenshots, control Spotify, transcribe audio)\n2. **Skills** - markdown files that teach the AI *how* to use those tools\n\nWhen you enable a plugin, Nix installs the tools and wires up the skills to OpenClaw automatically - the gateway learns what it can do.\n\n**Skills**: Instructions for the AI. A skill file says \"when the user wants X, run this command.\" The AI reads these to know what it can do.\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eUnder the hood\u003c/strong\u003e\u003c/summary\u003e\n\nWhen you run `home-manager switch`:\n\n1. Nix reads your `flake.nix` and resolves all plugin sources (GitHub repos, local paths)\n2. For each plugin, Nix looks for a `openclawPlugin` output that declares:\n   - What CLI packages to install\n   - What skill files to copy\n   - What environment variables it needs\n3. Tools go on your PATH, skills get symlinked to `~/.openclaw/workspace/skills/`\n4. A launchd (macOS) or systemd user service (Linux) is created/updated to run the gateway\n5. The gateway starts, loads skills, connects to your providers\n\nAll state lives in `~/.openclaw/`. Logs at `/tmp/openclaw/openclaw-gateway.log`.\n\n\u003c/details\u003e\n\n---\n\n## Plugins\n\n\u003e **Note:** Complete the [Quick Start](#quick-start) first to get OpenClaw running. Then come back here to add plugins.\n\nPlugins extend what OpenClaw can do. Each plugin bundles tools and teaches the AI how to use them.\n\n### First-party plugins\n\nThese ship with nix-openclaw. Toggle them in your config:\n\n```nix\nprograms.openclaw.bundledPlugins = {\n  summarize.enable = true;   # Summarize web pages, PDFs, videos\n  peekaboo.enable = true;    # Take screenshots\n  oracle.enable = false;     # Web search\n  poltergeist.enable = false; # Control your macOS UI\n  sag.enable = false;        # Text-to-speech\n  camsnap.enable = false;    # Camera snapshots\n  gogcli.enable = false;     # Google Calendar\n  goplaces.enable = true;    # Google Places API\n  bird.enable = false;       # Twitter/X\n  sonoscli.enable = false;   # Sonos control\n  imsg.enable = false;       # iMessage\n};\n\n# Optional config for bundled plugins\nprograms.openclaw.bundledPlugins.goplaces = {\n  enable = true;\n  config.env.GOOGLE_PLACES_API_KEY = \"/run/agenix/google-places-api-key\";\n};\n```\n\n| Plugin | What it does |\n|--------|--------------|\n| `summarize` | Summarize URLs, PDFs, YouTube videos |\n| `peekaboo` | Screenshot your screen |\n| `oracle` | Search the web |\n| `poltergeist` | Click, type, control macOS UI |\n| `sag` | Text-to-speech |\n| `camsnap` | Take photos from connected cameras |\n| `gogcli` | Google Calendar integration |\n| `goplaces` | Google Places API (New) CLI |\n| `bird` | Twitter/X integration |\n| `sonoscli` | Control Sonos speakers |\n| `imsg` | Send/read iMessages |\n\n### Adding community plugins\n\nTell your agent: *\"Add the plugin from github:owner/repo-name\"*\n\nOr add it manually to your config:\n\n```nix\ncustomPlugins = [\n  { source = \"github:owner/repo-name\"; }\n];\n```\n\nThen run `home-manager switch` to install.\n\n### Plugins with configuration\n\nSome plugins need settings (auth files, preferences). Here's a simplified example:\n\n```nix\n# Example: a padel court booking plugin (simplified for illustration)\ncustomPlugins = [\n  {\n    source = \"github:example/padel-cli\";\n    config = {\n      env = {\n        PADEL_AUTH_FILE = \"~/.secrets/padel-auth\";  # where your login token lives\n      };\n      settings = {\n        default_city = \"Barcelona\";\n        preferred_times = [ \"18:00\" \"20:00\" ];\n      };\n    };\n  }\n];\n```\n\n- `config.env` - paths to secrets/auth files the plugin needs\n- `config.settings` - preferences (rendered to `config.json` for the plugin)\n\n\u003cdetails\u003e\n\u003csummary\u003e\u003cstrong\u003eFor plugin developers\u003c/strong\u003e\u003c/summary\u003e\n\nWant to make your tool available as a OpenClaw plugin? Here's the contract.\n\n**Minimum structure:**\n\n```\nyour-plugin/\n  flake.nix          # Declares the plugin\n  skills/\n    your-skill/\n      SKILL.md       # Instructions for the AI\n```\n\n**Your `flake.nix` must export `openclawPlugin`:**\n\n```nix\n{\n  outputs = { self, nixpkgs, ... }:\n    let\n      pkgs = import nixpkgs { system = builtins.currentSystem; };\n    in {\n      openclawPlugin = {\n        name = \"hello-world\";\n        skills = [ ./skills/hello-world ];\n        packages = [ pkgs.hello ]; # CLI tools to install\n        needs = {\n          stateDirs = [];          # Directories to create (relative to ~)\n          requiredEnv = [];        # Required environment variables\n        };\n      };\n    };\n}\n```\n\n**Your `SKILL.md` teaches the AI:**\n\n```md\n---\nname: hello-world\ndescription: Prints hello world.\n---\n\nUse the `hello` CLI to print a greeting.\n```\n\nSee `examples/hello-world-plugin` for a complete working example.\n\n---\n\n**Full plugin authoring prompt** - paste this to your AI agent to make any repo nix-openclaw-native:\n\n```text\nGoal: Make this repo a nix-openclaw-native plugin with the standard contract.\n\nContract to implement:\n1) Add openclawPlugin output in flake.nix:\n   - name\n   - skills (paths to SKILL.md dirs)\n   - packages (CLI packages to put on PATH)\n   - needs (stateDirs + requiredEnv)\n\nExample:\nopenclawPlugin = {\n  name = \"my-plugin\";\n  skills = [ ./skills/my-plugin ];\n  packages = [ self.packages.${system}.default ];\n  needs = {\n    stateDirs = [ \".config/my-plugin\" ];\n    requiredEnv = [ \"MYPLUGIN_AUTH_FILE\" ];\n  };\n};\n\n2) Make the CLI explicitly configurable by env (no magic defaults):\n   - Support an auth file env (e.g., MYPLUGIN_AUTH_FILE)\n   - Honor XDG_CONFIG_HOME or a plugin-specific config dir env\n\n3) Provide AGENTS.md in the plugin repo:\n   - Plain-English explanation of knobs + values\n   - Generic placeholders only (no real secrets)\n   - Explain where credentials live (e.g., /run/agenix/...)\n\n4) Update SKILL.md to call the CLI by its PATH name.\n\nStandard plugin config shape (Nix-native, no JSON strings):\n\nplugins = [\n  {\n    source = \"github:owner/my-plugin\";\n    config = {\n      env = {\n        MYPLUGIN_AUTH_FILE = \"/run/agenix/myplugin-auth\";\n      };\n      settings = {\n        name = \"EXAMPLE_NAME\";\n        enabled = true;\n        retries = 3;\n        tags = [ \"alpha\" \"beta\" ];\n        window = { start = \"08:00\"; end = \"18:00\"; };\n        options = { mode = \"fast\"; level = 2; };\n      };\n    };\n  }\n];\n\nConfig flags the host will use:\n- `config.env` for required env vars (e.g., MYPLUGIN_AUTH_FILE)\n- `config.settings` for typed config keys (rendered to config.json in the first stateDir)\n\nCI note:\n- If the repo uses Garnix, add the plugin build to its `garnix.yaml` (or equivalent) so CI verifies it.\n\nWhy: explicit, minimal, fail-fast, no inline JSON strings.\nDeliverables: flake output, env overrides, AGENTS.md, skill update.\n```\n\n\u003c/details\u003e\n\n---\n\n## Configuration\n\n\u003e **Note:** You probably don't need to write this yourself. Your AI agent handles this when you use the [Quick Start](#quick-start) copypasta. These examples are here for reference.\n\u003e\n\u003e **Breaking change:** Nix now only emits config from `programs.openclaw.config` / `instances.\u003cname\u003e.config` (schema-typed). Legacy provider/routing/agent options are removed.\n\n### What OpenClaw needs (minimum)\n\n1. **Telegram bot token file** - create via [@BotFather](https://t.me/BotFather), set `channels.telegram.tokenFile`\n2. **Your Telegram user ID** - get from [@userinfobot](https://t.me/userinfobot), set `channels.telegram.allowFrom`\n3. **Gateway auth token** - set `gateway.auth.token` (or `OPENCLAW_GATEWAY_TOKEN`) for the local gateway\n4. **Provider API keys** - set via environment (e.g., `ANTHROPIC_API_KEY`) or `config.env.vars` (avoid secrets in store)\n\nThat's it. Everything else has sensible defaults.\n\n### Minimal config (single instance)\n\nThe simplest setup:\n\n```nix\n{\n  programs.openclaw = {\n    enable = true;\n    config = {\n      gateway = {\n        mode = \"local\";\n        auth = {\n          token = \"\u003cgatewayToken\u003e\"; # or set OPENCLAW_GATEWAY_TOKEN\n        };\n      };\n\n      channels.telegram = {\n        tokenFile = \"/run/agenix/telegram-bot-token\"; # any file path works\n        allowFrom = [ 12345678 ];  # your Telegram user ID\n      };\n    };\n\n    # Built-ins (tools + skills) shipped via nix-steipete-tools.\n    plugins = [\n      { source = \"github:openclaw/nix-steipete-tools?dir=tools/summarize\"; }\n    ];\n  };\n}\n```\n\nThen: `home-manager switch --flake .#youruser`\n\n### Sensible defaults config\n\nUses `instances.default` to unlock per-group mention rules. If `instances` is set, you don't need `programs.openclaw.enable`.\n\n```nix\n{\n  programs.openclaw = {\n    documents = ./documents;\n    config = {\n      gateway = {\n        mode = \"local\";\n        auth = {\n          token = \"\u003cgatewayToken\u003e\"; # or set OPENCLAW_GATEWAY_TOKEN\n        };\n      };\n\n      channels.telegram = {\n        tokenFile = \"/run/agenix/telegram-bot-token\";\n        allowFrom = [\n          12345678         # you (DM)\n          -1001234567890   # couples group (no @mention required)\n          -1002345678901   # noisy group (require @mention)\n        ];\n        groups = {\n          \"*\" = { requireMention = true; };\n          \"-1001234567890\" = { requireMention = false; }; # couples group\n          \"-1002345678901\" = { requireMention = true; };  # noisy group\n        };\n      };\n    };\n\n    instances.default = {\n      enable = true;\n      package = pkgs.openclaw; # batteries-included\n      stateDir = \"~/.openclaw\";\n      workspaceDir = \"~/.openclaw/workspace\";\n      launchd.enable = true;\n\n      # Plugins (prod: pinned GitHub). Built-ins are via nix-steipete-tools.\n      # MVP target: repo pointers resolve to tools + skills automatically.\n      plugins = [\n        { source = \"github:openclaw/nix-steipete-tools?dir=tools/oracle\"; }\n        { source = \"github:openclaw/nix-steipete-tools?dir=tools/peekaboo\"; }\n        { source = \"github:joshp123/xuezh\"; }\n        {\n          source = \"github:joshp123/padel-cli\";\n          config = {\n            env = { PADEL_AUTH_FILE = \"/run/agenix/padel-auth\"; };\n            settings = {\n              default_location = \"CITY_NAME\";\n              preferred_times = [ \"18:00\" \"20:00\" ];\n              preferred_duration = 90;\n              venues = [\n                {\n                  id = \"VENUE_ID\";\n                  alias = \"VENUE_ALIAS\";\n                  name = \"VENUE_NAME\";\n                  indoor = true;\n                  timezone = \"TIMEZONE\";\n                }\n              ];\n            };\n          };\n        }\n      ];\n    };\n  };\n}\n```\n\n---\n\n## Advanced\n\n### Dual-instance setup (prod + dev)\n\nUse a shared base config and override only what's different. After changing local plugin or gateway code, re-run `home-manager switch` to rebuild.\n\n```nix\n# flake inputs (pin prod + app)\ninputs = {\n  nix-openclaw.url = \"github:openclaw/nix-openclaw?ref=v0.1.0\"; # pins macOS app + gateway bundle\n};\n\nlet\n  prodConfig = {\n    channels.telegram = {\n      tokenFile = \"/run/agenix/telegram-prod\";\n      allowFrom = [ 12345678 ];\n    };\n  };\n  devConfig = {\n    channels.telegram = {\n      tokenFile = \"/run/agenix/telegram-dev\";\n      allowFrom = [ 12345678 ];\n    };\n  };\n  prod = {\n    enable = true;\n    # Prod gateway pin (comes from nix-openclaw input @ v0.1.0 above).\n    package = inputs.nix-openclaw.packages.${pkgs.system}.openclaw-gateway;\n    config = prodConfig;\n    plugins = [ { source = \"github:owner/your-plugin\"; } ];\n  };\nin {\n  # Pinned macOS app (POC: no local app builds, uses nix-openclaw @ v0.1.0 above).\n  programs.openclaw.appPackage =\n    inputs.nix-openclaw.packages.${pkgs.system}.openclaw-app;\n  programs.openclaw.documents = ./documents;\n  programs.openclaw.instances = {\n    prod = prod;\n    dev = prod // {\n      # Dev uses the same pinned macOS app (from nix-openclaw input),\n      # but overrides the gateway package to a local checkout.\n      config = devConfig;\n      gatewayPort = 18790;\n      # Local gateway checkout (path). App stays pinned.\n      gatewayPath = \"/Users/you/code/openclaw\";\n      # Local plugin overrides prod if names collide (last wins).\n      plugins = prod.plugins ++ [\n        { source = \"path:/Users/you/code/your-plugin\"; }\n        {\n          source = \"github:joshp123/padel-cli\";\n          config = {\n            env = { PADEL_AUTH_FILE = \"/run/agenix/padel-auth-dev\"; };\n            settings = {\n              default_location = \"CITY_NAME\";\n              preferred_times = [ \"18:00\" ];\n              preferred_duration = 90;\n              venues = [];\n            };\n          };\n        }\n      ];\n    };\n  };\n}\n```\n\n### Plugin collisions\n\nPlugins are keyed by their declared `name`. If two plugins declare the same name, the **last entry wins** (use this to override a prod plugin with a local dev one).\n\n### Tool overrides (avoid collisions)\n\nHome Manager auto-excludes `git` when `programs.git.enable = true`.\n\nDrop built-in tools that you already install elsewhere:\n\n```nix\nprograms.openclaw.excludeTools = [ \"git\" \"jq\" \"ripgrep\" ];\n```\n\nOr provide a custom list:\n\n```nix\nprograms.openclaw.toolNames = [ \"nodejs_22\" \"pnpm_10\" \"summarize\" ];\n```\n\nIf you override `programs.openclaw.package`, use `pkgs.openclawPackages.withTools { ... }.openclaw` to apply these lists.\n\n---\n\n## Packaging \u0026 Updates\n\n**Goal:** `nix-openclaw` is a great Nix package. Automation, promotion, and fleet rollout live elsewhere.\n\n### Stable only (for now)\n\nWe ship a single pinned upstream commit:\n- **Stable**: last known-good pin. This is the default.\n\nOutputs:\n```\n.#openclaw\n.#openclaw-gateway\n```\n\nPin lives in:\n- `nix/sources/openclaw-source.nix`\n\n### Responsibilities (who owns what)\n\n- **openclaw (upstream)**: source code, tests, releases.\n- **nix-openclaw**: Nix packaging, pins, CI builds.\n- **moltinators**: update cadence, smoke tests, promotion, rollout/rollback.\n\n### Automated pipeline (no manual steps)\n\n1) **moltinators updater** proposes a new stable pin.  \n2) **Garnix** builds the package on Linux + macOS and runs `pnpm test` on Linux.  \n   It also validates the generated Nix config options against the upstream schema.  \n3) **moltinators smoke test** runs against real Discord in `#moltinators-test`.  \n4) If green → promote to stable.  \n5) If red → keep current stable pin.\n\n---\n\n## Reference\n\n### Commands\n\n```bash\n# macOS: check service\nlaunchctl print gui/$UID/com.steipete.openclaw.gateway | grep state\n\n# macOS: view logs\ntail -50 /tmp/openclaw/openclaw-gateway.log\n\n# macOS: restart\nlaunchctl kickstart -k gui/$UID/com.steipete.openclaw.gateway\n\n# Linux: check service\nsystemctl --user status openclaw-gateway\n\n# Linux: view logs\njournalctl --user -u openclaw-gateway -f\n\n# Linux: restart\nsystemctl --user restart openclaw-gateway\n\n# Rollback\nhome-manager generations  # list\nhome-manager switch --rollback  # revert\n```\n\n### Packages\n\n| Package | Contents |\n| --- | --- |\n| `openclaw` (default) | macOS: gateway + app + tools · Linux: gateway + tools (headless) |\n| `openclaw-gateway` | Gateway CLI only |\n| `openclaw-tools` | Toolchain bundle (gateway helpers + CLIs) |\n| `openclaw-app` | macOS app only |\n\n### What we manage vs what you manage\n\n| Component | Nix manages | You manage |\n| --- | --- | --- |\n| Gateway binary | ✓ | |\n| macOS app | ✓ | |\n| Service (launchd/systemd) | ✓ | |\n| Tools (whisper, etc) | ✓ | |\n| Telegram bot token | | ✓ |\n| Anthropic API key | | ✓ |\n| Chat IDs | | ✓ |\n\n### Included tools\n\n\u003e **Platform note:** the toolchain is filtered per platform. macOS-only tools are skipped on Linux.\n\n**Core**: nodejs, pnpm, git, curl, jq, python3, ffmpeg, ripgrep\n\n**First‑party tools** are sourced from `nix-steipete-tools` when available (currently aarch64‑darwin).\n\n**AI/ML**: openai-whisper, sag (TTS)\n\n**Media**: spotify-player, sox, camsnap\n\n**macOS**: peekaboo, blucli\n\n**Integrations**: gogcli, goplaces, wacli, bird, mcporter\n\n---\n\n## Philosophy\n\nThe Zen of ~~Python~~ OpenClaw, ~~by~~ shamelessly stolen from Tim Peters\n\nBeautiful is better than ugly.\nExplicit is better than implicit.\nSimple is better than complex.\nComplex is better than complicated.\nFlat is better than nested.\nSparse is better than dense.\nReadability counts.\nSpecial cases aren't special enough to break the rules.\nAlthough practicality beats purity.\nErrors should never pass silently.\nUnless explicitly silenced.\nIn the face of ambiguity, refuse the temptation to guess.\nThere should be one-- and preferably only one --obvious way to do it.\nAlthough that way may not be obvious at first unless you're Dutch.\nNow is better than never.\nAlthough never is often better than *right* now.\nIf the implementation is hard to explain, it's a bad idea.\nIf the implementation is easy to explain, it may be a good idea.\nNamespaces are one honking great idea -- let's do more of those!\n\n---\n\n## Upstream\n\nWraps [OpenClaw](https://github.com/openclaw/openclaw) by Peter Steinberger.\n\n## License\n\nAGPL-3.0\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenclaw%2Fnix-openclaw","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fopenclaw%2Fnix-openclaw","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fopenclaw%2Fnix-openclaw/lists"}