跳到正文
GitHub·· 10 天前AI 评分38

nix-claude-code:用 Nix 声明式配置 Claude Code

dryvist/nix-claude-code

AI 导读

dryvist/nix-claude-code 是一个 Nix flake,把 Claude Code 的插件、marketplace、技能、hooks、MCP 和权限规则封装成可组合的 home-manager 模块,在 macOS 和 Linux 上可复现。

正文

Declarative Claude Code in Nix — plugins, marketplaces, skills, hooks, MCP, and permissions as composable home-manager modules. Reproducible on macOS and Linux.

CI License: MIT Nix Flake home-manager Anthropic Spec

A Nix flake that ships Claude Code as composable home-manager modules. Drop it into your flake — you get a fully-configured Claude Code with a curated plugin stack, statusline, hooks, MCP servers, and permission rules. All declared in Nix, reproducible across machines, rolled back with one command.

What you get

  • All marketplaces, no fiddling. Anthropic's official marketplaces (claude-plugins-official, anthropic-agent-skills) plus 15+ curated community marketplaces, wired up to refresh automatically.
  • Plugins as data. Every plugin you enable is declared in programs.claude.enabledPlugins, version-pinned in flake.lock, rolled back atomically with darwin-rebuild --rollback.
  • Full-trust auto mode. Claude Code ships with defaultMode = "auto" and zero hard-coded allow/ask/deny rules — every tool call goes to the auto-mode classifier, which reads the conversation and the repo instead of pattern-matching a command prefix. The structured permission data is still here and still exported for Codex, Gemini, and any other agent that has no classifier of its own.
  • Statusline themes. Pick powerline, ccstatusline, or daniel3303's theme with one option.
  • Optional account switching. Enable claude-swap only where needed for manual Claude subscription switching and parallel terminal sessions.
  • MCP plumbing. Surface programs.claude.mcpServers from your favorite MCP runtime; we wire them into Claude's settings.json exactly the way Anthropic specifies.
  • Built on Anthropic's official spec. Reads .claude-plugin/marketplace.json and .claude-plugin/plugin.json per the official plugin reference. No proprietary formats; no surprises.

Installation

Add nix-claude-code to your flake inputs:

{
  inputs = {
    nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";

    home-manager.url = "github:nix-community/home-manager/release-26.05";
    home-manager.inputs.nixpkgs.follows = "nixpkgs";

    nix-claude-code.url = "github:dryvist/nix-claude-code";
    nix-claude-code.inputs.nixpkgs.follows = "nixpkgs";
    nix-claude-code.inputs.home-manager.follows = "home-manager";
  };
}

Or scaffold from a template:

nix flake init -t github:dryvist/nix-claude-code#minimal
# or, if you already use flake-parts:
nix flake init -t github:dryvist/nix-claude-code#flake-parts

Usage

The simplest setup imports homeModules.default:

{
  outputs = { home-manager, nix-claude-code, nixpkgs, ... }: {
    homeConfigurations."you" = home-manager.lib.homeManagerConfiguration {
      pkgs = nixpkgs.legacyPackages.aarch64-darwin;
      modules = [
        nix-claude-code.homeModules.default
        ({ ... }: {
          home.username = "you";
          home.homeDirectory = "/Users/you";
          home.stateVersion = "25.11";
          programs.claude.enable = true;
        })
      ];
    };
  };
}

Then activate:

nix run home-manager#switch -- --flake .#you
claude   # ready to go

Switch Claude subscriptions

claude-swap is disabled by default. Enable it to install the manual account-switching CLI:

programs.claude.swap.disabled = false;

After activation, log in to each Claude subscription interactively and run cswap add for each account. Use cswap switch <alias> to change the active account, or cswap run <alias> -- … to start a parallel terminal-local Claude session. The module does not configure automatic switching or store account credentials in Nix.

Pick and choose

homeModules.default enables everything. Or compose à-la-carte:

Module What it ships
homeModules.default All of the below, sane defaults — the 95% answer
homeModules.claude Alias of default
homeModules.core settings.json, auto-mode posture, the claude-code binary
homeModules.plugins Marketplace + plugin management
homeModules.statusline Powerline / ccstatusline / daniel3303 themes
homeModules.hooks Marketplace-refresh hook
homeModules.mcp programs.claude.mcpServers option (you populate from any runtime)
homeModules.latest Opt-in auto-installer for the latest Claude Code release

Want only settings.json and the permission posture, nothing else? Import homeModules.core and skip the rest. Want the plugins but not the statusline? Import homeModules.core + homeModules.plugins.

See docs/settings.md for the full settings.json option catalog, including the freeform passthrough for keys with no typed option yet.

Already on flake-parts?

{
  outputs = inputs: inputs.flake-parts.lib.mkFlake { inherit inputs; } {
    imports = [ inputs.nix-claude-code.flakeModule ];
    # ...
  };
}

Architecture

flowchart LR
    A[17 marketplace inputs<br/>flake.nix] --> B[lib.parseMarketplace]
    C[data/permissions/*.nix<br/>Nix-native data] --> D[lib.mkDefaultPermissions]
    D --> P[Codex / Gemini / other<br/>agents without a classifier]
    B --> E[modules/plugins.nix]
    F[modules/core.nix<br/>defaultMode=auto, no rules] --> G[~/.claude/settings.json]
    E --> G
    H[modules/statusline] --> I[~/.claude/statusline]
    J[modules/hooks] --> K[~/.claude/hooks/]
    L[modules/mcp<br/>mcpServers option] --> G
    M[pkgs.claude-code] --> N[~/.nix-profile/bin/claude]

Loading

See docs/architecture.md for the full breakdown.

API

The lib.* exports are designed for any AI-agent tool that wants to consume Claude-spec data:

{ inputs, lib, ... }:
let
  market = inputs.nix-claude-code.lib.parseMarketplace inputs.jacobpevans-cc-plugins;
  # market :: { name; description; owner; plugins; raw; }

  skills = inputs.nix-claude-code.lib.discoverSkills inputs.anthropic-agent-skills;
  # skills :: [{ name; path; pluginRoot; }]

  perms = inputs.nix-claude-code.lib.mkDefaultPermissions { tool = "codex"; };
  # perms :: { allow; allowMcp; ask; deny; denyExact; denyPatterns; webfetchDomains; }
  # (`ask` is always empty — see data/permissions/README.md. Claude Code
  #  itself no longer consumes this; auto mode is its gate.)
in
  # ... build whatever you need
Lib export Purity Returns
lib.parseMarketplace pure { name; description; owner; plugins; raw; }
lib.parsePlugin pure { name; description; version; author; raw; }
lib.discoverSkills pure [{ name; path; pluginRoot; }]
lib.discoverCommands pure [{ name; path; pluginRoot; }]
lib.discoverAgents pure [{ name; path; pluginRoot; frontmatter; }]
lib.discoverHooks pure hooks.json attrset
lib.toSettingsJson pure ~/.claude/settings.json shape
lib.permissions.{allow,ask,deny,domains,toolSpecific} data Permission lists
lib.mkDefaultPermissions pure Composed permissions for a tool
lib.wrapCommandsAsSkills { pkgs } impure Derivation wrapping commands/<name>.md as synthetic SKILL.md files

Compatibility

Component Supported
Claude Code latest stable (auto-tracked from Anthropic upstreams)
nixpkgs nixos-26.05 (override via inputs.nix-claude-code.inputs.nixpkgs.follows)
home-manager release-26.05
Platforms aarch64-darwin, x86_64-darwin, aarch64-linux, x86_64-linux
Plugin spec Anthropic official

Comparison

nix-claude-code Hand-maintained .claude/
Reproducible across machines ✓ ✗
Atomic rollback ✓ (--rollback) ✗
Version-pinned plugins ✓ (flake.lock) ✗
Auto-refresh marketplaces ✓ (opt-in hook) manual
One-command setup on a new machine ✓ hours of /plugin install
Anthropic plugin spec compliant ✓ depends on what you wrote

Contributing

  • Add a marketplace: append to flake.nix inputs and the wiring in flake/modules.nix.
  • Add a statusline theme: drop a <name>.nix file in modules/statusline/.
  • Add a permission rule: edit data/permissions/*.nix. These are the source of truth for permission rules across AI agent tools that have no classifier of their own (Codex, Gemini). Claude Code does not consume them — teach the auto-mode classifier instead, via programs.claude.autoMode.
  • Add a lib helper: write a pure function in lib/, add a nix-unit test in checks/lib/.

Pre-commit hooks run treefmt, deadnix, statix, and YAML/TOML validation. CI runs nix flake check on every PR.

See docs/adopters.md for the full integration guide.

License

MIT © Jacob P. Evans — see LICENSE.


Part of a larger ecosystem of ~40 repos — see how it all fits together.

来源:GitHub · github.com