diff --git a/scripts/build-common.sh b/scripts/build-common.sh index 738c2b0..6bbaefa 100644 --- a/scripts/build-common.sh +++ b/scripts/build-common.sh @@ -8,6 +8,15 @@ set -euo pipefail +# Isolate the embeddable/standalone Python used for bundling from the BUILD +# machine's per-user site-packages. Without this, pip on a dev machine that has +# a system Python installed sees transitive deps as "already satisfied" via the +# user site (~/.local or %APPDATA%\Python) and SKIPS bundling them (e.g. +# typing_extensions, urllib3, certifi). The packaged app then crashes with +# ModuleNotFoundError on clean end-user machines while "working" on the build +# box. CI runners have no user site, so this is a no-op there. +export PYTHONNOUSERSITE=1 + # Check if this is being sourced by a platform script if [[ "${BASH_SOURCE[0]}" == "${0}" ]]; then echo "Error: build-common.sh should not be run directly" >&2 diff --git a/src/main/python.ts b/src/main/python.ts index 09caa45..6c9ae8c 100644 --- a/src/main/python.ts +++ b/src/main/python.ts @@ -546,6 +546,10 @@ export async function startPython(): Promise { XDG_CACHE_HOME: cacheBase, TORCH_HOME: process.env.TORCH_HOME || path.join(cacheBase, 'torch'), HF_HOME: process.env.HF_HOME || path.join(cacheBase, 'huggingface'), + // Never read the end user's per-user site-packages — the bundle ships + // its own deps, and a stray user-site package must not shadow (or mask + // a gap in) them. Mirrors PYTHONNOUSERSITE=1 used at build time. + PYTHONNOUSERSITE: '1', RESOURCESPATH: app.isPackaged ? process.resourcesPath : path.join(__dirname, '..', '..', 'resources'), @@ -597,6 +601,12 @@ export async function startPython(): Promise { // Set PYTHONHOME for bundled Python on all platforms if (app.isPackaged) { + // Packaged builds ship plugins but must NOT block startup doing a + // runtime `pip install` of heavy optional plugin deps (torch/whisperx/ + // demucs) — that hangs the backend past the readiness window on first + // launch. The slopsmith plugin loader honours this flag and loads such + // plugins degraded (their optional features stay off until deps exist). + pythonEnv.SLOPSMITH_SKIP_PLUGIN_INSTALL = '1'; if (process.platform === 'win32') { pythonEnv.PYTHONHOME = path.join(process.resourcesPath, 'python'); } else {