agent: make claudePlugins additive instead of replacing
The base set (skill-creator + base@hyperhive) was declared via the option's `default`, so a per-agent definition of claudePlugins replaced it wholesale. Move the base set to a plain `config` definition instead: a listOf option merges multiple plain definitions by concatenation, so an agent's own list now adds to the base set rather than replacing it, while lib.mkForce / lib.mkOverride on the agent side still replace the whole merged list deliberately (mkDefault was ruled out explicitly). Also de-dup at the JSON-render site with lib.unique, so an agent that names a base-set entry itself doesn't get it installed twice, and reword the option doc, which still claimed the old REPLACES semantics. Four module-eval cases cover the unset / agent-adds / mkForce-replaces / duplicate-entry shapes. Refs #4467
This commit is contained in:
parent
ce3b3d9467
commit
b6e180dfbf
2 changed files with 88 additions and 11 deletions
|
|
@ -697,6 +697,19 @@ let
|
|||
homeserver = "https://matrix.example.invalid";
|
||||
};
|
||||
};
|
||||
# `claudePlugins`'s additive-merge shape: a plain per-agent
|
||||
# definition must ADD to the module's own base-set definition rather than
|
||||
# replacing it, while `lib.mkForce` must still replace the whole list
|
||||
# outright — the two arms below plus the unset default (read directly off
|
||||
# `bare`-shaped `agent { }`, no fixture of its own needed) are the three
|
||||
# cases that shape has to hold.
|
||||
agentPluginsDefault = agent { };
|
||||
agentPluginsAdded = agent { claudePlugins = [ "foo@bar" ]; };
|
||||
agentPluginsForced = agent { claudePlugins = lib.mkForce [ "foo@bar" ]; };
|
||||
# The de-dup arm: an agent that names a base-set entry explicitly must not
|
||||
# get it installed twice.
|
||||
agentPluginsDuplicate = agent { claudePlugins = [ "base@hyperhive" ]; };
|
||||
agentPlugins = machine: machine.services.hyperhive.agent.claudePlugins;
|
||||
agentHarness = machine: machine.systemd.services.hive-agent;
|
||||
agentSubagentDaemon = machine: machine.systemd.services.hive-subagent-daemon;
|
||||
agentBaoIdentity = machine: machine.systemd.services.hive-agent-bao-identity;
|
||||
|
|
@ -2080,6 +2093,51 @@ let
|
|||
# No hive homeserver, so nothing may claim one.
|
||||
&& !(env ? HIVE_MATRIX_URL);
|
||||
}
|
||||
{
|
||||
# Case 1 of the additive-merge shape: an agent that declares
|
||||
# nothing gets exactly the module's base set, no more and no less.
|
||||
name = "an agent with no claudePlugins definition gets exactly the base set";
|
||||
ok =
|
||||
agentPlugins agentPluginsDefault == [
|
||||
"skill-creator@claude-plugins-official"
|
||||
"base@hyperhive"
|
||||
];
|
||||
}
|
||||
{
|
||||
# Case 2: a plain per-agent definition ADDS to the base set (list-typed
|
||||
# options at equal priority concatenate) rather than replacing it —
|
||||
# the property the operator ruling asked for instead of `mkDefault`.
|
||||
# Sorted before comparing: concatenation order between two same-
|
||||
# priority definitions is a module-system implementation detail this
|
||||
# case isn't about — membership and count are.
|
||||
name = "an agent's own claudePlugins definition adds to the base set";
|
||||
ok =
|
||||
builtins.sort builtins.lessThan (agentPlugins agentPluginsAdded) == [
|
||||
"base@hyperhive"
|
||||
"foo@bar"
|
||||
"skill-creator@claude-plugins-official"
|
||||
];
|
||||
}
|
||||
{
|
||||
# Case 3: `lib.mkForce` is still the escape hatch — an operator who
|
||||
# wants the base set gone, not extended, can still say so outright.
|
||||
name = "an agent's mkForce claudePlugins replaces the base set outright";
|
||||
ok = agentPlugins agentPluginsForced == [ "foo@bar" ];
|
||||
}
|
||||
{
|
||||
# De-dup arm: an agent that names a base-set entry itself must not get
|
||||
# it installed twice — `lib.unique` at the JSON-render site, not the
|
||||
# option's merge (the merge is a plain concatenation on purpose, so
|
||||
# the un-deduped list stays readable for `agentPlugins` above).
|
||||
name = "an agent repeating a base-set plugin does not get it installed twice";
|
||||
ok =
|
||||
builtins.sort builtins.lessThan (
|
||||
builtins.fromJSON agentPluginsDuplicate.environment.etc."hyperhive/claude-plugins.json".text
|
||||
) == [
|
||||
"base@hyperhive"
|
||||
"skill-creator@claude-plugins-official"
|
||||
];
|
||||
}
|
||||
{
|
||||
# The doctrine three glue files state, as a property a rewrite has to
|
||||
# keep: a client is defined by holding a certificate the store accepts,
|
||||
|
|
|
|||
Loading…
Reference in a new issue