🎩 You're Invited:Meet the Socket team at Black Hat in Las Vegas, August 3-6.RSVP
Sign In

freebuff

Package Overview
Dependencies
Maintainers
3
Versions
98
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

freebuff - npm Package Compare versions

Comparing version
0.0.122
to
0.0.123
+1211
launcher.js
#!/usr/bin/env node
const { spawn, execFileSync } = require('child_process')
const fs = require('fs')
const http = require('http')
const https = require('https')
const os = require('os')
const path = require('path')
const { pipeline } = require('stream/promises')
const zlib = require('zlib')
const tar = require('tar')
const { createReleaseHttpClient } = require('./http')
function createLauncher(productConfig) {
const {
packageName,
displayName,
includeTreeSitterWasm = true,
startupBanner = [],
telemetryEvent = 'cli.update_codebuff_failed',
telemetryProperties = {},
tempDownloadDirName = `.${packageName}-download-temp`,
} = productConfig
/**
* Terminal escape sequences to reset terminal state after the child process exits.
* When the binary is SIGKILL'd, it can't clean up its own terminal state.
* The wrapper (this process) survives and must reset these modes.
*/
const EXIT_ALTERNATE_SCREEN_SEQUENCE = '\x1b[?1049l'
const SAFE_TERMINAL_RESET_SEQUENCES =
'\x1b[?1000l' + // Disable X10 mouse mode
'\x1b[?1002l' + // Disable button event mouse mode
'\x1b[?1003l' + // Disable any-event mouse mode (all motion)
'\x1b[?1006l' + // Disable SGR extended mouse mode
'\x1b[?1004l' + // Disable focus reporting
'\x1b[?2004l' + // Disable bracketed paste mode
'\x1b[<u' + // Pop kitty keyboard protocol flags
'\x1b[>4;0m' + // Reset modifyOtherKeys
'\x1b[?25h' // Show cursor
const FULL_TERMINAL_RESET_SEQUENCES =
EXIT_ALTERNATE_SCREEN_SEQUENCE + SAFE_TERMINAL_RESET_SEQUENCES
function resetTerminal(options = {}) {
const { exitAlternateScreen = false } = options
try {
if (process.stdin.isTTY && process.stdin.setRawMode) {
process.stdin.setRawMode(false)
}
} catch {
// stdin may be closed
}
try {
if (process.stdout.isTTY) {
// Exiting the alternate screen is only safe after an interactive child.
// Plain CLI paths like --help never enter it, and ?1049l can erase output.
process.stdout.write(
exitAlternateScreen
? FULL_TERMINAL_RESET_SEQUENCES
: SAFE_TERMINAL_RESET_SEQUENCES,
)
}
} catch {
// stdout may be closed
}
}
function getUnsignedExitCode(code) {
return code != null && code < 0 ? code >>> 0 : code
}
function isWindowsNativeCrashCode(code) {
const unsignedCode = getUnsignedExitCode(code)
return (
process.platform === 'win32' &&
(unsignedCode === 0xc000001d ||
unsignedCode === 0xc0000005 ||
unsignedCode === 0xc0000409)
)
}
function shouldExitAlternateScreen(code, signal) {
return Boolean(signal) || isWindowsNativeCrashCode(code)
}
function isIllegalInstructionExit(code, signal) {
const unsignedCode = getUnsignedExitCode(code)
return (
signal === 'SIGILL' ||
(process.platform === 'win32' && unsignedCode === 0xc000001d)
)
}
function createConfig(packageName) {
const homeDir = os.homedir()
const configDir = path.join(homeDir, '.config', 'manicode')
const binaryName =
process.platform === 'win32' ? `${packageName}.exe` : packageName
return {
homeDir,
configDir,
binaryName,
binaryPath: path.join(configDir, binaryName),
metadataPath: path.join(configDir, `${packageName}-metadata.json`),
tempDownloadDir: path.join(configDir, tempDownloadDirName),
userAgent: `${packageName}-cli`,
requestTimeout: 20000,
downloadRequestTimeout: 120000,
downloadMaxAttempts: 3,
}
}
const CONFIG = createConfig(packageName)
const { downloadFile, httpGet, withRetries } = createReleaseHttpClient({
env: process.env,
userAgent: CONFIG.userAgent,
requestTimeout: CONFIG.requestTimeout,
})
function getPostHogConfig() {
const apiKey =
process.env.CODEBUFF_POSTHOG_API_KEY ||
process.env.NEXT_PUBLIC_POSTHOG_API_KEY
const host =
process.env.CODEBUFF_POSTHOG_HOST ||
process.env.NEXT_PUBLIC_POSTHOG_HOST_URL
if (!apiKey || !host) {
return null
}
return { apiKey, host }
}
/**
* Track update failure event to PostHog.
* Fire-and-forget - errors are silently ignored.
*/
function trackUpdateFailed(errorMessage, version, context = {}) {
try {
const posthogConfig = getPostHogConfig()
if (!posthogConfig) {
return
}
const payload = JSON.stringify({
api_key: posthogConfig.apiKey,
event: telemetryEvent,
properties: {
distinct_id: `anonymous-${CONFIG.homeDir}`,
error: errorMessage,
version: version || 'unknown',
platform: process.platform,
arch: process.arch,
...telemetryProperties,
...context,
},
timestamp: new Date().toISOString(),
})
const parsedUrl = new URL(`${posthogConfig.host}/capture/`)
const isHttps = parsedUrl.protocol === 'https:'
const options = {
hostname: parsedUrl.hostname,
port: parsedUrl.port || (isHttps ? 443 : 80),
path: parsedUrl.pathname + parsedUrl.search,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(payload),
},
}
const transport = isHttps ? https : http
const req = transport.request(options)
req.on('error', () => {}) // Silently ignore errors
req.write(payload)
req.end()
} catch (e) {
// Silently ignore any tracking errors
}
}
const PLATFORM_TARGETS = {
'linux-x64': `${packageName}-linux-x64.tar.gz`,
'linux-x64-baseline': `${packageName}-linux-x64-baseline.tar.gz`,
'linux-arm64': `${packageName}-linux-arm64.tar.gz`,
'darwin-x64': `${packageName}-darwin-x64.tar.gz`,
'darwin-arm64': `${packageName}-darwin-arm64.tar.gz`,
'win32-x64': `${packageName}-win32-x64.tar.gz`,
'win32-x64-baseline': `${packageName}-win32-x64-baseline.tar.gz`,
}
const BASELINE_FALLBACK_TARGETS = {
'linux-x64': 'linux-x64-baseline',
'win32-x64': 'win32-x64-baseline',
}
const term = {
clearLine: () => {
if (process.stderr.isTTY) {
process.stderr.write('\r\x1b[K')
}
},
write: (text) => {
term.clearLine()
process.stderr.write(text)
},
writeLine: (text) => {
term.clearLine()
process.stderr.write(text + '\n')
},
}
function getPlatformKey() {
return `${process.platform}-${process.arch}`
}
function getTargetOverride() {
const envNames = [
`${packageName.toUpperCase()}_BINARY_TARGET`,
'CODEBUFF_BINARY_TARGET',
'CLI_BINARY_TARGET',
]
for (const envName of envNames) {
const target = process.env[envName]
if (target && PLATFORM_TARGETS[target]) {
return target
}
}
return null
}
function linuxCpuHasAvx2() {
try {
return /\bavx2\b/i.test(fs.readFileSync('/proc/cpuinfo', 'utf8'))
} catch {
return true
}
}
// Returns true (AVX2 present), false (absent), or null (couldn't determine).
// Ask the OS directly via IsProcessorFeaturePresent (kernel32), which is
// backed by CPUID — far more reliable than matching CPU model names, and it
// works on the stock Windows PowerShell that ships with every supported
// Windows version. Feature 40 = PF_AVX2_INSTRUCTIONS_AVAILABLE.
function probeWindowsAvx2() {
const script =
'$f = Add-Type -MemberDefinition \'[DllImport("kernel32.dll")] ' +
"public static extern bool IsProcessorFeaturePresent(uint feature);' " +
'-Name Cpu -Namespace Win32 -PassThru; $f::IsProcessorFeaturePresent(40)'
try {
const out = execFileSync(
'powershell.exe',
['-NoProfile', '-NonInteractive', '-Command', script],
{
encoding: 'utf8',
timeout: 5000,
stdio: ['ignore', 'pipe', 'ignore'],
},
).trim()
if (out === 'True') return true
if (out === 'False') return false
return null
} catch {
// No PowerShell, locked-down policy, timeout, etc. — inconclusive.
return null
}
}
let _hasAvx2Cache
function machineHasAvx2() {
if (_hasAvx2Cache === undefined) {
_hasAvx2Cache = detectMachineHasAvx2()
}
return _hasAvx2Cache
}
function detectMachineHasAvx2() {
if (process.arch !== 'x64') {
return true
}
// Linux detection is a cheap file read, so we don't bother persisting it.
if (process.platform === 'linux') {
return linuxCpuHasAvx2()
}
if (process.platform !== 'win32') {
return true
}
// Windows detection shells out to PowerShell. getDefaultTargetKey runs on
// every launch (via the version check), so cache the result on disk to keep
// startup fast after the first probe.
const cached = readCachedAvx2()
if (cached !== null) {
return cached
}
const detected = probeWindowsAvx2()
if (detected === null) {
// Inconclusive probe: assume AVX2 for this launch and rely on the SIGILL
// fallback, but don't persist it — a transient failure must not lock in a
// wrong answer for the lifetime of the install. We'll re-probe next launch.
return true
}
writeCachedAvx2(detected)
return detected
}
function getCpuFeatureCachePath() {
return path.join(CONFIG.configDir, 'cpu-features.json')
}
function readCachedAvx2() {
try {
const cache = JSON.parse(
fs.readFileSync(getCpuFeatureCachePath(), 'utf8'),
)
return typeof cache.avx2 === 'boolean' ? cache.avx2 : null
} catch {
return null
}
}
function writeCachedAvx2(value) {
try {
fs.mkdirSync(CONFIG.configDir, { recursive: true })
fs.writeFileSync(
getCpuFeatureCachePath(),
JSON.stringify({ avx2: value }),
)
} catch {
// Best effort; we'll just re-probe next launch.
}
}
function getDefaultTargetKey() {
const override = getTargetOverride()
if (override) {
return override
}
const platformKey = getPlatformKey()
// Select the binary up front from explicit CPU feature detection rather than
// optimistically launching the AVX2 build and waiting for it to crash with
// an illegal instruction. The crash isn't always a clean immediate failure —
// it can surface later from a deeper code path — so older CPUs (e.g. an
// Intel Xeon with AVX but no AVX2) are safer on baseline from the start.
//
// This assumes every baseline target is gated on AVX2 specifically, which
// holds today (only linux-x64 and win32-x64 have baseline builds, both
// AVX2-gated). If a baseline build is ever added for a different reason, give
// BASELINE_FALLBACK_TARGETS a per-target capability and check that instead.
if (BASELINE_FALLBACK_TARGETS[platformKey] && !machineHasAvx2()) {
return BASELINE_FALLBACK_TARGETS[platformKey]
}
return platformKey
}
function getBaselineFallbackTargetKey() {
// Runtime safety net: if proactive detection was unavailable or wrong and the
// optimized binary still dies with SIGILL, fall back to baseline.
return BASELINE_FALLBACK_TARGETS[getPlatformKey()] || null
}
function isTargetAllowedForThisMachine(target) {
const override = getTargetOverride()
if (override) {
return target === override
}
// Check the baseline fallback first: it's always safe on its platform and
// avoids running CPU detection when a baseline binary is already installed.
return (
target === getBaselineFallbackTargetKey() ||
target === getDefaultTargetKey()
)
}
function getDownloadTargetKey() {
const override = getTargetOverride()
if (override) {
return override
}
const metadata = getCurrentMetadata()
if (metadata?.target && isTargetAllowedForThisMachine(metadata.target)) {
return metadata.target
}
return getDefaultTargetKey()
}
async function getLatestVersion() {
try {
const res = await httpGet(
`https://registry.npmjs.org/${packageName}/latest`,
)
if (res.statusCode !== 200) return null
const body = await streamToString(res)
const packageData = JSON.parse(body)
return packageData.version || null
} catch (error) {
return null
}
}
function streamToString(stream) {
return new Promise((resolve, reject) => {
let data = ''
stream.on('data', (chunk) => (data += chunk))
stream.on('end', () => resolve(data))
stream.on('error', reject)
})
}
function getCurrentVersion() {
try {
const metadata = getCurrentMetadata()
if (!metadata) {
return null
}
// Also verify the binary still exists
if (!fs.existsSync(CONFIG.binaryPath)) {
return null
}
const metadataTarget = metadata.target || getPlatformKey()
if (!isTargetAllowedForThisMachine(metadataTarget)) {
return null
}
return metadata.version || null
} catch (error) {
return null
}
}
function getCurrentMetadata() {
try {
if (!fs.existsSync(CONFIG.metadataPath)) {
return null
}
return JSON.parse(fs.readFileSync(CONFIG.metadataPath, 'utf8'))
} catch {
return null
}
}
function compareVersions(v1, v2) {
if (!v1 || !v2) return 0
// Always update if the current version is not a valid semver
// e.g. 1.0.420-beta.1
if (!v1.match(/^\d+(\.\d+)*$/)) {
return -1
}
const parseVersion = (version) => {
const parts = version.split('-')
const mainParts = parts[0].split('.').map(Number)
const prereleaseParts = parts[1] ? parts[1].split('.') : []
return { main: mainParts, prerelease: prereleaseParts }
}
const p1 = parseVersion(v1)
const p2 = parseVersion(v2)
for (let i = 0; i < Math.max(p1.main.length, p2.main.length); i++) {
const n1 = p1.main[i] || 0
const n2 = p2.main[i] || 0
if (n1 < n2) return -1
if (n1 > n2) return 1
}
if (p1.prerelease.length === 0 && p2.prerelease.length === 0) {
return 0
} else if (p1.prerelease.length === 0) {
return 1
} else if (p2.prerelease.length === 0) {
return -1
} else {
for (
let i = 0;
i < Math.max(p1.prerelease.length, p2.prerelease.length);
i++
) {
const pr1 = p1.prerelease[i] || ''
const pr2 = p2.prerelease[i] || ''
const isNum1 = !isNaN(parseInt(pr1))
const isNum2 = !isNaN(parseInt(pr2))
if (isNum1 && isNum2) {
const num1 = parseInt(pr1)
const num2 = parseInt(pr2)
if (num1 < num2) return -1
if (num1 > num2) return 1
} else if (isNum1 && !isNum2) {
return 1
} else if (!isNum1 && isNum2) {
return -1
} else if (pr1 < pr2) {
return -1
} else if (pr1 > pr2) {
return 1
}
}
return 0
}
}
function formatBytes(bytes) {
if (bytes === 0) return '0 B'
const k = 1024
const sizes = ['B', 'KB', 'MB', 'GB']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]
}
function createProgressBar(percentage, width = 30) {
const filled = Math.round((width * percentage) / 100)
const empty = width - filled
return '[' + '█'.repeat(filled) + '░'.repeat(empty) + ']'
}
function isRetryableDownloadError(error) {
if (error && typeof error.retryable === 'boolean') return error.retryable
return !['EACCES', 'ENOSPC', 'EPERM', 'EROFS'].includes(error?.code)
}
function getPartialArchivePath(version, targetKey) {
return path.join(
CONFIG.configDir,
`.${packageName}-${version}-${targetKey}.tar.gz.part`,
)
}
function getFileSize(filePath) {
try {
return fs.statSync(filePath).size
} catch (error) {
if (error.code === 'ENOENT') return 0
throw error
}
}
function removeFileIfPresent(filePath) {
try {
fs.unlinkSync(filePath)
} catch (error) {
if (error.code !== 'ENOENT') throw error
}
}
function formatDownloadSource(downloadUrl) {
try {
const parsedUrl = new URL(downloadUrl)
return `${parsedUrl.origin}${parsedUrl.pathname}`
} catch {
return downloadUrl
}
}
function printDownloadFailure(error) {
const code = error.code ? ` (${error.code})` : ''
console.error(
`❌ Failed to download ${packageName}: ${error.message}${code}`,
)
if (error.requestUrl) {
console.error(
`Download source: ${formatDownloadSource(error.requestUrl)}`,
)
}
if (error.downloadedBytes > 0) {
const total = error.totalBytes
? ` of ${formatBytes(error.totalBytes)}`
: ''
console.error(
`Saved ${formatBytes(error.downloadedBytes)}${total}; the next run will resume this download.`,
)
} else if (error.requestUrl) {
console.error(
'Please retry. The release host may be temporarily unavailable.',
)
} else {
console.error(
'The downloaded update could not be installed; the existing binary was preserved when possible.',
)
}
}
function prepareTempDownloadDir() {
if (fs.existsSync(CONFIG.tempDownloadDir)) {
fs.rmSync(CONFIG.tempDownloadDir, { recursive: true })
}
fs.mkdirSync(CONFIG.tempDownloadDir, { recursive: true })
}
async function downloadAndExtract(
downloadUrl,
version,
targetKey,
{ quiet = false } = {},
) {
let attempts = 0
const partialArchivePath = getPartialArchivePath(version, targetKey)
let totalBytes = null
try {
return await withRetries(
async (attempt) => {
attempts = attempt
prepareTempDownloadDir()
if (!quiet) term.write('Downloading...')
let lastProgressTime = Date.now()
const result = await downloadFile(downloadUrl, partialArchivePath, {
timeout: CONFIG.downloadRequestTimeout,
onProgress: ({ downloadedBytes, totalBytes: progressTotal }) => {
totalBytes = progressTotal
if (quiet) return
const now = Date.now()
if (
now - lastProgressTime < 100 &&
downloadedBytes !== progressTotal
) {
return
}
lastProgressTime = now
if (progressTotal) {
const pct = Math.round((downloadedBytes / progressTotal) * 100)
term.write(
`Downloading... ${createProgressBar(pct)} ${pct}% of ${formatBytes(progressTotal)}`,
)
} else {
term.write(`Downloading... ${formatBytes(downloadedBytes)}`)
}
},
})
totalBytes = result.totalBytes
try {
await pipeline(
fs.createReadStream(partialArchivePath),
zlib.createGunzip(),
tar.x({ cwd: CONFIG.tempDownloadDir }),
)
} catch (error) {
// A complete archive that cannot be extracted is corrupt. Do not
// resume it on the next attempt.
removeFileIfPresent(partialArchivePath)
throw error
}
const tempBinaryPath = path.join(
CONFIG.tempDownloadDir,
CONFIG.binaryName,
)
if (!fs.existsSync(tempBinaryPath)) {
const files = fs.readdirSync(CONFIG.tempDownloadDir)
removeFileIfPresent(partialArchivePath)
const error = new Error(
`Binary not found after extraction. Expected: ${CONFIG.binaryName}, Available files: ${files.join(', ')}`,
)
error.retryable = false
throw error
}
removeFileIfPresent(partialArchivePath)
return tempBinaryPath
},
{
maxAttempts: CONFIG.downloadMaxAttempts,
shouldRetry: isRetryableDownloadError,
onRetry: ({ nextAttempt, delayMs }) => {
if (quiet) return
term.writeLine(
`Download interrupted. Retrying in ${delayMs / 1000}s (${nextAttempt}/${CONFIG.downloadMaxAttempts})...`,
)
},
},
)
} catch (error) {
try {
fs.rmSync(CONFIG.tempDownloadDir, { recursive: true, force: true })
} catch {
// Best effort after a failed download.
}
trackUpdateFailed(error.message, version, {
stage: 'download',
errorCode: error.code,
statusCode: error.statusCode,
target: targetKey,
attempts,
bytesDownloaded: getFileSize(partialArchivePath),
totalBytes: error.totalBytes || totalBytes,
})
error.downloadedBytes = getFileSize(partialArchivePath)
error.totalBytes ||= totalBytes
error.requestUrl ||= downloadUrl
throw error
}
}
async function stageBinary(
version,
targetKey = getDownloadTargetKey(),
options = {},
) {
const fileName = PLATFORM_TARGETS[targetKey]
if (!fileName) {
const error = new Error(
`Unsupported platform: ${process.platform} ${process.arch}`,
)
trackUpdateFailed(error.message, version, {
stage: 'platform_check',
target: targetKey,
})
throw error
}
const downloadUrl = `${
process.env.NEXT_PUBLIC_CODEBUFF_APP_URL || 'https://codebuff.com'
}/api/releases/download/${version}/${fileName}`
fs.mkdirSync(CONFIG.configDir, { recursive: true })
const tempBinaryPath = await downloadAndExtract(
downloadUrl,
version,
targetKey,
options,
)
try {
if (process.platform !== 'win32') {
fs.chmodSync(tempBinaryPath, 0o755)
}
} catch (error) {
try {
fs.rmSync(CONFIG.tempDownloadDir, { recursive: true, force: true })
} catch {
// Preserve the original chmod error.
}
throw error
}
return { tempBinaryPath, version, targetKey }
}
function replaceFileWithRollback(sourcePath, targetPath, replacements) {
const backupPath = fs.existsSync(targetPath)
? `${targetPath}.old.${Date.now()}.${replacements.length}`
: null
if (backupPath) {
fs.renameSync(targetPath, backupPath)
}
try {
fs.renameSync(sourcePath, targetPath)
} catch (error) {
if (backupPath && fs.existsSync(backupPath)) {
fs.renameSync(backupPath, targetPath)
}
throw error
}
replacements.push({ backupPath, targetPath })
}
function rollbackReplacements(replacements) {
for (const { backupPath, targetPath } of replacements.reverse()) {
removeFileIfPresent(targetPath)
if (backupPath && fs.existsSync(backupPath)) {
fs.renameSync(backupPath, targetPath)
}
}
}
function commitReplacements(replacements) {
for (const { backupPath } of replacements) {
if (!backupPath) continue
try {
removeFileIfPresent(backupPath)
} catch {
// The replacement is already committed. A stale backup is safer than
// rolling back a working install because cleanup failed.
}
}
}
function installStagedBinary({ tempBinaryPath, version, targetKey }) {
const replacements = []
const metadataTempPath = `${CONFIG.metadataPath}.new.${process.pid}`
try {
fs.writeFileSync(
metadataTempPath,
JSON.stringify({ version, target: targetKey }, null, 2),
)
replaceFileWithRollback(tempBinaryPath, CONFIG.binaryPath, replacements)
// Move tree-sitter.wasm next to the binary if the tarball included
// it. The CLI binary loads this at startup; embedding it inside the
// binary itself was unreliable on Windows (bun --compile asset
// bundling silently dropped or unbound it across several attempts),
// so we ship it as a sibling file instead. Older artifacts that
// pre-date this change won't have the wasm and will still install —
// they'll just hit the same crash they had before, which is fine.
if (includeTreeSitterWasm) {
const tempWasmPath = path.join(
CONFIG.tempDownloadDir,
'tree-sitter.wasm',
)
if (fs.existsSync(tempWasmPath)) {
const targetWasmPath = path.join(
path.dirname(CONFIG.binaryPath),
'tree-sitter.wasm',
)
replaceFileWithRollback(tempWasmPath, targetWasmPath, replacements)
}
}
replaceFileWithRollback(
metadataTempPath,
CONFIG.metadataPath,
replacements,
)
commitReplacements(replacements)
} catch (error) {
rollbackReplacements(replacements)
throw error
} finally {
removeFileIfPresent(metadataTempPath)
if (fs.existsSync(CONFIG.tempDownloadDir)) {
fs.rmSync(CONFIG.tempDownloadDir, { recursive: true })
}
}
term.clearLine()
console.log(`Download complete! Starting ${displayName}...`)
}
async function downloadBinary(version, targetKey = getDownloadTargetKey()) {
const stagedBinary = await stageBinary(version, targetKey)
installStagedBinary(stagedBinary)
}
async function ensureBinaryExists() {
const currentVersion = getCurrentVersion()
if (currentVersion !== null) {
return
}
const version = await getLatestVersion()
if (!version) {
console.error('❌ Failed to determine latest version')
console.error('Please check your internet connection and try again')
process.exit(1)
}
try {
await downloadBinary(version)
} catch (error) {
term.clearLine()
printDownloadFailure(error)
process.exit(1)
}
}
function stopRunningProcess(runningProcess) {
return new Promise((resolve, reject) => {
let forceKillTimer
let forceKillTimeout
const cleanup = () => {
clearTimeout(forceKillTimer)
clearTimeout(forceKillTimeout)
runningProcess.removeListener('exit', handleExit)
}
const handleExit = () => {
cleanup()
resolve()
}
const fail = (error) => {
cleanup()
reject(error)
}
runningProcess.once('exit', handleExit)
forceKillTimer = setTimeout(() => {
forceKillTimeout = setTimeout(() => {
fail(new Error(`${packageName} did not exit after SIGKILL`))
}, 1000)
try {
runningProcess.kill('SIGKILL')
} catch (error) {
fail(error)
}
}, 5000)
try {
runningProcess.kill('SIGTERM')
} catch (error) {
fail(error)
}
})
}
async function checkForUpdates(runningProcess, exitListener) {
let stoppedForUpdate = false
try {
const currentVersion = getCurrentVersion()
const latestVersion = await getLatestVersion()
if (!latestVersion) return
if (
// Download new version if current version is unknown or outdated.
currentVersion === null ||
compareVersions(currentVersion, latestVersion) < 0
) {
const stagedBinary = await stageBinary(
latestVersion,
getDownloadTargetKey(),
{ quiet: true },
)
term.clearLine()
runningProcess.removeListener('exit', exitListener)
try {
await stopRunningProcess(runningProcess)
} catch (error) {
runningProcess.on('exit', exitListener)
throw error
}
stoppedForUpdate = true
resetTerminal({ exitAlternateScreen: true })
console.log(`Update available: ${currentVersion} → ${latestVersion}`)
installStagedBinary(stagedBinary)
const newChild = spawnInstalledBinary({ detached: false })
attachExitHandler(newChild)
return new Promise(() => {})
}
} catch (error) {
if (stoppedForUpdate && fs.existsSync(CONFIG.binaryPath)) {
console.error(
`Update failed; restarting ${packageName} ${getCurrentVersion()}.`,
)
const child = spawnInstalledBinary({ detached: false })
attachExitHandler(child)
return new Promise(() => {})
}
try {
fs.rmSync(CONFIG.tempDownloadDir, { recursive: true, force: true })
} catch {
// Best effort after a failed background update.
}
// A staging failure leaves the current process and binary untouched.
}
}
function printCrashDiagnostics(code, signal) {
// Windows NTSTATUS codes (unsigned DWORD)
const unsignedCode = getUnsignedExitCode(code)
const isIllegalInstruction = isIllegalInstructionExit(code, signal)
const isAccessViolation =
signal === 'SIGSEGV' ||
(process.platform === 'win32' && unsignedCode === 0xc0000005)
const isBusError = signal === 'SIGBUS'
const isAbort =
signal === 'SIGABRT' ||
(process.platform === 'win32' && unsignedCode === 0xc0000409)
if (!isIllegalInstruction && !isAccessViolation && !isBusError && !isAbort)
return
const exitInfo = signal ? `signal ${signal}` : `code ${code}`
console.error('')
console.error(`❌ ${packageName} exited immediately (${exitInfo})`)
console.error('')
if (isIllegalInstruction) {
console.error(
'Your CPU may not support the required instruction set (AVX2).',
)
console.error('This typically affects CPUs from before 2013.')
console.error('')
printBaselineOverrideHint()
} else if (isAccessViolation) {
console.error('The binary crashed with an access violation.')
console.error('')
} else if (isBusError) {
console.error('The binary crashed with a bus error.')
console.error('This may indicate a platform compatibility issue.')
console.error('')
} else if (isAbort) {
console.error('The binary crashed with an abort signal.')
console.error('')
}
printSystemInfo()
console.error('')
console.error('Please report this issue at:')
console.error(' https://github.com/CodebuffAI/codebuff/issues')
console.error('')
}
function printBaselineOverrideHint() {
const fallbackTarget = getBaselineFallbackTargetKey()
if (!fallbackTarget) return
console.error('To force the baseline (non-AVX2) build, set:')
console.error(
` ${packageName.toUpperCase()}_BINARY_TARGET=${fallbackTarget}`,
)
console.error('')
}
function printSystemInfo() {
const metadata = getCurrentMetadata()
console.error('System info:')
console.error(` Platform: ${process.platform} ${process.arch}`)
console.error(` Node: ${process.version}`)
if (process.arch === 'x64') {
console.error(` AVX2: ${machineHasAvx2() ? 'yes' : 'no'}`)
}
console.error(` Target: ${metadata?.target || getDefaultTargetKey()}`)
console.error(` Binary: ${CONFIG.binaryPath}`)
}
function getInstalledBinaryStatus() {
try {
const stats = fs.statSync(CONFIG.binaryPath)
return stats.isFile() ? `yes (${formatBytes(stats.size)})` : 'no'
} catch {
return 'no'
}
}
function printSpawnFailure(err) {
resetTerminal()
const code = err && err.code ? ` (${err.code})` : ''
console.error(`Failed to start ${packageName}: ${err.message}${code}`)
console.error('')
printSystemInfo()
console.error(` Exists: ${getInstalledBinaryStatus()}`)
if (process.platform === 'win32') {
console.error('')
console.error(
'On Windows, this can happen when Windows Security or antivirus blocks',
)
console.error(
'or quarantines the downloaded executable, or when the binary requires',
)
console.error('CPU instructions that are not available on this machine.')
console.error('')
printBaselineOverrideHint()
}
console.error('')
console.error('Try deleting the downloaded files and running again:')
console.error(` ${CONFIG.configDir}`)
console.error('')
}
function exitOnSpawnFailure(err) {
printSpawnFailure(err)
process.exit(1)
}
function spawnInstalledBinary(options = {}) {
if (!fs.existsSync(CONFIG.binaryPath)) {
try {
if (fs.existsSync(CONFIG.metadataPath))
fs.unlinkSync(CONFIG.metadataPath)
} catch {
// best effort
}
const error = new Error(
`downloaded binary is missing at ${CONFIG.binaryPath}`,
)
error.code = 'BINARY_MISSING'
exitOnSpawnFailure(error)
}
// spawn() only emits 'error' asynchronously for a few errno values
// (EACCES, EAGAIN, EMFILE, ENFILE, ENOENT); everything else — notably
// UNKNOWN on Windows when antivirus or Smart App Control blocks the
// exe or the download is corrupt — is thrown synchronously.
let child
try {
child = spawn(CONFIG.binaryPath, process.argv.slice(2), {
stdio: 'inherit',
...options,
})
} catch (err) {
exitOnSpawnFailure(err)
}
child.on('error', exitOnSpawnFailure)
return child
}
async function tryFallbackToBaseline(code, signal) {
if (!isIllegalInstructionExit(code, signal)) {
return false
}
const fallbackTarget = getBaselineFallbackTargetKey()
if (!fallbackTarget) {
return false
}
const metadata = getCurrentMetadata()
const currentTarget = metadata?.target || getDefaultTargetKey()
if (currentTarget === fallbackTarget) {
return false
}
const version = metadata?.version || (await getLatestVersion())
if (!version) {
return false
}
resetTerminal({
exitAlternateScreen: shouldExitAlternateScreen(code, signal),
})
console.error('')
console.error(
`${packageName} is switching to the older-CPU binary for this machine.`,
)
try {
await downloadBinary(version, fallbackTarget)
} catch (error) {
term.clearLine()
console.error(`Failed to download ${fallbackTarget}: ${error.message}`)
return false
}
const child = spawnInstalledBinary({ detached: false })
attachExitHandler(child, false)
return true
}
function attachExitHandler(child, allowBaselineFallback = true) {
const exitListener = async (code, signal) => {
if (
allowBaselineFallback &&
(await tryFallbackToBaseline(code, signal))
) {
return
}
resetTerminal({
exitAlternateScreen: shouldExitAlternateScreen(code, signal),
})
printCrashDiagnostics(code, signal)
process.exit(signal ? 1 : code || 0)
}
child.on('exit', exitListener)
return exitListener
}
async function main() {
for (const line of startupBanner) {
console.log(line)
}
if (startupBanner.length > 0) console.log('')
await ensureBinaryExists()
const child = spawnInstalledBinary()
const exitListener = attachExitHandler(child)
setTimeout(() => {
checkForUpdates(child, exitListener)
}, 100)
}
return {
config: productConfig,
main,
stopRunningProcess,
}
}
module.exports = { createLauncher }
+231
-10
const http = require('http')
const https = require('https')
const fs = require('fs')
const { pipeline } = require('stream/promises')
const tls = require('tls')

@@ -11,5 +13,16 @@

httpsModule = https,
fsModule = fs,
pipelineFn = pipeline,
tlsModule = tls,
}) {
function getProxyUrl() {
function getProxyUrl(protocol = 'https:') {
if (protocol === 'http:') {
return (
env.HTTP_PROXY ||
env.http_proxy ||
env.HTTPS_PROXY ||
env.https_proxy ||
null
)
}
return (

@@ -91,7 +104,11 @@ env.HTTPS_PROXY ||

async function buildRequestOptions(url, options = {}) {
async function buildRequest(url, options = {}) {
const parsedUrl = new URL(url)
if (!['http:', 'https:'].includes(parsedUrl.protocol)) {
throw new Error(`Unsupported URL protocol: ${parsedUrl.protocol}`)
}
const isHttps = parsedUrl.protocol === 'https:'
const reqOptions = {
hostname: parsedUrl.hostname,
port: parsedUrl.port || 443,
port: parsedUrl.port || (isHttps ? 443 : 80),
path: parsedUrl.pathname + parsedUrl.search,

@@ -104,7 +121,29 @@ headers: {

const proxyUrl = getProxyUrl()
const proxyUrl = getProxyUrl(parsedUrl.protocol)
if (!proxyUrl || shouldBypassProxy(parsedUrl.hostname)) {
return reqOptions
return { transport: isHttps ? httpsModule : httpModule, reqOptions }
}
const proxy = new URL(proxyUrl)
if (!['http:', 'https:'].includes(proxy.protocol)) {
throw new Error(`Unsupported proxy protocol: ${proxy.protocol}`)
}
if (!isHttps) {
reqOptions.hostname = proxy.hostname
reqOptions.port = proxy.port || (proxy.protocol === 'https:' ? 443 : 80)
reqOptions.path = parsedUrl.href
reqOptions.headers.Host = parsedUrl.host
if (proxy.username || proxy.password) {
const auth = Buffer.from(
`${decodeURIComponent(proxy.username || '')}:${decodeURIComponent(proxy.password || '')}`,
).toString('base64')
reqOptions.headers['Proxy-Authorization'] = `Basic ${auth}`
}
return {
transport: proxy.protocol === 'https:' ? httpsModule : httpModule,
reqOptions,
}
}
const tunnelSocket = await connectThroughProxy(

@@ -144,3 +183,3 @@ proxyUrl,

reqOptions.agent = new TunnelAgent({ keepAlive: false })
return reqOptions
return { transport: httpsModule, reqOptions }
}

@@ -150,6 +189,6 @@

const redirectCount = options.redirectCount || 0
const reqOptions = await buildRequestOptions(url, options)
const { transport, reqOptions } = await buildRequest(url, options)
return new Promise((resolve, reject) => {
const req = httpsModule.get(reqOptions, (res) => {
const req = transport.get(reqOptions, (res) => {
if ([301, 302, 303, 307, 308].includes(res.statusCode)) {

@@ -178,9 +217,16 @@ res.resume()

res.requestUrl = url
resolve(res)
})
req.on('error', reject)
req.on('error', (error) => {
error.requestUrl = url
reject(error)
})
req.setTimeout(options.timeout || requestTimeout, () => {
req.destroy()
reject(new Error('Request timeout.'))
const error = new Error('Request timeout.')
error.code = 'ETIMEDOUT'
error.requestUrl = url
reject(error)
})

@@ -190,2 +236,176 @@ })

function getFileSize(filePath) {
try {
return fsModule.statSync(filePath).size
} catch (error) {
if (error.code === 'ENOENT') return 0
throw error
}
}
function removeFileIfPresent(filePath) {
try {
fsModule.unlinkSync(filePath)
} catch (error) {
if (error.code !== 'ENOENT') throw error
}
}
function throwResponseError(res, message, requestUrl, retryable) {
res.resume()
const error = new Error(message)
error.statusCode = res.statusCode
error.retryable = retryable
error.requestUrl = requestUrl
throw error
}
function parseContentRange(value) {
if (!value) return null
const completeMatch = value.match(/^bytes (\d+)-(\d+)\/(\d+)$/i)
if (completeMatch) {
const start = Number(completeMatch[1])
const end = Number(completeMatch[2])
const total = Number(completeMatch[3])
if (start > end || end >= total) return null
return {
start,
end,
total,
}
}
const unsatisfiedMatch = value.match(/^bytes \*\/(\d+)$/i)
if (unsatisfiedMatch) {
return { start: null, end: null, total: Number(unsatisfiedMatch[1]) }
}
return null
}
function isRetryableStatus(statusCode) {
return (
statusCode === 408 ||
statusCode === 425 ||
statusCode === 429 ||
statusCode >= 500
)
}
async function downloadFile(url, destinationPath, options = {}) {
let resumedFrom = getFileSize(destinationPath)
let totalBytes = null
const headers = { ...options.headers }
if (resumedFrom > 0) {
headers.Range = `bytes=${resumedFrom}-`
}
const res = await httpGet(url, { ...options, headers })
const responseUrl = res.requestUrl || url
const contentRange = parseContentRange(res.headers['content-range'])
if (res.statusCode === 416 && contentRange?.total === resumedFrom) {
res.resume()
return {
downloadedBytes: resumedFrom,
totalBytes: resumedFrom,
resumedFrom,
responseUrl,
}
}
if (res.statusCode === 416) {
removeFileIfPresent(destinationPath)
throwResponseError(
res,
'Saved partial download is no longer valid',
responseUrl,
true,
)
}
let writeFlags
let expectedResponseBytes = null
if (res.statusCode === 206) {
if (!contentRange || contentRange.start !== resumedFrom) {
removeFileIfPresent(destinationPath)
throwResponseError(
res,
`Download resume mismatch: expected byte ${resumedFrom}`,
responseUrl,
true,
)
}
totalBytes = contentRange.total
expectedResponseBytes = contentRange.end - contentRange.start + 1
writeFlags = 'a'
} else if (res.statusCode === 200) {
// The server may ignore Range. Restart safely instead of appending a
// complete response to the existing partial archive.
resumedFrom = 0
totalBytes = Number(res.headers['content-length']) || null
writeFlags = 'w'
} else {
throwResponseError(
res,
`Download failed: HTTP ${res.statusCode}`,
responseUrl,
isRetryableStatus(res.statusCode),
)
}
let downloadedBytes = resumedFrom
res.on('data', (chunk) => {
downloadedBytes += chunk.length
options.onProgress?.({ downloadedBytes, totalBytes, resumedFrom })
})
try {
await pipelineFn(
res,
fsModule.createWriteStream(destinationPath, { flags: writeFlags }),
)
} catch (error) {
error.requestUrl ||= responseUrl
error.downloadedBytes = getFileSize(destinationPath)
error.totalBytes = totalBytes
throw error
}
downloadedBytes = getFileSize(destinationPath)
const responseBytes = downloadedBytes - resumedFrom
if (
expectedResponseBytes !== null &&
responseBytes !== expectedResponseBytes
) {
if (responseBytes > expectedResponseBytes) {
removeFileIfPresent(destinationPath)
}
const error = new Error(
`Download incomplete: response contained ${responseBytes} of ${expectedResponseBytes} bytes`,
)
error.code = 'EINCOMPLETE'
error.retryable = true
error.requestUrl = responseUrl
error.downloadedBytes = getFileSize(destinationPath)
error.totalBytes = totalBytes
throw error
}
if (totalBytes !== null && downloadedBytes !== totalBytes) {
const error = new Error(
`Download incomplete: received ${downloadedBytes} of ${totalBytes} bytes`,
)
error.code = 'EINCOMPLETE'
error.retryable = true
error.requestUrl = responseUrl
error.downloadedBytes = downloadedBytes
error.totalBytes = totalBytes
throw error
}
return { downloadedBytes, totalBytes, resumedFrom, responseUrl }
}
async function withRetries(

@@ -218,2 +438,3 @@ operation,

getProxyUrl,
downloadFile,
httpGet,

@@ -220,0 +441,0 @@ withRetries,

+25
-980
#!/usr/bin/env node
const { spawn, execFileSync } = require('child_process')
const fs = require('fs')
const http = require('http')
const https = require('https')
const os = require('os')
const path = require('path')
const { pipeline } = require('stream/promises')
const zlib = require('zlib')
const tar = require('tar')
const { createReleaseHttpClient } = require('./http')
const packagedLauncherPath = path.join(__dirname, 'launcher.js')
const sourceLauncherPath = path.join(
__dirname,
'..',
'..',
'..',
'cli',
'release-core',
'launcher.js',
)
// Published packages must not let an unrelated sibling path shadow their
// bundled launcher. Source checkouts only fall back when that copy is absent.
const { createLauncher } = require(
fs.existsSync(packagedLauncherPath)
? packagedLauncherPath
: sourceLauncherPath,
)
const packageName = 'freebuff'
/**
* Terminal escape sequences to reset terminal state after the child process exits.
* When the binary is SIGKILL'd, it can't clean up its own terminal state.
* The wrapper (this process) survives and must reset these modes.
*/
const EXIT_ALTERNATE_SCREEN_SEQUENCE = '\x1b[?1049l'
const SAFE_TERMINAL_RESET_SEQUENCES =
'\x1b[?1000l' + // Disable X10 mouse mode
'\x1b[?1002l' + // Disable button event mouse mode
'\x1b[?1003l' + // Disable any-event mouse mode (all motion)
'\x1b[?1006l' + // Disable SGR extended mouse mode
'\x1b[?1004l' + // Disable focus reporting
'\x1b[?2004l' + // Disable bracketed paste mode
'\x1b[<u' + // Pop kitty keyboard protocol flags
'\x1b[>4;0m' + // Reset modifyOtherKeys
'\x1b[?25h' // Show cursor
const FULL_TERMINAL_RESET_SEQUENCES =
EXIT_ALTERNATE_SCREEN_SEQUENCE + SAFE_TERMINAL_RESET_SEQUENCES
function resetTerminal(options = {}) {
const { exitAlternateScreen = false } = options
try {
if (process.stdin.isTTY && process.stdin.setRawMode) {
process.stdin.setRawMode(false)
}
} catch {
// stdin may be closed
}
try {
if (process.stdout.isTTY) {
// Exiting the alternate screen is only safe after an interactive child.
// Plain CLI paths like --help never enter it, and ?1049l can erase output.
process.stdout.write(
exitAlternateScreen
? FULL_TERMINAL_RESET_SEQUENCES
: SAFE_TERMINAL_RESET_SEQUENCES,
)
}
} catch {
// stdout may be closed
}
}
function getUnsignedExitCode(code) {
return code != null && code < 0 ? (code >>> 0) : code
}
function isWindowsNativeCrashCode(code) {
const unsignedCode = getUnsignedExitCode(code)
return (
process.platform === 'win32' &&
(unsignedCode === 0xC000001D ||
unsignedCode === 0xC0000005 ||
unsignedCode === 0xC0000409)
)
}
function shouldExitAlternateScreen(code, signal) {
return Boolean(signal) || isWindowsNativeCrashCode(code)
}
function isIllegalInstructionExit(code, signal) {
const unsignedCode = getUnsignedExitCode(code)
return (
signal === 'SIGILL' ||
(process.platform === 'win32' && unsignedCode === 0xC000001D)
)
}
function createConfig(packageName) {
const homeDir = os.homedir()
const configDir = path.join(homeDir, '.config', 'manicode')
const binaryName =
process.platform === 'win32' ? `${packageName}.exe` : packageName
return {
homeDir,
configDir,
binaryName,
binaryPath: path.join(configDir, binaryName),
metadataPath: path.join(configDir, 'freebuff-metadata.json'),
tempDownloadDir: path.join(configDir, '.freebuff-download-temp'),
userAgent: `${packageName}-cli`,
requestTimeout: 20000,
downloadRequestTimeout: 120000,
downloadMaxAttempts: 3,
}
}
const CONFIG = createConfig(packageName)
const { httpGet, withRetries } = createReleaseHttpClient({
env: process.env,
userAgent: CONFIG.userAgent,
requestTimeout: CONFIG.requestTimeout,
const launcher = createLauncher({
packageName: 'freebuff',
displayName: 'Freebuff',
telemetryEvent: 'cli.update_freebuff_failed',
})
function getPostHogConfig() {
const apiKey =
process.env.CODEBUFF_POSTHOG_API_KEY ||
process.env.NEXT_PUBLIC_POSTHOG_API_KEY
const host =
process.env.CODEBUFF_POSTHOG_HOST ||
process.env.NEXT_PUBLIC_POSTHOG_HOST_URL
module.exports = launcher
if (!apiKey || !host) {
return null
}
return { apiKey, host }
}
/**
* Track update failure event to PostHog.
* Fire-and-forget - errors are silently ignored.
*/
function trackUpdateFailed(errorMessage, version, context = {}) {
try {
const posthogConfig = getPostHogConfig()
if (!posthogConfig) {
return
}
const payload = JSON.stringify({
api_key: posthogConfig.apiKey,
event: 'cli.update_freebuff_failed',
properties: {
distinct_id: `anonymous-${CONFIG.homeDir}`,
error: errorMessage,
version: version || 'unknown',
platform: process.platform,
arch: process.arch,
...context,
},
timestamp: new Date().toISOString(),
})
const parsedUrl = new URL(`${posthogConfig.host}/capture/`)
const isHttps = parsedUrl.protocol === 'https:'
const options = {
hostname: parsedUrl.hostname,
port: parsedUrl.port || (isHttps ? 443 : 80),
path: parsedUrl.pathname + parsedUrl.search,
method: 'POST',
headers: {
'Content-Type': 'application/json',
'Content-Length': Buffer.byteLength(payload),
},
}
const transport = isHttps ? https : http
const req = transport.request(options)
req.on('error', () => {})
req.write(payload)
req.end()
} catch (e) {
// Silently ignore any tracking errors
}
}
const PLATFORM_TARGETS = {
'linux-x64': `${packageName}-linux-x64.tar.gz`,
'linux-x64-baseline': `${packageName}-linux-x64-baseline.tar.gz`,
'linux-arm64': `${packageName}-linux-arm64.tar.gz`,
'darwin-x64': `${packageName}-darwin-x64.tar.gz`,
'darwin-arm64': `${packageName}-darwin-arm64.tar.gz`,
'win32-x64': `${packageName}-win32-x64.tar.gz`,
'win32-x64-baseline': `${packageName}-win32-x64-baseline.tar.gz`,
}
const BASELINE_FALLBACK_TARGETS = {
'linux-x64': 'linux-x64-baseline',
'win32-x64': 'win32-x64-baseline',
}
const term = {
clearLine: () => {
if (process.stderr.isTTY) {
process.stderr.write('\r\x1b[K')
}
},
write: (text) => {
term.clearLine()
process.stderr.write(text)
},
writeLine: (text) => {
term.clearLine()
process.stderr.write(text + '\n')
},
}
function getPlatformKey() {
return `${process.platform}-${process.arch}`
}
function getTargetOverride() {
const envNames = [
`${packageName.toUpperCase()}_BINARY_TARGET`,
'CODEBUFF_BINARY_TARGET',
'CLI_BINARY_TARGET',
]
for (const envName of envNames) {
const target = process.env[envName]
if (target && PLATFORM_TARGETS[target]) {
return target
}
}
return null
}
function linuxCpuHasAvx2() {
try {
return /\bavx2\b/i.test(fs.readFileSync('/proc/cpuinfo', 'utf8'))
} catch {
return true
}
}
// Returns true (AVX2 present), false (absent), or null (couldn't determine).
// Ask the OS directly via IsProcessorFeaturePresent (kernel32), which is
// backed by CPUID — far more reliable than matching CPU model names, and it
// works on the stock Windows PowerShell that ships with every supported
// Windows version. Feature 40 = PF_AVX2_INSTRUCTIONS_AVAILABLE.
function probeWindowsAvx2() {
const script =
"$f = Add-Type -MemberDefinition '[DllImport(\"kernel32.dll\")] " +
"public static extern bool IsProcessorFeaturePresent(uint feature);' " +
"-Name Cpu -Namespace Win32 -PassThru; $f::IsProcessorFeaturePresent(40)"
try {
const out = execFileSync(
'powershell.exe',
['-NoProfile', '-NonInteractive', '-Command', script],
{ encoding: 'utf8', timeout: 5000, stdio: ['ignore', 'pipe', 'ignore'] },
).trim()
if (out === 'True') return true
if (out === 'False') return false
return null
} catch {
// No PowerShell, locked-down policy, timeout, etc. — inconclusive.
return null
}
}
let _hasAvx2Cache
function machineHasAvx2() {
if (_hasAvx2Cache === undefined) {
_hasAvx2Cache = detectMachineHasAvx2()
}
return _hasAvx2Cache
}
function detectMachineHasAvx2() {
if (process.arch !== 'x64') {
return true
}
// Linux detection is a cheap file read, so we don't bother persisting it.
if (process.platform === 'linux') {
return linuxCpuHasAvx2()
}
if (process.platform !== 'win32') {
return true
}
// Windows detection shells out to PowerShell. getDefaultTargetKey runs on
// every launch (via the version check), so cache the result on disk to keep
// startup fast after the first probe.
const cached = readCachedAvx2()
if (cached !== null) {
return cached
}
const detected = probeWindowsAvx2()
if (detected === null) {
// Inconclusive probe: assume AVX2 for this launch and rely on the SIGILL
// fallback, but don't persist it — a transient failure must not lock in a
// wrong answer for the lifetime of the install. We'll re-probe next launch.
return true
}
writeCachedAvx2(detected)
return detected
}
function getCpuFeatureCachePath() {
return path.join(CONFIG.configDir, 'cpu-features.json')
}
function readCachedAvx2() {
try {
const cache = JSON.parse(fs.readFileSync(getCpuFeatureCachePath(), 'utf8'))
return typeof cache.avx2 === 'boolean' ? cache.avx2 : null
} catch {
return null
}
}
function writeCachedAvx2(value) {
try {
fs.mkdirSync(CONFIG.configDir, { recursive: true })
fs.writeFileSync(getCpuFeatureCachePath(), JSON.stringify({ avx2: value }))
} catch {
// Best effort; we'll just re-probe next launch.
}
}
function getDefaultTargetKey() {
const override = getTargetOverride()
if (override) {
return override
}
const platformKey = getPlatformKey()
// Select the binary up front from explicit CPU feature detection rather than
// optimistically launching the AVX2 build and waiting for it to crash with
// an illegal instruction. The crash isn't always a clean immediate failure —
// it can surface later from a deeper code path — so older CPUs (e.g. an
// Intel Xeon with AVX but no AVX2) are safer on baseline from the start.
//
// This assumes every baseline target is gated on AVX2 specifically, which
// holds today (only linux-x64 and win32-x64 have baseline builds, both
// AVX2-gated). If a baseline build is ever added for a different reason, give
// BASELINE_FALLBACK_TARGETS a per-target capability and check that instead.
if (BASELINE_FALLBACK_TARGETS[platformKey] && !machineHasAvx2()) {
return BASELINE_FALLBACK_TARGETS[platformKey]
}
return platformKey
}
function getBaselineFallbackTargetKey() {
// Runtime safety net: if proactive detection was unavailable or wrong and the
// optimized binary still dies with SIGILL, fall back to baseline.
return BASELINE_FALLBACK_TARGETS[getPlatformKey()] || null
}
function isTargetAllowedForThisMachine(target) {
const override = getTargetOverride()
if (override) {
return target === override
}
// Check the baseline fallback first: it's always safe on its platform and
// avoids running CPU detection when a baseline binary is already installed.
return (
target === getBaselineFallbackTargetKey() ||
target === getDefaultTargetKey()
)
}
function getDownloadTargetKey() {
const override = getTargetOverride()
if (override) {
return override
}
const metadata = getCurrentMetadata()
if (metadata?.target && isTargetAllowedForThisMachine(metadata.target)) {
return metadata.target
}
return getDefaultTargetKey()
}
async function getLatestVersion() {
try {
const res = await httpGet(
`https://registry.npmjs.org/${packageName}/latest`,
)
if (res.statusCode !== 200) return null
const body = await streamToString(res)
const packageData = JSON.parse(body)
return packageData.version || null
} catch (error) {
return null
}
}
function streamToString(stream) {
return new Promise((resolve, reject) => {
let data = ''
stream.on('data', (chunk) => (data += chunk))
stream.on('end', () => resolve(data))
stream.on('error', reject)
})
}
function getCurrentVersion() {
try {
const metadata = getCurrentMetadata()
if (!metadata) {
return null
}
if (!fs.existsSync(CONFIG.binaryPath)) {
return null
}
const metadataTarget = metadata.target || getPlatformKey()
if (!isTargetAllowedForThisMachine(metadataTarget)) {
return null
}
return metadata.version || null
} catch (error) {
return null
}
}
function getCurrentMetadata() {
try {
if (!fs.existsSync(CONFIG.metadataPath)) {
return null
}
return JSON.parse(fs.readFileSync(CONFIG.metadataPath, 'utf8'))
} catch {
return null
}
}
function compareVersions(v1, v2) {
if (!v1 || !v2) return 0
if (!v1.match(/^\d+(\.\d+)*$/)) {
return -1
}
const parseVersion = (version) => {
const parts = version.split('-')
const mainParts = parts[0].split('.').map(Number)
const prereleaseParts = parts[1] ? parts[1].split('.') : []
return { main: mainParts, prerelease: prereleaseParts }
}
const p1 = parseVersion(v1)
const p2 = parseVersion(v2)
for (let i = 0; i < Math.max(p1.main.length, p2.main.length); i++) {
const n1 = p1.main[i] || 0
const n2 = p2.main[i] || 0
if (n1 < n2) return -1
if (n1 > n2) return 1
}
if (p1.prerelease.length === 0 && p2.prerelease.length === 0) {
return 0
} else if (p1.prerelease.length === 0) {
return 1
} else if (p2.prerelease.length === 0) {
return -1
} else {
for (
let i = 0;
i < Math.max(p1.prerelease.length, p2.prerelease.length);
i++
) {
const pr1 = p1.prerelease[i] || ''
const pr2 = p2.prerelease[i] || ''
const isNum1 = !isNaN(parseInt(pr1))
const isNum2 = !isNaN(parseInt(pr2))
if (isNum1 && isNum2) {
const num1 = parseInt(pr1)
const num2 = parseInt(pr2)
if (num1 < num2) return -1
if (num1 > num2) return 1
} else if (isNum1 && !isNum2) {
return 1
} else if (!isNum1 && isNum2) {
return -1
} else if (pr1 < pr2) {
return -1
} else if (pr1 > pr2) {
return 1
}
}
return 0
}
}
function formatBytes(bytes) {
if (bytes === 0) return '0 B'
const k = 1024
const sizes = ['B', 'KB', 'MB', 'GB']
const i = Math.floor(Math.log(bytes) / Math.log(k))
return parseFloat((bytes / Math.pow(k, i)).toFixed(1)) + ' ' + sizes[i]
}
function createProgressBar(percentage, width = 30) {
const filled = Math.round((width * percentage) / 100)
const empty = width - filled
return '[' + '█'.repeat(filled) + '░'.repeat(empty) + ']'
}
function isRetryableDownloadStatus(statusCode) {
return (
statusCode === 408 ||
statusCode === 425 ||
statusCode === 429 ||
statusCode >= 500
)
}
function isRetryableDownloadError(error) {
if (error && typeof error.retryable === 'boolean') return error.retryable
return !['EACCES', 'ENOSPC', 'EPERM', 'EROFS'].includes(error?.code)
}
function prepareTempDownloadDir() {
if (fs.existsSync(CONFIG.tempDownloadDir)) {
fs.rmSync(CONFIG.tempDownloadDir, { recursive: true })
}
fs.mkdirSync(CONFIG.tempDownloadDir, { recursive: true })
}
async function downloadAndExtract(downloadUrl, version, targetKey) {
let attempts = 0
try {
return await withRetries(
async (attempt) => {
attempts = attempt
prepareTempDownloadDir()
term.write('Downloading...')
const res = await httpGet(downloadUrl, {
timeout: CONFIG.downloadRequestTimeout,
})
if (res.statusCode !== 200) {
res.resume()
const error = new Error(`Download failed: HTTP ${res.statusCode}`)
error.statusCode = res.statusCode
error.retryable = isRetryableDownloadStatus(res.statusCode)
throw error
}
const totalSize = parseInt(res.headers['content-length'] || '0', 10)
let downloadedSize = 0
let lastProgressTime = Date.now()
res.on('data', (chunk) => {
downloadedSize += chunk.length
const now = Date.now()
if (now - lastProgressTime >= 100 || downloadedSize === totalSize) {
lastProgressTime = now
if (totalSize > 0) {
const pct = Math.round((downloadedSize / totalSize) * 100)
term.write(
`Downloading... ${createProgressBar(pct)} ${pct}% of ${formatBytes(
totalSize,
)}`,
)
} else {
term.write(`Downloading... ${formatBytes(downloadedSize)}`)
}
}
})
await pipeline(
res,
zlib.createGunzip(),
tar.x({ cwd: CONFIG.tempDownloadDir }),
)
const tempBinaryPath = path.join(
CONFIG.tempDownloadDir,
CONFIG.binaryName,
)
if (!fs.existsSync(tempBinaryPath)) {
const files = fs.readdirSync(CONFIG.tempDownloadDir)
const error = new Error(
`Binary not found after extraction. Expected: ${CONFIG.binaryName}, Available files: ${files.join(', ')}`,
)
error.retryable = false
throw error
}
return tempBinaryPath
},
{
maxAttempts: CONFIG.downloadMaxAttempts,
shouldRetry: isRetryableDownloadError,
onRetry: ({ nextAttempt, delayMs }) => {
term.writeLine(
`Download interrupted. Retrying in ${delayMs / 1000}s (${nextAttempt}/${CONFIG.downloadMaxAttempts})...`,
)
},
},
)
} catch (error) {
if (fs.existsSync(CONFIG.tempDownloadDir)) {
fs.rmSync(CONFIG.tempDownloadDir, { recursive: true })
}
trackUpdateFailed(error.message, version, {
stage: 'download',
statusCode: error.statusCode,
target: targetKey,
attempts,
})
throw error
}
}
async function downloadBinary(version, targetKey = getDownloadTargetKey()) {
const fileName = PLATFORM_TARGETS[targetKey]
if (!fileName) {
const error = new Error(
`Unsupported platform: ${process.platform} ${process.arch}`,
)
trackUpdateFailed(error.message, version, {
stage: 'platform_check',
target: targetKey,
})
throw error
}
const downloadUrl = `${
process.env.NEXT_PUBLIC_CODEBUFF_APP_URL || 'https://codebuff.com'
}/api/releases/download/${version}/${fileName}`
fs.mkdirSync(CONFIG.configDir, { recursive: true })
const tempBinaryPath = await downloadAndExtract(
downloadUrl,
version,
targetKey,
)
if (process.platform !== 'win32') {
fs.chmodSync(tempBinaryPath, 0o755)
}
try {
if (fs.existsSync(CONFIG.binaryPath)) {
try {
fs.unlinkSync(CONFIG.binaryPath)
} catch (err) {
const backupPath = CONFIG.binaryPath + `.old.${Date.now()}`
try {
fs.renameSync(CONFIG.binaryPath, backupPath)
} catch (renameErr) {
throw new Error(
`Failed to replace existing binary. ` +
`unlink error: ${err.code || err.message}, ` +
`rename error: ${renameErr.code || renameErr.message}`,
)
}
}
}
fs.renameSync(tempBinaryPath, CONFIG.binaryPath)
// Move tree-sitter.wasm next to the binary if the tarball included
// it. The CLI binary loads this at startup; embedding it inside the
// binary itself was unreliable on Windows (bun --compile asset
// bundling silently dropped or unbound it across several attempts),
// so we ship it as a sibling file instead. Older artifacts that
// pre-date this change won't have the wasm and will still install —
// they'll just hit the same crash they had before, which is fine.
const tempWasmPath = path.join(CONFIG.tempDownloadDir, 'tree-sitter.wasm')
if (fs.existsSync(tempWasmPath)) {
const targetWasmPath = path.join(
path.dirname(CONFIG.binaryPath),
'tree-sitter.wasm',
)
try {
if (fs.existsSync(targetWasmPath)) fs.unlinkSync(targetWasmPath)
} catch {
// best effort; rename below will surface the real error if it matters
}
fs.renameSync(tempWasmPath, targetWasmPath)
}
fs.writeFileSync(
CONFIG.metadataPath,
JSON.stringify({ version, target: targetKey }, null, 2),
)
} finally {
if (fs.existsSync(CONFIG.tempDownloadDir)) {
fs.rmSync(CONFIG.tempDownloadDir, { recursive: true })
}
}
term.clearLine()
console.log('Download complete! Starting Freebuff...')
}
async function ensureBinaryExists() {
const currentVersion = getCurrentVersion()
if (currentVersion !== null) {
return
}
const version = await getLatestVersion()
if (!version) {
console.error('❌ Failed to determine latest version')
console.error('Please check your internet connection and try again')
if (require.main === module) {
launcher.main().catch((error) => {
console.error('❌ Unexpected error:', error.message)
process.exit(1)
}
try {
await downloadBinary(version)
} catch (error) {
term.clearLine()
console.error('❌ Failed to download freebuff:', error.message)
console.error('Please check your internet connection and try again')
process.exit(1)
}
}
async function checkForUpdates(runningProcess, exitListener) {
try {
const currentVersion = getCurrentVersion()
const latestVersion = await getLatestVersion()
if (!latestVersion) return
if (
currentVersion === null ||
compareVersions(currentVersion, latestVersion) < 0
) {
term.clearLine()
runningProcess.removeListener('exit', exitListener)
await new Promise((resolve) => {
let exited = false
runningProcess.once('exit', () => {
exited = true
resolve()
})
runningProcess.kill('SIGTERM')
setTimeout(() => {
if (!exited) {
runningProcess.kill('SIGKILL')
// Safety: resolve after giving SIGKILL time to take effect
setTimeout(() => resolve(), 1000)
}
}, 5000)
})
resetTerminal({ exitAlternateScreen: true })
console.log(`Update available: ${currentVersion} → ${latestVersion}`)
await downloadBinary(latestVersion)
const newChild = spawnInstalledBinary({ detached: false })
attachExitHandler(newChild)
return new Promise(() => {})
}
} catch (error) {
// Ignore update failures
}
}
function printCrashDiagnostics(code, signal) {
// Windows NTSTATUS codes (unsigned DWORD)
const unsignedCode = getUnsignedExitCode(code)
const isIllegalInstruction = isIllegalInstructionExit(code, signal)
const isAccessViolation =
signal === 'SIGSEGV' ||
(process.platform === 'win32' && unsignedCode === 0xC0000005)
const isBusError = signal === 'SIGBUS'
const isAbort =
signal === 'SIGABRT' ||
(process.platform === 'win32' && unsignedCode === 0xC0000409)
if (!isIllegalInstruction && !isAccessViolation && !isBusError && !isAbort) return
const exitInfo = signal ? `signal ${signal}` : `code ${code}`
console.error('')
console.error(`❌ ${packageName} exited immediately (${exitInfo})`)
console.error('')
if (isIllegalInstruction) {
console.error('Your CPU may not support the required instruction set (AVX2).')
console.error('This typically affects CPUs from before 2013.')
console.error('')
printBaselineOverrideHint()
} else if (isAccessViolation) {
console.error('The binary crashed with an access violation.')
console.error('')
} else if (isBusError) {
console.error('The binary crashed with a bus error.')
console.error('This may indicate a platform compatibility issue.')
console.error('')
} else if (isAbort) {
console.error('The binary crashed with an abort signal.')
console.error('')
}
printSystemInfo()
console.error('')
console.error('Please report this issue at:')
console.error(' https://github.com/CodebuffAI/codebuff/issues')
console.error('')
}
function printBaselineOverrideHint() {
const fallbackTarget = getBaselineFallbackTargetKey()
if (!fallbackTarget) return
console.error('To force the baseline (non-AVX2) build, set:')
console.error(` ${packageName.toUpperCase()}_BINARY_TARGET=${fallbackTarget}`)
console.error('')
}
function printSystemInfo() {
const metadata = getCurrentMetadata()
console.error('System info:')
console.error(` Platform: ${process.platform} ${process.arch}`)
console.error(` Node: ${process.version}`)
if (process.arch === 'x64') {
console.error(` AVX2: ${machineHasAvx2() ? 'yes' : 'no'}`)
}
console.error(` Target: ${metadata?.target || getDefaultTargetKey()}`)
console.error(` Binary: ${CONFIG.binaryPath}`)
}
function getInstalledBinaryStatus() {
try {
const stats = fs.statSync(CONFIG.binaryPath)
return stats.isFile() ? `yes (${formatBytes(stats.size)})` : 'no'
} catch {
return 'no'
}
}
function printSpawnFailure(err) {
resetTerminal()
const code = err && err.code ? ` (${err.code})` : ''
console.error(`Failed to start ${packageName}: ${err.message}${code}`)
console.error('')
printSystemInfo()
console.error(` Exists: ${getInstalledBinaryStatus()}`)
if (process.platform === 'win32') {
console.error('')
console.error(
'On Windows, this can happen when Windows Security or antivirus blocks',
)
console.error(
'or quarantines the downloaded executable, or when the binary requires',
)
console.error('CPU instructions that are not available on this machine.')
console.error('')
printBaselineOverrideHint()
}
console.error('')
console.error('Try deleting the downloaded files and running again:')
console.error(` ${CONFIG.configDir}`)
console.error('')
}
function exitOnSpawnFailure(err) {
printSpawnFailure(err)
process.exit(1)
}
function spawnInstalledBinary(options = {}) {
if (!fs.existsSync(CONFIG.binaryPath)) {
try {
if (fs.existsSync(CONFIG.metadataPath)) fs.unlinkSync(CONFIG.metadataPath)
} catch {
// best effort
}
const error = new Error(
`downloaded binary is missing at ${CONFIG.binaryPath}`,
)
error.code = 'BINARY_MISSING'
exitOnSpawnFailure(error)
}
// spawn() only emits 'error' asynchronously for a few errno values
// (EACCES, EAGAIN, EMFILE, ENFILE, ENOENT); everything else — notably
// UNKNOWN on Windows when antivirus or Smart App Control blocks the
// exe or the download is corrupt — is thrown synchronously.
let child
try {
child = spawn(CONFIG.binaryPath, process.argv.slice(2), {
stdio: 'inherit',
...options,
})
} catch (err) {
exitOnSpawnFailure(err)
}
child.on('error', exitOnSpawnFailure)
return child
}
async function tryFallbackToBaseline(code, signal) {
if (!isIllegalInstructionExit(code, signal)) {
return false
}
const fallbackTarget = getBaselineFallbackTargetKey()
if (!fallbackTarget) {
return false
}
const metadata = getCurrentMetadata()
const currentTarget = metadata?.target || getDefaultTargetKey()
if (currentTarget === fallbackTarget) {
return false
}
const version = metadata?.version || (await getLatestVersion())
if (!version) {
return false
}
resetTerminal({
exitAlternateScreen: shouldExitAlternateScreen(code, signal),
})
console.error('')
console.error(
`${packageName} is switching to the older-CPU binary for this machine.`,
)
try {
await downloadBinary(version, fallbackTarget)
} catch (error) {
term.clearLine()
console.error(`Failed to download ${fallbackTarget}: ${error.message}`)
return false
}
const child = spawnInstalledBinary({ detached: false })
attachExitHandler(child, false)
return true
}
function attachExitHandler(child, allowBaselineFallback = true) {
const exitListener = async (code, signal) => {
if (
allowBaselineFallback &&
(await tryFallbackToBaseline(code, signal))
) {
return
}
resetTerminal({
exitAlternateScreen: shouldExitAlternateScreen(code, signal),
})
printCrashDiagnostics(code, signal)
process.exit(signal ? 1 : (code || 0))
}
child.on('exit', exitListener)
return exitListener
}
async function main() {
await ensureBinaryExists()
const child = spawnInstalledBinary()
const exitListener = attachExitHandler(child)
setTimeout(() => {
checkForUpdates(child, exitListener)
}, 100)
}
main().catch((error) => {
console.error('❌ Unexpected error:', error.message)
process.exit(1)
})
{
"name": "freebuff",
"version": "0.0.122",
"version": "0.0.123",
"description": "The world's strongest free coding agent",

@@ -10,9 +10,9 @@ "license": "MIT",

"scripts": {
"postinstall": "node postinstall.js",
"preuninstall": "node -e \"const fs = require('fs'); const path = require('path'); const os = require('os'); const binaryPath = path.join(os.homedir(), '.config', 'manicode', process.platform === 'win32' ? 'freebuff.exe' : 'freebuff'); try { fs.unlinkSync(binaryPath) } catch (e) { /* ignore if file doesn't exist */ }\""
"prepack": "node ../../../cli/release-core/prepare-package.js",
"postpack": "node ../../../cli/release-core/prepare-package.js --clean"
},
"files": [
"index.js",
"launcher.js",
"http.js",
"postinstall.js",
"README.md"

@@ -19,0 +19,0 @@ ],

#!/usr/bin/env node
const fs = require('fs');
const os = require('os');
const path = require('path');
// Clean up old binary to force fresh download on next launch
const binaryPath = path.join(
os.homedir(),
'.config',
'manicode',
process.platform === 'win32' ? 'freebuff.exe' : 'freebuff'
);
try {
fs.unlinkSync(binaryPath);
} catch (e) {
/* ignore if file doesn't exist */
}
console.log('\n');
console.log('⚡ Welcome to Freebuff!');
console.log('\n');
console.log('To get started:');
console.log(' 1. cd to your project directory');
console.log(' 2. Run: freebuff');
console.log('\n');
console.log('Example:');
console.log(' $ cd ~/my-project');
console.log(' $ freebuff');
console.log('\n');
console.log('For more information, visit: https://codebuff.com/docs');
console.log('\n');