Files
lxs/windows/apps/claude-code.ps1
T

206 lines
7.5 KiB
PowerShell

<#
LXS - Claude Code (Windows)
Description: Install and check the Claude Code CLI.
Two supported install methods, both official:
- winget (Anthropic.ClaudeCode) - does not auto-update
- the native installer from claude.ai - updates itself in the background
Repo: https://git.hyko.cx/hykocx/lxs
#>
# Load LXS common library (colors, UI helpers, spinner, loggers, guards).
# Prefers the sibling ..\lib\common.ps1 (repo checkout or installed layout) and
# only hits the network when this script is run standalone.
$LxsRawBase = if ($env:LXS_RAW_BASE) { $env:LXS_RAW_BASE } else { 'https://git.hyko.cx/hykocx/lxs/raw/branch/main' }
if (-not $env:LXS_RAW_PLATFORM_BASE) { $env:LXS_RAW_PLATFORM_BASE = "$LxsRawBase/windows" }
$LxsLibPath = if ($PSScriptRoot) { Join-Path $PSScriptRoot '..\lib\common.ps1' } else { $null }
if ($LxsLibPath -and (Test-Path $LxsLibPath)) {
. $LxsLibPath
} else {
try {
$LxsLibSource = Invoke-RestMethod -Uri "$env:LXS_RAW_PLATFORM_BASE/lib/common.ps1" -UseBasicParsing -ErrorAction Stop
} catch {
Write-Error 'Failed to fetch lib/common.ps1'
exit 1
}
# The library ships with a UTF-8 BOM (Windows PowerShell 5.1 needs it to
# read the file as UTF-8); over HTTP that BOM arrives as a leading U+FEFF
# character, which the parser will not accept.
. ([scriptblock]::Create(($LxsLibSource -replace '^\uFEFF', '')))
}
$env:LXS_LOG_FILE = Join-Path (Get-LxsTempDir) 'lxs_claude_code.log'
if (-not (Assert-LxsWindows)) { exit 1 }
$LxsClaudeInstallerUrl = 'https://claude.ai/install.ps1'
function Get-LxsClaudeCommand {
return (Get-Command claude -ErrorAction SilentlyContinue)
}
function Show-LxsClaudeStatus {
Clear-Host
Show-LxsBoxTop -Title 'CLAUDE CODE STATUS'
Write-Host ''
$cmd = Get-LxsClaudeCommand
if (-not $cmd) {
Write-Host " $($script:Gray)claude is not on your PATH$($script:NC)"
Write-Host ''
Write-Host "$($script:Gray)If you just installed it, open a new terminal so the PATH change$($script:NC)"
Write-Host "$($script:Gray)takes effect.$($script:NC)"
Write-Host ''
return
}
Write-LxsOk "Found: $($cmd.Source)"
Write-Host ''
& claude --version
Write-Host ''
Show-LxsSeparator
Write-Host ''
Write-LxsInfo 'Running claude doctor (read-only diagnostics)...'
Write-Host ''
& claude doctor
}
function Install-LxsClaudeWinget {
Clear-Host
Show-LxsBoxTop -Title 'INSTALL VIA WINGET'
Write-Host ''
Write-Host 'Installs the Anthropic.ClaudeCode package.'
Write-Host ''
Write-Host "$($script:Gray)winget installs do not update themselves - run option 5, or$($script:NC)"
Write-Host "$($script:Gray)$('winget upgrade Anthropic.ClaudeCode'), to get new versions.$($script:NC)"
Write-Host ''
if (-not (Confirm-LxsAction -Question 'Install Claude Code with winget?' -DefaultYes)) {
Write-LxsInfo 'Cancelled.'
return
}
Write-Host ''
if (Install-LxsWingetPackage -Id 'Anthropic.ClaudeCode' -Name 'Claude Code') {
Write-Host ''
Write-LxsOk 'Open a new terminal, then run: claude'
}
}
function Install-LxsClaudeNative {
Clear-Host
Show-LxsBoxTop -Title 'INSTALL VIA THE NATIVE INSTALLER'
Write-Host ''
Write-Host 'This is the install method Anthropic documents as recommended.'
Write-Host 'It downloads and runs a script from claude.ai:'
Write-Host ''
Write-Host " $($script:White)irm $LxsClaudeInstallerUrl | iex$($script:NC)"
Write-Host ''
Write-Host "$($script:Gray)It installs into your user profile (no admin needed) and keeps$($script:NC)"
Write-Host "$($script:Gray)itself updated in the background.$($script:NC)"
Write-Host ''
if (-not (Confirm-LxsAction -Question 'Download and run that installer now?')) {
Write-LxsInfo 'Cancelled.'
return
}
Write-Host ''
Write-LxsInfo "Fetching $LxsClaudeInstallerUrl..."
try {
$installer = Invoke-RestMethod -Uri $LxsClaudeInstallerUrl -UseBasicParsing -ErrorAction Stop
} catch {
Write-LxsErr "Download failed: $($_.Exception.Message)"
return
}
Write-LxsOk 'Installer downloaded'
Write-Host ''
Show-LxsSeparator
Write-Host ''
try {
& ([scriptblock]::Create($installer))
} catch {
Write-LxsErr "Installer failed: $($_.Exception.Message)"
return
}
Write-Host ''
Show-LxsSeparator
Write-Host ''
Write-LxsOk 'Open a new terminal, then run: claude'
}
function Install-LxsGitForWindows {
Clear-Host
Show-LxsBoxTop -Title 'GIT FOR WINDOWS'
Write-Host ''
Write-Host 'Optional but recommended alongside Claude Code: with Git for Windows'
Write-Host 'installed, Claude Code uses Git Bash for its Bash tool. Without it,'
Write-Host 'it falls back to the PowerShell tool.'
Write-Host ''
if (-not (Confirm-LxsAction -Question 'Install Git for Windows?' -DefaultYes)) {
Write-LxsInfo 'Cancelled.'
return
}
Write-Host ''
Install-LxsWingetPackage -Id 'Git.Git' -Name 'Git for Windows' | Out-Null
}
function Update-LxsClaudeCode {
Clear-Host
Show-LxsBoxTop -Title 'UPDATE CLAUDE CODE'
Write-Host ''
if (-not (Get-LxsClaudeCommand)) {
Write-LxsErr 'claude is not installed (or not on your PATH).'
return
}
# A native install updates itself; a winget install needs winget. Trying
# `claude update` first covers the native case and reports the right thing
# for the winget case.
Write-LxsInfo 'Asking Claude Code to update itself...'
Write-Host ''
& claude update
Write-Host ''
Show-LxsSeparator
Write-Host ''
if ((Test-LxsWinget) -and (Test-LxsPackageInstalled -Id 'Anthropic.ClaudeCode')) {
Write-LxsInfo 'This looks like a winget install; upgrading through winget too...'
Write-Host ''
& winget upgrade --id Anthropic.ClaudeCode --exact --silent `
--accept-package-agreements --accept-source-agreements
Write-Host ''
Write-Host "$($script:Gray)A winget upgrade can fail while Claude Code is running, because$($script:NC)"
Write-Host "$($script:Gray)Windows locks the executable. Close it and retry if that happens.$($script:NC)"
}
}
function Show-LxsClaudeMenu {
while ($true) {
Clear-Host
Show-LxsBoxTop -Title 'CLAUDE CODE'
Write-Host ''
Show-LxsMenuItem '1' 'Show status' 'version + claude doctor'
Show-LxsMenuItem '2' 'Install (native)' 'auto-updating, recommended'
Show-LxsMenuItem '3' 'Install (winget)' 'manual updates'
Show-LxsMenuItem '4' 'Install Git for Windows' 'enables the Bash tool'
Show-LxsMenuItem '5' 'Update Claude Code'
Show-LxsMenuItem '0' 'Back' '' -Exit
Write-Host ''
Show-LxsBoxBottom
Write-Host ''
Write-Host "$($script:Gray) Claude Code needs a Pro, Max, Team, Enterprise or Console account.$($script:NC)"
Write-Host ''
$choice = Read-LxsChoice
Write-Host ''
switch ($choice) {
'1' { Show-LxsClaudeStatus; Read-LxsEnter }
'2' { Install-LxsClaudeNative; Read-LxsEnter }
'3' { Install-LxsClaudeWinget; Read-LxsEnter }
'4' { Install-LxsGitForWindows; Read-LxsEnter }
'5' { Update-LxsClaudeCode; Read-LxsEnter }
'0' { return }
default { Write-LxsErr 'Invalid protocol. Select 0-5.'; Start-Sleep -Seconds 1 }
}
}
}
Show-LxsClaudeMenu
exit 75