${title}
' echo 'Auto-generated from the hyperhive flake. Source: nix/docs/default.nix.
' cmark-gfm ${doc.optionsCommonMark} echo '{ pkgs, lib, self, nixosSystem, }: # Options documentation for hyperhive's NixOS module surfaces. # Closes #616. HTML output added per mara on internal-requests #8. # # Three rendering layers: # CommonMark — `pkgs.nixosOptionsDoc.optionsCommonMark`. Source of # truth; kept as `.md` files in the bundle. # HTML — `pkgs.cmark-gfm` over the CommonMark output, wrapped # in a minimal inline-CSS template. Primary surface; the # bundle's `index.html` / `host.html` / `agent.html` are # what the operator's nginx serves from # `hyperhive.darkest.space/options/`. # # Three output trees consumed by `flake.nix`: # docs-host — operator-facing host-module options # (`services.hive-c0re.*`, `hyperhive.{domain,forge,matrix}.*`) # docs-agent — per-agent harness options # (`hyperhive.{model,allowedRecipients,extraMcpServers,…}`) # docs — bundled static site (index + host + agent, .html + .md) # # All asset paths inside the rendered HTML are relative (e.g. # `./host.html`) so the bundle can be mounted at any URL prefix # without rewriting; styles are inline so there's no second-fetch # request for the operator's browser. let # Evaluate the host module under a stub NixOS system. Stubs satisfy # the few hard-required options (filesystems, stateVersion) without # actually enabling the hive — we only want the option *declarations* # to evaluate, not the config. hostEval = nixosSystem { system = pkgs.stdenv.hostPlatform.system; modules = [ self.nixosModules.default ( { lib, ... }: { nixpkgs.overlays = [ self.overlays.default ]; fileSystems."/" = { device = "/dev/null"; fsType = "tmpfs"; }; boot.loader.grub.enable = false; system.stateVersion = "25.11"; # Force-disable every hyperhive subsystem so config evaluation # doesn't pull in heavy build inputs (matrix container, forge, # etc.). Options are still fully declared either way — that's # what nixosOptionsDoc traverses. services.hyperhive.enable = lib.mkForce false; services.hyperhive.forge.enable = lib.mkForce false; services.hyperhive.matrix.enable = lib.mkForce false; services.hyperhive.gateway.enable = lib.mkForce false; } ) ]; }; # Agent options live in the already-evaluated `agent-base` container # config. Reusing it avoids re-evaluating the harness module against # a fresh stub — the options tree is identical to what a real agent # container sees. agentEval = self.nixosConfigurations.agent-base; # Strip the nix-store prefix from option declaration paths and rewrite # them as forge URLs so the rendered docs link back to the source. forgeRoot = "https://forge.darkest.space/hyperhive/hyperhive/src/branch/main"; storePrefix = toString self + "/"; transformOptions = opt: opt // { declarations = map ( decl: let declStr = toString decl; relPath = if lib.hasPrefix storePrefix declStr then lib.removePrefix storePrefix declStr else baseNameOf declStr; in { url = "${forgeRoot}/${relPath}"; name = relPath; } ) opt.declarations; }; # Filter an evaluated `options` tree down to a set of top-level # subtrees we care about. Anything outside the listed roots is # dropped — keeps the rendered docs focused on hyperhive's surface # instead of NixOS's 10k+ default options. pickSubtrees = options: roots: let pick = path: if lib.hasAttrByPath path options then lib.setAttrByPath path (lib.getAttrFromPath path options) else { }; in lib.foldl' lib.recursiveUpdate { } (map pick roots); hostOptions = pickSubtrees hostEval.options [ [ "hyperhive" ] [ "services" "hive-c0re" ] ]; agentOptions = pickSubtrees agentEval.options [ [ "hyperhive" ] ]; hostDoc = pkgs.nixosOptionsDoc { options = hostOptions; inherit transformOptions; }; agentDoc = pkgs.nixosOptionsDoc { options = agentOptions; inherit transformOptions; }; # Plain-markdown page (with a short header). Source of truth; the # HTML version is rendered from this. mkMarkdownPage = name: title: doc: pkgs.runCommand "hyperhive-${name}.md" { } '' { echo "# ${title}" echo echo "" echo cat ${doc.optionsCommonMark} } > $out ''; # Inline-stylesheet, loaded as plain text from `./style.css` so it's # editable with normal CSS tooling (#625). Inlined into every page # so the bundle doesn't depend on a second HTTP fetch — keeps the # `/options/` mount trivial for nginx (no MIME guessing for separate # .css files, no cache-busting needed when this updates). styleCSS = builtins.readFile ./style.css; # HTML page: CommonMark → cmark-gfm → minimal template with inline # CSS + relative-only links. cmark-gfm rather than plain cmark so # any future tables / autolinks Just Work without revisiting. mkHtmlPage = name: title: doc: pkgs.runCommand "hyperhive-${name}.html" { nativeBuildInputs = [ pkgs.cmark-gfm ]; } '' { echo '' echo '' echo '
' echo '' echo '' echo 'Auto-generated from the hyperhive flake. Source: nix/docs/default.nix.
' cmark-gfm ${doc.optionsCommonMark} echo 'Auto-generated from the hyperhive flake. Two reading paths:
' echo 'Options exposed by hyperhive.nixosModules.default to operator host configurations: services.hyperhive.{enable,domain,c0re,forge,matrix,gateway}.*.
Per-agent options declared in nix/templates/harness-base.nix and visible from every agent.nix: hyperhive.model, hyperhive.allowedRecipients, hyperhive.extraMcpServers, hyperhive.frontend.*, hyperhive.forge.*, hyperhive.matrix.*, hyperhive.gui.*.
nix build .#docs # bundled static site (index + host + agent)'
echo 'nix build .#docs-host # host page only (HTML)'
echo 'nix build .#docs-agent # agent page only (HTML)'
echo 'The bundle also ships .md versions of each page (host.md, agent.md) — same content, source-of-truth shape — alongside the HTML.