TL;DR
hermes update on Windows has four critical bugs:
- Refuses to run when the Desktop app is open (asks user to "close the desktop manually", but
slash_worker outlives Hermes.exe for several seconds — user can't tell when it's safe).
- Tree-kills the active chat session — the user's
tui_gateway.slash_worker is a grandchild of Hermes.exe and gets swept up in taskkill /IM Hermes.exe /T /F. Chat disappears mid-stream. Claude Code never does this.
- Silently destroys local un-pushed commits — does
git reset --hard origin/main with no prompt, no warning. Commits survive only in the reflog (30-90 days, then gone).
- Doesn't reliably restart the Desktop after update —
atexit-registered relaunch doesn't fire on all Windows exit paths. ~1/3 updates leaves the user with no desktop.
Reproduction
git clone <https://github.com/NousResearch/hermes-agent>
cd hermes-agent
hermes desktop # launches Hermes.exe
# open a chat, start streaming
# in another shell:
hermes update
# → 5-10s desktop black-out, chat gone, any un-pushed commits vanished
Root cause
apps/desktop/release/win-unpacked/Hermes.exe is an unpacked dev build (not an NSIS installer). Its python.exe -m hermes_cli.main serve backend holds .pyd files in the venv mandatory-locked while running. hermes update either (a) refuses to run because of this lock, (b) kills the desktop to release it, or (c) silently rewrites the user's local git history in the process.
apps/desktop/electron/main.ts:2390-2480 already has the right self-restart machinery (releaseBackendLockForUpdate) for the desktop's own in-app update — it's just not exposed to the hermes update CLI.
Proposed fix
hermes update should detect Desktop-owned venv-holders (via HERMES_DESKTOP=1 env + parent-chain), and tree-kill only the main + backend — exclude tui_gateway.slash_worker by cmdline match so the chat survives.
- Smart-skip the heavy rebuilds when only Python source changed:
git diff --name-only FETCH_HEAD..HEAD → if only hermes_cli/, hermes_constants/, docs changed → skip pip install, npm install, vite build, electron-builder. Pure source updates become "git pull + bytecode cache clear + desktop reload" — no .pyd locks taken, no desktop black-out.
- Pre-flight check in
hermes update: if git log --oneline origin/main..HEAD is non-empty, refuse with "push or stash first". Add --force-divergent-update for the rare override case.
- Belt-and-suspenders relaunch: a
finally block in the cmd_update wrapper (in addition to atexit) so the Desktop re-launches on every exit path.
A working implementation of all four is in our local fork at:
b795d7fc8 fix(update): auto-close + relaunch Desktop around hermes update on Windows
332c2f8c4 fix(update): precise-PID kill — keep chat / renderer alive
b007b9b43 test(update): cover self-restart helpers
a374e6596 feat(update): smart-skip — only rebuild what actually changed
efdd3dbe0 fix(update): chat survival + reliable relaunch + smart-skip fetch awareness
The patch file is attached (hermes-self-restart-desktop.patch, applies cleanly to main at 0.18.2 / commit 7b5ba2054). We can submit as a PR if reviewers are interested.
Why this matters
Hermes Desktop is positioned as the user-friendly, end-user surface for the project. The current update experience is bad enough that a user who tries it once will never try it again — they'll pin a version, go back to the CLI, or switch to Claude Code (which "just works" through its own update cycle).
The fixes are small (1-3 days of work), well-understood, and don't require an architecture change. They need to be in the next release.
TL;DR
hermes updateon Windows has four critical bugs:slash_workeroutlivesHermes.exefor several seconds — user can't tell when it's safe).tui_gateway.slash_workeris a grandchild ofHermes.exeand gets swept up intaskkill /IM Hermes.exe /T /F. Chat disappears mid-stream. Claude Code never does this.git reset --hard origin/mainwith no prompt, no warning. Commits survive only in the reflog (30-90 days, then gone).atexit-registered relaunch doesn't fire on all Windows exit paths. ~1/3 updates leaves the user with no desktop.Reproduction
Root cause
apps/desktop/release/win-unpacked/Hermes.exeis an unpacked dev build (not an NSIS installer). Itspython.exe -m hermes_cli.main servebackend holds.pydfiles in the venv mandatory-locked while running.hermes updateeither (a) refuses to run because of this lock, (b) kills the desktop to release it, or (c) silently rewrites the user's local git history in the process.apps/desktop/electron/main.ts:2390-2480already has the right self-restart machinery (releaseBackendLockForUpdate) for the desktop's own in-app update — it's just not exposed to thehermes updateCLI.Proposed fix
hermes updateshould detect Desktop-owned venv-holders (viaHERMES_DESKTOP=1env + parent-chain), and tree-kill only the main + backend — excludetui_gateway.slash_workerby cmdline match so the chat survives.git diff --name-only FETCH_HEAD..HEAD→ if onlyhermes_cli/,hermes_constants/, docs changed → skippip install,npm install,vite build,electron-builder. Pure source updates become "git pull + bytecode cache clear + desktop reload" — no.pydlocks taken, no desktop black-out.hermes update: ifgit log --oneline origin/main..HEADis non-empty, refuse with "push or stash first". Add--force-divergent-updatefor the rare override case.finallyblock in thecmd_updatewrapper (in addition toatexit) so the Desktop re-launches on every exit path.A working implementation of all four is in our local fork at:
The patch file is attached (
hermes-self-restart-desktop.patch, applies cleanly tomainat 0.18.2 / commit7b5ba2054). We can submit as a PR if reviewers are interested.Why this matters
Hermes Desktop is positioned as the user-friendly, end-user surface for the project. The current update experience is bad enough that a user who tries it once will never try it again — they'll pin a version, go back to the CLI, or switch to Claude Code (which "just works" through its own update cycle).
The fixes are small (1-3 days of work), well-understood, and don't require an architecture change. They need to be in the next release.