UNPKG

morphbox

Version:

Docker-based AI sandbox for development with Claude integration

94 lines (77 loc) • 2.9 kB
#!/usr/bin/env node import { handler } from './build/handler.js'; import { env } from './build/env.js'; import polka from 'polka'; import { spawn } from 'child_process'; import { fileURLToPath } from 'url'; import { dirname, join } from 'path'; import { getAvailablePort } from './build/server/port-utils.js'; const __filename = fileURLToPath(import.meta.url); const __dirname = dirname(__filename); // Parse command line arguments const args = process.argv.slice(2); const terminalMode = args.includes('--terminal'); // Environment variables const path = env('SOCKET_PATH', false); const host = env('HOST', env('MORPHBOX_HOST', '0.0.0.0')); const preferredPort = parseInt(env('PORT', !path && '8008')); const preferredWsPort = parseInt(env('WS_PORT', '8009')); // Main async function to handle port allocation async function startServers() { // Get available ports const port = path ? preferredPort : await getAvailablePort(preferredPort, host); const wsPort = await getAvailablePort(preferredWsPort, host); // Start the websocket server in a separate process const wsServerPath = join(__dirname, 'src/lib/server/websocket-server.ts'); const wsProcess = spawn('npx', ['tsx', wsServerPath], { stdio: 'inherit', env: { ...process.env, WS_PORT: wsPort.toString(), MORPHBOX_HOST: host } }); wsProcess.on('error', (err) => { console.error('Failed to start WebSocket server:', err); process.exit(1); }); // Create the main server const server = polka(); // Add middleware to inject terminal mode flag server.use((req, res, next) => { // Inject terminal mode into the request so the app can access it req.terminalMode = terminalMode; // Also set it as a header that the client can read if (terminalMode) { res.setHeader('X-Terminal-Mode', 'true'); } next(); }); // Use the SvelteKit handler server.use(handler); // Start the server server.listen({ path, host, port }, () => { if (terminalMode) { console.log(`\nšŸ–„ļø Morphbox Terminal Mode (Claude Code only)`); console.log(`šŸ“ Running on ${path ? path : `http://${host}:${port}`}`); console.log(`šŸ”Œ WebSocket server on ws://${host}:${wsPort}`); console.log('\nPress Ctrl+C to exit\n'); } else { console.log(`\nšŸš€ Morphbox running on ${path ? path : `http://${host}:${port}`}`); console.log(`šŸ”Œ WebSocket server on ws://${host}:${wsPort}`); } }); // Handle cleanup process.on('SIGINT', () => { console.log('\nšŸ›‘ Shutting down...'); wsProcess.kill('SIGTERM'); process.exit(0); }); process.on('SIGTERM', () => { wsProcess.kill('SIGTERM'); process.exit(0); }); // Export for programmatic usage return { server, terminalMode }; } // Start the servers startServers().catch(err => { console.error('Failed to start servers:', err); process.exit(1); });