- apiKeys: list of API key names (openai, google, anthropic, openrouter) - mkDirenvStdlib: generates use_api_keys() bash function - mkSopsSecrets: generates sops-nix secrets attribute set Consumers (ops-dev, dotfiles) can now import from skills.lib instead of maintaining duplicate key lists.
144 lines
4.7 KiB
Nix
144 lines
4.7 KiB
Nix
{
|
|
description = "AI agent skills for Claude Code and OpenCode";
|
|
|
|
inputs = {
|
|
nixpkgs.url = "github:NixOS/nixpkgs/nixos-unstable";
|
|
flake-utils.url = "github:numtide/flake-utils";
|
|
};
|
|
|
|
outputs = { self, nixpkgs, flake-utils }:
|
|
let
|
|
# Home Manager module for deploying skills
|
|
skillsModule = import ./modules/ai-skills.nix;
|
|
|
|
# List of available skills
|
|
availableSkills = [
|
|
"bd-issue-tracking"
|
|
"niri-window-capture"
|
|
"orch"
|
|
"screenshot-latest"
|
|
"tufte-press"
|
|
"worklog"
|
|
"update-spec-kit"
|
|
"update-opencode"
|
|
"web-search"
|
|
"web-research"
|
|
];
|
|
in
|
|
flake-utils.lib.eachDefaultSystem
|
|
(system:
|
|
let
|
|
pkgs = import nixpkgs { inherit system; };
|
|
in
|
|
{
|
|
# Development shell for working on skills
|
|
devShells.default = pkgs.mkShell {
|
|
name = "ai-skills";
|
|
packages = with pkgs; [
|
|
bash
|
|
shellcheck
|
|
jq
|
|
];
|
|
|
|
shellHook = ''
|
|
echo "🤖 AI Skills development environment"
|
|
echo "Available skills: ${builtins.concatStringsSep ", " availableSkills}"
|
|
echo ""
|
|
echo "Commands:"
|
|
echo " ./bin/deploy-skill.sh <name> - Copy skill to dotfiles"
|
|
echo " bash -n skills/*/scripts/*.sh - Validate all scripts"
|
|
'';
|
|
};
|
|
|
|
# Package individual skills for deployment
|
|
packages =
|
|
let
|
|
# Filter to only skills that exist
|
|
existingSkills = builtins.filter
|
|
(name: builtins.pathExists (./skills + "/${name}"))
|
|
availableSkills;
|
|
|
|
individualSkills = builtins.listToAttrs (
|
|
map (skillName: {
|
|
name = skillName;
|
|
value = pkgs.stdenv.mkDerivation {
|
|
name = "ai-skill-${skillName}";
|
|
src = ./skills + "/${skillName}";
|
|
|
|
installPhase = ''
|
|
mkdir -p $out
|
|
cp -r . $out/
|
|
|
|
# Make scripts executable
|
|
if [ -d $out/scripts ]; then
|
|
chmod +x $out/scripts/*.sh 2>/dev/null || true
|
|
fi
|
|
'';
|
|
};
|
|
}) existingSkills
|
|
);
|
|
in
|
|
individualSkills // {
|
|
# All skills as a combined package
|
|
all-skills = pkgs.symlinkJoin {
|
|
name = "all-ai-skills";
|
|
paths = builtins.attrValues individualSkills;
|
|
};
|
|
};
|
|
})
|
|
// {
|
|
# Export the Home Manager module
|
|
homeManagerModules.ai-skills = skillsModule;
|
|
|
|
# Also export as nixosModules for compatibility
|
|
nixosModules.ai-skills = skillsModule;
|
|
|
|
# Export skills paths for direct use
|
|
lib = {
|
|
inherit availableSkills;
|
|
|
|
# Helper to get skill path
|
|
getSkillPath = skillName: ./skills/${skillName};
|
|
|
|
# Helper to get all skill paths
|
|
getAllSkillPaths = map (name: ./skills/${name}) availableSkills;
|
|
|
|
# API Keys - Single Source of Truth
|
|
# Used by both direnv stdlib and sops-nix configuration
|
|
apiKeys = [ "openai" "google" "anthropic" "openrouter" ];
|
|
|
|
# Generate direnv stdlib use_api_keys function
|
|
mkDirenvStdlib = keys:
|
|
let
|
|
toEnvVar = key: {
|
|
"openai" = "OPENAI_API_KEY";
|
|
"google" = "GEMINI_API_KEY";
|
|
"anthropic" = "ANTHROPIC_API_KEY";
|
|
"openrouter" = "OPENROUTER_API_KEY";
|
|
}.${key} or (builtins.throw "Unknown API key: ${key}");
|
|
|
|
# Google key exports both GEMINI_API_KEY and GOOGLE_API_KEY
|
|
mkExport = key:
|
|
if key == "google" then ''
|
|
[ -f /run/secrets/api_keys/${key} ] && export ${toEnvVar key}="$(cat /run/secrets/api_keys/${key})" && export GOOGLE_API_KEY="$GEMINI_API_KEY"''
|
|
else ''
|
|
[ -f /run/secrets/api_keys/${key} ] && export ${toEnvVar key}="$(cat /run/secrets/api_keys/${key})"'';
|
|
in ''
|
|
use_api_keys() {
|
|
${builtins.concatStringsSep "\n " (map mkExport keys)}
|
|
}
|
|
'';
|
|
|
|
# Generate sops-nix secrets attribute set
|
|
mkSopsSecrets = { keys, owner, group ? "users" }:
|
|
builtins.listToAttrs (map (key: {
|
|
name = "api_keys/${key}";
|
|
value = {
|
|
mode = "0600";
|
|
inherit owner group;
|
|
};
|
|
}) keys);
|
|
};
|
|
};
|
|
}
|