Default Electron to the gnome-libsecret password store so Hermes can use GNOME Keyring for secure remote tokens. Declare libsecret as a runtime dependency.
Tidying the terminal agent's Hermes away only happened in the menu installer,
so `pacman -S hermes-desktop` on its own, or an install interrupted after the
package landed, left two Hermeses -- and by then the menu entry that would
have noticed is disabled, because we are installed.
Co-Authored-By: Codex XHigh <noreply@openai.com>
Pairing the app with the mise CLI does not work, and pinning the app back to
the tag behind PyPI's release does not rescue it: v2026.7.20's desktop reaches
"backend is ready" and then hangs without ever opening a window, against its
own matching runtime. Only the newest app against a runtime built from its own
commit starts, which is the arrangement upstream ships.
So the package returns to the newest tag and the launcher sets
HERMES_DESKTOP_IGNORE_EXISTING, which keeps the app off whatever hermes is on
PATH -- on Omarchy that is the mise CLI installed for the terminal agent, a
different release, and the version gap is what produced the 401. The app
provisions ~/.hermes itself on first launch instead.
mise and uv are no longer dependencies, since the launcher no longer installs
anything; git and curl are, because the app's own bootstrap needs them.
Built from v2026.8.18 against the CLI on PyPI, the app never starts: it
resolves the CLI, launches the backend, and then fails its readiness probe
with 401 Unauthorized. The two have to agree on the dashboard session-token
handshake -- the app scrapes window.__HERMES_SESSION_TOKEN__ out of the served
HTML, and web_server.py falls back to a random token when it cannot agree, so
every probe after that is rejected. A month separated the two: the tag was
2026-08-18, hermes-agent 0.19.0 on PyPI was 2026-07-20.
Upstream never meets this because their installer builds the app from the same
checkout it installs the CLI from. Pinning the CLI forward to the app's commit
is not open to us either -- Hermes refuses a non-editable install from a git
checkout and tells you to use `uv sync` instead. So the app is pinned back
instead, to the tag PyPI's current release was cut from.
Verified on a worker: the desktop reaches "Hermes backend is ready" and maps
its window, where the newer build stopped at the 401 every time.
The launcher only delegated to omarchy-install-hermes-cli and, when that was
absent, printed a warning to stderr -- which nothing sees under a graphical
launch -- and started the app anyway. The app then offered to install Hermes
itself, and that copy wins permanently: it checks ~/.hermes/hermes-agent
before it checks PATH, so installing the CLI afterwards changes nothing until
that directory is deleted.
So install it here when omarchy's script isn't around, with the same
interpreter pin and the same exported cooldown, and hand the app the real
executable by putting the mise install's bin directory on PATH instead of
leaving it to search. Its probe allows 15 seconds; resolving this way takes
0.2. mise and uv become dependencies, which is what makes the package
self-sufficient on a machine without Omarchy.
Pin the build stamp. write-build-stamp.mjs resolves the commit the app pins
its first-launch bootstrap to, preferring $GITHUB_SHA and otherwise running
`git rev-parse`. That fallback is wrong under makepkg: the build happens
inside this repository, so git ascends out of srcdir and stamps the app with
an omarchy-pkgs commit that means nothing upstream. Confirmed by rebuilding --
the stamp now reads the tag's own commit rather than this repo's HEAD.
Ship upstream's MIT licence. The package declares MIT and was installing only
Electron's licence text.
Repair a drifted CLI before launching rather than only a missing one. `mise
up` can leave Hermes rebuilt against the system Python, and a stub can be
there but cold; either way the wrapper's own repair takes minutes while the
app allows 15 seconds before bootstrapping its own copy. Running the installer
unconditionally costs nothing when Hermes is healthy.
Register the hermes:// scheme. The desktop entry took %U while declaring no
MimeType, so the scheme electron-builder configures went unhandled.
Chromium falls back to XWayland often enough to matter, and the result is a
blurry window on every scaled display -- the same reason the ChatGPT and Grok
Bot launchers set this. Skipped when the caller has already named a platform.
Install > AI is for GUI apps, so the package becomes the desktop shell and the
terminal agent moves to a lazy mise stub that omarchy installs itself.
Nous builds Hermes Desktop for macOS and Windows only -- their download page
offers a .dmg and an .exe and points Linux users at a terminal install -- so
there is no vendor binary to repackage the way grok-bot repackages xAI's deb.
Their electron-builder config does carry a Linux target though, untested by
upstream but working: npm ci at the workspace root, npm run pack in
apps/desktop, and electron-builder stages node-pty and get-windows for
linux-x64 on its own. 337 MB unpacked, 129 MB packaged.
The app is only a shell -- it runs `hermes serve` against a CLI it does not
ship, and clones its own unpinned copy into ~/.hermes when it finds none. So
/usr/bin/hermes-desktop makes sure the CLI is there before handing over, and
says so plainly rather than bootstrapping a second Hermes where Omarchy's
installer isn't around to do it properly.