feat(multica): publish fork Multica CLI installers (agent-arka support)
- 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.
This commit is contained in:
1 parent
83731e3b50
commit
7144d7d703
4 files changed
+382
No files matched your search
@@ -0,0 +1,59 @@
|
||||
# Multica fork CLI (Arka)
|
||||
|
||||
Кастомный билд CLI Multica от Arka: поддержка **agent-arka** runtime (провайдер
|
||||
`agent-arka` на `plan.arka-ai.ru`), Arka SSO, русская локализация. Скачивается
|
||||
из публичных релизов этого репозитория; токен не нужен.
|
||||
|
||||
## Установка
|
||||
|
||||
macOS / Linux / WSL:
|
||||
|
||||
```bash
|
||||
curl -fsSL https://git.arka-ai.ru/arka/public/raw/branch/main/multica/install.sh | bash
|
||||
```
|
||||
|
||||
Windows (PowerShell):
|
||||
|
||||
```powershell
|
||||
irm https://git.arka-ai.ru/arka/public/raw/branch/main/multica/install.ps1 | iex
|
||||
```
|
||||
|
||||
Бинарь ставится в `/usr/local/bin` (или `~/.local/bin`), на Windows — в
|
||||
`~\.multica\bin`, и добавляется в `PATH`.
|
||||
|
||||
## Подключение к серверу
|
||||
|
||||
```bash
|
||||
multica setup self-host \
|
||||
--server-url https://plan.arka-ai.ru \
|
||||
--app-url https://plan.arka-ai.ru
|
||||
```
|
||||
|
||||
Команда настроит CLI, откроет браузер для входа и запустит daemon.
|
||||
|
||||
## Проверка
|
||||
|
||||
```bash
|
||||
multica version # 0.6.1-arka
|
||||
multica daemon status # running; агенты включают agent-arka
|
||||
```
|
||||
|
||||
Проверить, что бинарь умеет agent-arka:
|
||||
|
||||
```bash
|
||||
multica daemon probe-runtimes
|
||||
# provider_summary должен содержать "agent-arka"
|
||||
```
|
||||
|
||||
## Пин версии
|
||||
|
||||
```bash
|
||||
MULTICA_VERSION=0.6.1-arka curl -fsSL .../multica/install.sh | bash
|
||||
```
|
||||
|
||||
## Релизы
|
||||
|
||||
Бинари публикуются в [релизах](https://git.arka-ai.ru/arka/public/releases/tag/multica-v0.6.1-arka):
|
||||
`multica-cli-<version>-linux-{amd64,arm64}.tar.gz`,
|
||||
`multica-cli-<version>-darwin-{amd64,arm64}.tar.gz`,
|
||||
`multica-cli-<version>-windows-amd64.zip`, `checksums.txt`.
|
||||
@@ -0,0 +1,133 @@
|
||||
# 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 ""
|
||||
@@ -0,0 +1,175 @@
|
||||
#!/usr/bin/env bash
|
||||
# Multica fork CLI — installer (Linux / macOS / WSL).
|
||||
#
|
||||
# Installs the fork-built `multica` CLI (with agent-arka runtime support, Arka
|
||||
# SSO, Russian i18n) from arka/public releases.
|
||||
#
|
||||
# curl -fsSL https://git.arka-ai.ru/arka/public/raw/branch/main/multica/install.sh | bash
|
||||
#
|
||||
# Environment:
|
||||
# MULTICA_VERSION pin a release (e.g. 0.6.1-arka). Default: newest multica-v* on git.arka-ai.ru/arka/public
|
||||
# MULTICA_BIN_DIR install dir (default: /usr/local/bin, else ~/.local/bin)
|
||||
# NO_COLOR 1 to disable color output
|
||||
|
||||
if [ -z "${BASH_VERSION:-}" ]; then
|
||||
echo "The Multica installer needs bash. Run:" >&2
|
||||
echo " curl -fsSL https://git.arka-ai.ru/arka/public/raw/branch/main/multica/install.sh | bash" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
set -euo pipefail
|
||||
|
||||
PUBLIC_API="${MULTICA_PUBLIC_API:-https://git.arka-ai.ru/api/v1}"
|
||||
PUBLIC_DL="${MULTICA_PUBLIC_DL:-https://git.arka-ai.ru/arka/public/releases/download}"
|
||||
REPO="arka/public"
|
||||
TAG_PREFIX="multica-v"
|
||||
|
||||
if [[ -t 1 && -z "${NO_COLOR:-}" ]]; then
|
||||
C_GREEN=$'\033[32m'; C_YELLOW=$'\033[33m'; C_RED=$'\033[31m'; C_BOLD=$'\033[1m'; C_RESET=$'\033[0m'
|
||||
else
|
||||
C_GREEN=''; C_YELLOW=''; C_RED=''; C_BOLD=''; C_RESET=''
|
||||
fi
|
||||
|
||||
info() { printf '%s\n' "$*"; }
|
||||
ok() { printf '%s✓%s %s\n' "$C_GREEN" "$C_RESET" "$*"; }
|
||||
warn() { printf '%s⚠%s %s\n' "$C_YELLOW" "$C_RESET" "$*"; }
|
||||
die() { printf '%s✗%s %s\n' "$C_RED" "$C_RESET" "$*" >&2; exit 1; }
|
||||
|
||||
_mc_tmp=""
|
||||
cleanup() { [[ -n "${_mc_tmp:-}" ]] && rm -rf "$_mc_tmp"; }
|
||||
trap cleanup EXIT
|
||||
|
||||
detect_platform() {
|
||||
local os arch
|
||||
os=$(uname -s | tr '[:upper:]' '[:lower:]')
|
||||
arch=$(uname -m)
|
||||
case "$arch" in
|
||||
x86_64|amd64) arch="amd64" ;;
|
||||
aarch64|arm64) arch="arm64" ;;
|
||||
*) die "Unsupported architecture: $arch" ;;
|
||||
esac
|
||||
case "$os" in
|
||||
linux) PLATFORM="linux-${arch}" ;;
|
||||
darwin) PLATFORM="darwin-${arch}" ;;
|
||||
mingw*|msys*|cygwin*)
|
||||
die "This curl installer is for Linux/macOS/WSL. On Windows run the PowerShell installer instead:"$'\n'" irm https://git.arka-ai.ru/arka/public/raw/branch/main/multica/install.ps1 | iex"
|
||||
;;
|
||||
*) die "Unsupported OS: $os" ;;
|
||||
esac
|
||||
}
|
||||
|
||||
fetch_latest_version() {
|
||||
local json tags
|
||||
json=$(curl -fsSL "${PUBLIC_API}/repos/${REPO}/releases?limit=50") || die "Cannot list releases at ${PUBLIC_API}/repos/${REPO}/releases"
|
||||
tags=$(printf '%s' "$json" | grep -oE '"tag_name":[[:space:]]*"'"${TAG_PREFIX}"'[^"]+"' | sed 's/.*"'"${TAG_PREFIX}"'//;s/"$//' || true)
|
||||
if [[ -z "$tags" ]]; then
|
||||
die "No ${TAG_PREFIX}* releases on ${REPO} yet"
|
||||
fi
|
||||
printf '%s\n' "$tags" | head -n 1
|
||||
}
|
||||
|
||||
sha256_file() {
|
||||
if command -v sha256sum >/dev/null 2>&1; then
|
||||
sha256sum "$1" | awk '{print $1}'
|
||||
elif command -v shasum >/dev/null 2>&1; then
|
||||
shasum -a 256 "$1" | awk '{print $1}'
|
||||
else
|
||||
die "Need sha256sum or shasum"
|
||||
fi
|
||||
}
|
||||
|
||||
ensure_path() {
|
||||
local bindir="$1"
|
||||
case ":$PATH:" in
|
||||
*":${bindir}:"*) return 0 ;;
|
||||
esac
|
||||
local line="export PATH=\"${bindir}:\$PATH\""
|
||||
local rc
|
||||
for rc in "${HOME}/.zprofile" "${HOME}/.zshrc" "${HOME}/.bash_profile" "${HOME}/.bashrc" "${HOME}/.profile"; do
|
||||
[[ -f "$rc" ]] || continue
|
||||
if grep -Fqs "$bindir" "$rc"; then
|
||||
return 0
|
||||
fi
|
||||
done
|
||||
if [[ -n "${SHELL:-}" && "${SHELL}" == *zsh* ]]; then
|
||||
rc="${HOME}/.zshrc"
|
||||
else
|
||||
rc="${HOME}/.bashrc"
|
||||
[[ -f "$rc" ]] || rc="${HOME}/.profile"
|
||||
fi
|
||||
printf '\n# Multica CLI\n%s\n' "$line" >>"$rc"
|
||||
warn "Added ${bindir} to PATH in ${rc} (open a new shell, or: source ${rc})"
|
||||
}
|
||||
|
||||
main() {
|
||||
printf '%s\n' "${C_BOLD}Multica${C_RESET} — fork CLI installer (agent-arka support)"
|
||||
command -v curl >/dev/null 2>&1 || die "curl is required"
|
||||
command -v tar >/dev/null 2>&1 || die "tar is required"
|
||||
|
||||
detect_platform
|
||||
|
||||
local version
|
||||
if [[ -n "${MULTICA_VERSION:-}" ]]; then
|
||||
version="${MULTICA_VERSION#v}"
|
||||
version="${version#multica-v}"
|
||||
info "Using pinned version ${version}"
|
||||
else
|
||||
info "Resolving latest Multica release…"
|
||||
version=$(fetch_latest_version)
|
||||
info "Latest: ${version}"
|
||||
fi
|
||||
|
||||
local asset="multica-cli-${version}-${PLATFORM}.tar.gz"
|
||||
local url="${PUBLIC_DL}/${TAG_PREFIX}${version}/${asset}"
|
||||
|
||||
_mc_tmp=$(mktemp -d)
|
||||
info "Downloading ${url} ..."
|
||||
curl -fsSL "$url" -o "$_mc_tmp/multica.tar.gz" || die "Failed to download ${asset}"
|
||||
|
||||
info "Verifying checksum …"
|
||||
local expected actual
|
||||
expected=$(curl -fsSL "${PUBLIC_DL}/${TAG_PREFIX}${version}/checksums.txt" | awk -v a="$asset" '$2==a {print $1; exit}' 2>/dev/null || true)
|
||||
actual=$(sha256_file "$_mc_tmp/multica.tar.gz")
|
||||
if [[ -n "$expected" ]]; then
|
||||
if [[ "$expected" != "$actual" ]]; then
|
||||
die "Checksum mismatch for ${asset}: expected ${expected}, got ${actual}"
|
||||
fi
|
||||
ok "Checksum verified"
|
||||
else
|
||||
warn "No checksum entry for ${asset}; skipping verification"
|
||||
fi
|
||||
|
||||
tar -xzf "$_mc_tmp/multica.tar.gz" -C "$_mc_tmp" multica || die "Failed to extract multica"
|
||||
|
||||
local bindir
|
||||
if [[ -n "${MULTICA_BIN_DIR:-}" ]]; then
|
||||
bindir="${MULTICA_BIN_DIR}"
|
||||
elif [[ -w /usr/local/bin ]]; then
|
||||
bindir="/usr/local/bin"
|
||||
elif command -v sudo >/dev/null 2>&1; then
|
||||
bindir="/usr/local/bin"
|
||||
else
|
||||
bindir="${HOME}/.local/bin"
|
||||
fi
|
||||
mkdir -p "$bindir"
|
||||
|
||||
if [[ ! -w "$bindir" ]]; then
|
||||
sudo mv "$_mc_tmp/multica" "$bindir/multica" || die "Cannot write to ${bindir}"
|
||||
else
|
||||
mv "$_mc_tmp/multica" "$bindir/multica"
|
||||
fi
|
||||
chmod +x "$bindir/multica"
|
||||
ensure_path "$bindir"
|
||||
|
||||
ok "Multica CLI ${version} installed to ${bindir}/multica"
|
||||
rm -rf "$_mc_tmp"; _mc_tmp=""
|
||||
|
||||
printf '\n'
|
||||
printf ' Next — connect to your Multica server:\n'
|
||||
printf ' multica setup self-host\n'
|
||||
printf ' Or for this instance:\n'
|
||||
printf ' multica setup self-host --server-url https://plan.arka-ai.ru --app-url https://plan.arka-ai.ru\n'
|
||||
printf '\n'
|
||||
}
|
||||
|
||||
main "$@"
|
||||
Reference in new issue
Block a user