2026-03-10 00:51:27 -07:00
|
|
|
|
# ============================================================================
|
|
|
|
|
|
# Hermes Agent — Example Skin Template
|
|
|
|
|
|
# ============================================================================
|
|
|
|
|
|
#
|
|
|
|
|
|
# Copy this file to ~/.hermes/skins/<name>.yaml to create a custom skin.
|
|
|
|
|
|
# All fields are optional — missing values inherit from the default skin.
|
|
|
|
|
|
# Activate with: /skin <name> or display.skin: <name> in config.yaml
|
|
|
|
|
|
#
|
feat(tui): put the kawaii face+verb ticker in the status bar, not the thinking panel
The status bar was showing stale lifecycle text ("running…") while the
face+verb stream flickered through the thinking panel as Python pushed
thinking.delta events. That's backwards — the face ticker is the
primary "I'm alive" signal, it belongs in the status bar; the thinking
panel is for substantive reasoning and tool activity.
Status bar now reads `ui.busy`: when true, renders a local `<FaceTicker>`
cycling FACES × VERBS on a 2.5s interval, unaffected by server events.
When false, the bar shows the actual status string (ready, starting
agent…, interrupted, etc.).
Side effect: `scheduleThinkingStatus` still patches `ui.status` with
Python's face text, but while busy the bar ignores that string and uses
the ticker instead. No server-side changes needed — Python keeps
emitting thinking.delta as a liveness heartbeat, the TUI just doesn't
let it fight the status bar.
2026-04-16 20:14:25 -05:00
|
|
|
|
# Keys are marked:
|
|
|
|
|
|
# (both) — applies to both the classic CLI and the TUI
|
|
|
|
|
|
# (classic) — classic CLI only (see hermes --tui in user-guide/tui.md)
|
|
|
|
|
|
# (tui) — TUI only
|
|
|
|
|
|
#
|
2026-03-10 00:51:27 -07:00
|
|
|
|
# See hermes_cli/skin_engine.py for the full schema reference.
|
|
|
|
|
|
# ============================================================================
|
|
|
|
|
|
|
|
|
|
|
|
# Required: unique skin name (used in /skin command and config)
|
|
|
|
|
|
name: example
|
|
|
|
|
|
description: An example custom skin — copy and modify this template
|
|
|
|
|
|
|
|
|
|
|
|
# ── Colors ──────────────────────────────────────────────────────────────────
|
feat(tui): put the kawaii face+verb ticker in the status bar, not the thinking panel
The status bar was showing stale lifecycle text ("running…") while the
face+verb stream flickered through the thinking panel as Python pushed
thinking.delta events. That's backwards — the face ticker is the
primary "I'm alive" signal, it belongs in the status bar; the thinking
panel is for substantive reasoning and tool activity.
Status bar now reads `ui.busy`: when true, renders a local `<FaceTicker>`
cycling FACES × VERBS on a 2.5s interval, unaffected by server events.
When false, the bar shows the actual status string (ready, starting
agent…, interrupted, etc.).
Side effect: `scheduleThinkingStatus` still patches `ui.status` with
Python's face text, but while busy the bar ignores that string and uses
the ticker instead. No server-side changes needed — Python keeps
emitting thinking.delta as a liveness heartbeat, the TUI just doesn't
let it fight the status bar.
2026-04-16 20:14:25 -05:00
|
|
|
|
# Hex color values. These control the visual palette.
|
2026-03-10 00:51:27 -07:00
|
|
|
|
colors:
|
feat(tui): put the kawaii face+verb ticker in the status bar, not the thinking panel
The status bar was showing stale lifecycle text ("running…") while the
face+verb stream flickered through the thinking panel as Python pushed
thinking.delta events. That's backwards — the face ticker is the
primary "I'm alive" signal, it belongs in the status bar; the thinking
panel is for substantive reasoning and tool activity.
Status bar now reads `ui.busy`: when true, renders a local `<FaceTicker>`
cycling FACES × VERBS on a 2.5s interval, unaffected by server events.
When false, the bar shows the actual status string (ready, starting
agent…, interrupted, etc.).
Side effect: `scheduleThinkingStatus` still patches `ui.status` with
Python's face text, but while busy the bar ignores that string and uses
the ticker instead. No server-side changes needed — Python keeps
emitting thinking.delta as a liveness heartbeat, the TUI just doesn't
let it fight the status bar.
2026-04-16 20:14:25 -05:00
|
|
|
|
# Banner panel (the startup welcome box) — (both)
|
2026-03-10 00:51:27 -07:00
|
|
|
|
banner_border: "#CD7F32" # Panel border
|
|
|
|
|
|
banner_title: "#FFD700" # Panel title text
|
|
|
|
|
|
banner_accent: "#FFBF00" # Section headers (Available Tools, Skills, etc.)
|
|
|
|
|
|
banner_dim: "#B8860B" # Dim/muted text (separators, model info)
|
|
|
|
|
|
banner_text: "#FFF8DC" # Body text (tool names, skill names)
|
|
|
|
|
|
|
feat(tui): put the kawaii face+verb ticker in the status bar, not the thinking panel
The status bar was showing stale lifecycle text ("running…") while the
face+verb stream flickered through the thinking panel as Python pushed
thinking.delta events. That's backwards — the face ticker is the
primary "I'm alive" signal, it belongs in the status bar; the thinking
panel is for substantive reasoning and tool activity.
Status bar now reads `ui.busy`: when true, renders a local `<FaceTicker>`
cycling FACES × VERBS on a 2.5s interval, unaffected by server events.
When false, the bar shows the actual status string (ready, starting
agent…, interrupted, etc.).
Side effect: `scheduleThinkingStatus` still patches `ui.status` with
Python's face text, but while busy the bar ignores that string and uses
the ticker instead. No server-side changes needed — Python keeps
emitting thinking.delta as a liveness heartbeat, the TUI just doesn't
let it fight the status bar.
2026-04-16 20:14:25 -05:00
|
|
|
|
# UI elements — (both)
|
|
|
|
|
|
ui_accent: "#FFBF00" # General accent (falls back to banner_accent)
|
2026-03-10 00:51:27 -07:00
|
|
|
|
ui_label: "#4dd0e1" # Labels
|
|
|
|
|
|
ui_ok: "#4caf50" # Success indicators
|
|
|
|
|
|
ui_error: "#ef5350" # Error indicators
|
|
|
|
|
|
ui_warn: "#ffa726" # Warning indicators
|
|
|
|
|
|
|
|
|
|
|
|
# Input area
|
feat(tui): put the kawaii face+verb ticker in the status bar, not the thinking panel
The status bar was showing stale lifecycle text ("running…") while the
face+verb stream flickered through the thinking panel as Python pushed
thinking.delta events. That's backwards — the face ticker is the
primary "I'm alive" signal, it belongs in the status bar; the thinking
panel is for substantive reasoning and tool activity.
Status bar now reads `ui.busy`: when true, renders a local `<FaceTicker>`
cycling FACES × VERBS on a 2.5s interval, unaffected by server events.
When false, the bar shows the actual status string (ready, starting
agent…, interrupted, etc.).
Side effect: `scheduleThinkingStatus` still patches `ui.status` with
Python's face text, but while busy the bar ignores that string and uses
the ticker instead. No server-side changes needed — Python keeps
emitting thinking.delta as a liveness heartbeat, the TUI just doesn't
let it fight the status bar.
2026-04-16 20:14:25 -05:00
|
|
|
|
prompt: "#FFF8DC" # Prompt text / `❯` glyph color (both)
|
|
|
|
|
|
input_rule: "#CD7F32" # Horizontal rule above input (classic)
|
|
|
|
|
|
|
|
|
|
|
|
# Response box — (classic)
|
|
|
|
|
|
response_border: "#FFD700" # Response box border
|
2026-03-10 00:51:27 -07:00
|
|
|
|
|
feat(tui): put the kawaii face+verb ticker in the status bar, not the thinking panel
The status bar was showing stale lifecycle text ("running…") while the
face+verb stream flickered through the thinking panel as Python pushed
thinking.delta events. That's backwards — the face ticker is the
primary "I'm alive" signal, it belongs in the status bar; the thinking
panel is for substantive reasoning and tool activity.
Status bar now reads `ui.busy`: when true, renders a local `<FaceTicker>`
cycling FACES × VERBS on a 2.5s interval, unaffected by server events.
When false, the bar shows the actual status string (ready, starting
agent…, interrupted, etc.).
Side effect: `scheduleThinkingStatus` still patches `ui.status` with
Python's face text, but while busy the bar ignores that string and uses
the ticker instead. No server-side changes needed — Python keeps
emitting thinking.delta as a liveness heartbeat, the TUI just doesn't
let it fight the status bar.
2026-04-16 20:14:25 -05:00
|
|
|
|
# Session display — (both)
|
|
|
|
|
|
session_label: "#DAA520" # "Session: " label
|
|
|
|
|
|
session_border: "#8B8682" # Session ID text
|
2026-03-10 00:51:27 -07:00
|
|
|
|
|
feat(tui): put the kawaii face+verb ticker in the status bar, not the thinking panel
The status bar was showing stale lifecycle text ("running…") while the
face+verb stream flickered through the thinking panel as Python pushed
thinking.delta events. That's backwards — the face ticker is the
primary "I'm alive" signal, it belongs in the status bar; the thinking
panel is for substantive reasoning and tool activity.
Status bar now reads `ui.busy`: when true, renders a local `<FaceTicker>`
cycling FACES × VERBS on a 2.5s interval, unaffected by server events.
When false, the bar shows the actual status string (ready, starting
agent…, interrupted, etc.).
Side effect: `scheduleThinkingStatus` still patches `ui.status` with
Python's face text, but while busy the bar ignores that string and uses
the ticker instead. No server-side changes needed — Python keeps
emitting thinking.delta as a liveness heartbeat, the TUI just doesn't
let it fight the status bar.
2026-04-16 20:14:25 -05:00
|
|
|
|
# TUI / CLI surfaces — (classic: status bar, voice badge, completion meta)
|
|
|
|
|
|
status_bar_bg: "#1a1a2e" # Status / usage bar background (classic)
|
|
|
|
|
|
voice_status_bg: "#1a1a2e" # Voice-mode badge background (classic)
|
|
|
|
|
|
completion_menu_bg: "#1a1a2e" # Completion list background (both)
|
|
|
|
|
|
completion_menu_current_bg: "#333355" # Active completion row background (both)
|
|
|
|
|
|
completion_menu_meta_bg: "#1a1a2e" # Completion meta column bg (classic)
|
|
|
|
|
|
completion_menu_meta_current_bg: "#333355" # Active meta bg (classic)
|
2026-03-10 00:51:27 -07:00
|
|
|
|
|
feat(tui): put the kawaii face+verb ticker in the status bar, not the thinking panel
The status bar was showing stale lifecycle text ("running…") while the
face+verb stream flickered through the thinking panel as Python pushed
thinking.delta events. That's backwards — the face ticker is the
primary "I'm alive" signal, it belongs in the status bar; the thinking
panel is for substantive reasoning and tool activity.
Status bar now reads `ui.busy`: when true, renders a local `<FaceTicker>`
cycling FACES × VERBS on a 2.5s interval, unaffected by server events.
When false, the bar shows the actual status string (ready, starting
agent…, interrupted, etc.).
Side effect: `scheduleThinkingStatus` still patches `ui.status` with
Python's face text, but while busy the bar ignores that string and uses
the ticker instead. No server-side changes needed — Python keeps
emitting thinking.delta as a liveness heartbeat, the TUI just doesn't
let it fight the status bar.
2026-04-16 20:14:25 -05:00
|
|
|
|
# Drag-to-select background — (tui)
|
|
|
|
|
|
selection_bg: "#3a3a55" # Uniform selection highlight in the TUI
|
2026-04-14 11:59:24 +08:00
|
|
|
|
|
2026-03-10 00:51:27 -07:00
|
|
|
|
# ── Spinner ─────────────────────────────────────────────────────────────────
|
feat(tui): put the kawaii face+verb ticker in the status bar, not the thinking panel
The status bar was showing stale lifecycle text ("running…") while the
face+verb stream flickered through the thinking panel as Python pushed
thinking.delta events. That's backwards — the face ticker is the
primary "I'm alive" signal, it belongs in the status bar; the thinking
panel is for substantive reasoning and tool activity.
Status bar now reads `ui.busy`: when true, renders a local `<FaceTicker>`
cycling FACES × VERBS on a 2.5s interval, unaffected by server events.
When false, the bar shows the actual status string (ready, starting
agent…, interrupted, etc.).
Side effect: `scheduleThinkingStatus` still patches `ui.status` with
Python's face text, but while busy the bar ignores that string and uses
the ticker instead. No server-side changes needed — Python keeps
emitting thinking.delta as a liveness heartbeat, the TUI just doesn't
let it fight the status bar.
2026-04-16 20:14:25 -05:00
|
|
|
|
# (classic) — the TUI uses its own animated indicators; spinner config here
|
|
|
|
|
|
# is only read by the classic prompt_toolkit CLI.
|
2026-03-10 00:51:27 -07:00
|
|
|
|
spinner:
|
|
|
|
|
|
# Faces shown while waiting for the API response
|
|
|
|
|
|
waiting_faces:
|
|
|
|
|
|
- "(。◕‿◕。)"
|
|
|
|
|
|
- "(◕‿◕✿)"
|
|
|
|
|
|
- "٩(◕‿◕。)۶"
|
|
|
|
|
|
|
|
|
|
|
|
# Faces shown during extended thinking/reasoning
|
|
|
|
|
|
thinking_faces:
|
|
|
|
|
|
- "(。•́︿•̀。)"
|
|
|
|
|
|
- "(◔_◔)"
|
|
|
|
|
|
- "(¬‿¬)"
|
|
|
|
|
|
|
|
|
|
|
|
# Verbs used in spinner messages (e.g., "pondering your request...")
|
|
|
|
|
|
thinking_verbs:
|
|
|
|
|
|
- "pondering"
|
|
|
|
|
|
- "contemplating"
|
|
|
|
|
|
- "musing"
|
|
|
|
|
|
- "ruminating"
|
|
|
|
|
|
|
|
|
|
|
|
# Optional: left/right decorations around the spinner
|
|
|
|
|
|
# Each entry is a [left, right] pair. Omit entirely for no wings.
|
|
|
|
|
|
# wings:
|
|
|
|
|
|
# - ["⟪⚔", "⚔⟫"]
|
|
|
|
|
|
# - ["⟪▲", "▲⟫"]
|
|
|
|
|
|
|
|
|
|
|
|
# ── Branding ────────────────────────────────────────────────────────────────
|
feat(tui): put the kawaii face+verb ticker in the status bar, not the thinking panel
The status bar was showing stale lifecycle text ("running…") while the
face+verb stream flickered through the thinking panel as Python pushed
thinking.delta events. That's backwards — the face ticker is the
primary "I'm alive" signal, it belongs in the status bar; the thinking
panel is for substantive reasoning and tool activity.
Status bar now reads `ui.busy`: when true, renders a local `<FaceTicker>`
cycling FACES × VERBS on a 2.5s interval, unaffected by server events.
When false, the bar shows the actual status string (ready, starting
agent…, interrupted, etc.).
Side effect: `scheduleThinkingStatus` still patches `ui.status` with
Python's face text, but while busy the bar ignores that string and uses
the ticker instead. No server-side changes needed — Python keeps
emitting thinking.delta as a liveness heartbeat, the TUI just doesn't
let it fight the status bar.
2026-04-16 20:14:25 -05:00
|
|
|
|
# Text strings used throughout the interface.
|
2026-03-10 00:51:27 -07:00
|
|
|
|
branding:
|
feat(tui): put the kawaii face+verb ticker in the status bar, not the thinking panel
The status bar was showing stale lifecycle text ("running…") while the
face+verb stream flickered through the thinking panel as Python pushed
thinking.delta events. That's backwards — the face ticker is the
primary "I'm alive" signal, it belongs in the status bar; the thinking
panel is for substantive reasoning and tool activity.
Status bar now reads `ui.busy`: when true, renders a local `<FaceTicker>`
cycling FACES × VERBS on a 2.5s interval, unaffected by server events.
When false, the bar shows the actual status string (ready, starting
agent…, interrupted, etc.).
Side effect: `scheduleThinkingStatus` still patches `ui.status` with
Python's face text, but while busy the bar ignores that string and uses
the ticker instead. No server-side changes needed — Python keeps
emitting thinking.delta as a liveness heartbeat, the TUI just doesn't
let it fight the status bar.
2026-04-16 20:14:25 -05:00
|
|
|
|
agent_name: "Hermes Agent" # (both) Banner title, about display
|
|
|
|
|
|
welcome: "Welcome! Type your message or /help for commands." # (both)
|
|
|
|
|
|
goodbye: "Goodbye! ⚕" # (both) Exit message
|
|
|
|
|
|
response_label: " ⚕ Hermes " # (classic) Response box header label
|
|
|
|
|
|
prompt_symbol: "❯ " # (both) Input prompt glyph
|
|
|
|
|
|
help_header: "(^_^)? Available Commands" # (both) /help overlay title
|
2026-03-10 00:51:27 -07:00
|
|
|
|
|
|
|
|
|
|
# ── Tool Output ─────────────────────────────────────────────────────────────
|
feat(tui): put the kawaii face+verb ticker in the status bar, not the thinking panel
The status bar was showing stale lifecycle text ("running…") while the
face+verb stream flickered through the thinking panel as Python pushed
thinking.delta events. That's backwards — the face ticker is the
primary "I'm alive" signal, it belongs in the status bar; the thinking
panel is for substantive reasoning and tool activity.
Status bar now reads `ui.busy`: when true, renders a local `<FaceTicker>`
cycling FACES × VERBS on a 2.5s interval, unaffected by server events.
When false, the bar shows the actual status string (ready, starting
agent…, interrupted, etc.).
Side effect: `scheduleThinkingStatus` still patches `ui.status` with
Python's face text, but while busy the bar ignores that string and uses
the ticker instead. No server-side changes needed — Python keeps
emitting thinking.delta as a liveness heartbeat, the TUI just doesn't
let it fight the status bar.
2026-04-16 20:14:25 -05:00
|
|
|
|
# Character used as the prefix for tool output lines. (both)
|
2026-03-10 00:51:27 -07:00
|
|
|
|
# Default is "┊" (thin dotted vertical line). Some alternatives:
|
|
|
|
|
|
# "╎" (light triple dash vertical)
|
|
|
|
|
|
# "▏" (left one-eighth block)
|
|
|
|
|
|
# "│" (box drawing light vertical)
|
|
|
|
|
|
# "┃" (box drawing heavy vertical)
|
|
|
|
|
|
tool_prefix: "┊"
|