diff --git a/flake.nix b/flake.nix index b20c18f9..5309e657 100644 --- a/flake.nix +++ b/flake.nix @@ -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: diff --git a/nix/assets.nix b/nix/assets.nix new file mode 100644 index 00000000..8fc83416 --- /dev/null +++ b/nix/assets.nix @@ -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; + }; +}