feat(admin): Administration page — Users tab + Server tab (hardware, per-user CPU/memory/home share)

/users becomes /admin (redirected), a tab shell over the existing Users view
and a new Server tab backed by GET /api/host (server/lib/host-stats.js):
hostname/OS/uptime, CPU and load, memory and swap, every real disk with
HDD/SSD, NVIDIA GPUs, and each user's live share from two /proc samples —
attributed by the member's Linux uid (S3) or, for host processes, by the
inherited AGENTHUB_LANE_ID's workspace owner. Read-only, staff-only (/host
in STAFF_ONLY_PREFIXES), comm names only. Members' tmux card moves to the
Server tab.
This commit is contained in:
2026-10-15 16:33:32 +07:00
parent 758609775f
commit b6b40b0c1b
20 changed files with 1333 additions and 22 deletions
+1
View File
@@ -115,6 +115,7 @@ export const i18nReady = i18n
"splash",
"lanes",
"users",
"admin",
"onboarding",
"artifacts",
],
+37
View File
@@ -0,0 +1,37 @@
{
"title": "Administration",
"description": "Accounts and the server AgentHub runs on.",
"tabs": {
"users": "Users",
"server": "Server"
},
"server": {
"title": "Server",
"uptime": "up {{v}}",
"uptimeDays": "{{d}} d {{h}} h",
"uptimeHours": "{{h}} h {{m}} min",
"cpu": "CPU",
"cores": "{{n}} cores · load {{load}}",
"cpuHelp": "Share of the whole machine: 100% means every core is busy.",
"memory": "Memory",
"swap": "Swap",
"homesDisk": "Homes disk",
"homesDiskHelp": "The disk that holds the users' home folders.",
"free": "free",
"usageTitle": "Usage by user",
"usageHelp": "Live, sampled over {{s}} s. A process counts for a user when it runs as their Linux account or inside one of their workspaces' sessions. Memory is resident (RSS); shared pages count once per process. Click a row for its busiest processes.",
"usageUnavailable": "Per-user usage is read from /proc and is only available on Linux.",
"who": "User",
"processes": "Processes",
"home": "Home",
"sampling": "Sampling…",
"hostGroup": "Host account (AgentHub and other host processes)",
"systemGroup": "System (root and other accounts)",
"disks": "Disks",
"mount": "Mount",
"device": "Device",
"used": "Used",
"homesBadge": "homes",
"gpus": "GPUs"
}
}
+1
View File
@@ -87,5 +87,6 @@
"sidebar": "Sidebar",
"now": "now",
"users": "Users",
"admin": "Administration",
"files": "Files"
}
+37
View File
@@ -0,0 +1,37 @@
{
"title": "Quản trị",
"description": "Tài khoản và máy chủ AgentHub đang chạy.",
"tabs": {
"users": "Người dùng",
"server": "Máy chủ"
},
"server": {
"title": "Máy chủ",
"uptime": "đã chạy {{v}}",
"uptimeDays": "{{d}} ngày {{h}} giờ",
"uptimeHours": "{{h}} giờ {{m}} phút",
"cpu": "CPU",
"cores": "{{n}} lõi · tải {{load}}",
"cpuHelp": "Tỷ lệ trên toàn máy: 100% nghĩa là mọi lõi đều bận.",
"memory": "Bộ nhớ",
"swap": "Swap",
"homesDisk": "Ổ chứa thư mục người dùng",
"homesDiskHelp": "Ổ đĩa chứa thư mục home của các người dùng.",
"free": "trống",
"usageTitle": "Mức sử dụng theo người dùng",
"usageHelp": "Số liệu trực tiếp, lấy mẫu trong {{s}} giây. Một tiến trình được tính cho người dùng khi nó chạy bằng tài khoản Linux của họ hoặc trong một phiên thuộc workspace của họ. Bộ nhớ là RSS; trang nhớ dùng chung được tính cho mỗi tiến trình. Bấm vào một dòng để xem các tiến trình nặng nhất.",
"usageUnavailable": "Mức dùng theo người dùng được đọc từ /proc nên chỉ có trên Linux.",
"who": "Người dùng",
"processes": "Tiến trình",
"home": "Thư mục home",
"sampling": "Đang lấy mẫu…",
"hostGroup": "Tài khoản máy chủ (AgentHub và tiến trình khác của host)",
"systemGroup": "Hệ thống (root và tài khoản khác)",
"disks": "Ổ đĩa",
"mount": "Điểm gắn",
"device": "Thiết bị",
"used": "Đã dùng",
"homesBadge": "home",
"gpus": "GPU"
}
}
+1
View File
@@ -87,5 +87,6 @@
"sidebar": "Thanh bên",
"now": "bây giờ",
"users": "Người dùng",
"admin": "Quản trị",
"files": "Quản lý file"
}