Installing the CLI Experimental
Prebuilt, self-contained CLI binaries ship for Windows x64, Linux x64, and macOS x64/arm64 — no Node or Python required. Windows also has an optional native, menu-only systray installer.
Prerequisites
- A running Hermes-Relay server reachable from this machine.
curl -s http://<host>:8767/healthshould return{"status":"ok"}. - That's it. The binary is self-contained (Bun-compiled, ~60–110 MB, depending on platform).
If you'd rather install from source, see the source install section below — but the binary is the recommended path.
Windows — PowerShell one-liner
powershell
irm https://raw.githubusercontent.com/Codename-11/hermes-relay/main/desktop/scripts/install.ps1 | iexBy default the script installs the Windows CLI and optional systray through the signed-checksum NSIS package. It:
- Detects architecture (x64; ARM64 lands once Bun's cross-compile target stabilizes).
- Resolves the latest CLI release by querying the GitHub Releases API directly and picking the SemVer-max
cli-v*tag, with a migration fallback to historicaldesktop-v*prereleases. Prereleases are included, so alpha builds aren't skipped (see CHANGELOG entry on alpha.11 for why this matters). - Downloads
hermes-relay-windows-x64-setup.exeand verifies SHA256 against the publishedSHA256SUMS.txt. - Runs the per-user installer. No administrator access is required.
- Installs
hermes-relay.exe,hermes-relay-tray.exe, and the uninstaller to%USERPROFILE%\.hermes\bin. - Adds that directory to your user PATH and creates Start-menu shortcuts for the TUI, systray, and uninstaller.
- Offers an optional Start systray when I sign in component. The same preference can be changed later from the tray menu.
- Starts the systray from the finish page when selected. The tray has no application window; right-click its notification-area icon.
For a CLI-only install, set the surface explicitly. This path downloads and verifies hermes-relay-win-x64.exe directly and prints the existing/new version comparison:
powershell
$env:HERMES_RELAY_INSTALL_SURFACE = 'cli'
irm https://raw.githubusercontent.com/Codename-11/hermes-relay/main/desktop/scripts/install.ps1 | iexOpen a new terminal (PATH updates don't retroactively apply to in-process shells), then verify:
powershell
hermes-relay --version
hermes-relay daemon statusSmartScreen warning on first launch
The binaries are unsigned during the experimental phase. Windows may show "Windows protected your PC" for the installer or first launch. Click More info → Run anyway. For a CLI-only install, you can also pre-allow the executable from PowerShell:
powershell
Unblock-File "$env:USERPROFILE\.hermes\bin\hermes-relay.exe"Code signing (EV cert) is a v1.0 milestone — the experimental phase doesn't justify the $300/yr.
Pin a specific version
powershell
$env:HERMES_RELAY_VERSION = 'cli-v0.4.0-alpha.2'
irm https://raw.githubusercontent.com/Codename-11/hermes-relay/main/desktop/scripts/install.ps1 | iexThe resolver compares full SemVer including the prerelease tail, so an older alpha is correctly recognized as an upgrade.
Uninstall
Use Apps → Installed apps → Hermes Relay CLI + Systray, the Start-menu uninstaller, or %USERPROFILE%\.hermes\bin\uninstall-hermes-relay.exe. Uninstall stops the tray and daemon, removes the installed binaries, Start-menu shortcuts, sign-in entry, and user-PATH entry, while preserving pairing/session data.
macOS / Linux — curl one-liner
bash
curl -fsSL https://raw.githubusercontent.com/Codename-11/hermes-relay/main/desktop/scripts/install.sh | shThe script:
Detects OS/arch (published assets:
linux-x64,darwin-x64, anddarwin-arm64).Resolves the latest
cli-v*release via the Releases API +sort -V, with a migration fallback to historicaldesktop-v*prereleases (prerelease-aware, no shell deps beyondcurl/sort).Downloads the matching binary +
SHA256SUMS.txtand verifies SHA256 (sha256sumon Linux,shasum -a 256on macOS).Reads the existing binary's
--versionif present and printsupgrading X → Y/reinstalling X/installing fresh.Installs to
$HOME/.hermes/bin/hermes-relay(mode 0755).Creates a
hermessymlink next to the binary — same collision-safety as Windows: skipped if anything already exists at that path.Hints how to add
$HOME/.hermes/binto your PATH if it isn't already — does not mutate your shell rc silently. Add the line yourself:bashexport PATH="$HOME/.hermes/bin:$PATH"Put it in
~/.bashrc/~/.zshrc/~/.config/fish/config.fishdepending on your shell.Re-runs the new binary's
--versionpost-install to confirm.
Verify in a fresh shell:
bash
hermes-relay --version
hermes --versionmacOS quarantine
Unsigned binaries get quarantined by Gatekeeper on first run. If macOS refuses to open the binary, clear the xattr:
bash
xattr -dr com.apple.quarantine ~/.hermes/bin/hermes-relayApple Developer ID signing + notarization is a v1.0 milestone.
Pin a specific version
bash
HERMES_RELAY_VERSION=cli-v0.4.0-alpha.2 \
curl -fsSL https://raw.githubusercontent.com/Codename-11/hermes-relay/main/desktop/scripts/install.sh | shUninstall
See Uninstall below — the curl one-liner reverses install.sh, with optional tiers for session-data purge and service cleanup.
Self-update — hermes-relay update
Once installed, you don't have to keep re-running the curl | sh one-liner. The binary self-updates:
bash
hermes-relay update # download + verify + swap to latest cli-v*
hermes-relay update --check # dry-run: print available version, don't install
hermes-relay update --yes # skip confirm prompt
hermes-relay update --json # machine-readable statusThe updater:
- Polls the GitHub Releases API and picks the SemVer-max
cli-v*tag, with a migration fallback to historicaldesktop-v*prereleases (prereleases included). The same resolver as the install scripts — fixed in alpha.11; pre-alpha.11 builds may report "Up to date" when a newer alpha exists, so use the install one-liner once to bootstrap onto alpha.11+ if you're stuck below it. - SemVer-compares to your running version (
hermes-relay --version— embedded at build time, accurate inside Bun-compiled binaries). - Downloads the platform asset and verifies SHA256.
- POSIX (macOS / Linux): atomic
fs.renameover the running binary. The running process keeps the old inode open, sohermes-relay daemon(if running) keeps serving until restarted; the nexthermes-relay <verb>invocation picks up the new binary. - Windows: can't replace a running
.exe, so the updater writes to<bin>.new.exeandfinalizePendingUpdate()runs at the top ofmain()on every subsequent invocation to rename it into place. Result: the swap completes the next time you runhermes-relay.
hermes-relay update updates the CLI binary only. Windows systray/installer changes ship in the same release but require rerunning the PowerShell installer (or downloading the new setup asset) so both executables stay on the same version.
If hermes-relay update --check says "Up to date" but you know there's a newer alpha, see the troubleshooting note.
Install from source (Node ≥21)
For dev / contributors / custom builds:
bash
git clone https://github.com/Codename-11/hermes-relay
cd hermes-relay/desktop
npm install
npm run build
npm link # puts `hermes-relay` on your PATH via the npm global bin dirDev loop — skip the tsc build, run TypeScript directly:
bash
npx tsx src/cli.ts --help
npx tsx src/cli.ts pair --remote ws://<host>:8767The package name in desktop/package.json is local workspace metadata today. The CLI is not published to npm; use GitHub Release binaries or a local clone with npm link.
Uninstall
The uninstallers mirror the installers — one-liners on both platforms, three removal tiers.
Tiers
| Flag | What it removes |
|---|---|
| (default) | $HOME/.hermes/bin/hermes-relay[.exe] plus the hermes / hermes.cmd alias (only if it points at our binary) and the Windows user-PATH entry. Preserves ~/.hermes/remote-sessions.json. |
--purge | Also deletes ~/.hermes/remote-sessions.json — bearer tokens, cert pins, and the tools-consent flag. |
--service | Stub. Prints the commands to remove a manually-installed systemd unit, launchd plist, or Windows service. No service installers ship yet. |
Tiers combine: --purge --service runs both.
--purge warning: remote-sessions.json is shared with the Ink TUI and the Hermes Android desktop tooling. Wiping it signs those surfaces out too. Use --purge when giving a machine away — not for routine cleanup.
Windows
powershell
# Binary + user-PATH entry only (default)
irm https://raw.githubusercontent.com/Codename-11/hermes-relay/main/desktop/scripts/uninstall.ps1 | iex
# Also purge session tokens — iex can't forward args, so set env first
$env:HERMES_RELAY_UNINSTALL_PURGE = 1
irm https://raw.githubusercontent.com/Codename-11/hermes-relay/main/desktop/scripts/uninstall.ps1 | iexThe script removes %USERPROFILE%\.hermes\bin\hermes-relay.exe, the hermes.cmd alias (if it points at our binary), strips that directory from your user PATH (not system — no admin needed), and removes the install dir if it's empty.
Open a new terminal afterward so shells pick up the PATH change.
macOS / Linux
bash
# Binary only (default)
curl -fsSL https://raw.githubusercontent.com/Codename-11/hermes-relay/main/desktop/scripts/uninstall.sh | sh
# Also purge session tokens
curl -fsSL https://raw.githubusercontent.com/Codename-11/hermes-relay/main/desktop/scripts/uninstall.sh | sh -s -- --purgeinstall.sh never touches your shell rc, so neither does uninstall.sh. If you added $HOME/.hermes/bin to your PATH manually, remove that line from your rc yourself — the script prints a reminder.
Override install dir
Both scripts honor the same env var as the installers:
bash
HERMES_RELAY_INSTALL_DIR=/opt/hermes \
curl -fsSL https://raw.githubusercontent.com/Codename-11/hermes-relay/main/desktop/scripts/uninstall.sh | shpowershell
$env:HERMES_RELAY_INSTALL_DIR = 'C:\tools\hermes\bin'
irm https://raw.githubusercontent.com/Codename-11/hermes-relay/main/desktop/scripts/uninstall.ps1 | iexVerify
After install, all of these should succeed:
bash
hermes-relay --version # 0.x.x (matches release tag)
hermes-relay --help # Full help text — every subcommand listed
hermes-relay status # Local view — no sessions stored yet
hermes-relay doctor # Full local diagnostic (version / paths / sessions / daemon)
hermes --version # Alias resolves to the same binaryNext step: Pairing — mint a code on the server and exchange it for a stored session token.