Claude Code на Windows: фикс зависшего claude update
Коротко
TL;DR: Встроенный claude update на Windows зависает: его HTTP-клиент отваливается по таймауту на загрузке бинарника ~240 МБ (issue #37801). Решение — качать claude.exe напрямую через curl -L -C - с резюмом, сверять SHA256 по официальному манифесту и активировать копией поверх .local\bin\claude.exe.
Практический гайд: как обновить Claude Code (нативная установка) в обход встроенного апдейтера, когда он «висит бесконечно» на загрузке.
Почему встроенный апдейтер зависает
claude update и install.ps1 делают две вещи: читают крошечный файл-метаданные с версией (летит мгновенно) и качают сам бинарник claude.exe — это ~230–240 МБ. На дросселированном/медленном канале мелкие запросы проходят, а большой файл отдаётся по чуть-чуть (десятки–сотни КБ/с). Плюс известный баг апдейтера (anthropics/claude-code issue #37801): его внутренний HTTP-клиент отваливается по таймауту на большой загрузке, хотя прямой curl тянет тот же URL нормально. Итог — «бесконечное» ожидание.
Решение: качать бинарник напрямую через curl с возобновлением, проверять SHA256 по официальному манифесту и активировать вручную.
Структура нативной установки
Версии хранятся как отдельные ~240 МБ exe-файлы:
%USERPROFILE%\.local\share\claude\versions\2.1.167 <- файлы версий
%USERPROFILE%\.local\share\claude\versions\2.1.170
%USERPROFILE%\.local\bin\claude.exe <- активный лаунчер (копия нужной версии)«Активировать версию» = скопировать нужный файл версии поверх ...\.local\bin\claude.exe.
База загрузки (бакет GCS):
https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases.../latestи.../stable-> строка с номером версии.../<версия>/manifest.json-> размеры и SHA256 по платформам.../<версия>/win32-x64/claude.exe-> сам бинарник
Способ 1. Скрипт-обновлятор (рекомендую)
Сохрани как cc-update.ps1 и запускай вместо claude update. Он сам узнаёт свежую версию, качает с резюмом, сверяет чек-сумму и переключает, делая бэкап.
# cc-update.ps1 — надёжное обновление Claude Code в обход встроенного апдейтера
$ErrorActionPreference = "Stop"
$B = "https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases"
$V = "$env:USERPROFILE\.local\share\claude\versions"
$BIN = "$env:USERPROFILE\.local\bin\claude.exe"
# платформа (win32-x64 по умолчанию; arm64 подхватится автоматически)
$plat = if ($env:PROCESSOR_ARCHITECTURE -eq "ARM64") { "win32-arm64" } else { "win32-x64" }
# 1) какая версия свежая и какая стоит
$target = (curl.exe -s --max-time 15 "$B/latest").Trim()
$current = (& $BIN --version 2>$null) -replace "[^\d.]",""
Write-Host "установлено: $current | доступно: $target"
if ($current -eq $target) { Write-Host "уже свежая версия, выходим"; return }
# 2) манифест: ожидаемые размер и SHA256
$info = (curl.exe -s --max-time 15 "$B/$target/manifest.json" | ConvertFrom-Json).platforms.$plat
$expected = $info.checksum.ToLower()
Write-Host "цель: $($info.binary) $($info.size) байт sha256=$expected"
# 3) докачка с резюмом и ретраями (без --max-time, чтобы дотянул на медленном канале)
$partial = "$V\$target.partial"
Write-Host "качаю (резюм включён, можно прерывать и перезапускать)..."
curl.exe -L -C - --retry 8 --retry-delay 3 --retry-all-errors -o $partial "$B/$target/$plat/$($info.binary)"
# 4) проверка целостности
$actual = (Get-FileHash $partial -Algorithm SHA256).Hash.ToLower()
if ($actual -ne $expected) { Write-Host "SHA256 НЕ совпал — файл битый, активацию отменяю"; return }
Write-Host "SHA256 ок"
# 5) активация с бэкапом
Rename-Item $partial "$V\$target" -Force
Copy-Item $BIN "$BIN.bak_$current" -Force
Copy-Item "$V\$target" $BIN -Force
Unblock-File $BIN # снять mark-of-the-web
Write-Host ("ГОТОВО -> " + (& $BIN --version))
Write-Host "бэкап прежней версии: $BIN.bak_$current"Запуск:
powershell -ExecutionPolicy Bypass -File .\cc-update.ps1Закачка медленная (на дросселированном канале это 15–40 минут), но скрипт можно прерывать и запускать снова: curl -C - докачает с места обрыва, а не с нуля.
Способ 2. Вручную, быстро
$B="https://storage.googleapis.com/claude-code-dist-86c565f3-f756-42ad-8dfa-d59b1c096819/claude-code-releases"
$V="$env:USERPROFILE\.local\share\claude\versions"; $BIN="$env:USERPROFILE\.local\bin\claude.exe"
$ver=(curl.exe -s "$B/latest").Trim()
curl.exe -L -C - --retry 8 -o "$V\$ver.partial" "$B/$ver/win32-x64/claude.exe"
# сверить sha256 с (curl.exe -s "$B/$ver/manifest.json" | ConvertFrom-Json).platforms."win32-x64".checksum
Rename-Item "$V\$ver.partial" "$V\$ver" -Force
Copy-Item $BIN "$BIN.bak" -Force; Copy-Item "$V\$ver" $BIN -Force; Unblock-File $BIN
& $BIN --versionОткат
$BIN="$env:USERPROFILE\.local\bin\claude.exe"
Copy-Item "$BIN.bak_2.1.167" $BIN -Force # подставь имя своего бэкапа
& $BIN --versionПодводные камни (важно)
- Пустой
--versionпри запуске файла версии напрямую — это норма, не повреждение. Номер печатает только лаунчер (...\.local\bin\claude.exe), а «голый» файл версии при прямом вызове молчит. Поэтому валидируй закачку по SHA256, а не по выводу--version. Проверяй версию уже после активации, запуская лаунчер. - Mark-of-the-web / SmartScreen. Свежескачанный exe Windows помечает как «из интернета».
Unblock-Fileэто снимает; если первый запуск всё равно подвисает — проверь, не выскочил ли промпт SmartScreen. - Проверь, что качается большой файл. Если
curlмгновенно отдаёт несколько КБ и выходит — ты скачал метаданные, а не бинарник. Размер должен совпасть сsizeиз манифеста (~240 МБ). - Дубли установок. Если ставил и через npm, и нативно — снеси npm-версию (
npm uninstall -g @anthropic-ai/claude-code), иначе PATH подхватит не тот бинарник. - Канал.
latest— самые свежие,stable— задержанные стабильные. Поменяй.../latestна.../stableв скрипте, если хочешь меньше риска.
Гайд проверен на реальном обновлении 2.1.167 -> 2.1.170 (Windows, нативная установка). SHA256 скачанного бинарника сошёлся с официальным манифестом Anthropic.
Пост из Telegram-канала Аи Помогатор