- multica/install.sh (Linux/macOS/WSL): downloads the fork-built multica CLI (0.6.1-arka, agent-arka runtime support) from arka/public releases, verifies SHA256, installs to /usr/local/bin or ~/.local/bin, PATH. - multica/install.ps1 (Windows): same, installs to ~/.multica/bin. - multica/README.md + root README table entry. - Release multica-v0.6.1-arka hosts multica-cli-* tarballs/zip + checksums.
134 lines
5.2 KiB
PowerShell
134 lines
5.2 KiB
PowerShell
# 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 ""
|