feat(dashboard): add terminalBackground field to DashboardTheme

Wires the xterm.js terminal pane background color into the theme
system. Previously hardcoded as #0d2626; now reads from
DashboardTheme.terminalBackground with #000000 as default.

Users can override via ~/.hermes/dashboard-themes/*.yaml:
  terminalBackground: "#1a0a2e"
This commit is contained in:
davidgut1982
2026-06-01 20:13:56 -07:00
committed by Teknium
parent f24b7ed9d9
commit fc995634cc
5 changed files with 34 additions and 29 deletions
+22 -5
View File
@@ -36,6 +36,7 @@ import { usePageHeader } from "@/contexts/usePageHeader";
import { useI18n } from "@/i18n";
import { api } from "@/lib/api";
import { PluginSlot } from "@/plugins";
import { useTheme } from "@/themes";
function buildWsUrl(
authParam: [string, string],
@@ -66,8 +67,9 @@ function generateChannelId(): string {
// with cream foreground — we intentionally don't pick monokai or a loud
// theme, because the TUI's skin engine already paints the content; the
// terminal chrome just needs to sit quietly inside the dashboard.
const TERMINAL_THEME = {
background: "#0d2626",
// `background` is omitted here — it's supplied dynamically from the active
// theme's `terminalBackground` field so users can control it via YAML themes.
const TERMINAL_THEME_STATIC = {
foreground: "#f0e6d2",
cursor: "#f0e6d2",
cursorAccent: "#0d2626",
@@ -157,6 +159,13 @@ export default function ChatPage({ isActive = true }: { isActive?: boolean }) {
: false,
);
const { theme } = useTheme();
const terminalBg = theme.terminalBackground ?? "#000000";
const terminalTheme = useMemo(
() => ({ ...TERMINAL_THEME_STATIC, background: terminalBg }),
[terminalBg],
);
// The dashboard keeps ChatPage mounted persistently so the PTY survives tab
// switches. That is great for ordinary /chat navigation, but it means query
// param changes do NOT remount the component. Resume-in-chat from the
@@ -312,7 +321,7 @@ export default function ChatPage({ isActive = true }: { isActive?: boolean }) {
// Browser-embedded chat runs the TUI in inline mode. Keep transcript
// history in xterm.js so the browser wheel can scroll it directly.
scrollback: 5000,
theme: TERMINAL_THEME,
theme: terminalTheme,
});
termRef.current = term;
@@ -721,6 +730,14 @@ export default function ChatPage({ isActive = true }: { isActive?: boolean }) {
};
}, [isActive]);
// Keep the live xterm theme in sync when the active theme's terminal
// background changes (e.g. user switches to a custom YAML theme mid-session).
useEffect(() => {
const term = termRef.current;
if (!term) return;
term.options.theme = { ...TERMINAL_THEME_STATIC, background: terminalBg };
}, [terminalBg]);
// Layout:
// outer flex column — sits inside the dashboard's content area
// row split — terminal pane (flex-1) + sidebar (fixed width, lg+)
@@ -828,7 +845,7 @@ export default function ChatPage({ isActive = true }: { isActive?: boolean }) {
"p-2 sm:p-3",
)}
style={{
backgroundColor: TERMINAL_THEME.background,
backgroundColor: terminalBg,
boxShadow: "0 8px 32px rgba(0, 0, 0, 0.4)",
}}
>
@@ -852,7 +869,7 @@ export default function ChatPage({ isActive = true }: { isActive?: boolean }) {
"bottom-2 right-2 px-2 py-1 text-xs sm:bottom-3 sm:right-3 sm:px-2.5 sm:py-1.5",
"lg:bottom-4 lg:right-4",
)}
style={{ color: TERMINAL_THEME.foreground }}
style={{ color: TERMINAL_THEME_STATIC.foreground }}
>
<span className="inline-flex items-center gap-1.5">
<Copy className="h-3 w-3 shrink-0" />
+6
View File
@@ -297,6 +297,12 @@ function applyTheme(theme: DashboardTheme) {
injectFontStylesheet(theme.typography.fontUrl);
applyCustomCSS(theme.customCSS);
applyLayoutVariant(theme.layoutVariant);
// Terminal background — read by ChatPage via useTheme(); also available as CSS var.
root.style.setProperty(
"--theme-terminal-background",
theme.terminalBackground ?? "#0d2626",
);
}
// ---------------------------------------------------------------------------
+1
View File
@@ -51,6 +51,7 @@ export const defaultTheme: DashboardTheme = {
},
typography: DEFAULT_TYPOGRAPHY,
layout: DEFAULT_LAYOUT,
terminalBackground: "#000000",
};
export const midnightTheme: DashboardTheme = {
+3
View File
@@ -162,6 +162,9 @@ export interface DashboardTheme {
/** Per-component CSS-var overrides. See `ThemeComponentStyles`. */
componentStyles?: ThemeComponentStyles;
colorOverrides?: ThemeColorOverrides;
/** Background color for the embedded terminal pane (xterm.js).
* Hex string. Defaults to `"#0d2626"` when absent. */
terminalBackground?: string;
}
/**