@echo off setlocal EnableExtensions EnableDelayedExpansion title AetherForge Control Server cd /d "%~dp0" set "ROOT=%CD%" :: Remove corrupt empty Go file that breaks server builds (accidental placeholder). if exist "server\internal\ollama\main.go" ( for %%F in ("server\internal\ollama\main.go") do if %%~zF==0 del "server\internal\ollama\main.go" ) echo. echo ============================================================== echo AetherForge - Control Server Launcher echo ============================================================== echo This window stays open and shows live server logs. echo Press Ctrl+C to stop the server. echo ============================================================== echo. :: Common tool paths (Go/Node installs + user Go bin for garble) set "PATH=C:\Program Files\Go\bin;%USERPROFILE%\go\bin;C:\Program Files\nodejs;%PATH%" :: ============================================================ :: STEP 1: Go :: ============================================================ echo [1/5] Checking Go... where go >nul 2>nul if errorlevel 1 goto install_go echo Go found: call go version goto go_ready :install_go echo Go not found. Checking for existing installation... if exist "C:\Program Files\Go\bin\go.exe" ( echo Found Go at C:\Program Files\Go\bin set "PATH=C:\Program Files\Go\bin;%PATH%" goto go_ready ) echo Downloading and installing Go... if /i "%PROCESSOR_ARCHITECTURE%"=="AMD64" ( set "GO_ARCH=amd64" ) else ( set "GO_ARCH=386" ) set "GO_VERSION=1.22.2" set "GO_URL=https://go.dev/dl/go%GO_VERSION%.windows-%GO_ARCH%.msi" set "GO_MSI=%TEMP%\go-installer.msi" powershell -NoProfile -Command "& { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri '%GO_URL%' -OutFile '%GO_MSI%' }" if errorlevel 1 ( echo ERROR: Failed to download Go. Get it from https://go.dev/dl/ goto fatal_exit ) msiexec /i "%GO_MSI%" /quiet /norestart if errorlevel 1 ( echo ERROR: Go install failed. Run this script as Administrator. goto fatal_exit ) del "%GO_MSI%" 2>nul set "PATH=C:\Program Files\Go\bin;%USERPROFILE%\go\bin;%PATH%" echo Go installed. :go_ready :: Garble (optional, for Forge obfuscation — failure is non-fatal) echo [1.5/5] Checking Garble (optional)... where garble >nul 2>nul if errorlevel 1 ( echo Installing garble via go install... go install mvdan.cc/garble@latest if errorlevel 1 echo WARNING: Garble install failed; Forge obfuscation may be unavailable. ) :: ============================================================ :: STEP 2: Node.js :: ============================================================ echo [2/5] Checking Node.js... where node >nul 2>nul if errorlevel 1 goto install_node echo Node.js found: call node --version goto node_ready :install_node echo Node.js not found. Checking for existing installation... if exist "C:\Program Files\nodejs\node.exe" ( echo Found Node.js at C:\Program Files\nodejs set "PATH=C:\Program Files\nodejs;%PATH%" goto node_ready ) echo Downloading and installing Node.js... set "NODE_VERSION=20.12.2" set "NODE_URL=https://nodejs.org/dist/v%NODE_VERSION%/node-v%NODE_VERSION%-x64.msi" set "NODE_MSI=%TEMP%\node-installer.msi" powershell -NoProfile -Command "& { [Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12; Invoke-WebRequest -Uri '%NODE_URL%' -OutFile '%NODE_MSI%' }" if errorlevel 1 ( echo WARNING: Node.js download failed. Frontend build will be skipped. set "SKIP_FRONTEND=1" goto node_ready ) msiexec /i "%NODE_MSI%" /quiet /norestart if errorlevel 1 ( echo WARNING: Node.js install failed. Frontend build will be skipped. set "SKIP_FRONTEND=1" goto node_ready ) set "PATH=C:\Program Files\nodejs;%PATH%" del "%NODE_MSI%" 2>nul echo Node.js installed. :node_ready :: ============================================================ :: STEP 3: Data directories :: ============================================================ echo [3/5] Preparing data directories... if not exist "data\builds" mkdir "data\builds" if not exist "data\logs" mkdir "data\logs" if not exist "data\blueprints" mkdir "data\blueprints" if not exist "data\preps" mkdir "data\preps" if not exist "bin" mkdir "bin" echo OK: data\ and bin\ :: ============================================================ :: STEP 4: Frontend :: ============================================================ if defined SKIP_FRONTEND goto skip_frontend echo [4/5] Building dashboard (server\web)... cd /d "%ROOT%\server\web" if not exist "node_modules" ( echo npm install... call npm install if errorlevel 1 ( cd /d "%ROOT%" echo ERROR: npm install failed. goto fatal_exit ) ) echo npm run build... call npm run build if errorlevel 1 ( cd /d "%ROOT%" echo ERROR: Frontend build failed. goto fatal_exit ) cd /d "%ROOT%" echo Frontend built: server\web\dist goto frontend_done :skip_frontend echo [4/5] Skipping frontend build (Node.js unavailable) if not exist "server\web\dist\index.html" ( echo WARNING: No server\web\dist\index.html — dashboard may not load. ) :frontend_done if exist "server\web\dist\index.html" ( if not exist "server\webroot" mkdir "server\webroot" xcopy /E /I /Y /Q "server\web\dist\*" "server\webroot\" >nul echo Copied dashboard to server\webroot ) :: ============================================================ :: STEP 5: Server binary :: ============================================================ echo [5/5] Building control server... cd /d "%ROOT%\server" go mod download if errorlevel 1 echo WARNING: go mod download had issues; continuing... echo go build... go build -ldflags="-s -w" -o "..\bin\miner-server.exe" . if errorlevel 1 ( cd /d "%ROOT%" echo ERROR: Server build failed. goto fatal_exit ) cd /d "%ROOT%" if not exist "bin\miner-server.exe" ( echo ERROR: bin\miner-server.exe was not created. goto fatal_exit ) echo Server binary: bin\miner-server.exe :: ============================================================ :: LAUNCH (foreground — logs stay in this window) :: ============================================================ echo. echo Stopping any previous miner-server.exe... taskkill /F /IM miner-server.exe >nul 2>nul timeout /t 1 /nobreak >nul set "LAN_IP=localhost" for /f "usebackq delims=" %%I in (`powershell -NoProfile -Command "(Get-NetIPAddress -AddressFamily IPv4 | Where-Object { $_.IPAddress -notlike '127.*' -and $_.PrefixOrigin -ne 'WellKnown' } | Select-Object -First 1 -ExpandProperty IPAddress) 2>$null"`) do set "LAN_IP=%%I" echo. echo ============================================================== echo STARTING CONTROL SERVER echo ============================================================== echo Dashboard: http://localhost:8989 echo LAN: http://%LAN_IP%:8989 echo Agents WS: ws://%LAN_IP%:8989/ws/agent echo Data: %ROOT%\data\ echo. echo Live logs appear below. Ctrl+C stops the server. echo ============================================================== echo. :: Open browser after a short delay (server starts in this window) start "" cmd /c "timeout /t 3 /nobreak >nul && start http://localhost:8989/" echo [Server] miner-server.exe -port 8989 -data "%ROOT%\data" echo. .\bin\miner-server.exe -port 8989 -data "%ROOT%\data" set "EXITCODE=!ERRORLEVEL!" echo. if "!EXITCODE!"=="0" ( echo [Server] Stopped normally. ) else ( echo [Server] Exited with code !EXITCODE!. echo If port 8989 was in use, close other miner-server windows and run again. ) echo. goto end_pause :fatal_exit echo. echo ============================================================== echo LAUNCH FAILED — fix the errors above and run run.bat again. echo ============================================================== echo. :end_pause pause endlocal