# Multica fork CLI — Windows installer # # Installs the fork-built `multica.exe` CLI (with agent-arka runtime support, # Arka SSO, Russian i18n) from arka/public releases. # # irm https://git.arka-ai.ru/arka/public/raw/branch/main/multica/install.ps1 | iex # # Environment: # $env:MULTICA_VERSION pin a release (e.g. 0.6.1-arka). Default: newest multica-v* on git.arka-ai.ru/arka/public $ErrorActionPreference = "Stop" $PublicApi = if ($env:MULTICA_PUBLIC_API) { $env:MULTICA_PUBLIC_API } else { "https://git.arka-ai.ru/api/v1" } $PublicDl = if ($env:MULTICA_PUBLIC_DL) { $env:MULTICA_PUBLIC_DL } else { "https://git.arka-ai.ru/arka/public/releases/download" } $Repo = "arka/public" $TagPrefix = "multica-v" $BinDir = Join-Path $env:USERPROFILE ".multica\bin" function Write-Info { Write-Host "==> $args" -ForegroundColor Cyan } function Write-Ok { Write-Host "OK $args" -ForegroundColor Green } function Write-Warn { Write-Host "WARN $args" -ForegroundColor Yellow } function Write-Fail { Write-Host "FAIL $args" -ForegroundColor Red; exit 1 } function Get-WindowsCliArch { $arch = $env:PROCESSOR_ARCHITECTURE if ($arch -eq "AMD64" -or $arch -eq "x86_64") { return "amd64" } if ($arch -eq "ARM64") { return "arm64" } Write-Fail "Unsupported architecture: $arch" } function Get-LatestMulticaVersion { $url = "$PublicApi/repos/$Repo/releases?limit=50" try { $releases = Invoke-RestMethod -Uri $url -UseBasicParsing -ErrorAction Stop } catch { Write-Fail "Cannot list releases at $url : $_" } $tags = $releases | Where-Object { $_.tag_name -like "$TagPrefix*" } | ForEach-Object { $_.tag_name } if (-not $tags) { Write-Fail "No ${TagPrefix}* releases on $Repo yet" } $latest = $tags | Sort-Object -Descending | Select-Object -First 1 return $latest.Substring($TagPrefix.Length) } function Add-ToUserPath { param([string]$Dir) $currentPath = [Environment]::GetEnvironmentVariable("Path", "User") if ($currentPath -and $currentPath.Split(";") -contains $Dir) { return } $newPath = if ($currentPath) { "$currentPath;$Dir" } else { $Dir } [Environment]::SetEnvironmentVariable("Path", $newPath, "User") if ($env:Path -notlike "*$Dir*") { $env:Path = "$Dir;$env:Path" } Write-Ok "Added $Dir to user PATH" } if (-not [Environment]::Is64BitOperatingSystem) { Write-Fail "Multica requires a 64-bit Windows installation." } $arch = Get-WindowsCliArch $version = if ($env:MULTICA_VERSION) { $env:MULTICA_VERSION.TrimStart("v").TrimStart($TagPrefix) } else { Get-LatestMulticaVersion } Write-Info "Installing Multica fork CLI ${version} (windows-$arch)..." $asset = "multica-cli-$version-windows-$arch.zip" $url = "$PublicDl/$TagPrefix$version/$asset" $tmpDir = Join-Path ([System.IO.Path]::GetTempPath()) "multica-install" if (Test-Path $tmpDir) { Remove-Item $tmpDir -Recurse -Force } New-Item -ItemType Directory -Path $tmpDir | Out-Null Write-Info "Downloading $url ..." try { Invoke-WebRequest -Uri $url -OutFile (Join-Path $tmpDir "multica.zip") -UseBasicParsing } catch { Remove-Item $tmpDir -Recurse -Force Write-Fail "Failed to download CLI binary: $_" } # Verify SHA256 checksum $checksumUrl = "$PublicDl/$TagPrefix$version/checksums.txt" try { $checksums = Invoke-WebRequest -Uri $checksumUrl -UseBasicParsing -ErrorAction Stop $checksumContent = if ($checksums.Content -is [byte[]]) { [System.Text.Encoding]::UTF8.GetString($checksums.Content) } else { [string]$checksums.Content } $zipFile = Join-Path $tmpDir "multica.zip" $actualHash = (Get-FileHash -Path $zipFile -Algorithm SHA256).Hash.ToLower() $expectedLine = ($checksumContent -split "`r?`n") | Where-Object { $_ -match [regex]::Escape($asset) } | Select-Object -First 1 if ($expectedLine) { $expectedHash = ($expectedLine -split "\s+")[0].ToLower() if ($actualHash -ne $expectedHash) { Remove-Item $tmpDir -Recurse -Force Write-Fail "Checksum verification failed. Expected: $expectedHash, Got: $actualHash" } Write-Ok "Checksum verified" } else { Write-Warn "Could not find checksum entry for $asset - skipping verification." } } catch { Write-Warn "Could not download checksums.txt - skipping verification." } Expand-Archive -Path (Join-Path $tmpDir "multica.zip") -DestinationPath $tmpDir -Force if (-not (Test-Path $BinDir)) { New-Item -ItemType Directory -Path $BinDir -Force | Out-Null } $exeSrc = Join-Path $tmpDir "multica.exe" if (-not (Test-Path $exeSrc)) { $exeSrc = Get-ChildItem -Path $tmpDir -Filter "multica.exe" -Recurse | Select-Object -First 1 -ExpandProperty FullName } if (-not $exeSrc -or -not (Test-Path $exeSrc)) { Remove-Item $tmpDir -Recurse -Force Write-Fail "multica.exe not found in downloaded archive." } Copy-Item $exeSrc (Join-Path $BinDir "multica.exe") -Force Remove-Item $tmpDir -Recurse -Force Add-ToUserPath $BinDir Write-Ok "Multica CLI installed to $BinDir\multica.exe" Write-Host "" Write-Host " Next — connect to your Multica server:" Write-Host " multica setup self-host" Write-Host " Or for this instance:" Write-Host " multica setup self-host --server-url https://plan.arka-ai.ru --app-url https://plan.arka-ai.ru" Write-Host ""