From e7d4cf73d501b962521347e019b244105caa3457 Mon Sep 17 00:00:00 2001 From: paisley <8197966+su8su@users.noreply.github.com> Date: Fri, 6 Mar 2026 15:07:05 +0800 Subject: [PATCH] Fix ubuntu debs (#320) --- .github/workflows/release.yml | 3 ++- electron-builder.yml | 13 ++++++++----- electron/main/index.ts | 8 ++++++++ package.json | 4 ++-- scripts/installer.nsh | 35 +++++++++++++++++++++++++++++++++- scripts/linux/after-install.sh | 33 ++++++++++++++++++++++++++++++++ scripts/linux/after-remove.sh | 6 ++++++ 7 files changed, 93 insertions(+), 9 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 1cce214ff..93390e283 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -196,7 +196,8 @@ jobs: - **macOS**: On first launch, you may see "cannot verify developer". Go to System Preferences → Security & Privacy to allow the app to run - **Windows**: SmartScreen may block the app. Click "More info" → "Run anyway" to proceed - - **Linux**: AppImage requires executable permission: `chmod +x ClawX-*.AppImage` + - **Linux AppImage**: First run `chmod +x ClawX-*.AppImage` to add execute permission. On Ubuntu 22.04 you may also need `sudo apt install libfuse2`; on Ubuntu 24.04 use `sudo apt install libfuse2t64` + - **Linux .deb (Ubuntu 24.04)**: If installation fails due to missing dependencies, use `sudo apt install libgtk-3-0t64 libnotify4t64 libxss1t64` before installing --- diff --git a/electron-builder.yml b/electron-builder.yml index d4500a325..6ddc885ef 100644 --- a/electron-builder.yml +++ b/electron-builder.yml @@ -167,19 +167,22 @@ linux: Comment: AI Assistant powered by OpenClaw Categories: Utility;Network; Keywords: ai;assistant;automation;chat; + StartupWMClass: clawx appImage: license: LICENSE deb: depends: - - libgtk-3-0 - - libnotify4 + # Use OR syntax to support both Ubuntu 22.04 and Ubuntu 24.04 (t64 transition). + # Ubuntu 24.04 renamed many libraries with a t64 suffix (64-bit time_t ABI transition). + - libgtk-3-0 | libgtk-3-0t64 + - libnotify4 | libnotify4t64 - libnss3 - - libxss1 - - libxtst6 + - libxss1 | libxss1t64 + - libxtst6 | libxtst6t64 - xdg-utils - - libatspi2.0-0 + - libatspi2.0-0 | libatspi2.0-0t64 - libuuid1 afterInstall: scripts/linux/after-install.sh afterRemove: scripts/linux/after-remove.sh diff --git a/electron/main/index.ts b/electron/main/index.ts index 2a8997804..b387c40b3 100644 --- a/electron/main/index.ts +++ b/electron/main/index.ts @@ -37,6 +37,14 @@ import { ensureBuiltinSkillsInstalled } from '../utils/skill-config'; // set `"disable-hardware-acceleration": false` in the app config (future). app.disableHardwareAcceleration(); +// On Linux, set CHROME_DESKTOP so Chromium can find the correct .desktop file. +// On Wayland this maps the running window to clawx.desktop (→ icon + app grouping); +// on X11 it supplements the StartupWMClass matching. +// Must be called before app.whenReady() / before any window is created. +if (process.platform === 'linux') { + app.setDesktopName('clawx.desktop'); +} + // Prevent multiple instances of the app from running simultaneously. // Without this, two instances each spawn their own gateway process on the // same port, then each treats the other's gateway as "orphaned" and kills diff --git a/package.json b/package.json index 294a92016..4b40a0f76 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "clawx", - "version": "0.1.22", + "version": "0.1.23-alpha.1", "pnpm": { "onlyBuiltDependencies": [ "@whiskeysockets/baileys", @@ -107,4 +107,4 @@ "zx": "^8.8.5" }, "packageManager": "pnpm@10.29.2+sha512.bef43fa759d91fd2da4b319a5a0d13ef7a45bb985a3d7342058470f9d2051a3ba8674e629672654686ef9443ad13a82da2beb9eeb3e0221c87b8154fff9d74b8" -} +} \ No newline at end of file diff --git a/scripts/installer.nsh b/scripts/installer.nsh index 74ea8c50d..d06256de4 100644 --- a/scripts/installer.nsh +++ b/scripts/installer.nsh @@ -8,6 +8,14 @@ !endif !macro customCheckAppRunning + ; Pre-emptively remove old shortcuts to prevent the Windows "Missing Shortcut" + ; dialog during upgrades. The built-in NSIS uninstaller deletes ClawX.exe + ; *before* removing shortcuts; Windows Shell link tracking can detect the + ; broken target in that brief window and pop a resolver dialog. + ; Delete is a silent no-op when the file doesn't exist (safe for fresh installs). + Delete "$DESKTOP\${PRODUCT_NAME}.lnk" + Delete "$SMPROGRAMS\${PRODUCT_NAME}.lnk" + ${nsProcess::FindProcess} "${APP_EXECUTABLE_FILENAME}" $R0 ${if} $R0 == 0 @@ -73,7 +81,15 @@ ; Add resources\cli to the current user's PATH for openclaw CLI. ; Read current PATH, skip if already present, append otherwise. + ; + ; ReadRegStr silently returns "" when the value exceeds the NSIS string + ; buffer (8192 chars for the electron-builder large-strings build). + ; Without an error-flag check we would overwrite the entire user PATH with + ; only our CLI directory, destroying every other PATH entry. + ClearErrors ReadRegStr $0 HKCU "Environment" "Path" + IfErrors _ci_readFailed + StrCmp $0 "" _ci_setNew ; Check if our CLI dir is already in PATH @@ -94,6 +110,12 @@ WriteRegExpandStr HKCU "Environment" "Path" $0 ; Broadcast WM_SETTINGCHANGE so running Explorer/terminals pick up the change SendMessage ${HWND_BROADCAST} ${WM_SETTINGCHANGE} 0 "STR:Environment" /TIMEOUT=500 + Goto _ci_done + + _ci_readFailed: + ; PATH value could not be read (likely exceeds NSIS buffer). + ; Skip modification to avoid destroying existing entries. + DetailPrint "Warning: Could not read user PATH (may exceed 8192 chars). Skipping PATH update." _ci_done: !macroend @@ -137,7 +159,9 @@ FunctionEnd !macro customUnInstall ; Remove resources\cli from user PATH + ClearErrors ReadRegStr $0 HKCU "Environment" "Path" + IfErrors _cu_pathDone StrCmp $0 "" _cu_pathDone ; Remove our entry (with leading or trailing semicolons) @@ -145,8 +169,17 @@ FunctionEnd Push "$INSTDIR\resources\cli" Call un._cu_RemoveFromPath Pop $0 + + ; If PATH is now empty, delete the registry value instead of writing "" + StrCmp $0 "" _cu_deletePath WriteRegExpandStr HKCU "Environment" "Path" $0 - SendMessage ${HWND_BROADCAST} ${WM_SETTINGCHANGE} 0 "STR:Environment" /TIMEOUT=500 + Goto _cu_pathBroadcast + + _cu_deletePath: + DeleteRegValue HKCU "Environment" "Path" + + _cu_pathBroadcast: + SendMessage ${HWND_BROADCAST} ${WM_SETTINGCHANGE} 0 "STR:Environment" /TIMEOUT=500 _cu_pathDone: diff --git a/scripts/linux/after-install.sh b/scripts/linux/after-install.sh index 53447be71..ffff478a0 100644 --- a/scripts/linux/after-install.sh +++ b/scripts/linux/after-install.sh @@ -26,4 +26,37 @@ if [ -f "$OPENCLAW_WRAPPER" ]; then ln -sf "$OPENCLAW_WRAPPER" /usr/local/bin/openclaw 2>/dev/null || true fi +# Set chrome-sandbox permissions. +# On systems without working user namespaces, the SUID bit is required. +# On Ubuntu 24.04+, user namespaces are available but blocked by AppArmor; +# we rely on the AppArmor profile below instead, so 0755 is correct there. +if ! { [[ -L /proc/self/ns/user ]] && unshare --user true; }; then + # No user namespace support — fall back to SUID sandbox + chmod 4755 '/opt/ClawX/chrome-sandbox' || true +else + chmod 0755 '/opt/ClawX/chrome-sandbox' || true +fi + +# Install AppArmor profile (Ubuntu 24.04+). +# Ubuntu 24.04 enables kernel.apparmor_restrict_unprivileged_userns=1 by default, +# which blocks Electron's sandbox. The bundled AppArmor profile grants the 'userns' +# permission so the app can create user namespaces without disabling the global policy. +# +# We first check if AppArmor is enabled and if the running version supports abi/4.0 +# (Ubuntu 22.04 does not; it runs fine without the profile, so we skip it there). +if apparmor_status --enabled > /dev/null 2>&1; then + APPARMOR_PROFILE_SOURCE='/opt/ClawX/resources/apparmor-profile' + APPARMOR_PROFILE_TARGET='/etc/apparmor.d/clawx' + if apparmor_parser --skip-kernel-load --debug "$APPARMOR_PROFILE_SOURCE" > /dev/null 2>&1; then + cp -f "$APPARMOR_PROFILE_SOURCE" "$APPARMOR_PROFILE_TARGET" + + # Skip live-loading in a chroot environment (e.g. image-building pipelines). + if ! { [ -x '/usr/bin/ischroot' ] && /usr/bin/ischroot; } && hash apparmor_parser 2>/dev/null; then + apparmor_parser --replace --write-cache --skip-read-cache "$APPARMOR_PROFILE_TARGET" + fi + else + echo "Skipping AppArmor profile installation: this version of AppArmor does not support the bundled profile" + fi +fi + echo "ClawX has been installed successfully." diff --git a/scripts/linux/after-remove.sh b/scripts/linux/after-remove.sh index 1eade9ebd..9dbd238f4 100644 --- a/scripts/linux/after-remove.sh +++ b/scripts/linux/after-remove.sh @@ -18,4 +18,10 @@ if command -v gtk-update-icon-cache &> /dev/null; then gtk-update-icon-cache -q /usr/share/icons/hicolor || true fi +# Remove AppArmor profile +APPARMOR_PROFILE_TARGET='/etc/apparmor.d/clawx' +if [ -f "$APPARMOR_PROFILE_TARGET" ]; then + rm -f "$APPARMOR_PROFILE_TARGET" +fi + echo "ClawX has been removed."