mirror of
https://github.com/NousResearch/hermes-agent.git
synced 2026-05-08 03:01:47 +00:00
fix(tui): honor skin highlight colors (#20895)
This commit is contained in:
parent
da6019820a
commit
f1a8e99942
5 changed files with 61 additions and 6 deletions
|
|
@ -42,6 +42,7 @@ All fields are optional. Missing values inherit from the ``default`` skin.
|
||||||
session_border: "#8B8682" # Session ID dim color
|
session_border: "#8B8682" # Session ID dim color
|
||||||
status_bar_bg: "#1a1a2e" # TUI status/usage bar background
|
status_bar_bg: "#1a1a2e" # TUI status/usage bar background
|
||||||
voice_status_bg: "#1a1a2e" # TUI voice status background
|
voice_status_bg: "#1a1a2e" # TUI voice status background
|
||||||
|
selection_bg: "#333355" # TUI mouse-selection highlight background
|
||||||
completion_menu_bg: "#1a1a2e" # Completion menu background
|
completion_menu_bg: "#1a1a2e" # Completion menu background
|
||||||
completion_menu_current_bg: "#333355" # Active completion row background
|
completion_menu_current_bg: "#333355" # Active completion row background
|
||||||
completion_menu_meta_bg: "#1a1a2e" # Completion meta column background
|
completion_menu_meta_bg: "#1a1a2e" # Completion meta column background
|
||||||
|
|
|
||||||
|
|
@ -209,6 +209,34 @@ describe('fromSkin', () => {
|
||||||
expect(theme.color.completionCurrentBg).toBe('#bfbfbf')
|
expect(theme.color.completionCurrentBg).toBe('#bfbfbf')
|
||||||
})
|
})
|
||||||
|
|
||||||
|
it('uses active completion color as the selection highlight fallback', async () => {
|
||||||
|
const { fromSkin } = await importThemeWithCleanEnv()
|
||||||
|
|
||||||
|
const theme = fromSkin({ completion_menu_current_bg: '#123456' }, {})
|
||||||
|
|
||||||
|
expect(theme.color.selectionBg).toBe('#123456')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('maps completion meta background colors from skins', async () => {
|
||||||
|
const { fromSkin } = await importThemeWithCleanEnv()
|
||||||
|
|
||||||
|
const theme = fromSkin({
|
||||||
|
completion_menu_meta_bg: '#111111',
|
||||||
|
completion_menu_meta_current_bg: '#222222'
|
||||||
|
}, {})
|
||||||
|
|
||||||
|
expect(theme.color.completionMetaBg).toBe('#111111')
|
||||||
|
expect(theme.color.completionMetaCurrentBg).toBe('#222222')
|
||||||
|
})
|
||||||
|
|
||||||
|
it('lets selection_bg override completion highlight colors', async () => {
|
||||||
|
const { fromSkin } = await importThemeWithCleanEnv()
|
||||||
|
|
||||||
|
const theme = fromSkin({ completion_menu_current_bg: '#123456', selection_bg: '#654321' }, {})
|
||||||
|
|
||||||
|
expect(theme.color.selectionBg).toBe('#654321')
|
||||||
|
})
|
||||||
|
|
||||||
it('overrides branding', async () => {
|
it('overrides branding', async () => {
|
||||||
const { fromSkin } = await importThemeWithCleanEnv()
|
const { fromSkin } = await importThemeWithCleanEnv()
|
||||||
const { brand } = fromSkin({}, { agent_name: 'TestBot', prompt_symbol: '$' })
|
const { brand } = fromSkin({}, { agent_name: 'TestBot', prompt_symbol: '$' })
|
||||||
|
|
|
||||||
|
|
@ -182,7 +182,7 @@ export function FloatingOverlays({
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<Box
|
<Box
|
||||||
backgroundColor={active ? theme.color.completionCurrentBg : undefined}
|
backgroundColor={active ? theme.color.completionCurrentBg : theme.color.completionBg}
|
||||||
flexDirection="row"
|
flexDirection="row"
|
||||||
key={`${start + i}:${item.text}:${item.display}:${item.meta ?? ''}`}
|
key={`${start + i}:${item.text}:${item.display}:${item.meta ?? ''}`}
|
||||||
width="100%"
|
width="100%"
|
||||||
|
|
@ -191,7 +191,15 @@ export function FloatingOverlays({
|
||||||
{' '}
|
{' '}
|
||||||
{item.display}
|
{item.display}
|
||||||
</Text>
|
</Text>
|
||||||
{item.meta ? <Text color={theme.color.muted}> {item.meta}</Text> : null}
|
{item.meta ? (
|
||||||
|
<Text
|
||||||
|
backgroundColor={active ? theme.color.completionMetaCurrentBg : theme.color.completionMetaBg}
|
||||||
|
color={theme.color.muted}
|
||||||
|
>
|
||||||
|
{' '}
|
||||||
|
{item.meta}
|
||||||
|
</Text>
|
||||||
|
) : null}
|
||||||
</Box>
|
</Box>
|
||||||
)
|
)
|
||||||
})}
|
})}
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,8 @@ export interface ThemeColors {
|
||||||
muted: string
|
muted: string
|
||||||
completionBg: string
|
completionBg: string
|
||||||
completionCurrentBg: string
|
completionCurrentBg: string
|
||||||
|
completionMetaBg: string
|
||||||
|
completionMetaCurrentBg: string
|
||||||
|
|
||||||
label: string
|
label: string
|
||||||
ok: string
|
ok: string
|
||||||
|
|
@ -264,8 +266,10 @@ export const DARK_THEME: Theme = {
|
||||||
// new value sits ~60% luminance — readable without losing the "muted /
|
// new value sits ~60% luminance — readable without losing the "muted /
|
||||||
// secondary" semantic. Field labels still use `label` (65%) which
|
// secondary" semantic. Field labels still use `label` (65%) which
|
||||||
// stays brighter so hierarchy holds.
|
// stays brighter so hierarchy holds.
|
||||||
completionBg: '#FFFFFF',
|
completionBg: '#1a1a2e',
|
||||||
completionCurrentBg: mix('#FFFFFF', '#FFBF00', 0.25),
|
completionCurrentBg: '#333355',
|
||||||
|
completionMetaBg: '#1a1a2e',
|
||||||
|
completionMetaCurrentBg: '#333355',
|
||||||
|
|
||||||
label: '#DAA520',
|
label: '#DAA520',
|
||||||
ok: '#4caf50',
|
ok: '#4caf50',
|
||||||
|
|
@ -312,6 +316,8 @@ export const LIGHT_THEME: Theme = {
|
||||||
muted: '#7A5A0F',
|
muted: '#7A5A0F',
|
||||||
completionBg: '#F5F5F5',
|
completionBg: '#F5F5F5',
|
||||||
completionCurrentBg: mix('#F5F5F5', '#A0651C', 0.25),
|
completionCurrentBg: mix('#F5F5F5', '#A0651C', 0.25),
|
||||||
|
completionMetaBg: '#F5F5F5',
|
||||||
|
completionMetaCurrentBg: mix('#F5F5F5', '#A0651C', 0.25),
|
||||||
|
|
||||||
label: '#7A5A0F',
|
label: '#7A5A0F',
|
||||||
ok: '#2E7D32',
|
ok: '#2E7D32',
|
||||||
|
|
@ -517,12 +523,20 @@ export function fromSkin(
|
||||||
): Theme {
|
): Theme {
|
||||||
const d = DEFAULT_THEME
|
const d = DEFAULT_THEME
|
||||||
const c = (k: string) => colors[k]
|
const c = (k: string) => colors[k]
|
||||||
|
const hasSkinColors = Object.keys(colors).length > 0
|
||||||
|
|
||||||
const accent = c('ui_accent') ?? c('banner_accent') ?? d.color.accent
|
const accent = c('ui_accent') ?? c('banner_accent') ?? d.color.accent
|
||||||
const bannerAccent = c('banner_accent') ?? c('banner_title') ?? d.color.accent
|
const bannerAccent = c('banner_accent') ?? c('banner_title') ?? d.color.accent
|
||||||
const muted = c('banner_dim') ?? d.color.muted
|
const muted = c('banner_dim') ?? d.color.muted
|
||||||
const completionBg = c('completion_menu_bg') ?? d.color.completionBg
|
const completionBg = c('completion_menu_bg') ?? d.color.completionBg
|
||||||
|
|
||||||
|
const completionCurrentBg =
|
||||||
|
c('completion_menu_current_bg') ??
|
||||||
|
(hasSkinColors ? mix(completionBg, bannerAccent, 0.25) : d.color.completionCurrentBg)
|
||||||
|
|
||||||
|
const completionMetaBg = c('completion_menu_meta_bg') ?? completionBg
|
||||||
|
const completionMetaCurrentBg = c('completion_menu_meta_current_bg') ?? completionCurrentBg
|
||||||
|
|
||||||
return normalizeThemeForAnsiLightTerminal({
|
return normalizeThemeForAnsiLightTerminal({
|
||||||
color: {
|
color: {
|
||||||
primary: c('ui_primary') ?? c('banner_title') ?? d.color.primary,
|
primary: c('ui_primary') ?? c('banner_title') ?? d.color.primary,
|
||||||
|
|
@ -531,7 +545,9 @@ export function fromSkin(
|
||||||
text: c('ui_text') ?? c('banner_text') ?? d.color.text,
|
text: c('ui_text') ?? c('banner_text') ?? d.color.text,
|
||||||
muted,
|
muted,
|
||||||
completionBg,
|
completionBg,
|
||||||
completionCurrentBg: c('completion_menu_current_bg') ?? mix(completionBg, bannerAccent, 0.25),
|
completionCurrentBg,
|
||||||
|
completionMetaBg,
|
||||||
|
completionMetaCurrentBg,
|
||||||
|
|
||||||
label: c('ui_label') ?? d.color.label,
|
label: c('ui_label') ?? d.color.label,
|
||||||
ok: c('ui_ok') ?? d.color.ok,
|
ok: c('ui_ok') ?? d.color.ok,
|
||||||
|
|
@ -548,7 +564,7 @@ export function fromSkin(
|
||||||
statusWarn: c('ui_warn') ?? d.color.statusWarn,
|
statusWarn: c('ui_warn') ?? d.color.statusWarn,
|
||||||
statusBad: d.color.statusBad,
|
statusBad: d.color.statusBad,
|
||||||
statusCritical: d.color.statusCritical,
|
statusCritical: d.color.statusCritical,
|
||||||
selectionBg: c('selection_bg') ?? d.color.selectionBg,
|
selectionBg: c('selection_bg') ?? c('completion_menu_current_bg') ?? (hasSkinColors ? completionCurrentBg : d.color.selectionBg),
|
||||||
|
|
||||||
diffAdded: d.color.diffAdded,
|
diffAdded: d.color.diffAdded,
|
||||||
diffRemoved: d.color.diffRemoved,
|
diffRemoved: d.color.diffRemoved,
|
||||||
|
|
|
||||||
|
|
@ -67,6 +67,7 @@ Controls all color values throughout the CLI. Values are hex color strings.
|
||||||
| `session_border` | Session ID dim border color | `#8B8682` |
|
| `session_border` | Session ID dim border color | `#8B8682` |
|
||||||
| `status_bar_bg` | Background color for the TUI status / usage bar | `#1a1a2e` |
|
| `status_bar_bg` | Background color for the TUI status / usage bar | `#1a1a2e` |
|
||||||
| `voice_status_bg` | Background color for the voice-mode status badge | `#1a1a2e` |
|
| `voice_status_bg` | Background color for the voice-mode status badge | `#1a1a2e` |
|
||||||
|
| `selection_bg` | Background color for the TUI mouse-selection highlighter. Falls back to `completion_menu_current_bg` when unset. | `#333355` |
|
||||||
| `completion_menu_bg` | Background color for the completion menu list | `#1a1a2e` |
|
| `completion_menu_bg` | Background color for the completion menu list | `#1a1a2e` |
|
||||||
| `completion_menu_current_bg` | Background color for the active completion row | `#333355` |
|
| `completion_menu_current_bg` | Background color for the active completion row | `#333355` |
|
||||||
| `completion_menu_meta_bg` | Background color for the completion meta column | `#1a1a2e` |
|
| `completion_menu_meta_bg` | Background color for the completion meta column | `#1a1a2e` |
|
||||||
|
|
@ -139,6 +140,7 @@ colors:
|
||||||
session_border: "#8B8682"
|
session_border: "#8B8682"
|
||||||
status_bar_bg: "#1a1a2e"
|
status_bar_bg: "#1a1a2e"
|
||||||
voice_status_bg: "#1a1a2e"
|
voice_status_bg: "#1a1a2e"
|
||||||
|
selection_bg: "#333355"
|
||||||
completion_menu_bg: "#1a1a2e"
|
completion_menu_bg: "#1a1a2e"
|
||||||
completion_menu_current_bg: "#333355"
|
completion_menu_current_bg: "#333355"
|
||||||
completion_menu_meta_bg: "#1a1a2e"
|
completion_menu_meta_bg: "#1a1a2e"
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue