@echo off setlocal for %%I in ("%~dp0..") do set "PROJECT_ROOT=%%~fI" set "WEB_DIR=%PROJECT_ROOT%\src\web" set "LIBCLANG_PATH=%PROJECT_ROOT%\.tools\libclang\clang\native" where cargo >nul 2>nul if errorlevel 1 ( echo [ERROR] Cargo was not found in PATH pause exit /b 1 ) where bun >nul 2>nul if errorlevel 1 ( echo [ERROR] Bun was not found in PATH pause exit /b 1 ) if not exist "%LIBCLANG_PATH%\libclang.dll" ( echo [ERROR] libclang.dll was not found at echo %LIBCLANG_PATH% echo. echo Install it with echo python -m pip install --target "%PROJECT_ROOT%\.tools\libclang" libclang pause exit /b 1 ) if not exist "%PROJECT_ROOT%\dht-search.toml" ( echo [INFO] Creating local configuration from template copy /Y "%PROJECT_ROOT%\dht-search.example.toml" "%PROJECT_ROOT%\dht-search.toml" >nul if errorlevel 1 ( echo [ERROR] Failed to create dht-search.toml pause exit /b 1 ) ) if not exist "%WEB_DIR%\node_modules" ( echo [INFO] Installing Web dependencies pushd "%WEB_DIR%" call bun install --frozen-lockfile if errorlevel 1 ( popd echo [ERROR] Failed to install Web dependencies pause exit /b 1 ) popd ) echo. echo [INFO] Starting backend and Web in this window echo [INFO] Backend: http://127.0.0.1:8080 echo [INFO] Web: http://127.0.0.1:5173 echo. echo Open http://127.0.0.1:5173 after both services are ready echo Press Ctrl+C once to stop both services echo. powershell -NoProfile -ExecutionPolicy Bypass -Command ^ "$backend = $null; $web = $null;" ^ "function Stop-Tree($process) {" ^ " if ($null -ne $process) {" ^ " $process.Refresh();" ^ " if (-not $process.HasExited) { Start-Process -FilePath 'taskkill.exe' -ArgumentList @('/PID', [string]$process.Id, '/T', '/F') -NoNewWindow -Wait | Out-Null }" ^ " }" ^ "}" ^ "try {" ^ " $backend = Start-Process -FilePath 'cargo' -ArgumentList @('run','-p','dht-search','--bin','dht-search','--','--config','dht-search.toml') -WorkingDirectory $env:PROJECT_ROOT -NoNewWindow -PassThru;" ^ " $web = Start-Process -FilePath 'bun' -ArgumentList @('--bun','run','dev','--','--host','127.0.0.1') -WorkingDirectory $env:WEB_DIR -NoNewWindow -PassThru;" ^ " while (-not $backend.HasExited -and -not $web.HasExited) { Start-Sleep -Milliseconds 250 }" ^ "} finally {" ^ " for ($i = 0; $i -lt 20; $i++) {" ^ " if (($null -eq $backend -or $backend.HasExited) -and ($null -eq $web -or $web.HasExited)) { break }" ^ " Start-Sleep -Milliseconds 250" ^ " }" ^ " Stop-Tree $backend;" ^ " Stop-Tree $web;" ^ "}" endlocal