summaryrefslogtreecommitdiffstats
path: root/nix/home-manager.nix
diff options
context:
space:
mode:
authorSimen A. W. Olsen <hello@simenandre.no>2026-10-25 12:41:28 +0100
committerSimen A. W. Olsen <hello@simenandre.no>2026-10-25 12:41:28 +0100
commitc596038adc7cdbd64988e61fee856d533b58c25d (patch)
treea02fde25835416d143ff56b807e640f6a7e9cf82 /nix/home-manager.nix
downloadskills-c596038adc7cdbd64988e61fee856d533b58c25d.tar.gz
skills-c596038adc7cdbd64988e61fee856d533b58c25d.zip
feat: skills, a package manager for agent skillsHEADv0.1.0main
Diffstat (limited to 'nix/home-manager.nix')
-rw-r--r--nix/home-manager.nix98
1 files changed, 98 insertions, 0 deletions
diff --git a/nix/home-manager.nix b/nix/home-manager.nix
new file mode 100644
index 0000000..53db658
--- /dev/null
+++ b/nix/home-manager.nix
@@ -0,0 +1,98 @@
+self:
+{
+ config,
+ lib,
+ pkgs,
+ ...
+}:
+
+let
+ cfg = config.programs.skills;
+ lock = lib.importJSON cfg.lockFile;
+
+ fetch =
+ src:
+ builtins.fetchTree (
+ {
+ type = "git";
+ inherit (src) url rev;
+ allRefs = true;
+ }
+ # With a narHash Nix reuses what `skills` already put in the store, so
+ # private sources work even when root evaluates this without SSH keys.
+ // lib.optionalAttrs (src ? narHash) { inherit (src) narHash; }
+ );
+
+ skills = lib.concatMapAttrs (
+ _: src:
+ let
+ tree = fetch src;
+ in
+ lib.mapAttrs (_: path: "${tree}/${path}") src.skills
+ ) lock.sources;
+
+ linkInto = dir: lib.mapAttrs' (name: path: lib.nameValuePair "${dir}/${name}" { source = path; }) skills;
+in
+{
+ options.programs.skills = {
+ enable = lib.mkEnableOption "agent skills from a skills lock file";
+
+ package = lib.mkOption {
+ type = lib.types.package;
+ default = self.packages.${pkgs.stdenv.hostPlatform.system}.default;
+ defaultText = lib.literalExpression "skills.packages.\${system}.default";
+ description = "The skills CLI.";
+ };
+
+ lockFile = lib.mkOption {
+ type = lib.types.path;
+ example = lib.literalExpression "./skills.lock";
+ description = "The skills.lock whose skills to install.";
+ };
+
+ manifest = lib.mkOption {
+ type = lib.types.nullOr lib.types.str;
+ default = null;
+ example = "/home/me/dotfiles/skills.json";
+ description = ''
+ Absolute path of the writable skills.json next to {option}`lockFile`,
+ so that `skills add` and `skills update` edit your configuration.
+ '';
+ };
+
+ agents = lib.mkOption {
+ type = lib.types.listOf (
+ lib.types.enum [
+ "claude"
+ "codex"
+ "opencode"
+ ]
+ );
+ default = [ "claude" ];
+ description = "Agents to install the skills into.";
+ };
+ };
+
+ config = lib.mkIf cfg.enable {
+ assertions = [
+ {
+ assertion = lock.version or null == 1;
+ message = "programs.skills.lockFile has an unsupported version; upgrade skills.";
+ }
+ ];
+
+ home.packages = [ cfg.package ];
+
+ home.sessionVariables = {
+ SKILLS_MANAGED_BY = "home-manager";
+ }
+ // lib.optionalAttrs (cfg.manifest != null) { SKILLS_MANIFEST = cfg.manifest; };
+
+ home.file = lib.mkMerge [
+ (lib.mkIf (lib.elem "claude" cfg.agents) (linkInto ".claude/skills"))
+ (lib.mkIf (lib.elem "codex" cfg.agents) (linkInto ".codex/skills"))
+ ];
+
+ xdg.configFile = lib.mkIf (lib.elem "opencode" cfg.agents) (linkInto "opencode/skills");
+ };
+}