M README.md => README.md +1 -0
@@ 66,6 66,7 @@ Runnable examples: [`examples/basic`](examples/basic) and
| `claude.enable`, `codex.enable` | Make the agent available to launchers. |
| `claude.package`, `codex.package` | Agent package; defaults come from this flake's inputs. |
| `claude.settings` | JSON passed with `--settings` (layered over the account's `settings.json`). |
+| `claude.plugins` | Plugin directories loaded with `--plugin-dir`; nothing is installed into the account. |
| `codex.settings` | TOML linked as `$CODEX_HOME/agent-environments.config.toml` and selected with `--profile agent-environments` (layered over the account's `config.toml`). |
| `instructions.<name>.{text,order}` | Fragments of `CLAUDE.md` / `AGENTS.md`, sorted by `order` (default 1000), then name. |
| `skills.packages` | `mkSkill` packages to enable. Their skill dependencies are added automatically. |
M checks/default.nix => checks/default.nix +9 -2
@@ 46,6 46,10 @@ let
skills = [ leaf ];
};
+ fixturePlugin = pkgs.writeTextDir ".claude-plugin/plugin.json" (
+ builtins.toJSON { name = "fixture"; }
+ );
+
full = mkEnvironment {
inherit pkgs;
modules = [
@@ 65,6 69,7 @@ let
order = 10;
};
claude.settings.model = "opus";
+ claude.plugins = [ fixturePlugin ];
codex.settings.model = "gpt-5";
launchers = {
claude-work.agent = "claude";
@@ 130,10 135,12 @@ in
[ -f $s/skills/leaf/SKILL.md ] || fail "dependency skill leaf missing"
grep -qxF "HELLO=yes" $STUB_LOG.env || fail "skill runtime input not on PATH"
- # Settings layered via --settings, user args passed through after it.
+ # Settings layered via --settings, plugins loaded with --plugin-dir, user args
+ # passed through after them.
[ "$(sed -n 1p $STUB_LOG.args)" = "--settings" ] || fail "missing --settings"
grep -q '"model": *"opus"' "$(sed -n 2p $STUB_LOG.args)" || fail "settings file content"
- [ "$(sed -n '3,$p' $STUB_LOG.args)" = "$(printf -- '--resume\nx')" ] || fail "user args not passed through"
+ [ "$(sed -n 3,4p $STUB_LOG.args)" = "$(printf -- "--plugin-dir\n${fixturePlugin}")" ] || fail "plugin not loaded"
+ [ "$(sed -n '5,$p' $STUB_LOG.args)" = "$(printf -- '--resume\nx')" ] || fail "user args not passed through"
[ ! -e $s/settings.json ] || fail "launcher must not own settings.json"
${full.launchers.codex-work}/bin/codex-work exec hi
M modules/claude.nix => modules/claude.nix +14 -4
@@ 20,6 20,11 @@ in
default = { };
description = "Settings layered over the account's settings.json via --settings.";
};
+ plugins = lib.mkOption {
+ type = lib.types.listOf lib.types.path;
+ default = [ ];
+ description = "Plugin directories, loaded with --plugin-dir. Nothing is installed into the account.";
+ };
};
config.build.agents.claude = lib.mkIf cfg.enable {
@@ 28,9 33,14 @@ in
instructionsFile = "CLAUDE.md";
# Managed links: path relative to the state dir -> store path.
files = { };
- flags = lib.optionals (cfg.settings != { }) [
- "--settings"
- "${settingsFile}"
- ];
+ flags =
+ lib.optionals (cfg.settings != { }) [
+ "--settings"
+ "${settingsFile}"
+ ]
+ ++ lib.concatMap (p: [
+ "--plugin-dir"
+ "${p}"
+ ]) cfg.plugins;
};
}