superhuman

MEDIUM
maintainer joeyeamigh 1 votes scanned 2026-09-17 00:27:14.276658
View on AUR
Why flagged

The package downloads and executes remote Node.js tools (npm, npx) and a Windows binary from a non-standard host without checksum verification, creating a supply-chain risk if those sources are compromised.

Triggered rules

Medium npm/yarn/pnpm install of an undeclared external package npm_install_external

Runs `npm/yarn/pnpm install <package>` for a package not in source=(), pulling unpinned, unreviewed code at build time. Severity downgraded: the package declares/looks like a Node.js consumer, where build-time installs are expected.

  • PKGBUILD:62 npm install --silent @electron/asar
Medium npx/bunx/deno executes a remote package remote_code_tool

`npx`/`bunx`/`pnpm dlx`/`deno run <url>` downloads AND runs a remote package at build time — the moral equivalent of piping a download into a shell. Severity downgraded: Node.js consumer context.

  • PKGBUILD:67 npx @electron/asar extract app-win/resources/app.asar asar-contents
  • PKGBUILD:82 npx @electron/asar pack asar-contents app.asar
Medium source=() URL on a non-standard host source_untrusted_domain

One or more source=() URLs point to a host outside the trusted allowlist (github.com, gitlab.com, codeberg.org, pypi.org, …).

  • PKGBUILD:23 "Superhuman-${pkgver}.exe::https://assets.mail.superhuman.com/webapp/download/Superhuman.exe"
Medium AI review llm_review

An AI model (qwen/qwen3-235b-a22b-2507) reviewed this and agrees it is MEDIUM (confidence 85%): The package downloads and executes remote Node.js tools (npm, npx) and a Windows binary from a non-standard host without checksum verification, creating a supply-chain risk if those sources are compromised.

PKGBUILD

4 offending line(s) highlighted
1# Maintainer: Joey Eamigh @JoeyEamigh on GitHub
2
3# shellcheck shell=bash
4# shellcheck disable=SC2034 # Variables used by makepkg
5# shellcheck disable=SC2154 # srcdir/pkgdir/startdir set by makepkg
6
7pkgname=superhuman
8pkgver=1041.0.51
9pkgrel=1
10pkgdesc="The fastest email experience ever made (unofficial)"
11arch=('x86_64')
12url="https://superhuman.com"
13license=('custom:proprietary')
14depends=('gtk3' 'nss' 'alsa-lib' 'libcups' 'libxkbcommon' 'libdrm' 'mesa' 'libnotify')
15makedepends=('p7zip' 'nodejs' 'npm' 'wget' 'unzip')
16optdepends=(
17 'libappindicator-gtk3: System tray support'
18 'xdg-utils: Protocol handler registration'
19)
20options=('!strip')
21install=superhuman.install
22source=(
23 "Superhuman-${pkgver}.exe::https://assets.mail.superhuman.com/webapp/download/Superhuman.exe"
24 "linux_tray.js"
25)
26sha256sums=('SKIP'
27 '2ca108b624f8e444e3ad4a70f5d066342a85dc6d245ce63220a91e5c2b4cfd25')
28noextract=("Superhuman-${pkgver}.exe")
29
30_electron_version="41.6.1"
31_failed_patches=()
32
33prepare() {
34 cd "$srcdir" || return
35 _failed_patches=()
36
37 # Extract Windows installer
38 msg2 "Extracting Windows installer..."
39 mkdir -p extract
40 7z x -y "Superhuman-${pkgver}.exe" -o"extract" > /dev/null
41
42 # Extract the app from app-64.7z
43 mkdir -p app-win
44 7z x -y "extract/\$PLUGINSDIR/app-64.7z" -o"app-win" > /dev/null
45
46 # Detect Electron version
47 _electron_version=$(strings app-win/Superhuman.exe 2>/dev/null | grep -oP 'Electron/\K[0-9]+\.[0-9]+\.[0-9]+' | head -1 || echo "$_electron_version")
48 msg2 "Detected Electron version: ${_electron_version}"
49
50 # Download Electron for Linux
51 msg2 "Downloading Electron ${_electron_version}..."
52 mkdir -p electron
53 wget -q "https://github.com/electron/electron/releases/download/v${_electron_version}/electron-v${_electron_version}-linux-x64.zip" \
54 -O electron/electron.zip
55 cd electron || return
56 unzip -qo electron.zip
57 rm electron.zip
58 cd ..
59
60 # Install asar tool
61 msg2 "Installing asar tool..."
62 npm install --silent @electron/asar
63
64 # Extract app.asar
65 msg2 "Extracting app.asar..."
66 mkdir -p asar-contents
67 npx @electron/asar extract app-win/resources/app.asar asar-contents
68
69 # Extract version from package.json
70 if [ -f "asar-contents/package.json" ]; then
71 _app_version=$(grep -oP '"version"\s*:\s*"\K[^"]+' asar-contents/package.json 2>/dev/null || echo "unknown")
72 msg2 "Detected Superhuman version: ${_app_version}"
73 echo "${_app_version}" > VERSION
74 fi
75
76 # Apply Linux compatibility patches
77 _write_patch_tool
78 _apply_patches
79
80 # Repack app.asar
81 msg2 "Repacking app.asar..."
82 npx @electron/asar pack asar-contents app.asar
83}
84
85# The main process ships as a single webpack bundle, so every patch is an exact
86# literal replacement guarded by an expected match count. A drifted match string
87# fails loudly instead of silently clobbering an unrelated module.
88_write_patch_tool() {
89 cat > "$srcdir/apply_patch.js" << 'PATCHER'
90const fs = require('fs')
91
92const [file, expected, find, replace] = process.argv.slice(2)
93const parts = fs.readFileSync(file, 'utf8').split(find)
94const found = parts.length - 1
95
96if (found !== Number(expected)) {
97 process.stderr.write(` expected ${expected} match(es), found ${found}\n`)
98 process.stderr.write(` anchor: ${find.split('\n')[0].trim().slice(0, 100)}\n`)
99 process.exit(1)
100}
101
102fs.writeFileSync(file, parts.join(replace))
103PATCHER
104}
105
106# _bundle_patch <description> required|optional <expected matches> <find> <replace>
107# A required patch aborts the build; an optional one is reported in the summary.
108_bundle_patch() {
109 local desc="$1"
110 local importance="$2"
111 local count="$3"
112 local find="$4"
113 local replace="$5"
114
115 if node "$srcdir/apply_patch.js" "$srcdir/asar-contents/dist/main.js" "$count" "$find" "$replace"; then
116 msg2 "Applied: $desc"
117 return 0
118 fi
119
120 if [ "$importance" = "required" ]; then
121 error "REQUIRED PATCH FAILED: $desc"
122 error ">>> MAINTAINER: Superhuman changed, patches need review <<<"
123 return 1
124 fi
125
126 warning "OPTIONAL PATCH FAILED: $desc"
127 _failed_patches+=("$desc")
128 return 0
129}
130
131_apply_patches() {
132 msg2 "Applying Linux compatibility patches..."
133 local dist_dir="$srcdir/asar-contents/dist"
134
135 if [ ! -f "$dist_dir/main.js" ]; then
136 error "Superhuman bundle layout changed: dist/main.js not found"
137 return 1
138 fi
139
140 # Upstream already hides the last window instead of closing it, but gates
141 # that on macOS. Without this the window teardown runs on every close and
142 # destroys the tabs behind a still-visible window.
143 _bundle_patch \
144 "Window: Close to tray instead of quitting" \
145 required \
146 1 \
147 " if (this.main.windows.length === 1 && isMac && !isForceQuitting) {" \
148 " if (this.main.windows.length === 1 && (isMac || process.platform === 'linux') && !isForceQuitting) {"
149
150 _bundle_patch \
151 "Updater: Skip on Linux, updates come from pacman" \
152 required \
153 1 \
154 " async _startUpdate() {" \
155 " async _startUpdate() {
156 if (process.platform === 'linux') {
157 this.setStage(stages.SKIPPED)
158 return
159 }"
160
161 _bundle_patch \
162 "Window: Ctrl shortcuts for Linux" \
163 optional \
164 1 \
165 " _registerShortcuts(view) {" \
166 " _registerShortcuts(view) {
167 if (process.platform === 'linux') {
168 this._registerWindowsShortcuts(view);
169 return;
170 }"
171
172 _bundle_patch \
173 "Window: Zoom control for Linux" \
174 optional \
175 1 \
176 "(process.platform === 'win32' && input.control)" \
177 "((process.platform === 'win32' || process.platform === 'linux') && input.control)"
178
179 _bundle_patch \
180 "Main: Linux argv URL handling" \
181 optional \
182 1 \
183 " } else if (process.platform === 'win32') {
184 // the \`open-url\` event is Mac-only, so on Windows startup we check argv directly" \
185 " } else if (process.platform === 'win32' || process.platform === 'linux') {
186 // the \`open-url\` event is Mac-only, so on Windows startup we check argv directly"
187
188 # wasOpenedAsHidden() is macOS-only, so the autostart entry's --hidden flag
189 # is otherwise ignored.
190 _bundle_patch \
191 "Main: Honor --hidden on Linux" \
192 optional \
193 1 \
194 " let launchHidden = process.platform === 'win32' ? false : this._loginItem.wasOpenedAsHidden()" \
195 " let launchHidden = process.argv.includes('--hidden') || (process.platform === 'win32' ? false : this._loginItem.wasOpenedAsHidden())"
196
197 # Tray module - close to tray with a show/hide and quit menu
198 cp "$srcdir/linux_tray.js" "$dist_dir/linux_tray.js"
199 sed -i "1i\\
200if (process.platform === 'linux') require('./linux_tray');" "$dist_dir/main.js"
201 msg2 "Applied: Tray module (self-initializing)"
202
203 if [ ${#_failed_patches[@]} -gt 0 ]; then
204 warning "=========================================="
205 warning "${#_failed_patches[@]} optional patch(es) failed:"
206 local desc
207 for desc in "${_failed_patches[@]}"; do
208 warning " - $desc"
209 done
210 warning "The app will run but these features are missing."
211 warning ">>> MAINTAINER: Superhuman updated, patches need review <<<"
212 warning "=========================================="
213 fi
214}
215
216build() {
217 cd "$srcdir" || return
218
219 mkdir -p superhuman-linux/resources
220
221 # Copy Electron files
222 cp -r electron/* superhuman-linux/
223
224 # Remove default app
225 rm -f superhuman-linux/resources/default_app.asar
226
227 # Copy patched app.asar
228 cp app.asar superhuman-linux/resources/
229
230 # Copy version file
231 [ -f VERSION ] && cp VERSION superhuman-linux/
232
233 # Rename electron binary
234 mv superhuman-linux/electron superhuman-linux/superhuman-bin
235
236 # Create wrapper script
237 cat > superhuman-linux/superhuman << 'WRAPPER'
238#!/bin/bash
239SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)"
240
241# Electron resolves the desktop entry from this when registering itself as the
242# mailto:/superhuman: handler via xdg-settings.
243export CHROME_DESKTOP="${CHROME_DESKTOP:-superhuman.desktop}"
244
245ARGS=()
246for arg in "$@"; do
247 if [[ "$arg" == superhuman://login* ]]; then
248 ARGS+=("${arg/superhuman:\/\/login/superhuman://~login}")
249 else
250 ARGS+=("$arg")
251 fi
252done
253
254exec "${SCRIPT_DIR}/superhuman-bin" "${ARGS[@]}"
255WRAPPER
256 chmod +x superhuman-linux/superhuman
257}
258
259package() {
260 cd "$srcdir" || return
261
262 # Install main application
263 install -dm755 "$pkgdir/opt/superhuman"
264 cp -r superhuman-linux/* "$pkgdir/opt/superhuman/"
265 chmod +x "$pkgdir/opt/superhuman/superhuman"
266 chmod +x "$pkgdir/opt/superhuman/superhuman-bin"
267 chmod +x "$pkgdir/opt/superhuman/chrome_crashpad_handler"
268
269 # Fallback sandbox for kernels without unprivileged user namespaces
270 chmod 4755 "$pkgdir/opt/superhuman/chrome-sandbox"
271
272 # Install icon (check both locations: assets/ for GitHub, root for AUR)
273 local icon_src=""
274 if [ -f "$startdir/assets/superhuman.png" ]; then
275 icon_src="$startdir/assets/superhuman.png"
276 elif [ -f "$startdir/superhuman.png" ]; then
277 icon_src="$startdir/superhuman.png"
278 fi
279 if [ -n "$icon_src" ]; then
280 install -Dm644 "$icon_src" "$pkgdir/usr/share/icons/hicolor/256x256/apps/superhuman.png"
281 cp "$icon_src" "$pkgdir/opt/superhuman/"
282 fi
283
284 install -Dm644 superhuman-linux/LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE.electron"
285
286 # Create bin symlinks
287 install -dm755 "$pkgdir/usr/bin"
288 ln -s /opt/superhuman/superhuman "$pkgdir/usr/bin/superhuman"
289
290 # Install desktop file
291 install -Dm644 /dev/stdin "$pkgdir/usr/share/applications/superhuman.desktop" << 'EOF'
292[Desktop Entry]
293Name=Superhuman
294Comment=The fastest email experience ever made
295Exec=/opt/superhuman/superhuman %U
296Icon=superhuman
297Type=Application
298Categories=Network;Email;
299MimeType=x-scheme-handler/mailto;x-scheme-handler/superhuman;
300StartupWMClass=superhuman
301Terminal=false
302X-KDE-Protocols=mailto;superhuman;
303EOF
304
305 # Install autostart file (disabled by default)
306 install -Dm644 /dev/stdin "$pkgdir/etc/xdg/autostart/superhuman.desktop" << 'EOF'
307[Desktop Entry]
308Name=Superhuman
309Comment=The fastest email experience ever made
310Exec=/opt/superhuman/superhuman --hidden
311Icon=superhuman
312Type=Application
313Terminal=false
314X-GNOME-Autostart-enabled=false
315Hidden=true
316NoDisplay=true
317EOF
318}
319

Changes since previous scan

--- PKGBUILD @ 2026-09-10 00:22
+++ PKGBUILD @ 2026-09-17 00:27
@@ -5,13 +5,13 @@
# shellcheck disable=SC2154 # srcdir/pkgdir/startdir set by makepkg
pkgname=superhuman
-pkgver=1041.0.42
+pkgver=1041.0.51
pkgrel=1
pkgdesc="The fastest email experience ever made (unofficial)"
arch=('x86_64')
url="https://superhuman.com"
license=('custom:proprietary')
-depends=('gtk3' 'nss' 'alsa-lib' 'libxss' 'libxtst' 'libdrm' 'mesa' 'libnotify')
+depends=('gtk3' 'nss' 'alsa-lib' 'libcups' 'libxkbcommon' 'libdrm' 'mesa' 'libnotify')
makedepends=('p7zip' 'nodejs' 'npm' 'wget' 'unzip')
optdepends=(
'libappindicator-gtk3: System tray support'
@@ -23,26 +23,16 @@
"Superhuman-${pkgver}.exe::https://assets.mail.superhuman.com/webapp/download/Superhuman.exe"
"linux_tray.js"
)
-sha256sums=('SKIP' 'SKIP')
+sha256sums=('SKIP'
+ '2ca108b624f8e444e3ad4a70f5d066342a85dc6d245ce63220a91e5c2b4cfd25')
noextract=("Superhuman-${pkgver}.exe")
_electron_version="41.6.1"
-_patch_failures=0
-
-# Automatically detect version from the downloaded exe
-# Uncomment pkgver() for -git style versioning
-# pkgver() {
-# cd "$srcdir"
-# if [ -f "VERSION" ]; then
-# cat VERSION
-# else
-# echo "1.0.0"
-# fi
-# }
+_failed_patches=()
prepare() {
cd "$srcdir" || return
- _patch_failures=0
+ _failed_patches=()
# Extract Windows installer
msg2 "Extracting Windows installer..."
@@ -84,6 +74,7 @@
fi
# Apply Linux compatibility patches
+ _write_patch_tool
_apply_patches
# Repack app.asar
@@ -91,145 +82,132 @@
npx @electron/asar pack asar-contents app.asar
}
-# Graceful patch function - warns on failure instead of breaking build
-_safe_sed_patch() {
+# The main process ships as a single webpack bundle, so every patch is an exact
+# literal replacement guarded by an expected match count. A drifted match string
+# fails loudly instead of silently clobbering an unrelated module.
+_write_patch_tool() {
+ cat > "$srcdir/apply_patch.js" << 'PATCHER'
+const fs = require('fs')
+
+const [file, expected, find, replace] = process.argv.slice(2)
+const parts = fs.readFileSync(file, 'utf8').split(find)
+const found = parts.length - 1
+
+if (found !== Number(expected)) {
+ process.stderr.write(` expected ${expected} match(es), found ${found}\n`)
+ process.stderr.write(` anchor: ${find.split('\n')[0].trim().slice(0, 100)}\n`)
+ process.exit(1)
+}
+
+fs.writeFileSync(file, parts.join(replace))
+PATCHER
+}
+
+# _bundle_patch <description> required|optional <expected matches> <find> <replace>
+# A required patch aborts the build; an optional one is reported in the summary.
+_bundle_patch() {
local desc="$1"
- local file="$2"
- local pattern="$3"
- local replacement="$4"
- local replace_all="${5:-false}"
-
- if [ ! -f "$file" ]; then
- warning "PATCH FAILED: $desc"
- warning " File not found: $(basename "$file")"
- warning " >>> MAINTAINER: App structure changed, update needed <<<"
- ((_patch_failures++)) || true
+ local importance="$2"
+ local count="$3"
+ local find="$4"
+ local replace="$5"
+
+ if node "$srcdir/apply_patch.js" "$srcdir/asar-contents/dist/main.js" "$count" "$find" "$replace"; then
+ msg2 "Applied: $desc"
+ return 0
+ fi
+
+ if [ "$importance" = "required" ]; then
+ error "REQUIRED PATCH FAILED: $desc"
+ error ">>> MAINTAINER: Superhuman changed, patches need review <<<"
return 1
fi
- if ! grep -q "$pattern" "$file" 2>/dev/null; then
- warning "PATCH FAILED: $desc"
- warning " Pattern not found in: $(basename "$file")"
- warning " >>> MAINTAINER: App code changed, update needed <<<"
- ((_patch_failures++)) || true
- return 1
- fi
-
- if [ "$replace_all" = "true" ]; then
- sed -i "s#$pattern#$replacement#g" "$file"
- else
- sed -i "s#$pattern#$replacement#" "$file"
- fi
-
- msg2 "Applied: $desc"
- return 0
-}
-
-_safe_insert_patch() {
- local desc="$1"
- local file="$2"
- local after_pattern="$3"
- local text="$4"
-
- if [ ! -f "$file" ]; then
- warning "PATCH FAILED: $desc - File not found"
- warning " >>> MAINTAINER: App structure changed, update needed <<<"
- ((_patch_failures++)) || true
- return 1
- fi
-
- if ! grep -q "$after_pattern" "$file" 2>/dev/null; then
- warning "PATCH FAILED: $desc - Pattern not found"
- warning " >>> MAINTAINER: App code changed, update needed <<<"
- ((_patch_failures++)) || true
- return 1
- fi
-
- sed -i "/$after_pattern/a\\
-$text" "$file"
- msg2 "Applied: $desc"
+ warning "OPTIONAL PATCH FAILED: $desc"
+ _failed_patches+=("$desc")
return 0
}
_apply_patches() {
msg2 "Applying Linux compatibility patches..."
- local src_dir="$srcdir/asar-contents/src"
-
- # =========================================================================
- # CORE PATCHES
- # =========================================================================
-
- _safe_sed_patch \
- "Memory poller: Linux support" \
- "${src_dir}/native_memory_poller.js" \
- "if (process.platform === 'darwin') {" \
- "if (process.platform === 'darwin' || process.platform === 'linux') {" \
- true
-
- _safe_sed_patch \
+ local dist_dir="$srcdir/asar-contents/dist"
+
+ if [ ! -f "$dist_dir/main.js" ]; then
+ error "Superhuman bundle layout changed: dist/main.js not found"
+ return 1
+ fi
+
+ # Upstream already hides the last window instead of closing it, but gates
+ # that on macOS. Without this the window teardown runs on every close and
+ # destroys the tabs behind a still-visible window.
+ _bundle_patch \
+ "Window: Close to tray instead of quitting" \
+ required \
+ 1 \
+ " if (this.main.windows.length === 1 && isMac && !isForceQuitting) {" \
+ " if (this.main.windows.length === 1 && (isMac || process.platform === 'linux') && !isForceQuitting) {"
+
+ _bundle_patch \
+ "Updater: Skip on Linux, updates come from pacman" \
+ required \
+ 1 \
+ " async _startUpdate() {" \
+ " async _startUpdate() {
+ if (process.platform === 'linux') {
+ this.setStage(stages.SKIPPED)
+ return
+ }"
+
+ _bundle_patch \
"Window: Ctrl shortcuts for Linux" \
- "${src_dir}/window.js" \
- "} else if (process.platform === 'win32') {" \
- "} else if (process.platform === 'win32' || process.platform === 'linux') {" \
- true
-
- _safe_sed_patch \
+ optional \
+ 1 \
+ " _registerShortcuts(view) {" \
+ " _registerShortcuts(view) {
+ if (process.platform === 'linux') {
+ this._registerWindowsShortcuts(view);
+ return;
+ }"
+
+ _bundle_patch \
"Window: Zoom control for Linux" \
- "${src_dir}/window.js" \
+ optional \
+ 1 \
"(process.platform === 'win32' && input.control)" \
- "((process.platform === 'win32' || process.platform === 'linux') \\&\\& input.control)" \
- true
-
- _safe_sed_patch \
+ "((process.platform === 'win32' || process.platform === 'linux') && input.control)"
+
+ _bundle_patch \
"Main: Linux argv URL handling" \
- "${src_dir}/main.js" \
- "} else if (process.platform === 'win32') {" \
- "} else if (process.platform === 'win32' || process.platform === 'linux') {" \
- true
-
- _safe_sed_patch \
- "Main: Fix async download handler" \
- "${src_dir}/main.js" \
- "await fs.promises.mkdir(downloadsLocation, { recursive: true })" \
- "fs.mkdirSync(downloadsLocation, { recursive: true })"
-
- # =========================================================================
- # AUTO-UPDATER - Skip on Linux (use pacman)
- # =========================================================================
-
- if [ -f "${src_dir}/updater.js" ] && grep -q "if (appConfig.isDev) {" "${src_dir}/updater.js"; then
- _safe_insert_patch \
- "Updater: Skip on Linux" \
- "${src_dir}/updater.js" \
- "if (appConfig.isDev) {" \
-"\\ // Linux: Use system package manager for updates\\
-\\ if (process.platform === 'linux') {\\
-\\ console.log('[Superhuman Linux] Updates managed by pacman');\\
-\\ return;\\
-\\ }"
- fi
-
- # =========================================================================
- # TRAY MODULE - Close to tray with account switcher
- # =========================================================================
-
- cp "$srcdir/linux_tray.js" "${src_dir}/linux_tray.js"
-
- # Import and initialize tray - the module self-initializes via app events
+ optional \
+ 1 \
+ " } else if (process.platform === 'win32') {
+ // the \`open-url\` event is Mac-only, so on Windows startup we check argv directly" \
+ " } else if (process.platform === 'win32' || process.platform === 'linux') {
+ // the \`open-url\` event is Mac-only, so on Windows startup we check argv directly"
+
+ # wasOpenedAsHidden() is macOS-only, so the autostart entry's --hidden flag
+ # is otherwise ignored.
+ _bundle_patch \
+ "Main: Honor --hidden on Linux" \
+ optional \
+ 1 \
+ " let launchHidden = process.platform === 'win32' ? false : this._loginItem.wasOpenedAsHidden()" \
+ " let launchHidden = process.argv.includes('--hidden') || (process.platform === 'win32' ? false : this._loginItem.wasOpenedAsHidden())"
+
+ # Tray module - close to tray with a show/hide and quit menu
+ cp "$srcdir/linux_tray.js" "$dist_dir/linux_tray.js"
sed -i "1i\\
-if (process.platform === 'linux') { require('./linux_tray'); }" \
- "${src_dir}/main.js"
-
+if (process.platform === 'linux') require('./linux_tray');" "$dist_dir/main.js"
msg2 "Applied: Tray module (self-initializing)"
- # =========================================================================
- # PATCH SUMMARY
- # =========================================================================
-
- if [ $_patch_failures -gt 0 ]; then
+ if [ ${#_failed_patches[@]} -gt 0 ]; then
warning "=========================================="
- warning "$_patch_failures patch(es) failed!"
- warning "The app may work but some features might be broken."
+ warning "${#_failed_patches[@]} optional patch(es) failed:"
+ local desc
+ for desc in "${_failed_patches[@]}"; do
+ warning " - $desc"
+ done
+ warning "The app will run but these features are missing."
warning ">>> MAINTAINER: Superhuman updated, patches need review <<<"
warning "=========================================="
fi
@@ -259,6 +237,10 @@
cat > superhuman-linux/superhuman << 'WRAPPER'
#!/bin/bash
SCRIPT_DIR="$(cd "$(dirname "$(readlink -f "${BASH_SOURCE[0]}")")" && pwd)"
+
+# Electron resolves the desktop entry from this when registering itself as the
+# mailto:/superhuman: handler via xdg-settings.
+export CHROME_DESKTOP="${CHROME_DESKTOP:-superhuman.desktop}"
ARGS=()
for arg in "$@"; do
@@ -269,7 +251,7 @@
fi
done
-exec "${SCRIPT_DIR}/superhuman-bin" --no-sandbox "${ARGS[@]}"
+exec "${SCRIPT_DIR}/superhuman-bin" "${ARGS[@]}"
WRAPPER
chmod +x superhuman-linux/superhuman
}
@@ -283,7 +265,9 @@
chmod +x "$pkgdir/opt/superhuman/superhuman"
chmod +x "$pkgdir/opt/superhuman/superhuman-bin"
chmod +x "$pkgdir/opt/superhuman/chrome_crashpad_handler"
- chmod 4755 "$pkgdir/opt/superhuman/chrome-sandbox" 2>/dev/null || true
+
+ # Fallback sandbox for kernels without unprivileged user namespaces
+ chmod 4755 "$pkgdir/opt/superhuman/chrome-sandbox"
# Install icon (check both locations: assets/ for GitHub, root for AUR)
local icon_src=""
@@ -296,6 +280,8 @@
install -Dm644 "$icon_src" "$pkgdir/usr/share/icons/hicolor/256x256/apps/superhuman.png"
cp "$icon_src" "$pkgdir/opt/superhuman/"
fi
+
+ install -Dm644 superhuman-linux/LICENSE "$pkgdir/usr/share/licenses/$pkgname/LICENSE.electron"
# Create bin symlinks
install -dm755 "$pkgdir/usr/bin"
@@ -311,7 +297,7 @@
Type=Application
Categories=Network;Email;
MimeType=x-scheme-handler/mailto;x-scheme-handler/superhuman;
-StartupWMClass=Superhuman
+StartupWMClass=superhuman
Terminal=false
X-KDE-Protocols=mailto;superhuman;
EOF

Scan history

Scanned at (UTC)SeverityRules
2026-09-17 00:27:14 Medium 4
2026-09-16 00:03:17 Medium 4
2026-09-15 00:25:31 Medium 4
2026-09-14 00:27:57 Medium 4
2026-09-13 00:19:54 Medium 4
2026-09-12 00:25:17 Medium 4
2026-09-11 00:19:22 Medium 4
2026-09-10 11:20:36 Medium 4
2026-09-10 00:22:44 Medium 4
2026-09-09 00:04:09 Medium 4
2026-09-08 00:18:08 Medium 4
2026-09-07 00:30:15 Medium 4
2026-09-06 00:17:06 Medium 4
2026-09-05 00:16:27 Medium 4
2026-09-04 00:03:13 Medium 4
2026-09-03 00:15:47 Medium 4
2026-09-02 00:02:31 Medium 4
2026-09-01 11:47:58 Medium 4
2026-09-01 00:11:19 Medium 4
2026-08-31 00:19:57 Medium 4

Report a package

Reports go to the AURWatch maintainer (one person) and are read by hand. No login required.

0 / 4000
Your suggestion