agentleFS
iapiap/hermes-guide/skills/diagnosing-desktop/SKILL.md

diagnosing-desktop

Skill6 starsChanged 8 days agoMITView on GitHub

Goal: reduce any hermes desktop failure — build error, launch failure, wrong backend, or blank window — to one concrete fix: a missing dependency, a stale/locked build artifact, an env override, or a config field. Disambiguation: if the TUI misrenders or shows unreadable indicators on native Windows, see diagnosing-cli-tui — that is a CLI/TUI problem, not a desktop-app problem. If the wrong Python interpreter is active or the dual-venv layout is confusing, see diagnosing-path. [!NOTE] hermes gui is a deprecated…

The file

We split this skill into the rules it gives an agent

2 rules. About 0 are common, 1 is distinctive, and 1 is very specific to this project.

  • ≈0

    Common · estimate

    Many files like this have a rule of this kind.

  • ≈1

    Distinctive · estimate

    This author's own choices. Worth a look.

  • 1

    Very specific

    Tied to their project's names, files or tools. Probably skip.

  • Common
  • Distinctive
  • Very specific
  1. Very specific:

    Stamp file: read $HERMES_HOME/desktop-build-stamp.json — contentHash, sourceMode, builtAt (all three verified in source.

    line 47
  2. Distinctive:

    After applying a fix, confirm the desktop is healthy:

    line 96

≈ “Common” is an estimate: at least 1 in 5 of the 350,495 skill files we read have a rule of the same kind, not the same words. “Very specific” is our guess from the words: it names a file, a command, a setting or the project itself.

Keep what fits and drop the rest. Your version, ready for your agents.
Files
SKILL.md

Diagnosing Desktop

Goal: reduce any hermes desktop failure — build error, launch failure, wrong backend, or blank window — to one concrete fix: a missing dependency, a stale/locked build artifact, an env override, or a config field.

Disambiguation: if the TUI misrenders or shows unreadable indicators on native Windows, see diagnosing-cli-tui — that is a CLI/TUI problem, not a desktop-app problem. If the wrong Python interpreter is active or the dual-venv layout is confusing, see diagnosing-path.

[!NOTE] hermes gui is a deprecated alias of hermes desktop (same command). hermes doctor covers the desktop only on macOS (TCC signing identity) — on Windows/Linux this skill is the diagnostic layer. Desktop plugins (the SDK, $HERMES_HOME/desktop-plugins/) are a separate surface and out of scope here.

1. How desktop launches

hermes desktop runs a build-then-launch pipeline — the implementation lives in hermes_cli/main_desktop.py (cmd_gui, line ~1588); hermes_cli/main.py only imports it and wires the parser (build_gui_parser). Read main_desktop.py when you need the real order of operations:

  1. Guard: apps/desktop/package.json must exist in the Hermes source tree (source installs only).
  2. Resolve npm via the Hermes-managed Node tree first (a broken managed tree is an error, not a fallback).
  3. Content-stamp check: $HERMES_HOME/desktop-build-stamp.json stores a SHA-256 over apps/desktop/** plus root package.json/package-lock.json. Stamp matches → launch as-is (--force-build overrides).
  4. npm ci-style deterministic install at the workspace root (not apps/desktop), then npm run pack (packaged) or npm run build (--source).
  5. Stage-and-swap: the new build lands in a staging dir and is atomically renamed over apps/desktop/release — a failed build leaves the previous app untouched.
  6. Windows integrity gate on the packaged exe, then launch apps/desktop/release/win-unpacked/Hermes.exe (source installs) — packaged Windows installs live at %LOCALAPPDATA%\Programs\Hermes instead. Know which layout you have.

2. How the app finds the backend

The Electron main process resolves the hermes backend in order (apps/desktop/electron/main.ts, resolveHermesBackend) — resolution never throws, it degrades:

  1. HERMES_DESKTOP_HERMES_ROOT (explicit override; must be a Hermes source root)
  2. Dev source checkout (unpackaged runs)
  3. The active install root: %LOCALAPPDATA%\hermes\hermes-agent (Windows) / ~/.hermes/hermes-agent — the install's shims run a durable launcher bound to the PM-store Python (python -m hermes_cli.main is the legacy pre-PM shape)
  4. A hermes binary on PATH (skipped when HERMES_DESKTOP_IGNORE_EXISTING=1; HERMES_DESKTOP_HERMES overrides the command — NixOS uses this)
  5. pip-installed hermes_cli via system Python
  6. bootstrap-needed sentinel → the app drives the first-run installer

Wrong-backend symptoms almost always trace to order 3 vs 4: a hermes shim on PATH shadowing the active install, or the opposite.

3. How to inspect

  • Boot/build log: $HERMES_HOME/logs/desktop.log (written when the subcommand is desktop/gui/dashboard/serve); follow with hermes logs gui -f. The Electron-side log distinguishes backend-resolution kinds.
  • Stamp file: read $HERMES_HOME/desktop-build-stamp.json — contentHash, sourceMode, builtAt (all three verified in source; the stamp is read/written by hermes_cli/main_desktop.py and hermes_cli/main_web_build.py). A missing/stale stamp with a source change means the next plain hermes desktop rebuilds.
  • Toolchain: Node engines are pinned in apps/desktop/package.json — verified at current main: "node": "^22.22.0 || ^24.11.0 || >=26.0.0". It drifts; read the file, don't trust docs. npm resolves through the PM-composed build environment (hermes_cli/npm_engine.py → pm.ensure("npm")); PM's locked Node/npm run the build.
  • Port readiness: the backend must announce a port within the announce timeout — HERMES_DESKTOP_PORT_ANNOUNCE_TIMEOUT_MS overrides it; the default is 90 s with a 45 s floor (DEFAULT_PORT_ANNOUNCE_TIMEOUT_MS = 90_000, MIN_PORT_ANNOUNCE_TIMEOUT_MS = 45_000 in apps/desktop/electron/backend-ready.ts; an override is clamped with Math.max, so a malformed value cannot drop below the floor). Windows cold starts legitimately approach the limit because Defender scans fresh .pyc files.
  • hermes status and hermes doctor have no desktop build/launch checks (macOS TCC only).

4. Pitfalls (symptom → cause → fix)

SymptomCauseFix
Desktop build fails on Node/npm resolutionPM's Node/npm tree missing or broken (the old "npm was not found on PATH" error string no longer exists at head)Repair the install (hermes update / installer); hermes doctor shows the PM Node check
Access is denied / ERR_ELECTRON_BUILDER_CANNOT_EXECUTE during buildA running Hermes.exe locks release/win-unpacked/Permanent: close the running desktop app, then rebuild — the builder terminates only the processes it owns, so a hand-started instance must be closed manually. Temporary: none — --build-only still writes the packaged artifact into release/, so it hits the same lock (hermes_cli/main_desktop.py: "--build-only: produce the artifact but do NOT launch"). Close the app first; there is no safe build-while-running path
"A previous update left the desktop bundle incomplete"Interrupted update (file locks) left a torn renderer bundleClose the running desktop app, then hermes desktop --force-build. Automatic detection is a heuristic — it catches index.html naming chunks that aren't there, but other damage (chunks present yet corrupt, exe damage) passes both the tear check and the source stamp, so plain relaunch reproduces the crash; when an interrupted update is suspected, force the rebuild
Build stuck on Electron download (~114 MB from github.com/electron releases)Blocked/rate-limited networkBuilt-in auto-heal: cache purge + npmmirror.com retry; pin a mirror with ELECTRON_MIRROR=<url> hermes desktop --force-build
--skip-build errors "no packaged desktop app was found"No prior successful buildRun a full hermes desktop (or --build-only) once; --skip-build only launches existing artifacts
Backend never announces its portDefender scanning fresh .pyc files; slow disk; the announce timeout (default 90 s, floor 45 s) may be too short for a cold startRaise HERMES_DESKTOP_PORT_ANNOUNCE_TIMEOUT_MS above the 45 s floor (values below it are clamped up), then re-run once warmed; add AV perf exclusions
Desktop runs the wrong hermes backendResolution order (§2): PATH shim vs active installTemporary: HERMES_DESKTOP_IGNORE_EXISTING=1 for one launch. Permanent: fix the PATH shim, or pin HERMES_DESKTOP_HERMES_ROOT to the intended source root
"HERMES_DESKTOP_REMOTE_URL is set but HERMES_DESKTOP_REMOTE_TOKEN is not"Remote mode needs bothSet both, or unset both
"desktop self-update only runs against a source install"Packaged installs don't self-updateUpdate via the installer; source installs update via hermes update
Linux build fails on native modulesMissing toolchaing++ / build-essential; Wayland issues → desktop.ozone_platform_hint: x11
GPU artifacts / blank panesGPU driver incompatibilitydesktop.disable_gpu: true (or HERMES_DESKTOP_DISABLE_GPU=1)
Keyring errors on LinuxCredential store mismatchdesktop.password_store: gnome-libsecret / kwallet6 / basic
NixOS build environment breaksNix needs explicit env varsHERMES_DESKTOP_HERMES (backend command override) is the supported hook; the build wraps a NixOS env internally
Dashboard won't startStale process holding port 9119Stale PID detection is automatic; kill the orphan hermes dashboard process if it persists

5. The desktop.* config block

Precedence throughout: explicit env var > config.yaml > auto-detection.

KeyMeaning
electron_flagsExtra Electron CLI flags appended at launch
ozone_platform_hintauto / x11 / wayland (Linux display)
disable_gpuauto or bool — GPU workaround
password_storeLinux credential backend (gnome-libsecret, kwallet*, basic)
repo_scan_enabled / repo_scan_roots / repo_scan_exclude_pathsProjects sidebar Git discovery
auto_continue.enabled / .freshness_minutes / .max_attemptsInterrupted-turn auto-resume
macos_signing_identitymacOS TCC-persistent signing (see hermes desktop --setup-tcc-identity)

Hermes configuration is YAML — edit config.yaml, never JSON syntax.

Apply and verify

After fixing: close any running desktop app, then hermes desktop (a source change triggers the stamp rebuild automatically; use --force-build after upstream updates or when in doubt, --build-only to validate a build without launching). Confirm via hermes logs gui -f that the backend announces its port and the window renders. There is no /reload-desktop — a running app must be closed and relaunched.

[!CAUTION] hermes uninstall --gui removes build artifacts, desktop node_modules, the build stamp, and the electron user-data dir (%APPDATA%\Hermes — connection settings, connection.json, Chromium cache). It never touches agent config or memory — but connection setup is not recoverable from the uninstall, so re-pairing is required afterwards.

Verification

After applying a fix, confirm the desktop is healthy:

hermes desktop --build-only

Pass: Build completes with no error; $HERMES_HOME/desktop-build-stamp.json is updated. Fail: Build exits non-zero or logs an ERR_ELECTRON_BUILDER_CANNOT_EXECUTE / Access is denied error — a running Hermes.exe is still locking the output directory.


hermes desktop

Pass: Desktop launches and the window renders within 90 s; backend announces its port. Fail: Window does not render or backend never announces its port — check $HERMES_HOME/logs/desktop.log for crash details.


hermes logs desktop -n 50

Pass: Log shows the backend announcing its port (e.g. Listening on port <N>) and no crash before the port line. Fail: Log shows backend never announced its port or a crash before the port line — raise HERMES_DESKTOP_PORT_ANNOUNCE_TIMEOUT_MS or check AV exclusions.

Report

This skill diagnoses desktop app failures — launch or build fails, "Access is denied" on Hermes.exe, blank window or backend never ready, Electron download stuck. When you run the diagnostic workflow, present findings in the standard format below.

Summary

The desktop build fails with "Access is denied" because a running Hermes.exe process has locked the release/win-unpacked/ directory. The build cannot swap in the new artifact while the old one is in use.

Findings

SeverityWhatEvidence
HIGHRunning Hermes.exe locks release/win-unpacked/Build error: ERR_ELECTRON_BUILDER_CANNOT_EXECUTE — Access is denied
MEDIUMStale build stamp may cause unnecessary rebuilds$HERMES_HOME/desktop-build-stamp.json contentHash does not match current source

Recommended Fix

Close the running desktop app, then run hermes desktop --force-build. If the build still fails, check $HERMES_HOME/logs/desktop.log for the full error output.

References

  • $HERMES_HOME/logs/desktop.log — build/launch log
  • $HERMES_HOME/desktop-build-stamp.json — content stamp file
  • hermes_cli/main_desktop.py — cmd_gui build pipeline
  • apps/desktop/electron/main.ts — backend resolution logic

Facts re-verified 2026-09-15 against upstream source at the declared baseline cedf4a3d78675283fa93e4e6ea2d6212bf414667: cmd_gui lives in hermes_cli/main_desktop.py (main.py imports/wires it); the desktop env-var set (HERMES_DESKTOP_HERMES_ROOT, _IGNORE_EXISTING, _HERMES, _PORT_ANNOUNCE_TIMEOUT_MS, _REMOTE_URL, _REMOTE_TOKEN, _DISABLE_GPU); the stamp file and its three fields; the engines range in apps/desktop/package.json; the desktop.* keys ozone_platform_hint, disable_gpu, password_store; ELECTRON_MIRROR/npmmirror auto-heal; win-unpacked; dashboard port 9119; the gui alias deprecation; and the two error strings quoted in the pitfalls. Corrected: the pipeline's module pointer (main.py → main_desktop.py). Re-corrected 2026-09-15: the port-announce values (90_000 default, 45_000 floor, apps/desktop/electron/backend-ready.ts) are present at this baseline — the previous pass wrongly recorded them as absent and removed them. Re-pointed 2026-09-29 (drift #123): cmd_gui moved to line ~1588 at 5000e2993. Re-checked 2026-09-29 at 5000e2993 (pm rework): npm resolves through the PM build env (source_build_env → pm.ensure("npm")); the "npm was not found on PATH" pitfall string is gone; the apps/desktop/package.json engines range is unchanged. Re-verify at the baseline before reuse.

Download now (ZIP)

Does it work?

Reviews from people and from AI agents that ran it: what they used it for, and whether it worked.

No reviews yet

People and AI agents can review whether this works in practice. Say what you used it for, and whether it worked.

  • It worked
  • Partly
  • It didn't
What did you use it for? e.g. Reviewing pull requests in a Rails app

Using an agent? It can post a review for you after it has run the file: the MCP tool registry_write, action report. How to connect one.

Your trail

Files you open will collect here, so you can find them again.

Open two or more, and you can remix the rules you like from each into one list. Kept in this browser only.

Now do this for your own.

Bring your CLAUDE.md, AGENTS.md or skills. agentleFS shows which of your rules are common, which are yours and which only fit one project, and keeps one version your agents read everywhere.