mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-30 06:41:51 +00:00
Removes the global `uppercase` + `font-mondwest` from the App.tsx root
that forced every page to opt-out, replaces stacked-alpha text colors
with semantic tokens for WCAG-AA contrast across all 7 themes, and
applies the new `text-display` utility from @nous-research/ui@0.16.0
on intentional brand chrome (page titles, sidebar headings, segmented
filters) only. Bumps every sub-12px arbitrary text size to text-xs.
Also widens the dashboard plugin routes (/api/dashboard/agent-plugins/
{name:path}/...) so category-namespaced plugins like observability/
langfuse and image_gen/openai can be enable/disabled from the dashboard
— previously the FE encodeURIComponent-ed the slash and the backend
{name} route rejected it. _validate_plugin_name still blocks .. and
backslash, and strips leading/trailing slash.
Touches sessions/env/keys page chrome and adds two new i18n keys
(`overview`, `showMore`/`showLess`) across all 18 locales.
Squashes 19 commits from PR #28832.
Co-authored-by: Hermes <noreply@nousresearch.com>
70 lines
2.3 KiB
TypeScript
70 lines
2.3 KiB
TypeScript
import { Link } from "react-router-dom";
|
|
import type { StatusResponse } from "@/lib/api";
|
|
import { useSidebarStatus } from "@/hooks/useSidebarStatus";
|
|
import { cn } from "@/lib/utils";
|
|
import { useI18n } from "@/i18n";
|
|
|
|
/** Gateway + session summary for the System sidebar block (no separate strip chrome). */
|
|
export function SidebarStatusStrip() {
|
|
const status = useSidebarStatus();
|
|
const { t } = useI18n();
|
|
|
|
if (status === null) {
|
|
return (
|
|
<div className="px-5 py-1.5" aria-hidden>
|
|
<div className="h-2 w-[80%] max-w-full animate-pulse rounded-sm bg-midground/10" />
|
|
</div>
|
|
);
|
|
}
|
|
|
|
const gw = gatewayLine(status, t);
|
|
const { activeSessionsLabel, gatewayStatusLabel } = t.app;
|
|
|
|
return (
|
|
<Link
|
|
to="/sessions"
|
|
title={t.app.statusOverview}
|
|
className={cn(
|
|
"block text-left",
|
|
"px-5 pb-2 pt-0.5",
|
|
"text-text-secondary",
|
|
"transition-colors hover:text-midground",
|
|
"focus-visible:outline-none focus-visible:ring-1 focus-visible:ring-midground/40",
|
|
"focus-visible:ring-inset",
|
|
)}
|
|
>
|
|
<div className="flex flex-col gap-1 font-mondwest text-xs leading-snug tracking-[0.08em]">
|
|
<p className="break-words">
|
|
<span className="text-text-tertiary">{gatewayStatusLabel}</span>{" "}
|
|
<span className={cn("font-medium", gw.tone)}>{gw.label}</span>
|
|
</p>
|
|
|
|
<p className="break-words">
|
|
<span className="text-text-tertiary">{activeSessionsLabel}</span>{" "}
|
|
<span className="tabular-nums text-text-secondary">
|
|
{status.active_sessions}
|
|
</span>
|
|
</p>
|
|
</div>
|
|
</Link>
|
|
);
|
|
}
|
|
|
|
function gatewayLine(
|
|
status: StatusResponse,
|
|
t: ReturnType<typeof useI18n>["t"],
|
|
): { label: string; tone: string } {
|
|
const g = t.app.gatewayStrip;
|
|
const byState: Record<string, { label: string; tone: string }> = {
|
|
running: { label: g.running, tone: "text-success" },
|
|
starting: { label: g.starting, tone: "text-warning" },
|
|
startup_failed: { label: g.failed, tone: "text-destructive" },
|
|
stopped: { label: g.stopped, tone: "text-muted-foreground" },
|
|
};
|
|
if (status.gateway_state && byState[status.gateway_state]) {
|
|
return byState[status.gateway_state];
|
|
}
|
|
return status.gateway_running
|
|
? { label: g.running, tone: "text-success" }
|
|
: { label: g.off, tone: "text-muted-foreground" };
|
|
}
|