Skip to content

ankurCES/hermes-desktop

Repository files navigation

Hermes Desktop

A native desktop client for the Hermes Agent gateway. Tauri + Rust port of the pan-ui web dashboard.

What's in the box

  • Tauri 2 + Rust backend that talks to a local Hermes gateway over HTTP and SSE. Replaces the Next.js BFF that pan-ui shipped.
  • React 18 + Vite + Tailwind UI reimplementing every pan-ui view inside the Tauri webview (chat, sessions, skills, extensions, plugins, memory, profiles, settings, runtime dashboard, login).
  • OS keyring for the Hermes API key and workspace password.
  • Auto-launch the hermes binary as a sidecar when the gateway is down (mirrors pan-ui's gateway-manager behaviour).
  • Mock mode for offline use while the gateway isn't running.

Layout

hermes-desktop/
├── src/                 # React UI
│   ├── views/           # Chat, Settings, Runtime, Skills, …
│   ├── components/      # Sidebar, TopBar, Toast, PageHeader
│   ├── lib/tauri.ts     # Typed invoke + listen helpers, event narrowing
│   └── store/           # Zustand stores (config, auth)
└── src-tauri/
    └── src/
        ├── lib.rs       # Tauri builder, plugin list, command registration
        ├── gateway.rs   # reqwest + reqwest-eventsource Hermes client
        ├── runtime.rs   # Auto-launch / probe the `hermes` binary
        ├── config.rs    # Persistent settings + keyring helpers
        ├── error.rs     # AppError → { kind, message } payload
        ├── state.rs     # AppState shared across commands
        └── commands/    # One file per feature area

Prerequisites

  • Rust 1.77+ (1.95 used during development)
  • Node.js 18.18+
  • Tauri 2 system deps for your platform — see https://v2.tauri.app/start/prerequisites/
  • A running Hermes Agent gateway (or set HERMES_API_BASE_URL to a remote one). Hermes Desktop will auto-launch hermes gateway if it isn't already running and the binary is on PATH.

Run

npm install
npm run tauri:dev

The first run takes a few minutes while Cargo compiles Tauri and the React toolchain builds. Subsequent runs are fast.

Bootstrap from scratch (Ubuntu / Debian)

To go from a clean Ubuntu 22.04+ / Debian 12 box to a built .deb and .AppImage, run the bootstrap script. It installs system packages, Node 20 LTS, Rust 1.77+, clones the repo, and runs the Tauri release build.

Fetch and run (review the script first if you're cautious — see scripts/bootstrap.sh):

bash <(curl -fsSL https://raw.githubusercontent.com/ankurCES/hermes-desktop/main/scripts/bootstrap.sh)

Or save and inspect first:

curl -fsSL https://raw.githubusercontent.com/ankurCES/hermes-desktop/main/scripts/bootstrap.sh -o bootstrap.sh
chmod +x bootstrap.sh
./bootstrap.sh

The script is idempotent: it skips Node and Rust install if they're already present, and reuses an existing ~/hermes-desktop checkout. Override the checkout location with HERMES_DESKTOP_DIR=/path/to/dir ./bootstrap.sh.

System packages it installs (Ubuntu 22.04+ / Debian 12 names):

  • Build toolchain: build-essential, curl, wget, file, pkg-config, libssl-dev
  • Tauri 2 runtime: libgtk-3-dev, libwebkit2gtk-4.1-dev, libsoup-3.0-dev, libjavascriptcoregtk-4.1-dev, libayatana-appindicator3-dev, librsvg2-dev

The final artefacts land in src-tauri/target/release/bundle/. To install the deb:

sudo apt install -y src-tauri/target/release/bundle/deb/*.deb

Build a release binary

npm run tauri:build

Produces a signed-able .app bundle on macOS, .msi/.exe on Windows, and .deb/.AppImage on Linux under src-tauri/target/release/bundle/.

Install prebuilt package

The prebuilt release artefacts are published to GitHub Releases alongside each tagged version. Pick the one-liner for your platform.

Ubuntu / Debian (.deb):

curl -sSL https://github.com/ankurCES/hermes-desktop/releases/latest/download/hermes-desktop_amd64.deb -o /tmp/hermes-desktop.deb && sudo apt install -y /tmp/hermes-desktop.deb

macOS (.app bundle, drag-installable):

curl -sSL https://github.com/ankurCES/hermes-desktop/releases/latest/download/hermes-desktop_aarch64.app.tar.gz | tar -xz -C /Applications

The macOS one-liner targets Apple Silicon. For an Intel Mac, swap aarch64x64 in the URL.

Configuration

Settings live in two places:

  1. Persistent JSON via tauri-plugin-store at the OS-standard config location (~/Library/Application Support/ai.euraika.hermes-desktop/ on macOS, %APPDATA% on Windows, ~/.config/... on Linux). Open Settings in the app to edit.
  2. OS keyring for the Hermes API key and workspace password — never written to disk in plaintext.

Default gateway URL: http://127.0.0.1:8642. Override with the HERMES_API_BASE_URL environment variable or the Settings panel.

Mapping pan-ui → Hermes Desktop

pan-ui (Next.js) Hermes Desktop (Tauri)
middleware.ts auth gate commands/auth.rs + LoginView
/api/runtime/status runtime_status command
/api/runtime/health runtime_health command
/api/chat/stream SSE send_message command + chat:stream:* events
/api/chat/sessions list_sessions / create_session
/api/skills/... list_skills / skill_action
/api/extensions/... list_extensions / test_extension
/api/memory/agent get_memory / update_memory
/api/profiles/... list_profiles / select_profile
Cookie auth + HERMES_MOCK_MODE Keyring + in-app mock mode toggle

Known caveats

  • Hermes gateway API surface is permissive. We use serde_json::Value shapes in most places rather than typed structs, so the app will work with any gateway that returns the JSON shapes pan-ui expected. If the gateway diverges, the typed surface is concentrated in src-tauri/src/commands/ and easy to retarget.
  • Plugin install via the marketplace is wired (install_hub_extension) but the plugin-specific command set (list_plugins, toggle_plugin, install_plugin) assumes a /v1/plugins namespace on the gateway. If your gateway uses a different path, update the calls in src-tauri/src/commands/extensions.rs.
  • Login is local. pan-ui's auth was a signed cookie for the webview. The desktop app issues its own local session; the Hermes API key is what actually gates gateway access.

License

MIT, same as pan-ui.