nix-ai:用 Nix 声明式管理 Claude Code、Codex、Copilot 等 AI 编码工具配置
dryvist/nix-ai
dryvist 发布 nix-ai,用 Nix 将 Claude Code、Gemini/Antigravity、GitHub Copilot、OpenAI Codex、Qwen Code 等 AI 编码工具的插件、hooks、权限规则和 MCP 服务器目录统一声明为代码,一条命令即可在任意机器上重建相同配置。
Your AI coding toolkit, declared once. Reproduced everywhere
Ever spent hours configuring Claude Code plugins, Gemini settings, and MCP servers — only to lose it all when you switch machines? nix-ai captures your entire AI setup as code using Nix. One command rebuilds everything, identically, every time.
What it manages
| Tool | What you get |
|---|---|
| Claude Code | Plugin ecosystem, hooks, agents, commands, rules |
| Gemini / Antigravity | CLI + IDE settings, custom commands, permission rules |
| GitHub Copilot | Configuration, permissions |
| OpenAI Codex | Settings, rules, approval policy |
| Qwen Code & Cecli | Settings for the Alibaba and Aider-fork CLIs |
| MCP Servers | One catalog (GitHub, Terraform, Context7, filesystem, memory, …) fanned out to every agent |
| AI Dev Tools | cclint, rulesync, and more |
| MLX (macOS) | Local Apple Silicon inference via mlx_lm.server behind llama-swap, with launchd integration |
Claude Code, Codex and Antigravity CLI are always configured. The other agent CLIs
(Copilot, OpenCode, Qwen Code, Cecli, claude-zai, claude-flow) are
installed only when programs.ai.untrustedClis.enable = true. oh-my-openagent (the
OpenCode plugin entry and the omo-senpi wrapper) is off by default and needs
programs.ai.ohMyOpenagent.disabled = false; omo-senpi also needs the untrusted gate.
Prerequisites
- Nix with flakes (Determinate Nix recommended)
- home-manager
- A supported platform:
aarch64-darwinorx86_64-linux
Installation
Add the input to your flake:
{ inputs.nix-ai = { url = "github:dryvist/nix-ai"; inputs.nixpkgs.follows = "nixpkgs"; inputs.home-manager.follows = "home-manager"; }; }
Then add the module to your home-manager config:
sharedModules = [ nix-ai.homeManagerModules.default ];
That's it. The module evaluates with zero extra configuration — every AI tool, plugin, and permission rule comes preconfigured. (Local MLX inference stays idle until you point it at a model; see Usage.)
How it works
nix-ai exports home-manager modules that merge into your existing configuration:
| Export | What it includes |
|---|---|
homeManagerModules.default |
The full AI stack — every tool below |
homeManagerModules.claude |
Just Claude Code |
homeManagerModules.codex |
Just OpenAI Codex |
homeManagerModules.mcp |
Just the MCP server catalog |
homeManagerModules.maestro |
Just Maestro orchestration |
(also: agent-skills, antigravity-cli, antigravity-ide, cecli, qwen-code) |
One module per tool |
lib.ci.claudeSettingsJson |
Pure settings JSON for CI validation (no derivations) |
lib.aiStackModels |
Role-name → model-ID registry, for foreign (non-module) consumers |
Self-contained design
The module injects its own dependencies via _module.args. Your consuming flake
only needs two follows lines:
inputs.nixpkgs.follows = "nixpkgs"; inputs.home-manager.follows = "home-manager";
No AI-specific inputs to wire up, no extra configuration. It just works.
Usage
Everything is enabled with sensible defaults. Common toggles on the default module:
| Option | Type | Default | Description |
|---|---|---|---|
programs.claude.model |
str or null | null |
Override the default model (e.g. "opus", "sonnet") |
programs.claude.outputStyle |
str or null | null |
Output style (e.g. "concise", "explanatory"); null = upstream default |
programs.claude.effortLevel |
enum or null | null |
Reasoning effort ("low" / "medium" / "high"); null = upstream default |
programs.claude.settings.sandbox.enabled |
bool | false |
Filesystem/network sandbox isolation |
programs.claude.trustedProjectDirs |
list of str | [] |
Directories auto-trusted for CLAUDE.md imports |
services.aiStack.defaultLocalModelId |
str | "" |
Local MLX model ID; set to enable on-device inference |
Claude's full option schema comes from nix-claude-code;
the MCP catalog is documented in modules/mcp/README.md.
Testing and validation
nix flake check # nixfmt, statix, deadnix, shellcheck, and full module evaluation nix fmt # auto-fix formatting
Repository structure
modules/
├── claude/ # Claude Code — plugins, hooks, agents, rules
├── codex/ # OpenAI Codex
├── antigravity-*/ # Gemini / Antigravity CLI + IDE
├── cecli/ # Cecli (Aider fork)
├── qwen-code/ # Alibaba Qwen Code
├── mcp/ # MCP server catalog, fanned out to every agent
├── mlx/ # MLX local inference (mlx_lm + llama-swap, macOS)
├── fabric/ # Fabric prompt patterns + CLI
├── agent-skills/ # Cross-tool skill deployment
├── token-meter.nix # splunk/token-meter usage dashboard + HTTPS gate
└── common/ # Shared permission engine and formatters
lib/ # Pure helpers (settings/registry generators, CI exports)
docs/ # Architecture notes (docs/architecture) and ADRs (docs/adr)
launchd/TCC
Agents defined here declare their program and arguments as usual. The consuming host
configuration renders every agent behind a distinctly named executable and checks the
rendered plists, so Background Items never lists a shell or interpreter. The launched
program, its arguments and its final process image are unchanged; MLX agents keep Apple's
bash through programs.mlx.appleInterpreter.
License
来源:GitHub · github.com