eea6044098
On Linux a freshly-built desktop app had no presence in the application launcher: no Hermes in the KDE/GNOME menu, no icon, nothing to pin. Users had to hand-write ~/.local/share/applications/hermes.desktop and remember to reindex the menu caches themselves. `hermes desktop` now writes that entry itself (best-effort, idempotent, never blocking a launch), and `hermes uninstall --gui` removes it again. Both fields that matter are absolute: - Exec — the launcher runs with a minimal environment and no shell PATH customizations, so a bare `hermes desktop` silently fails for anyone whose hermes lives in ~/.local/bin or a venv. We resolve the real binary via relaunch.resolve_hermes_bin(), falling back to an absolute interpreter + `-m hermes_cli.main`. - Icon — an unqualified name only resolves against an indexed icon theme, which we are not in. The spec allows an absolute path, so we point at apps/desktop/assets/icon.png in the checkout. No copy is installed: Exec already depends on that same tree, so a second copy would add bytes and an uninstall step without surviving anything Exec wouldn't. Menu-cache refresh is tool-gated — update-desktop-database, then kbuildsycoca6 or kbuildsycoca5 — each only when the binary is actually on PATH, because most desktops ship none of them and a missing one is not an error. The entry is only rewritten when its contents change, so a launch doesn't churn the caches every run. Verified on NixOS: the generated entry passes desktop-file-validate, a real kbuildsycoca6 on PATH is invoked with --noincremental, a real update-desktop-database writes mimeinfo.cache, absent tools are skipped cleanly, and removal leaves the checkout's icon untouched.