From 1d739663152268a04cafd8b53a2294ccdccb858a Mon Sep 17 00:00:00 2001 From: s1d3sw1ped_bot <12+s1d3sw1ped_bot@git.s1d3sw1ped.com> Date: Wed, 2 Sep 2026 01:30:38 +0000 Subject: [PATCH] pkgbuild: Install auto-update launch shim Replace the /usr/bin/grok-bot (and sand) plain symlink with a launch shim that checks the latest Gitea release, pacman -U's a newer .pkg.tar.zst when available, then execs the real binary under /opt/Grok Bot/. Skip with GROK_BOT_NO_UPDATE=1; fail soft on network/API errors. Bump pkgrel for the packaging change. https://git.s1d3sw1ped.com/s1d3sw1ped/grok-bot-bin/issues/2 --- .SRCINFO | 5 +++- PKGBUILD | 28 +++++++++--------- README.md | 3 +- grok-bot-launch.sh | 72 ++++++++++++++++++++++++++++++++++++++++++++++ 4 files changed, 92 insertions(+), 16 deletions(-) create mode 100755 grok-bot-launch.sh diff --git a/.SRCINFO b/.SRCINFO index 035517c..f98cca4 100644 --- a/.SRCINFO +++ b/.SRCINFO @@ -1,7 +1,7 @@ pkgbase = grok-bot-bin pkgdesc = Grok Bot desktop agent (official .deb repackaged) pkgver = 0.30.0 - pkgrel = 1 + pkgrel = 2 url = https://cursor.com/download/bot arch = x86_64 license = LicenseRef-proprietary @@ -18,6 +18,7 @@ pkgbase = grok-bot-bin depends = nss depends = xdg-utils optdepends = libappindicator-gtk3: tray icon support + optdepends = curl: auto-update check on launch provides = grok-bot provides = sand conflicts = grok-bot @@ -26,7 +27,9 @@ pkgbase = grok-bot-bin options = !strip options = !debug source = https://downloads.cursor.com/grokbot/stable/2385d097738b3719cc5ecd9281a107aa106215f1/linux/x64/grok-bot_0.30.0_amd64.deb + source = grok-bot-launch.sh noextract = grok-bot_0.30.0_amd64.deb sha256sums = fb888b2204c8a51c71a9f5f9a2913ac10561f3ef6939c1245ecae4e837d4ada2 + sha256sums = 886c8b55eb44d2f7812be50dcc1571907dc2d7e755171e67e916f497634f09eb pkgname = grok-bot-bin diff --git a/PKGBUILD b/PKGBUILD index dfffb6a..e71a744 100644 --- a/PKGBUILD +++ b/PKGBUILD @@ -10,7 +10,7 @@ pkgname=grok-bot-bin pkgver=0.30.0 _commit=2385d097738b3719cc5ecd9281a107aa106215f1 -pkgrel=1 +pkgrel=2 pkgdesc="Grok Bot desktop agent (official .deb repackaged)" arch=('x86_64') url="https://cursor.com/download/bot" @@ -31,30 +31,30 @@ depends=( ) optdepends=( 'libappindicator-gtk3: tray icon support' + 'curl: auto-update check on launch' ) provides=('grok-bot' 'sand') conflicts=('grok-bot' 'sand') replaces=('sand') options=('!strip' '!debug') -source=("https://downloads.cursor.com/grokbot/stable/${_commit}/linux/x64/grok-bot_${pkgver}_amd64.deb") +source=( + "https://downloads.cursor.com/grokbot/stable/${_commit}/linux/x64/grok-bot_${pkgver}_amd64.deb" + "grok-bot-launch.sh" +) noextract=("grok-bot_${pkgver}_amd64.deb") -sha256sums=('fb888b2204c8a51c71a9f5f9a2913ac10561f3ef6939c1245ecae4e837d4ada2') +sha256sums=( + 'fb888b2204c8a51c71a9f5f9a2913ac10561f3ef6939c1245ecae4e837d4ada2' + '886c8b55eb44d2f7812be50dcc1571907dc2d7e755171e67e916f497634f09eb' +) package() { bsdtar -O -xf "$srcdir/grok-bot_${pkgver}_amd64.deb" data.tar.xz \ | bsdtar -xJf - -C "$pkgdir" - if [[ -f "$pkgdir/opt/Grok Bot/grok-bot" ]]; then - _bin=grok-bot - else - _bin=sand - fi - - install -dm755 "$pkgdir/usr/bin" - ln -sf "/opt/Grok Bot/${_bin}" "$pkgdir/usr/bin/${_bin}" - if [[ "$_bin" != grok-bot ]]; then - ln -sf "/opt/Grok Bot/${_bin}" "$pkgdir/usr/bin/grok-bot" - fi + # Auto-update launch shim (not a plain symlink into /opt). + install -Dm755 "$srcdir/grok-bot-launch.sh" "$pkgdir/usr/bin/grok-bot" + # Keep provides(sand) on PATH; both names run the same shim. + ln -sf grok-bot "$pkgdir/usr/bin/sand" # Path contains a space, so Chromium cannot use the SUID sandbox. # Arch/CachyOS kernels have user namespaces; keep chrome-sandbox non-setuid. diff --git a/README.md b/README.md index 4d09baf..75f6004 100644 --- a/README.md +++ b/README.md @@ -57,5 +57,6 @@ Scheduled Gitea Actions will do the same and build a release package. ## Notes -- Linux has no in-app updater for Grok Bot; re-run update + `makepkg -si` (or install the newer release). +- `/usr/bin/grok-bot` (and `sand`) is a launch shim: unless `GROK_BOT_NO_UPDATE=1`, it checks the latest Gitea release and may `pacman -U` a newer `.pkg.tar.zst` before exec'ing `/opt/Grok Bot/…`. Network/API failures still launch the installed binary. +- Upstream Linux builds still have no in-app updater for the Electron app itself; `scripts/update.sh` bumps the PKGBUILD from Cursor's feed when packaging a new upstream version. - `chrome-sandbox` is left non-setuid because the install path contains a space; user namespaces cover sandboxing on CachyOS. diff --git a/grok-bot-launch.sh b/grok-bot-launch.sh new file mode 100755 index 0000000..71a1716 --- /dev/null +++ b/grok-bot-launch.sh @@ -0,0 +1,72 @@ +#!/usr/bin/env bash +# Launch shim for grok-bot-bin: optionally auto-update from Gitea releases, then +# exec the real binary under /opt/Grok Bot/. Fail soft on network/API errors. +set -u + +REAL_DIR="/opt/Grok Bot" +API_URL='https://git.s1d3sw1ped.com/api/v1/repos/s1d3sw1ped/grok-bot-bin/releases?limit=1' + +_maybe_update() { + [[ "${GROK_BOT_NO_UPDATE:-}" == "1" ]] && return 0 + command -v curl >/dev/null 2>&1 || return 0 + command -v pacman >/dev/null 2>&1 || return 0 + command -v vercmp >/dev/null 2>&1 || return 0 + + local installed + installed=$(pacman -Q grok-bot-bin 2>/dev/null | awk '{print $2}') || return 0 + [[ -n "$installed" ]] || return 0 + + local json + json=$(curl -fsSL --connect-timeout 3 --max-time 10 "$API_URL" 2>/dev/null) || return 0 + [[ -n "$json" ]] || return 0 + + local asset_url asset_name remote_ver + asset_url=$(grep -oE 'https://[^"[:space:]\\]+grok-bot-bin-[^"[:space:]\\]+\.pkg\.tar\.zst' <<<"$json" | head -1) || true + [[ -n "$asset_url" ]] || return 0 + asset_name=$(basename "$asset_url") + if [[ "$asset_name" =~ ^grok-bot-bin-(.+)-x86_64\.pkg\.tar\.zst$ ]]; then + remote_ver="${BASH_REMATCH[1]}" + else + return 0 + fi + + # Only upgrade when remote is strictly newer (vercmp: 1 means a > b). + local cmp + cmp=$(vercmp "$remote_ver" "$installed" 2>/dev/null) || return 0 + [[ "$cmp" =~ ^-?[0-9]+$ ]] || return 0 + if (( cmp <= 0 )); then + return 0 + fi + + local tmpdir pkg + tmpdir=$(mktemp -d 2>/dev/null) || return 0 + # shellcheck disable=SC2064 + trap "rm -rf '$tmpdir'" RETURN + pkg="$tmpdir/$asset_name" + + echo "grok-bot: updating grok-bot-bin ${installed} -> ${remote_ver}" >&2 + if ! curl -fL --connect-timeout 5 --max-time 600 -o "$pkg" "$asset_url" 2>/dev/null; then + echo "grok-bot: download failed; launching installed version" >&2 + return 0 + fi + + # Prefer passwordless sudo; fall back to interactive sudo. Fail soft either way. + if ! sudo -n pacman -U --noconfirm "$pkg" 2>/dev/null; then + if ! sudo pacman -U --noconfirm "$pkg"; then + echo "grok-bot: pacman -U failed; launching installed version" >&2 + return 0 + fi + fi +} + +_maybe_update || true +trap - RETURN + +if [[ -x "${REAL_DIR}/grok-bot" ]]; then + exec "${REAL_DIR}/grok-bot" "$@" +elif [[ -x "${REAL_DIR}/sand" ]]; then + exec "${REAL_DIR}/sand" "$@" +else + echo "grok-bot: real binary not found under ${REAL_DIR}" >&2 + exit 127 +fi