Files
omarchy-pkgs/pkgbuilds/hermes-desktop/PKGBUILD
T
Spencer BullandGPT-6 Codex 2fb9ab2ba9 Launch native Hermes without privileged sandbox setup
Use the same direct executable path for menu launches and URLs, require working user namespaces, and retain only the first-update relaunch gate backport. This avoids the upstream CLI fallback that makes a helper in the user runtime setuid-root.

Co-Authored-By: GPT-6 Codex (xhigh) <noreply@openai.com>
2026-09-07 03:17:42 -05:00

141 lines
4.2 KiB
Bash

# Maintainer: David Heinemeier Hansson <david@hey.com>
# Build a prebuilt release; Omarchy seeds it into the user's Hermes checkout
# so the upstream updater can rebuild and relaunch it in place.
pkgname=hermes-desktop
pkgver=2026.8.31
pkgrel=4
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'
'gdk-pixbuf2'
'git'
'glib2'
'glibc'
'gtk3'
'hicolor-icon-theme'
'libcups'
'libdrm'
'libglvnd'
'libnotify'
'libsecret'
'libx11'
'libxcb'
'libxcomposite'
'libxdamage'
'libxext'
'libxfixes'
'libxkbcommon'
'libxrandr'
'make'
'mesa'
'nodejs'
'npm'
'nspr'
'nss'
'pango'
'python'
'systemd-libs'
'util-linux'
'xdg-utils'
)
optdepends=('omarchy: sets up the user installation for in-app updates')
# The build runs the repo's own npm workspace install, which fetches Electron
# and rebuilds node-pty against it.
makedepends=('imagemagick')
# 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=29112bef099274229cadff79cdff7bf7b99c4b77
_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'
'runtime.patch'
'runtime-test.py')
sha256sums=('78fb3ff707ec1d17044b875ecac8bef28aa39d44242824f6871ca40afe7bf217'
'7324b1d5e7db16c6169dd9e685f4093925c4a8c0568cb7ce416ac734f3336606'
'3ef685bfcf366776b025d26c37d32854d8d4aa2023b2bd07c8e08b001ef1e8c4'
'd60d164e24fdcf6532133b8ea43c77a201e4b9e9dbc396187b58d51d8590ef52'
'03b67e26c234c797a6b1d4c9f34a57502dba37f462540e47ce6c88f6ea79302a'
'69bc57d04610567eca35679328668619fcd3f129ed099bf5e2a1f24d1f197de9')
build() {
cd "${srcdir}/${_srcdir}"
export GITHUB_SHA="${_commit}"
export GITHUB_REF_NAME="main"
# 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
}
check() {
python "${srcdir}/runtime-test.py" "${srcdir}/${_srcdir}" "${srcdir}/runtime.patch" "${srcdir}/hermes-desktop.sh"
}
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}/${_srcdir}/scripts/install.sh" \
"${pkgdir}/usr/share/${pkgname}/install.sh"
# Let the release's first updater relaunch with the user-namespace sandbox.
install -Dm644 "${srcdir}/runtime.patch" "${pkgdir}/usr/share/${pkgname}/runtime.patch"
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
}