Compare commits

..
Author SHA1 Message Date
atlas
01db1af346 feat(#2280): add --bin hive-metric to daemonBins — hive-metric now on main 2026-07-10 21:32:12 +02:00
atlas
2f16f0e438 fix(#2280): add nativeBuildInputs to daemonBins + hiveForgePkg — sqlite/pkg-config 2026-07-10 21:31:38 +02:00
atlas
4a9aff584e refactor(#2280): packages.default = symlinkJoin — one rustc per bin, no double builds
Each binary now has its own derivation (daemonBins for hive-c0re/hive-ag3nt/MCP
servers, hivectlPkg, hiveForgePkg), all sharing cargoArtifacts for a single
rustc compilation. packages.default = pkgs.symlinkJoin assembles them without
any additional compilation — no rustc is invoked more than once regardless of
which packages the operator builds together.

NixOS module consumers (pkgs.hyperhive = packages.default) are unaffected:
symlinkJoin exposes all binaries at the same /bin/ paths.
2026-07-10 21:31:38 +02:00
atlas
c1ffa12a99 feat(#2280): packages.hivectl and packages.hive-forge — single-bin splits
Operators who only want hivectl or hive-forge can now add:
  inputs.hyperhive.packages.${system}.hivectl
  inputs.hyperhive.packages.${system}.hive-forge
to their environment.systemPackages without pulling the full
workspace (hive-c0re daemon, hive-ag3nt harness, etc.) into PATH.

Both reuse the shared cargoArtifacts so there is no extra compile
cost when both packages and the default workspace are built together.

packages.hivectl carries the shell completions and the wireguard-tools
wrapper identical to what packages.default ships for hivectl.
packages.hive-forge is a lean CLI-only build.
2026-07-10 21:31:38 +02:00

106
flake.nix
View file

@ -171,47 +171,51 @@
inherit (nixpkgs) lib; inherit (nixpkgs) lib;
inherit (nixpkgs.lib) nixosSystem; inherit (nixpkgs.lib) nixosSystem;
}; };
in # Daemon + harness + MCP server binaries. Excludes hivectl and
{ # hive-forge which are their own derivations below — so each bin
# Build the workspace binaries without running tests. Tests # is compiled exactly once. `packages.default` joins all three
# are run as a separate check (`checks.cargo-test`) that # via symlinkJoin; no binary is compiled more than once regardless
# carries the `hyperhive-assets` build input — `hive-ag3nt:: # of which packages the operator builds together.
# prompt::tests` reads the production prompt template at test #
# runtime through `$HIVE_ASSETS_DIR`, so wiring the env var # Tests are kept in the separate `checks.cargo-test` derivation
# into the build phase here would make the prompt's hash a # (carries the hyperhive-assets build input for the prompt-template
# build input of `default` (defeats the asset-split cache goal: a # assertions in hive-ag3nt::prompt::tests). Keeping them out of the
# prompt edit would still bust the binary derivation, even # binary derivations means a prompt edit doesn't bust the cargo cache.
# though no .rs file changed). Keeping tests in a separate daemonBins = craneLib.buildPackage {
# check derivation localises the asset-rebuild blast radius src = cleanSrc;
# to that one check — `nix flake check` still exercises them. inherit cargoArtifacts nativeBuildInputs;
default = craneLib.buildPackage { cargoExtraArgs = "--bin hive-c0re --bin hive-agent --bin hive-agent-mcp --bin hive-agent-wake --bin hive-bash-daemon --bin hive-bash-mcp --bin hive-matrix-daemon --bin hive-matrix-mcp --bin hive-metric";
pname = "hyperhive-daemon";
version = "0.1.0";
meta.description = "hyperhive daemon + agent harness + bash/matrix MCP servers";
doCheck = false;
};
# Operator CLI — ships `hivectl` (with shell completions and the
# `wg` wrapper) without the daemon binaries. Suitable for
# `nix profile install .#hivectl` / `environment.systemPackages
# = [ inputs.hyperhive.packages.${system}.hivectl ]` when the
# operator only wants the admin CLI. Shares `cargoArtifacts` with
# `daemonBins` so there is no double-rustc cost.
hivectlPkg = craneLib.buildPackage {
src = cleanSrc; src = cleanSrc;
inherit cargoArtifacts; inherit cargoArtifacts;
# `installShellFiles` provides `installShellCompletion` and cargoExtraArgs = "--bin hivectl";
# `makeWrapper` provides `wrapProgram` for the postInstall below; pname = "hivectl";
# appended (not in the shared set) so they're build inputs only of version = "0.1.0";
# this binary derivation. meta.description = "hyperhive operator CLI";
doCheck = false;
# `installShellFiles` + `makeWrapper` scoped to this derivation
# only — daemon bins don't need them.
nativeBuildInputs = nativeBuildInputs ++ [ nativeBuildInputs = nativeBuildInputs ++ [
pkgs.installShellFiles pkgs.installShellFiles
pkgs.makeWrapper pkgs.makeWrapper
]; ];
pname = "hyperhive-workspace"; # Ship shell completions (the binary's own `completions <shell>`
version = "0.1.0"; # verb is the single source of truth, so they never drift from
meta.description = "hyperhive workspace (hive-c0re, hive-ag3nt, hive-root)"; # the actual verbs). Wrap with wireguard-tools so `hivectl wg`
doCheck = false; # subcommands work before `swarm.wireguard.enable` is set (wg
# Ship hivectl shell completions in the package (the binary's own # init is the very first setup step). Completion generation runs
# `completions <shell>` verb is the single source of truth, so they # before wrapProgram since wrapProgram renames the real binary.
# never drift from the actual verbs). Lands at
# `$out/share/{zsh/site-functions,bash-completion,fish}/…`; an
# operator gets working completion as soon as hivectl is in their
# system/user profile with the shell's completion enabled.
#
# Then wrap hivectl with `wireguard-tools` on PATH so its `wg`
# subcommands (`wg init`/`peer`/`status`) work even before the
# WireGuard mesh is configured — `wg init` is the *first* setup
# step, run before `swarm.wireguard.enable` (which would otherwise
# be what pulls wireguard-tools onto the system). Completion
# generation runs first since wrapProgram renames the real binary.
postInstall = '' postInstall = ''
installShellCompletion --cmd hivectl \ installShellCompletion --cmd hivectl \
--bash <("$out/bin/hivectl" completions bash) \ --bash <("$out/bin/hivectl" completions bash) \
@ -221,6 +225,38 @@
--prefix PATH : ${pkgs.wireguard-tools}/bin --prefix PATH : ${pkgs.wireguard-tools}/bin
''; '';
}; };
# Forgejo CLI — ships `hive-forge` without the rest of the
# workspace. Useful for operator workstations / CI environments
# that only need forge access. Shares `cargoArtifacts` with
# `daemonBins`.
hiveForgePkg = craneLib.buildPackage {
src = cleanSrc;
inherit cargoArtifacts nativeBuildInputs;
cargoExtraArgs = "--bin hive-forge";
pname = "hive-forge";
version = "0.1.0";
meta.description = "hyperhive Forgejo CLI";
doCheck = false;
};
in
{
# All workspace binaries in one derivation via symlinkJoin.
# Each binary is compiled exactly once (one rustc per bin, all
# sharing `cargoArtifacts`); symlinkJoin assembles the outputs
# without any additional compilation. The NixOS module's
# `pkgs.hyperhive` (= this) and `nix build .#` both land here.
default = pkgs.symlinkJoin {
name = "hyperhive";
paths = [
daemonBins
hivectlPkg
hiveForgePkg
];
};
# Per-bin split packages — useful for operator workstations that
# only want the CLI(s) without the daemon binaries.
hivectl = hivectlPkg;
hive-forge = hiveForgePkg;
# Bundled browser assets — see ./nix/frontend.nix. Output is # Bundled browser assets — see ./nix/frontend.nix. Output is
# $out/{dashboard,agent}/ which the Rust binaries serve via # $out/{dashboard,agent}/ which the Rust binaries serve via
# tower_http::ServeDir. # tower_http::ServeDir.