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) nixosSystem;
};
in
{
# Build the workspace binaries without running tests. Tests
# are run as a separate check (`checks.cargo-test`) that
# carries the `hyperhive-assets` build input — `hive-ag3nt::
# prompt::tests` reads the production prompt template at test
# runtime through `$HIVE_ASSETS_DIR`, so wiring the env var
# into the build phase here would make the prompt's hash a
# build input of `default` (defeats the asset-split cache goal: a
# prompt edit would still bust the binary derivation, even
# though no .rs file changed). Keeping tests in a separate
# check derivation localises the asset-rebuild blast radius
# to that one check — `nix flake check` still exercises them.
default = craneLib.buildPackage {
# Daemon + harness + MCP server binaries. Excludes hivectl and
# hive-forge which are their own derivations below — so each bin
# is compiled exactly once. `packages.default` joins all three
# via symlinkJoin; no binary is compiled more than once regardless
# of which packages the operator builds together.
#
# Tests are kept in the separate `checks.cargo-test` derivation
# (carries the hyperhive-assets build input for the prompt-template
# assertions in hive-ag3nt::prompt::tests). Keeping them out of the
# binary derivations means a prompt edit doesn't bust the cargo cache.
daemonBins = craneLib.buildPackage {
src = cleanSrc;
inherit cargoArtifacts nativeBuildInputs;
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;
inherit cargoArtifacts;
# `installShellFiles` provides `installShellCompletion` and
# `makeWrapper` provides `wrapProgram` for the postInstall below;
# appended (not in the shared set) so they're build inputs only of
# this binary derivation.
cargoExtraArgs = "--bin hivectl";
pname = "hivectl";
version = "0.1.0";
meta.description = "hyperhive operator CLI";
doCheck = false;
# `installShellFiles` + `makeWrapper` scoped to this derivation
# only — daemon bins don't need them.
nativeBuildInputs = nativeBuildInputs ++ [
pkgs.installShellFiles
pkgs.makeWrapper
];
pname = "hyperhive-workspace";
version = "0.1.0";
meta.description = "hyperhive workspace (hive-c0re, hive-ag3nt, hive-root)";
doCheck = false;
# Ship hivectl shell completions in the package (the binary's own
# `completions <shell>` verb is the single source of truth, so they
# 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.
# Ship shell completions (the binary's own `completions <shell>`
# verb is the single source of truth, so they never drift from
# the actual verbs). Wrap with wireguard-tools so `hivectl wg`
# subcommands work before `swarm.wireguard.enable` is set (wg
# init is the very first setup step). Completion generation runs
# before wrapProgram since wrapProgram renames the real binary.
postInstall = ''
installShellCompletion --cmd hivectl \
--bash <("$out/bin/hivectl" completions bash) \
@ -221,6 +225,38 @@
--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
# $out/{dashboard,agent}/ which the Rust binaries serve via
# tower_http::ServeDir.