This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.
A Nix × Neovim plugin manager shipped as a home-manager module (programs.nvimx). Users write lazy.nvim-style Lua; at lock time a headless Neovim evaluates the spec (lua/nvimx/extract.lua → resolve.lua → genflake.lua) and pins plugins in plugins.json + flake.lock. Builds are then pure and offline, and a generated bootstrap makes lazy.nvim load everything from the Nix store. Files under lua/nvimx/ are standalone scripts run via nvim -l / nvim --headless, not a require module tree.
nix flake check --option abort-on-warn trueandnix fmt -- --ci— exactly what CI runs (.github/workflows/check.yml); anylib.warn/builtins.warnevaluation warning (e.g. a deprecated nixpkgs alias) fails CI; home-managerwarningsare plain traces and are not caught. Both must pass.nix build .#checks.x86_64-linux.<name>— run one check.nix eval .#checks.<system>.<name>.drvPath— anix flake checksilently skips other systems (aarch64-darwin, and aarch64-linux on an x86 host); run this foraarch64-darwin/aarch64-linuxwhen touching system-dependent code.nix flake check --no-build --all-systemsevaluates all of them.nix fmt -- --clear-cache— required after editingstylua.tomlor.luacheckrc(treefmt caches on file + command).nix build .#demo && ./result/bin/nvim— smoke test;:Lazyshould show every plugin as local with no git operations.nix run .#lock -- --config ./nvim --out ./nvim/nvimx-lock— lock pipeline; also--update [name...],--import-lazy-lock [path].nix run .#skills-install— regenerates.claude/skills/from theagent-skillsinput with rsync--delete. Never hand-edit.claude/skills/.
No test framework. Every check is a derivation in its own tests/checks/<name>.nix (listed in tests/checks/default.nix; shared helpers in tests/checks/lib.nix), usually comparing output against tests/fixtures/**/golden/. tests/*.lua drivers run under nvim -l and fail via bare assert(). Check comments explain why (often citing issue numbers and other check names) — match that when adding a check.
- Locking is the only online step.
nix/lib/build-network.nixthrows at evaluation time on builds needing network; escape hatches:plugins.overrides>plugins.nixpkgsFallback>nix/build-registry/. - No IFD — e.g. checks pin blink.cmp with a literal
builtins.fetchTree. - Systems are
x86_64-linux,aarch64-linuxandaarch64-darwinonly (x86_64-darwinis out of scope). Wrap system-dependent outputs inforAllSystems;homeModulesandtemplatesstay system-independent. - CI has one workflow per system only for per-system README badges. Add steps to
check.ymlonly, never to the per-systemci-*.ymlfiles. lua/nvimx/bootstrap.lua.inis excluded from stylua/luacheck only by its extension — keep the name.- Don't set
programs.stylua.settingsin treefmt; it would overridestylua.toml.
- Conventional Commits: English, lowercase, imperative, no trailing period, scoped by subsystem (
lock,resolve,hm,dev,extract,build-registry,plugin-drv,treesitter,wrapper,ci). - Branch as
<type>/<slug>. Never push to main — merge via PR as a merge commit (not squash). Write PRs in English.