//! Resolve the on-disk path to hyperhive's static assets (branding + //! claude prompts). Single source of truth for both the host daemon //! (`hive-c0re`) and the in-container harness (the `hive` binary) so //! they agree on the lookup contract. //! //! At runtime, the path is read from `$HIVE_ASSETS_DIR`. In nix //! builds that env var is set by the `hive-c0re` / `harness-base` modules //! to `${pkgs.hyperhive-assets}/share/hyperhive` (see `nix/assets.nix`). //! For `cargo run` outside nix, set it yourself: //! //! ```sh //! HIVE_ASSETS_DIR=$(pwd)/dev-assets cargo run ... //! ``` //! //! where `dev-assets/` is laid out the same as the nix output: //! //! ```text //! dev-assets/ //! branding/ //! hyperhive.{svg,png} //! agent-configs.{svg,png} //! prompts/ //! system.md //! claude-settings.json //! ``` //! //! A convenience `cargo xtask seed-dev-assets` could materialise this //! by copying `branding/` + `hive-ag3nt/prompts/` + rendering //! `agent-configs.png` via rsvg-convert, but it's intentionally not //! shipped yet — dev setups vary too much for one helper to fit. //! //! Each crate that wants a specific asset goes through one of the //! typed helpers (`branding_svg()`, `prompt_template()`, …) so the //! lookup contract is centralised. Missing files panic at first //! call with a clear "set `HIVE_ASSETS_DIR` + put the file at …" //! message — same failure shape as the old `include_*!` macros //! (which would have failed at compile time, not runtime, but the //! diagnostic value is identical). use std::path::PathBuf; /// Read `$HIVE_ASSETS_DIR`. Panics with a clear remediation message /// when unset — every code path that calls into this module is one /// the binary cannot run without, so a hard early failure is the /// right shape. fn dir() -> PathBuf { match std::env::var("HIVE_ASSETS_DIR") { Ok(v) if !v.is_empty() => PathBuf::from(v), _ => panic!( "HIVE_ASSETS_DIR is not set. Inside the nix-built systemd \ units this is wired automatically from \ `pkgs.hyperhive-assets`; for `cargo run` outside nix, \ set it to a directory laid out like \ `nix/assets.nix`'s output (branding/ + prompts/ \ subdirs). See hive-sh4re/src/assets.rs for the contract.", ), } } /// `$HIVE_ASSETS_DIR/branding/hyperhive.svg` — the project's primary /// mark. Loaded by the per-agent web UI as its default icon /// (`/agents//icon.svg` falls through here when the agent didn't /// override `hyperhive.icon` in its `agent.nix`). #[must_use] pub fn branding_svg() -> PathBuf { dir().join("branding/hyperhive.svg") } /// `$HIVE_ASSETS_DIR/branding/hyperhive.png` — the same mark /// rasterised, used by `hive-c0re::forge::push_avatar` to upload /// the forge org avatar. #[must_use] pub fn core_avatar_png() -> PathBuf { dir().join("branding/hyperhive.png") } /// `$HIVE_ASSETS_DIR/branding/agent-configs.png` — secondary org /// mark for the `agent-configs/` mirror org. Rendered from /// `agent-configs.svg` at asset-build time (was rendered in /// `hive-c0re/build.rs`). #[must_use] pub fn config_org_avatar_png() -> PathBuf { dir().join("branding/agent-configs.png") } /// `$HIVE_ASSETS_DIR/prompts/system.md` — the claude system prompt /// template. `hive-ag3nt::prompt::render` filters the role markers /// inside it per agent / manager flavor. #[must_use] pub fn prompt_template() -> PathBuf { dir().join("prompts/system.md") } /// `$HIVE_ASSETS_DIR/prompts/claude-settings.json` — the static /// `--settings` JSON every claude invocation reads. #[must_use] pub fn claude_settings() -> PathBuf { dir().join("prompts/claude-settings.json") }