,
+ /// Human-readable name for this node, shown in the web UI so multiple
+ /// tabs pointing at different remote hosts are distinguishable. Defaults
+ /// to the machine hostname; overridable via `hk serve --name`.
+ pub node_name: String,
}
diff --git a/crates/hk-web/tests/api_test.rs b/crates/hk-web/tests/api_test.rs
index 5a1f9beb..601c9d21 100644
--- a/crates/hk-web/tests/api_test.rs
+++ b/crates/hk-web/tests/api_test.rs
@@ -17,6 +17,7 @@ fn test_state() -> (WebState, tempfile::TempDir) {
adapters: Arc::new(adapter::all_adapters()),
pending_clones: Arc::new(Mutex::new(HashMap::new())),
token: None,
+ node_name: "test-node".to_string(),
};
(state, tmp)
}
@@ -34,6 +35,29 @@ async fn health_returns_ok() {
assert_eq!(response.status(), StatusCode::OK);
}
+#[tokio::test]
+async fn server_info_returns_node_name() {
+ let (state, _tmp) = test_state();
+ let app = hk_web::router::build_router(state);
+
+ let response = app
+ .oneshot(
+ Request::post("/api/server_info")
+ .header("content-type", "application/json")
+ .body(Body::from("{}"))
+ .unwrap(),
+ )
+ .await
+ .unwrap();
+
+ assert_eq!(response.status(), StatusCode::OK);
+ let body = axum::body::to_bytes(response.into_body(), usize::MAX)
+ .await
+ .unwrap();
+ let value: serde_json::Value = serde_json::from_slice(&body).unwrap();
+ assert_eq!(value["node_name"], "test-node");
+}
+
#[tokio::test]
async fn list_extensions_returns_array() {
let (state, _tmp) = test_state();
diff --git a/src/components/layout/sidebar.tsx b/src/components/layout/sidebar.tsx
index 64ce87ff..a4a3c898 100644
--- a/src/components/layout/sidebar.tsx
+++ b/src/components/layout/sidebar.tsx
@@ -11,6 +11,7 @@ import {
import { useTranslation } from "react-i18next";
import { NavLink } from "react-router-dom";
import { isDesktop } from "@/lib/transport";
+import { useServerInfo } from "@/lib/use-server-info";
import { ScopeSwitcher } from "./scope-switcher";
import { UpdateCard } from "./update-card";
import { WebUpdateCard } from "./web-update-card";
@@ -71,6 +72,7 @@ function SidebarLink({
export function Sidebar() {
const { t } = useTranslation("navigation");
+ const serverInfo = useServerInfo();
return (