# Maintainer: David Heinemeier Hansson # Nous builds Hermes Desktop for macOS and Windows only -- their download page # offers a .dmg and an .exe and tells Linux users to install from a terminal -- # so there is no vendor binary to repackage. Their electron-builder config does # carry a Linux target, though, and it works; this builds it. # # The app only runs against a Hermes runtime built from its own commit, so it # provisions one itself under ~/.hermes on first launch and the package stays # on the newest tag. Pairing it with the mise CLI instead was tried and does # not work: PyPI trails the tags, and the version gap fails the readiness probe # with a 401. Pinning back to the tag behind PyPI's release does not rescue it # either -- v2026.7.20's desktop hangs after "backend is ready" without ever # opening a window, against its own matching runtime. # # The app is only a shell: it runs `hermes serve` against a Hermes CLI it does # not ship, and clones its own copy with the upstream install script when it # finds none. /usr/bin/hermes-desktop heads that off. See hermes-desktop.sh. pkgname=hermes-desktop pkgver=2026.8.18 pkgrel=2 pkgdesc='Native desktop shell for Hermes Agent' arch=('x86_64') url='https://github.com/NousResearch/hermes-agent' license=('MIT') depends=( 'alsa-lib' 'at-spi2-core' 'cairo' 'dbus' 'expat' 'curl' 'gcc-libs' 'gdk-pixbuf2' 'git' 'glib2' 'glibc' 'gtk3' 'hicolor-icon-theme' 'libcups' 'libdrm' 'libglvnd' 'libnotify' 'libsecret' 'libx11' 'libxcb' 'libxcomposite' 'libxdamage' 'libxext' 'libxfixes' 'libxkbcommon' 'libxrandr' 'mesa' 'nspr' 'nss' 'pango' 'systemd-libs' 'xdg-utils' ) optdepends=('omarchy: installs the Hermes CLI the app needs on first launch') # The build runs the repo's own npm workspace install, which fetches Electron # and rebuilds node-pty against it. makedepends=('git' 'imagemagick' 'nodejs' 'npm' 'python') # Electron bundles prebuilt binaries that stripping corrupts. options=('!strip' '!debug') # The tag's commit. apps/desktop/scripts/write-build-stamp.mjs pins the app's # first-launch bootstrap to a Hermes commit, and resolves it from $GITHUB_SHA # before falling back to `git rev-parse`. That fallback is wrong here: makepkg # builds inside this repository, so git ascends out of srcdir and stamps the # app with an omarchy-pkgs commit that means nothing upstream. _commit=e624e9fde561e1add9388384012b295fde669ade _srcdir="hermes-agent-${pkgver}" source=("${pkgname}-${pkgver}.tar.gz::${url}/archive/refs/tags/v${pkgver}.tar.gz" 'hermes-desktop.sh' 'hermes-desktop.desktop' 'hermes-desktop.png') sha256sums=('1e3d39d3638ec15fa9d31af262568a953e9272090deb1c50c44cd401175f5b80' 'f5833b969ce451aadee9f08d92db55cce3c7c9213175080590bf37444854d676' '3ef685bfcf366776b025d26c37d32854d8d4aa2023b2bd07c8e08b001ef1e8c4' 'd60d164e24fdcf6532133b8ea43c77a201e4b9e9dbc396187b58d51d8590ef52') build() { cd "${srcdir}/${_srcdir}" export GITHUB_SHA="${_commit}" export GITHUB_REF_NAME="v${pkgver}" # The desktop workspace resolves against the repo root, so the install has to # happen there rather than in apps/desktop. npm ci cd apps/desktop npm run pack } package() { cd "${srcdir}/${_srcdir}/apps/desktop/release/linux-unpacked" install -dm755 "${pkgdir}/opt/${pkgname}" cp -a . "${pkgdir}/opt/${pkgname}/" install -Dm755 "${srcdir}/hermes-desktop.sh" "${pkgdir}/usr/bin/${pkgname}" install -Dm644 "${srcdir}/hermes-desktop.desktop" \ "${pkgdir}/usr/share/applications/${pkgname}.desktop" install -Dm644 "${srcdir}/hermes-desktop.png" \ "${pkgdir}/usr/share/icons/hicolor/1024x1024/apps/${pkgname}.png" local size for size in 512 256 128 64 48; do magick "${srcdir}/hermes-desktop.png" -resize "${size}x${size}" "${srcdir}/icon-${size}.png" install -Dm644 "${srcdir}/icon-${size}.png" \ "${pkgdir}/usr/share/icons/hicolor/${size}x${size}/apps/${pkgname}.png" done install -Dm644 "${srcdir}/${_srcdir}/LICENSE" \ "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE" install -Dm644 "${pkgdir}/opt/${pkgname}/LICENSE.electron.txt" \ "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE.electron.txt" # Chromium's setuid sandbox is only needed where unprivileged user namespaces # are unavailable; where they work, setuid root is the worse of the two. if ! { [[ -L /proc/self/ns/user ]] && unshare --user true; }; then chmod 4755 "${pkgdir}/opt/${pkgname}/chrome-sandbox" else chmod 0755 "${pkgdir}/opt/${pkgname}/chrome-sandbox" fi }