hermes-hudui-consciousness-monitor

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Hermes HUD Web UI Skill

Hermes HUD Web UI Skill

Skill by ara.so — Hermes Skills collection.
Skill by ara.so — Hermes Skills collection.

Overview

概述

Hermes HUD Web UI is a browser-based consciousness monitor for Hermes, the AI agent with persistent memory. It provides 18 tabs covering executive dashboard, identity, memory, skills, sessions, health diagnostics, costs, model analytics, gateway control, plugin management, and live chat. The UI updates in real-time via WebSocket and reads from the same
~/.hermes/
data directory as the Hermes agent.
Key Features:
  • Real-time monitoring of agent memory, sessions, and health
  • Cost and token analytics per model
  • Gateway managed-tool visibility (web search, image generation, TTS, browser automation)
  • Hermes Replay: export shareable, redacted session artifacts
  • 5 themes, keyboard shortcuts, command palette
  • Bilingual: English and Chinese
  • Companion to the TUI version; both can run simultaneously
Hermes HUD Web UI是一款基于浏览器的意识监控工具,用于监控具备持久化记忆的AI Agent——Hermes。它提供18个标签页,涵盖执行仪表板、身份信息、内存、技能、会话、健康诊断、成本、模型分析、网关控制、插件管理及实时聊天。UI通过WebSocket实现实时更新,并读取与Hermes Agent相同的
~/.hermes/
数据目录。
核心特性:
  • 实时监控Agent内存、会话及健康状态
  • 按模型统计成本与Token分析
  • 网关管理工具可见性(网页搜索、图像生成、TTS、浏览器自动化)
  • Hermes Replay:导出可分享的脱敏会话 artifacts
  • 5种主题、键盘快捷键、命令面板
  • 双语支持:英文和中文
  • 与TUI版本兼容;两者可同时运行

Installation

安装

Requirements

要求

  • Python 3.11+
  • Node.js 18+
  • A running Hermes agent with data in
    ~/.hermes/
  • Python 3.11+
  • Node.js 18+
  • 运行中的Hermes Agent,且数据存储在
    ~/.hermes/
    目录中

Quick Start

快速开始

bash
git clone https://github.com/joeynyc/hermes-hudui.git
cd hermes-hudui
./install.sh
hermes-hudui
The installer creates a Python virtual environment, installs dependencies, and builds the frontend. Open http://localhost:3001 after launch.
bash
git clone https://github.com/joeynyc/hermes-hudui.git
cd hermes-hudui
./install.sh
hermes-hudui
安装程序会创建Python虚拟环境、安装依赖并构建前端。启动后打开 http://localhost:3001。

Manual Installation

手动安装

bash
undefined
bash
undefined

Clone repository

Clone repository

Create virtual environment

Create virtual environment

python3.11 -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate
python3.11 -m venv venv source venv/bin/activate # On Windows: venv\Scripts\activate

Install Python dependencies

Install Python dependencies

pip install -e .
pip install -e .

Install Node dependencies and build frontend

Install Node dependencies and build frontend

cd frontend npm install npm run build cd ..
cd frontend npm install npm run build cd ..

Launch

Launch

hermes-hudui
undefined
hermes-hudui
undefined

Future Runs

后续运行

bash
cd hermes-hudui
source venv/bin/activate && hermes-hudui
bash
cd hermes-hudui
source venv/bin/activate && hermes-hudui

Optional TUI Integration

可选TUI集成

If you also want the TUI version available:
bash
undefined
如果同时需要TUI版本:
bash
undefined

In zsh (quotes required)

In zsh (quotes required)

pip install 'hermes-hudui[tui]'
pip install 'hermes-hudui[tui]'

In bash/fish (quotes optional but safe)

In bash/fish (quotes optional but safe)

pip install 'hermes-hudui[tui]'
undefined
pip install 'hermes-hudui[tui]'
undefined

Configuration

配置

Environment Variables

环境变量

bash
undefined
bash
undefined

Custom port (default: 3001)

Custom port (default: 3001)

export HERMES_HUD_PORT=8080
export HERMES_HUD_PORT=8080

Custom Hermes data directory (default: ~/.hermes/)

Custom Hermes data directory (default: ~/.hermes/)

export HERMES_DATA_DIR=/path/to/custom/hermes/data
export HERMES_DATA_DIR=/path/to/custom/hermes/data

WebSocket host (default: localhost)

WebSocket host (default: localhost)

export HERMES_WS_HOST=0.0.0.0
undefined
export HERMES_WS_HOST=0.0.0.0
undefined

Data Directory Structure

数据目录结构

Hermes HUD reads from
~/.hermes/
:
~/.hermes/
├── identity.json          # Agent identity and configuration
├── memory/                # Persistent memory store
├── sessions/              # Session logs and history
├── skills/                # Installed skills
├── cron/                  # Scheduled jobs
├── projects/              # Project tracking
├── health/                # Health metrics
└── costs/                 # Usage and cost tracking
Hermes HUD读取
~/.hermes/
目录中的数据:
~/.hermes/
├── identity.json          # Agent identity and configuration
├── memory/                # Persistent memory store
├── sessions/              # Session logs and history
├── skills/                # Installed skills
├── cron/                  # Scheduled jobs
├── projects/              # Project tracking
├── health/                # Health metrics
└── costs/                 # Usage and cost tracking

Replay Export Directory

重放导出目录

Exported replay artifacts are written to:
~/.hermes-hud/replays/
├── session_abc123/
│   ├── replay.redacted.json
│   ├── replay.md
│   ├── replay.html
│   ├── share-card.png
│   └── fork.json
导出的重放artifacts会写入以下目录:
~/.hermes-hud/replays/
├── session_abc123/
│   ├── replay.redacted.json
│   ├── replay.md
│   ├── replay.html
│   ├── share-card.png
│   └── fork.json

Key Commands

关键命令

CLI

CLI

bash
undefined
bash
undefined

Start the web UI

Start the web UI

hermes-hudui
hermes-hudui

Start on custom port

Start on custom port

HERMES_HUD_PORT=8080 hermes-hudui
HERMES_HUD_PORT=8080 hermes-hudui

Point to custom Hermes data directory

Point to custom Hermes data directory

HERMES_DATA_DIR=/custom/path hermes-hudui
undefined
HERMES_DATA_DIR=/custom/path hermes-hudui
undefined

Keyboard Shortcuts (In Browser)

浏览器快捷键

KeyAction
1
9
,
0
Switch between tabs 1-10
t
Open theme picker
Ctrl+K
Open command palette
按键操作
1
9
,
0
在第1-10个标签页间切换
t
打开主题选择器
Ctrl+K
打开命令面板

Themes

主题

Five built-in themes (toggle with
t
):
  1. Neural Awakening (cyan) — default
  2. Hermes Teal (official Nous palette)
  3. Blade Runner (amber)
  4. fsociety (green)
  5. Anime (purple)
Optional CRT scanlines available in theme settings.
内置5种主题(按
t
键切换):
  1. Neural Awakening(青色)——默认主题
  2. Hermes Teal(官方Nous配色)
  3. Blade Runner(琥珀色)
  4. fsociety(绿色)
  5. Anime(紫色)
主题设置中可选择是否启用CRT扫描线效果。

Language Toggle

语言切换

Click the language icon in the top-right header to switch between English and Chinese. Persists to localStorage. When Chinese is selected, chat responses from your agent also come back in Chinese.
点击右上角头部的语言图标可在英文和中文间切换,设置会保存到localStorage。选择中文后,Agent的聊天回复也会以中文返回。

Core Functionality

核心功能

Accessing the Dashboard

访问仪表板

After starting
hermes-hudui
, navigate to http://localhost:3001 in your browser. The executive dashboard loads first, showing:
  • Agent health status
  • Spend pulse (recent costs)
  • Top model by usage
  • Provider/gateway risk
  • Highest-cost session
  • Action items
  • Agent健康状态
  • 支出动态(近期成本)
  • 使用量最高的模型
  • 提供商/网关风险
  • 成本最高的会话
  • 待办事项

Real-Time Updates

实时更新

The UI uses WebSocket for live updates. Health reacts to filesystem changes in
~/.hermes/
and WebSocket messages. Expensive refresh paths (e.g., full memory scans) are throttled.
UI通过WebSocket实现实时更新。健康状态会响应
~/.hermes/
目录中的文件系统变化及WebSocket消息。资源消耗较高的刷新路径(如完整内存扫描)会被限流。

Gateway Managed Tools

网关管理工具

The Gateway tab shows routing for:
  • Web search
  • Image generation
  • Text-to-speech
  • Browser automation
Each tool displays one of three states:
  • Gateway: routed through Nous Tool Gateway
  • Direct Key: using your own API key
  • Unavailable: not configured
网关标签页显示以下工具的路由情况:
  • 网页搜索
  • 图像生成
  • 文本转语音(TTS)
  • 浏览器自动化
每个工具会显示三种状态之一:
  • Gateway:通过Nous Tool Gateway路由
  • Direct Key:使用您自己的API密钥
  • Unavailable:未配置

Plugin Hub

插件中心

The Plugins tab shows:
  • Installed dashboard and agent plugins
  • Extension entry points
  • Runtime status
  • Required auth commands
  • Enable/disable/update actions (two-click safety)
插件标签页显示:
  • 已安装的仪表板和Agent插件
  • 扩展入口点
  • 运行时状态
  • 所需的认证命令
  • 启用/禁用/更新操作(双击确认安全机制)

Hermes Replay

Hermes Replay

Purpose: Turn agent runs into redacted, shareable proof artifacts.
Workflow:
  1. Open the Replay tab
  2. Select a Hermes session from the list
  3. Inspect the normalized timeline
  4. Review the run receipt
  5. Export artifacts (local files, no upload by default)
Export Formats:
  • Redacted JSON (
    replay.redacted.json
    )
  • GitHub-ready Markdown (
    replay.md
    )
  • Standalone HTML (
    replay.html
    )
  • PNG share card 1200×630 (
    share-card.png
    )
  • Fork-safe metadata (
    fork.json
    )
Safe Share Mode (default):
  • Redacts raw tool arguments
  • Strips terminal output
  • Removes assistant reasoning
  • Masks tokens, emails, local paths
  • Includes local hashes and Ed25519 signatures for integrity
Example redacted payload:
assets/example-replay.redacted.json
用途: 将Agent运行记录转换为脱敏的、可分享的证明artifacts。
流程:
  1. 打开Replay标签页
  2. 从列表中选择一个Hermes会话
  3. 查看标准化时间线
  4. 审核运行记录
  5. 导出artifacts(默认保存到本地文件,不上传)
导出格式:
  • 脱敏JSON(
    replay.redacted.json
  • 适用于GitHub的Markdown(
    replay.md
  • 独立HTML(
    replay.html
  • PNG分享卡片(1200×630,
    share-card.png
  • 可用于复刻的元数据(
    fork.json
安全分享模式(默认):
  • 脱敏原始工具参数
  • 移除终端输出
  • 删除助手推理过程
  • 掩码Token、邮箱、本地路径
  • 包含本地哈希和Ed25519签名以保证完整性
示例脱敏载荷:
assets/example-replay.redacted.json

Code Examples

代码示例

Python: Extending the Backend

Python:扩展后端

Add a custom WebSocket event handler:
python
undefined
添加自定义WebSocket事件处理器:
python
undefined

server/handlers/custom_handler.py

server/handlers/custom_handler.py

from server.websocket import send_message
async def handle_custom_event(websocket, data): """ Custom event handler for new dashboard features. """ event_type = data.get("type")
if event_type == "request_custom_metric":
    metric_data = compute_custom_metric()
    await send_message(websocket, {
        "type": "custom_metric",
        "payload": metric_data
    })
def compute_custom_metric(): # Read from ~/.hermes/ or compute live data return { "metric_name": "agent_velocity", "value": 42, "timestamp": "2026-05-16T18:00:00Z" }

Register the handler in `server/websocket.py`:

```python
from server.handlers.custom_handler import handle_custom_event

async def handle_message(websocket, message):
    data = json.loads(message)
    
    if data["type"] == "request_custom_metric":
        await handle_custom_event(websocket, data)
    # ... existing handlers
from server.websocket import send_message
async def handle_custom_event(websocket, data): """ Custom event handler for new dashboard features. """ event_type = data.get("type")
if event_type == "request_custom_metric":
    metric_data = compute_custom_metric()
    await send_message(websocket, {
        "type": "custom_metric",
        "payload": metric_data
    })
def compute_custom_metric(): # Read from ~/.hermes/ or compute live data return { "metric_name": "agent_velocity", "value": 42, "timestamp": "2026-05-16T18:00:00Z" }

在`server/websocket.py`中注册处理器:

```python
from server.handlers.custom_handler import handle_custom_event

async def handle_message(websocket, message):
    data = json.loads(message)
    
    if data["type"] == "request_custom_metric":
        await handle_custom_event(websocket, data)
    # ... existing handlers

Python: Reading Hermes Data

Python:读取Hermes数据

Access agent identity and memory:
python
import json
from pathlib import Path

def load_hermes_identity():
    """Load agent identity from ~/.hermes/identity.json"""
    hermes_dir = Path.home() / ".hermes"
    identity_path = hermes_dir / "identity.json"
    
    if identity_path.exists():
        with open(identity_path, "r") as f:
            return json.load(f)
    return None

def get_recent_sessions(limit=10):
    """Get most recent session logs"""
    sessions_dir = Path.home() / ".hermes" / "sessions"
    
    if not sessions_dir.exists():
        return []
    
    session_files = sorted(
        sessions_dir.glob("*.json"),
        key=lambda p: p.stat().st_mtime,
        reverse=True
    )
    
    sessions = []
    for session_file in session_files[:limit]:
        with open(session_file, "r") as f:
            sessions.append(json.load(f))
    
    return sessions
访问Agent身份信息和内存:
python
import json
from pathlib import Path

def load_hermes_identity():
    """Load agent identity from ~/.hermes/identity.json"""
    hermes_dir = Path.home() / ".hermes"
    identity_path = hermes_dir / "identity.json"
    
    if identity_path.exists():
        with open(identity_path, "r") as f:
            return json.load(f)
    return None

def get_recent_sessions(limit=10):
    """Get most recent session logs"""
    sessions_dir = Path.home() / ".hermes" / "sessions"
    
    if not sessions_dir.exists():
        return []
    
    session_files = sorted(
        sessions_dir.glob("*.json"),
        key=lambda p: p.stat().st_mtime,
        reverse=True
    )
    
    sessions = []
    for session_file in session_files[:limit]:
        with open(session_file, "r") as f:
            sessions.append(json.load(f))
    
    return sessions

JavaScript: Custom Dashboard Widget

JavaScript:自定义仪表板组件

Add a new chart to the frontend:
javascript
// frontend/src/components/CustomMetricWidget.jsx
import React, { useEffect, useState } from 'react';
import { useWebSocket } from '../hooks/useWebSocket';

export function CustomMetricWidget() {
  const [metricData, setMetricData] = useState(null);
  const { sendMessage, onMessage } = useWebSocket();

  useEffect(() => {
    // Request custom metric from backend
    sendMessage({ type: 'request_custom_metric' });

    // Listen for response
    const unsubscribe = onMessage((data) => {
      if (data.type === 'custom_metric') {
        setMetricData(data.payload);
      }
    });

    return unsubscribe;
  }, []);

  if (!metricData) return <div>Loading...</div>;

  return (
    <div className="metric-widget">
      <h3>{metricData.metric_name}</h3>
      <div className="metric-value">{metricData.value}</div>
      <div className="metric-timestamp">{metricData.timestamp}</div>
    </div>
  );
}
向前端添加新图表:
javascript
// frontend/src/components/CustomMetricWidget.jsx
import React, { useEffect, useState } from 'react';
import { useWebSocket } from '../hooks/useWebSocket';

export function CustomMetricWidget() {
  const [metricData, setMetricData] = useState(null);
  const { sendMessage, onMessage } = useWebSocket();

  useEffect(() => {
    // Request custom metric from backend
    sendMessage({ type: 'request_custom_metric' });

    // Listen for response
    const unsubscribe = onMessage((data) => {
      if (data.type === 'custom_metric') {
        setMetricData(data.payload);
      }
    });

    return unsubscribe;
  }, []);

  if (!metricData) return <div>Loading...</div>;

  return (
    <div className="metric-widget">
      <h3>{metricData.metric_name}</h3>
      <div className="metric-value">{metricData.value}</div>
      <div className="metric-timestamp">{metricData.timestamp}</div>
    </div>
  );
}

Python: Replay Export Customization

Python:自定义重放导出器

Create a custom replay exporter:
python
undefined
创建自定义重放导出器:
python
undefined

server/replay/custom_exporter.py

server/replay/custom_exporter.py

import json from pathlib import Path from datetime import datetime
class CustomReplayExporter: def init(self, session_id, replay_data): self.session_id = session_id self.replay_data = replay_data self.output_dir = Path.home() / ".hermes-hud" / "replays" / session_id self.output_dir.mkdir(parents=True, exist_ok=True)
def export_json(self):
    """Export custom JSON format"""
    output_path = self.output_dir / "custom-export.json"
    
    custom_format = {
        "version": "1.0",
        "session_id": self.session_id,
        "exported_at": datetime.utcnow().isoformat(),
        "timeline": self.replay_data.get("timeline", []),
        "metadata": self.replay_data.get("metadata", {})
    }
    
    with open(output_path, "w") as f:
        json.dump(custom_format, f, indent=2)
    
    return output_path

def export_csv(self):
    """Export timeline as CSV"""
    import csv
    
    output_path = self.output_dir / "timeline.csv"
    timeline = self.replay_data.get("timeline", [])
    
    if not timeline:
        return None
    
    with open(output_path, "w", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=timeline[0].keys())
        writer.writeheader()
        writer.writerows(timeline)
    
    return output_path
undefined
import json from pathlib import Path from datetime import datetime
class CustomReplayExporter: def init(self, session_id, replay_data): self.session_id = session_id self.replay_data = replay_data self.output_dir = Path.home() / ".hermes-hud" / "replays" / session_id self.output_dir.mkdir(parents=True, exist_ok=True)
def export_json(self):
    """Export custom JSON format"""
    output_path = self.output_dir / "custom-export.json"
    
    custom_format = {
        "version": "1.0",
        "session_id": self.session_id,
        "exported_at": datetime.utcnow().isoformat(),
        "timeline": self.replay_data.get("timeline", []),
        "metadata": self.replay_data.get("metadata", {})
    }
    
    with open(output_path, "w") as f:
        json.dump(custom_format, f, indent=2)
    
    return output_path

def export_csv(self):
    """Export timeline as CSV"""
    import csv
    
    output_path = self.output_dir / "timeline.csv"
    timeline = self.replay_data.get("timeline", [])
    
    if not timeline:
        return None
    
    with open(output_path, "w", newline="") as f:
        writer = csv.DictWriter(f, fieldnames=timeline[0].keys())
        writer.writeheader()
        writer.writerows(timeline)
    
    return output_path
undefined

Common Patterns

常见模式

Monitoring Agent Health

监控Agent健康状态

python
from pathlib import Path
import json

def check_agent_health():
    """Check Hermes agent health status"""
    health_file = Path.home() / ".hermes" / "health" / "status.json"
    
    if not health_file.exists():
        return {"status": "unknown", "message": "Health file not found"}
    
    with open(health_file, "r") as f:
        health_data = json.load(f)
    
    return {
        "status": health_data.get("status"),
        "last_check": health_data.get("timestamp"),
        "issues": health_data.get("issues", [])
    }
python
from pathlib import Path
import json

def check_agent_health():
    """Check Hermes agent health status"""
    health_file = Path.home() / ".hermes" / "health" / "status.json"
    
    if not health_file.exists():
        return {"status": "unknown", "message": "Health file not found"}
    
    with open(health_file, "r") as f:
        health_data = json.load(f)
    
    return {
        "status": health_data.get("status"),
        "last_check": health_data.get("timestamp"),
        "issues": health_data.get("issues", [])
    }

Accessing Cost Analytics

访问成本分析数据

python
def get_cost_summary(model_name=None):
    """Get cost analytics, optionally filtered by model"""
    costs_dir = Path.home() / ".hermes" / "costs"
    
    if not costs_dir.exists():
        return {"total": 0, "by_model": {}}
    
    total_cost = 0
    by_model = {}
    
    for cost_file in costs_dir.glob("*.json"):
        with open(cost_file, "r") as f:
            data = json.load(f)
            model = data.get("model")
            cost = data.get("cost", 0)
            
            if model_name and model != model_name:
                continue
            
            total_cost += cost
            by_model[model] = by_model.get(model, 0) + cost
    
    return {
        "total": total_cost,
        "by_model": by_model
    }
python
def get_cost_summary(model_name=None):
    """Get cost analytics, optionally filtered by model"""
    costs_dir = Path.home() / ".hermes" / "costs"
    
    if not costs_dir.exists():
        return {"total": 0, "by_model": {}}
    
    total_cost = 0
    by_model = {}
    
    for cost_file in costs_dir.glob("*.json"):
        with open(cost_file, "r") as f:
            data = json.load(f)
            model = data.get("model")
            cost = data.get("cost", 0)
            
            if model_name and model != model_name:
                continue
            
            total_cost += cost
            by_model[model] = by_model.get(model, 0) + cost
    
    return {
        "total": total_cost,
        "by_model": by_model
    }

WebSocket Real-Time Updates

WebSocket实时更新

javascript
// frontend/src/hooks/useAgentHealth.js
import { useEffect, useState } from 'react';
import { useWebSocket } from './useWebSocket';

export function useAgentHealth() {
  const [health, setHealth] = useState(null);
  const { sendMessage, onMessage } = useWebSocket();

  useEffect(() => {
    // Request initial health status
    sendMessage({ type: 'request_health' });

    // Subscribe to health updates
    const unsubscribe = onMessage((data) => {
      if (data.type === 'health_update') {
        setHealth(data.payload);
      }
    });

    // Refresh every 30 seconds
    const interval = setInterval(() => {
      sendMessage({ type: 'request_health' });
    }, 30000);

    return () => {
      unsubscribe();
      clearInterval(interval);
    };
  }, []);

  return health;
}
javascript
// frontend/src/hooks/useAgentHealth.js
import { useEffect, useState } from 'react';
import { useWebSocket } from './useWebSocket';

export function useAgentHealth() {
  const [health, setHealth] = useState(null);
  const { sendMessage, onMessage } = useWebSocket();

  useEffect(() => {
    // Request initial health status
    sendMessage({ type: 'request_health' });

    // Subscribe to health updates
    const unsubscribe = onMessage((data) => {
      if (data.type === 'health_update') {
        setHealth(data.payload);
      }
    });

    // Refresh every 30 seconds
    const interval = setInterval(() => {
      sendMessage({ type: 'request_health' });
    }, 30000);

    return () => {
      unsubscribe();
      clearInterval(interval);
    };
  }, []);

  return health;
}

Troubleshooting

故障排查

Port Already in Use

端口已被占用

bash
undefined
bash
undefined

Error: Address already in use

Error: Address already in use

Solution: Use a different port

Solution: Use a different port

HERMES_HUD_PORT=8080 hermes-hudui
undefined
HERMES_HUD_PORT=8080 hermes-hudui
undefined

WebSocket Connection Failed

WebSocket连接失败

Symptom: Dashboard loads but shows "disconnected" status, no real-time updates.
Causes:
  • Backend not running
  • Firewall blocking WebSocket
  • Port mismatch between frontend and backend
Solution:
bash
undefined
症状: 仪表板加载成功但显示“已断开连接”状态,无实时更新。
原因:
  • 后端未运行
  • 防火墙阻止WebSocket连接
  • 前端与后端端口不匹配
解决方案:
bash
undefined

Verify backend is running

Verify backend is running

ps aux | grep hermes-hudui
ps aux | grep hermes-hudui

Check logs for WebSocket errors

Check logs for WebSocket errors

tail -f ~/.hermes-hud/logs/server.log
tail -f ~/.hermes-hud/logs/server.log

Ensure frontend points to correct WebSocket URL

Ensure frontend points to correct WebSocket URL

Check frontend/.env or frontend/src/config.js

Check frontend/.env or frontend/src/config.js

undefined
undefined

Missing Hermes Data Directory

缺少Hermes数据目录

Symptom: Dashboard shows "No data found" or empty tabs.
Cause: Hermes agent hasn't run yet or data is in non-standard location.
Solution:
bash
undefined
症状: 仪表板显示“未找到数据”或标签页为空。
原因: Hermes Agent尚未运行,或数据存储在非标准位置。
解决方案:
bash
undefined

Verify Hermes data exists

Verify Hermes data exists

ls -la ~/.hermes/
ls -la ~/.hermes/

If data is elsewhere, set environment variable

If data is elsewhere, set environment variable

HERMES_DATA_DIR=/path/to/hermes/data hermes-hudui
undefined
HERMES_DATA_DIR=/path/to/hermes/data hermes-hudui
undefined

Replay Export Fails

重放导出失败

Symptom: Export button doesn't create files or throws permission error.
Cause: Insufficient permissions on
~/.hermes-hud/replays/
directory.
Solution:
bash
undefined
症状: 导出按钮未创建文件或抛出权限错误。
原因:
~/.hermes-hud/replays/
目录权限不足。
解决方案:
bash
undefined

Create directory with correct permissions

Create directory with correct permissions

mkdir -p ~/.hermes-hud/replays chmod 755 ~/.hermes-hud/replays
mkdir -p ~/.hermes-hud/replays chmod 755 ~/.hermes-hud/replays

Check disk space

Check disk space

df -h ~
undefined
df -h ~
undefined

Frontend Build Errors

前端构建错误

Symptom:
./install.sh
fails during
npm run build
.
Cause: Node.js version < 18 or missing dependencies.
Solution:
bash
undefined
症状:
./install.sh
在执行
npm run build
时失败。
原因: Node.js版本低于18或缺少依赖。
解决方案:
bash
undefined

Check Node.js version

Check Node.js version

node --version # Should be 18+
node --version # Should be 18+

Update Node.js (via nvm)

Update Node.js (via nvm)

nvm install 18 nvm use 18
nvm install 18 nvm use 18

Clean install

Clean install

cd frontend rm -rf node_modules package-lock.json npm install npm run build
undefined
cd frontend rm -rf node_modules package-lock.json npm install npm run build
undefined

Theme Not Persisting

主题未持久化

Symptom: Theme resets to default on page reload.
Cause: localStorage disabled or browser privacy mode.
Solution:
  • Disable private/incognito mode
  • Check browser console for localStorage errors
  • Verify site isn't blocked in browser settings
症状: 页面刷新后主题重置为默认。
原因: localStorage被禁用或浏览器处于隐私模式。
解决方案:
  • 关闭隐私/无痕模式
  • 检查浏览器控制台是否有localStorage错误
  • 验证浏览器设置未阻止该站点

Gateway Tools Show "Unavailable"

网关工具显示“不可用”

Symptom: All gateway-managed tools show unavailable status.
Cause: Hermes agent not configured with gateway credentials or direct API keys.
Solution:
bash
undefined
症状: 所有网关管理工具显示不可用状态。
原因: Hermes Agent未配置网关凭证或直接API密钥。
解决方案:
bash
undefined

Configure Nous Tool Gateway (if using gateway)

Configure Nous Tool Gateway (if using gateway)

In Hermes agent config (~/.hermes/config.json):

In Hermes agent config (~/.hermes/config.json):

{ "gateway": { "enabled": true, "api_key": "${NOUS_GATEWAY_API_KEY}" } }
{ "gateway": { "enabled": true, "api_key": "${NOUS_GATEWAY_API_KEY}" } }

Or configure direct API keys

Or configure direct API keys

{ "providers": { "openai": { "api_key": "${OPENAI_API_KEY}" }, "anthropic": { "api_key": "${ANTHROPIC_API_KEY}" } } }
{ "providers": { "openai": { "api_key": "${OPENAI_API_KEY}" }, "anthropic": { "api_key": "${ANTHROPIC_API_KEY}" } } }

Restart Hermes agent and HUD

Restart Hermes agent and HUD

undefined
undefined

Platform Support

平台支持

  • macOS: Full support
  • Linux: Full support
  • Windows: Use WSL (Windows Subsystem for Linux)
  • macOS:完全支持
  • Linux:完全支持
  • Windows:使用WSL(Windows Subsystem for Linux)

Related Resources

相关资源

  • Hermes Agent — The AI agent Hermes HUD monitors
  • Hermes HUD TUI — Terminal UI companion
  • Example Redacted Replay — Sample export artifact
  • Hermes Agent — Hermes HUD监控的AI Agent
  • Hermes HUD TUI — 终端UI配套工具
  • Example Redacted Replay — 示例导出artifact