From dc484b6782a50442f4693cb28f738e389b32b26d Mon Sep 17 00:00:00 2001 From: ben Date: Wed, 11 Mar 2026 18:34:17 -0700 Subject: [PATCH] fix(desktop): fail fast on missing linux deps (#848) --- README.md | 2 + packages/desktop/scripts/tauri-before-dev.mjs | 71 ++++++++++++++++++- packaging/aur/PKGBUILD | 1 + 3 files changed, 73 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 6d7e5d10..9276e09e 100644 --- a/README.md +++ b/README.md @@ -84,6 +84,7 @@ Before running `pnpm dev`, ensure these are installed and active in your shell: - **Bun 1.3.9+** (`bun --version`) - Rust toolchain (for Tauri), with Cargo from current `rustup` stable (supports `Cargo.lock` v4) - Xcode Command Line Tools (macOS) +- On Linux, WebKitGTK 4.1 development packages so `pkg-config` can resolve `webkit2gtk-4.1` and `javascriptcoregtk-4.1` ### One-minute sanity check @@ -126,6 +127,7 @@ All repo `dev` entrypoints now opt into the same dev-mode isolation so local tes ### Arch Users: ```bash +sudo pacman -S --needed webkit2gtk-4.1 yay -s opencode # Releases version ``` diff --git a/packages/desktop/scripts/tauri-before-dev.mjs b/packages/desktop/scripts/tauri-before-dev.mjs index 52489abb..66f9cba0 100644 --- a/packages/desktop/scripts/tauri-before-dev.mjs +++ b/packages/desktop/scripts/tauri-before-dev.mjs @@ -1,4 +1,5 @@ import { spawn, spawnSync } from "node:child_process"; +import { readFileSync } from "node:fs"; import { resolve } from "node:path"; import { fileURLToPath } from "node:url"; @@ -68,7 +69,7 @@ const holdOpenUntilSignal = ({ uiChild } = {}) => { // alive with a timer until Tauri stops the dev process. const timer = setInterval(() => {}, 60_000); - let stopping = false; + let stopping = false; const stop = () => { if (stopping) return; @@ -124,6 +125,73 @@ const runPrepareSidecars = () => { } }; +const readLinuxReleaseInfo = () => { + try { + const content = readFileSync("/etc/os-release", "utf8"); + const values = new Map(); + for (const line of content.split(/\r?\n/)) { + if (!line || line.startsWith("#") || !line.includes("=")) continue; + const separator = line.indexOf("="); + const key = line.slice(0, separator); + const rawValue = line.slice(separator + 1).trim(); + const value = rawValue.replace(/^"|"$/g, ""); + values.set(key, value); + } + return { + id: values.get("ID") ?? "", + like: values.get("ID_LIKE") ?? "", + prettyName: values.get("PRETTY_NAME") ?? values.get("NAME") ?? "Linux", + }; + } catch { + return { id: "", like: "", prettyName: "Linux" }; + } +}; + +const getLinuxDesktopDependencyHint = () => { + const release = readLinuxReleaseInfo(); + const family = `${release.id} ${release.like}`.toLowerCase(); + + if (family.includes("arch")) { + return "Install the missing desktop dependency and retry:\n sudo pacman -S --needed webkit2gtk-4.1"; + } + + if (family.includes("ubuntu") || family.includes("debian")) { + return ( + "Install the missing desktop dependencies and retry:\n" + + " sudo apt install libwebkit2gtk-4.1-dev build-essential curl wget file libxdo-dev libssl-dev libayatana-appindicator3-dev librsvg2-dev" + ); + } + + if (family.includes("fedora") || family.includes("rhel")) { + return ( + "Install the missing desktop dependencies and retry:\n" + + " sudo dnf install webkit2gtk4.1-devel openssl-devel curl wget file libappindicator-gtk3-devel librsvg2-devel" + ); + } + + return `Install WebKitGTK 4.1 development packages for ${release.prettyName} so pkg-config can resolve both webkit2gtk-4.1 and javascriptcoregtk-4.1, then retry.`; +}; + +const ensureLinuxDesktopDependencies = () => { + if (process.platform !== "linux") return; + + const requiredPkgConfigs = ["webkit2gtk-4.1", "javascriptcoregtk-4.1"]; + const missing = requiredPkgConfigs.filter((pkg) => { + const result = spawnSync("pkg-config", ["--exists", pkg], { stdio: "ignore" }); + return result.status !== 0; + }); + + if (missing.length === 0) return; + + console.error( + "[openwork] Missing Linux desktop system dependencies required by Tauri:\n" + + ` ${missing.join(", ")}\n\n` + + `${getLinuxDesktopDependencyHint()}\n\n` + + "If you only need the web UI, run `pnpm dev:ui`." + ); + process.exit(1); +}; + const runUiDevServer = () => { const child = spawn(pnpmCmd, ["-w", "dev:ui"], { stdio: "inherit", @@ -156,6 +224,7 @@ const runUiDevServer = () => { }; runPrepareSidecars(); +ensureLinuxDesktopDependencies(); const main = async () => { let detectedViteUrl = null; diff --git a/packaging/aur/PKGBUILD b/packaging/aur/PKGBUILD index e59d95b9..c71cf5c1 100644 --- a/packaging/aur/PKGBUILD +++ b/packaging/aur/PKGBUILD @@ -5,6 +5,7 @@ pkgdesc="An Open source alternative to Claude Cowork" arch=('x86_64' 'aarch64') url="https://github.com/different-ai/openwork" license=('MIT') +# webkit2gtk-4.1 provides both webkit2gtk-4.1.pc and javascriptcoregtk-4.1.pc depends=('gtk3' 'glib2' 'libayatana-appindicator' 'libsoup3' 'webkit2gtk-4.1' 'openssl' 'dbus' 'librsvg') # Architecture-specific sources and checksums