From fe409baf0005ffa1f0f733fed34cc1c884a5ae7e Mon Sep 17 00:00:00 2001 From: Spencer Bull Date: Tue, 1 Sep 2026 09:33:12 -0500 Subject: [PATCH] Add OpenClaw to the fast ring, following the npm registry Package OpenClaw 2026.9.1 as a local PKGBUILD based on the AUR one, tracking the npm registry's latest dist-tag through the repository's declarative npm upstream provider: upstream's release cadence outruns the AUR maintainer, and the dist-tag is the stable channel where a plain version-max would ship next cycle's betas. A 24h min_release_age quarantines fresh releases, which matters more than usual here because the npm tarball is not vendored: package() resolves ~330 transitive dependencies from the live registry without integrity pins. The pinned sha256 was verified against the registry by hand. The initial pin was taken inside its quarantine window through the documented BYPASS_MIN_RELEASE_AGE maintainer path, deliberately, and lands through this reviewed change as that path intends. The AUR post_upgrade restart attempt is replaced with printed guidance: it targeted a nonexistent openclaw.service, and the real openclaw-gateway.service is a systemd user unit a root pacman hook cannot reach (voxtype-bin sets the precedent). The builder ships npm 12, which refuses install-time lifecycle scripts unless the package is allow-listed, and for a local tarball the allow-list key is the tarball's own file: spec rather than the package name. Without it openclaw's postinstall never runs, the .openclaw-lifecycle-pending marker ships in the package, and every invocation dies trying to finish the lifecycle inside the root-owned /usr/lib/node_modules/openclaw. package() now passes --allow-scripts and fails the build if the marker survives. That postinstall also runs upstream's legacy-state migration against whatever home it sees, so the npm call gets a scratch HOME under $srcdir with the OPENCLAW_* location overrides unset: a maintainer's own ~/.openclaw is not the build's to prune. --- pkgbuilds/openclaw/.omarchy/package.json | 11 ++++ pkgbuilds/openclaw/PKGBUILD | 72 ++++++++++++++++++++++++ pkgbuilds/openclaw/openclaw.install | 17 ++++++ 3 files changed, 100 insertions(+) create mode 100644 pkgbuilds/openclaw/.omarchy/package.json create mode 100644 pkgbuilds/openclaw/PKGBUILD create mode 100644 pkgbuilds/openclaw/openclaw.install diff --git a/pkgbuilds/openclaw/.omarchy/package.json b/pkgbuilds/openclaw/.omarchy/package.json new file mode 100644 index 00000000..1c25fbcd --- /dev/null +++ b/pkgbuilds/openclaw/.omarchy/package.json @@ -0,0 +1,11 @@ +{ + "source": "local", + "release_ring": "fast", + "min_release_age": "24h", + "upstream": { + "npm": "openclaw", + "sources": { + "any": ["{npm_tarball}"] + } + } +} diff --git a/pkgbuilds/openclaw/PKGBUILD b/pkgbuilds/openclaw/PKGBUILD new file mode 100644 index 00000000..5b2f50c6 --- /dev/null +++ b/pkgbuilds/openclaw/PKGBUILD @@ -0,0 +1,72 @@ +# Based on the AUR openclaw package: +# Maintainer: Ralph Torres +# Contributor: Evert Vorster +# Contributor: Emir-Eins +# Contributor: Wuxxin +# Followed here straight from the npm registry (see .omarchy/package.json), since +# upstream's release cadence outruns the AUR. + +pkgname=openclaw +pkgver=2026.9.1 +pkgrel=1 +pkgdesc='Multi-channel AI gateway with extensible messaging integrations' +arch=(x86_64 aarch64) +url=https://github.com/openclaw/openclaw +license=(MIT) + +depends=('nodejs>=22') +makedepends=(npm) +optdepends=( + '1password-cli: 1password skill' + 'curl: weather, openai-whisper-api skills' + 'ffmpeg: video-frames skill' + 'github-cli: github, gh-issues skills' + 'jq: session-logs, trello skills' + 'python-openai-whisper: openai-whisper skill' + 'ripgrep: session-logs skill' + 'tmux: tmux skill' + 'uv: nano-pdf skill' + 'go: for installing skill tools not packaged for Arch' +) +source=($pkgname-$pkgver.tgz::https://registry.npmjs.org/$pkgname/-/$pkgname-$pkgver.tgz) +sha256sums=('1bfcac877d53f1e41b69d15c24e081895b2f07d6ff2ffdfe0bf8a7336ab00e59') +options=(!debug !strip) +install=$pkgname.install +noextract=($pkgname-$pkgver.tgz) + +package() { + export SHARP_IGNORE_GLOBAL_LIBVIPS=1 + # npm 12 blocks install-time lifecycle scripts unless the package is + # allow-listed, and for a local tarball the allow-list key is the tarball's + # own file: spec, not the package name (arborist matches node.resolved). + # Upstream's postinstall prunes stale dist files and clears the + # .openclaw-lifecycle-pending marker the tarball ships with; without it, + # every openclaw invocation tries to finish that lifecycle itself and dies + # with EACCES on the root-owned install. + # That postinstall also migrates legacy state under whatever home it sees + # (pruning plugin-runtime-deps in ~/.openclaw and friends), so it gets a + # scratch home: a maintainer's own OpenClaw is not the build's to touch. + mkdir -p "$srcdir"/home + env -u OPENCLAW_HOME -u OPENCLAW_STATE_DIR -u OPENCLAW_CONFIG_PATH HOME="$srcdir"/home \ + npm install --silent --global --cache "$srcdir"/npm-cache \ + --allow-scripts="file:$srcdir/$pkgname-$pkgver.tgz" \ + --prefix "$pkgdir"/usr "$srcdir"/$pkgname-$pkgver.tgz + if [[ -e "$pkgdir"/usr/lib/node_modules/$pkgname/.openclaw-lifecycle-pending ]]; then + error "openclaw's postinstall did not run; the package would fail on first use" + return 1 + fi + + cat > $pkgname <<'EOF' +#!/bin/sh +export SHARP_IGNORE_GLOBAL_LIBVIPS=1 +exec node /usr/lib/node_modules/openclaw/openclaw.mjs "$@" +EOF + install -Dm755 -t "$pkgdir"/usr/bin $pkgname + + cd "$pkgdir"/usr/lib/node_modules/$pkgname + install -Dm644 -t "$pkgdir"/usr/share/licenses/$pkgname LICENSE + install -Dm644 -t "$pkgdir"/usr/share/doc/$pkgname README.md CHANGELOG.md + for f in docs/* + do ln -s /usr/lib/node_modules/$pkgname/"$f" "$pkgdir"/usr/share/doc/$pkgname/ + done +} diff --git a/pkgbuilds/openclaw/openclaw.install b/pkgbuilds/openclaw/openclaw.install new file mode 100644 index 00000000..dccd8c6e --- /dev/null +++ b/pkgbuilds/openclaw/openclaw.install @@ -0,0 +1,17 @@ +post_install() { + printf "%s\n" \ + "==> Install gateway service: openclaw gateway install --force" \ + "==> Perform onboarding once: openclaw onboard" +} + +post_upgrade() { + # The gateway runs as a systemd user unit (openclaw-gateway.service in + # ~/.config/systemd/user), which a root pacman hook has no session bus + # to reach, so it cannot be restarted from here and keeps running the + # old code until the user restarts it. + printf "%s\n" \ + "==> Restart the gateway to apply updates:" \ + " openclaw gateway restart" \ + "==> Run doctor to migrate configs, check gateway health, etc.:" \ + " openclaw doctor" +}