fix: provision bundled claude runtime in release builds#386
Conversation
There was a problem hiding this comment.
Code Review
This pull request adds support for bundling the claude binary as a sidecar alongside bun and uv, updating the download script, .gitignore, and documentation, while introducing provisioning and live manifest tests. Feedback from the review focuses on preserving the script's offline-friendly and idempotent nature by lazily resolving the Claude version and manifest only when a download is actually required. Additionally, suggestions were made to clean up temporary files created during the download process using unlinkSync.
Important
The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.
| async function ensureClaude(platform, version, manifest) { | ||
| const isWindowsTarget = platform.platformKey.startsWith('win32-') | ||
| const exeExt = isWindowsTarget ? '.exe' : '' | ||
| const destName = `claude-${platform.rustTriple}${exeExt}` | ||
| const destPath = join(BINARIES_DIR, destName) | ||
|
|
||
| if (existsSync(destPath)) { | ||
| console.log(` claude (${platform.platformKey}): already exists at binaries/${destName}, skipping`) | ||
| return | ||
| } | ||
|
|
||
| const claudeKey = platform.claudePlatform | ||
| const expected = manifest.platforms?.[claudeKey]?.checksum | ||
| if (!expected) { | ||
| throw new Error(`claude manifest ${version} has no checksum for platform "${claudeKey}"`) | ||
| } | ||
|
|
||
| const binFile = `claude${exeExt}` | ||
| const url = `${CLAUDE_BASE_URL}/${version}/${claudeKey}/${binFile}` | ||
| const tmpBin = join(tmpdir(), `${destName}-dl-${Date.now()}`) | ||
| console.log(` claude (${platform.platformKey}): downloading ${version}/${claudeKey}...`) | ||
| await download(url, tmpBin) | ||
|
|
||
| const actual = sha256(tmpBin) | ||
| if (actual !== expected) { | ||
| throw new Error(`claude (${claudeKey}) checksum mismatch: expected ${expected}, got ${actual}`) | ||
| } | ||
|
|
||
| copyFileSync(tmpBin, destPath) | ||
| if (!isWindowsTarget) chmodSync(destPath, 0o755) | ||
| console.log(` claude (${platform.platformKey}): installed to binaries/${destName} (verified)`) | ||
| } |
There was a problem hiding this comment.
Currently, the Claude version and manifest are resolved eagerly at the top level. This causes the script to make network requests to downloads.claude.ai even if all sidecar binaries already exist locally, breaking the offline-friendly and idempotent nature of the script.
By lazily resolving the Claude version and manifest inside ensureClaude only when a download is actually required, we can avoid unnecessary network requests and allow offline builds when the binaries are already present. Additionally, we can wrap the download in a try...finally block to ensure the temporary binary file is cleaned up.
let claudeVersion = null
let claudeManifest = null
async function ensureClaude(platform) {
const isWindowsTarget = platform.platformKey.startsWith('win32-')
const exeExt = isWindowsTarget ? '.exe' : ''
const destName = `claude-${platform.rustTriple}${exeExt}`
const destPath = join(BINARIES_DIR, destName)
if (existsSync(destPath)) {
console.log(` claude (${platform.platformKey}): already exists at binaries/${destName}, skipping`)
return
}
if (!claudeVersion) {
step('Resolving claude runtime version')
claudeVersion = await resolveClaudeVersion()
claudeManifest = await fetchClaudeManifest(claudeVersion)
console.log(` claude runtime: ${claudeVersion}`)
}
const claudeKey = platform.claudePlatform
const expected = claudeManifest.platforms?.[claudeKey]?.checksum
if (!expected) {
throw new Error(`claude manifest ${claudeVersion} has no checksum for platform "${claudeKey}"`)
}
const binFile = `claude${exeExt}`
const url = `${CLAUDE_BASE_URL}/${claudeVersion}/${claudeKey}/${binFile}`
const tmpBin = join(tmpdir(), `${destName}-dl-${Date.now()}`)
try {
console.log(` claude (${platform.platformKey}): downloading ${claudeVersion}/${claudeKey}...`)
await download(url, tmpBin)
const actual = sha256(tmpBin)
if (actual !== expected) {
throw new Error(`claude (${claudeKey}) checksum mismatch: expected ${expected}, got ${actual}`)
}
copyFileSync(tmpBin, destPath)
if (!isWindowsTarget) chmodSync(destPath, 0o755)
console.log(` claude (${platform.platformKey}): installed to binaries/${destName} (verified)`)
} finally {
try {
if (existsSync(tmpBin)) unlinkSync(tmpBin)
} catch {}
}
}| step('Resolving claude runtime version') | ||
| const claudeVersion = await resolveClaudeVersion() | ||
| const claudeManifest = await fetchClaudeManifest(claudeVersion) | ||
| console.log(` claude runtime: ${claudeVersion}`) |
| archive: platform.uvArchive, | ||
| binaryName: 'uv', | ||
| }) | ||
| await ensureClaude(platform, claudeVersion, claudeManifest) |
| */ | ||
|
|
||
| import { existsSync, chmodSync, mkdirSync, copyFileSync } from 'node:fs' | ||
| import { existsSync, chmodSync, mkdirSync, copyFileSync, readFileSync } from 'node:fs' |
| async function downloadText(url, label) { | ||
| const tmp = join(tmpdir(), `claude-${label}-${Date.now()}`) | ||
| await download(url, tmp) | ||
| return readFileSync(tmp, 'utf8') | ||
| } |
There was a problem hiding this comment.
Clean up the temporary file created during the download of text files (like the version pointer or manifest) to avoid cluttering the system's temp directory.
async function downloadText(url, label) {
const tmp = join(tmpdir(), `claude-${label}-${Date.now()}`)
try {
await download(url, tmp)
return readFileSync(tmp, 'utf8')
} finally {
try {
if (existsSync(tmp)) unlinkSync(tmp)
} catch {}
}
}
No description provided.