diff --git a/scripts/patches/cowork.sh b/scripts/patches/cowork.sh index 35853c0..3a2685f 100644 --- a/scripts/patches/cowork.sh +++ b/scripts/patches/cowork.sh @@ -807,12 +807,27 @@ install_node_pty() { echo '{"name":"node-pty-build","version":"1.0.0","private":true}' > package.json echo 'Installing node-pty (this compiles native module)...' - if npm install node-pty 2>&1; then - echo 'node-pty installed successfully' - pty_src_dir="$node_pty_build_dir/node_modules/node-pty" - else - echo 'Failed to install node-pty - terminal features may not work' + # Fail loudly on npm install failure rather than warn-and-continue. + # The previous behavior silently dropped pty_src_dir, skipped the + # entire copy block, and shipped the upstream Windows node-pty + # binaries (the #401 failure mode). check_dependencies should now + # install gcc/g++/make/python3 before we get here, so this branch + # is the last line of defense for build-tool gaps that auto-install + # couldn't fix (unknown distro, broken package mirror, etc.). + if ! npm install node-pty 2>&1; then + echo "Error: 'npm install node-pty' failed." >&2 + echo 'node-pty has a native module compiled via node-gyp;' >&2 + echo 'this usually means the build environment lacks a C/C++' >&2 + echo 'compiler, make, or python3.' >&2 + echo '' >&2 + echo 'Install build tools and re-run:' >&2 + echo ' Debian/Ubuntu: sudo apt install build-essential python3' >&2 + echo ' Fedora/RHEL: sudo dnf install gcc gcc-c++ make python3' >&2 + cd "$project_root" || exit 1 + exit 1 fi + echo 'node-pty installed successfully' + pty_src_dir="$node_pty_build_dir/node_modules/node-pty" fi if [[ -n $pty_src_dir && -d $pty_src_dir ]]; then diff --git a/scripts/setup/dependencies.sh b/scripts/setup/dependencies.sh index 3f39425..1b4cff9 100644 --- a/scripts/setup/dependencies.sh +++ b/scripts/setup/dependencies.sh @@ -22,32 +22,51 @@ check_dependencies() { rpm) all_deps="$all_deps rpmbuild" ;; esac + # node-pty has a native C++ module compiled via node-gyp during + # `npm install`. Without gcc/g++/make/python3 the install silently + # emits a warning, leaves pty_src_dir empty, and the build ends up + # shipping the upstream Windows binaries (the #401 failure mode). + # Skip when --node-pty-dir is set (Nix and explicit overrides bring + # their own pre-built node-pty). + if [[ -z ${node_pty_dir:-} ]]; then + all_deps="$all_deps gcc g++ make python3" + fi + # Command-to-package mappings per distro family declare -A debian_pkgs=( [p7zip]='p7zip-full' [wget]='wget' [wrestool]='icoutils' [icotool]='icoutils' [convert]='imagemagick' [dpkg-deb]='dpkg-dev' [rpmbuild]='rpm' + [gcc]='build-essential' [g++]='build-essential' + [make]='build-essential' [python3]='python3' ) declare -A rpm_pkgs=( [p7zip]='p7zip p7zip-plugins' [wget]='wget' [wrestool]='icoutils' [icotool]='icoutils' [convert]='ImageMagick' [dpkg-deb]='dpkg' [rpmbuild]='rpm-build' + [gcc]='gcc' [g++]='gcc-c++' + [make]='make' [python3]='python3' ) - local cmd + local cmd pkg for cmd in $all_deps; do if ! check_command "$cmd"; then case "$distro_family" in - debian) - deps_to_install="$deps_to_install ${debian_pkgs[$cmd]}" - ;; - rpm) - deps_to_install="$deps_to_install ${rpm_pkgs[$cmd]}" - ;; + debian) pkg="${debian_pkgs[$cmd]}" ;; + rpm) pkg="${rpm_pkgs[$cmd]}" ;; *) echo "Warning: Cannot auto-install '$cmd' on unknown distro. Please install manually." >&2 + continue ;; esac + # Several commands map to the same package (gcc/g++/make + # -> build-essential, wrestool/icotool -> icoutils). Skip + # if the package is already queued so the log line stays + # readable. + case " $deps_to_install " in + *" $pkg "*) ;; + *) deps_to_install="$deps_to_install $pkg" ;; + esac fi done