PR #16046 added /busy and /verbose hints to the classic CLI and the gateway runner but skipped the Ink TUI (and therefore the dashboard /chat page, which embeds the TUI via PTY). This extends the same latch to the TUI with TUI-native wording. The TUI's busy-input model is not the /busy knob from the CLI — single Enter while busy auto-queues, double Enter on an empty line interrupts. The new busy-input hint teaches THAT gesture instead of telling the user to flip a config that does not apply. Changes: - agent/onboarding.py — add busy_input_hint_tui() + tool_progress_hint_tui() - tui_gateway/server.py — onboarding.claim JSON-RPC (Ink triggers busy hint on enqueue) + _maybe_emit_onboarding_hint helper hooked into _on_tool_complete for the 30s/tool_progress=all path. Same config.yaml latch so each hint fires at most once per install across CLI, gateway, and TUI combined. - ui-tui/src/gatewayTypes.ts — OnboardingClaimResponse + onboarding.hint event - ui-tui/src/app/createGatewayEventHandler.ts — render the hint event as sys() - ui-tui/src/app/useSubmission.ts — claim busy_input_prompt on first busy enqueue - tests/agent/test_onboarding.py — +3 cases for TUI hint shape - tests/tui_gateway/test_protocol.py — +4 cases for onboarding.claim - website/docs/user-guide/tui.md — new 'Interrupting and queueing' section explaining the TUI's double-Enter model and the hints Validation: scripts/run_tests.sh tests/agent/test_onboarding.py \ tests/tui_gateway/test_protocol.py \ tests/gateway/test_busy_session_ack.py -> 66 passed npm --prefix ui-tui run type-check -> clean npm --prefix ui-tui run lint -> clean npm --prefix ui-tui run build -> clean
9.7 KiB
| sidebar_position | title | description |
|---|---|---|
| 2 | TUI | Launch the modern terminal UI for Hermes — mouse-friendly, rich overlays, and non-blocking input. |
TUI
The TUI is the modern front-end for Hermes — a terminal UI backed by the same Python runtime as the Classic CLI. Same agent, same sessions, same slash commands; a cleaner, more responsive surface for interacting with them.
It's the recommended way to run Hermes interactively.
Launch
# Launch the TUI
hermes --tui
# Resume the latest TUI session (falls back to the latest classic session)
hermes --tui -c
hermes --tui --continue
# Resume a specific session by ID or title
hermes --tui -r 20260409_000000_aa11bb
hermes --tui --resume "my t0p session"
# Run source directly — skips the prebuild step (for TUI contributors)
hermes --tui --dev
You can also enable it via env var:
export HERMES_TUI=1
hermes # now uses the TUI
hermes chat # same
The classic CLI remains available as the default. Anything documented in CLI Interface — slash commands, quick commands, skill preloading, personalities, multi-line input, interrupts — works in the TUI identically.
Why the TUI
- Instant first frame — the banner paints before the app finishes loading, so the terminal never feels frozen while Hermes is starting.
- Non-blocking input — type and queue messages before the session is ready. Your first prompt sends the moment the agent comes online.
- Rich overlays — model picker, session picker, approval and clarification prompts all render as modal panels rather than inline flows.
- Live session panel — tools and skills fill in progressively as they initialize.
- Mouse-friendly selection — drag to highlight with a uniform background instead of SGR inverse. Copy with your terminal's normal copy gesture.
- Alternate-screen rendering — differential updates mean no flicker when streaming, no scrollback clutter after you quit.
- Composer affordances — inline paste-collapse for long snippets,
Cmd+V/Ctrl+Vtext paste with clipboard-image fallback, bracketed-paste safety, and image/file-path attachment normalization.
Same skins and personalities apply. Switch mid-session with /skin ares, /personality pirate, and the UI repaints live. See Skins & Themes for the full list of customizable keys and which ones apply to classic vs TUI — the TUI honors the banner palette, UI colors, prompt glyph/color, session display, completion menu, selection bg, tool_prefix, and help_header.
Requirements
- Node.js ≥ 20 — the TUI runs as a subprocess launched from the Python CLI.
hermes doctorverifies this. - TTY — like the classic CLI, piping stdin or running in non-interactive environments falls back to single-query mode.
On first launch Hermes installs the TUI's Node dependencies into ui-tui/node_modules (one-time, a few seconds). Subsequent launches are fast. If you pull a new Hermes version, the TUI bundle is rebuilt automatically when sources are newer than the dist.
External prebuild
Distributions that ship a prebuilt bundle (Nix, system packages) can point Hermes at it:
export HERMES_TUI_DIR=/path/to/prebuilt/ui-tui
hermes --tui
The directory must contain dist/entry.js and an up-to-date node_modules.
Keybindings
Keybindings match the Classic CLI exactly. The only behavioral differences:
- Mouse drag highlights text with a uniform selection background.
Cmd+V/Ctrl+Vfirst tries normal text paste, then falls back to OSC52/native clipboard reads, and finally image attach when the clipboard or pasted payload resolves to an image./terminal-setupinstalls local VS Code / Cursor / Windsurf terminal bindings for betterCmd+Enterand undo/redo parity on macOS.- Slash autocompletion opens as a floating panel with descriptions, not an inline dropdown.
Slash commands
All slash commands work unchanged. A few are TUI-owned — they produce richer output or render as overlays rather than inline panels:
| Command | TUI behavior |
|---|---|
/help |
Overlay with categorized commands, arrow-key navigable |
/sessions |
Modal session picker — preview, title, token totals, resume inline |
/model |
Modal model picker grouped by provider, with cost hints |
/skin |
Live preview — theme change applies as you browse |
/details |
Toggle verbose tool-call details (global or per-section) |
/usage |
Rich token / cost / context panel |
Every other slash command (including installed skills, quick commands, and personality toggles) works identically to the classic CLI. See Slash Commands Reference.
Status line
The TUI's status line tracks agent state in real time:
| Status | Meaning |
|---|---|
starting agent… |
Session ID is live; tools and skills still coming online. You can type — messages queue and send when ready. |
ready |
Agent is idle, accepting input. |
thinking… / running… |
Agent is reasoning or running a tool. |
interrupted |
Current turn was cancelled; press Enter to send again. |
forging session… / resuming… |
Initial connect or --resume handshake. |
The per-skin status-bar colors and thresholds are shared with the classic CLI — see Skins for customization.
Interrupting and queueing
The TUI's busy-input model is different from the classic CLI's display.busy_input_mode knob. There is no mode to configure — both behaviors are always available:
- Single Enter while busy — message is queued and sent as the next turn after the agent finishes.
- Double Enter on an empty line while busy — interrupts the current turn.
- Double Enter on an empty line with queued messages and no running turn — drains the next queued message.
The first time you send a message while the agent is working, the TUI prints a one-time (tip) line explaining the double-Enter gesture. It fires once per install — the same onboarding.seen.busy_input_prompt latch used by the classic CLI and the gateway. Delete that key from ~/.hermes/config.yaml to see the tip again.
Similarly, the first time a tool runs for 30 seconds or longer while you're in the noisiest tool_progress: all mode, the TUI prints a one-time (tip) about /verbose for cycling display modes. Latched under onboarding.seen.tool_progress_prompt.
Configuration
The TUI respects all standard Hermes config: ~/.hermes/config.yaml, profiles, personalities, skins, quick commands, credential pools, memory providers, tool/skill enablement. No TUI-specific config file exists.
A handful of keys tune the TUI surface specifically:
display:
skin: default # any built-in or custom skin
personality: helpful
details_mode: collapsed # hidden | collapsed | expanded — global accordion default
sections: # optional: per-section overrides (any subset)
thinking: expanded # always open
tools: expanded # always open
activity: collapsed # opt back IN to the activity panel (hidden by default)
mouse_tracking: true # disable if your terminal conflicts with mouse reporting
Runtime toggles:
/details [hidden|collapsed|expanded|cycle]— set the global mode/details <section> [hidden|collapsed|expanded|reset]— override one section (sections:thinking,tools,subagents,activity)
Default visibility
The TUI ships with opinionated per-section defaults that stream the turn as a live transcript instead of a wall of chevrons:
thinking— expanded. Reasoning streams inline as the model emits it.tools— expanded. Tool calls and their results render open.subagents— falls through to the globaldetails_mode(collapsed under chevron by default — stays quiet until a delegation actually happens).activity— hidden. Ambient meta (gateway hints, terminal-parity nudges, background notifications) is noise for most day-to-day use. Tool failures still render inline on the failing tool row; ambient errors/warnings surface via a floating-alert backstop when every panel is hidden.
Per-section overrides take precedence over both the section default and the
global details_mode. To reshape the layout:
display.sections.thinking: collapsed— put thinking back under a chevrondisplay.sections.tools: collapsed— put tool calls back under a chevrondisplay.sections.activity: collapsed— opt the activity panel back in/details <section> <mode>at runtime
Anything set explicitly in display.sections wins over the defaults, so
existing configs keep working unchanged.
Sessions
Sessions are shared between the TUI and the classic CLI — both write to the same ~/.hermes/state.db. You can start a session in one, resume in the other. The session picker surfaces sessions from both sources, with a source tag.
See Sessions for lifecycle, search, compression, and export.
Reverting to the classic CLI
Launching hermes (without --tui) stays on the classic CLI. To make a machine prefer the TUI, set HERMES_TUI=1 in your shell profile. To go back, unset it.
If the TUI fails to launch (no Node, missing bundle, TTY issue), Hermes prints a diagnostic and falls back — rather than leaving you stuck.
See also
- CLI Interface — full slash command and keybinding reference (shared)
- Sessions — resume, branch, and history
- Skins & Themes — theme the banner, status bar, and overlays
- Voice Mode — works in both interfaces
- Configuration — all config keys