mirror of
https://github.com/samsonjs/vibetunnel.git
synced 2026-06-28 05:29:29 +00:00
Bun deleted, Nodejs is new king. Xcode not yet updated.
This commit is contained in:
parent
8e62137820
commit
c7153769a8
4 changed files with 398 additions and 497 deletions
|
|
@ -1,272 +0,0 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Minimal Node.js SEA build script - NO BUN!
|
||||
* Bundles src/cli.ts and all imports into a single executable
|
||||
*/
|
||||
|
||||
const { execSync } = require('child_process');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
console.log('Building standalone vibetunnel executable using Node.js SEA...');
|
||||
console.log(`Node.js version: ${process.version}`);
|
||||
|
||||
// Check Node.js version
|
||||
const nodeVersion = parseInt(process.version.split('.')[0].substring(1));
|
||||
if (nodeVersion < 20) {
|
||||
console.error('Error: Node.js 20 or higher is required for SEA feature');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function patchNodePty() {
|
||||
console.log('Patching node-pty for SEA build...');
|
||||
|
||||
// Patch prebuild-loader.js to use process.dlopen instead of require
|
||||
const prebuildLoaderFile = path.join(__dirname, 'node_modules/@homebridge/node-pty-prebuilt-multiarch/lib/prebuild-loader.js');
|
||||
const prebuildLoaderContent = `"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
|
||||
// Custom loader for SEA that uses process.dlopen
|
||||
var pty;
|
||||
|
||||
// Helper function to load native module using dlopen
|
||||
function loadNativeModule(modulePath) {
|
||||
const module = { exports: {} };
|
||||
process.dlopen(module, modulePath);
|
||||
return module.exports;
|
||||
}
|
||||
|
||||
// Determine the path to pty.node
|
||||
function getPtyPath() {
|
||||
const execDir = path.dirname(process.execPath);
|
||||
// Look for pty.node next to the executable first
|
||||
const ptyPath = path.join(execDir, 'pty.node');
|
||||
|
||||
if (fs.existsSync(ptyPath)) {
|
||||
return ptyPath;
|
||||
}
|
||||
|
||||
// If not found, throw error with helpful message
|
||||
throw new Error('Could not find pty.node next to executable at: ' + ptyPath);
|
||||
}
|
||||
|
||||
try {
|
||||
const ptyPath = getPtyPath();
|
||||
console.log('Loading pty.node from:', ptyPath);
|
||||
|
||||
// Set spawn-helper path for Unix systems
|
||||
if (process.platform !== 'win32') {
|
||||
const execDir = path.dirname(process.execPath);
|
||||
const spawnHelperPath = path.join(execDir, 'spawn-helper');
|
||||
if (fs.existsSync(spawnHelperPath)) {
|
||||
process.env.NODE_PTY_SPAWN_HELPER_PATH = spawnHelperPath;
|
||||
console.log('Set spawn-helper path:', spawnHelperPath);
|
||||
} else {
|
||||
console.error('Warning: spawn-helper not found at:', spawnHelperPath);
|
||||
}
|
||||
}
|
||||
|
||||
pty = loadNativeModule(ptyPath);
|
||||
} catch (error) {
|
||||
console.error('Failed to load pty.node:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
exports.default = pty;
|
||||
//# sourceMappingURL=prebuild-loader.js.map`;
|
||||
|
||||
fs.writeFileSync(prebuildLoaderFile, prebuildLoaderContent);
|
||||
|
||||
// Also patch windowsPtyAgent.js if it exists
|
||||
const windowsPtyAgentFile = path.join(__dirname, 'node_modules/@homebridge/node-pty-prebuilt-multiarch/lib/windowsPtyAgent.js');
|
||||
if (fs.existsSync(windowsPtyAgentFile)) {
|
||||
let content = fs.readFileSync(windowsPtyAgentFile, 'utf8');
|
||||
// Replace direct require of .node files with our loader
|
||||
content = content.replace(
|
||||
/require\(['"]\.\.\/build\/Release\/pty\.node['"]\)/g,
|
||||
"require('./prebuild-loader').default"
|
||||
);
|
||||
fs.writeFileSync(windowsPtyAgentFile, content);
|
||||
}
|
||||
|
||||
// Patch index.js exports.native line
|
||||
const indexFile = path.join(__dirname, 'node_modules/@homebridge/node-pty-prebuilt-multiarch/lib/index.js');
|
||||
if (fs.existsSync(indexFile)) {
|
||||
let content = fs.readFileSync(indexFile, 'utf8');
|
||||
// Replace the exports.native line that directly requires .node
|
||||
content = content.replace(
|
||||
/exports\.native = \(process\.platform !== 'win32' \? require\(prebuild_file_path_1\.ptyPath \|\| '\.\.\/build\/Release\/pty\.node'\) : null\);/,
|
||||
"exports.native = (process.platform !== 'win32' ? require('./prebuild-loader').default : null);"
|
||||
);
|
||||
fs.writeFileSync(indexFile, content);
|
||||
}
|
||||
|
||||
// Patch unixTerminal.js to fix spawn-helper path resolution
|
||||
const unixTerminalFile = path.join(__dirname, 'node_modules/@homebridge/node-pty-prebuilt-multiarch/lib/unixTerminal.js');
|
||||
if (fs.existsSync(unixTerminalFile)) {
|
||||
let content = fs.readFileSync(unixTerminalFile, 'utf8');
|
||||
|
||||
// Replace the helperPath resolution logic
|
||||
const helperPathPatch = `var helperPath;
|
||||
// For SEA, use spawn-helper from environment or next to executable
|
||||
if (process.env.NODE_PTY_SPAWN_HELPER_PATH) {
|
||||
helperPath = process.env.NODE_PTY_SPAWN_HELPER_PATH;
|
||||
console.log('[node-pty] Using spawn-helper from env:', helperPath);
|
||||
} else {
|
||||
// In SEA context, look next to the executable
|
||||
const execDir = path.dirname(process.execPath);
|
||||
const spawnHelperPath = path.join(execDir, 'spawn-helper');
|
||||
if (require('fs').existsSync(spawnHelperPath)) {
|
||||
helperPath = spawnHelperPath;
|
||||
console.log('[node-pty] Using spawn-helper next to executable:', helperPath);
|
||||
} else {
|
||||
// Fallback to original logic
|
||||
helperPath = '../build/Release/spawn-helper';
|
||||
helperPath = path.resolve(__dirname, helperPath);
|
||||
helperPath = helperPath.replace('app.asar', 'app.asar.unpacked');
|
||||
helperPath = helperPath.replace('node_modules.asar', 'node_modules.asar.unpacked');
|
||||
}
|
||||
}`;
|
||||
|
||||
// Find and replace the helperPath section
|
||||
content = content.replace(
|
||||
/var helperPath;[\s\S]*?helperPath = helperPath\.replace\('node_modules\.asar', 'node_modules\.asar\.unpacked'\);/m,
|
||||
helperPathPatch
|
||||
);
|
||||
|
||||
fs.writeFileSync(unixTerminalFile, content);
|
||||
}
|
||||
|
||||
console.log('Patched node-pty to use process.dlopen() instead of require().');
|
||||
}
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
// Create build directory
|
||||
if (!fs.existsSync('build')) {
|
||||
fs.mkdirSync('build');
|
||||
}
|
||||
|
||||
// Create native directory
|
||||
if (!fs.existsSync('native')) {
|
||||
fs.mkdirSync('native');
|
||||
}
|
||||
|
||||
// 0. Patch node-pty
|
||||
patchNodePty();
|
||||
|
||||
// 1. Bundle TypeScript with esbuild using custom loader
|
||||
console.log('Bundling TypeScript with esbuild...');
|
||||
const buildDate = new Date().toISOString();
|
||||
const buildTimestamp = Date.now();
|
||||
|
||||
// Use esbuild directly without custom loader since we're patching node-pty
|
||||
const esbuildCmd = `npx esbuild src/cli.ts \\
|
||||
--bundle \\
|
||||
--platform=node \\
|
||||
--target=node20 \\
|
||||
--outfile=build/bundle.js \\
|
||||
--format=cjs \\
|
||||
--sourcemap=inline \\
|
||||
--source-root=/ \\
|
||||
--keep-names \\
|
||||
--define:process.env.BUILD_DATE='"${buildDate}"' \\
|
||||
--define:process.env.BUILD_TIMESTAMP='"${buildTimestamp}"'`;
|
||||
|
||||
console.log('Running:', esbuildCmd);
|
||||
execSync(esbuildCmd, { stdio: 'inherit' });
|
||||
|
||||
// 2. Create SEA configuration
|
||||
console.log('\nCreating SEA configuration...');
|
||||
const seaConfig = {
|
||||
main: 'build/bundle.js',
|
||||
output: 'build/sea-prep.blob',
|
||||
disableExperimentalSEAWarning: true,
|
||||
useSnapshot: false,
|
||||
useCodeCache: false
|
||||
};
|
||||
|
||||
fs.writeFileSync('build/sea-config.json', JSON.stringify(seaConfig, null, 2));
|
||||
|
||||
// 3. Generate SEA blob
|
||||
console.log('Generating SEA blob...');
|
||||
execSync('node --experimental-sea-config build/sea-config.json', { stdio: 'inherit' });
|
||||
|
||||
// 4. Create executable
|
||||
console.log('\nCreating executable...');
|
||||
const nodeExe = process.execPath;
|
||||
const targetExe = process.platform === 'win32' ? 'native/vibetunnel.exe' : 'native/vibetunnel';
|
||||
|
||||
// Copy node binary
|
||||
fs.copyFileSync(nodeExe, targetExe);
|
||||
if (process.platform !== 'win32') {
|
||||
fs.chmodSync(targetExe, 0o755);
|
||||
}
|
||||
|
||||
// 5. Inject the blob
|
||||
console.log('Injecting SEA blob...');
|
||||
let postjectCmd = `npx postject ${targetExe} NODE_SEA_BLOB build/sea-prep.blob \\
|
||||
--sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2`;
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
postjectCmd += ' --macho-segment-name NODE_SEA';
|
||||
}
|
||||
|
||||
execSync(postjectCmd, { stdio: 'inherit' });
|
||||
|
||||
// 6. Sign on macOS
|
||||
if (process.platform === 'darwin') {
|
||||
console.log('Signing executable...');
|
||||
execSync(`codesign --sign - ${targetExe}`, { stdio: 'inherit' });
|
||||
}
|
||||
|
||||
// 7. Restore original node-pty
|
||||
console.log('Restoring original node-pty...');
|
||||
execSync('rm -rf node_modules/@homebridge/node-pty-prebuilt-multiarch', { stdio: 'inherit' });
|
||||
execSync('npm install @homebridge/node-pty-prebuilt-multiarch --silent --no-fund --no-audit', { stdio: 'inherit' });
|
||||
|
||||
// 8. Copy only necessary native files
|
||||
console.log('Copying native modules...');
|
||||
const nativeModulesDir = 'node_modules/@homebridge/node-pty-prebuilt-multiarch/build/Release';
|
||||
|
||||
// Copy pty.node
|
||||
fs.copyFileSync(
|
||||
path.join(nativeModulesDir, 'pty.node'),
|
||||
'native/pty.node'
|
||||
);
|
||||
console.log(' - Copied pty.node');
|
||||
|
||||
// Copy spawn-helper (Unix only)
|
||||
if (process.platform !== 'win32') {
|
||||
fs.copyFileSync(
|
||||
path.join(nativeModulesDir, 'spawn-helper'),
|
||||
'native/spawn-helper'
|
||||
);
|
||||
fs.chmodSync('native/spawn-helper', 0o755);
|
||||
console.log(' - Copied spawn-helper');
|
||||
}
|
||||
|
||||
// 9. Clean up
|
||||
console.log('\nCleaning up...');
|
||||
fs.rmSync('build', { recursive: true, force: true });
|
||||
|
||||
console.log('\n✅ Build complete!');
|
||||
console.log(`\nPortable executable created in native/ directory:`);
|
||||
console.log(` - vibetunnel (executable)`);
|
||||
console.log(` - pty.node`);
|
||||
if (process.platform !== 'win32') {
|
||||
console.log(` - spawn-helper`);
|
||||
}
|
||||
console.log('\nAll files must be kept together in the same directory.');
|
||||
console.log('This bundle will work on any machine with the same OS/architecture.');
|
||||
|
||||
} catch (error) {
|
||||
console.error('\n❌ Build failed:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
|
|
@ -1,156 +1,343 @@
|
|||
#!/usr/bin/env node
|
||||
|
||||
/**
|
||||
* Build standalone vibetunnel executable with native modules
|
||||
*
|
||||
* Note: Bun does not support universal binaries. This builds for the native architecture only.
|
||||
* Build standalone vibetunnel executable using Node.js SEA (Single Executable Application)
|
||||
*
|
||||
* This script creates a portable executable that bundles the VibeTunnel server into a single
|
||||
* binary using Node.js's built-in SEA feature. The resulting executable can run on any machine
|
||||
* with the same OS/architecture without requiring Node.js to be installed.
|
||||
*
|
||||
* ## Output
|
||||
* Creates a `native/` directory with just 3 files:
|
||||
* - `vibetunnel` - The standalone executable (includes all JS code and sourcemaps)
|
||||
* - `pty.node` - Native binding for terminal emulation
|
||||
* - `spawn-helper` - Helper binary for spawning processes (Unix only)
|
||||
*
|
||||
* ## How it works
|
||||
*
|
||||
* 1. **Patches node-pty** to work with SEA's limitations:
|
||||
* - SEA's require() can only load built-in Node.js modules, not external files
|
||||
* - We patch node-pty to use `process.dlopen()` instead of `require()` for native modules
|
||||
* - All file lookups are changed to look next to the executable, not in node_modules
|
||||
*
|
||||
* 2. **Bundles TypeScript** using esbuild:
|
||||
* - Compiles and bundles all TypeScript/JavaScript into a single file
|
||||
* - Includes inline sourcemaps for better debugging
|
||||
* - Source map support can be enabled with --sourcemap flag
|
||||
*
|
||||
* 3. **Creates SEA blob**:
|
||||
* - Uses Node.js's experimental SEA config to generate a blob from the bundle
|
||||
* - The blob contains all the JavaScript code and can be injected into a Node binary
|
||||
*
|
||||
* 4. **Injects into Node.js binary**:
|
||||
* - Copies the Node.js executable and injects the SEA blob using postject
|
||||
* - Signs the binary on macOS to avoid security warnings
|
||||
*
|
||||
* ## Portability
|
||||
* The resulting executable is fully portable:
|
||||
* - No absolute paths are embedded
|
||||
* - Native modules are loaded relative to the executable location
|
||||
* - Can be moved to any directory or machine with the same OS/architecture
|
||||
*
|
||||
* ## Usage
|
||||
* ```bash
|
||||
* node build-native-node.js # Build without sourcemaps (default)
|
||||
* node build-native-node.js --sourcemap # Build with inline sourcemaps
|
||||
* ```
|
||||
*
|
||||
* ## Requirements
|
||||
* - Node.js 20+ (for SEA support)
|
||||
* - postject (installed automatically if needed)
|
||||
*
|
||||
* ## Known Limitations
|
||||
* - The SEA warning about require() limitations is expected and harmless
|
||||
* - Native modules must be distributed alongside the executable
|
||||
* - Cross-platform builds are not supported (build on the target platform)
|
||||
*/
|
||||
|
||||
const { execSync } = require('child_process');
|
||||
const fs = require('fs');
|
||||
const path = require('path');
|
||||
|
||||
console.log('Building standalone vibetunnel executable for native architecture...');
|
||||
console.log('Note: Bun does not support universal binaries');
|
||||
// Parse command line arguments
|
||||
const includeSourcemaps = process.argv.includes('--sourcemap');
|
||||
|
||||
console.log('Building standalone vibetunnel executable using Node.js SEA...');
|
||||
console.log(`Node.js version: ${process.version}`);
|
||||
if (includeSourcemaps) {
|
||||
console.log('Including sourcemaps in build');
|
||||
}
|
||||
|
||||
// Check Node.js version
|
||||
const nodeVersion = parseInt(process.version.split('.')[0].substring(1));
|
||||
if (nodeVersion < 20) {
|
||||
console.error('Error: Node.js 20 or higher is required for SEA feature');
|
||||
process.exit(1);
|
||||
}
|
||||
|
||||
function patchNodePty() {
|
||||
console.log('Patching node-pty for standalone build...');
|
||||
console.log('Reinstalling node-pty to ensure clean state...');
|
||||
execSync('rm -rf node_modules/@homebridge/node-pty-prebuilt-multiarch', { stdio: 'inherit' });
|
||||
execSync('npm install @homebridge/node-pty-prebuilt-multiarch --silent --no-fund --no-audit', { stdio: 'inherit' });
|
||||
|
||||
console.log('Patching node-pty for SEA build...');
|
||||
|
||||
// Patch prebuild-file-path.js to look next to executable
|
||||
const prebuildPathFile = path.join(__dirname, 'node_modules/@homebridge/node-pty-prebuilt-multiarch/lib/prebuild-file-path.js');
|
||||
const prebuildPathContent = `"use strict";
|
||||
// Patch prebuild-loader.js to use process.dlopen instead of require
|
||||
const prebuildLoaderFile = path.join(__dirname, 'node_modules/@homebridge/node-pty-prebuilt-multiarch/lib/prebuild-loader.js');
|
||||
const prebuildLoaderContent = `"use strict";
|
||||
Object.defineProperty(exports, "__esModule", { value: true });
|
||||
exports.ptyPath = void 0;
|
||||
var path = require("path");
|
||||
var fs = require("fs");
|
||||
|
||||
// For bundled executables, look next to the binary
|
||||
if (process.argv[0] === 'bun' && process.execPath.endsWith('vibetunnel')) {
|
||||
exports.ptyPath = path.join(path.dirname(process.execPath), 'pty.node');
|
||||
} else {
|
||||
// Original prebuild logic
|
||||
var fs = require("fs");
|
||||
var os = require("os");
|
||||
function prebuildName() {
|
||||
var tags = [];
|
||||
tags.push(process.versions.hasOwnProperty('electron') ? 'electron' : 'node');
|
||||
tags.push('abi' + process.versions.modules);
|
||||
if (os.platform() === 'linux' && fs.existsSync('/etc/alpine-release')) {
|
||||
tags.push('musl');
|
||||
}
|
||||
return tags.join('.') + '.node';
|
||||
}
|
||||
var pathToBuild = path.resolve(__dirname, "../prebuilds/" + os.platform() + "-" + os.arch() + "/" + prebuildName());
|
||||
exports.ptyPath = fs.existsSync(pathToBuild) ? pathToBuild : null;
|
||||
}
|
||||
//# sourceMappingURL=prebuild-file-path.js.map`;
|
||||
// Custom loader for SEA that uses process.dlopen
|
||||
var pty;
|
||||
|
||||
fs.writeFileSync(prebuildPathFile, prebuildPathContent);
|
||||
|
||||
// Also update unixTerminal.js
|
||||
const unixTerminalPath = path.join(__dirname, 'node_modules/@homebridge/node-pty-prebuilt-multiarch/lib/unixTerminal.js');
|
||||
let unixTerminal = fs.readFileSync(unixTerminalPath, 'utf8');
|
||||
|
||||
// Add check for bundled executable after helperPath is set
|
||||
const helperPathInsert = `
|
||||
// For bundled executables, look next to the binary
|
||||
if (process.argv[0] === 'bun' && process.execPath.endsWith('vibetunnel')) {
|
||||
helperPath = path.join(path.dirname(process.execPath), 'spawn-helper');
|
||||
} else {
|
||||
helperPath = path.resolve(__dirname, helperPath);
|
||||
}`;
|
||||
|
||||
// Find where to insert - after the helperPath assignment
|
||||
const resolveMatch = unixTerminal.match(/helperPath = path\.resolve\(__dirname, helperPath\);/);
|
||||
if (resolveMatch) {
|
||||
unixTerminal = unixTerminal.replace(
|
||||
'helperPath = path.resolve(__dirname, helperPath);',
|
||||
helperPathInsert
|
||||
);
|
||||
} else {
|
||||
// If already patched, look for the bundled check
|
||||
if (!unixTerminal.includes('process.execPath.endsWith')) {
|
||||
// Find the helperPath line and add our check
|
||||
const helperPathLine = unixTerminal.indexOf("helperPath = '../build/Release/spawn-helper';");
|
||||
if (helperPathLine !== -1) {
|
||||
const nextLineIndex = unixTerminal.indexOf('\n', helperPathLine) + 1;
|
||||
unixTerminal = unixTerminal.slice(0, nextLineIndex) + helperPathInsert + '\n' + unixTerminal.slice(nextLineIndex);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fs.writeFileSync(unixTerminalPath, unixTerminal);
|
||||
|
||||
console.log('Patched node-pty to look for native files next to executable.');
|
||||
// Helper function to load native module using dlopen
|
||||
function loadNativeModule(modulePath) {
|
||||
const module = { exports: {} };
|
||||
process.dlopen(module, modulePath);
|
||||
return module.exports;
|
||||
}
|
||||
|
||||
|
||||
console.log('Building standalone vibetunnel executable...');
|
||||
// Determine the path to pty.node
|
||||
function getPtyPath() {
|
||||
const execDir = path.dirname(process.execPath);
|
||||
// Look for pty.node next to the executable first
|
||||
const ptyPath = path.join(execDir, 'pty.node');
|
||||
|
||||
if (fs.existsSync(ptyPath)) {
|
||||
return ptyPath;
|
||||
}
|
||||
|
||||
// If not found, throw error with helpful message
|
||||
throw new Error('Could not find pty.node next to executable at: ' + ptyPath);
|
||||
}
|
||||
|
||||
try {
|
||||
// 1. Apply patches
|
||||
patchNodePty();
|
||||
|
||||
// 2. Create native directory
|
||||
if (!fs.existsSync('native')) {
|
||||
fs.mkdirSync('native');
|
||||
const ptyPath = getPtyPath();
|
||||
|
||||
// Set spawn-helper path for Unix systems
|
||||
if (process.platform !== 'win32') {
|
||||
const execDir = path.dirname(process.execPath);
|
||||
const spawnHelperPath = path.join(execDir, 'spawn-helper');
|
||||
if (fs.existsSync(spawnHelperPath)) {
|
||||
process.env.NODE_PTY_SPAWN_HELPER_PATH = spawnHelperPath;
|
||||
}
|
||||
}
|
||||
|
||||
// 3. Compile with Bun
|
||||
console.log('Compiling with Bun...');
|
||||
const buildDate = new Date().toISOString();
|
||||
const buildTimestamp = Date.now();
|
||||
|
||||
// Detect how we're running bun
|
||||
let bunCommand = 'bun';
|
||||
if (process.argv[0].includes('npx')) {
|
||||
// We're running via npx, so bun should also be run via npx
|
||||
bunCommand = 'npx -y bun';
|
||||
}
|
||||
|
||||
// Note: Bun compile doesn't fully support sourcemaps in stack traces yet
|
||||
// Using --minify=false to preserve more readable code structure
|
||||
const compileCmd = `BUILD_DATE="${buildDate}" BUILD_TIMESTAMP="${buildTimestamp}" ${bunCommand} build src/cli.ts --compile --sourcemap=inline --outfile native/vibetunnel`;
|
||||
|
||||
console.log(`Running: ${compileCmd}`);
|
||||
console.log(`Build date: ${buildDate}`);
|
||||
execSync(compileCmd, { stdio: 'inherit', env: { ...process.env, BUILD_DATE: buildDate, BUILD_TIMESTAMP: buildTimestamp } });
|
||||
|
||||
// 4. Copy native modules
|
||||
console.log('Creating native directory and copying modules...');
|
||||
const nativeModulesDir = 'node_modules/@homebridge/node-pty-prebuilt-multiarch/build/Release';
|
||||
|
||||
fs.copyFileSync(
|
||||
path.join(nativeModulesDir, 'pty.node'),
|
||||
'native/pty.node'
|
||||
);
|
||||
|
||||
fs.copyFileSync(
|
||||
path.join(nativeModulesDir, 'spawn-helper'),
|
||||
'native/spawn-helper'
|
||||
);
|
||||
|
||||
// 5. Restore original node-pty
|
||||
console.log('Restoring original node-pty...');
|
||||
execSync('rm -rf node_modules/@homebridge/node-pty-prebuilt-multiarch', { stdio: 'inherit' });
|
||||
execSync('npm install @homebridge/node-pty-prebuilt-multiarch --silent --no-fund --no-audit', { stdio: 'inherit' }); // Added --no-fund --no-audit for cleaner output
|
||||
|
||||
console.log('\nBuild complete!');
|
||||
console.log('');
|
||||
console.log('Standalone build created in native/ directory:');
|
||||
console.log(' - native/vibetunnel (executable)');
|
||||
console.log(' - native/pty.node');
|
||||
console.log(' - native/spawn-helper');
|
||||
console.log('');
|
||||
console.log('All three files must be in the same directory when running.');
|
||||
|
||||
|
||||
pty = loadNativeModule(ptyPath);
|
||||
} catch (error) {
|
||||
console.error('Build failed:');
|
||||
if (error.stderr) {
|
||||
console.error(error.stderr.toString());
|
||||
console.error('Failed to load pty.node:', error);
|
||||
throw error;
|
||||
}
|
||||
|
||||
exports.default = pty;
|
||||
//# sourceMappingURL=prebuild-loader.js.map`;
|
||||
|
||||
fs.writeFileSync(prebuildLoaderFile, prebuildLoaderContent);
|
||||
|
||||
// Also patch windowsPtyAgent.js if it exists
|
||||
const windowsPtyAgentFile = path.join(__dirname, 'node_modules/@homebridge/node-pty-prebuilt-multiarch/lib/windowsPtyAgent.js');
|
||||
if (fs.existsSync(windowsPtyAgentFile)) {
|
||||
let content = fs.readFileSync(windowsPtyAgentFile, 'utf8');
|
||||
// Replace direct require of .node files with our loader
|
||||
content = content.replace(
|
||||
/require\(['"]\.\.\/build\/Release\/pty\.node['"]\)/g,
|
||||
"require('./prebuild-loader').default"
|
||||
);
|
||||
fs.writeFileSync(windowsPtyAgentFile, content);
|
||||
}
|
||||
if (error.stdout) {
|
||||
console.error(error.stdout.toString());
|
||||
|
||||
// Patch index.js exports.native line
|
||||
const indexFile = path.join(__dirname, 'node_modules/@homebridge/node-pty-prebuilt-multiarch/lib/index.js');
|
||||
if (fs.existsSync(indexFile)) {
|
||||
let content = fs.readFileSync(indexFile, 'utf8');
|
||||
// Replace the exports.native line that directly requires .node
|
||||
content = content.replace(
|
||||
/exports\.native = \(process\.platform !== 'win32' \? require\(prebuild_file_path_1\.ptyPath \|\| '\.\.\/build\/Release\/pty\.node'\) : null\);/,
|
||||
"exports.native = (process.platform !== 'win32' ? require('./prebuild-loader').default : null);"
|
||||
);
|
||||
fs.writeFileSync(indexFile, content);
|
||||
}
|
||||
console.error(error.message);
|
||||
|
||||
// Patch unixTerminal.js to fix spawn-helper path resolution
|
||||
const unixTerminalFile = path.join(__dirname, 'node_modules/@homebridge/node-pty-prebuilt-multiarch/lib/unixTerminal.js');
|
||||
if (fs.existsSync(unixTerminalFile)) {
|
||||
let content = fs.readFileSync(unixTerminalFile, 'utf8');
|
||||
|
||||
// Replace the helperPath resolution logic
|
||||
const helperPathPatch = `var helperPath;
|
||||
// For SEA, use spawn-helper from environment or next to executable
|
||||
if (process.env.NODE_PTY_SPAWN_HELPER_PATH) {
|
||||
helperPath = process.env.NODE_PTY_SPAWN_HELPER_PATH;
|
||||
} else {
|
||||
// In SEA context, look next to the executable
|
||||
const execDir = path.dirname(process.execPath);
|
||||
const spawnHelperPath = path.join(execDir, 'spawn-helper');
|
||||
if (require('fs').existsSync(spawnHelperPath)) {
|
||||
helperPath = spawnHelperPath;
|
||||
} else {
|
||||
// Fallback to original logic
|
||||
helperPath = '../build/Release/spawn-helper';
|
||||
helperPath = path.resolve(__dirname, helperPath);
|
||||
helperPath = helperPath.replace('app.asar', 'app.asar.unpacked');
|
||||
helperPath = helperPath.replace('node_modules.asar', 'node_modules.asar.unpacked');
|
||||
}
|
||||
}`;
|
||||
|
||||
// Find and replace the helperPath section
|
||||
content = content.replace(
|
||||
/var helperPath;[\s\S]*?helperPath = helperPath\.replace\('node_modules\.asar', 'node_modules\.asar\.unpacked'\);/m,
|
||||
helperPathPatch
|
||||
);
|
||||
|
||||
fs.writeFileSync(unixTerminalFile, content);
|
||||
}
|
||||
|
||||
console.log('Patched node-pty to use process.dlopen() instead of require().');
|
||||
}
|
||||
|
||||
// Cleanup function
|
||||
function cleanup() {
|
||||
if (fs.existsSync('build') && !process.argv.includes('--keep-build')) {
|
||||
console.log('Cleaning up build directory...');
|
||||
fs.rmSync('build', { recursive: true, force: true });
|
||||
}
|
||||
}
|
||||
|
||||
// Ensure cleanup happens on exit
|
||||
process.on('exit', cleanup);
|
||||
process.on('SIGINT', () => {
|
||||
console.log('\nBuild interrupted');
|
||||
process.exit(1);
|
||||
}
|
||||
});
|
||||
process.on('SIGTERM', () => {
|
||||
console.log('\nBuild terminated');
|
||||
process.exit(1);
|
||||
});
|
||||
|
||||
async function main() {
|
||||
try {
|
||||
// Create build directory
|
||||
if (!fs.existsSync('build')) {
|
||||
fs.mkdirSync('build');
|
||||
}
|
||||
|
||||
// Create native directory
|
||||
if (!fs.existsSync('native')) {
|
||||
fs.mkdirSync('native');
|
||||
}
|
||||
|
||||
// 0. Patch node-pty
|
||||
patchNodePty();
|
||||
|
||||
// 1. Bundle TypeScript with esbuild using custom loader
|
||||
console.log('Bundling TypeScript with esbuild...');
|
||||
const buildDate = new Date().toISOString();
|
||||
const buildTimestamp = Date.now();
|
||||
|
||||
// Use esbuild directly without custom loader since we're patching node-pty
|
||||
let esbuildCmd = `npx esbuild src/cli.ts \\
|
||||
--bundle \\
|
||||
--platform=node \\
|
||||
--target=node20 \\
|
||||
--outfile=build/bundle.js \\
|
||||
--format=cjs \\
|
||||
--keep-names \\
|
||||
--define:process.env.BUILD_DATE='"${buildDate}"' \\
|
||||
--define:process.env.BUILD_TIMESTAMP='"${buildTimestamp}"'`;
|
||||
|
||||
if (includeSourcemaps) {
|
||||
esbuildCmd += ' \\\n --sourcemap=inline \\\n --source-root=/';
|
||||
}
|
||||
|
||||
console.log('Running:', esbuildCmd);
|
||||
execSync(esbuildCmd, { stdio: 'inherit' });
|
||||
|
||||
// 2. Create SEA configuration
|
||||
console.log('\nCreating SEA configuration...');
|
||||
const seaConfig = {
|
||||
main: 'build/bundle.js',
|
||||
output: 'build/sea-prep.blob',
|
||||
disableExperimentalSEAWarning: true,
|
||||
useSnapshot: false,
|
||||
useCodeCache: false
|
||||
};
|
||||
|
||||
fs.writeFileSync('build/sea-config.json', JSON.stringify(seaConfig, null, 2));
|
||||
|
||||
// 3. Generate SEA blob
|
||||
console.log('Generating SEA blob...');
|
||||
execSync('node --experimental-sea-config build/sea-config.json', { stdio: 'inherit' });
|
||||
|
||||
// 4. Create executable
|
||||
console.log('\nCreating executable...');
|
||||
const nodeExe = process.execPath;
|
||||
const targetExe = process.platform === 'win32' ? 'native/vibetunnel.exe' : 'native/vibetunnel';
|
||||
|
||||
// Copy node binary
|
||||
fs.copyFileSync(nodeExe, targetExe);
|
||||
if (process.platform !== 'win32') {
|
||||
fs.chmodSync(targetExe, 0o755);
|
||||
}
|
||||
|
||||
// 5. Inject the blob
|
||||
console.log('Injecting SEA blob...');
|
||||
let postjectCmd = `npx postject ${targetExe} NODE_SEA_BLOB build/sea-prep.blob \\
|
||||
--sentinel-fuse NODE_SEA_FUSE_fce680ab2cc467b6e072b8b5df1996b2`;
|
||||
|
||||
if (process.platform === 'darwin') {
|
||||
postjectCmd += ' --macho-segment-name NODE_SEA';
|
||||
}
|
||||
|
||||
execSync(postjectCmd, { stdio: 'inherit' });
|
||||
|
||||
// 6. Sign on macOS
|
||||
if (process.platform === 'darwin') {
|
||||
console.log('Signing executable...');
|
||||
execSync(`codesign --sign - ${targetExe}`, { stdio: 'inherit' });
|
||||
}
|
||||
|
||||
// 7. Restore original node-pty
|
||||
console.log('Restoring original node-pty...');
|
||||
execSync('rm -rf node_modules/@homebridge/node-pty-prebuilt-multiarch', { stdio: 'inherit' });
|
||||
execSync('npm install @homebridge/node-pty-prebuilt-multiarch --silent --no-fund --no-audit', { stdio: 'inherit' });
|
||||
|
||||
// 8. Copy only necessary native files
|
||||
console.log('Copying native modules...');
|
||||
const nativeModulesDir = 'node_modules/@homebridge/node-pty-prebuilt-multiarch/build/Release';
|
||||
|
||||
// Copy pty.node
|
||||
fs.copyFileSync(
|
||||
path.join(nativeModulesDir, 'pty.node'),
|
||||
'native/pty.node'
|
||||
);
|
||||
console.log(' - Copied pty.node');
|
||||
|
||||
// Copy spawn-helper (Unix only)
|
||||
if (process.platform !== 'win32') {
|
||||
fs.copyFileSync(
|
||||
path.join(nativeModulesDir, 'spawn-helper'),
|
||||
'native/spawn-helper'
|
||||
);
|
||||
fs.chmodSync('native/spawn-helper', 0o755);
|
||||
console.log(' - Copied spawn-helper');
|
||||
}
|
||||
|
||||
console.log('\n✅ Build complete!');
|
||||
console.log(`\nPortable executable created in native/ directory:`);
|
||||
console.log(` - vibetunnel (executable)`);
|
||||
console.log(` - pty.node`);
|
||||
if (process.platform !== 'win32') {
|
||||
console.log(` - spawn-helper`);
|
||||
}
|
||||
console.log('\nAll files must be kept together in the same directory.');
|
||||
console.log('This bundle will work on any machine with the same OS/architecture.');
|
||||
|
||||
} catch (error) {
|
||||
console.error('\n❌ Build failed:', error.message);
|
||||
process.exit(1);
|
||||
}
|
||||
}
|
||||
|
||||
main();
|
||||
164
web/package-lock.json
generated
164
web/package-lock.json
generated
|
|
@ -1099,16 +1099,6 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/@puppeteer/browsers/node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/@puppeteer/browsers/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
|
|
@ -1211,6 +1201,16 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@puppeteer/browsers/node_modules/yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/@rollup/rollup-android-arm-eabi": {
|
||||
"version": "4.44.0",
|
||||
"resolved": "https://registry.npmjs.org/@rollup/rollup-android-arm-eabi/-/rollup-android-arm-eabi-4.44.0.tgz",
|
||||
|
|
@ -3080,6 +3080,16 @@
|
|||
"node": ">= 0.8"
|
||||
}
|
||||
},
|
||||
"node_modules/commander": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
|
||||
"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/component-emitter": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.3.1.tgz",
|
||||
|
|
@ -3145,16 +3155,6 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/concurrently/node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/concurrently/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
|
|
@ -3246,6 +3246,16 @@
|
|||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/concurrently/node_modules/yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/content-disposition": {
|
||||
"version": "0.5.4",
|
||||
"resolved": "https://registry.npmjs.org/content-disposition/-/content-disposition-0.5.4.tgz",
|
||||
|
|
@ -4145,22 +4155,6 @@
|
|||
"@types/yauzl": "^2.9.1"
|
||||
}
|
||||
},
|
||||
"node_modules/extract-zip/node_modules/get-stream": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
|
||||
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pump": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/fast-deep-equal": {
|
||||
"version": "3.1.3",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz",
|
||||
|
|
@ -4578,6 +4572,22 @@
|
|||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/get-stream": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-5.2.0.tgz",
|
||||
"integrity": "sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"pump": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/get-tsconfig": {
|
||||
"version": "4.10.1",
|
||||
"resolved": "https://registry.npmjs.org/get-tsconfig/-/get-tsconfig-4.10.1.tgz",
|
||||
|
|
@ -4970,6 +4980,16 @@
|
|||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/is-glob": {
|
||||
"version": "4.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-glob/-/is-glob-4.0.3.tgz",
|
||||
|
|
@ -5261,6 +5281,16 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lru-cache": {
|
||||
"version": "7.18.3",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
|
||||
"integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/lz-string": {
|
||||
"version": "1.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lz-string/-/lz-string-1.5.0.tgz",
|
||||
|
|
@ -6228,16 +6258,6 @@
|
|||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-agent/node_modules/lru-cache": {
|
||||
"version": "7.18.3",
|
||||
"resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-7.18.3.tgz",
|
||||
"integrity": "sha512-jumlc0BIUrS3qJGgIkWZsyfAM7NCWiBcCDhnd+3NNM5KbBmLTgHVfWBcg6W+rLUsIpzpERPsvwUP7CckAQSOoA==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/proxy-from-env": {
|
||||
"version": "1.1.0",
|
||||
"resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz",
|
||||
|
|
@ -7034,16 +7054,6 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/string-width-cjs/node_modules/strip-ansi": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz",
|
||||
|
|
@ -7156,16 +7166,6 @@
|
|||
"node": ">=16 || 14 >=14.17"
|
||||
}
|
||||
},
|
||||
"node_modules/sucrase/node_modules/commander": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-4.1.1.tgz",
|
||||
"integrity": "sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">= 6"
|
||||
}
|
||||
},
|
||||
"node_modules/superagent": {
|
||||
"version": "10.2.1",
|
||||
"resolved": "https://registry.npmjs.org/superagent/-/superagent-10.2.1.tgz",
|
||||
|
|
@ -8122,16 +8122,6 @@
|
|||
"dev": true,
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz",
|
||||
"integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==",
|
||||
"dev": true,
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/wrap-ansi-cjs/node_modules/string-width": {
|
||||
"version": "4.2.3",
|
||||
"resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz",
|
||||
|
|
@ -8247,13 +8237,14 @@
|
|||
}
|
||||
},
|
||||
"node_modules/yargs-parser": {
|
||||
"version": "21.1.1",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz",
|
||||
"integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==",
|
||||
"version": "13.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
|
||||
"integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
"dependencies": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs/node_modules/ansi-regex": {
|
||||
|
|
@ -8377,17 +8368,6 @@
|
|||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/yargs/node_modules/yargs-parser": {
|
||||
"version": "13.1.2",
|
||||
"resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.2.tgz",
|
||||
"integrity": "sha512-3lbsNRf/j+A4QuSZfDRA7HRSfWrzO0YjqTJd5kjAq37Zep1CEgaYmrH9Q3GwPiB9cHyd1Y1UwggGhJGoxipbzg==",
|
||||
"dev": true,
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"camelcase": "^5.0.0",
|
||||
"decamelize": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"node_modules/yauzl": {
|
||||
"version": "2.10.0",
|
||||
"resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz",
|
||||
|
|
|
|||
|
|
@ -4,8 +4,14 @@ import { startVibeTunnelForward } from './server/fwd.js';
|
|||
import { startVibeTunnelServer } from './server/server.js';
|
||||
import { VERSION } from './server/version.js';
|
||||
|
||||
// Enable source map support for better stack traces
|
||||
process.setSourceMapsEnabled(true);
|
||||
// Source maps are only included if built with --sourcemap flag
|
||||
|
||||
// Suppress the SEA warning if running in SEA context
|
||||
// This warning is expected and harmless - we handle external modules properly
|
||||
if (!process.argv[1]) {
|
||||
// In SEA context, argv[1] is undefined
|
||||
process.env.NODE_NO_WARNINGS = '1';
|
||||
}
|
||||
|
||||
// Handle uncaught exceptions
|
||||
process.on('uncaughtException', (error) => {
|
||||
|
|
|
|||
Loading…
Reference in a new issue