dashboard: optional matrix GUI static mount at /matrix (#607 v0)
This commit is contained in:
parent
dc99e64b2d
commit
360f2af15f
3 changed files with 69 additions and 0 deletions
|
|
@ -51,6 +51,17 @@ pub async fn serve(port: u16, coord: Arc<Coordinator>) -> Result<()> {
|
|||
);
|
||||
}
|
||||
tracing::info!(static_dir = %static_dir.display(), "dashboard static dir resolved");
|
||||
// Optional matrix-GUI static dist (#607). When `HIVE_MATRIX_GUI_DIR`
|
||||
// is set and the dir exists, mount it at `/matrix/` as a sibling
|
||||
// ServeDir before the SPA fallback. Pre-#15 (nginx front) this
|
||||
// is the simplest way to put fluffychat-web on the same origin as
|
||||
// the dashboard so the operator has matrix chat one tab away.
|
||||
let matrix_gui_dir: Option<PathBuf> = std::env::var_os("HIVE_MATRIX_GUI_DIR")
|
||||
.map(PathBuf::from)
|
||||
.filter(|p| p.is_dir());
|
||||
if let Some(dir) = &matrix_gui_dir {
|
||||
tracing::info!(matrix_gui_dir = %dir.display(), "matrix GUI mount enabled at /matrix");
|
||||
}
|
||||
let app = Router::new()
|
||||
.route("/api/state", get(api_state))
|
||||
.route("/approve/{id}", post(post_approve))
|
||||
|
|
@ -92,6 +103,14 @@ pub async fn serve(port: u16, coord: Arc<Coordinator>) -> Result<()> {
|
|||
// /static/dashboard.css → dist/static/dashboard.css, etc.).
|
||||
.fallback_service(ServeDir::new(&static_dir))
|
||||
.with_state(AppState { coord });
|
||||
// Sibling static mount for the optional matrix GUI dist. Layered
|
||||
// before the SPA fallback so `/matrix/...` resolves there instead
|
||||
// of falling through to the dashboard.
|
||||
let app = if let Some(dir) = matrix_gui_dir {
|
||||
app.nest_service("/matrix", ServeDir::new(dir))
|
||||
} else {
|
||||
app
|
||||
};
|
||||
let addr = SocketAddr::from(([0, 0, 0, 0], port));
|
||||
let listener = bind_with_retry(addr).await?;
|
||||
tracing::info!(%port, "dashboard listening");
|
||||
|
|
@ -223,6 +242,11 @@ struct StateSnapshot {
|
|||
/// links each container's config + each approval's commit into the
|
||||
/// forge's `agent-configs` repos.
|
||||
forge_present: bool,
|
||||
/// Whether the matrix GUI static dist is mounted at `/matrix/`
|
||||
/// (`HIVE_MATRIX_GUI_DIR` set + dir exists). Drives the dashboard's
|
||||
/// `M4TR1X →` tab-strip entry so it doesn't flash a dead link when
|
||||
/// the operator hasn't opted in (#607).
|
||||
matrix_gui_enabled: bool,
|
||||
}
|
||||
|
||||
/// `OpQuestion` + computed `question_refs` / `answer_refs`. Built
|
||||
|
|
@ -415,6 +439,9 @@ async fn api_state(headers: HeaderMap, State(state): State<AppState>) -> axum::J
|
|||
port_conflicts,
|
||||
rebuild_queue: state.coord.rebuild_queue.snapshot(),
|
||||
forge_present: crate::forge::is_present().await,
|
||||
matrix_gui_enabled: std::env::var_os("HIVE_MATRIX_GUI_DIR")
|
||||
.map(PathBuf::from)
|
||||
.is_some_and(|p| p.is_dir()),
|
||||
})
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -220,6 +220,13 @@ in
|
|||
# Agents poll this URL for Forgejo notifications. Derived from
|
||||
# hyperhive.forge.{domain,httpPort} so it tracks forge config changes.
|
||||
HIVE_FORGE_URL = "http://${config.hyperhive.forge.domain}:${toString config.hyperhive.forge.httpPort}";
|
||||
}
|
||||
// lib.optionalAttrs config.hyperhive.matrix.gui.enable {
|
||||
# Optional matrix-GUI static dist mounted at /matrix/ by the
|
||||
# dashboard router (#607 v0). Pre-#15 / pre-nginx-front: this is
|
||||
# the simplest same-origin shape — fluffychat-web ships as a
|
||||
# static dist, no runtime daemon needed.
|
||||
HIVE_MATRIX_GUI_DIR = "${config.hyperhive.matrix.gui.package}";
|
||||
};
|
||||
serviceConfig = {
|
||||
ExecStart = "${cfg.package}/bin/hive-c0re --socket /run/hyperhive/host.sock serve --hyperhive-flake ${cfg.hyperhiveFlake} --dashboard-port ${toString cfg.dashboardPort} --operator-pronouns ${lib.escapeShellArg cfg.operatorPronouns} --context-window-tokens ${lib.escapeShellArg (builtins.toJSON cfg.contextWindowTokens)}";
|
||||
|
|
|
|||
|
|
@ -155,6 +155,41 @@ in
|
|||
registration tokens.
|
||||
'';
|
||||
};
|
||||
|
||||
gui = {
|
||||
enable = lib.mkOption {
|
||||
type = lib.types.bool;
|
||||
default = false;
|
||||
description = ''
|
||||
Mount a matrix web client (default `pkgs.fluffychat-web`) as
|
||||
a static sibling of the dashboard at `/matrix/`, served by
|
||||
hive-c0re's own axum router via the `HIVE_MATRIX_GUI_DIR`
|
||||
env var (#607 v0). Off by default; flip to `true` once the
|
||||
operator wants matrix chat one tab away from the dashboard
|
||||
without standing up a separate gateway.
|
||||
|
||||
Same-origin via hive-c0re is the simplest single-host
|
||||
shape; the post-#15 nginx-front re-root (`https://matrix.''${hyperhive.domain}`)
|
||||
is tracked separately in #609. fluffychat-web supports
|
||||
per-login server pick — point it at the in-host tuwunel URL
|
||||
(`http://localhost:8008` by default) the first time.
|
||||
'';
|
||||
};
|
||||
|
||||
package = lib.mkOption {
|
||||
type = lib.types.package;
|
||||
default = pkgs.fluffychat-web;
|
||||
defaultText = lib.literalExpression "pkgs.fluffychat-web";
|
||||
description = ''
|
||||
Static web client dist to serve at `/matrix/`. Defaults to
|
||||
`pkgs.fluffychat-web` — first-class threads support, e2ee
|
||||
+ voice + spaces, full feature surface in the flutter→web
|
||||
build. Override to swap for `hydrogen-web` (lightest),
|
||||
`cinny` (no threads), `element-web` (heaviest, full
|
||||
features), or an out-of-tree client dist.
|
||||
'';
|
||||
};
|
||||
};
|
||||
};
|
||||
|
||||
config = lib.mkIf cfg.enable {
|
||||
|
|
|
|||
Loading…
Reference in a new issue