Skills DirectorySkills Directory
SkillsLearnSecurityCategoriesDocsCommunityBlog
Sign InSubmit Skill
Skills Directory

Security-tested agent skills for Claude, coding agents, and AI workflows.

Directory

  • Browse Skills
  • All Skills A–Z
  • Claude Skills
  • Claude Code Skills
  • Agent Skills
  • Categories
  • Submit a Skill

Learn

  • Learn Hub
  • Install Claude Skills
  • Write SKILL.md
  • Skills vs MCP
  • Directories Compared

Security

  • Security
  • Methodology
  • Secure Claude Skills
  • Security Badges

Company

  • About
  • Community
  • Blog
  • API Docs
  • Advertise

2026 Skills Directory. All rights reserved.

Back to skills

Hermes Hudui Consciousness Monitor

BSecurity

> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection. A browser-based consciousness monitor for the Hermes AI agent. Reads from `~/.hermes/` data files and serves a real-time React dashboard via a FastAPI backend with WebSocket support.

81 stars
0 votes
0 copies
0 views
Added 9/19/2026
developmenttypescriptpythongobashreactnodefastapigitapidatabase

Works with

terminalcliapi

Security Analysis

B84/100
mediumInstalls packages at runtime which could introduce malicious dependencies
mediumInstalls packages at runtime which could introduce malicious dependencies

Scanned 9/19/2026

Install to Claude Code

$npx -y skills add reason-machines/trending-skills --skill hermes-hudui-consciousness-monitor --agent claude-code

Installs into .claude/skills of the current project.

Are you the author of Hermes Hudui Consciousness Monitor?

Add the live security badge to your README — it updates automatically with every re-scan.

Security grade badge for Hermes Hudui Consciousness Monitor
[![Security: B — Skills Directory](https://www.skillsdirectory.com/api/skills/reason-machines-hermes-hudui-consciousness-monitor/badge)](https://www.skillsdirectory.com/skills/reason-machines-hermes-hudui-consciousness-monitor)

More formats (shields.io, HTML) on the badges page.

Download Zip
Files
SKILL.md
```markdown
---
name: hermes-hudui-consciousness-monitor
description: Web UI consciousness monitor for Hermes AI agent with persistent memory — FastAPI backend + React frontend dashboard
triggers:
  - set up hermes hud web ui
  - monitor hermes agent in browser
  - hermes hudui dashboard
  - show hermes agent consciousness monitor
  - hermes web ui not working
  - add token cost tracking hermes
  - hermes hud websocket updates
  - configure hermes hudui themes
---

# ☤ Hermes HUD Web UI

> Skill by [ara.so](https://ara.so) — Daily 2026 Skills collection.

A browser-based consciousness monitor for the Hermes AI agent. Reads from `~/.hermes/` data files and serves a real-time React dashboard via a FastAPI backend with WebSocket support.

## Architecture Overview

```
React Frontend (Vite + SWR)
    ↓ /api/* + WebSocket /ws
FastAPI Backend (Python 3.11+)
    ↓ collectors/*.py + cache + file watcher
~/.hermes/ (agent data files)
```

- **Backend**: FastAPI with collectors, mtime-based cache, watchfiles watcher
- **Frontend**: React + Vite + SWR with silent background updates and auto-reconnect WebSocket
- **Data source**: `~/.hermes/` directory — no database, no external APIs

## Installation

### Quick Install

```bash
git clone https://github.com/joeynyc/hermes-hudui.git
cd hermes-hudui
python3.11 -m venv venv
source venv/bin/activate
./install.sh
hermes-hudui
```

Open http://localhost:3001

### Manual Install

```bash
python3.11 -m venv venv
source venv/bin/activate

# Install Python package
pip install -e .

# Build frontend and copy to backend static dir
cd frontend
npm install
npm run build
cp -r dist/* ../backend/static/

# Start server
hermes-hudui
```

### Subsequent Runs

```bash
source venv/bin/activate
hermes-hudui
```

### With TUI Support (Optional)

```bash
pip install hermes-hudui[tui]
```

## Requirements

- Python 3.11+
- Node.js 18+
- A running Hermes agent with data written to `~/.hermes/`

## Key CLI Commands

| Command | Description |
|---------|-------------|
| `hermes-hudui` | Start the web server on port 3001 |
| `./install.sh` | Full install: venv setup + pip install + frontend build |

## Backend: Collectors

Collectors are Python modules in `backend/collectors/` that read `~/.hermes/` and return dataclasses. Each collector corresponds to a dashboard panel.

### Collector Pattern

```python
# backend/collectors/identity.py
from dataclasses import dataclass
from pathlib import Path
import json

HERMES_DIR = Path.home() / ".hermes"

@dataclass
class IdentityData:
    designation: str
    substrate: str
    runtime: str
    days_conscious: int
    brain_size_mb: float

def collect_identity() -> IdentityData:
    config_path = HERMES_DIR / "config.json"
    if not config_path.exists():
        return IdentityData(
            designation="Unknown",
            substrate="unknown",
            runtime="unknown",
            days_conscious=0,
            brain_size_mb=0.0,
        )
    data = json.loads(config_path.read_text())
    return IdentityData(
        designation=data.get("designation", "Hermes"),
        substrate=data.get("substrate", "unknown"),
        runtime=data.get("runtime", "unknown"),
        days_conscious=data.get("days_conscious", 0),
        brain_size_mb=data.get("brain_size_mb", 0.0),
    )
```

### Registering a New Collector in FastAPI

```python
# backend/main.py (simplified pattern)
from fastapi import FastAPI
from backend.collectors.identity import collect_identity
from backend.cache import cached

app = FastAPI()

@app.get("/api/identity")
async def identity():
    return cached("identity", collect_identity)
```

## Backend: Caching

The cache uses mtime-based invalidation. TTLs by data type:

| Data Type | TTL |
|-----------|-----|
| Sessions | 30s |
| Skills | 60s |
| Patterns | 60s |
| Profiles | 45s |

### Using the Cache

```python
from backend.cache import cached

# Simple usage — key + callable
result = cached("sessions", collect_sessions)

# With TTL override
result = cached("identity", collect_identity, ttl=10)
```

### Cache Invalidation

The file watcher (`watchfiles`) monitors `~/.hermes/` and invalidates relevant cache keys when files change, triggering WebSocket broadcasts to all clients.

## Backend: WebSocket

The WebSocket endpoint at `/ws` broadcasts `data_changed` events when `~/.hermes/` files change.

### Server-Side Broadcast Pattern

```python
# backend/ws.py (simplified)
from fastapi import WebSocket
import asyncio
import json

connected_clients: list[WebSocket] = []

async def broadcast_change(event: str = "data_changed"):
    message = json.dumps({"type": event})
    dead = []
    for ws in connected_clients:
        try:
            await ws.send_text(message)
        except Exception:
            dead.append(ws)
    for ws in dead:
        connected_clients.remove(ws)

@app.websocket("/ws")
async def websocket_endpoint(websocket: WebSocket):
    await websocket.accept()
    connected_clients.append(websocket)
    try:
        while True:
            await websocket.receive_text()  # keep alive
    except Exception:
        connected_clients.remove(websocket)
```

## Frontend: SWR Data Fetching

Each panel fetches its own API endpoint with `keepPreviousData` to avoid loading flashes.

```typescript
// frontend/src/hooks/useIdentity.ts
import useSWR from "swr";

const fetcher = (url: string) => fetch(url).then((r) => r.json());

export function useIdentity() {
  return useSWR("/api/identity", fetcher, {
    keepPreviousData: true,
    revalidateOnFocus: false,
  });
}
```

## Frontend: WebSocket Hook

Auto-reconnects with exponential backoff and triggers SWR revalidation on `data_changed` events.

```typescript
// frontend/src/hooks/useHermesSocket.ts
import { useEffect, useRef } from "react";
import { mutate } from "swr";

export function useHermesSocket() {
  const wsRef = useRef<WebSocket | null>(null);
  const retryDelay = useRef(1000);

  function connect() {
    const ws = new WebSocket(`ws://${location.host}/ws`);
    wsRef.current = ws;

    ws.onmessage = (event) => {
      const msg = JSON.parse(event.data);
      if (msg.type === "data_changed") {
        // Revalidate all SWR keys
        mutate(() => true, undefined, { revalidate: true });
      }
    };

    ws.onclose = () => {
      setTimeout(() => {
        retryDelay.current = Math.min(retryDelay.current * 2, 30000);
        connect();
      }, retryDelay.current);
    };

    ws.onopen = () => {
      retryDelay.current = 1000; // reset on success
    };
  }

  useEffect(() => {
    connect();
    return () => wsRef.current?.close();
  }, []);
}
```

## Frontend: Panel Component Pattern

```typescript
// frontend/src/panels/IdentityPanel.tsx
import { useIdentity } from "../hooks/useIdentity";

export function IdentityPanel() {
  const { data, isLoading } = useIdentity();

  // Show stale data while refreshing — no loading flash
  if (!data) return <div className="panel-loading">Loading…</div>;

  return (
    <div className="panel">
      <h2>Identity</h2>
      <dl>
        <dt>Designation</dt>
        <dd>{data.designation}</dd>
        <dt>Days Conscious</dt>
        <dd>{data.days_conscious}</dd>
        <dt>Brain Size</dt>
        <dd>{data.brain_size_mb.toFixed(1)} MB</dd>
      </dl>
    </div>
  );
}
```

## Token Cost Pricing

Costs are calculated from token counts using hardcoded per-model pricing in the backend.

### Supported Models and Pricing

| Provider | Model | Input | Output | Cache Read |
|----------|-------|------:|-------:|-----------:|
| Anthropic | Claude Opus 4 | $15/M | $75/M | $1.50/M |
| Anthropic | Claude Sonnet 4 | $3/M | $15/M | $0.30/M |
| Anthropic | Claude Haiku 3.5 | $0.80/M | $4/M | $0.08/M |
| OpenAI | GPT-4o | $2.50/M | $10/M | $1.25/M |
| OpenAI | o1 | $15/M | $60/M | $7.50/M |
| DeepSeek | V3 | $0.27/M | $1.10/M | $0.07/M |
| xAI | Grok 3 | $3/M | $15/M | $0.75/M |
| Google | Gemini 2.5 Pro | $1.25/M | $10/M | $0.31/M |

Unknown models fall back to Claude Opus pricing. Local/free models are detected and priced at $0.

### Cost Calculation Example

```python
# backend/collectors/costs.py (pattern)
PRICING = {
    "claude-opus-4": {"input": 15.0, "output": 75.0, "cache_read": 1.50},
    "claude-sonnet-4": {"input": 3.0, "output": 15.0, "cache_read": 0.30},
    "gpt-4o": {"input": 2.50, "output": 10.0, "cache_read": 1.25},
    # ... etc
}

def calculate_cost(model: str, input_tokens: int, output_tokens: int, cache_tokens: int = 0) -> float:
    # Detect local/free models
    if any(tag in model.lower() for tag in ["local", "ollama", "lmstudio"]):
        return 0.0

    pricing = PRICING.get(model, PRICING["claude-opus-4"])  # fallback
    cost = (
        (input_tokens / 1_000_000) * pricing["input"]
        + (output_tokens / 1_000_000) * pricing["output"]
        + (cache_tokens / 1_000_000) * pricing["cache_read"]
    )
    return round(cost, 6)
```

## Themes

Switch themes with the `t` key or the theme picker UI.

| Theme | Key | Description |
|-------|-----|-------------|
| Neural Awakening | `ai` | Cyan/blue on deep navy |
| Blade Runner | `blade-runner` | Amber/orange on warm black |
| fsociety | `fsociety` | Green on pure black |
| Anime | `anime` | Purple/violet on indigo |

CRT scanline overlay is togglable via the theme picker.

### Applying a Theme Programmatically

```typescript
// frontend/src/theme.ts
type Theme = "ai" | "blade-runner" | "fsociety" | "anime";

export function setTheme(theme: Theme) {
  document.documentElement.setAttribute("data-theme", theme);
  localStorage.setItem("hermes-theme", theme);
}

export function getTheme(): Theme {
  return (localStorage.getItem("hermes-theme") as Theme) ?? "ai";
}
```

## Keyboard Shortcuts

| Key | Action |
|-----|--------|
| `1`–`9`, `0` | Switch dashboard tabs |
| `t` | Toggle theme picker |
| `Ctrl+K` | Open command palette |

## Dashboard Panels / Tabs

| Tab | Data Source | Description |
|-----|-------------|-------------|
| Identity | `~/.hermes/config.json` | Designation, substrate, uptime |
| What I Know | Session logs | Conversations, messages, actions, skills |
| What I Remember | Memory files | Capacity bars, user profile, corrections |
| What I See | API key files | Key presence, service health |
| What I'm Learning | Skills directory | Recently modified skills with categories |
| What I'm Working On | Project files | Active projects, dirty file status |
| While You Sleep | Cron config | Scheduled jobs |
| How I Think | Tool logs | Tool usage patterns with gradient bars |
| My Rhythm | Activity logs | Daily activity sparkline |
| Growth Delta | Snapshots | Diffs showing what changed |
| Token Costs | Token logs | Per-model USD cost with daily trend |

## Adding a New API Endpoint

```python
# 1. Create collector
# backend/collectors/my_feature.py
from dataclasses import dataclass
from pathlib import Path

HERMES_DIR = Path.home() / ".hermes"

@dataclass
class MyFeatureData:
    value: str

def collect_my_feature() -> MyFeatureData:
    path = HERMES_DIR / "my_feature.json"
    if not path.exists():
        return MyFeatureData(value="none")
    import json
    return MyFeatureData(**json.loads(path.read_text()))

# 2. Register route in backend/main.py
from backend.collectors.my_feature import collect_my_feature
from backend.cache import cached

@app.get("/api/my-feature")
async def my_feature():
    return cached("my_feature", collect_my_feature, ttl=30)

# 3. Create frontend hook
# frontend/src/hooks/useMyFeature.ts
import useSWR from "swr";
const fetcher = (url: string) => fetch(url).then(r => r.json());
export const useMyFeature = () =>
  useSWR("/api/my-feature", fetcher, { keepPreviousData: true });
```

## Common Patterns

### Check if `~/.hermes/` Exists

```python
from pathlib import Path

HERMES_DIR = Path.home() / ".hermes"

if not HERMES_DIR.exists():
    raise RuntimeError(
        "No ~/.hermes/ directory found. "
        "Make sure the Hermes agent has run at least once."
    )
```

### Graceful Missing File Handling

```python
def safe_read_json(path: Path, default=None):
    try:
        return json.loads(path.read_text()) if path.exists() else default
    except (json.JSONDecodeError, OSError):
        return default
```

### Frontend: Rebuild After Backend Changes

```bash
cd frontend
npm run build
cp -r dist/* ../backend/static/
```

During development, run the Vite dev server separately (proxy configured in `vite.config.ts` to forward `/api` and `/ws` to the FastAPI backend on port 3001).

```bash
# Terminal 1 — backend
source venv/bin/activate
hermes-hudui

# Terminal 2 — frontend dev server with HMR
cd frontend
npm run dev
# Opens http://localhost:5173 with proxy to :3001
```

## Troubleshooting

### Port Already in Use

```bash
# Find and kill the process using port 3001
lsof -ti:3001 | xargs kill -9
hermes-hudui
```

### Frontend Not Loading (blank page)

The frontend static files may not be built or copied:

```bash
cd frontend
npm install
npm run build
cp -r dist/* ../backend/static/
hermes-hudui
```

### WebSocket Not Connecting ("● live" badge missing)

1. Check the browser console for WebSocket errors
2. Ensure the backend is running (`hermes-hudui`)
3. Confirm no firewall is blocking ws://localhost:3001/ws
4. The hook auto-reconnects with exponential backoff — wait a moment

### No Data Showing / Empty Dashboard

```bash
# Check that ~/.hermes/ exists and has files
ls ~/.hermes/

# Check backend logs for collector errors
hermes-hudui  # errors printed to stdout
```

### `watchfiles` Not Detecting Changes

```bash
pip install --upgrade watchfiles
```

On Linux, you may need to increase inotify limits:

```bash
echo fs.inotify.max_user_watches=524288 | sudo tee -a /etc/sysctl.conf
sudo sysctl -p
```

### WSL: Browser Can't Reach Server

The install script detects WSL automatically. If the browser can't connect:

```bash
# Get WSL IP
hostname -I | awk '{print $1}'
# Open http://<wsl-ip>:3001 instead of localhost
```

### Python Version Mismatch

```bash
python3.11 --version  # must be 3.11+
python3.11 -m venv venv  # explicitly use 3.11
```

## Platform Support

| Platform | Status |
|----------|--------|
| macOS | Native via `./install.sh` |
| Linux | Native via `./install.sh` |
| Windows | Via WSL only |
| WSL | Auto-detected by install script |

## Relationship to hermes-hud (TUI)

Both read from the same `~/.hermes/` directory independently. The Web UI (`hermes-hudui`) is fully standalone — it ships its own collectors. It adds features the TUI lacks:

- Dedicated Memory, Skills, and Sessions tabs
- Per-model token cost tracking with daily trend
- Command palette (`Ctrl+K`)
- Live theme switcher with preview
- WebSocket real-time updates

Install both side by side:

```bash
pip install hermes-hud       # TUI version
pip install hermes-hudui[tui] # Web UI + TUI bridge
```
```

Attribution

reason-machinesreason-machines
View sourceMore from reason-machines →
SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Is this your skill, or is something wrong with this listing? Request removal or report an issue. Author removals are honored within 72 hours.

Comments (0)

No comments yet. Be the first to comment!

SSkills DirectorySkills Directory

Ship a skill? Prove it's safe.

Free 120-pattern security scan, letter grade, and an embeddable README badge.

Submit a skill

Related Skills

Browser Extension Developer

Use this skill when developing or maintaining browser extension code in the `browser/` directory, including Chrome/Firefox/Edge compatibility, content scripts, background scripts, or i18n updates.

281612 votes

Seo Optimizer

SEO optimization with keyword analysis, readability assessment, technical validation, content quality. Use for search rankings, blog posts, content audits, or encountering keyword density, readability scores, meta tags, schema markup errors.

2132 votes

Google Official Seo Guide

Official Google SEO guide covering search optimization, best practices, Search Console, crawling, indexing, and improving website search visibility based on official Google documentation

1862 votes

Tanstack Start

Build a full-stack TanStack Start app on Cloudflare Workers from scratch — SSR, file-based routing, server functions, D1+Drizzle, better-auth, Tailwind v4+shadcn/ui. Use whenever the user mentions TanStack Start, asks to scaffold a full-stack Cloudflare app with SSR, wants an SSR dashboard, or asks for a React 19 + Cloudflare Workers app with file-based routing and server functions — even if they don't name TanStack Start specifically. No template repo — Claude generates every file fresh per ...

9881 votes

Pentest

PTES-aligned adversarial security audit for backend, frontend, and mobile applications. Produces a CVSS-scored Hacker Report with verified PoCs and phased remediation.

5491 votes
View all in development →