hermes-agent/web
Harry Riddle a562420383 fix(tui): robust clipboard handling with debug logging and headless detection
Problem: Ctrl+C in Hermes TUI shows 'copied' but clipboard often empty.
Root causes:
- Native Linux tools (xclip, wl-copy) require DISPLAY/WAYLAND_DISPLAY; in
  headless Docker/SSH they fail or hang.
- OSC 52 fallback requires terminal emulator support; when absent, sequence
  is dropped silently.
- Dashboard OSC 52 → Clipboard API path fails due to missing user gesture;
  errors were silently caught.
- User feedback 'copied selection' was shown unconditionally, regardless of
  success.

Solution implemented:
- Short-circuit Linux native clipboard probing when no display server is
  present (no DISPLAY and no WAYLAND_DISPLAY). Avoids futile attempts and
  timeouts.
- Add HERMES_TUI_DEBUG_CLIPBOARD env var (1/true). When set, TUI logs to
  stderr which clipboard path is used, probe results on Linux, and whether
  OSC 52 was emitted. Greatly improves diagnosability.
- Improve dashboard clipboard error handling: replace empty catch blocks
  with console.warn messages for OSC 52 decode/Write failures and direct
  copy/paste errors. Makes browser permission/user-gesture failures visible
  in DevTools.
- Add comprehensive clipboard troubleshooting documentation to README and
  AGENTS, covering OSC 52 verification, tmux config, Docker/headless
  constraints, env vars, dashboard caveats, and fallback strategies.

Technical details:
-  in ui-tui/packages/hermes-ink/src/ink/termio/osc.ts:
  - Early return on Linux if both DISPLAY and WAYLAND_DISPLAY unset.
  - Refactor probe sequence to async  with 500ms timeout,
    caching result; subsequent copies use cached tool immediately.
  - Emit debug logs when HERMES_TUI_DEBUG_CLIPBOARD=1.
-  in ink.tsx: log when OSC 52 not emitted (native
  or tmux path in use) in debug mode.
- : OSC 52 handler and Ctrl+Shift+C handler now
  log warnings to console on Clipboard API rejection with error message.
- Documentation: new 'Clipboard Troubleshooting' section in README; new
  'Clipboard environment variables and pitfalls' subsection in AGENTS.md
  (Known Pitfalls).

Tests: full ui-tui test suite (292 tests) passes; clipboard and OSC tests
unaffected. No breaking changes.

Files changed:
- ui-tui/packages/hermes-ink/src/ink/termio/osc.ts
- ui-tui/packages/hermes-ink/src/ink/ink.tsx
- web/src/pages/ChatPage.tsx
- README.md
- AGENTS.md
- CHANGELOG.md (new)
2026-04-26 05:46:45 -07:00
..
public feat(web): add /api/pty WebSocket bridge to embed TUI in dashboard 2026-04-24 10:51:49 -04:00
src fix(tui): robust clipboard handling with debug logging and headless detection 2026-04-26 05:46:45 -07:00
eslint.config.js feat: web UI dashboard for managing Hermes Agent (#8756) 2026-04-12 22:26:28 -07:00
index.html fix: use grid/cell components 2026-04-19 15:21:57 -04:00
package-lock.json feat(web): add /api/pty WebSocket bridge to embed TUI in dashboard 2026-04-24 10:51:49 -04:00
package.json feat(web): add /api/pty WebSocket bridge to embed TUI in dashboard 2026-04-24 10:51:49 -04:00
README.md feat: web UI dashboard for managing Hermes Agent (#8756) 2026-04-12 22:26:28 -07:00
tsconfig.app.json feat: web UI dashboard for managing Hermes Agent (#8756) 2026-04-12 22:26:28 -07:00
tsconfig.json feat: web UI dashboard for managing Hermes Agent (#8756) 2026-04-12 22:26:28 -07:00
tsconfig.node.json feat: web UI dashboard for managing Hermes Agent (#8756) 2026-04-12 22:26:28 -07:00
vite.config.ts fix: mobile chat in new layout 2026-04-24 12:07:46 -04:00

Hermes Agent — Web UI

Browser-based dashboard for managing Hermes Agent configuration, API keys, and monitoring active sessions.

Stack

  • Vite + React 19 + TypeScript
  • Tailwind CSS v4 with custom dark theme
  • shadcn/ui-style components (hand-rolled, no CLI dependency)

Development

# Start the backend API server
cd ../
python -m hermes_cli.main web --no-open

# In another terminal, start the Vite dev server (with HMR + API proxy)
cd web/
npm run dev

The Vite dev server proxies /api requests to http://127.0.0.1:9119 (the FastAPI backend).

Build

npm run build

This outputs to ../hermes_cli/web_dist/, which the FastAPI server serves as a static SPA. The built assets are included in the Python package via pyproject.toml package-data.

Structure

src/
├── components/ui/   # Reusable UI primitives (Card, Badge, Button, Input, etc.)
├── lib/
│   ├── api.ts       # API client — typed fetch wrappers for all backend endpoints
│   └── utils.ts     # cn() helper for Tailwind class merging
├── pages/
│   ├── StatusPage   # Agent status, active/recent sessions
│   ├── ConfigPage   # Dynamic config editor (reads schema from backend)
│   └── EnvPage      # API key management with save/clear
├── App.tsx          # Main layout and navigation
├── main.tsx         # React entry point
└── index.css        # Tailwind imports and theme variables