Dashboard › cli › Session 1OnDUhN3UhWk
1OnDUhN3UhWkpoaaNPerform a READ-ONLY independent correctness/adversarial merge-gate review of getsentry/cli PR #1569. Repository: /home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade. Exact immutable base: ec83887a16f780f32fba4b7d710bad262dba3a22. Exact immutable head: 9525f72c70fabbb23ec21d13cf86add58f6287cc. Use Git objects (git show, git diff) as evidence; do not modify files, commits, branches, worktree, or VCS state. Inspect every changed source and test file. Verify merge base, base/head trees, changed paths, full diff, and git diff --check. Focus on regressions in dual-source upgrade behavior: genuine-404-only fallback; terminal non-404/transport/malformed responses; selected-source affinity through discovery, changelog, delta, prefetch, token, manifest, blob, and setup; trusted pagination and cycle detection; exact abort-reason and response-body error classification; npm runtime shape/status across npm/pnpm/bun/yarn and no subprocess on validation failure; canonical Toolkit cli@VERSION versus legacy vVERSION; stable/nightly pin validation; strict GHCR token/OCI/tag validation and repeated cursor handling; redirect auth isolation; artifact versus tracking channel; offline and transport-only cache fallback; delta final SHA and cleanup; end-to-end nightly Toolkit blob/setup coverage. Settled contract: patch caching is source-neutral because dual-published artifacts for each version pair must be byte-identical and cached chains verify final output SHA-256. Raise it only if you prove a defect that survives both guarantees. Return a substantive non-empty findings-first report ordered by severity. Classify evidence as PASS, CONCERN, MUST-FIX, or BLOCKED and cite exact HEAD file:line. Every defect must include a deterministic regression and concrete fix. State scope and residual risks. If any tool fails, report BLOCKED with exact command/error. End the final line exactly MERGE or DO-NOT-MERGE.
/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/packages/cli/AGENTS.md /home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/AGENTS.md
No files found
<path>/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/AGENTS.md</path> <type>file</type> <content> 1: # Jared (Outpost agent) 2: 3: Autonomous GitHub coding agent. Work in `/workspace/repo`. 4: 5: ## Model tiers 6: 7: The primary model is chosen per event (see `src/agents/models.ts`): heavy for 8: code-producing situations, cheaper for lightweight ones. 9: 10: | Role | Subagent | Model | 11: | --- | --- | --- | 12: | Triage / plan / review (heavy) | (primary Jared) | Claude Opus 4.8 | 13: | Triage / plan / review (light) | (primary Jared) | xAI Grok 4.3 | 14: | Explore | `explore` | OpenAI gpt-5-mini | 15: | Implement | `implement` | Moonshot kimi-k2.7-code | 16: | Ship (commit/push/PR) | `ship` | xAI Grok (`grok-build-0.1`) | 17: 18: Pipeline: triage → explore → plan → implement → review → ship. 19: (`worker` is a deprecated alias of `implement`.) 20: 21: Operators also talk to Jared directly from the Outpost dashboard. ...
<path>/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/packages/cli/AGENTS.md</path> <type>file</type> <content> 1: # AGENTS.md 2: 3: Guidelines for AI agents working in this codebase. 4: 5: ## Project Overview 6: 7: **Sentry CLI** is a command-line interface for [Sentry](https://sentry.io), built with Node.js, [pnpm](https://pnpm.io), and [Stricli](https://bloomberg.github.io/stricli/). It lives in `packages/cli` of a pnpm workspace; the docs site lives in `apps/cli-docs`. ...
BASE_COMMIT ec83887a16f780f32fba4b7d710bad262dba3a22 BASE_TREE 110d6530e57ca4fbfb2a3f98e52013d2668b5b5e BASE_PARENTS e7beceb6ba09b64dc277ae1732df04e65500062b BASE_SUBJECT fix(event): Prevent immediate retry of rate-limited org in event view fallback (#1566) HEAD_COMMIT 9525f72c70fabbb23ec21d13cf86add58f6287cc HEAD_TREE 22f49363a13e32c36dcd9e1ca95916809c2dc271 HEAD_PARENTS a84012184c79c2566c7466aa6beda5f767199218 HEAD_SUBJECT fix(cli): harden upgrade metadata validation
ec83887a16f780f32fba4b7d710bad262dba3a22
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 | ...
(no output)
04867eaf9b412a62d4b1ea1c59c2b382c557bd0b cc356b77799633918710e0c8d358034894f86147 ec83887a16f780f32fba4b7d710bad262dba3a22 feat(cli): add toolkit upgrade bridge 9c874298e3b57515ba36d35140627a668a46dc7b 4dd2c6153592d15804b1aaef8da9015e0df0345b 04867eaf9b412a62d4b1ea1c59c2b382c557bd0b fix(cli): address toolkit bridge review 723375b6ce4e37884e760fa0f848e7e7e3effcc9 c0c0ace97578535769b33929fb2494113eec3e5d 9c874298e3b57515ba36d35140627a668a46dc7b fix(cli): address upgrade review findings dbee7e9f2a4555e044f74dfebad002cccfa43a1f 024dbc7afa15d0632eb4c15ed6c808dab974a9c5 723375b6ce4e37884e760fa0f848e7e7e3effcc9 test(cli): update toolkit upgrade fixtures 5ffa5cd0fe02c0a5dc5bec9a8a099f4135c0b447 a1cbad382fe2fec2c40f31bd64eaf1898b779428 dbee7e9f2a4555e044f74dfebad002cccfa43a1f fix(cli): harden upgrade source resolution c8c815bbecf472061ec02ab96d1a31f23f078d01 ecd342742030111dd72ce73739016ac3b803d521 5ffa5cd0fe02c0a5dc5bec9a8a099f4135c0b447 fix(cli): validate GitHub release ...
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
@@ -13,56 +13,60 @@
* as the version argument. The choice is persisted in the local database
* so that subsequent bare `sentry cli upgrade` calls use the same channel.
*/
import { spawn } from "node:child_process";
import { homedir } from "node:os";
import { dirname, join } from "node:path";
import { setTimeout } from "node:timers/promises";
import type { SentryContext } from "../../context.js";
import {
determineInstallDir,
isDowngrade,
+ isNightlyVersion,
LEGACY_INSTALL_SUBDIR,
releaseLock,
samePath,
+ type UpgradeSource,
} from "../../lib/binary.js";
import { buildCommand } from "../../lib/command.js";
import { CLI_VERSION } from "../../lib/constants.js";
import {
getReleaseChannel,
type ReleaseChannel,
...
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
@@ -14,25 +14,29 @@ import {
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 {
+ stringifyUnknown,
+ UpgradeError,
+ UpgradeTransportError,
+} from "./errors.js";
import { logger } from "./logger.js";
import { isProcessRunning } from "./process-utils.js";
/** Known directories where the curl installer may place the binary */
export const KNOWN_CURL_DIRS = [".local/bin", ...
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
@@ -21,36 +21,38 @@ import {
makeCache,
OciClient,
type OciManifest,
PATCH_TAG_PREFIX,
type PatchCache,
type PatchChain,
type ProgressHandler,
resolveAndApply,
SIZE_THRESHOLD_RATIO,
type SourceStrategy,
type StableChainInfo,
} from "binpatch";
+import { prerelease as semverPrerelease, valid as semverValid } from "semver";
import {
compareVersions,
- GITHUB_RELEASES_URL,
+ getGitHubReleasesUrl,
getPlatformBinaryName,
isDowngrade,
isNightlyVersion,
+ PRIMARY_UPGRADE_SOURCE,
+ type UpgradeSource,
} from "./binary.js";
import { CLI_VERSION } from "./constants.js";
import { customFetch } from "./custom-ca.js";
import { getConfigDir } from "./db/index.js";
import { formatBytes } from "./formatters/numbers.js";
-import { ...
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
@@ -609,24 +609,32 @@ export class UpgradeError extends CliError {
network_error: "Failed to fetch version information.",
execution_failed: "Upgrade command failed.",
version_not_found: "The specified version was not found.",
offline_cache_miss:
"Cannot upgrade offline — no pre-downloaded update is available.",
};
super(message ?? defaultMessages[reason], EXIT.UPGRADE);
this.name = "UpgradeError";
this.reason = reason;
}
}
+/** Upgrade failure caused by transport rather than an HTTP or metadata error. */
+export class UpgradeTransportError extends UpgradeError {
+ constructor(message: string) {
+ super("network_error", message);
+ this.name = "UpgradeTransportError";
+ }
+}
+
// Seer Errors
export type SeerErrorReason = ...
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
@@ -8,34 +8,43 @@
* 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.
* Using `fetch` with `redirect: "follow"` would forward the Authorization
* header to Azure, which returns 404. Must follow the redirect manually
* without the auth header.
*/
+import { valid as semverValid } from "semver";
+import {
+ PRIMARY_UPGRADE_SOURCE,
+ parseUpgradeJson,
+ type UpgradeSource,
+} from ...
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
@@ -6,29 +6,36 @@
* AST-based section extraction and produces structured data that can be
* re-serialized as filtered markdown for rendering via `renderMarkdown()`.
*
* Only three categories are kept — everything else is filtered out:
* - **New Features** (✨) — from `### New Features` sections or `feat:` commits
* - **Bug Fixes** (🐛) — from `### Bug Fixes` sections or `fix:` commits
* - **Performance** (⚡) — from `### Performance` sections or `perf:` commits
*/
import { marked, type Token, type Tokens } from "marked";
import {
compareVersions,
- GITHUB_RELEASES_URL,
getGitHubHeaders,
+ getGitHubReleasesUrl,
+ PRIMARY_UPGRADE_SOURCE,
+ type UpgradeSource,
} from "./binary.js";
import { customFetch } from "./custom-ca.js";
-import type { ...
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
@@ -12,53 +12,65 @@ import {
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,
determineInstallDir,
fetchWithUpgradeError,
- GITHUB_RELEASES_URL,
getBinaryDownloadUrl,
getBinaryFilename,
getBinaryPaths,
getGitHubHeaders,
+ getGitHubLatestReleaseUrl,
+ getGitHubReleaseByTagUrl,
+ getGitHubRepositoryUrl,
getPlatformBinaryName,
type InstallationMethod,
...
diff --git a/packages/cli/src/lib/version-check.ts b/packages/cli/src/lib/version-check.ts
index c69ff0466..34393b1c7 100644
--- a/packages/cli/src/lib/version-check.ts
+++ b/packages/cli/src/lib/version-check.ts
@@ -1,42 +1,46 @@
/**
* Background version check for "new version available" notifications.
*
* For nightly builds (CLI_VERSION contains "-dev.<timestamp>"), checks GHCR for the
* latest nightly version via the OCI manifest annotation. For stable builds,
* checks GitHub Releases. Results are cached in the database and shown on
* subsequent runs.
*/
// biome-ignore lint/performance/noNamespaceImport: Sentry SDK recommends namespace import
import * as Sentry from "@sentry/node-core/light";
import { compare as semverCompare } from "semver";
+import type { UpgradeSource } from "./binary.js";
import { CLI_VERSION } from "./constants.js";
import { getReleaseChannel } from "./db/release-channel.js";
import {
getVersionCheckInfo,
markUpdateNotified,
...
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
@@ -119,39 +119,39 @@ describe("upgradeCommand.func", () => {
// Note: We skip testing "unknown installation method" case because
// detectInstallationMethod() runs actual shell commands (npm list, etc.)
// which can be slow/flaky in CI. The unknown method handling is tested
// indirectly through the upgrade.ts unit tests in lib/upgrade.test.ts.
test("shows installation info with specified method", async () => {
globalThis.fetch = (async () =>
- new Response(JSON.stringify({ tag_name: "v0.0.0-dev" }), {
+ new Response(JSON.stringify([{ tag_name: "cli@1.0.0" }]), {
status: 200,
headers: { "Content-Type": "application/json" },
})) as typeof fetch;
const func = await upgradeCommand.loader();
const { ...
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
@@ -35,16 +35,17 @@ import { CLI_VERSION } from "../../../src/lib/constants.js";
import {
clearInstallInfo,
setInstallInfo,
} from "../../../src/lib/db/install-info.js";
import {
getReleaseChannel,
setReleaseChannel,
} from "../../../src/lib/db/release-channel.js";
+import { setVersionCheckInfo } from "../../../src/lib/db/version-check.js";
import { TEST_TMP_DIR, useTestConfigDir } from "../../helpers.js";
/** Store original fetch for restoration */
let originalFetch: typeof globalThis.fetch;
/** Helper to mock fetch */
function mockFetch(
fn: (url: string | URL | Request, init?: RequestInit) => Promise<Response>
@@ -167,16 +168,20 @@ function createMockContext(
/**
* Mock fetch to simulate GHCR manifest ...
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
@@ -20,34 +20,39 @@ import { afterEach, beforeEach, describe, expect, test } from "vitest";
import {
acquireLock,
compareVersions,
determineInstallDir,
fetchWithUpgradeError,
getBinaryDownloadUrl,
getBinaryFilename,
getBinaryPaths,
+ getGitHubReleaseByTagUrl,
getLegacyInstallDirs,
getPlatformBinaryName,
installBinary,
isDowngrade,
isMusl,
+ parseUpgradeJson,
releaseLock,
replaceBinarySync,
+ resolveUpgradeSource,
samePath,
+ UPGRADE_SOURCES,
+ UpgradeSourceNotFoundError,
} from "../../src/lib/binary.js";
import { UpgradeError } from "../../src/lib/errors.js";
describe("getBinaryDownloadUrl", () => {
test("builds correct URL for current platform", () => {
const url = getBinaryDownloadUrl("1.0.0");
- ...
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
@@ -94,20 +94,20 @@ describe("resolveStableDelta", () => {
// Create a "current binary" to patch from
const oldBinaryPath = tempFile("old-binary.bin");
const destPath = tempFile("patched-binary.bin");
writeFileSync(oldBinaryPath, Buffer.from("old binary content for testing"));
// Set up fetch mocks — releases API + patch download
// Since applyPatch will fail (we don't have a real TRDIFF10 matching this binary),
// we expect resolveStableDelta to throw, but the chain resolution should succeed
- const patchUrl = `https://github.com/getsentry/cli/releases/download/0.14.0/${BINARY_NAME}.patch`;
+ const patchUrl = ...
diff --git a/packages/cli/test/lib/delta-upgrade.test.ts b/packages/cli/test/lib/delta-upgrade.test.ts
index 3752d4ae6..68d1cfbdf 100644
--- a/packages/cli/test/lib/delta-upgrade.test.ts
+++ b/packages/cli/test/lib/delta-upgrade.test.ts
@@ -6,18 +6,21 @@
* async orchestration functions tested via fetch mocking.
*/
import { createHash } from "node:crypto";
import { existsSync, unlinkSync } from "node:fs";
import { access, readFile } from "node:fs/promises";
import { tmpdir } from "node:os";
import { join } from "node:path";
-import { afterEach, beforeEach, describe, expect, test } from "vitest";
-import { getPlatformBinaryName } from "../../src/lib/binary.js";
+import { afterEach, beforeEach, describe, expect, test, vi } from "vitest";
+import {
+ getPlatformBinaryName,
+ UPGRADE_SOURCES,
+} from "../../src/lib/binary.js";
import {
applyPatchChain,
attemptDeltaUpgrade,
canAttemptDelta,
downloadStablePatch,
type ExtractStableChainOpts,
extractSha256,
...
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,25 +1,27 @@
/**
* 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;
@@ -32,31 +34,31 @@ function ...
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
@@ -4,26 +4,32 @@
* 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 "../../src/lib/delta-upgrade.js";
import {
buildChangelogSummary,
...
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
@@ -115,16 +115,17 @@ vi.mock("node:child_process", async (importOriginal) => {
// 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,
setInstallInfo,
} from "../../src/lib/db/install-info.js";
import { UpgradeError } from "../../src/lib/errors.js";
import { isProcessRunning } from "../../src/lib/process-utils.js";
@@ -135,16 +136,17 @@ const {
downloadBinaryToTemp,
executeUpgrade,
fetchLatestFromGitHub,
fetchLatestFromNpm,
fetchLatestNightlyVersion,
fetchLatestVersion,
...
Date: Sep 10, 2026 * 🔴 [requested-review] (11:34) User requested a READ-ONLY independent correctness/adversarial merge-gate review of getsentry/cli PR #1569 in `/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade`. * 🔴 (11:34) User specified exact immutable base `ec83887a16f780f32fba4b7d710bad262dba3a22` and exact immutable head `9525f72c70fa…