DashboardcliSession 056Pj9ojvE8B

Session 056Pj9ojvE8B

Full ID: 056Pj9ojvE8BBbIVC
Messages: 36
Distillations: 0
Time range: 2026-09-10 11:14:32 — 2026-09-10 11:29:22

Conversation (36 messages)

READ-ONLY merge-gate review of getsentry/cli PR #1569. Review immutable Git objects only in repo /home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade. Exact base: ec83887a16f780f32fba4b7d710bad262dba3a22. Exact head: 9525f72c70fabbb23ec21d13cf86add58f6287cc. Never modify files or VCS and never use the worktree file contents as evidence; use git show/diff against exact SHAs. Inspect every changed source and test file. Verify merge base, trees, complete diff, changed paths, and diff --check. Focus on behavioral regressions in dual-source upgrade resolution: genuine-404-only fallback, source affinity, GitHub pagination, cancellation/body error typing, strict npm and GHCR response validation, canonical Toolkit versus legacy tags, pinned stable/nightly validation, package-manager no-spawn failures, channel/offline behavior, redirect auth isolation, delta final SHA/cleanup, and end-to-end nightly blob/setup coverage. The source-neutral patch cache is an accepted contract because dual-published artifacts are byte-identical and cached output is final-SHA verified; report it only if you prove a defect that survives both guarantees. Your response MUST be non-empty. Findings first, ordered by severity, classified PASS/CONCERN/MUST-FIX/BLOCKED, with exact HEAD file:line evidence. For each defect, give a deterministic regression and concrete fix. If no defect exists, state PASS and residual risks. If any tool fails, state BLOCKED with the exact command/error. End the final line exactly MERGE or DO-NOT-MERGE.

gateway · 2026-09-10 11:14:32
result
commit
commit
ec83887a16f780f32fba4b7d710bad262dba3a22
9525f72c70fabbb23ec21d13cf86add58f6287cc
ec83887a16f780f32fba4b7d710bad262dba3a22
gateway · 2026-09-10 11:15:13
result
commit=ec83887a16f780f32fba4b7d710bad262dba3a22
tree=110d6530e57ca4fbfb2a3f98e52013d2668b5b5e
parents=e7beceb6ba09b64dc277ae1732df04e65500062b
author=sentry[bot] <39604003+sentry[bot]@users.noreply.github.com>
author_date=2026-09-09T19:01:12+01:00
committer=GitHub <noreply@github.com>
commit_date=2026-09-09T19:01:12+01:00
subject=fix(event): Prevent immediate retry of rate-limited org in event view fallback (#1566)
commit=9525f72c70fabbb23ec21d13cf86add58f6287cc
tree=22f49363a13e32c36dcd9e1ca95916809c2dc271
parents=a84012184c79c2566c7466aa6beda5f767199218
author=Burak Yigit Kaya <byk@sentry.io>
author_date=2026-09-10T10:43:42+00:00
committer=Burak Yigit Kaya <byk@sentry.io>
commit_date=2026-09-10T10:43:42+00:00
subject=fix(cli): harden upgrade metadata validation
gateway · 2026-09-10 11:15:25
result
M	packages/cli/src/commands/cli/upgrade.ts
M	packages/cli/src/lib/binary.ts
M	packages/cli/src/lib/delta-upgrade.ts
M	packages/cli/src/lib/errors.ts
M	packages/cli/src/lib/ghcr.ts
M	packages/cli/src/lib/release-notes.ts
M	packages/cli/src/lib/upgrade.ts
M	packages/cli/src/lib/version-check.ts
M	packages/cli/test/commands/cli.test.ts
M	packages/cli/test/commands/cli/upgrade.test.ts
M	packages/cli/test/lib/binary.test.ts
M	packages/cli/test/lib/delta-upgrade.mocked.test.ts
M	packages/cli/test/lib/delta-upgrade.test.ts
M	packages/cli/test/lib/ghcr.test.ts
M	packages/cli/test/lib/release-notes.test.ts
M	packages/cli/test/lib/upgrade.test.ts
M	packages/cli/test/lib/version-check.test.ts
 packages/cli/src/commands/cli/upgrade.ts           | 180 +++--
 packages/cli/src/lib/binary.ts                     | 191 +++++-
 packages/cli/src/lib/delta-upgrade.ts              | 170 ++++-
 packages/cli/src/lib/errors.ts                     |   8 +
 packages/cli/src/lib/ghcr.ts                       | ...
gateway · 2026-09-10 11:15:37
result
diff_sha256=4950719273dc17d5a9e061b8cfe70c62131fe3299dc1799d9c09bb522b112193  -
gateway · 2026-09-10 11:15:57
result
diff --git a/packages/cli/src/commands/cli/upgrade.ts b/packages/cli/src/commands/cli/upgrade.ts
index 8d8282368..b3039d86b 100644
--- a/packages/cli/src/commands/cli/upgrade.ts
+++ b/packages/cli/src/commands/cli/upgrade.ts
@@ -1,414 +1,465 @@
 /**
  * sentry cli upgrade
  *
  * Self-update the Sentry CLI to the latest or a specific version.
  * After upgrading, spawns the NEW binary with `cli setup` to update
  * completions, agent skills, and record installation metadata.
  *
  * Supports two release channels:
  * - stable (default): tracks the latest GitHub release
  * - nightly: tracks the rolling nightly prerelease built from main
  *
  * The channel can be set via --channel or by passing "nightly"/"stable"
  * as the version argument. The choice is persisted in the local database
  * so that subsequent bare `sentry cli upgrade` calls use the same channel. ...
gateway · 2026-09-10 11:16:07
result
diff --git a/packages/cli/src/lib/binary.ts b/packages/cli/src/lib/binary.ts
index 75582612a..e64f5059e 100644
--- a/packages/cli/src/lib/binary.ts
+++ b/packages/cli/src/lib/binary.ts
@@ -1,450 +1,621 @@
 /**
  * Binary Management
  *
  * Shared utilities for installing, replacing, and managing the CLI binary.
  * Used by both `setup --install` (fresh installs) and `upgrade` (self-updates).
  */
 
 import { spawnSync } from "node:child_process";
 import {
   existsSync,
   mkdirSync,
   readFileSync,
   renameSync,
   unlinkSync,
   writeFileSync,
 } from "node:fs";
 import { chmod, copyFile, mkdir, realpath, unlink } from "node:fs/promises";
 import { delimiter, dirname, isAbsolute, join, resolve, sep } from "node:path";
 import { compare as semverCompare } from "semver";
 import { getUserAgent } from "./constants.js";
 import {
   buildTlsErrorDetail,
   customFetch,
   isTlsCertError,
 } from "./custom-ca.js";
-import { stringifyUnknown, UpgradeError } from "./errors.js";
+import ...
gateway · 2026-09-10 11:16:16
result
diff --git a/packages/cli/src/lib/delta-upgrade.ts b/packages/cli/src/lib/delta-upgrade.ts
index ec709b8c8..204875dce 100644
--- a/packages/cli/src/lib/delta-upgrade.ts
+++ b/packages/cli/src/lib/delta-upgrade.ts
@@ -1,388 +1,481 @@
 /** Delta upgrade discovery and application backed by binpatch. */
 
 import { join } from "node:path";
 // biome-ignore lint/performance/noNamespaceImport: Sentry SDK recommends namespace import
 import * as Sentry from "@sentry/node-core/light";
 import {
   applyPatchChainInMemory,
   extractStableChain as binpatchExtractStableChain,
   filterAndSortChainTags as binpatchFilterAndSortChainTags,
   validateChainStep as binpatchValidateChainStep,
   type DeltaTelemetry,
   type DeltaUnavailableReason,
   type ExtractStableChainOpts,
   type GitHubRelease,
   getPatchFromVersion,
   getPatchTargetSha256,
   ghcrSource,
   githubReleaseSource,
   type InstrumentHook,
   MAX_NIGHTLY_CHAIN_DEPTH,
   makeCache,
   OciClient,
   type OciManifest,
   ...
gateway · 2026-09-10 11:16:28
result
diff --git a/packages/cli/src/lib/errors.ts b/packages/cli/src/lib/errors.ts
index f81b8c70c..b21505cd1 100644
--- a/packages/cli/src/lib/errors.ts
+++ b/packages/cli/src/lib/errors.ts
@@ -501,240 +501,248 @@ export class ResolutionError extends CliError {
   override format(): string {
     return this.message;
   }
 }
 
 /**
  * Build a {@link ValidationError} message with Try: examples and optional Note: section.
  *
  * Matches {@link buildResolutionMessage} / {@link buildContextMessage} formatting so
  * agent consumers get actionable recovery commands plus diagnostic context in a
  * predictable shape. Always pass `field` when constructing the error — unfielded
  * validation errors collapse into one Sentry fingerprint. ...
gateway · 2026-09-10 11:16:37
result
diff --git a/packages/cli/src/lib/ghcr.ts b/packages/cli/src/lib/ghcr.ts
index 43d6deb7e..5bca7c061 100644
--- a/packages/cli/src/lib/ghcr.ts
+++ b/packages/cli/src/lib/ghcr.ts
@@ -1,520 +1,659 @@
 /**
  * GHCR (GitHub Container Registry) Client
  *
  * Encapsulates the OCI download protocol for fetching nightly CLI binaries
  * from ghcr.io/getsentry/cli. Nightly builds are pushed as OCI artifacts
  * via ORAS with the version baked into the manifest annotation.
  *
  * Key design decisions:
  * - Anonymous access: nightly package is public; no token needed beyond the
  *   standard ghcr.io anonymous token exchange.
  * - Version discovery from manifest annotation: `annotations.version` in the
  *   OCI manifest holds the nightly version. Checking the latest version only
  *   requires a token exchange + manifest fetch (2 HTTP requests total).
  * - Redirect quirk: ghcr.io blob downloads return 307 to Azure Blob Storage. ...
gateway · 2026-09-10 11:16:46
result
diff --git a/packages/cli/src/lib/release-notes.ts b/packages/cli/src/lib/release-notes.ts
index ddf617535..903ca51f6 100644
--- a/packages/cli/src/lib/release-notes.ts
+++ b/packages/cli/src/lib/release-notes.ts
@@ -1,142 +1,149 @@
 /**
  * Release Notes Parser & Aggregation
  *
  * Extracts user-facing changelog entries from GitHub Release bodies (stable)
  * or conventional commit messages (nightly). Uses `marked.lexer()` for
  * AST-based section extraction and produces structured data that can be
  * re-serialized as filtered markdown for rendering via `renderMarkdown()`. ...
gateway · 2026-09-10 11:16:55
result
diff --git a/packages/cli/src/lib/upgrade.ts b/packages/cli/src/lib/upgrade.ts
index 945adc48d..b29d67ff2 100644
--- a/packages/cli/src/lib/upgrade.ts
+++ b/packages/cli/src/lib/upgrade.ts
@@ -1,149 +1,247 @@
 /**
  * Upgrade Module
  *
  * Detects how the CLI was installed and provides self-upgrade functionality.
  * Binary management helpers (download URLs, locking, replacement) live in
  * binary.ts and are shared with the setup --install flow.
  */
 
 import { spawn } from "node:child_process";
 import {
   chmodSync,
   closeSync,
   existsSync,
   openSync,
   realpathSync,
   statSync,
   unlinkSync,
   writeSync,
 } from "node:fs";
 import { writeFile } from "node:fs/promises";
 import { homedir } from "node:os";
 import { dirname, isAbsolute, join, sep } from "node:path";
 import { setTimeout } from "node:timers/promises";
+import { prerelease as semverPrerelease, valid as semverValid } from "semver";
 import {
   acquireLock,
   cleanupOldBinary,
+  compareVersions,
   ...
gateway · 2026-09-10 11:19:15
result
diff --git a/packages/cli/test/commands/cli.test.ts b/packages/cli/test/commands/cli.test.ts
index cd1514eb0..4eec11e9d 100644
--- a/packages/cli/test/commands/cli.test.ts
+++ b/packages/cli/test/commands/cli.test.ts
@@ -77,160 +77,154 @@ describe("feedbackCommand.func", () => {
   });
 
   test("throws ValidationError for whitespace-only message", async () => {
     const func = await feedbackCommand.loader();
     const mockContext = {
       stdout: { write: vi.fn(() => true) },
       stderr: { write: vi.fn(() => true) },
     };
 
     await expect(func.call(mockContext, {}, "   ")).rejects.toThrow(
       "Please provide a feedback message."
     );
   });
 
   test("throws ConfigError when Sentry is disabled", async () => {
     const func = await feedbackCommand.loader();
     const mockContext = {
       stdout: { write: vi.fn(() => true) },
       stderr: { write: vi.fn(() => true) },
     };
 
     // Sentry is disabled in test environment (no DSN)
     await expect(
       ...
gateway · 2026-09-10 11:19:28
result
diff --git a/packages/cli/test/commands/cli/upgrade.test.ts b/packages/cli/test/commands/cli/upgrade.test.ts
index ca9688e46..b7fead58f 100644
--- a/packages/cli/test/commands/cli/upgrade.test.ts
+++ b/packages/cli/test/commands/cli/upgrade.test.ts
@@ -3,80 +3,81 @@
  *
  * Tests the `sentry cli upgrade` command through Stricli's run().
  * Covers resolveTargetVersion branches (check mode, already up-to-date,
  * version validation) and error paths.
  *
  * Status messages go through consola (→ process.stderr). Tests capture stderr
  * via a spy on process.stderr.write and assert on the collected output. ...
gateway · 2026-09-10 11:19:38
result
diff --git a/packages/cli/test/lib/binary.test.ts b/packages/cli/test/lib/binary.test.ts
index 6fcfb3b1a..29ead3828 100644
--- a/packages/cli/test/lib/binary.test.ts
+++ b/packages/cli/test/lib/binary.test.ts
@@ -1,113 +1,240 @@
 /**
  * Binary Management Tests
  *
  * Tests for shared binary helpers: install directory selection, paths,
  * download URLs, locking, and binary installation.
  */
 
 import {
   chmodSync,
   mkdirSync,
   readFileSync,
   realpathSync,
   rmSync,
   symlinkSync,
   writeFileSync,
 } from "node:fs";
 import { access, readFile, writeFile } from "node:fs/promises";
 import { join, sep } from "node:path";
 import { afterEach, beforeEach, describe, expect, test } from "vitest";
 import {
   acquireLock,
   compareVersions,
   determineInstallDir,
   fetchWithUpgradeError,
   getBinaryDownloadUrl,
   getBinaryFilename,
   getBinaryPaths,
+  getGitHubReleaseByTagUrl,
   getLegacyInstallDirs,
   getPlatformBinaryName,
   installBinary,
   isDowngrade,
   ...
gateway · 2026-09-10 11:19:47
result
diff --git a/packages/cli/test/lib/delta-upgrade.mocked.test.ts b/packages/cli/test/lib/delta-upgrade.mocked.test.ts
index cd0a2fddc..f6186ab59 100644
--- a/packages/cli/test/lib/delta-upgrade.mocked.test.ts
+++ b/packages/cli/test/lib/delta-upgrade.mocked.test.ts
@@ -42,145 +42,145 @@ vi.mock("../../src/lib/constants.js", async (importOriginal) => {
 import { getPlatformBinaryName } from "../../src/lib/binary.js";
 import {
   attemptDeltaUpgrade,
   resolveNightlyDelta,
   resolveStableDelta,
 } from "../../src/lib/delta-upgrade.js";
 
 // ============================================================================
 // Fetch mock infrastructure
 // ============================================================================
 
 let originalFetch: typeof globalThis.fetch;
 
 beforeEach(() => {
   originalFetch = globalThis.fetch;
 });
 
 afterEach(() => {
   globalThis.fetch = originalFetch;
 });
 
 function mockFetch(
   fn: (url: string | URL | Request, init?: RequestInit) => ...
gateway · 2026-09-10 11:19:57
result
diff --git a/packages/cli/test/lib/ghcr.test.ts b/packages/cli/test/lib/ghcr.test.ts
index e5c81d532..a55612b5a 100644
--- a/packages/cli/test/lib/ghcr.test.ts
+++ b/packages/cli/test/lib/ghcr.test.ts
@@ -1,257 +1,365 @@
 /**
  * GHCR Client Tests
  *
  * Unit tests for the GHCR/OCI download protocol helpers.
  * All HTTP calls are mocked via globalThis.fetch to avoid network access.
  */
 
 import { afterEach, beforeEach, describe, expect, test } from "vitest";
+import { UPGRADE_SOURCES } from "../../src/lib/binary.js";
 import { UpgradeError } from "../../src/lib/errors.js";
 import {
   downloadLayerBlob,
   downloadNightlyBlob,
   fetchManifest,
   fetchNightlyManifest,
   findLayerByFilename,
   GHCR_REPO,
   GHCR_TAG,
+  GhcrManifestHttpError,
   getAnonymousToken,
   getNightlyVersion,
   listTags,
   type OciManifest,
 } from "../../src/lib/ghcr.js";
 
 /** Store original fetch for restoration */
 let originalFetch: typeof globalThis.fetch;
 
 /** Helper to mock fetch without ...
gateway · 2026-09-10 11:20:08
result
diff --git a/packages/cli/test/lib/release-notes.test.ts b/packages/cli/test/lib/release-notes.test.ts
index 78963b471..ffccf4901 100644
--- a/packages/cli/test/lib/release-notes.test.ts
+++ b/packages/cli/test/lib/release-notes.test.ts
@@ -1,71 +1,77 @@
 /**
  * Unit Tests for Release Notes Parser & Aggregation
  *
  * Tests core invariants (section extraction, version filtering, truncation)
  * that are hard to express as property-based tests due to format specifics.
  *
  * Core random-input invariants (category validity, filtering, commit parsing)
  * are tested via property-based tests in release-notes.property.test.ts.
  */
 
 import { marked } from "marked";
-import { describe, expect, test } from "vitest";
-import type { GitHubRelease } from "../../src/lib/delta-upgrade.js";
+import { afterEach, beforeEach, describe, expect, test } from "vitest";
+import { UPGRADE_SOURCES } from "../../src/lib/binary.js";
+import {
+  fetchRecentReleases,
+  type GitHubRelease,
+} from ...
gateway · 2026-09-10 11:20:24
result
diff --git a/packages/cli/test/lib/upgrade.test.ts b/packages/cli/test/lib/upgrade.test.ts
index 7c6f63a4b..d10f21dd6 100644
--- a/packages/cli/test/lib/upgrade.test.ts
+++ b/packages/cli/test/lib/upgrade.test.ts
@@ -103,60 +103,62 @@ const { spawnImpl } = vi.hoisted(() => ({
 // Initialize with the real default now that fakeProcess is defined
 spawnImpl.fn = () => fakeProcess(0);
 
 vi.mock("node:child_process", async (importOriginal) => {
   const orig = await importOriginal<typeof import("node:child_process")>();
   return {
     ...orig,
     spawn: (cmd: string, args: string[], opts: object) =>
       spawnImpl.fn(cmd, args, opts),
   };
 });
 
 // Dynamic imports: must run AFTER vi.mock() so upgrade.ts picks up the
 // mocked spawn.
 import { isEnoentSpawnError } from "../../src/commands/cli/upgrade.js";
 import {
   acquireLock,
   getBinaryDownloadUrl,
   isNightlyVersion,
   releaseLock,
+  UPGRADE_SOURCES,
 } from "../../src/lib/binary.js";
 import {
   clearInstallInfo,
   ...
gateway · 2026-09-10 11:20:38
result
diff --git a/packages/cli/test/lib/version-check.test.ts b/packages/cli/test/lib/version-check.test.ts
index 20172cd83..dd047a5cb 100644
--- a/packages/cli/test/lib/version-check.test.ts
+++ b/packages/cli/test/lib/version-check.test.ts
@@ -1,61 +1,64 @@
 /**
  * Version Check Logic Tests
  */
 
 import { setTimeout as sleep } from "node:timers/promises";
-import { afterEach, beforeEach, describe, expect, test } from "vitest";
+import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
+import { UPGRADE_SOURCES } from "../../src/lib/binary.js";
 import { setReleaseChannel } from "../../src/lib/db/release-channel.js";
 import {
   getVersionCheckInfo,
   setVersionCheckInfo,
 } from "../../src/lib/db/version-check.js";
+// biome-ignore lint/performance/noNamespaceImport: Vitest requires the module namespace to spy on an ESM export
+import * as deltaUpgrade from "../../src/lib/delta-upgrade.js";
 import {
   ApiError,
   ContextError,
   ValidationError,
 } from ...
gateway · 2026-09-10 11:21:02
result
package.json
packages/cli/package.json
pnpm-lock.yaml
gateway · 2026-09-10 11:21:20
result
04867eaf9b412a62d4b1ea1c59c2b382c557bd0b ec83887a16f780f32fba4b7d710bad262dba3a22 feat(cli): add toolkit upgrade bridge
9c874298e3b57515ba36d35140627a668a46dc7b 04867eaf9b412a62d4b1ea1c59c2b382c557bd0b fix(cli): address toolkit bridge review
723375b6ce4e37884e760fa0f848e7e7e3effcc9 9c874298e3b57515ba36d35140627a668a46dc7b fix(cli): address upgrade review findings
dbee7e9f2a4555e044f74dfebad002cccfa43a1f 723375b6ce4e37884e760fa0f848e7e7e3effcc9 test(cli): update toolkit upgrade fixtures
5ffa5cd0fe02c0a5dc5bec9a8a099f4135c0b447 dbee7e9f2a4555e044f74dfebad002cccfa43a1f fix(cli): harden upgrade source resolution
c8c815bbecf472061ec02ab96d1a31f23f078d01 5ffa5cd0fe02c0a5dc5bec9a8a099f4135c0b447 fix(cli): validate GitHub release pagination
b6484e0fb1eb0f8bce68272d538f5c3b26cd5bd5 c8c815bbecf472061ec02ab96d1a31f23f078d01 fix(cli): validate resolved upgrade metadata
c6030fbf4d0c190f037c86d832edb6680d3e54ab b6484e0fb1eb0f8bce68272d538f5c3b26cd5bd5 fix(cli): bind nightly manifests to ...
gateway · 2026-09-10 11:21:39
result
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/commands/cli/upgrade.ts:309:  const resolved = await resolveExistingUpgradeVersion(target);
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/commands/cli/upgrade.ts:341:      ? await resolveLatestUpgradeVersion(channel)
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/upgrade.ts:497:export async function fetchLatestFromGitHubWithSource(
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/upgrade.ts:549:export async function fetchLatestFromGitHub(
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/upgrade.ts:554:    await fetchLatestFromGitHubWithSource(
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/upgrade.ts:708:    ? fetchLatestFromGitHub()
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/upgrade.ts:713:export function resolveLatestUpgradeVersion(
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/upgrade.ts:719:    : ...
gateway · 2026-09-10 11:21:56
result
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/delta-upgrade.ts:387:    (await client.listTags(opts.token, PATCH_TAG_PREFIX, opts.signal));
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/delta-upgrade.ts:401:      chainTags.map((tag) => client.fetchManifest(opts.token, tag, opts.signal))
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/ghcr.ts:258:export async function getAnonymousToken(
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/ghcr.ts:310:export async function fetchManifest(
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/ghcr.ts:357:export async function fetchNightlyManifest(
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/ghcr.ts:362:  return await fetchManifest(token, GHCR_TAG, signal, source);
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/ghcr.ts:432:export async function downloadNightlyBlob(
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/ghcr.ts:599:export ...
gateway · 2026-09-10 11:22:05
result
{
  "name": "sentry",
  "version": "0.45.0-dev.0",
  "description": "Sentry CLI - A command-line interface for using Sentry built by robots and humans for robots and humans",
  "repository": {
    "type": "git",
    "url": "git+https://github.com/getsentry/cli.git"
  },
  "main": "./dist/index.cjs",
  "type": "module",
  "types": "./dist/index.d.cts",
  "exports": {
    ".": {
      "import": {
        "types": "./dist/index.d.mts",
        "default": "./dist/index.mjs"
      },
      "require": {
        "types": "./dist/index.d.cts",
        "default": "./dist/index.cjs"
      }
    }
  },
  "bin": {
    "sentry": "./dist/bin.cjs"
  },
  "files": [
    "dist/bin.cjs",
    "dist/index.cjs",
    "dist/index.mjs",
    "dist/index.d.cts",
    "dist/index.d.mts",
    "dist/ink-app.js",
    "dist/node-sqlite3-wasm.wasm",
    "dist/assets/spleen-8x16.bin",
    "dist/vendor/symbolic_bg.wasm",
    "LICENSE.md",
    "THIRD_PARTY_LICENSES.md",
    "README.md"
  ],
  "license": ...
gateway · 2026-09-10 11:22:21
result
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/commands/cli/upgrade.ts:892:  return fetchChangelog({
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/test/lib/release-notes.test.ts:339:    const changelog = await fetchChangelog({
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/test/lib/release-notes.test.ts:376:    const changelog = await fetchChangelog({
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/test/lib/release-notes.test.ts:392:    const changelog = await fetchChangelog({
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/test/lib/release-notes.test.ts:410:    const changelog = await fetchChangelog({
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/test/lib/release-notes.test.ts:429:    const changelog = await fetchChangelog({
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/test/lib/release-notes.test.ts:443:    const changelog = await ...
gateway · 2026-09-10 11:25:15
result
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/custom-ca.ts:305:export function customFetch(
/**
 * Custom CA certificate loading for corporate TLS proxies.
 *
 * Reads CA bundles from (in priority order):
 * 1. `sentry cli defaults ca-cert` (stored path in SQLite)
 * 2. `NODE_EXTRA_CA_CERTS` env var
 *
 * Returns a `tls` options object for Bun's `fetch()`. On the Node.js npm
 * distribution, Node natively honors `NODE_EXTRA_CA_CERTS` so the extra
 * `tls.ca` option is harmless (ignored by Node's fetch).
 *
 * Security model: When the CA source is an env var (not a stored default)
 * AND the target is SaaS (`*.sentry.io`), a one-time warning is logged.
 * `sentry cli defaults ca-cert` silences the warning — the user has
 * explicitly acknowledged the custom CA. See CLI-1K6 plan for the full
 * threat model discussion. ...
gateway · 2026-09-10 11:25:26
result
9525f72c70fabbb23ec21d13cf86add58f6287cc:pnpm-lock.yaml:2696:  binpatch@0.4.2:
9525f72c70fabbb23ec21d13cf86add58f6287cc:pnpm-lock.yaml:7801:  binpatch@0.4.2: {}
9525f72c70fabbb23ec21d13cf86add58f6287cc:pnpm-lock.yaml:221:      binpatch:
gateway · 2026-09-10 11:26:21
result
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/delta-upgrade.ts:167:    cleanup: () => base.cleanup(),
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/delta-upgrade.ts:455:        await client.downloadBlobBuffer(opts.token, digest, opts.signal)
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/delta-upgrade.ts:488:          `SHA-256 mismatch after patching: got ${sha256}, expected ${chain.expectedSha256}`
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/upgrade.ts:17:  unlinkSync,
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/upgrade.ts:27:  cleanupOldBinary,
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/upgrade.ts:275: * Start cleanup of the .old binary for this install.
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/upgrade.ts:280:  cleanupOldBinary(oldPath);
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/upgrade.ts:1250:      ...
gateway · 2026-09-10 11:26:39
result
  2320	          JSON.stringify({
  2321	            layers: [],
  2322	            annotations: { version: "0.14.0-dev.124" },
  2323	          }),
  2324	          { status: 200 }
  2325	        );
  2326	      }
  2327	      return new Response("Unexpected", { status: 500 });
  2328	    });
  2329	
  2330	    await expect(
  2331	      executeUpgrade(
  2332	        "curl",
  2333	        "0.14.0-dev.123",
  2334	        undefined,
  2335	        false,
  2336	        undefined,
  2337	        UPGRADE_SOURCES[0]
  2338	      )
  2339	    ).rejects.toMatchObject({ reason: "network_error" });
  2340	    expect(requests.some((request) => request.includes("/blobs/"))).toBe(false);
  2341	  });
  2342	});
  2343	
  2344	describe("downloadBinaryToTemp offline errors", () => {
  2345	  const offlineBinDir = join(TEST_TMP_DIR, "upgrade-offline-test");
  2346	  const offlineInstallPath = join(offlineBinDir, "sentry");
  2347	
  2348	  beforeEach(() => {
  2349	    clearInstallInfo();
  ...
gateway · 2026-09-10 11:26:47
result
  2440	
  2441	  test("throws execution_failed UpgradeError after retry budget is exhausted", async () => {
  2442	    // Serve an empty gzip payload. The outer stream completes cleanly, so
  2443	    // neither fetchWithUpgradeError nor streamDecompressToFile throws —
  2444	    // but `destPath` ends up with zero bytes. The verification loop polls
  2445	    // 5 times (~3.1s cumulative) before giving up with an actionable
  2446	    // error; without it the caller would spawn the empty file and fail
  2447	    // with "Executable not found in $PATH" (the CLI-1D3 symptom).
  2448	    const emptyGzip = gzipSync(new Uint8Array(0));
  2449	    mockFetch(async (url) => {
  2450	      const urlStr = String(url);
  2451	      if (urlStr.endsWith(".gz")) {
  2452	        return new Response(emptyGzip, { status: 200 });
  2453	      }
  2454	      return new Response("Not Found", { status: 404 });
  2455	    });
  2456	
  2457	    try {
  2458	      await downloadBinaryToTemp("0.26.1");
  ...
gateway · 2026-09-10 11:27:04
result
  1080	    });
  1081	
  1082	    proc.on("close", (code) => {
  1083	      if (code === 0) {
  1084	        resolve();
  1085	      } else {
  1086	        reject(
  1087	          new UpgradeError(
  1088	            "execution_failed",
  1089	            `${pm} install failed with exit code ${code}`
  1090	          )
  1091	        );
  1092	      }
  1093	    });
  1094	
  1095	    proc.on("error", (err) => {
  1096	      reject(
  1097	        new UpgradeError("execution_failed", `${pm} failed: ${err.message}`)
  1098	      );
  1099	    });
  1100	  });
  1101	}
  1102	
  1103	/**
  1104	 * Execute the upgrade using the appropriate method.
  1105	 *
  1106	 * For curl installs, downloads the new binary to a temp path and returns a
  1107	 * DownloadResult with the binary path and lock path. The caller should spawn
  1108	 * `setup --install` on the new binary, then release the lock. ...
gateway · 2026-09-10 11:27:12
result
ec83887a16f780f32fba4b7d710bad262dba3a22:packages/cli/src/lib/upgrade.ts:902:export async function downloadBinaryToTemp(
gateway · 2026-09-10 11:27:22
result
   890	 *
   891	 * If the child resolves to the same install path, it takes over the lock via
   892	 * process.ppid recognition in acquireLock — the parent's subsequent release
   893	 * is then a harmless no-op.
   894	 *
   895	 * @param version - Target version to download (used for display and comparison)
   896	 * @param downloadTag - Git tag to use in the download URL. Defaults to `version`.
   897	 *   Pass `NIGHTLY_TAG` ("nightly") when installing from the rolling nightly release
   898	 *   so the URL points to the prerelease assets regardless of the version string.
   899	 * @returns The downloaded binary path and lock path to release
   900	 * @throws {UpgradeError} When download fails
   901	 */
   902	export async function downloadBinaryToTemp(
   903	  version: string,
   904	  downloadTag?: string,
   905	  offline?: OfflineMode,
   906	  setMessage?: SetMessage
   907	): Promise<DownloadResult> {
   908	  const { tempPath, lockPath } = getCurlInstallPaths();
   909	
 ...
gateway · 2026-09-10 11:27:34
result
9525f72c70fabbb23ec21d13cf86add58f6287cc:packages/cli/src/lib/binary.ts:238:export function getBinaryDownloadUrl(
gateway · 2026-09-10 11:27:50
result
{
  "compilerOptions": {
    "lib": ["ESNext"],
    "target": "ESNext",
    "module": "ESNext",
    "jsx": "react-jsx",
    "moduleDetection": "force",
    "allowJs": true,
    "moduleResolution": "bundler",
    "allowImportingTsExtensions": true,
    "verbatimModuleSyntax": true,
    "noEmit": true,
    "resolveJsonModule": true,
    "strict": true,
    "skipLibCheck": true,
    "noFallthroughCasesInSwitch": true,
    "noUncheckedIndexedAccess": true,
    "noImplicitOverride": true,
    "esModuleInterop": true,
    "forceConsistentCasingInFileNames": true,
    "noUnusedLocals": false,
    "noUnusedParameters": false,
    "noPropertyAccessFromIndexSignature": false,
    "strictNullChecks": true
  },
  "include": ["src/**/*.ts", "src/**/*.tsx"],
  "exclude": ["node_modules", "dist"]
}
import { existsSync } from "node:fs";
import { dirname, join } from "node:path";
import { defineConfig, type Plugin } from "vitest/config";

const JS_EXT_RE = /\.js$/;

/**
 * Vite plugin to rewrite lazy ...
gateway · 2026-09-10 11:29:22