From 33e191de2b93c55f04a7f44bbe2543d0762d3db2 Mon Sep 17 00:00:00 2001 From: s1d3sw1ped_bot Date: Wed, 2 Sep 2026 01:10:40 +0000 Subject: [PATCH] pkgbuild: Add grok-bot-bin from official .deb Temporary Arch/CachyOS packaging until upstream ships a native package. Pulls Cursor's amd64 deb by commit from the linux-x64 update feed. Includes update script and Gitea Actions for bump + makepkg release. --- .SRCINFO | 32 +++++++++++++++++ .gitea/workflows/build.yml | 48 +++++++++++++++++++++++++ .gitea/workflows/update.yml | 29 +++++++++++++++ PKGBUILD | 70 +++++++++++++++++++++++++++++++++++++ README.md | 60 ++++++++++++++++++++++++++++++- scripts/update.sh | 42 ++++++++++++++++++++++ 6 files changed, 280 insertions(+), 1 deletion(-) create mode 100644 .SRCINFO create mode 100644 .gitea/workflows/build.yml create mode 100644 .gitea/workflows/update.yml create mode 100644 PKGBUILD create mode 100755 scripts/update.sh diff --git a/.SRCINFO b/.SRCINFO new file mode 100644 index 0000000..035517c --- /dev/null +++ b/.SRCINFO @@ -0,0 +1,32 @@ +pkgbase = grok-bot-bin + pkgdesc = Grok Bot desktop agent (official .deb repackaged) + pkgver = 0.30.0 + pkgrel = 1 + url = https://cursor.com/download/bot + arch = x86_64 + license = LicenseRef-proprietary + depends = alsa-lib + depends = at-spi2-core + depends = gtk3 + depends = libdrm + depends = libnotify + depends = libsecret + depends = libxkbcommon + depends = libxss + depends = libxtst + depends = mesa + depends = nss + depends = xdg-utils + optdepends = libappindicator-gtk3: tray icon support + provides = grok-bot + provides = sand + conflicts = grok-bot + conflicts = sand + replaces = sand + options = !strip + options = !debug + source = https://downloads.cursor.com/grokbot/stable/2385d097738b3719cc5ecd9281a107aa106215f1/linux/x64/grok-bot_0.30.0_amd64.deb + noextract = grok-bot_0.30.0_amd64.deb + sha256sums = fb888b2204c8a51c71a9f5f9a2913ac10561f3ef6939c1245ecae4e837d4ada2 + +pkgname = grok-bot-bin diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml new file mode 100644 index 0000000..cb02f55 --- /dev/null +++ b/.gitea/workflows/build.yml @@ -0,0 +1,48 @@ +name: Build Arch package +on: + push: + tags: ['v*'] + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + container: + image: archlinux:base-devel + steps: + - name: Prepare build user + run: | + pacman -Syu --noconfirm git + useradd -m builder + echo 'builder ALL=(ALL) NOPASSWD: ALL' > /etc/sudoers.d/builder + chmod 440 /etc/sudoers.d/builder + - uses: actions/checkout@v4 + - name: Build package + run: | + chown -R builder:builder . + sudo -u builder makepkg -sf --noconfirm + - name: Upload artifact + uses: actions/upload-artifact@v3 + with: + name: grok-bot-bin + path: '*.pkg.tar.zst' + if-no-files-found: error + - name: Attach package to Gitea release + if: startsWith(github.ref, 'refs/tags/') + env: + GITEA_TOKEN: ${{ secrets.GITHUB_TOKEN }} + run: | + set -euo pipefail + tag="${GITHUB_REF_NAME}" + ver="${tag#v}" + pkg=$(ls -1 *.pkg.tar.zst | head -1) + api="${GITHUB_API_URL:-https://git.s1d3sw1ped.com/api/v1}/repos/${GITHUB_REPOSITORY}/releases" + # create release if missing + curl -fsS -X POST -H "Authorization: token ${GITEA_TOKEN}" -H "Content-Type: application/json" \ + -d "{\"tag_name\":\"${tag}\",\"name\":\"${tag}\",\"body\":\"grok-bot-bin ${ver} (official .deb repackaged)\"}" \ + "$api" || true + rid=$(curl -fsS -H "Authorization: token ${GITEA_TOKEN}" "$api/tags/${tag}" | jq -r .id) + curl -fsS -X POST -H "Authorization: token ${GITEA_TOKEN}" \ + -H "Content-Type: application/octet-stream" \ + --data-binary @"$pkg" \ + "${GITHUB_SERVER_URL:-https://git.s1d3sw1ped.com}/api/v1/repos/${GITHUB_REPOSITORY}/releases/${rid}/assets?name=$(basename "$pkg")" diff --git a/.gitea/workflows/update.yml b/.gitea/workflows/update.yml new file mode 100644 index 0000000..eac2c85 --- /dev/null +++ b/.gitea/workflows/update.yml @@ -0,0 +1,29 @@ +name: Check for new release +on: + schedule: + - cron: '17 6 * * *' + workflow_dispatch: + +jobs: + update: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - name: Bump PKGBUILD if a new version is out + run: | + set -euo pipefail + sudo apt-get update -qq + sudo apt-get install -y -qq jq curl + before=$(sed -n 's/^pkgver=//p' PKGBUILD) + ./scripts/update.sh + after=$(sed -n 's/^pkgver=//p' PKGBUILD) + if [[ "$before" == "$after" ]]; then + echo "No bump" + exit 0 + fi + git config user.name 's1d3sw1ped_bot' + git config user.email 's1d3sw1ped_bot@git.s1d3sw1ped.com' + git add PKGBUILD .SRCINFO + git commit -m "pkgbuild: Bump grok-bot-bin to ${after}" + git tag "v${after}" + git push origin "HEAD:${GITHUB_REF_NAME}" "v${after}" diff --git a/PKGBUILD b/PKGBUILD new file mode 100644 index 0000000..dfffb6a --- /dev/null +++ b/PKGBUILD @@ -0,0 +1,70 @@ +# Maintainer: s1d3sw1ped +# Unofficial Arch/CachyOS repackage of the official Grok Bot .deb. +# Temporary until upstream ships a native package. +# +# Version oracle (commit is in the download URL): +# https://api2.cursor.sh/updates/api/update/linux-x64/sand/0.0.0/00000000-0000-0000-0000-000000000000/stable +# Deb URL: +# https://downloads.cursor.com/grokbot/stable//linux/x64/grok-bot__amd64.deb + +pkgname=grok-bot-bin +pkgver=0.30.0 +_commit=2385d097738b3719cc5ecd9281a107aa106215f1 +pkgrel=1 +pkgdesc="Grok Bot desktop agent (official .deb repackaged)" +arch=('x86_64') +url="https://cursor.com/download/bot" +license=('LicenseRef-proprietary') +depends=( + 'alsa-lib' + 'at-spi2-core' + 'gtk3' + 'libdrm' + 'libnotify' + 'libsecret' + 'libxkbcommon' + 'libxss' + 'libxtst' + 'mesa' + 'nss' + 'xdg-utils' +) +optdepends=( + 'libappindicator-gtk3: tray icon support' +) +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") +noextract=("grok-bot_${pkgver}_amd64.deb") +sha256sums=('fb888b2204c8a51c71a9f5f9a2913ac10561f3ef6939c1245ecae4e837d4ada2') + +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 + + # Path contains a space, so Chromium cannot use the SUID sandbox. + # Arch/CachyOS kernels have user namespaces; keep chrome-sandbox non-setuid. + if [[ -f "$pkgdir/opt/Grok Bot/chrome-sandbox" ]]; then + chmod 0755 "$pkgdir/opt/Grok Bot/chrome-sandbox" + fi + + install -dm755 "$pkgdir/usr/share/licenses/$pkgname" + ln -sf "/opt/Grok Bot/LICENSE.electron.txt" \ + "$pkgdir/usr/share/licenses/$pkgname/LICENSE.electron.txt" + ln -sf "/opt/Grok Bot/LICENSES.chromium.html" \ + "$pkgdir/usr/share/licenses/$pkgname/LICENSES.chromium.html" +} diff --git a/README.md b/README.md index f9b5ea7..4d09baf 100644 --- a/README.md +++ b/README.md @@ -1,3 +1,61 @@ # grok-bot-bin -Unofficial Arch/CachyOS package of the official Grok Bot .deb \ No newline at end of file +Unofficial Arch / CachyOS package of the official [Grok Bot](https://cursor.com/download/bot) `.deb`. Temporary until upstream packages for Arch. + +Not affiliated with Cursor / SpaceXAI. The app binary is unchanged; this only repacks it for `pacman`. + +## Install (build locally) + +```bash +git clone https://git.s1d3sw1ped.com/s1d3sw1ped/grok-bot-bin.git +cd grok-bot-bin +makepkg -si +``` + +With an AUR helper against this git URL: + +```bash +paru -S grok-bot-bin --aururl https://git.s1d3sw1ped.com +# or: +yay -S grok-bot-bin # after cloning locally / using a custom AUR mirror +``` + +Simplest reliable path on CachyOS today: + +```bash +makepkg -si +``` + +## Install from a release package + +When CI has published a `.pkg.tar.zst` on the [Releases](https://git.s1d3sw1ped.com/s1d3sw1ped/grok-bot-bin/releases) page: + +```bash +curl -LO 'https://git.s1d3sw1ped.com/s1d3sw1ped/grok-bot-bin/releases/download/v0.30.0/grok-bot-bin-0.30.0-1-x86_64.pkg.tar.zst' +sudo pacman -U grok-bot-bin-0.30.0-1-x86_64.pkg.tar.zst +``` + +Download first, then `pacman -U` the local file (`LocalFileSigLevel = Optional`). Do not pass the remote URL straight to pacman if signatures are required. + +## Custom pacman repo (optional) + +After CI publishes a repo database under Releases (or Packages), add to `/etc/pacman.conf`: + +```ini +[grok-bot] +SigLevel = Optional TrustAll +Server = https://git.s1d3sw1ped.com/s1d3sw1ped/grok-bot-bin/releases/latest/download +``` + +Exact `Server=` URL may change once the first repo DB lands; `makepkg -si` works regardless. + +## Updating + +`./scripts/update.sh` reads Cursor's linux-x64 update feed, downloads the matching `.deb`, and bumps `pkgver` / `_commit` / `sha256sums` in `PKGBUILD` and `.SRCINFO`. + +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). +- `chrome-sandbox` is left non-setuid because the install path contains a space; user namespaces cover sandboxing on CachyOS. diff --git a/scripts/update.sh b/scripts/update.sh new file mode 100755 index 0000000..246ffb6 --- /dev/null +++ b/scripts/update.sh @@ -0,0 +1,42 @@ +#!/usr/bin/env bash +# Bump PKGBUILD/.SRCINFO when Cursor publishes a newer linux-x64 Grok Bot. +set -euo pipefail +cd "$(dirname "$0")/.." + +FEED='https://api2.cursor.sh/updates/api/update/linux-x64/sand/0.0.0/00000000-0000-0000-0000-000000000000/stable' +resp=$(curl -fsSL "$FEED") +version=$(jq -r .version <<<"$resp") +commit=$(jq -r .url <<<"$resp" | sed -E 's#.*/stable/([^/]+)/.*#\1#') +current=$(sed -n 's/^pkgver=//p' PKGBUILD) + +if [[ -z "$version" || "$version" == "null" || ! "$commit" =~ ^[0-9a-f]{40}$ ]]; then + echo "Could not parse update feed: $resp" >&2 + exit 1 +fi +if [[ "$version" == "$current" ]]; then + echo "Up to date at $version" + exit 0 +fi + +echo "Bump $current -> $version (commit $commit)" +deb_url="https://downloads.cursor.com/grokbot/stable/${commit}/linux/x64/grok-bot_${version}_amd64.deb" +tmp=$(mktemp) +trap 'rm -f "$tmp"' EXIT +curl -fsSL --retry 3 "$deb_url" -o "$tmp" +sha=$(sha256sum "$tmp" | cut -d' ' -f1) + +sed -i \ + -e "s/^pkgver=.*/pkgver=${version}/" \ + -e "s/^_commit=.*/_commit=${commit}/" \ + -e "s/^sha256sums=.*/sha256sums=('${sha}')/" \ + PKGBUILD + +# Refresh .SRCINFO source URL + hashes without requiring makepkg. +sed -i \ + -e "s/^\\tpkgver = .*/\\tpkgver = ${version}/" \ + -e "s#^\\tsource = https://downloads.cursor.com/grokbot/stable/.*/linux/x64/grok-bot_.*_amd64.deb#\\tsource = https://downloads.cursor.com/grokbot/stable/${commit}/linux/x64/grok-bot_${version}_amd64.deb#" \ + -e "s/^\\tnoextract = grok-bot_.*_amd64.deb/\\tnoextract = grok-bot_${version}_amd64.deb/" \ + -e "s/^\\tsha256sums = .*/\\tsha256sums = ${sha}/" \ + .SRCINFO + +echo "Updated PKGBUILD and .SRCINFO to ${version} sha256=${sha}"