mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-21 03:39:54 +00:00
feat(desktop): theme xterm with active light/dark mode
The right-sidebar terminal hardcoded a light palette, which read poorly on the dark glass surface. Subscribe to `useTheme().resolvedMode` and hot-swap `term.options.theme` so Shift+X (and any other mode change) updates the terminal in place without tearing down the PTY session. Dark mode uses xterm's built-in defaults (white fg/cursor + vivid ANSI 16) with just a transparent background so the glass shows through; light mode keeps the existing hand-tuned overrides for legibility on a bright surface.
This commit is contained in:
@@ -1,14 +1,21 @@
|
||||
import type { Terminal } from '@xterm/xterm'
|
||||
import type { ITheme, Terminal } from '@xterm/xterm'
|
||||
import type { CSSProperties } from 'react'
|
||||
|
||||
export const TERMINAL_THEME = {
|
||||
background: '#00000000',
|
||||
// xterm's defaults (white fg/cursor + vivid ANSI 16) already match a dark
|
||||
// terminal — we just punch the background transparent so the glass shows.
|
||||
// Light mode has no built-in, so hand-tune fg/cursor for a bright surface.
|
||||
const TRANSPARENT_BG: ITheme = { background: '#00000000' }
|
||||
|
||||
const LIGHT_OVERRIDES: ITheme = {
|
||||
cursor: '#6f6f6f',
|
||||
cursorAccent: '#f7f7f7',
|
||||
foreground: '#4d4d4d',
|
||||
selectionBackground: '#8c8c8c33'
|
||||
}
|
||||
|
||||
export const terminalTheme = (mode: 'light' | 'dark'): ITheme =>
|
||||
mode === 'dark' ? TRANSPARENT_BG : { ...TRANSPARENT_BG, ...LIGHT_OVERRIDES }
|
||||
|
||||
export const isMacPlatform = () => navigator.platform.toLowerCase().includes('mac')
|
||||
|
||||
export const addSelectionShortcutLabel = () => (isMacPlatform() ? '⌘L' : 'Ctrl+L')
|
||||
|
||||
@@ -6,13 +6,9 @@ import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import type { CSSProperties } from 'react'
|
||||
|
||||
import { triggerHaptic } from '@/lib/haptics'
|
||||
import { useTheme } from '@/themes/context'
|
||||
|
||||
import {
|
||||
isAddSelectionShortcut,
|
||||
TERMINAL_THEME,
|
||||
terminalSelectionAnchor,
|
||||
terminalSelectionLabel
|
||||
} from './selection'
|
||||
import { isAddSelectionShortcut, terminalSelectionAnchor, terminalSelectionLabel, terminalTheme } from './selection'
|
||||
|
||||
type TerminalStatus = 'closed' | 'open' | 'starting'
|
||||
|
||||
@@ -29,6 +25,8 @@ export function useTerminalSession({ cwd, onAddSelectionToChat }: UseTerminalSes
|
||||
const selectionLabelRef = useRef('')
|
||||
const selectionRef = useRef('')
|
||||
const onAddSelectionToChatRef = useRef(onAddSelectionToChat)
|
||||
const { resolvedMode } = useTheme()
|
||||
const resolvedModeRef = useRef(resolvedMode)
|
||||
const [status, setStatus] = useState<TerminalStatus>('starting')
|
||||
const [selection, setSelection] = useState('')
|
||||
const [selectionStyle, setSelectionStyle] = useState<CSSProperties | null>(null)
|
||||
@@ -38,11 +36,20 @@ export function useTerminalSession({ cwd, onAddSelectionToChat }: UseTerminalSes
|
||||
onAddSelectionToChatRef.current = onAddSelectionToChat
|
||||
}, [onAddSelectionToChat])
|
||||
|
||||
useEffect(() => {
|
||||
resolvedModeRef.current = resolvedMode
|
||||
|
||||
if (termRef.current) {
|
||||
termRef.current.options.theme = terminalTheme(resolvedMode)
|
||||
}
|
||||
}, [resolvedMode])
|
||||
|
||||
const addSelectionToChat = useCallback(() => {
|
||||
const selectedText = selectionRef.current || termRef.current?.getSelection() || ''
|
||||
|
||||
const label =
|
||||
selectionLabelRef.current || (termRef.current ? terminalSelectionLabel(termRef.current, shellNameRef.current, selectedText) : 'selection')
|
||||
selectionLabelRef.current ||
|
||||
(termRef.current ? terminalSelectionLabel(termRef.current, shellNameRef.current, selectedText) : 'selection')
|
||||
|
||||
const trimmed = selectedText.trim()
|
||||
|
||||
@@ -102,7 +109,7 @@ export function useTerminalSession({ cwd, onAddSelectionToChat }: UseTerminalSes
|
||||
lineHeight: 1.12,
|
||||
macOptionIsMeta: true,
|
||||
scrollback: 1000,
|
||||
theme: TERMINAL_THEME
|
||||
theme: terminalTheme(resolvedModeRef.current)
|
||||
})
|
||||
|
||||
const fit = new FitAddon()
|
||||
|
||||
Reference in New Issue
Block a user