aboutsummaryrefslogtreecommitdiffstats
path: root/nix
diff options
context:
space:
mode:
Diffstat (limited to 'nix')
-rw-r--r--nix/home-manager.nix98
-rw-r--r--nix/package.nix45
2 files changed, 143 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");
+ };
+}
diff --git a/nix/package.nix b/nix/package.nix
new file mode 100644
index 0000000..414f173
--- /dev/null
+++ b/nix/package.nix
@@ -0,0 +1,45 @@
+{
+ lib,
+ stdenv,
+ buildGoModule,
+ git,
+ makeWrapper,
+ installShellFiles,
+ version,
+ src,
+}:
+
+buildGoModule {
+ pname = "skills";
+ inherit version src;
+
+ vendorHash = "sha256-7K17JaXFsjf163g5PXCb5ng2gYdotnZ2IDKk8KFjNj0=";
+
+ ldflags = [
+ "-s"
+ "-w"
+ "-X main.version=${version}"
+ ];
+
+ nativeBuildInputs = [
+ makeWrapper
+ installShellFiles
+ ];
+
+ postInstall = ''
+ wrapProgram $out/bin/skills --prefix PATH : ${lib.makeBinPath [ git ]}
+ ''
+ + lib.optionalString (stdenv.buildPlatform.canExecute stdenv.hostPlatform) ''
+ installShellCompletion --cmd skills \
+ --bash <($out/bin/skills completion bash) \
+ --fish <($out/bin/skills completion fish) \
+ --zsh <($out/bin/skills completion zsh)
+ '';
+
+ meta = {
+ description = "Install and update agent skills from git repositories";
+ homepage = "https://git.simenandre.no/skills/about/";
+ license = lib.licenses.mit;
+ mainProgram = "skills";
+ };
+}