| [CmdletBinding()] |
| param( |
| [Parameter(Mandatory=$true)][string]$BuildManifestUrl, |
| [Parameter(Mandatory=$true)][string]$TargetDrive, |
| [switch]$SkipModelDownloads |
| ) |
| $ErrorActionPreference = "Stop" |
| if ($TargetDrive.Length -eq 2 -and $TargetDrive[1] -eq ':') { $TargetDrive = "$TargetDrive\" } |
| if (!(Test-Path $TargetDrive)) { throw "Target drive not found: $TargetDrive" } |
| $manifest = Invoke-RestMethod -Uri $BuildManifestUrl |
| if ($manifest.product -ne "JackAILocal") { throw "Wrong product manifest." } |
| $Root = (Resolve-Path $TargetDrive).Path |
| New-Item -ItemType Directory -Force -Path "$Root\models\ollama", "$Root\models\gguf", "$Root\backends", "$Root\bin", "$Root\manifest" | Out-Null |
|
|
| |
| $SeedRoot = Resolve-Path (Join-Path $PSScriptRoot "..\..") |
| robocopy $SeedRoot $Root /E /XD ".git" ".jackailocal" "target" | Out-Null |
|
|
| foreach ($asset in $manifest.assets) { |
| $dest = Join-Path $Root $asset.path |
| New-Item -ItemType Directory -Force -Path (Split-Path $dest) | Out-Null |
| if ($asset.url -and !(Test-Path $dest)) { |
| Invoke-WebRequest -Uri $asset.url -OutFile $dest |
| } |
| if ($asset.sha256) { |
| $h = (Get-FileHash -Algorithm SHA256 $dest).Hash.ToLowerInvariant() |
| if ($h -ne $asset.sha256.ToLowerInvariant()) { throw "Checksum failed for $($asset.path)" } |
| } |
| } |
|
|
| if (-not $SkipModelDownloads) { |
| $OllamaExe = Join-Path $Root "backends\ollama\windows\ollama.exe" |
| if (Test-Path $OllamaExe) { |
| $env:OLLAMA_MODELS = Join-Path $Root "models\ollama" |
| foreach ($m in $manifest.ollama_models) { & $OllamaExe pull $m } |
| } |
| } |
|
|
| $manifest | ConvertTo-Json -Depth 20 | Set-Content -Encoding UTF8 (Join-Path $Root "manifest\build-manifest.json") |
| Write-Host "JackAILocal key built at $Root" |
| Write-Host "Use START-HERE.cmd on the key." |
|
|