diff --git a/flake.nix b/flake.nix index 63818b00..ae0af5ee 100644 --- a/flake.nix +++ b/flake.nix @@ -128,6 +128,7 @@ frontend = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.frontend; assets = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.assets; xdgIcons = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.xdg-icons; + swaggerUiTheme = lib.mkDefault self.packages.${pkgs.stdenv.hostPlatform.system}.swagger-ui-theme; hyperhiveFlake = lib.mkDefault "${sources.hyperhiveFlakeSource}"; # Narrow docs/ source, threaded as its own meta-flake input # so doc edits don't re-hash the whole flake source. diff --git a/hive-c0re/swagger-ui-theme/index.html b/hive-c0re/swagger-ui-theme/index.html index 133dc243..5fd30668 100644 --- a/hive-c0re/swagger-ui-theme/index.html +++ b/hive-c0re/swagger-ui-theme/index.html @@ -1,11 +1,16 @@ - - +
diff --git a/nix/host-modules/hive-c0re/options.nix b/nix/host-modules/hive-c0re/options.nix index bd10cecd..b67c0b6b 100644 --- a/nix/host-modules/hive-c0re/options.nix +++ b/nix/host-modules/hive-c0re/options.nix @@ -65,6 +65,19 @@ processes to their icon. ''; }; + swaggerUiTheme = lib.mkOption { + type = lib.types.package; + defaultText = lib.literalExpression "hyperhive.packages.\${system}.swagger-ui-theme"; + description = '' + Swagger UI re-theme static override files (see + `nix/packages/swagger-ui-theme.nix`; output has `index.html` + + `hyperhive-theme.css`). The hive-gateway module `alias`es these + two files straight from the store over `/api/docs/`, so a theme + tweak is a gateway config change — hive-c0re's own vendored + Swagger UI build is untouched. Override to ship a custom theme + (or the vendored default) without a hive-c0re rebuild. + ''; + }; hyperhiveFlake = lib.mkOption { type = lib.types.str; defaultText = lib.literalMD "the hyperhive flake's own filtered source store path"; diff --git a/nix/host-modules/hive-gateway/default.nix b/nix/host-modules/hive-gateway/default.nix index d23de50d..a2c53f95 100644 --- a/nix/host-modules/hive-gateway/default.nix +++ b/nix/host-modules/hive-gateway/default.nix @@ -24,6 +24,12 @@ let # container's). dashboardDist = "${config.services.hyperhive.c0re.servedFrontend}/dashboard"; + # Swagger UI re-theme static override files — nginx `alias`es these + # straight from the store over `/api/docs/`, so a theme tweak ships + # as a gateway config change (see vhosts.nix's `swaggerThemeLocations` + # and nix/packages/swagger-ui-theme.nix). + swaggerUiTheme = config.services.hyperhive.c0re.swaggerUiTheme; + # Self-signed TLS is the implicit floor: when neither an operator cert # (`tls.certDir`) nor ACME (`tls.acme.enable`) is configured, the gateway # generates + serves a hive-CA-signed leaf (see hive-tls.nix). There is no @@ -261,6 +267,7 @@ in matrixCfg hyperhiveDomain dashboardDist + swaggerUiTheme tlsCert tlsKey ; diff --git a/nix/host-modules/hive-gateway/vhosts.nix b/nix/host-modules/hive-gateway/vhosts.nix index e9fc2370..645d58f9 100644 --- a/nix/host-modules/hive-gateway/vhosts.nix +++ b/nix/host-modules/hive-gateway/vhosts.nix @@ -11,6 +11,7 @@ matrixCfg, hyperhiveDomain, dashboardDist, + swaggerUiTheme, # nix/packages/swagger-ui-theme.nix: has index.html + hyperhive-theme.css errorPages, # ./error-pages.nix: { notFound, unreachable, unauthorized } tlsCert, tlsKey, @@ -304,6 +305,33 @@ let proxyPass = "http://${cfg.upstreamHost}:${toString cfg.upstreamPort}"; }; }; + + # Swagger UI re-theme: exact-match locations `alias`ed straight to + # `swaggerUiTheme`'s store path, nginx-served with no involvement + # from hive-c0re at all. `=` locations win over the `/api/` prefix + # block above regardless of declaration order (nginx's own location- + # matching precedence — exact match beats longest-prefix), so this + # doesn't need to be declared before it. Every OTHER Swagger UI asset + # (bundle.js, openapi.json, favicons, the *vendored* index.html c0re + # would otherwise serve) still falls through `/api/` to c0re's own + # embedded `utoipa-swagger-ui` dist unchanged — only these two exact + # paths are intercepted. A theme tweak is therefore a change to + # `hive-c0re/swagger-ui-theme/` + a gateway container activation, not + # a hive-c0re rebuild+restart. See nix/packages/swagger-ui-theme.nix. + swaggerThemeLocations = { + "= /api/docs/" = { + extraConfig = '' + alias ${swaggerUiTheme}/index.html; + ${dashboardAuth} + ''; + }; + "= /api/docs/hyperhive-theme.css" = { + extraConfig = '' + alias ${swaggerUiTheme}/hyperhive-theme.css; + ${dashboardAuth} + ''; + }; + }; in { # Accept-header SPA map for the matrix GUI only (see docs/gateway.md @@ -325,6 +353,7 @@ in // wellKnownLocations // agentLocations // dashboardProxyLocation + // swaggerThemeLocations // lib.optionalAttrs cfg.auth.enable { # Internal-only target for the 401 error_page above. # `internal` prevents direct client access; `alias` serves diff --git a/nix/packages/default.nix b/nix/packages/default.nix index 29c14b4d..ce53804f 100644 --- a/nix/packages/default.nix +++ b/nix/packages/default.nix @@ -158,6 +158,11 @@ in xdg-icons = pkgs.callPackage ./hive-xdg-icons.nix { hyperhiveSvg = ../../branding/hyperhive.svg; }; + # Swagger UI re-theme static override files — see + # ./swagger-ui-theme.nix. The gateway `alias`es these straight from + # the store; a theme tweak is a gateway config change, not a + # hive-c0re rebuild. + swagger-ui-theme = pkgs.callPackage ./swagger-ui-theme.nix { }; # Pre-built per-container system closures. Exposed as packages # so operators can `nix build .#agent-base-toplevel` (or wire diff --git a/nix/packages/swagger-ui-theme.nix b/nix/packages/swagger-ui-theme.nix new file mode 100644 index 00000000..7e21faa6 --- /dev/null +++ b/nix/packages/swagger-ui-theme.nix @@ -0,0 +1,49 @@ +{ + stdenv, +}: + +# The hand-authored Swagger UI re-theme files (`hive-c0re/swagger-ui- +# theme/`), shipped as a standalone derivation so the gateway can +# `alias` them straight from the nix store instead of hive-c0re's own +# build serving them — see nix/host-modules/hive-gateway/vhosts.nix's +# `swaggerThemeLocations`. This is what lets a CSS tweak ship as a +# gateway config change (activate the gateway container) rather than a +# hive-c0re rebuild+restart: the two files nginx exact-matches +# (`/api/docs/` and `/api/docs/hyperhive-theme.css`) come from here; +# every other Swagger UI asset (bundle.js, openapi.json, favicons, …) +# still falls through the existing `/api/` prefix proxy to hive-c0re's +# own vendored (unthemed) `utoipa-swagger-ui` embed, unchanged. +# +# Pure data: copied verbatim, no build step. +# +# Output layout: +# $out/index.html — themed index.html Swagger UI page +# $out/hyperhive-theme.css — the re-theme, consumes --baseNN vars +# from the dashboard's own colors.css +# (loaded via an absolute /static/ +# colors.css , same origin) + +stdenv.mkDerivation { + pname = "hyperhive-swagger-ui-theme"; + version = "0.1.0"; + # Narrow src keeps this derivation's input hash decoupled from the + # rest of the tree — a theme tweak only re-hashes this. + src = ../../hive-c0re/swagger-ui-theme; + + dontBuild = true; + dontConfigure = true; + + installPhase = '' + runHook preInstall + mkdir -p $out + cp -r ./* $out/ + runHook postInstall + ''; + + dontFixup = true; + + meta = { + description = "hyperhive Swagger UI Catppuccin Mocha re-theme (static override files)"; + homepage = "https://forge.darkest.space/hyperhive/hyperhive"; + }; +}