param(
[string]$Invite = ""
)
$ErrorActionPreference = "Stop"
if (-not $Invite) {
$Invite = $env:ATOMCODE_INVITE
}
$DefaultVersion = "v4.24.2"
$RepoBase = "https://atomgit.com/atomgit_atomcode/atomcode/releases/download"
$RepoLatestApi = "https://api.atomgit.com/api/v5/repos/atomgit_atomcode/atomcode/releases/latest"
$RealArch = if ($env:PROCESSOR_ARCHITEW6432) {
$env:PROCESSOR_ARCHITEW6432
} else {
$env:PROCESSOR_ARCHITECTURE
}
switch ($RealArch) {
"AMD64" { $ArchTag = "x64" }
"ARM64" { $ArchTag = "arm64" }
default {
Write-Host "Unsupported architecture: $RealArch (supported: AMD64, ARM64)" -ForegroundColor Red
exit 1
}
}
if ($env:ATOMCODE_VERSION) {
$Version = $env:ATOMCODE_VERSION
} else {
Write-Host "==> Detecting latest version"
try {
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$ProgressPreference = 'SilentlyContinue'
$Latest = Invoke-RestMethod -Uri $RepoLatestApi -UseBasicParsing -TimeoutSec 10
$Version = $Latest.tag_name
} catch {
$Version = $null
}
if (-not $Version) { $Version = $DefaultVersion }
}
$BinName = "atomcode-$Version-windows-$ArchTag.exe"
$Url = "$RepoBase/$Version/$BinName"
$Prefix = if ($env:ATOMCODE_PREFIX) {
$env:ATOMCODE_PREFIX
} else {
Join-Path $env:LOCALAPPDATA "AtomCode"
}
if (-not (Test-Path $Prefix)) {
New-Item -ItemType Directory -Path $Prefix -Force | Out-Null
}
if ($Invite) {
if ($Invite -match '^[A-Za-z0-9]{8}$') {
$AtomcodeDir = if ($env:ATOMCODE_HOME) {
$env:ATOMCODE_HOME
} else {
Join-Path $env:USERPROFILE ".atomcode"
}
New-Item -ItemType Directory -Force -Path $AtomcodeDir | Out-Null
$InstallUuid = [guid]::NewGuid().ToString()
$pendingInvite = @"
invite_code=$Invite
install_uuid=$InstallUuid
attempted_at=$([DateTimeOffset]::UtcNow.ToUnixTimeSeconds())
"@
Set-Content -Path (Join-Path $AtomcodeDir "pending_invite") -Value $pendingInvite
} else {
Write-Warning "Invalid invite code format, skipping referral"
}
}
$Dest = Join-Path $Prefix "atomcode.exe"
$TmpFile = Join-Path $env:TEMP "atomcode-download.exe"
Write-Host "==> Downloading $BinName"
Write-Host " from $Url"
try {
[Net.ServicePointManager]::SecurityProtocol = [Net.SecurityProtocolType]::Tls12
$ProgressPreference = 'SilentlyContinue'
Invoke-WebRequest -Uri $Url -OutFile $TmpFile -UseBasicParsing
} catch {
Write-Host "Error: download failed." -ForegroundColor Red
Write-Host " $_" -ForegroundColor Red
Write-Host " URL: $Url" -ForegroundColor Red
exit 1
}
$Header = [System.IO.File]::ReadAllBytes($TmpFile)[0..3]
if ([char]$Header[0] -eq '<') {
Write-Host "Error: download looks like an HTML page, not a binary." -ForegroundColor Red
Write-Host " The release may not exist, or the URL is wrong." -ForegroundColor Red
Write-Host " URL: $Url" -ForegroundColor Red
Remove-Item $TmpFile -Force -ErrorAction SilentlyContinue
exit 1
}
Write-Host "==> Installing to $Dest"
if (Test-Path $Dest) {
try {
Remove-Item $Dest -Force -ErrorAction Stop
} catch {
Write-Host "Error: cannot replace existing $Dest" -ForegroundColor Red
Write-Host " It may be in use. Close any running atomcode.exe and re-run this installer." -ForegroundColor Red
Write-Host " $_" -ForegroundColor Red
Remove-Item $TmpFile -Force -ErrorAction SilentlyContinue
exit 1
}
}
Move-Item -Path $TmpFile -Destination $Dest
$UserPath = [Environment]::GetEnvironmentVariable("Path", "User")
if ($UserPath -notlike "*$Prefix*") {
$NewPath = "$Prefix;$UserPath"
[Environment]::SetEnvironmentVariable("Path", $NewPath, "User")
$env:Path = "$Prefix;$env:Path"
Write-Host ""
Write-Host "Added $Prefix to user PATH." -ForegroundColor Green
Write-Host "New terminal windows will pick it up automatically."
}
Write-Host ""
Write-Host "Installed: $Dest" -ForegroundColor Green
try {
& $Dest --version
} catch {
}
Write-Host ""
Write-Host "Run 'atomcode' to get started." -ForegroundColor Cyan