Files
skills/flake.nix
alexion ab2c05acb2 feat: add dev shell with python3 and the benchmark skill (task 0004)
nix develop places benchmark-skill into ./.claude/skills/ (so /benchmark-skill
is available in this repo) and puts python3 on PATH to run the deterministic
core without a one-off nix shell.
2026-07-24 09:01:24 -04:00

107 lines
4.2 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;
mkSkillsShellHook = import ./lib/mk-skills-shell-hook.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 mkSkillsShellHook; };
# 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;
};
# Proves the per-project dev-shell helper: it runs the produced hook
# against a fixture project and asserts placement, stateless
# stale-removal, and that hand-authored skills stay untouched.
shell-hook = import ./checks/shell-hook.nix {
inherit pkgs mkSkill mkSkillsShellHook;
};
# Proves the benchmark skill's deterministic core at its single seam:
# it feeds committed fixtures to the core and asserts the metrics, the
# Efficacy verdict, and the rendered report.
benchmark-core = import ./checks/benchmark-core.nix {
inherit pkgs;
};
};
# A working shell for developing skills in this repo.
# python3 runs the benchmark skill's deterministic core.
# The benchmark-skill is placed into ./.claude/skills/ on entry, so
# /benchmark-skill is available while working in this repo.
devShells.default = pkgs.mkShell {
packages = [ pkgs.python3 ];
shellHook = mkSkillsShellHook [ (skillPackages pkgs).benchmark-skill ];
};
}
);
}