Dashboard › cli › Distillation
0a2d7340-ee3d-4bdb-b551-234fd425e840["lore_tm_v1_AMW4eaRf8JsGbpW_23evgeJlLxxHA3-BCe__k5a70xw","lore_tm_v1_qf3inY_BUjFnnHJye5WtZ26p3OhMXYHBtj7m772tOjY","lore_tm_v1_4lbBIBCruiPSfCYNtxNFdmz2JcoiA7QQr5qSubsCva4","lore_tm_v1_8Fd7jChHdtgSCLZmYIHWrNwmR7VgZhCMnvs6vKxACns","lore_tm_v1_qineWeih_sAb6B-c59NDKKlROfmmIVGjX9-b5eGhsCI","lore_tm_v1_llS4P4nogYC4oN2w2ksGSUATW3ND4pk0jLDcPy9P3A0","lore_tm_v1_nk-mX8gSw4r42WLo3gpSWTqsbbp7eac33IguMszvhBs","lore_tm_v1_20fNd0_a5awWPNj2ubEf7jfbdAzco_enRTx04PpCa4A","lore_tm_v1_wLPEm015wfRJQrUe39PmmofZEZDQx9ZSi7z6OIL1WW0","lore_tm_v1_g0DIydXaJH7wN-qXK3PpON7GSMoRbZeiKwzXKY5cwhc"]
binpatch type/API contract for streaming TRDIFF10 application: patch header layout is magic "TRDIFF10" at bytes [0..8], signed sign-magnitude i64 LE controlLen at [8..16], diffLen at [16..24], newSize at [24..32], followed by zstd(control) | zstd(diff) | zstd(extra).read()/pread and a single-block read-ahead cache; it never sits fully in the JS heap, and only referenced windows are pulled in from the OS page cache populated by the reflink copy.node:zlib createZstdDecompress(); output is incrementally written with fs.openSync + fs.writeSync, and the fd is closeSyncβd before return so callers can spawn the output without racing Linux ETXTBSY; SHA-256 is computed inline with node:crypto createHash.Nβ1 redundant disk writes, temp copies, and SHA-256 passes.MAX_OUTPUT_SIZE places a hard ceiling on untrusted TRDIFF10 newSize before new Uint8Array(newSize) allocation and final SHA-256 verification; the stated legitimate gateway binary size is approximately 310 MB and the ceiling is 2 GiB to prevent OOM denial of service.offtin(buf, offset) decodes zig-bsdiff signed 64-bit little-endian sign-magnitude integers, with the sign in bit 7 of byte 7 and magnitude in the lower 63 bits, rather than standard twoβs complement.addDiffChunk(output, oldChunk, diffChunk, n) performs per-byte wrapping addition with 4-byte SWAR using lows = (a & 0x7f7f7f7f) + (b & 0x7f7f7f7f), highs = (a ^ b) & 0x80808080, and result = lows ^ highs; a tail loop handles n % 4, and OldReader zero-fills out-of-range positions.applyPatchToMemory(oldFile, patchData), applyPatchChainInMemory(oldPath, patches, destPath, onBytes?), and applyPatch(oldPath, patchData, destPath); applyPatchChainInMemory() applies patches oldest-first and returns the final SHA-256, while applyPatch() is the documented single-patch wrapper.makeCache(cacheDir) creates a product-neutral file cache lazily. Its layout uses <fromVersion>-<toVersion>.patch for raw patches and chain-<fromVersion>-<toVersion>.json for metadata; PatchCache exposes save(), load(), cleanup(), and clear(), with reads of a missing directory resolving empty.MAX_STABLE_CHAIN_DEPTH = 10, MAX_NIGHTLY_CHAIN_DEPTH = 30, SIZE_THRESHOLD_RATIO = 0.6, and PATCH_TAG_PREFIX = "patch-".PatchChain contains patches, totalSize, expectedSha256, and optional steps; DeltaResult contains sha256, patchBytes, and chainLength. The final produced binaryβs SHA-256 is the sole trust anchor.InstrumentHook wraps each HTTP operation and must transparently preserve the wrapped promiseβs resolved/rejected value; an exception thrown by the hook aborts the current operation just as an exception from the wrapped function would.BinpatchErrorReason is exactly "network_error" | "execution_failed" | "version_not_found" | "offline_cache_miss", represented by product-neutral BinpatchError."resolve", "download", "apply", "verify"; event types are "phase", "bytes" with written and nullable total, and "done".safeProgress(handler) ensures a misbehaving progress consumer can never abort the underlying operation; progress is cosmetic, and no handler means silent operation.SourceStrategy.resolveChain(currentVersion, targetVersion, signal?, report?) returns an oldest-first PatchChain or null; a null return always falls back to a full download.report/onUnavailable only classifies a null result, while null is always a full-download fallback. Reasons are "no_patches", "malformed_chain", "too_long", "over_budget", and "network".resolveAndApply(opts) checks the cache first, then the source unless offline, applies the chain, verifies SHA-256, and writes destPath; it returns DeltaResult | null. It throws only for genuine apply/verification failures such as corrupt patches or SHA mismatch, which the caller also handles by falling back to a full download.OciClient is an anonymous read-only OCI client with injected registry, repo, userAgent, and optional fetch; it supports token exchange, manifest fetch, paginated/filterable tag listing, and blob download with optional AbortSignal.ghcr.io returns HTTP 307 to Azure Blob Storage; the redirected request omits the Authorization header to avoid an Azure 404.ghcrSource(config) resolves nightly chains from tags named <patchTagPrefix><version>. Manifests use from-version=<prev>, sha256-<binaryName>=<hex>, and a layer titled <binaryName>.patch; the target manifestβs <binaryName>.gz layer supplies the full-download size for the ratio gate.githubReleaseSource(config) resolves stable chains from GitHub releases whose platform assets are <binaryName>, <binaryName>.gz, and <binaryName>.patch; chains are releases between current and target in oldest-first order and are capped by MAX_STABLE_CHAIN_DEPTH and SIZE_THRESHOLD_RATIO.packages/cli/src/commands/cli/upgrade.ts, resolveChannelAndVersion() treats case-insensitive positional "nightly" and "stable" as channel selectors with versionArg: undefined; other values retain getReleaseChannel() and become the explicit version argument.packages/cli/src/commands/cli/upgrade.ts, resolveOfflineTarget() strips VERSION_PREFIX_REGEX from an explicit version or reads latestVersion from getVersionCheckInfo(); if unavailable, it throws UpgradeError("network_error", "No cached version available. Run any command to trigger a background version check, then retry.").resolveTargetWithFallback() supports explicit offline mode only without an unpinned channel switch, reads the cached version before persisting a changed channel because setReleaseChannel clears that cache, and returns offline mode "explicit". Automatic fallback occurs only for curl installs and UpgradeError reason "network_error"; it returns "network-fallback" when cache resolution succeeds and otherwise rethrows the original network error.validateMethod() rejects "unknown" with UpgradeError("unknown_method"); rejects a pinned stable Homebrew version because Homebrew formula versioning does not support it; and rejects --offline for every installation method except "curl".resolveTargetVersion() calls fetchLatestVersion(method, channel), strips VERSION_PREFIX_REGEX from an explicit target, returns a structured "checked" result for flags.check, and returns "up-to-date" when CLI_VERSION === target unless forced or changing channels.versionExists() unless the positional belongs to CHANNEL_VERSIONS; nightly pins always use lookup method "curl" regardless of current installation method, and a miss throws UpgradeError("version_not_found", \Version ${target} not found`)`.buildCheckResult() sets action "checked" and, when the current version differs, emits either Run 'sentry cli upgrade ${target}' to update. for a specific pinned version or Run 'sentry cli upgrade' to update. otherwise..craft.yml uses Craft minimum version '2.21.1', automatic changelog and versioning policies, pre/post commands bash -c 'cd packages/cli && node --experimental-strip-types script/bump-version.ts --pre' and --post, and targets npm, GitHub, Vercel project prj_wVkOnIwI3eIQbGD1Gw7qS1MqFFIK, registry app 'app:sentry', and Homebrew tap getsentry/tools formula sentry..craft.yml publishes registry files matching /^sentry-.*\.gz$/ with SHA-256 hex checksums and URL template https://github.com/getsentry/cli/releases/download/{{version}}/{{file}}; the Homebrew formula supports darwin|linux on arm64|x64, installs the first sentry-* artifact as sentry, and runs sentry cli setup --method brew --no-modify-path in post_install..github/workflows/release.yml pins NODE_VERSION_22: "22.23.1" because floating Node 22 may reuse 22.23.0, which has the ERR_STREAM_PREMATURE_CLOSE keep-alive fetch regression nodejs/node#64004; the fix is in 22.23.1..github/workflows/ci.yml defines generate-patches, which runs off PRs on main and release/**, uses continue-on-error: true, and invokes BYK/binpatch/action@0.4.2 in generate-ghcr mode for nightly and generate-release mode for stable, with binary-glob: 'sentry-*', new-binaries-dir: new-binaries, new-gz-dir: new-binaries, and patches-dir: patches..github/workflows/ci.yml uploads patches/*.patch as artifact sentry-patches when either generation step reports has-patches == 'true'; generation failures create or comment on an open GitHub issue titled "Delta patch generation failed" to avoid duplicates.publish-nightly job runs only for pushes to main, uses BYK/binpatch/action@0.4.2 in publish-ghcr mode for ghcr.io/getsentry/cli, and passes from-version: ${{ needs.generate-patches.outputs.from-version }} from the actual generation step rather than re-deriving it.from-version annotation is critical because binpatch verifies only the final output SHA; a mismatched annotation can silently bypass the userβs expected upgrade path..github/workflows/ci.ymlβs build-npm smoke matrix runs produced artifacts on Node "20", "22", and "24", but always builds under pinned NODE_VERSION_22 because script/require-shim.mjs uses node:module APIs requiring Node 22.15+.