nix: split static runtime assets into their own derivation (#555)

Hoists the project's branding/* + hive-ag3nt/prompts/* out of the
rust derivation's src set. Lives as `packages.<system>.assets` (also
exported as `pkgs.hyperhive-assets` via the default overlay).

Output layout:

  $out/share/hyperhive/branding/{hyperhive,agent-configs}.{svg,png}
  $out/share/hyperhive/prompts/{system.md,claude-settings.json}

`agent-configs.png` is rendered at build time from its SVG via
rsvg-convert — same shape as the old `hive-c0re/build.rs` rasteriser,
just hoisted into nix so the librsvg dependency stays *here* instead
of in the rust derivation.

No consumer change yet — the rust binaries still `include_bytes!`
their copies from the in-source paths; later commits in this PR cut
those over to runtime loads from `$HIVE_ASSETS_DIR/share/hyperhive/`.

Why split: `src = ./.;` on the crane derivation invalidates the
cargo cache on every edit to anything in the repo, including
branding tweaks + prompt edits + docs. Splitting these out is the
first step toward dropping the rust src input down to
`craneLib.cleanCargoSource ./.` (the eventual end-state in the
final commit of this PR).
This commit is contained in:
iris 2026-05-29 02:11:54 +02:00 committed by Mara
commit 246dd19390
2 changed files with 87 additions and 0 deletions

View file

@ -106,6 +106,12 @@
frontend = pkgs.callPackage ./nix/frontend.nix {
branding-svg = ./branding/hyperhive.svg;
};
# Static runtime assets the rust binaries read via
# `assets::path()` (#555): branding/* + hive-ag3nt/prompts/*,
# plus the rendered agent-configs.png. Split out of the
# rust derivation so a tweak to e.g. system.md doesn't bust
# the cargo cache.
assets = pkgs.callPackage ./nix/assets.nix { };
# Pre-built per-container system closures. Exposed as packages
# so operators can `nix build .#agent-base-toplevel` (or wire
# them into their host system closure via the
@ -137,6 +143,10 @@
# is applied (manager + agent containers both apply it via
# `mkContainer` further down).
hyperhive-frontend = self.packages.${prev.stdenv.hostPlatform.system}.frontend;
# Static runtime assets (#555). 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;
};
claude-unstable =
final: prev:

77
nix/assets.nix Normal file
View file

@ -0,0 +1,77 @@
{
stdenv,
lib,
librsvg,
}:
# Static assets the rust workspace reads at runtime: the project's
# branding SVG/PNG family + the claude system-prompt template +
# claude-settings JSON. Lives as its own derivation so a tweak to
# branding/agent-configs.svg or hive-ag3nt/prompts/system.md doesn't
# invalidate the rust derivation's cargo cache (closes #555 follow-up
# to #538 — naersk previously paired with `src = ./.;` invalidating
# every rust build on any branding/prompt edit; crane inherited that
# coupling and this split breaks it cleanly).
#
# Output layout:
#
# $out/share/hyperhive/branding/{hyperhive.svg, hyperhive.png,
# agent-configs.svg, agent-configs.png}
# $out/share/hyperhive/prompts/{system.md, claude-settings.json}
#
# The agent-configs PNG is rendered at build time from the SVG via
# rsvg-convert — same shape as the old `hive-c0re/build.rs` rasteriser,
# just hoisted into nix so the librsvg dependency stays *here* instead
# of in the rust derivation's nativeBuildInputs.
stdenv.mkDerivation {
pname = "hyperhive-assets";
version = "0.1.0";
# `src` is intentionally narrow — only branding/ + the hive-ag3nt/prompts/
# subdir, NOT the whole tree. Keeps the input hash decoupled from
# rust source / docs / nix module edits.
srcs = [
../branding
../hive-ag3nt/prompts
];
# `unpackPhase` would normally extract each src to its own dir; we
# just want them side-by-side, so hand-roll a flat copy.
unpackPhase = ''
runHook preUnpack
cp -r ${../branding} branding
cp -r ${../hive-ag3nt/prompts} prompts
chmod -R u+w branding prompts
runHook postUnpack
'';
nativeBuildInputs = [ librsvg ];
# No real build step — just render the agent-configs PNG alongside
# its SVG. 300×300 matches branding/hyperhive.png, which is the size
# Forgejo's avatar endpoint accepts without resampling on upload (the
# same constraint hive-c0re/build.rs encoded).
buildPhase = ''
runHook preBuild
rsvg-convert --width 300 --height 300 \
-o branding/agent-configs.png \
branding/agent-configs.svg
runHook postBuild
'';
installPhase = ''
runHook preInstall
mkdir -p $out/share/hyperhive
cp -r branding $out/share/hyperhive/branding
cp -r prompts $out/share/hyperhive/prompts
runHook postInstall
'';
# Pure data — no executables to fixup, no shared libs to patchelf.
dontFixup = true;
meta = {
description = "hyperhive static assets (branding + claude prompts)";
homepage = "https://forge.darkest.space/hyperhive/hyperhive";
license = lib.licenses.mit;
};
}