Add a hash-backed npm runtime plugin path that lowers OpenClaw-style npm sources into immutable plugin roots and wires them through the existing Home Manager plugin resolver. Keep flake-backed customPlugins unchanged and document the boundary for agents and maintainers.
Tests: nix build .#checks.aarch64-darwin.default-instance --no-link; nix flake check --no-build; git diff --check
Co-authored-by: Codex <noreply@openai.com>
Use QMD's real update/embed/query commands instead of the nonexistent qmd pull path, and keep the activation script in nix/scripts instead of inline Nix.
Tests: nix build .#checks.aarch64-darwin.config-validity .#checks.aarch64-darwin.qmd-runtime --no-link; nix eval .#checks.x86_64-linux.qmd-runtime.name; scripts/check-flake-lock-owners.sh; git diff --check
Keep the QMD package internal to OpenClaw, but source it from upstream tobi/qmd on Linux and from the repaired nix-openclaw-tools package on Darwin until upstream Darwin packaging works.
Tests: scripts/check-flake-lock-owners.sh; nix build .#checks.aarch64-darwin.qmd-runtime --no-link; nix eval .#packages.x86_64-linux.qmd.outPath; nix eval .#packages.aarch64-darwin.qmd.outPath; git diff --check
Keep upstream tobi/qmd as the Linux QMD package while retaining the nix-openclaw-tools Darwin repair package until upstream Darwin is fixed. This preserves the batteries-included runtime path without forking the Linux package surface.
Tests: nix build '.#checks.aarch64-darwin.qmd-runtime' --accept-flake-config --no-link; nix eval --option eval-cache false --raw '.#checks.x86_64-linux.qmd-runtime.name' --accept-flake-config; nix eval --option eval-cache false --raw '.#checks.aarch64-darwin.qmd-runtime.name' --accept-flake-config; git diff --check
What:
- consume QMD from nix-openclaw-tools instead of a separate upstream flake input
- expose QMD as an internal OpenClaw battery on Darwin and Linux
- add an opt-in Home Manager qmd model prewarm activation
- keep plugin packages off the user's shell PATH by default while preserving the runtime PATH
Why:
- nix-openclaw-tools owns reproducible tool packages and cacheable plugin metadata
- nixos-config should configure OpenClaw, not hand-wire runtime tools
Tests:
- nix build .#checks.aarch64-darwin.package-contents --accept-flake-config --no-link
- nix build .#checks.aarch64-darwin.qmd-runtime --accept-flake-config --no-link
- nix build .#checks.aarch64-darwin.bin-surface .#checks.aarch64-darwin.config-validity .#checks.aarch64-darwin.gateway-smoke --accept-flake-config --no-link
- nix eval .#checks.x86_64-linux.default-instance.drvPath --accept-flake-config
Make QMD the Nix-supported batteries-included local memory backend by pinning the upstream QMD flake and adding qmd to the private openclaw wrapper PATH.
Keep QMD opt-in through upstream OpenClaw config with memory.backend = qmd, and document that builtin memorySearch.provider = local remains an escape hatch rather than the primary supported Nix path.
Also point nix run .#openclaw at the batteries-included bundle so app execution gets the same internal runtime PATH as the package.
Tests: sh -n nix/scripts/check-openclaw-qmd-runtime.sh; scripts/check-flake-lock-owners.sh; git diff --check; nix flake show --accept-flake-config --json; nix build .#checks.aarch64-darwin.qmd-runtime .#checks.aarch64-darwin.bin-surface .#packages.aarch64-darwin.openclaw --accept-flake-config --no-link --print-out-paths; nix build .#checks.x86_64-linux.qmd-runtime --accept-flake-config --no-link --print-out-paths; nix build .#checks.aarch64-darwin.ci --accept-flake-config --no-link --print-out-paths; nix build .#packages.x86_64-linux.openclaw .#checks.x86_64-linux.bin-surface --accept-flake-config --no-link --print-out-paths; scripts/hm-activation-macos.sh; nix build .#checks.x86_64-linux.gateway-smoke --accept-flake-config --no-link --print-out-paths; nix run .#openclaw --accept-flake-config -- --version; bash -n scripts/update-pins.sh; node --check scripts/select-openclaw-release.mjs; node --check scripts/select-openclaw-release.test.mjs; node scripts/select-openclaw-release.test.mjs
Expose only the openclaw command from the default package while keeping bundled runtime tools on the wrapper PATH. Remove the public openclaw-tools package output and document runtime tools as implementation detail.
Tests: nix build .#packages.aarch64-darwin.openclaw .#checks.aarch64-darwin.bin-surface .#packages.x86_64-linux.openclaw .#checks.x86_64-linux.bin-surface --accept-flake-config --no-link --print-out-paths; nix build .#checks.aarch64-darwin.ci --accept-flake-config --no-link --print-out-paths; git diff --check --cached
What:
- export the agent-first flake template
- remove unsupported Intel macOS setup claims
- replace stale Discord channel links with the public invite path
- simplify the advanced dual-instance example and sync plugin docs
Why:
- make the documented first-run path match the flake users actually consume
- avoid sending users toward unsupported systems or dead Discord links
Tests:
- git diff --cached --check: passed
- nix flake show --json --accept-flake-config | jq -e '.templates."agent-first"': passed
- nix flake init -t /Users/josh/code/nix-openclaw#agent-first --accept-flake-config: wrote flake.nix and documents/
- rg stale onboarding strings in README.md AGENTS.md templates/agent-first/flake.nix docs: no matches
What:
- replace the misleading gateway test check with a source-checks build/config-options check
- remove the full upstream Vitest suite from the hard Nix promotion gate
- document that yolo validates the Nix-owned package contract, not upstream source test health
Why:
- the current full packageable upstream release builds as a package but has failing upstream Vitest cases when rebuilt from source
- nix-openclaw should block on packaging, smoke startup, config generation, module activation, and app artifacts rather than an upstream-owned unit test suite
Tests:
- git diff --check
- bash -n scripts/update-pins.sh scripts/hm-activation-macos.sh nix/modules/home-manager/openclaw-launchd-relink.sh nix/scripts/source-checks-build.sh nix/scripts/source-checks-check.sh nix/scripts/config-options-check.sh
- ruby -e 'require "yaml"; YAML.load_file(".github/workflows/ci.yml"); YAML.load_file(".github/workflows/yolo-update.yml")'
- nix eval --accept-flake-config --raw .#checks.x86_64-linux.source-checks.drvPath
- nix eval --accept-flake-config --raw .#checks.x86_64-linux.ci.drvPath
- nix flake show --accept-flake-config --all-systems --json
- scripts/check-flake-lock-owners.sh
- node scripts/select-openclaw-release.test.mjs
- scripts/hm-activation-macos.sh
- nix build --accept-flake-config -L .#checks.aarch64-darwin.ci
Fix the documented minimal Home Manager plugin option to use customPlugins, remove the stale duplicate skill-file builder, and assert duplicate plugin skill paths against the paths Home Manager actually installs.
Add local plugin fixtures so the default-instance check covers the agent-facing customPlugins path and duplicate skill collisions.
What:
- move the completed OpenClaw packaging ExecPlan out of the pending slot
- document recursive self-review and the macOS Home Manager activation gate for daily maintenance
- make macOS app publishing explicitly out of scope for nix-openclaw automation
- replace an unclear README ownership label with release automation
Why:
- future maintainer runs need enough durable context to repair nix-openclaw without relearning this thread
- missing upstream macOS assets should be classified, not turned into a competing release process
Tests:
- git diff --check
- node scripts/select-openclaw-release.test.mjs
- bash -n scripts/update-pins.sh
- ruby -e 'require "yaml"; YAML.load_file(".github/workflows/yolo-update.yml"); YAML.load_file(".github/workflows/ci.yml")'
- scripts/check-flake-lock-owners.sh
- nix flake show --accept-flake-config
What:
- split the stable-release updater into read-only selection and pin materialization modes
- rewrite yolo into select, validate-linux, validate-macos, and promote jobs
- fail yolo when the newest stable release is incomplete instead of silently sticking
- update maintainer docs to describe the new safe promotion policy
Why:
- stop direct yolo pushes from moving main without the same Linux and macOS proof as CI
- keep mirroring the newest stable release while making broken upstream releases visible
Tests:
- bash -n scripts/update-pins.sh
- ruby -e 'require "yaml"; YAML.load_file(".github/workflows/yolo-update.yml"); puts "yaml-ok"'
- GITHUB_ACTIONS=true GH_TOKEN="$(gh auth token)" scripts/update-pins.sh select
- temp copy pinned to v2026.4.11: scripts/update-pins.sh select emits v2026.4.14 tuple
What:
- switch the pin updater from upstream-main commit selection to upstream stable release selection
- restore Yolo Update Pins as an hourly stable-release poller
- update maintainer and README docs to describe stable-release mirroring and the recovery lesson
Why:
- OpenClaw stable is already tag-based upstream, and nix-openclaw should mirror that release line directly
- this removes the old latest-green-main churn model and keeps source + app pins tied to one published upstream release
Tests:
- bash -n scripts/update-pins.sh
- GITHUB_ACTIONS=true GH_TOKEN="$(gh auth token)" scripts/update-pins.sh
What:
- remove legacy option migrations for programs.openclaw.firstParty/plugins
- add explicit removed-option failures pointing to bundledPlugins/customPlugins
- add plugin-catalog.nix as single source of truth for bundled plugins
- generate bundled option toggles, source map, linux check selection, and tool list from the catalog
- update docs/wording from first-party to bundled plugins
Why:
- enforce forward-only API changes with fail-fast errors
- eliminate duplicated plugin lists drifting across module/check/tool surfaces
- keep consumer configuration mental model simple: bundledPlugins + customPlugins only
Tests:
- nix flake check --no-build (pass)
- Add golden paths doc and link from README\n- Default workspaceDir to stateDir/workspace and pin agents.defaults.workspace when unset\n- Fix macOS app defaults domain and add openclaw.nixMode toggle
What:
- add bundledPlugins/customPlugins options
- alias firstParty/plugins to new names
- update docs + checks to new naming
Why:
- clearer split between bundled and custom plugins
Tests:
- not run (config/docs change)
What:
- add firstParty.<name>.config option
- pass config into first-party plugin entries
- document first-party config example
Why:
- support batteries-included plugins with env/settings
Tests:
- not run (config/docs change)
What:
- clarify that adopted workspace docs should be copied with symlinks dereferenced
Why:
- prevent broken Nix store links when moving docs across machines
Tests:
- not run (docs-only change)
What: auto-drop git from bundled toolchain when programs.git.enable.
Why: avoid git-jump buildEnv collision without user config.
Tests: not run (module change)
What: add tool list overrides + excludes in tooling and module defaults.
Why: let downstream drop overlapping tools to avoid buildEnv collisions.
Tests: not run (packaging change)
- Add Requirements section making clear Nix must be installed first
- Link to Determinate Nix docs
- Include install command for those without Nix
- Add note to Plugins section: complete Quick Start first
Addresses user feedback about unclear ordering.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Keeps the top of README clean while rewarding curious readers.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>