Fix Homebrew library dependencies in release builds (#269)

This commit is contained in:
Peter Steinberger 2025-07-08 09:55:52 +01:00 committed by GitHub
parent 32caa7ac4f
commit 6b93fdbf41
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
15 changed files with 677 additions and 31 deletions

48
.github/scripts/verify-release.sh vendored Executable file
View file

@ -0,0 +1,48 @@
#!/bin/bash
# GitHub Actions script to verify release builds
# This should be run after building the DMG but before creating the release
set -e
echo "::group::Release Build Verification"
# Find the built app (adjust path as needed for your CI)
APP_PATH="$1"
if [ -z "$APP_PATH" ]; then
# Try to find it in common locations
if [ -f "build/VibeTunnel.app" ]; then
APP_PATH="build/VibeTunnel.app"
elif [ -f "mac/build/Release/VibeTunnel.app" ]; then
APP_PATH="mac/build/Release/VibeTunnel.app"
else
echo "::error::Could not find VibeTunnel.app. Please provide path as argument."
exit 1
fi
fi
# Run the verification script
if ./verify-release-build.sh "$APP_PATH"; then
echo "::notice::✅ Release build verification passed!"
else
echo "::error::❌ Release build verification failed! Check the logs above."
exit 1
fi
echo "::endgroup::"
# Additional CI-specific checks
echo "::group::Additional CI Checks"
# Check that we're not on a debug branch
if [[ "$GITHUB_REF" == *"debug"* ]] || [[ "$GITHUB_REF" == *"test"* ]]; then
echo "::warning::Building from a branch that contains 'debug' or 'test' in the name"
fi
# Verify build configuration from environment
if [ "$CONFIGURATION" == "Debug" ]; then
echo "::error::Building with Debug configuration! Use Release for production builds."
exit 1
fi
echo "::endgroup::"

1
.gitignore vendored
View file

@ -129,3 +129,4 @@ playwright-report/
buildServer.json
/temp
/temp/webrtc-check
/web/release-check/

View file

@ -1,5 +1,15 @@
# Changelog
## [1.0.0-beta.8] - 2025-07-08
#### **Homebrew Library Dependencies**
- **FIXED**: Release builds now correctly bundle all Homebrew library dependencies
- **FIXED**: App launches reliably on systems without developer tools installed
- Updated build scripts to handle dynamic library dependencies properly
#### **File Browser Enhancements**
- **FIXED**: File browser going dark due to event bubbling issues with modal handling
## [1.0.0-beta.7] - 2025-07-08
### 🎯 Major Features

185
docs/homebrew-issue.md Normal file
View file

@ -0,0 +1,185 @@
# Homebrew Library Dependencies Issue
## Summary
VibeTunnel beta 7 shipped with Homebrew library dependencies, causing the app to fail on systems without Homebrew installed. This document explains the issue, how to identify it, and how to prevent it in future releases.
## The Problem
When users without Homebrew installed tried to run VibeTunnel beta 7, they received errors like:
```
dyld: Library not loaded: /opt/homebrew/opt/brotli/lib/libbrotlidec.1.dylib
Referenced from: /Applications/VibeTunnel.app/Contents/Resources/vibetunnel
Reason: image not found
```
## Binary Dependencies Comparison
### Beta 6 (Working) vs Beta 7 (Broken)
| Component | Beta 6 | Beta 7 |
|-----------|--------|--------|
| **Main App Binary** | System frameworks only | System frameworks + Thread Sanitizer |
| **vibetunnel Server** | System libraries only (106MB) | System + 10 Homebrew libraries (63MB) |
| **Frameworks Directory** | Clean | Contains `libclang_rt.tsan_osx_dynamic.dylib` |
### Beta 7 Homebrew Dependencies
The `vibetunnel` server binary in beta 7 linked to these Homebrew libraries:
```
/opt/homebrew/opt/libuv/lib/libuv.1.dylib
/opt/homebrew/opt/brotli/lib/libbrotlidec.1.dylib
/opt/homebrew/opt/brotli/lib/libbrotlienc.1.dylib
/opt/homebrew/opt/c-ares/lib/libcares.2.dylib
/opt/homebrew/opt/libnghttp2/lib/libnghttp2.14.dylib
/opt/homebrew/opt/openssl@3/lib/libcrypto.3.dylib
/opt/homebrew/opt/openssl@3/lib/libssl.3.dylib
/opt/homebrew/opt/icu4c@77/lib/libicui18n.77.dylib
/opt/homebrew/opt/icu4c@77/lib/libicuuc.77.dylib
```
## Root Cause
The issue was introduced by commit `826d8de4` which added `node-path-setup.sh` with:
```bash
export PATH="/opt/homebrew/bin:/usr/local/bin:..."
```
This prioritized Homebrew in PATH during the build process, causing:
1. Node.js to be built linking against Homebrew libraries
2. Native modules (node-pty, authenticate-pam) to link against Homebrew
3. The final vibetunnel binary to inherit these dependencies
## How to Test for Homebrew Dependencies
### Quick Check with otool
Check any binary for Homebrew dependencies:
```bash
# Check for Homebrew paths
otool -L /path/to/binary | grep -E "/opt/homebrew|/usr/local/Cellar"
# Show all dependencies
otool -L /path/to/binary
```
### Automated Verification Script
Use the provided verification script:
```bash
./verify-release-build.sh /Applications/VibeTunnel.app
```
This script checks for:
- Homebrew dependencies in all binaries
- Thread/Address/UB Sanitizer libraries
- Debug symbols and settings
- Code signing status
### Manual Testing Process
1. **Check the main app binary:**
```bash
otool -L /Applications/VibeTunnel.app/Contents/MacOS/VibeTunnel
```
2. **Check the server binary:**
```bash
otool -L /Applications/VibeTunnel.app/Contents/Resources/vibetunnel
```
3. **Check native modules:**
```bash
otool -L /Applications/VibeTunnel.app/Contents/Resources/pty.node
otool -L /Applications/VibeTunnel.app/Contents/Resources/authenticate_pam.node
```
4. **Check for sanitizer libraries:**
```bash
ls -la /Applications/VibeTunnel.app/Contents/Frameworks/ | grep -i "clang\|san"
```
## What Dependencies Are Acceptable?
### ✅ Good (System Libraries Only)
```
/usr/lib/libz.1.dylib
/System/Library/Frameworks/CoreFoundation.framework/...
/System/Library/Frameworks/Security.framework/...
/usr/lib/libc++.1.dylib
/usr/lib/libSystem.B.dylib
```
### ❌ Bad (Homebrew/External)
Any path containing:
- `/opt/homebrew/`
- `/usr/local/Cellar/`
- `/usr/local/opt/`
- `libclang_rt.*san*` (sanitizer libraries)
## Prevention
### Build Environment
The fix involves using a clean PATH during builds:
```bash
# Set this before building
export VIBETUNNEL_BUILD_CLEAN_ENV=true
```
This modifies `node-path-setup.sh` to put Homebrew at the END of PATH instead of the beginning.
### Xcode Settings
Ensure these are disabled in the scheme:
- Thread Sanitizer (`enableThreadSanitizer`)
- Address Sanitizer (`enableAddressSanitizer`)
- ASan Stack Use After Return (`enableASanStackUseAfterReturn`)
- NSZombieEnabled
Check with:
```bash
./mac/scripts/check-xcode-settings.sh
```
### CI/CD Integration
Add to your release workflow:
```yaml
- name: Verify Release Build
run: ./.github/scripts/verify-release.sh "${{ steps.build.outputs.app-path }}"
```
## Testing on a Clean System
To properly test a release:
1. **Find a Mac without Homebrew** (or temporarily rename `/opt/homebrew`)
2. **Install the app** from the DMG
3. **Run the app** and verify it starts without library errors
4. **Check Console.app** for any dlopen or library loading errors
## The Fix
The solution involved:
1. **Modifying PATH priority** - Homebrew paths moved to end during builds
2. **Clean environment** - Removing LDFLAGS, LIBRARY_PATH, etc. during compilation
3. **Configure flags** - Using `--shared-zlib` to prefer system libraries
4. **Verification tools** - Scripts to catch these issues before release
## Key Takeaways
- Always check library dependencies before releasing
- Homebrew should never be required for the release build
- Build environments can contaminate the final binary
- Automated verification prevents these issues
- The size difference (106MB → 63MB) wasn't from optimization alone - it included external libraries

View file

@ -1,5 +1,15 @@
# Changelog
## [1.0.0-beta.8] - 2025-07-08
#### **Homebrew Library Dependencies**
- **FIXED**: Release builds now correctly bundle all Homebrew library dependencies
- **FIXED**: App launches reliably on systems without developer tools installed
- Updated build scripts to handle dynamic library dependencies properly
#### **File Browser Enhancements**
- **FIXED**: File browser going dark due to event bubbling issues with modal handling
## [1.0.0-beta.7] - 2025-07-08
### 🎯 Major Features

View file

@ -39,8 +39,7 @@
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
enableASanStackUseAfterReturn = "YES"
enableThreadSanitizer = "YES"
enableASanStackUseAfterReturn = "NO"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
@ -64,13 +63,6 @@
isEnabled = "YES">
</EnvironmentVariable>
</EnvironmentVariables>
<AdditionalOptions>
<AdditionalOption
key = "NSZombieEnabled"
value = "YES"
isEnabled = "YES">
</AdditionalOption>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

View file

@ -1,8 +1,8 @@
// VibeTunnel Version Configuration
// This file contains the version and build number for the app
MARKETING_VERSION = 1.0.0-beta.7
CURRENT_PROJECT_VERSION = 170
MARKETING_VERSION = 1.0.0-beta.8
CURRENT_PROJECT_VERSION = 171
// Domain and GitHub configuration
APP_DOMAIN = vibetunnel.sh

View file

@ -64,6 +64,8 @@ echo "Building web frontend..."
# Setup Node.js PATH (Homebrew, nvm, Volta, fnm)
SCRIPT_DIR="$( cd "$( dirname "$0" )" && pwd )"
# Set environment variable to use clean build environment
export VIBETUNNEL_BUILD_CLEAN_ENV=true
source "${SCRIPT_DIR}/node-path-setup.sh"
# Export CI to prevent interactive prompts

View file

@ -0,0 +1,109 @@
#!/bin/bash
# Script to check Xcode project settings for potential release issues
echo "Checking Xcode Project Settings"
echo "==============================="
ERRORS=0
PROJECT_DIR="$(cd "$(dirname "$0")/.." && pwd)"
# Check for Thread Sanitizer in xcscheme files
echo "1. Checking for Thread Sanitizer..."
SCHEME_FILES=$(find "$PROJECT_DIR" -name "*.xcscheme" 2>/dev/null)
for scheme in $SCHEME_FILES; do
if grep -q "enableThreadSanitizer.*YES" "$scheme" 2>/dev/null; then
echo "❌ ERROR: Thread Sanitizer is enabled in $(basename "$scheme")"
echo " File: $scheme"
((ERRORS++))
fi
done
if [ $ERRORS -eq 0 ]; then
echo "✅ Thread Sanitizer is not enabled"
fi
# Check for Address Sanitizer
echo ""
echo "2. Checking for Address Sanitizer..."
ASAN_ERRORS=0
for scheme in $SCHEME_FILES; do
if grep -q "enableAddressSanitizer.*YES" "$scheme" 2>/dev/null; then
echo "❌ ERROR: Address Sanitizer is enabled in $(basename "$scheme")"
echo " File: $scheme"
((ASAN_ERRORS++))
fi
if grep -q "enableASanStackUseAfterReturn.*YES" "$scheme" 2>/dev/null; then
echo "❌ ERROR: ASan Stack Use After Return is enabled in $(basename "$scheme")"
echo " File: $scheme"
((ASAN_ERRORS++))
fi
done
ERRORS=$((ERRORS + ASAN_ERRORS))
if [ $ASAN_ERRORS -eq 0 ]; then
echo "✅ Address Sanitizer is not enabled"
fi
# Check for UB Sanitizer
echo ""
echo "3. Checking for Undefined Behavior Sanitizer..."
UBSAN_ERRORS=0
for scheme in $SCHEME_FILES; do
if grep -q "enableUBSanitizer.*YES" "$scheme" 2>/dev/null; then
echo "❌ ERROR: Undefined Behavior Sanitizer is enabled in $(basename "$scheme")"
echo " File: $scheme"
((UBSAN_ERRORS++))
fi
done
ERRORS=$((ERRORS + UBSAN_ERRORS))
if [ $UBSAN_ERRORS -eq 0 ]; then
echo "✅ Undefined Behavior Sanitizer is not enabled"
fi
# Check for NSZombie
echo ""
echo "4. Checking for NSZombieEnabled..."
ZOMBIE_ERRORS=0
for scheme in $SCHEME_FILES; do
if grep -q "NSZombieEnabled.*YES" "$scheme" 2>/dev/null; then
echo "❌ ERROR: NSZombieEnabled is set in $(basename "$scheme")"
echo " File: $scheme"
((ZOMBIE_ERRORS++))
fi
done
ERRORS=$((ERRORS + ZOMBIE_ERRORS))
if [ $ZOMBIE_ERRORS -eq 0 ]; then
echo "✅ NSZombieEnabled is not set"
fi
# Check build configuration in project.pbxproj
echo ""
echo "5. Checking Release configuration..."
PBXPROJ="$PROJECT_DIR/VibeTunnel-Mac.xcodeproj/project.pbxproj"
if [ -f "$PBXPROJ" ]; then
# This is a simple check - a more thorough check would parse the file properly
if grep -q "ENABLE_TESTABILITY.*YES.*Release" "$PBXPROJ" 2>/dev/null; then
echo "⚠️ WARNING: Testability might be enabled in Release configuration"
else
echo "✅ Release configuration looks OK"
fi
else
echo "⚠️ WARNING: Could not find project.pbxproj"
fi
# Summary
echo ""
echo "==============================="
if [ $ERRORS -eq 0 ]; then
echo "✅ All Xcode settings checks passed!"
exit 0
else
echo "❌ Found $ERRORS error(s) in Xcode settings!"
echo "These settings must be disabled for release builds."
exit 1
fi

View file

@ -11,8 +11,16 @@ if [ -s "$HOME/.nvm/nvm.sh" ]; then
source "$NVM_DIR/nvm.sh" 2>/dev/null || true
fi
# Set final PATH with Homebrew priority
export PATH="/opt/homebrew/bin:/usr/local/bin:$HOME/.volta/bin:$HOME/Library/pnpm:$HOME/.bun/bin:$PATH"
# Check if we're in a build context that needs to avoid Homebrew library contamination
# This is set by build scripts that compile native code
if [ "${VIBETUNNEL_BUILD_CLEAN_ENV}" = "true" ]; then
# For builds, add Homebrew at the END of PATH to avoid library contamination
# This ensures system libraries are preferred during compilation
export PATH="$HOME/.volta/bin:$HOME/Library/pnpm:$HOME/.bun/bin:$PATH:/opt/homebrew/bin:/usr/local/bin"
else
# For normal usage, Homebrew can be at the beginning for convenience
export PATH="/opt/homebrew/bin:/usr/local/bin:$HOME/.volta/bin:$HOME/Library/pnpm:$HOME/.bun/bin:$PATH"
fi
# Verify Node.js is available
if ! command -v node >/dev/null 2>&1; then

64
test-homebrew-fix.sh Executable file
View file

@ -0,0 +1,64 @@
#!/bin/bash
set -e
echo "Testing Homebrew dependency fix..."
echo "================================"
cd "$(dirname "$0")"
# Clean up existing builds
echo "1. Cleaning existing Node.js builds..."
rm -rf web/.node-builds
echo "2. Cleaning existing native builds..."
rm -rf web/native
rm -rf web/build
echo "3. Building custom Node.js without Homebrew dependencies..."
cd web
# Set clean build environment to avoid Homebrew contamination
export VIBETUNNEL_BUILD_CLEAN_ENV=true
node build-custom-node.js
echo ""
echo "4. Checking custom Node.js dependencies..."
CUSTOM_NODE=$(find .node-builds -name "node-v*-minimal" -type d -exec test -f {}/out/Release/node \; -print | sort -V | tail -n1)
if [ -n "$CUSTOM_NODE" ]; then
echo "Custom Node.js found at: $CUSTOM_NODE"
echo "Dependencies:"
otool -L "$CUSTOM_NODE/out/Release/node" | grep -v "/usr/lib\|/System"
echo ""
fi
echo "5. Building vibetunnel with custom Node.js..."
node build-native.js --custom-node
echo ""
echo "6. Checking vibetunnel dependencies..."
if [ -f native/vibetunnel ]; then
echo "Dependencies of native/vibetunnel:"
otool -L native/vibetunnel | grep -v "/usr/lib\|/System"
# Check for Homebrew dependencies
if otool -L native/vibetunnel | grep -q "/opt/homebrew\|/usr/local/Cellar"; then
echo ""
echo "❌ ERROR: Homebrew dependencies found!"
otool -L native/vibetunnel | grep -E "/opt/homebrew|/usr/local/Cellar"
exit 1
else
echo ""
echo "✅ SUCCESS: No Homebrew dependencies found!"
fi
else
echo "❌ ERROR: native/vibetunnel not found!"
exit 1
fi
echo ""
echo "7. Testing the binary..."
cd native
./vibetunnel --version
echo ""
echo "Test complete!"

197
verify-release-build.sh Executable file
View file

@ -0,0 +1,197 @@
#!/bin/bash
set -e
# Colors for output
RED='\033[0;31m'
GREEN='\033[0;32m'
YELLOW='\033[1;33m'
NC='\033[0m' # No Color
echo "VibeTunnel Release Build Verification"
echo "====================================="
# Check if an app path was provided
if [ $# -eq 0 ]; then
echo "Usage: $0 /path/to/VibeTunnel.app"
echo "Example: $0 /Applications/VibeTunnel.app"
exit 1
fi
APP_PATH="$1"
ERRORS=0
WARNINGS=0
# Verify the app exists
if [ ! -d "$APP_PATH" ]; then
echo -e "${RED}❌ ERROR: App not found at $APP_PATH${NC}"
exit 1
fi
echo "Checking: $APP_PATH"
echo ""
# Function to check a binary for issues
check_binary() {
local binary_path="$1"
local binary_name=$(basename "$binary_path")
echo "Checking $binary_name..."
# Check for Thread Sanitizer
if otool -L "$binary_path" 2>/dev/null | grep -q "libclang_rt.tsan"; then
echo -e "${RED}❌ ERROR: Thread Sanitizer library found in $binary_name${NC}"
((ERRORS++))
fi
# Check for Address Sanitizer
if otool -L "$binary_path" 2>/dev/null | grep -q "libclang_rt.asan"; then
echo -e "${RED}❌ ERROR: Address Sanitizer library found in $binary_name${NC}"
((ERRORS++))
fi
# Check for Undefined Behavior Sanitizer
if otool -L "$binary_path" 2>/dev/null | grep -q "libclang_rt.ubsan"; then
echo -e "${RED}❌ ERROR: Undefined Behavior Sanitizer library found in $binary_name${NC}"
((ERRORS++))
fi
# Check for Homebrew dependencies
local homebrew_deps=$(otool -L "$binary_path" 2>/dev/null | grep -E "/opt/homebrew|/usr/local/Cellar" || true)
if [ -n "$homebrew_deps" ]; then
echo -e "${RED}❌ ERROR: Homebrew dependencies found in $binary_name:${NC}"
echo "$homebrew_deps"
((ERRORS++))
fi
# Check for debug symbols (for main app binary)
if [[ "$binary_name" == "VibeTunnel" ]]; then
# Check if binary was built with debug configuration
if nm -a "$binary_path" 2>/dev/null | grep -q "_NSZombieEnabled"; then
echo -e "${YELLOW}⚠️ WARNING: Binary may contain debug code (NSZombie references found)${NC}"
((WARNINGS++))
fi
fi
}
# 1. Check main app binary
echo "1. Main App Binary"
echo "------------------"
MAIN_BINARY="$APP_PATH/Contents/MacOS/VibeTunnel"
if [ -f "$MAIN_BINARY" ]; then
check_binary "$MAIN_BINARY"
else
echo -e "${RED}❌ ERROR: Main binary not found${NC}"
((ERRORS++))
fi
# 2. Check for sanitizer libraries in Frameworks
echo ""
echo "2. Checking Frameworks"
echo "---------------------"
FRAMEWORKS_DIR="$APP_PATH/Contents/Frameworks"
if [ -d "$FRAMEWORKS_DIR" ]; then
SANITIZER_LIBS=$(find "$FRAMEWORKS_DIR" -name "*clang_rt*san*" -o -name "*asan*" -o -name "*tsan*" -o -name "*ubsan*" 2>/dev/null || true)
if [ -n "$SANITIZER_LIBS" ]; then
echo -e "${RED}❌ ERROR: Sanitizer libraries found in Frameworks:${NC}"
echo "$SANITIZER_LIBS"
((ERRORS++))
else
echo -e "${GREEN}✅ No sanitizer libraries in Frameworks${NC}"
fi
else
echo "No Frameworks directory found"
fi
# 3. Check vibetunnel server binary
echo ""
echo "3. VibeTunnel Server Binary"
echo "--------------------------"
SERVER_BINARY="$APP_PATH/Contents/Resources/vibetunnel"
if [ -f "$SERVER_BINARY" ]; then
check_binary "$SERVER_BINARY"
# Check size (debug builds are often larger)
SIZE_MB=$(ls -lh "$SERVER_BINARY" | awk '{print $5}')
echo "Binary size: $SIZE_MB"
# Get size in bytes for comparison
SIZE_BYTES=$(stat -f%z "$SERVER_BINARY" 2>/dev/null || stat -c%s "$SERVER_BINARY" 2>/dev/null)
if [ "$SIZE_BYTES" -gt 157286400 ]; then # 150 MB
echo -e "${YELLOW}⚠️ WARNING: Binary size exceeds 150MB, might be a debug build${NC}"
((WARNINGS++))
fi
else
echo -e "${RED}❌ ERROR: Server binary not found${NC}"
((ERRORS++))
fi
# 4. Check native modules
echo ""
echo "4. Native Modules"
echo "----------------"
for module in pty.node authenticate_pam.node spawn-helper; do
MODULE_PATH="$APP_PATH/Contents/Resources/$module"
if [ -f "$MODULE_PATH" ]; then
check_binary "$MODULE_PATH"
else
echo -e "${YELLOW}⚠️ WARNING: $module not found${NC}"
((WARNINGS++))
fi
done
# 5. Check build configuration (if Info.plist contains debug info)
echo ""
echo "5. Build Configuration"
echo "--------------------"
INFO_PLIST="$APP_PATH/Contents/Info.plist"
if [ -f "$INFO_PLIST" ]; then
# Check for common debug keys
if plutil -p "$INFO_PLIST" 2>/dev/null | grep -qi "debug"; then
echo -e "${YELLOW}⚠️ WARNING: Info.plist may contain debug configuration${NC}"
((WARNINGS++))
else
echo -e "${GREEN}✅ No obvious debug configuration in Info.plist${NC}"
fi
else
echo -e "${YELLOW}⚠️ WARNING: Info.plist not found${NC}"
((WARNINGS++))
fi
# 6. Check code signature
echo ""
echo "6. Code Signature"
echo "----------------"
CODESIGN_INFO=$(codesign -dvvv "$APP_PATH" 2>&1 || true)
if echo "$CODESIGN_INFO" | grep -q "Authority="; then
echo -e "${GREEN}✅ App is signed${NC}"
# Check if it's a development certificate
if echo "$CODESIGN_INFO" | grep -q "Developer ID"; then
echo -e "${GREEN}✅ Signed with Developer ID (release)${NC}"
elif echo "$CODESIGN_INFO" | grep -q "Apple Development"; then
echo -e "${YELLOW}⚠️ WARNING: Signed with development certificate${NC}"
((WARNINGS++))
fi
else
echo -e "${YELLOW}⚠️ WARNING: App is not signed${NC}"
((WARNINGS++))
fi
# Summary
echo ""
echo "====================================="
echo "Verification Summary"
echo "====================================="
if [ $ERRORS -eq 0 ] && [ $WARNINGS -eq 0 ]; then
echo -e "${GREEN}✅ All checks passed! This appears to be a valid release build.${NC}"
exit 0
elif [ $ERRORS -eq 0 ]; then
echo -e "${YELLOW}⚠️ Build has $WARNINGS warning(s) but no critical errors.${NC}"
echo "Review the warnings above to ensure they're acceptable."
exit 0
else
echo -e "${RED}❌ Build has $ERRORS error(s) and $WARNINGS warning(s).${NC}"
echo "This build should NOT be released!"
exit 1
fi

View file

@ -98,8 +98,8 @@ async function buildCustomNode() {
// Support CI environment variable
nodeSourceVersion = process.env.NODE_VERSION;
} else {
// Default to Node.js 24.2.0 (recommended version)
nodeSourceVersion = '24.2.0';
// Default to Node.js 24.3.0 (recommended version)
nodeSourceVersion = '24.3.0';
}
const platform = process.platform;
@ -177,6 +177,7 @@ async function buildCustomNode() {
'--without-inspector', // Remove debugging/profiling features
'--without-node-code-cache', // Disable code cache
'--without-node-snapshot', // Don't create/use startup snapshot
'--shared-zlib', // Use system zlib instead of building custom
];
// Check if ninja is available
@ -188,7 +189,8 @@ async function buildCustomNode() {
console.log('Ninja not found, using Make...');
}
// Enable ccache if available
// Enable ccache if available in system paths
try {
execSync('which ccache', { stdio: 'ignore' });
process.env.CC = 'ccache gcc';
@ -201,8 +203,6 @@ async function buildCustomNode() {
// Use -Os optimization which is proven to be safe
process.env.CFLAGS = '-Os';
process.env.CXXFLAGS = '-Os';
// Clear LDFLAGS to avoid any issues
delete process.env.LDFLAGS;
execSync(`./configure ${configureArgs.join(' ')}`, { stdio: 'inherit' });
@ -277,6 +277,7 @@ Path: ${customNodePath}
`;
fs.writeFileSync(summaryPath, summary);
// Change back to original directory
process.chdir(originalCwd);

View file

@ -321,21 +321,40 @@ async function main() {
const customVersion = execSync(`"${nodeExe}" --version`, { encoding: 'utf8' }).trim();
console.log(`Custom Node.js version: ${customVersion}`);
// Save original PATH and use clean environment
const originalPath = process.env.PATH;
const cleanEnv = {
...process.env,
// Use only system paths to avoid Homebrew contamination
PATH: '/usr/bin:/bin:/usr/sbin:/sbin',
npm_config_runtime: 'node',
npm_config_target: customVersion.substring(1), // Remove 'v' prefix
npm_config_arch: process.arch,
npm_config_target_arch: process.arch,
npm_config_disturl: 'https://nodejs.org/dist',
npm_config_build_from_source: 'true',
// Node.js 24 requires C++20
CXXFLAGS: '-std=c++20',
npm_config_cxxflags: '-std=c++20'
};
// Remove any Homebrew-related environment variables
delete cleanEnv.LDFLAGS;
delete cleanEnv.LIBRARY_PATH;
delete cleanEnv.CPATH;
delete cleanEnv.C_INCLUDE_PATH;
delete cleanEnv.CPLUS_INCLUDE_PATH;
delete cleanEnv.PKG_CONFIG_PATH;
console.log('Using clean PATH to avoid Homebrew dependencies during native module rebuild...');
execSync(`pnpm rebuild node-pty authenticate-pam`, {
stdio: 'inherit',
env: {
...process.env,
npm_config_runtime: 'node',
npm_config_target: customVersion.substring(1), // Remove 'v' prefix
npm_config_arch: process.arch,
npm_config_target_arch: process.arch,
npm_config_disturl: 'https://nodejs.org/dist',
npm_config_build_from_source: 'true',
// Node.js 24 requires C++20
CXXFLAGS: '-std=c++20',
npm_config_cxxflags: '-std=c++20'
}
env: cleanEnv
});
// Restore original PATH
process.env.PATH = originalPath;
}
// 2. Bundle TypeScript with esbuild

View file

@ -1,6 +1,6 @@
{
"name": "@vibetunnel/vibetunnel-cli",
"version": "1.0.0-beta.7",
"version": "1.0.0-beta.8",
"description": "Web frontend for terminal multiplexer",
"main": "dist/server.js",
"bin": {