6 Commits

Author SHA1 Message Date
linus 1001abba40 scripts: Prompt polkit for GUI grok-bot auto-update (#17)
Tag release after merge / tag (push) Successful in 2s
Build Arch package / build (push) Successful in 29s
pkexec auth_admin helper for GUI pacman -U; cancel still launches. Blake GO. Closes #16.
2026-09-04 12:30:10 -05:00
ash 56b6c046ef scripts: Prompt polkit for GUI grok-bot auto-update
Desktop Exec=grok-bot has no TTY, so interactive sudo cannot
prompt and auto-update is skipped. Try sudo -n, then pkexec of a
grok-bot-bin-only helper (auth_admin, not NOPASSWD), then
interactive sudo on a TTY. Cancel or deny still launches the
installed binary.

#16
2026-09-04 17:17:02 +00:00
linus a9697913da ci: Open bump PRs instead of pushing protected master (#15)
Tag release after merge / tag (push) Successful in 3s
Bump opens chore/bump-* PR; tag-release.yml tags after master merge. Blake GO. Closes #14.
2026-09-04 11:10:57 -05:00
ash 7d361549e1 ci: Open bump PRs instead of pushing protected master
Nightly update.yml rewrote PKGBUILD then failed with pre-receive hook
declined on protected master and tags. Push chore/bump-$pkgver and open
(or reuse) a PR instead. After merge, tag-release.yml creates v$pkgver
so build.yml still attaches the package.
2026-09-04 15:40:21 +00:00
eva 049b00de10 pkgbuild: Bump grok-bot-bin to 0.39.0 (#13)
Build Arch package / build (push) Successful in 27s
pkgbuild: Bump grok-bot-bin to 0.39.0
2026-09-04 09:55:15 -05:00
eva eb83529a0d pkgbuild: Bump grok-bot-bin to 0.39.0 2026-09-04 14:54:45 +00:00
8 changed files with 290 additions and 44 deletions
+11 -6
View File
@@ -1,7 +1,7 @@
pkgbase = grok-bot-bin
pkgdesc = Grok Bot desktop agent (official .deb repackaged)
pkgver = 0.36.0
pkgrel = 1
pkgver = 0.39.0
pkgrel = 2
url = https://cursor.com/download/bot
arch = x86_64
license = LicenseRef-proprietary
@@ -19,6 +19,7 @@ pkgbase = grok-bot-bin
depends = xdg-utils
optdepends = libappindicator-gtk3: tray icon support
optdepends = curl: auto-update check on launch
optdepends = polkit: graphical password prompt for desktop auto-update (pkexec)
provides = grok-bot
provides = sand
conflicts = grok-bot
@@ -26,10 +27,14 @@ pkgbase = grok-bot-bin
replaces = sand
options = !strip
options = !debug
source = https://downloads.cursor.com/grokbot/stable/9465f3ae75550511296fabbb7a4b6fc8afe9e408/linux/x64/grok-bot_0.36.0_amd64.deb
source = https://downloads.cursor.com/grokbot/stable/d8bc9c753edddb313047c9c69b480b7f8f321087/linux/x64/grok-bot_0.39.0_amd64.deb
source = grok-bot-launch.sh
noextract = grok-bot_0.36.0_amd64.deb
sha256sums = 948b4177667d9a03915c1aee497e7c5438705393da8083a6af0177288512d07e
sha256sums = 1c5a3599db15816caa839fc9e088ba9798757e44fec89c066ef5f6f3c0972aee
source = pkexec-pacman-u
source = com.s1d3sw1ped.grok-bot-bin.policy
noextract = grok-bot_0.39.0_amd64.deb
sha256sums = ae498adaf71f9ff1734a786163c5807fa50165acb5aa102bb68f43ead96de4fe
sha256sums = 36e1c522f7a3920a850a6235263d82ad5990611612979447c1e9eff92548ac1e
sha256sums = e92ea4534d864d7f302a082a8717a52af9675195af41092d18f15094f74fed45
sha256sums = a9533dfe4d31332ac1505d2e582eff27771dd0107108a5f6289d0d3839431a74
pkgname = grok-bot-bin
+58
View File
@@ -0,0 +1,58 @@
name: Tag release after merge
on:
push:
branches: ['master']
workflow_dispatch:
jobs:
tag:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
token: ${{ secrets.GITEA_TOKEN }}
- name: Create v$pkgver tag if missing
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
set -euo pipefail
if [[ "${GITHUB_REF:-}" != "refs/heads/master" ]]; then
echo "error: refusing to tag from ${GITHUB_REF:-unset}; only master" >&2
exit 1
fi
pkgver=$(sed -n 's/^pkgver=//p' PKGBUILD | head -1)
if [[ -z "$pkgver" ]]; then
echo "error: could not read pkgver from PKGBUILD" >&2
exit 1
fi
if [[ ! "$pkgver" =~ ^[0-9]+\.[0-9]+\.[0-9]+([.-][0-9A-Za-z]+)*$ ]]; then
echo "error: PKGBUILD pkgver looks wrong: $pkgver" >&2
exit 1
fi
if [[ -z "${GITHUB_SHA:-}" ]]; then
echo "error: GITHUB_SHA is empty; cannot tag v${pkgver}" >&2
exit 1
fi
tag="v${pkgver}"
existing=$(git ls-remote --tags origin "refs/tags/${tag}")
if [[ -n "$existing" ]]; then
echo "Tag ${tag} already exists; nothing to do"
exit 0
fi
if [[ -z "${GITEA_TOKEN:-}" ]]; then
echo "error: GITEA_TOKEN is empty; cannot push tag ${tag}" >&2
exit 1
fi
git tag "${tag}" "${GITHUB_SHA}"
if git push origin "refs/tags/${tag}"; then
echo "Pushed tag ${tag} -> ${GITHUB_SHA}"
exit 0
fi
existing=$(git ls-remote --tags origin "refs/tags/${tag}")
if [[ -n "$existing" ]]; then
echo "Tag ${tag} appeared concurrently; nothing to do"
exit 0
fi
echo "error: could not push tag ${tag} for ${GITHUB_SHA}." >&2
echo "error: Manual path: git tag ${tag} && git push origin ${tag} so build.yml can attach the release asset." >&2
exit 1
+90 -8
View File
@@ -10,6 +10,8 @@ jobs:
steps:
- uses: actions/checkout@v4
- name: Bump PKGBUILD if a new version is out
env:
GITEA_TOKEN: ${{ secrets.GITEA_TOKEN }}
run: |
set -euo pipefail
sudo apt-get update -qq
@@ -17,9 +19,9 @@ jobs:
for cmd in jq curl python3; do
command -v "$cmd" >/dev/null || { echo "error: missing $cmd" >&2; exit 1; }
done
before=$(sed -n 's/^pkgver=//p' PKGBUILD)
before=$(sed -n 's/^pkgver=//p' PKGBUILD | head -1)
./scripts/update.sh
after=$(sed -n 's/^pkgver=//p' PKGBUILD)
after=$(sed -n 's/^pkgver=//p' PKGBUILD | head -1)
if [[ -z "$after" ]]; then
echo "error: could not read pkgver after update.sh" >&2
exit 1
@@ -28,15 +30,95 @@ jobs:
echo "No bump (still $after)"
exit 0
fi
if [[ -z "${GITEA_TOKEN:-}" ]]; then
echo "error: GITEA_TOKEN is empty; cannot open or reuse bump PR" >&2
exit 1
fi
if [[ -z "${GITHUB_REPOSITORY:-}" ]]; then
echo "error: GITHUB_REPOSITORY is empty; cannot open or reuse bump PR" >&2
exit 1
fi
git config user.name 'eva'
git config user.email 's1d3sw1ped+eva@gmail.com'
git add PKGBUILD .SRCINFO
git commit -m "pkgbuild: Bump grok-bot-bin to ${after}"
git tag "v${after}"
# Proven on this forge: run 1190 pushed master + tag v0.35.0.
# Still fail the job if push is denied rather than reporting a landed bump.
if ! git push origin "HEAD:${GITHUB_REF_NAME}" "v${after}"; then
echo "error: could not push commit/tag to ${GITHUB_REF_NAME} (v${after})." >&2
echo "error: Manual path: ./scripts/update.sh, commit, PR/merge, then tag v${after} and push the tag so build.yml can attach the release asset." >&2
# Do not tag here and do not push protected master. Open a bump PR;
# tag-release.yml creates v$pkgver after merge so build.yml can run.
branch="chore/bump-${after}"
git fetch origin "refs/heads/${branch}:refs/remotes/origin/${branch}" || \
echo "note: ${branch} not on origin yet (creating)"
if ! git push --force-with-lease origin "HEAD:refs/heads/${branch}"; then
echo "error: could not push ${branch} (pkgver ${after})." >&2
echo "error: Manual path: commit PKGBUILD+.SRCINFO, open a PR to master, merge, then let tag-release.yml create v${after} (or push that tag yourself)." >&2
exit 1
fi
api="${GITHUB_API_URL:-https://git.s1d3sw1ped.com/api/v1}"
repo="${GITHUB_REPOSITORY}"
title="pkgbuild: Bump grok-bot-bin to ${after}"
body=$(printf '%s\n' \
"Automated PKGBUILD bump from Cursor's linux-x64 feed (${before} → ${after})." \
"" \
"This job does not create a git tag. After this PR merges to master, tag-release.yml should create \`v${after}\` so build.yml can attach the \`.pkg.tar.zst\`.")
find_pr() {
local prs
if ! prs=$(curl -fsS -H "Authorization: token ${GITEA_TOKEN}" \
"${api}/repos/${repo}/pulls?state=open&limit=50"); then
echo "error: could not list open pull requests for ${repo}" >&2
return 1
fi
if ! jq -e 'type == "array"' >/dev/null <<<"$prs"; then
echo "error: unexpected pulls list response for ${repo}" >&2
printf '%s\n' "$prs" >&2
return 1
fi
jq -r --arg h "$branch" \
'[.[] | select(.base.ref == "master" and (.head.ref == $h or ((.head.label // "") | endswith(":" + $h)))) | (.html_url // .url)] | .[0] // empty' \
<<<"$prs"
}
existing=$(find_pr) || {
echo "error: could not look up existing PR for ${branch} → master" >&2
exit 1
}
if [[ -n "$existing" ]]; then
echo "Reusing existing PR: ${existing}"
exit 0
fi
payload=$(jq -n \
--arg title "$title" \
--arg body "$body" \
--arg head "$branch" \
--arg base "master" \
'{title:$title, body:$body, head:$head, base:$base}')
tmp=$(mktemp)
trap 'rm -f "$tmp"' EXIT
set +e
code=$(curl -sS -o "$tmp" -w '%{http_code}' -X POST \
-H "Authorization: token ${GITEA_TOKEN}" \
-H "Content-Type: application/json" \
-d "$payload" \
"${api}/repos/${repo}/pulls")
curl_ec=$?
set -e
if [[ $curl_ec -ne 0 ]]; then
echo "error: curl failed creating PR ${branch} → master (exit ${curl_ec})" >&2
exit 1
fi
if [[ "$code" == "201" ]]; then
pr_url=$(jq -r '.html_url // .url // empty' "$tmp")
echo "Opened PR: ${pr_url:-created (${branch} → master)}"
exit 0
fi
if [[ "$code" == "409" || "$code" == "422" ]]; then
existing=$(find_pr) || {
echo "error: PR create returned HTTP ${code} but looking up existing PR failed" >&2
cat "$tmp" >&2 || true
exit 1
}
if [[ -n "$existing" ]]; then
echo "Reusing existing PR: ${existing}"
exit 0
fi
fi
echo "error: could not open or reuse PR ${branch} → master (HTTP ${code})" >&2
cat "$tmp" >&2 || true
exit 1
+15 -5
View File
@@ -8,9 +8,9 @@
# https://downloads.cursor.com/grokbot/stable/<commit>/linux/x64/grok-bot_<pkgver>_amd64.deb
pkgname=grok-bot-bin
pkgver=0.36.0
_commit=9465f3ae75550511296fabbb7a4b6fc8afe9e408
pkgrel=1
pkgver=0.39.0
_commit=d8bc9c753edddb313047c9c69b480b7f8f321087
pkgrel=2
pkgdesc="Grok Bot desktop agent (official .deb repackaged)"
arch=('x86_64')
url="https://cursor.com/download/bot"
@@ -32,6 +32,7 @@ depends=(
optdepends=(
'libappindicator-gtk3: tray icon support'
'curl: auto-update check on launch'
'polkit: graphical password prompt for desktop auto-update (pkexec)'
)
provides=('grok-bot' 'sand')
conflicts=('grok-bot' 'sand')
@@ -40,11 +41,15 @@ options=('!strip' '!debug')
source=(
"https://downloads.cursor.com/grokbot/stable/${_commit}/linux/x64/grok-bot_${pkgver}_amd64.deb"
"grok-bot-launch.sh"
"pkexec-pacman-u"
"com.s1d3sw1ped.grok-bot-bin.policy"
)
noextract=("grok-bot_${pkgver}_amd64.deb")
sha256sums=(
'948b4177667d9a03915c1aee497e7c5438705393da8083a6af0177288512d07e'
'1c5a3599db15816caa839fc9e088ba9798757e44fec89c066ef5f6f3c0972aee'
'ae498adaf71f9ff1734a786163c5807fa50165acb5aa102bb68f43ead96de4fe'
'36e1c522f7a3920a850a6235263d82ad5990611612979447c1e9eff92548ac1e'
'e92ea4534d864d7f302a082a8717a52af9675195af41092d18f15094f74fed45'
'a9533dfe4d31332ac1505d2e582eff27771dd0107108a5f6289d0d3839431a74'
)
package() {
@@ -56,6 +61,11 @@ package() {
# Keep provides(sand) on PATH; both names run the same shim.
ln -sf grok-bot "$pkgdir/usr/bin/sand"
# pkexec helper + polkit action (auth_admin, not NOPASSWD) for desktop auto-update.
install -Dm755 "$srcdir/pkexec-pacman-u" "$pkgdir/usr/lib/grok-bot-bin/pkexec-pacman-u"
install -Dm644 "$srcdir/com.s1d3sw1ped.grok-bot-bin.policy" \
"$pkgdir/usr/share/polkit-1/actions/com.s1d3sw1ped.grok-bot-bin.policy"
# Always point the menu entry at the PATH shim. Upstream .desktop has used
# Exec="/opt/Grok Bot/grok-bot" (0.30) which bypasses auto-update; rewrite
# every build so a future /opt regression cannot ship again.
+21 -17
View File
@@ -6,7 +6,7 @@ Not affiliated with Cursor / SpaceXAI. The app binary is unchanged; this only re
## Install (build locally)
This tree packages **0.36.0** (`pkgver` / `pkgrel=1` in `PKGBUILD`). `makepkg -si` from git tip builds that version even before a release tag exists.
This tree packages **0.39.0** (`pkgver` / `pkgrel=2` in `PKGBUILD`). `makepkg -si` from git tip builds that version even before a release tag exists.
```bash
git clone https://git.s1d3sw1ped.com/s1d3sw1ped/grok-bot-bin.git
@@ -30,11 +30,11 @@ makepkg -si
## Install from a release package
`pacman -U` installs whatever `.pkg.tar.zst` is attached on [Releases](https://git.s1d3sw1ped.com/s1d3sw1ped/grok-bot-bin/releases), which lags git tip until someone **tags** the bump (see Updating). After `v0.36.0` is pushed, CI (`build.yml`) attaches `grok-bot-bin-0.36.0-1-x86_64.pkg.tar.zst`. Until that asset exists, use `makepkg -si` for 0.36.0; the newest published asset may still be `v0.35.0-2`.
`pacman -U` installs whatever `.pkg.tar.zst` is attached on [Releases](https://git.s1d3sw1ped.com/s1d3sw1ped/grok-bot-bin/releases), which lags git tip until the bump is tagged (see Updating). After `v0.39.0` is tagged, CI (`build.yml`) attaches `grok-bot-bin-0.39.0-1-x86_64.pkg.tar.zst`. Until a new tag's asset exists, use `makepkg -si` for git-tip `pkgver`.
```bash
curl -LO 'https://git.s1d3sw1ped.com/s1d3sw1ped/grok-bot-bin/releases/download/v0.36.0/grok-bot-bin-0.36.0-1-x86_64.pkg.tar.zst'
sudo pacman -U grok-bot-bin-0.36.0-1-x86_64.pkg.tar.zst
curl -LO 'https://git.s1d3sw1ped.com/s1d3sw1ped/grok-bot-bin/releases/download/v0.39.0/grok-bot-bin-0.39.0-1-x86_64.pkg.tar.zst'
sudo pacman -U grok-bot-bin-0.39.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.
@@ -53,42 +53,44 @@ Exact `Server=` URL may change once the first repo DB lands; `makepkg -si` works
## Updating
Stay-current path when Cursor's linux-x64 Grok Bot feed moves. `PKGBUILD` is currently **0.36.0** (pkgrel 1). One updater: `./scripts/update.sh`.
Stay-current path when Cursor's linux-x64 Grok Bot feed moves. `PKGBUILD` is currently **0.39.0** (pkgrel 2). One updater: `./scripts/update.sh`.
### Scheduled bump (Gitea Actions)
`.gitea/workflows/update.yml` runs daily (`cron: '17 6 * * *'`) and on `workflow_dispatch`. It:
1. Runs `./scripts/update.sh` against the live Cursor linux-x64 feed.
2. If `pkgver` changed, commits `PKGBUILD` and `.SRCINFO`.
3. Tags `v$pkgver` (an upstream bump resets `pkgrel` to 1, so 0.36.0 → tag `v0.36.0`).
4. Pushes the branch and tag.
2. If `pkgver` changed, commits `PKGBUILD` and `.SRCINFO` as eva.
3. Pushes branch `chore/bump-$pkgver` (force-with-lease if that version is re-run). It does **not** push `master` or create a tag.
4. Opens a PR into `master` via the Gitea API (or reuses an open PR from that head). Title: `pkgbuild: Bump grok-bot-bin to $pkgver`.
The tag triggers `.gitea/workflows/build.yml`, which builds the Arch package and attaches `grok-bot-bin-$pkgver-$pkgrel-x86_64.pkg.tar.zst` to the Gitea release.
`master` and tags stay protected; the bump job must not push those refs. A no-op is only “already at this `pkgver`” (exit 0). Branch push or PR create/reuse failures fail the job.
Actions **can** push and tag on this forge. [Run 1190](https://git.s1d3sw1ped.com/s1d3sw1ped/grok-bot-bin/actions/runs/1190) (schedule on `master`) bumped 0.30.0 → 0.35.0 and pushed `master` plus tag `v0.35.0`.
After that PR merges, `.gitea/workflows/tag-release.yml` (push to `master`, or `workflow_dispatch`) reads `pkgver` from `PKGBUILD`. If tag `v$pkgver` is missing, it creates and pushes it for the master commit; if the tag already exists, it is a no-op. Pushing only that tag does not re-run the PKGBUILD bump.
If the script cannot parse the feed, the `.deb` download fails, or `curl` / `python3` / `sha256sum` is missing, the job fails (it is not a silent “up to date”). `jq` is optional; without it the script parses the feed with `python3`. The workflow still `apt-get install`s `jq` for the run. A no-op is only “already at this `pkgver`.
The tag triggers `.gitea/workflows/build.yml`, which builds the Arch package and attaches `grok-bot-bin-$pkgver-$pkgrel-x86_64.pkg.tar.zst` to the Gitea release. An upstream bump resets `pkgrel` to 1, so 0.39.0 → tag `v0.39.0`.
Scheduled jobs run on the default branch (`master`). Product PRs land on `develop`; promote or run the manual path below if `develop` is ahead of `master`.
If the script cannot parse the feed, the `.deb` download fails, or `curl` / `python3` / `sha256sum` is missing, the job fails (it is not a silent “up to date”). `jq` is optional; without it the script parses the feed with `python3`. The workflow still `apt-get install`s `jq` for the run.
Scheduled jobs run on the default branch (`master`). Bump PRs target `master` so merge can tag. Product PRs still land on `develop` (see CONTRIBUTING).
### Manual force path
When you do not want to wait for cron, or you are landing a bump on `develop`:
When you do not want to wait for cron:
```bash
# requires curl, python3, sha256sum; jq optional
./scripts/update.sh
```
If the feed is newer, that rewrites `PKGBUILD` and `.SRCINFO`. Then commit, tag, and push (or open a PR into `develop`):
If the feed is newer, that rewrites `PKGBUILD` and `.SRCINFO`. Commit and open a PR into `master` (same as the scheduled job); after merge, `tag-release.yml` creates `v<pkgver>`. Or tag yourself after merge:
```bash
git add PKGBUILD .SRCINFO
git commit -m "pkgbuild: Bump grok-bot-bin to <pkgver>"
git push origin HEAD:develop # or open a PR into develop
# After it should cut a release:
git tag "v<pkgver>" # e.g. v0.36.0
git push origin "HEAD:chore/bump-<pkgver>" # then open a PR into master
# After merge, tag-release.yml creates v<pkgver>. To tag yourself:
git tag "v<pkgver>" # e.g. v0.39.0
git push origin "v<pkgver>"
makepkg -si # install from this tree without waiting for the release asset
```
@@ -98,6 +100,8 @@ Install the new version with `makepkg -si`, or (once CI publishes the asset) `pa
## Notes
- `/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.
- Auto-update privilege order: `sudo -n` (passwordless, e.g. lab NOPASSWD) → `pkexec` / polkit when launched from the desktop (no TTY, `DISPLAY` or `WAYLAND_DISPLAY` set) → interactive `sudo` when stdin is a TTY. Cancel or deny still launches the installed binary. Passwordless sudo is **not** the default.
- Desktop / CachyOS: `polkit` (provides `pkexec`) and a session polkit authentication agent (usually already running with KDE / GNOME / Hyprland / etc.) are required for the graphical password prompt. The package installs `/usr/lib/grok-bot-bin/pkexec-pacman-u` and `com.s1d3sw1ped.grok-bot-bin.update` (`auth_admin`, not NOPASSWD). `polkit` is an optdepend.
- If the app menu still launches an old binary without updating, run `/usr/bin/grok-bot` once from a terminal, or `sudo pacman -U` the newer `.pkg.tar.zst` from Releases — the menu must call the PATH shim, not `/opt/Grok Bot/…`.
- Upstream Linux builds still have no in-app updater for the Electron app itself; `scripts/update.sh` (cron or manual) is the packaging bump from Cursor's feed.
- `chrome-sandbox` is left non-setuid because the install path contains a space; user namespaces cover sandboxing on CachyOS.
+18
View File
@@ -0,0 +1,18 @@
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE policyconfig PUBLIC
"-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
"http://www.freedesktop.org/standards/PolicyKit/1/policyconfig.dtd">
<policyconfig>
<vendor>s1d3sw1ped</vendor>
<vendor_url>https://git.s1d3sw1ped.com/s1d3sw1ped/grok-bot-bin</vendor_url>
<action id="com.s1d3sw1ped.grok-bot-bin.update">
<description>Install a grok-bot-bin package update</description>
<message>Authentication is required to update Grok Bot</message>
<defaults>
<allow_any>no</allow_any>
<allow_inactive>no</allow_inactive>
<allow_active>auth_admin</allow_active>
</defaults>
<annotate key="org.freedesktop.policykit.exec.path">/usr/lib/grok-bot-bin/pkexec-pacman-u</annotate>
</action>
</policyconfig>
+38 -8
View File
@@ -5,6 +5,43 @@ set -u
REAL_DIR="/opt/Grok Bot"
API_URL='https://git.s1d3sw1ped.com/api/v1/repos/s1d3sw1ped/grok-bot-bin/releases?limit=1'
PKEXEC_HELPER=/usr/lib/grok-bot-bin/pkexec-pacman-u
# Privilege order for pacman -U:
# 1. sudo -n (NOPASSWD, e.g. lab CT113)
# 2. pkexec (graphical polkit; desktop Exec=grok-bot has no TTY)
# 3. interactive sudo (terminal TTY)
# Never default to passwordless sudo. Cancel/deny still launches the installed binary.
_install_update_pkg() {
local pkg=$1
if sudo -n true 2>/dev/null; then
if sudo -n pacman -U --noconfirm "$pkg"; then
return 0
fi
echo "grok-bot: pacman -U failed; launching installed version" >&2
return 1
fi
if [[ ! -t 0 ]] && command -v pkexec >/dev/null 2>&1 && [[ -x "$PKEXEC_HELPER" ]] \
&& [[ -n "${DISPLAY:-}${WAYLAND_DISPLAY:-}" ]]; then
if pkexec --disable-internal-agent "$PKEXEC_HELPER" "$pkg"; then
return 0
fi
echo "grok-bot: polkit auth failed or cancelled; launching installed version" >&2
return 1
fi
if [[ -t 0 ]]; then
if sudo pacman -U --noconfirm "$pkg"; then
return 0
fi
fi
echo "grok-bot: need sudo or polkit to auto-update; run: sudo pacman -U <pkg> or launch /usr/bin/grok-bot from a terminal" >&2
echo "grok-bot: pacman -U failed; launching installed version" >&2
return 1
}
_maybe_update() {
[[ "${GROK_BOT_NO_UPDATE:-}" == "1" ]] && return 0
@@ -50,14 +87,7 @@ _maybe_update() {
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: need sudo to auto-update; run: sudo pacman -U <pkg> or launch /usr/bin/grok-bot from a terminal" >&2
echo "grok-bot: pacman -U failed; launching installed version" >&2
return 0
fi
fi
_install_update_pkg "$pkg" || return 0
}
_maybe_update || true
+39
View File
@@ -0,0 +1,39 @@
#!/usr/bin/env bash
# Root helper for grok-bot-bin GUI auto-update. Invoked via pkexec only.
# Runs pacman -U on a local grok-bot-bin package — not a generic pacman wrapper.
set -euo pipefail
if [[ $# -ne 1 ]]; then
echo "pkexec-pacman-u: usage: pkexec-pacman-u /path/to/grok-bot-bin-*-x86_64.pkg.tar.zst" >&2
exit 2
fi
pkg=$1
if [[ "$pkg" != /* || "$pkg" == *..* ]]; then
echo "pkexec-pacman-u: refusing path: $pkg" >&2
exit 2
fi
base=$(basename -- "$pkg")
if [[ ! "$base" =~ ^grok-bot-bin-.+-x86_64\.pkg\.tar\.zst$ ]]; then
echo "pkexec-pacman-u: refusing package name: $base" >&2
exit 2
fi
if [[ ! -f "$pkg" || ! -r "$pkg" ]]; then
echo "pkexec-pacman-u: package not found or unreadable: $pkg" >&2
exit 2
fi
# Filename is not enough; require the package metadata name.
info=$(/usr/bin/pacman -Qp -- "$pkg" 2>/dev/null) || {
echo "pkexec-pacman-u: not a pacman package: $pkg" >&2
exit 2
}
name=${info%% *}
if [[ "$name" != grok-bot-bin ]]; then
echo "pkexec-pacman-u: refusing package $name" >&2
exit 2
fi
exec /usr/bin/pacman -U --noconfirm -- "$pkg"