# Hermes — OpenClaw Web Interface **Prod:** `https://chat.jqxp.org` · `wss://chat.jqxp.org/ws` **Dev:** `https://dev.jqxp.org` --- ## Stack ``` hermes/ backend/ Bun + TypeScript :3001 prod / :3003 dev frontend/ Vue 3 + Vite :8443 dev / jqxp.org prod (static) ``` ## Architecture ``` Browser(s) │ WebSocket /ws + HTTP /api/* ▼ server.ts (Bun.serve) ├── auth.ts token → user, session tokens ├── gateway.ts upstream WS → openclaw gateway :18789 ├── session-sm.ts per-connection state machine ├── session-watcher.ts JSONL tail → WS events ├── hud-builder.ts HUD event factory, result builders, path helpers ├── message-filter.ts strip sensitive values from tool output └── mcp/ MCP Streamable HTTP server ├── index.ts auth, routing, key management ├── dev.ts health, subscribe, push_state tools ├── events.ts in-memory event queue + long-poll ├── system.ts start/stop/restart/deploy tools └── fs.ts remote file read/write/edit/grep ``` See [backend/README.md](backend/README.md) and [frontend/README.md](frontend/README.md) for details. ## Dev ### On openclaw VM (tmux sessions) ```bash # Backend (auto-restarts on file change) cd hermes/backend PORT=3003 ~/.bun/bin/bun --watch run server.ts # tmux: hermes-bun # Frontend (Vite HMR) cd hermes/frontend bun run dev # tmux: webchat-vite → :8443 ``` ### From Titan host (Claude Code workspace) Local mirror: `D:/ClaudeCode/Titan/Openclaw/` ↔ `~/.openclaw/` on openclaw VM. ```bash # Pull entire project rsync -avz --exclude='node_modules' --exclude='dist' --exclude='.git' \ openclaw:~/.openclaw/workspace-titan/projects/hermes/ \ /d/ClaudeCode/Titan/Openclaw/workspace-titan/projects/hermes/ # Edit locally with Claude Code (Read/Edit tools — no shell escaping issues) # Push backend (bun --watch auto-restarts) rsync -avz --exclude='node_modules' --exclude='dist' --exclude='.git' \ /d/ClaudeCode/Titan/Openclaw/workspace-titan/projects/hermes/backend/ \ openclaw:~/.openclaw/workspace-titan/projects/hermes/backend/ # Push frontend (Vite HMR picks up instantly) rsync -avz --exclude='node_modules' --exclude='dist' --exclude='.git' \ /d/ClaudeCode/Titan/Openclaw/workspace-titan/projects/hermes/frontend/ \ openclaw:~/.openclaw/workspace-titan/projects/hermes/frontend/ ``` ## Deploy ```bash # Frontend → static hosting cd hermes/frontend && npm run build rsync -avz --delete dist/ u116526981@access1007204406.webspace-data.io:~/jqxp/ # Backend prod restart sudo systemctl restart openclaw-web-gateway.service curl https://chat.jqxp.org/health ``` ## Ports ``` :3001 prod backend systemd: openclaw-web-gateway.service :3003 dev backend tmux: hermes-bun :8443 dev frontend tmux: webchat-vite ``` ## Network ``` Browser → Cloudflare Tunnel → RouterVM → OpenClaw VM :3001 → gateway :18789 ``` ## Features (0.6.42) - Multi-modal chat: text, images, PDFs, audio recording - Audio STT via ElevenLabs Scribe v2 (mic → transcript → agent) - TTS via ElevenLabs (speaker icon on assistant messages, player bar) - Permanent sidebar rail with overlay expand, responsive - Previous session history (server-fetched, load more) - MCP server with 36+ tools (fs, system, deck, dev, takeover) - Real-time MCP event loop (dev_subscribe + dev_push_state) - Interactive dev tools: counter game, action picker, confetti - Automated test runner via Nextcloud Deck + takeover bridge - WebGL particle background (theme-aware) - Deploy to prod via MCP (system_deploy_prod) ## Open - [ ] Token management (tokens hardcoded in auth.ts) - [ ] Room mode (shared session, multiple users) - [ ] User message lifecycle (msgId-based updates, dedup) - [ ] Rename project/domain