{ hyperhivePackage, hyperhiveFlake, }: { pkgs, lib, config, ... }: let cfg = config.services.hive-c0re; in { options.services.hive-c0re = { enable = lib.mkEnableOption "hive-c0re — hyperhive coordinator daemon"; package = lib.mkOption { type = lib.types.package; default = hyperhivePackage pkgs.stdenv.hostPlatform.system; defaultText = lib.literalExpression "hyperhive.packages.\${system}.default"; description = "Package that provides /bin/hive-c0re."; }; hyperhiveFlake = lib.mkOption { type = lib.types.str; default = hyperhiveFlake; defaultText = lib.literalMD "the flake's own store path"; description = '' URL of the hyperhive flake (no fragment). Inlined into each per-agent `flake.nix` at `inputs.hyperhive.url`. The per-agent flake then pulls `hyperhive.nixosConfigurations.agent-base` to build the container. Defaults to this flake's own store path — only override if you want agents tracking a different ref. ''; }; dashboardPort = lib.mkOption { type = lib.types.port; default = 7000; description = "TCP port the hive-c0re dashboard listens on."; }; operatorPronouns = lib.mkOption { type = lib.types.str; default = "she/her"; example = "they/them"; description = '' Operator pronouns, free text. Threaded into every agent container as the `HIVE_OPERATOR_PRONOUNS` env var; the harness substitutes it into the agent / manager system prompt at boot so claude refers to the operator naturally in third person ("ask her", "tell them", etc.). Changes propagate to running agents on the next `↻ R3BU1LD` — forwards as a meta flake env-var bump, no per-agent approval needed. ''; }; }; config = lib.mkIf cfg.enable { environment.systemPackages = [ cfg.package pkgs.git ]; # Dashboard + per-container web UIs share the host's network namespace and # need their ports reachable. Dashboard: `cfg.dashboardPort` (default 7000). # Manager: 8000. Sub-agents: 8100..8999 (deterministic hash; see # `lifecycle::agent_web_port`). networking.firewall.allowedTCPPorts = [ cfg.dashboardPort 8000 ]; networking.firewall.allowedTCPPortRanges = [ { from = 8100; to = 8999; } ]; systemd.services.hive-c0re = { description = "hyperhive coordinator daemon"; wantedBy = [ "multi-user.target" ]; path = [ pkgs.git "/run/current-system/sw" ]; environment.HYPERHIVE_GIT = "${pkgs.git}/bin/git"; serviceConfig = { ExecStart = "${cfg.package}/bin/hive-c0re --socket /run/hyperhive/host.sock serve --hyperhive-flake ${cfg.hyperhiveFlake} --dashboard-port ${toString cfg.dashboardPort} --operator-pronouns ${lib.escapeShellArg cfg.operatorPronouns}"; Restart = "on-failure"; RestartSec = 2; RuntimeDirectory = "hyperhive"; RuntimeDirectoryMode = "0750"; RuntimeDirectoryPreserve = "yes"; StateDirectory = "hyperhive"; }; }; }; }