Skip to content

Commit 5de2086

Browse files
beautyfreeclaude
andauthored
v0.2.4: ship install.sh with Linux tar.xz for chrome-sandbox SUID + desktop integration (#12)
Electron's setuid sandbox wants chrome-sandbox owned by root with mode 4755. Three distribution paths handle this differently: - .deb → electron-builder postinst sets SUID automatically - AppImage → runtime handles sandbox via user namespaces / bind-mount - tar.xz → no install step = user hits "SUID sandbox helper binary ... not configured correctly" on first launch Fix: ship `build-resources/linux-install.sh` alongside the binary via electron-builder's `extraFiles` so it lands at `install.sh` in every Linux build (harmless inside .deb and AppImage, useful in tar.xz). Running it: 1. `sudo chown root:root chrome-sandbox && sudo chmod 4755` 2. Writes `~/.local/share/applications/skiller.desktop` pointing at the current extract location + an icon in `~/.local/share/icons`. 3. Refreshes desktop/icon caches best-effort. `./install.sh --uninstall` removes the menu entry + icon (leaves the chrome-sandbox SUID bit — harmless if the directory is deleted). README Linux row updated with the three-command install flow. Version bump to 0.2.4 so existing 0.2.3 users exercise the auto-updater through another release. Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
1 parent 5581e36 commit 5de2086

4 files changed

Lines changed: 102 additions & 2 deletions

File tree

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -81,7 +81,7 @@ Grab the installer for your OS from the [**latest release**](https://github.com/
8181
| --- | --- | --- |
8282
| macOS (Apple Silicon) | `Skiller-<version>-macos-arm64.dmg` | Signed + notarized. Open the DMG and drag Skiller to Applications. |
8383
| Windows (x64) | `Skiller-<version>-win-x64.exe` | NSIS installer. SmartScreen may show a one-time warning — click "More info" → "Run anyway". |
84-
| Linux (x64) | `Skiller-<version>-linux-x86_64.AppImage`, `.deb`, or `.tar.xz` | AppImage: `chmod +x`, run — ships a static runtime with squashfuse built in, so no `libfuse2` required (works on CachyOS/Manjaro/EndeavourOS out of the box). `.deb` for Ubuntu/Debian. `.tar.xz` is the no-auto-integration extract-and-run alternative. |
84+
| Linux (x64) | `Skiller-<version>-linux-x86_64.AppImage`, `.deb`, or `.tar.xz` | AppImage: `chmod +x`, run — static squashfuse runtime, no `libfuse2` required (works on CachyOS/Manjaro/EndeavourOS out of the box). `.deb` for Ubuntu/Debian. `.tar.xz`: extract, `cd Skiller-*`, run `./install.sh` once (sets SUID on `chrome-sandbox`, registers a `.desktop` entry). Passing `--uninstall` to the same script removes the menu entry. |
8585

8686
Every release is built and published by the CI matrix in `.github/workflows/release.yml` — tagging `vX.Y.Z` produces all three platforms automatically.
8787

build-resources/linux-install.sh

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#!/usr/bin/env bash
2+
#
3+
# Post-extract helper for the Skiller tar.xz Linux build.
4+
#
5+
# Why this exists: Electron's setuid sandbox wants `chrome-sandbox` owned by
6+
# root with mode 4755. .deb and AppImage builds handle this automatically
7+
# (postinst / runtime respectively); the tar.xz has no install step, so we
8+
# ship this script to do the same dance on demand.
9+
#
10+
# Usage (from inside the extracted directory):
11+
# ./install.sh
12+
#
13+
# What it does:
14+
# 1. Sets SUID on chrome-sandbox (needs sudo).
15+
# 2. Writes a `.desktop` entry pointing at the local `skiller` binary so
16+
# the app appears in your app launcher.
17+
# 3. Copies the icon into `~/.local/share/icons`.
18+
#
19+
# To undo everything, run `./install.sh --uninstall`.
20+
set -euo pipefail
21+
22+
APP_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
23+
BIN="$APP_DIR/skiller"
24+
SANDBOX="$APP_DIR/chrome-sandbox"
25+
ICON_SRC="$APP_DIR/resources/app.asar.unpacked/assets/icons/app/icon-512.png"
26+
DESKTOP_DIR="$HOME/.local/share/applications"
27+
DESKTOP_FILE="$DESKTOP_DIR/skiller.desktop"
28+
ICON_DIR="$HOME/.local/share/icons"
29+
ICON_DEST="$ICON_DIR/skiller.png"
30+
31+
if [[ ! -x "$BIN" ]]; then
32+
echo "error: $BIN not found or not executable — run this script from inside the extracted Skiller directory" >&2
33+
exit 1
34+
fi
35+
36+
if [[ "${1:-}" == "--uninstall" ]]; then
37+
rm -f "$DESKTOP_FILE" "$ICON_DEST"
38+
echo "✓ removed $DESKTOP_FILE and $ICON_DEST"
39+
echo " (chrome-sandbox SUID bit is harmless — left in place)"
40+
exit 0
41+
fi
42+
43+
# 1) chrome-sandbox SUID — needs root
44+
if [[ -f "$SANDBOX" ]]; then
45+
current_mode=$(stat -c '%a' "$SANDBOX" 2>/dev/null || stat -f '%Lp' "$SANDBOX")
46+
current_owner=$(stat -c '%U' "$SANDBOX" 2>/dev/null || stat -f '%Su' "$SANDBOX")
47+
if [[ "$current_mode" != "4755" || "$current_owner" != "root" ]]; then
48+
echo "→ setting SUID on $SANDBOX (needs sudo)…"
49+
sudo chown root:root "$SANDBOX"
50+
sudo chmod 4755 "$SANDBOX"
51+
else
52+
echo "✓ chrome-sandbox already configured"
53+
fi
54+
fi
55+
56+
# 2) Desktop entry
57+
mkdir -p "$DESKTOP_DIR"
58+
cat > "$DESKTOP_FILE" <<EOF
59+
[Desktop Entry]
60+
Name=Skiller
61+
Comment=Manage AI agent skills across Claude Code, Cursor, Copilot, and more
62+
Exec="$BIN" %U
63+
Icon=skiller
64+
Terminal=false
65+
Type=Application
66+
Categories=Development;
67+
StartupWMClass=Skiller
68+
EOF
69+
echo "✓ wrote $DESKTOP_FILE"
70+
71+
# 3) Icon
72+
if [[ -f "$ICON_SRC" ]]; then
73+
mkdir -p "$ICON_DIR"
74+
cp "$ICON_SRC" "$ICON_DEST"
75+
echo "✓ wrote $ICON_DEST"
76+
else
77+
echo "! icon source not found at $ICON_SRC — skipping (app will use a fallback icon)"
78+
fi
79+
80+
# Best-effort: ask the DE to refresh its caches. No error if the tools aren't
81+
# installed — the .desktop file still works on next login.
82+
if command -v update-desktop-database >/dev/null 2>&1; then
83+
update-desktop-database -q "$DESKTOP_DIR" || true
84+
fi
85+
if command -v gtk-update-icon-cache >/dev/null 2>&1; then
86+
gtk-update-icon-cache -q -t "$ICON_DIR" 2>/dev/null || true
87+
fi
88+
89+
echo
90+
echo "All set. Launch Skiller from your app menu, or run: \"$BIN\""

electron-builder.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,16 @@ linux:
7474
# explicit so we don't get bitten again if someone simplifies the author
7575
# field back to a plain string.
7676
maintainer: "Skiller Contributors <skiller@beautyfree.dev>"
77+
# Dropped alongside the executable. Only relevant for the `tar.xz` target:
78+
# .deb runs its own postinst chmod, AppImage's runtime handles sandbox via
79+
# bind-mount. The tar.xz install flow is:
80+
# tar xf Skiller-*.tar.xz
81+
# cd Skiller-*
82+
# ./install.sh # chmods chrome-sandbox, registers .desktop entry
83+
# `install.sh` bytes come from `build-resources/linux-install.sh`.
84+
extraFiles:
85+
- from: build-resources/linux-install.sh
86+
to: install.sh
7787
target:
7888
- target: AppImage
7989
arch: [x64]

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "skiller",
3-
"version": "0.2.3",
3+
"version": "0.2.4",
44
"description": "A desktop app for managing AI agent skills across Claude Code, Cursor, Copilot, Gemini CLI, and more",
55
"license": "MIT",
66
"author": {

0 commit comments

Comments
 (0)