スキルをNixで管理できるagent-skills-nixが便利

Nixを使い始めると、何でもかんでもNixに寄せたくなります。

HomebrewだけでなくzshのプラグインもNixで管理しているので、AIエージェントのスキルもNixで管理できたらなぁと。調べると agent-skills-nix というドンピシャなやつがあり、便利だったので布教します。

## agent-skills-nixとは

agent-skills-nixとは、NixでAIエージェントのスキルを管理できるツール?しくみ?です。

dotfilesで PC全体 として入れることもできますし、 リポジトリ毎 に入れることもできます。筆者は両方で使ってます。

.claude/skills.agents/skillsはもちろん、他のメジャーなAIエージェントのスキルディレクトリなら簡単に設定できます。

デフォルトで対応してないディレクトリにも対応できます。たとえば~/.claude_workのようにアカウント切り替えのために分けていても使えます。

## 何がうれしいか

前述のとおり「いろんなAIエージェント」「複数アカウント」のスキルディレクトリに対してコマンド一発で入り、一括でアップデートもできるのが便利です。

誰かがGitHubで配っているスキルだけではなく、普通に自分で書いたオリジナルのやつも管理対象にできます。

## 使い方

導入などはおそらく皆さんAIでやらせると思うので省きます。ここでは筆者の実際のやつを見せます。

{ inputs, lib, ... }:
let
# 仕事用の設定ディレクトリ(_work)には置きたくないスキルID。
# agent-skills-nixはターゲット単位でのスキル絞り込みに対応していないため、
# 同期後にactivationスクリプトでディレクトリごと削除する。
workExcludeSkills = [
"grilling"
"adr-creator"
"rrmap"
];
in
{
programs.agent-skills = {
enable = true;
sources = {
# 自作スキル(dotfilesローカル)
local = {
path = ./.;
};
# playwright-cli(GitHub)
playwright-cli = {
path = inputs.playwright-cli-skills;
subdir = "skills";
};
# drawio-mcp(GitHub)
drawio = {
path = inputs.drawio-mcp;
subdir = "plugins/claude-code/skills";
};
# grilling(GitHub, mattpocock/skills)
# https://github.com/mattpocock/skills/blob/main/skills/productivity/grilling/SKILL.md
grilling = {
path = inputs.mattpocock-skills;
subdir = "skills/productivity/grilling";
};
# natural-japanese(GitHub, coji/natural-japanese)
# https://github.com/coji/natural-japanese
natural-japanese = {
path = inputs.natural-japanese;
subdir = "skills";
};
# rrmap(GitHub, eetann/rrmap)
# https://github.com/eetann/rrmap
rrmap = {
path = inputs.rrmap-skills;
subdir = ".claude/skills";
};
# eli5(GitHub, anthropics/claude-plugins-community)
# https://github.com/anthropics/claude-plugins-community/tree/main/eli5
eli5 = {
path = inputs.claude-plugins-community;
subdir = "eli5/skills";
};
};
skills.enableAll = true;
targets.claude.enable = true;
targets.codex.enable = true;
# 仕事用の設定ディレクトリ(_work)にも同じスキルを配置する。
# structure は symlink-tree のまま(link はシェル変数展開が効かないため)。
targets.claude-work = {
enable = true;
dest = "$HOME/.claude_work/skills";
};
targets.codex-work = {
enable = true;
dest = "$HOME/.codex_work/skills";
};
};
# workExcludeSkillsに挙げたスキルを、agent-skills本体の同期後にwork系ディレクトリから削除する。
home.activation.agent-skills-work-exclude = lib.hm.dag.entryAfter [ "agent-skills" ] (
lib.concatMapStringsSep "\n" (skill: ''
$DRY_RUN_CMD rm -rf $VERBOSE_ARG "$HOME/.claude_work/skills/${skill}"
$DRY_RUN_CMD rm -rf $VERBOSE_ARG "$HOME/.codex_work/skills/${skill}"
'') workExcludeSkills
);
}

以下、細かい解説です。

### 仕事用アカウントにも配る

次の記事のように~/.claude_work/のように仕事用アカウントでは別ディレクトリを使っています。

Claude Codeのアカウント使い分け——もう誤爆してしょんぼりしない | eiji.page

agent-skills-nixは次のように書けば任意のディレクトリにスキルを放り込めるので、それをそのまま使ってます。

targets.claude-work = {
enable = true;
dest = "$HOME/.claude_work/skills";
};
targets.codex-work = {
enable = true;
dest = "$HOME/.codex_work/skills";
};

### 仕事用アカウントで使わないスキルを省く

仕事でリポジトリ内に同じスキルや似たようなスキルが入ってたりします。そうするとdotfiles側で管理しているやつは邪魔になるため、配置されないようにしてます。

grilling(grill-me)とかコミットあたりが鉄板でしょうか。

{ inputs, lib, ... }:
let
# 仕事用の設定ディレクトリ(_work)には置きたくないスキルID。
# 同期後にactivationスクリプトでディレクトリごと削除する。
workExcludeSkills = [
"grilling"
"adr-creator"
"rrmap"
];
in
{
# ...
# workExcludeSkillsに挙げたスキルを、agent-skills本体の同期後にwork系ディレクトリから削除する。
home.activation.agent-skills-work-exclude = lib.hm.dag.entryAfter [ "agent-skills" ] (
lib.concatMapStringsSep "\n" (skill: ''
$DRY_RUN_CMD rm -rf $VERBOSE_ARG "$HOME/.claude_work/skills/${skill}"
$DRY_RUN_CMD rm -rf $VERBOSE_ARG "$HOME/.codex_work/skills/${skill}"
'') workExcludeSkills
);
}

以上、agent-skills-nixの話でした。この前ちょうどWSLを入れたときにサクッと配置できたので爽快です。

筆者は物理的な引っ越しもNixでやりたかったんですがまぁ無理です。AIになんとかしてほしい。