Cross-platform fork of Hermes Desktop, rebuilt with Tauri 2 + Rust + TypeScript + Vite to run on Linux, macOS, and Windows instead of the original macOS-only SwiftUI app.
Same SSH-first workflow. Same Hermes host as source of truth. Now on every desktop OS.
The upstream project is a native SwiftUI Mac app (66 Swift sources, ~32 k lines). This fork replaces the entire native layer:
| Layer | Upstream | This fork |
|---|---|---|
| Desktop shell | SwiftUI + AppKit | Tauri 2 (Rust backend + system WebView) |
| Backend | Swift services + Process | Rust services, SSH transport, remote Python payloads |
| Frontend | SwiftUI views | TypeScript + HTML/CSS rendered by Vite |
| Terminal | Vendored SwiftTerm | xterm.js with Rust streaming SSH TTY bridge |
| Packaging | Xcode archive / build-macos-app.sh |
Tauri bundler: .deb, .rpm, .dmg, .msi, .nsis |
| CI | macos-ci.yml (Xcode) |
tauri-ci.yml (Linux + macOS + Windows matrix) |
All Hermes features have been ported:
- Connections — SSH profile CRUD, SSH test, active host selection, legacy Swift data import
- Overview — remote Hermes workspace discovery, profile listing, path/cron/session-store info
- Sessions — remote session list/search/pin/transcript/delete, chat via Hermes TUI resume
- Workflows — local preset storage, skill assignment, Terminal and Chat/TUI launch
- Kanban — board discovery/load/archive, full task lifecycle, dependency editing, dispatcher, home-channel subscriptions
- Files — canonical Hermes files, workspace bookmarks, remote read/write with conflict checks, directory browser
- Cron Jobs — list/search/create/update/pause/resume/run-now/delete with locked atomic JSON writes
- Usage — token totals, top sessions/models, recent trends, multi-profile breakdown
- Skills — remote discovery, detail loading, create/update with conflict checks
- Terminal — live SSH TTY sessions via xterm.js, tabs, theme presets, bracketed-paste input, workflow/session handoff
- Update checks — GitHub Releases polling with 24-hour gate, manual check, release preview
- Localization — English, Russian, Simplified Chinese (reuses upstream
.lprojresources) - Dark/Light theme — default dark, persisted toggle, CSS variable system
|
|
|
|
- Node.js 22+
- Rust 1.80+ (
rustup toolchain install stable) python3available on the Hermes host (remote payloads need it)- SSH access from this machine to the Hermes host, with the host key already accepted
Tauri on Linux requires WebKit2GTK and related system libraries:
# One-liner:
bash scripts/install-tauri-linux-deps.sh
# Or manually:
sudo apt-get update
sudo apt-get install -y \
libwebkit2gtk-4.1-dev \
libgtk-3-dev \
libayatana-appindicator3-dev \
librsvg2-dev \
libdbus-1-dev \
patchelf- macOS 14+ recommended
- Xcode Command Line Tools:
xcode-select --install - No extra Homebrew packages required — Tauri uses the system WebKit
- Visual Studio C++ Build Tools (Desktop development with C++ workload)
- WebView2 — pre-installed on Windows 10 (1803+) and Windows 11
- An SSH client on
PATH(Windows 10+ ships OpenSSH; or use Git for Windows SSH)
# 1. Clone the repository
git clone https://github.com/<your-fork>/hermes-desktop.git
cd hermes-desktop
# 2. Install npm dependencies
npm install
# 3. Run in development mode (hot-reload frontend + Rust backend)
npm run tauri devThe app opens a Tauri window with Vite hot-reload at http://127.0.0.1:5173.
Rust changes trigger an automatic backend rebuild.
hermes-desktop/
├── src/ # TypeScript/HTML/CSS frontend
│ ├── main.ts # Application entry, all UI modules
│ ├── styles.css # Shared layout/component styles
│ ├── themes.css # App theme variables and overrides
│ ├── api.ts # Tauri invoke wrappers
│ ├── types.ts # Shared TypeScript types
│ ├── i18n.ts # Localization engine + dictionaries
│ └── update.ts # GitHub Releases update checker
├── src-tauri/ # Rust backend (Tauri 2)
│ ├── Cargo.toml # Rust dependencies
│ ├── tauri.conf.json # Tauri app configuration
│ └── src/
│ ├── main.rs # Entry point
│ ├── lib.rs # Tauri command surface + app setup
│ ├── models.rs # Shared data models
│ ├── ssh.rs # SSH transport layer
│ ├── remote_python.rs # Remote Python payload wrapper
│ ├── storage.rs # Local app data persistence
│ ├── connection.rs # Connection profile management
│ ├── discovery.rs # Remote Hermes workspace discovery
│ ├── session.rs # Session browser service
│ ├── workflow.rs # Workflow preset management
│ ├── kanban.rs # Kanban board/task service
│ ├── file.rs # Remote file editor service
│ ├── cron.rs # Cron job management service
│ ├── usage.rs # Usage analytics service
│ ├── skill.rs # Skills catalog service
│ ├── terminal.rs # Live SSH TTY bridge
│ └── error.rs # Error types
├── scripts/
│ ├── install-tauri-linux-deps.sh # Linux system dependency installer
│ ├── check-i18n.mjs # Localization coverage checker
│ └── smoke-ui-themes.mjs # UI theme/view smoke test
├── index.html # Vite entry HTML
├── vite.config.ts # Vite configuration
├── package.json # npm scripts and dependencies
└── .github/workflows/
└── tauri-ci.yml # Cross-platform CI (Linux + macOS + Windows)
| Command | Description |
|---|---|
npm run dev |
Start Vite dev server (frontend only) |
npm run build |
TypeScript check + Vite production build |
npm run tauri dev |
Full Tauri dev mode (frontend + Rust backend, hot-reload) |
npm run tauri:build |
Build Tauri bundle for the current platform (all bundle types) |
npm run tauri:build:linux |
Build .deb and .rpm bundles |
npm run tauri:build:macos |
Build .dmg bundle |
npm run tauri:build:windows |
Build .msi and .nsis installers |
npm run test:i18n |
Verify localization key parity across all locales |
npm run test:smoke:ui |
Smoke-check app themes, Sessions, Terminal, and mobile layout |
npm run release:prepare -- 0.10.4 |
Bump app versions and run release checks before a normal git commit/tag/push |
npm run test:smoke:ssh |
Run read-only SSH smoke tests against a real Hermes host |
npm run test:smoke:ssh:mutations |
Run disposable mutation smoke tests against a real host |
# Install system dependencies (first time only)
bash scripts/install-tauri-linux-deps.sh
# Build .deb and .rpm
npm run tauri:build:linuxOutput:
src-tauri/target/release/bundle/deb/hermes-desktop_*.deb
src-tauri/target/release/bundle/rpm/hermes-desktop-*.rpm
Install the .deb:
sudo dpkg -i src-tauri/target/release/bundle/deb/hermes-desktop_*.debInstall the .rpm:
sudo rpm -i src-tauri/target/release/bundle/rpm/hermes-desktop-*.rpmnpm run tauri:build:macosOutput:
src-tauri/target/release/bundle/dmg/Hermes Desktop_*.dmg
Open the .dmg, drag Hermes Desktop.app to Applications.
Note
The current build is ad-hoc signed and not notarized. macOS may show a first-launch warning. Right-click → Open, or go to System Settings → Privacy & Security → Open Anyway.
npm run tauri:build:windowsOutput:
src-tauri\target\release\bundle\msi\Hermes Desktop_*.msi
src-tauri\target\release\bundle\nsis\Hermes Desktop_*-setup.exe
Run the .msi installer or the NSIS setup executable.
Note
Windows builds require Visual Studio C++ Build Tools and WebView2 runtime. WebView2 is pre-installed on Windows 10 (1803+) and all Windows 11 versions.
# Frontend type checking + build
npm run build
# Localization coverage
npm run test:i18n
# UI smoke test (uses Chromium when available, falls back to source invariants)
npm run test:smoke:ui
# Rust unit tests: storage, SSH, remote payloads, terminal, workflows
cargo test --manifest-path src-tauri/Cargo.toml
# Rust formatting check
cargo fmt --manifest-path src-tauri/Cargo.toml -- --check
# Rust type check
cargo check --manifest-path src-tauri/Cargo.tomlRead-only smoke — tests discovery, sessions, files, usage, skills, cron, kanban:
HERMES_SMOKE_HOST=your-host \
HERMES_SMOKE_USER=your-user \
HERMES_SMOKE_HOME='~/.hermes' \
npm run test:smoke:sshDisposable mutation smoke — creates temporary resources under .tauri-smoke,
then cleans up:
HERMES_SMOKE_HOST=your-host \
HERMES_SMOKE_USER=your-user \
HERMES_SMOKE_HOME='~/.hermes' \
HERMES_SMOKE_MUTATIONS=1 \
npm run test:smoke:ssh:mutationsOptional env vars: HERMES_SMOKE_PORT, HERMES_SMOKE_PROFILE.
The GitHub Actions workflow at .github/workflows/tauri-ci.yml runs on every
push, pull request, and manual dispatch.
| Platform | Runner | Bundle output |
|---|---|---|
| Linux | ubuntu-22.04 |
.deb, .rpm, .AppImage |
| macOS | macos-latest |
.dmg |
| Windows | windows-latest |
.msi, .nsis |
- Checkout repository
- Install Linux system dependencies (Linux only)
- Install Rust stable toolchain
- Setup Node.js 22 with npm cache
npm cinpm run test:i18n— localization paritynpm run build— frontend TypeScript + Vitecargo fmt --check— Rust formattingcargo check— Rust compilationcargo test— Rust unit tests- Platform-specific Tauri bundle build
- Upload bundle artifacts
Build artifacts are attached to each CI run and can be downloaded from the GitHub Actions summary page.
Prepare the version bump and local checks:
npm run release:prepare -- 0.10.4The prepare script updates package.json, package-lock.json,
src-tauri/Cargo.toml, src-tauri/Cargo.lock, and
src-tauri/tauri.conf.json, then runs localization, frontend, Rust formatting,
Rust check, and Rust test gates. It does not commit, tag, push, or create a
GitHub Release.
Review the diff, then use the normal git release flow:
git commit -m "Release v0.10.4"
$EDITOR RELEASE_NOTES.md
git tag -a v0.10.4 -F RELEASE_NOTES.md
git push origin main v0.10.4The annotated tag body becomes the GitHub Release notes, so it must explicitly list user-visible changes. Pushing the tag starts the existing GitHub Actions release job; do not create GitHub Releases manually before CI artifacts are ready.
The main Tauri configuration is in
src-tauri/tauri.conf.json:
- Product name:
Hermes Desktop - App identifier:
app.hermes.desktop - Window: 1320×860 default, 980×640 minimum, resizable
- Bundles:
.deb,.rpm,.dmg,.msi,.nsis(platform-dependent) - Category: Developer Tool
| Platform | Path |
|---|---|
| Linux | ~/.local/share/app.hermes.desktop/ |
| macOS | ~/Library/Application Support/app.hermes.desktop/ |
| Windows | %APPDATA%\app.hermes.desktop\ |
Stored data: connections.json, preferences.json, workflow presets, pinned
sessions, bookmarked files.
On macOS, the Tauri app automatically imports legacy Swift app data from
~/Library/Application Support/HermesDesktop/ when Tauri files are missing.
┌──────────────────────────────────────────────────┐
│ Tauri Window │
│ ┌────────────────────────────────────────────┐ │
│ │ TypeScript + HTML/CSS │ │
│ │ Vite HMR │ xterm.js │ i18n │ Update UI │ │
│ └────────────────┬───────────────────────────┘ │
│ │ Tauri IPC (invoke) │
│ ┌────────────────┴───────────────────────────┐ │
│ │ Rust Backend │ │
│ │ SSH Transport │ Remote Python Payloads │ │
│ │ Storage │ Connection │ Discovery │ ... │ │
│ └────────────────┬───────────────────────────┘ │
└───────────────────┼──────────────────────────────┘
│ SSH (system `ssh` binary)
▼
┌───────────────┐
│ Hermes Host │
│ ~/.hermes │
│ python3 │
└───────────────┘
The Rust backend executes commands on the Hermes host over SSH using the
system ssh binary. Remote operations are wrapped in generated Python
payloads that run on the host and return structured JSON. The frontend
communicates with the Rust backend through Tauri's IPC invoke mechanism.
| Feature | Swift app | Tauri app |
|---|---|---|
| Platform | macOS only | Linux, macOS, Windows |
| Terminal | SwiftTerm (native) | xterm.js (web-based) |
| Theme | System macOS appearance | Built-in dark/light toggle |
| Keyboard shortcuts | macOS Cmd+… | Platform-adaptive Cmd/Ctrl+… |
| Packaging | .app bundle + zip |
.deb, .rpm, .dmg, .msi, .nsis |
| Code signing | Ad-hoc macOS signing | Not yet (deferred) |
| Auto-update | GitHub Releases check | GitHub Releases check (same) |
error: could not find system library 'webkit2gtk-4.1'
Install the required packages:
bash scripts/install-tauri-linux-deps.shRight-click Hermes Desktop.app → Open → Confirm. Or: System Settings →
Privacy & Security → Open Anyway.
Download and install WebView2 Runtime from Microsoft. Already included on Windows 10 (1803+) and Windows 11.
Ensure OpenSSH is on your PATH. Windows 10+ includes OpenSSH as an optional
feature: Settings → Apps → Optional Features → OpenSSH Client.
Alternatively, add Git for Windows SSH to your PATH.
Ensure Rust 1.80+ is installed:
rustup update stable
rustup default stableThe cargo test suite includes tests that compile generated Python payloads
with python3 -m py_compile. Ensure python3 is available locally for these
tests to pass.
- README.md — Original upstream project documentation



