hyperhive/flake.nix

190 lines
7.4 KiB
Nix

{
description = "hyperhive multi-Claude-Code-agent orchestration on nixos-containers";
inputs = {
nixpkgs.url = "github:NixOS/nixpkgs/nixos-26.05";
# Crane is stateless — no nixpkgs input to follow; `crane.mkLib
# pkgs` returns the lib at whatever pkgs we pass it (we use the
# project's pinned nixpkgs).
crane.url = "github:ipetkov/crane";
treefmt-nix = {
url = "github:numtide/treefmt-nix";
inputs.nixpkgs.follows = "nixpkgs";
};
};
# Thin entry point — the real logic lives under nix/:
# nix/sources.nix filtered source views (meta-flake + docs inputs)
# nix/rust.nix shared crane wiring (cleanSrc, cargoArtifacts)
# nix/packages/ every package output
# nix/checks.nix flake checks
# nix/devshell.nix dev shell
# nix/treefmt.nix formatter config
# nix/modules/, nix/templates/ the NixOS module + container trees
outputs =
inputs@{
self,
nixpkgs,
crane,
treefmt-nix,
}:
let
inherit (nixpkgs) lib;
systems = [
"aarch64-linux"
"x86_64-linux"
];
sources = import ./nix/sources.nix { inherit lib; };
forAllSystems =
f:
lib.genAttrs systems (
system:
f rec {
inherit system;
pkgs = nixpkgs.legacyPackages.${system};
treefmt-eval = treefmt-nix.lib.evalModule pkgs (import ./nix/treefmt.nix);
craneLib = crane.mkLib pkgs;
rust = import ./nix/rust.nix { inherit pkgs craneLib; };
}
);
in
{
packages = forAllSystems (
{
pkgs,
craneLib,
rust,
...
}:
import ./nix/packages {
inherit
pkgs
craneLib
rust
self
nixpkgs
;
}
);
overlays = {
default = final: prev: {
hyperhive = self.packages.${prev.stdenv.hostPlatform.system}.default;
# Per-binary daemon/harness/MCP-server packages, exposed via the
# overlay so container nix evaluations can depend on exactly the
# bin(s) they need instead of the full `hyperhive` bundle — see
# `packages.<system>.hive-*` and their use in `harness-base.nix`.
hive-c0re = self.packages.${prev.stdenv.hostPlatform.system}.hive-c0re;
hive-priv = self.packages.${prev.stdenv.hostPlatform.system}.hive-priv;
hive-agent = self.packages.${prev.stdenv.hostPlatform.system}.hive-agent;
hive-agent-mcp = self.packages.${prev.stdenv.hostPlatform.system}.hive-agent-mcp;
hive-agent-wake = self.packages.${prev.stdenv.hostPlatform.system}.hive-agent-wake;
hive-bash-daemon = self.packages.${prev.stdenv.hostPlatform.system}.hive-bash-daemon;
hive-bash-mcp = self.packages.${prev.stdenv.hostPlatform.system}.hive-bash-mcp;
hive-matrix-daemon = self.packages.${prev.stdenv.hostPlatform.system}.hive-matrix-daemon;
hive-matrix-mcp = self.packages.${prev.stdenv.hostPlatform.system}.hive-matrix-mcp;
hive-metric = self.packages.${prev.stdenv.hostPlatform.system}.hive-metric;
# Bundled frontend dist (see nix/packages/frontend.nix). Output
# is $out/{dashboard,agent}/; consumers pick the surface they
# need. Exposed via the overlay so containers' nix evaluations
# can reach it as `pkgs.hyperhive-frontend` once the overlay
# is applied (manager + agent containers both apply it via
# `mkContainer` further down).
hyperhive-frontend = self.packages.${prev.stdenv.hostPlatform.system}.frontend;
# Static runtime assets. Exposed alongside the binary
# so the harness module can wire $HIVE_ASSETS_DIR straight
# to `${pkgs.hyperhive-assets}/share/hyperhive`.
hyperhive-assets = self.packages.${prev.stdenv.hostPlatform.system}.assets;
# Standalone docs/ tree (see nix/packages/reference-docs.nix).
# Exposed via the overlay so the harness module can build the
# in-container agent docs dir from it.
hyperhive-docs = self.packages.${prev.stdenv.hostPlatform.system}.reference-docs;
};
};
nixosModules = {
agent-base = ./nix/templates/agent-base.nix;
ruth = ./nix/templates/manager.nix;
# The hive-c0re module wants `pkgs.hyperhive` for its default
# `services.hyperhive.c0re.package`. To avoid making operators apply an
# overlay (which would also pollute their host pkgs with our
# build), we thread the package straight from this flake's
# `packages.<system>.default` via a `hyperhivePackage` argument.
hive-c0re = import ./nix/modules/hive-c0re.nix {
hyperhivePackage = system: self.packages.${system}.default;
hyperhiveFrontend = system: self.packages.${system}.frontend;
hyperhiveAssets = system: self.packages.${system}.assets;
hyperhiveXdgIcons = system: self.packages.${system}.xdg-icons;
hyperhiveFlake = "${sources.hyperhiveFlakeSource}";
# Narrow docs/ source, threaded as its own meta-flake input so
# doc edits don't re-hash the whole flake source.
hyperhiveDocs = "${sources.hyperhiveDocsSource}";
# Per-container toplevels — wired into `system.extraDependencies`
# when `services.hyperhive.c0re.preBuildAgentTemplates` is on so the
# host system closure pre-fetches the heavy build inputs.
# Defined only for x86_64-linux because nixosConfigurations are
# hardcoded to that system; the option's default keeps the
# extra deps gated so aarch64 hosts don't accidentally pull
# them in via cross-build.
agentBaseToplevel = self.packages.x86_64-linux.agent-base-toplevel;
managerToplevel = self.packages.x86_64-linux.ruth-toplevel;
};
hive-ci = ./nix/modules/hive-ci.nix;
hive-forge = ./nix/modules/hive-forge.nix;
# Convenience alias: one import covers the full hyperhive host
# stack (hive-c0re + hive-forge, since hive-c0re already pulls
# in hive-forge). Intended usage:
#
# imports = [ hyperhive.nixosModules.default ];
# services.hyperhive.enable = true;
#
default = self.nixosModules.hive-c0re;
};
nixosConfigurations =
let
mkContainer =
module:
nixpkgs.lib.nixosSystem {
system = "x86_64-linux";
modules = [
module
{
nixpkgs.overlays = [
self.overlays.default
];
}
];
};
in
{
agent-base = mkContainer self.nixosModules.agent-base;
ruth = mkContainer self.nixosModules.ruth;
};
devShells = forAllSystems ({ pkgs, rust, ... }: import ./nix/devshell.nix { inherit pkgs rust; });
formatter = forAllSystems ({ treefmt-eval, ... }: treefmt-eval.config.build.wrapper);
checks = forAllSystems (
{
pkgs,
system,
treefmt-eval,
craneLib,
rust,
...
}:
import ./nix/checks.nix {
inherit
pkgs
craneLib
rust
self
system
treefmt-eval
;
}
);
};
}