Expose homeModules.default, a home-manager module whose programs.agents.skills option places operator-selected skill derivations into Claude Code's skills directory, one recursive home.file per skill, gated on programs.claude-code.enable and sourcing configDir from the claude-code module. Add a nix flake check that builds the home-files tree under several operator configurations and asserts placement, recursion, the enable gate, configDir sourcing, and coexistence with an operator's own skills.
83 lines
3.0 KiB
Nix
83 lines
3.0 KiB
Nix
{
|
|
description = "Personal agent skills, packaged through Nix.";
|
|
|
|
inputs.nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
|
inputs.flake-utils.url = "github:numtide/flake-utils";
|
|
|
|
# Present only so `nix flake check` can evaluate `homeModules.default` against
|
|
# real home-manager (the home-manager-module check). Its nixpkgs follows this
|
|
# flake's, so the module is checked against the same nixpkgs-and-home-manager
|
|
# pairing a consumer following this flake would get. It has no bearing on the
|
|
# module a consumer imports — that module is a bare function taking the
|
|
# importing configuration's own home-manager and pkgs.
|
|
inputs.home-manager.url = "github:nix-community/home-manager";
|
|
inputs.home-manager.inputs.nixpkgs.follows = "nixpkgs";
|
|
|
|
outputs =
|
|
{ self, nixpkgs, flake-utils, home-manager }:
|
|
let
|
|
mkSkill = import ./lib/mk-skill.nix;
|
|
discoverSkills = import ./lib/discover.nix nixpkgs.lib;
|
|
|
|
discoveredSkills = discoverSkills ./skills;
|
|
|
|
skillPackages =
|
|
pkgs:
|
|
nixpkgs.lib.listToAttrs (
|
|
map (skill: {
|
|
inherit (skill) name;
|
|
value = mkSkill { inherit pkgs; inherit (skill) name src; };
|
|
}) discoveredSkills
|
|
);
|
|
in
|
|
{
|
|
lib = { inherit mkSkill; };
|
|
|
|
# Global placement: an operator selects skills into `~/.claude/skills/`
|
|
# via `programs.agents.skills`. Not per-system — it is a module function,
|
|
# and the skills it places come from the importing configuration's own
|
|
# selection rather than this flake's nixpkgs.
|
|
homeModules = rec {
|
|
agents-skills = ./home-manager-module.nix;
|
|
default = agents-skills;
|
|
};
|
|
}
|
|
//
|
|
# An explicit system list rather than `eachDefaultSystem`.
|
|
# That default set includes x86_64-darwin, which current nixpkgs no longer
|
|
# evaluates (its `legacyPackages` throws).
|
|
flake-utils.lib.eachSystem
|
|
[
|
|
"x86_64-linux"
|
|
"aarch64-linux"
|
|
"aarch64-darwin"
|
|
]
|
|
(
|
|
system:
|
|
let
|
|
pkgs = nixpkgs.legacyPackages.${system};
|
|
in
|
|
{
|
|
# No `default`: a catalog has no single default skill.
|
|
packages = skillPackages pkgs;
|
|
|
|
# Each discovered skill is folded in as its own check, so
|
|
# `nix flake check` builds every skill and fails on a malformed one.
|
|
checks = (skillPackages pkgs) // {
|
|
skill-build = import ./checks/skill-build.nix {
|
|
inherit pkgs mkSkill discoverSkills;
|
|
};
|
|
|
|
# Proves the global-placement module composes: it builds the
|
|
# home-files derivation `homeModules.default` produces under several
|
|
# operator configurations. Reuses this flake's `mkSkill` so the
|
|
# sample skills carry the same name contract real ones do.
|
|
home-manager-module = import ./checks/home-manager-module.nix {
|
|
inherit pkgs home-manager mkSkill;
|
|
module = self.homeModules.default;
|
|
};
|
|
};
|
|
}
|
|
);
|
|
}
|