@@ -69,6 +69,8 @@ $LibDir = Join-Path $ScriptDir "lib"
6969. (Join-Path $LibDir " tier-map.ps1" )
7070. (Join-Path $LibDir " detection.ps1" )
7171. (Join-Path $LibDir " env-generator.ps1" )
72+ . (Join-Path $LibDir " llm-endpoint.ps1" )
73+ . (Join-Path $LibDir " opencode-config.ps1" )
7274
7375# ── Phase context variables ───────────────────────────────────────────────────
7476# These are plain (non-$script:) variables set in the orchestrator scope.
@@ -93,6 +95,65 @@ $installDir = $script:DS_INSTALL_DIR
9395$sourceRoot = $SourceRoot
9496
9597# ── Phase dispatcher ──────────────────────────────────────────────────────────
98+ function Get-UsableWindowsBash {
99+ <#
100+ . SYNOPSIS
101+ Prefer a Git Bash-style shell for bootstrap-upgrade.sh on Windows.
102+ #>
103+ param (
104+ [string ]$InstallPath = $installDir
105+ )
106+
107+ $probeCommand = " command -v bash >/dev/null 2>&1"
108+ if ($InstallPath -match " ^([A-Za-z]):" ) {
109+ $probeCommand += " && test -d /$ ( $Matches [1 ].ToLower()) "
110+ }
111+
112+ $candidates = New-Object ' System.Collections.Generic.List[string]'
113+
114+ $gitCmd = Get-Command git - ErrorAction SilentlyContinue
115+ if ($gitCmd -and $gitCmd.Source ) {
116+ $gitRoot = Split-Path (Split-Path $gitCmd.Source - Parent) - Parent
117+ $gitBash = Join-Path $gitRoot " bin\bash.exe"
118+ if (Test-Path $gitBash ) {
119+ [void ]$candidates.Add ($gitBash )
120+ }
121+ }
122+
123+ $programFilesBash = Join-Path $env: ProgramFiles " Git\bin\bash.exe"
124+ if (Test-Path $programFilesBash ) {
125+ [void ]$candidates.Add ($programFilesBash )
126+ }
127+
128+ if (${env: ProgramFiles(x86)} -and $env: ProgramFiles -ne ${env: ProgramFiles(x86)} ) {
129+ $programFilesX86Bash = Join-Path ${env: ProgramFiles(x86)} " Git\bin\bash.exe"
130+ if (Test-Path $programFilesX86Bash ) {
131+ [void ]$candidates.Add ($programFilesX86Bash )
132+ }
133+ }
134+
135+ $bashCmd = Get-Command bash - ErrorAction SilentlyContinue
136+ if ($bashCmd -and $bashCmd.Source ) {
137+ [void ]$candidates.Add ($bashCmd.Source )
138+ }
139+
140+ $seen = @ {}
141+ foreach ($candidate in $candidates ) {
142+ if ([string ]::IsNullOrWhiteSpace($candidate )) { continue }
143+ if ($seen.ContainsKey ($candidate )) { continue }
144+ $seen [$candidate ] = $true
145+
146+ try {
147+ & $candidate - lc $probeCommand * > $null
148+ if ($LASTEXITCODE -eq 0 ) {
149+ return $candidate
150+ }
151+ } catch { }
152+ }
153+
154+ return $null
155+ }
156+
96157$PhasesDir = Join-Path $ScriptDir " phases"
97158
98159Write-DreamBanner
@@ -575,13 +636,29 @@ exec bash "$bashScript" "$bashInstallDir" "$($fullTierConfig.GgufFile)" "$($full
575636"@
576637 [System.IO.File ]::WriteAllText($wrapperScript , $wrapperContent.Replace (" `r`n " , " `n " ), (New-Object System.Text.UTF8Encoding($false )))
577638
578- Start-Process - FilePath " bash" - ArgumentList $wrapperScript `
579- - WindowStyle Hidden `
580- - RedirectStandardOutput $upgradeLog `
581- - RedirectStandardError $upgradeErrLog
582-
583- Write-AI " Full model ($ ( $fullTierConfig.LlmModel ) ) downloading in background."
584- Write-AI " Check progress: Get-Content '$upgradeLog ' -Tail 10"
639+ $bashPath = Get-UsableWindowsBash - InstallPath $installDir
640+ if ($bashPath ) {
641+ $upgradeProc = Start-Process - FilePath $bashPath - ArgumentList $wrapperScript `
642+ - WindowStyle Hidden `
643+ - RedirectStandardOutput $upgradeLog `
644+ - RedirectStandardError $upgradeErrLog `
645+ - PassThru
646+
647+ Start-Sleep - Seconds 2
648+ $upgradeProc.Refresh ()
649+
650+ if ($upgradeProc.HasExited ) {
651+ Write-AIWarn " Background full-model download exited immediately (exit code: $ ( $upgradeProc.ExitCode ) )."
652+ Write-AI " Retry manually with: & '$bashPath ' '$wrapperScript '"
653+ Write-AI " Error log: $upgradeErrLog "
654+ } else {
655+ Write-AI " Full model ($ ( $fullTierConfig.LlmModel ) ) downloading in background."
656+ Write-AI " Check progress: Get-Content '$upgradeLog ' -Tail 10"
657+ }
658+ } else {
659+ Write-AIWarn " No Git Bash-compatible shell was found for bootstrap-upgrade.sh."
660+ Write-AI " Install Git for Windows or run the upgrade script manually after adding bash.exe to PATH."
661+ }
585662 } else {
586663 Write-AIWarn " bootstrap-upgrade.sh not found at $upgradeScript "
587664 Write-AIWarn " Download the full model manually or re-run the installer."
@@ -608,22 +685,31 @@ if ($dryRun) {
608685}
609686
610687# ── Service health checks ─────────────────────────────────────────────────────
611- # Use Lemonade health endpoint when AMD + Lemonade is active, llama-server otherwise
612- $llmHealthUrl = $ (if ($useLemonade ) {
613- $script :LEMONADE_HEALTH_URL
614- } else {
615- " http://localhost:8080/health"
616- })
617- $llmHealthName = $ (if ($useLemonade ) { " LLM (Lemonade)" } else { " LLM (llama-server)" })
688+ $opencodeSync = Sync-WindowsOpenCodeConfigFromEnv - InstallDir $installDir `
689+ - GpuBackend $gpuInfo.Backend - UseLemonade:$useLemonade - CloudMode:$cloudMode `
690+ - DefaultModelId $tierConfig.GgufFile - DefaultModelName $tierConfig.LlmModel `
691+ - DefaultContextLimit ([int ]$tierConfig.MaxContext ) - SkipIfUnavailable
692+ switch ($opencodeSync.Status ) {
693+ " created" {
694+ Write-AISuccess " OpenCode config synced to active model (model: $ ( $opencodeSync.ModelName ) )"
695+ }
696+ " updated" {
697+ Write-AISuccess " OpenCode config synced to active model (model: $ ( $opencodeSync.ModelName ) )"
698+ }
699+ " regenerated" {
700+ Write-AISuccess " OpenCode config regenerated for active model (model: $ ( $opencodeSync.ModelName ) )"
701+ }
702+ }
703+
704+ $llmEndpoint = Get-WindowsLocalLlmEndpoint - InstallDir $installDir `
705+ - EnvMap (Get-WindowsDreamEnvMap - InstallDir $installDir ) `
706+ - UseLemonade:$useLemonade - GpuBackend $gpuInfo.Backend - CloudMode:$cloudMode
618707$healthChecks = @ (
619- @ { Name = $llmHealthName ; Url = $llmHealthUrl }
708+ @ { Name = $llmEndpoint .Name ; Url = $llmEndpoint .HealthUrl }
620709 @ { Name = " Chat UI (Open WebUI)" ; Url = " http://localhost:3000" }
621710)
622711if ($enableVoice ) { $healthChecks += @ { Name = " Whisper (STT)" ; Url = " http://localhost:9000/health" } }
623712if ($enableWorkflows ) { $healthChecks += @ { Name = " n8n (Workflows)" ; Url = " http://localhost:5678/healthz" } }
624- if (Test-Path $script :OPENCODE_EXE ) {
625- $healthChecks += @ { Name = " OpenCode (IDE)" ; Url = " http://localhost:$ ( $script :OPENCODE_PORT ) /" }
626- }
627713
628714Write-AI " Running health checks..."
629715$maxAttempts = 60 ; $allHealthy = $true
0 commit comments