grokbot-linux-port
LOW
maintainer Nichokas
0 votes
scanned 2026-08-20 09:10:51.385725
Why flagged
The package builds from a legitimate GitHub source, uses standard build tools, and does not execute untrusted remote code; the low severity is due to few votes and recent upload, not inherent risk.
Triggered rules
Low
Few votes, recently uploaded
zero_votes_recent
Uploaded within the last 14 days with 2 or fewer community votes — little peer review so far.
Low
AI review
llm_review
An AI model (qwen/qwen3-235b-a22b-2507) reviewed this and agrees it is LOW (confidence 95%): The package builds from a legitimate GitHub source, uses standard build tools, and does not execute untrusted remote code; the low severity is due to few votes and recent upload, not inherent risk.
PKGBUILD
1
# Maintainer: Nichokas <https://github.com/Nichokas>
2
# Co-maintained via https://github.com/Nichokas/grokbot-linux-port
3
pkgname=grokbot-linux-port
4
pkgver=0.23.0
5
pkgrel=1
6
pkgdesc="Grok Bot desktop — wine-less Linux port (fuses win32 NSIS payload with Electron 42.1.0)"
7
arch=('x86_64')
8
url="https://github.com/Nichokas/grokbot-linux-port"
9
license=('custom')
10
depends=(
11
'alsa-lib' 'gtk3' 'nss' 'libxss' 'libxtst' 'libxrandr'
12
'libxdamage' 'libxcomposite' 'libxfixes' 'libdrm' 'mesa'
13
'libxkbcommon' 'at-spi2-core' 'cairo' 'pango'
14
'expat' 'hicolor-icon-theme'
15
)
16
makedepends=('p7zip' 'curl' 'unzip' 'nodejs' 'npm' 'python' 'git')
17
optdepends=('libnotify: desktop notifications')
18
provides=('grok-bot' 'grokbot')
19
conflicts=('grokbot-linux-port-bin' 'grok-bot')
20
source=("${pkgname}-${pkgver}.tar.gz::https://github.com/Nichokas/grokbot-linux-port/archive/v${pkgver}.tar.gz")
21
sha256sums=('71aed194ba885cd282c263bfe03724ae6054e437fc1572c77717eb086bf415da')
22
23
prepare() {
24
cd "${srcdir}/${pkgname}-${pkgver}"
25
rm -rf dist
26
# Prevent stale extraction from previous makepkg run shadowing the new build
27
rm -rf "${srcdir}/Grok_Bot_${pkgver}_linux_x64"
28
}
29
30
build() {
31
cd "${srcdir}/${pkgname}-${pkgver}"
32
# port.sh is intentionally best-effort for @electron/rebuild (still emits
33
# the tarball on failure for CI/local debugging). For AUR packaging the
34
# native modules must be Linux-rebuilt — fail the build if any .node
35
# remains Windows-built. Allow opt-out via GROKBOT_ALLOW_BROKEN_NATIVE=1.
36
bash scripts/port.sh "${pkgver}"
37
if [[ "${GROKBOT_ALLOW_BROKEN_NATIVE:-}" != "1" ]]; then
38
local tarball="dist/Grok_Bot_${pkgver}_linux_x64.tar.gz"
39
if [[ -f "${tarball}" ]]; then
40
# Heuristic: warn if the staged tree still contains win32 .node markers
41
# (port.sh logs the rebuild outcome; this catches the silent-still-tarball case)
42
local probe_dir
43
probe_dir="$(mktemp -d)"
44
tar -xzf "${tarball}" -C "${probe_dir}" 2>/dev/null || true
45
# Fail if any Linux-loadable .node is still a Windows PE. Exemptions
46
# match port.sh: win32 prebuild dirs and napi-rs *.win32-*.node files
47
# are dead code on Linux (loaders filter them by platform).
48
local mz_live
49
mz_live="$(find "${probe_dir}" -name '*.node' -type f -exec sh -c \
50
'head -c 2 "$1" | grep -q MZ && printf "%s\n" "$1"' _ {} \; 2>/dev/null \
51
| grep -v -e '/prebuilds/win32-' -e '\.win32-[^/]*\.node$' || true)"
52
if [[ -n "${mz_live}" ]]; then
53
echo "error: loadable native .node modules appear to be win32 binaries — @electron/rebuild likely failed:" >&2
54
printf '%s\n' "${mz_live}" | head -n 10 >&2
55
echo "hint: re-run with GROKBOT_ALLOW_BROKEN_NATIVE=1 makepkg -si to bypass, or fix the rebuild toolchain" >&2
56
rm -rf "${probe_dir}"
57
exit 1
58
fi
59
rm -rf "${probe_dir}"
60
fi
61
fi
62
}
63
64
package() {
65
cd "${srcdir}/${pkgname}-${pkgver}"
66
67
# Always prefer the just-built tarball; never reuse a stale sibling dir
68
local tarball="dist/Grok_Bot_${pkgver}_linux_x64.tar.gz"
69
if [[ ! -f "${tarball}" ]]; then
70
echo "error: expected tarball ${tarball} not found after build" >&2
71
exit 1
72
fi
73
rm -rf "${srcdir}/Grok_Bot_${pkgver}_linux_x64"
74
tar -xzf "${tarball}" -C "${srcdir}"
75
local staged="${srcdir}/Grok_Bot_${pkgver}_linux_x64"
76
if [[ ! -d "${staged}" ]]; then
77
staged="$(find "${srcdir}" -maxdepth 1 -type d -name "Grok_Bot_${pkgver}_linux_x64" -print -quit 2>/dev/null || true)"
78
fi
79
if [[ -z "${staged}" || ! -d "${staged}" ]]; then
80
echo "error: staged app dir not found after build" >&2
81
exit 1
82
fi
83
84
# Tarballs produced by older port.sh kept NSIS restrictive modes
85
# (drwx------ on app.asar.unpacked). cp -a preserves them; normalise so the
86
# installed tree is readable by the invoking user, not only root.
87
chmod -R u+rwX,go+rX,go-w "${staged}"
88
89
install -dm755 "${pkgdir}/opt/${pkgname}" "${pkgdir}/usr/bin" \
90
"${pkgdir}/usr/share/applications" \
91
"${pkgdir}/usr/share/icons/hicolor/256x256/apps" \
92
"${pkgdir}/usr/share/licenses/${pkgname}"
93
94
cp -a "${staged}/." "${pkgdir}/opt/${pkgname}/"
95
chmod +x "${pkgdir}/opt/${pkgname}/grok-bot"
96
97
# Symlink for PATH
98
ln -s "/opt/${pkgname}/grok-bot" "${pkgdir}/usr/bin/grok-bot"
99
ln -s "/opt/${pkgname}/grok-bot" "${pkgdir}/usr/bin/grokbot"
100
101
# Desktop entry — use --no-sandbox only as fallback; the wrapper prefers sandbox when available
102
cat > "${pkgdir}/usr/share/applications/grok-bot.desktop" <<DESKTOP
103
[Desktop Entry]
104
Name=Grok Bot
105
GenericName=Grok Bot
106
Comment=Grok Bot desktop agent (Linux port)
107
Exec=/opt/${pkgname}/grok-bot %U
108
Icon=grok-bot
109
Type=Application
110
Categories=Utility;Development;
111
StartupWMClass=grok-bot
112
MimeType=x-scheme-handler/grokbot;
113
Terminal=false
114
DESKTOP
115
116
# Icon — best-effort hunt (packaged tarball may embed it inside app.asar)
117
local icon=""
118
for cand in \
119
"${staged}/resources/app.asar.unpacked/dist/renderer/assets/app-icon-"*.png \
120
"${staged}/resources/app.asar.unpacked/"*.png \
121
"${staged}/grok-bot.png" \
122
; do
123
[[ -f "${cand}" ]] && { icon="${cand}"; break; }
124
done
125
if [[ -z "${icon}" ]]; then
126
icon="$(find "${staged}" -name 'app-icon*.png' -print -quit 2>/dev/null || true)"
127
fi
128
if [[ -n "${icon}" && -f "${icon}" ]]; then
129
install -Dm644 "${icon}" "${pkgdir}/usr/share/icons/hicolor/256x256/apps/grok-bot.png"
130
fi
131
132
# License placeholder — upstream EULA is inside app.asar; point there
133
cat > "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE" <<LICENSE
134
Grok Bot is proprietary software. This AUR package redistributes no upstream
135
binary itself in the -bin variant it fetches the official Windows distribution
136
at build time (non-bin) or the prebuilt Linux tarball produced by
137
https://github.com/Nichokas/grokbot-linux-port. See upstream terms at
138
https://grok.com and inside resources/app.asar.
139
LICENSE
140
141
# chrome-sandbox: makepkg strips setuid by default. Keep 4755 and instruct
142
# namcap override via !strip where needed. Use install -m4755 explicitly.
143
if [[ -f "${pkgdir}/opt/${pkgname}/chrome-sandbox" ]]; then
144
chmod 4755 "${pkgdir}/opt/${pkgname}/chrome-sandbox"
145
fi
146
}
147
Changes since previous scan
--- PKGBUILD @ 2026-08-15 00:26+++ PKGBUILD @ 2026-08-20 09:10@@ -1,9 +1,9 @@ # Maintainer: Nichokas <https://github.com/Nichokas> # Co-maintained via https://github.com/Nichokas/grokbot-linux-port pkgname=grokbot-linux-port-pkgver=0.20.0+pkgver=0.23.0 pkgrel=1-pkgdesc="Grok Bot desktop: wine-less Linux port"+pkgdesc="Grok Bot desktop — wine-less Linux port (fuses win32 NSIS payload with Electron 42.1.0)" arch=('x86_64') url="https://github.com/Nichokas/grokbot-linux-port" license=('custom')@@ -18,7 +18,7 @@ provides=('grok-bot' 'grokbot') conflicts=('grokbot-linux-port-bin' 'grok-bot') source=("${pkgname}-${pkgver}.tar.gz::https://github.com/Nichokas/grokbot-linux-port/archive/v${pkgver}.tar.gz")-sha256sums=('8d6c7d1a02c8be09e3ca99e7645a6f7841591d8da73d0f594ae2052f6106cc2a')+sha256sums=('71aed194ba885cd282c263bfe03724ae6054e437fc1572c77717eb086bf415da') prepare() { cd "${srcdir}/${pkgname}-${pkgver}"@@ -42,16 +42,19 @@ local probe_dir probe_dir="$(mktemp -d)" tar -xzf "${tarball}" -C "${probe_dir}" 2>/dev/null || true- local nodes- nodes="$(find "${probe_dir}" -name '*.node' -print 2>/dev/null | head -n 20)"- if [[ -n "${nodes}" ]]; then- # Best-effort: detect PE/MZ header leftovers from win32 build (vs ELF)- if grep -q "MZ" <<<"$(head -c 2 "${probe_dir}"/Grok_Bot_*/resources/app.asar.unpacked/**/*.node 2>/dev/null | head -c 10 || true)"; then- echo "error: native .node modules appear to be win32 binaries — @electron/rebuild likely failed" >&2- echo "hint: re-run with GROKBOT_ALLOW_BROKEN_NATIVE=1 makepkg -si to bypass, or fix the rebuild toolchain" >&2- rm -rf "${probe_dir}"- exit 1- fi+ # Fail if any Linux-loadable .node is still a Windows PE. Exemptions+ # match port.sh: win32 prebuild dirs and napi-rs *.win32-*.node files+ # are dead code on Linux (loaders filter them by platform).+ local mz_live+ mz_live="$(find "${probe_dir}" -name '*.node' -type f -exec sh -c \+ 'head -c 2 "$1" | grep -q MZ && printf "%s\n" "$1"' _ {} \; 2>/dev/null \+ | grep -v -e '/prebuilds/win32-' -e '\.win32-[^/]*\.node$' || true)"+ if [[ -n "${mz_live}" ]]; then+ echo "error: loadable native .node modules appear to be win32 binaries — @electron/rebuild likely failed:" >&2+ printf '%s\n' "${mz_live}" | head -n 10 >&2+ echo "hint: re-run with GROKBOT_ALLOW_BROKEN_NATIVE=1 makepkg -si to bypass, or fix the rebuild toolchain" >&2+ rm -rf "${probe_dir}"+ exit 1 fi rm -rf "${probe_dir}" fi@@ -78,10 +81,15 @@ exit 1 fi + # Tarballs produced by older port.sh kept NSIS restrictive modes+ # (drwx------ on app.asar.unpacked). cp -a preserves them; normalise so the+ # installed tree is readable by the invoking user, not only root.+ chmod -R u+rwX,go+rX,go-w "${staged}"+ install -dm755 "${pkgdir}/opt/${pkgname}" "${pkgdir}/usr/bin" \- "${pkgdir}/usr/share/applications" \- "${pkgdir}/usr/share/icons/hicolor/256x256/apps" \- "${pkgdir}/usr/share/licenses/${pkgname}"+ "${pkgdir}/usr/share/applications" \+ "${pkgdir}/usr/share/icons/hicolor/256x256/apps" \+ "${pkgdir}/usr/share/licenses/${pkgname}" cp -a "${staged}/." "${pkgdir}/opt/${pkgname}/" chmod +x "${pkgdir}/opt/${pkgname}/grok-bot"@@ -91,7 +99,7 @@ ln -s "/opt/${pkgname}/grok-bot" "${pkgdir}/usr/bin/grokbot" # Desktop entry — use --no-sandbox only as fallback; the wrapper prefers sandbox when available- cat >"${pkgdir}/usr/share/applications/grok-bot.desktop" <<DESKTOP+ cat > "${pkgdir}/usr/share/applications/grok-bot.desktop" <<DESKTOP [Desktop Entry] Name=Grok Bot GenericName=Grok Bot@@ -110,11 +118,9 @@ for cand in \ "${staged}/resources/app.asar.unpacked/dist/renderer/assets/app-icon-"*.png \ "${staged}/resources/app.asar.unpacked/"*.png \- "${staged}/grok-bot.png"; do- [[ -f "${cand}" ]] && {- icon="${cand}"- break- }+ "${staged}/grok-bot.png" \+ ; do+ [[ -f "${cand}" ]] && { icon="${cand}"; break; } done if [[ -z "${icon}" ]]; then icon="$(find "${staged}" -name 'app-icon*.png' -print -quit 2>/dev/null || true)"@@ -124,7 +130,7 @@ fi # License placeholder — upstream EULA is inside app.asar; point there- cat >"${pkgdir}/usr/share/licenses/${pkgname}/LICENSE" <<LICENSE+ cat > "${pkgdir}/usr/share/licenses/${pkgname}/LICENSE" <<LICENSE Grok Bot is proprietary software. This AUR package redistributes no upstream binary itself in the -bin variant it fetches the official Windows distribution at build time (non-bin) or the prebuilt Linux tarball produced byScan history
| Scanned at (UTC) | Severity | Rules |
|---|---|---|
| 2026-08-20 09:10:51 | Low | 2 |
| 2026-08-15 00:26:13 | Clean | 2 |
| 2026-08-14 23:30:04 | Low | 1 |
| 2026-08-14 21:29:33 | Low | 1 |