param([switch]$SkipMigration) . (Join-Path $PSScriptRoot 'bell-common.ps1') $backend = $null $pidFile = $null try { $root = Get-BellPackageRoot $state = Initialize-BellRuntime -PackageRoot $root $bell = Join-Path $root 'bell.exe' if (-not (Test-Path -LiteralPath $bell -PathType Leaf)) { throw "Bell executable not found: $bell" } $runtime = Join-Path $root 'runtime' $logs = Join-Path $runtime 'logs' New-Item -ItemType Directory -Force -Path $logs,(Join-Path $root 'temp\logs') | Out-Null $pidFile = Join-Path $runtime 'bell.pid' if (Test-Path -LiteralPath $pidFile) { $oldPid = 0 if ([int]::TryParse((Get-Content -LiteralPath $pidFile -Raw).Trim(), [ref]$oldPid) -and (Get-Process -Id $oldPid -ErrorAction SilentlyContinue)) { throw "Bell appears to be running with process id $oldPid." } Remove-Item -LiteralPath $pidFile -Force } [IO.File]::WriteAllText($pidFile, "$PID", (New-Object Text.UTF8Encoding($false))) Push-Location $root try { $autoMigrate = (Get-BellEnvironmentValue -Name 'BELL_AUTO_MIGRATE' -Default 'true').ToLowerInvariant() if (-not $SkipMigration -and $autoMigrate -notin @('false','0','no')) { Write-Host 'Applying pending Bell database migrations...' & $bell migrate -c $state.SettingsPath if ($LASTEXITCODE -ne 0) { throw 'Bell database migration failed.' } } $backend = Start-Process -FilePath $bell -ArgumentList @('server','-c',$state.SettingsPath) -WorkingDirectory $root -RedirectStandardOutput (Join-Path $logs 'bell.out.log') -RedirectStandardError (Join-Path $logs 'bell.err.log') -WindowStyle Hidden -PassThru Wait-BellHealth -BaseUrl $state.BackendUrl Write-Host "Bell is available at $($state.WebUrl)/" Write-Host 'Press Ctrl+C in this window or run stop-bell.bat to stop Bell.' & (Join-Path $PSScriptRoot 'bell-web.ps1') -WebRoot $state.WebRoot -ListenHost $state.WebHost -ListenPort $state.WebPort -BackendUrl $state.BackendUrl } finally { Pop-Location } } catch { Write-Error $_.Exception.Message exit 1 } finally { if ($backend -and -not $backend.HasExited) { & taskkill.exe /PID $backend.Id /T /F 2>$null | Out-Null } if ($pidFile -and (Test-Path -LiteralPath $pidFile)) { Remove-Item -LiteralPath $pidFile -Force } }