Dashboard › cli › Session 1C3QCvvjjKRo
1C3QCvvjjKRozlzweRead-only analysis in /home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade. Analyze packages/cli/install and packages/cli/test/lib/install-script.test.ts. Design the smallest shell implementation and deterministic tests for Toolkit-first then legacy fallback across stable latest, pinned stable, rolling nightly, and pinned nightly. Contract: fallback only on actual HTTP 404; non-404 curl/HTTP/auth/network/malformed failures stop; gzip-to-raw fallback is asset fallback within one selected repo and must not switch repos prematurely; selected source stays fixed for token/manifest/blob; source list exact parity with TS; installer telemetry remains nonblocking. Never address unrelated musl defect. Do not edit files. Return concrete function/flow changes, fake curl test design, and shell pitfalls.
<path>/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/glowing-cactus</path> <type>directory</type> <entries> .craft.yml .git .github/ .gitignore .lore.md .nojekyll .npmrc .opencode/ .plans/ .ruff_cache/ AGENTS.md apps/ CHANGELOG.md codemods/ coverage/ dist-bin/ dist/ docs/ LICENSE.md node_modules/ package.json packages/ pnpm-lock.yaml pnpm-workspace.yaml README.md test-results.junit.xml (26 entries) </entries>
<path>/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade</path> <type>directory</type> <entries> .craft.yml .git .github/ .gitignore .lore.md .nojekyll .npmrc AGENTS.md apps/ CHANGELOG.md codemods/ LICENSE.md node_modules/ package.json packages/ pnpm-lock.yaml pnpm-workspace.yaml README.md (18 entries) </entries>
<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/install</path> <type>file</type> <content> 1: #!/bin/bash 2: set -euo pipefail 3: 4: RED='\033[0;31m' 5: MUTED='\033[0;2m' 6: NC='\033[0m' 7: 8: # Sentry error telemetry — fire-and-forget error reporting via envelope API. 9: # Uses the CLI's public write-only DSN. No PII collected. 10: # Opt-out: SENTRY_CLI_NO_TELEMETRY=1 11: SENTRY_DSN_KEY="1188a86f3f8168f089450587b00bca66" 12: SENTRY_INGEST="https://o1.ingest.us.sentry.io" 13: SENTRY_PROJECT_ID="4510776311808000" 14: 15: # Generate a UUID for the event. Tries /proc, uuidgen, then awk fallback. ...
<path>/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/packages/cli/install</path>
<type>file</type>
<content>
201: die "Unsupported: windows-$arch (only windows-x64 is supported)" "detect-arch"
202: fi
203: fi
204:
205: # Download binary to a temp location
206: tmpdir="${TMPDIR:-${TMP:-${TEMP:-/tmp}}}"
207: tmp_binary="${tmpdir}/sentry-install-$$${suffix}"
208: version=""
209:
210: # Clean up temp binary on failure (setup handles cleanup on success)
211: trap 'rm -f "$tmp_binary"' EXIT
212:
213: if [[ "$requested_version" == "nightly" ]]; then
214: # Nightly build: download from GHCR via OCI blob protocol.
215: # No jq needed — parse JSON with awk.
216: # ghcr.io blob downloads redirect to Azure Blob Storage. curl -L would
217: # forward the Authorization header to Azure, which returns 404. Instead,
218: # extract the redirect URL and follow it without the auth header. ...
<path>/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/packages/cli/test/lib/install-script.test.ts</path>
<type>file</type>
<content>
1: /**
2: * Install Script Tests
3: *
4: * Exercises the shell installer with fake download tools so argument parsing and
5: * setup delegation can be validated without network access.
6: */
7:
8: import { spawn } from "node:child_process";
9: import {
10: chmodSync,
11: mkdirSync,
12: mkdtempSync,
13: readFileSync,
14: rmSync,
15: writeFileSync,
16: } from "node:fs";
17: import { tmpdir } from "node:os";
18: import { join } from "node:path";
19: import { afterEach, beforeEach, describe, expect, test } from "vitest";
20: import { UPGRADE_SOURCES } from "../../src/lib/binary.js";
21:
22: function noop(): void {
23: // Intentionally empty — absorbs async spawn errors
24: }
25:
26: const repoRoot = join(import.meta.dirname, "..", "..");
27: const installScript = join(repoRoot, ...
Found 100 matches (more matches available)
/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/packages/cli/test/lib/api/releases.test.ts:
Line 20: mockGetRepositoryName: vi.fn((): string | null => "getsentry/cli"),
Line 266: name: "getsentry/cli",
Line 267: url: "https://github.com/getsentry/cli",
Line 276: mockGetRepositoryName.mockReturnValue("getsentry/cli");
Line 319: repository: "getsentry/cli",
/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/packages/cli/test/lib/upgrade.test.ts:
Line 980: "https://github.com/getsentry/cli/releases/download/"
/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/packages/cli/test/lib/api/issues.test.ts:
Line 53: parseResolveSpec(`${RESOLVE_COMMIT_EXPLICIT_PREFIX}getsentry/cli@abc123`)
Line 56: spec: { kind: "explicit", ...
<path>/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/packages/cli/src/lib/binary.ts</path>
<type>file</type>
<content>
90: *
91: * Defined here (alongside other installation constants like
92: * {@link KNOWN_CURL_DIRS}) so that both `upgrade.ts` and
93: * `db/install-info.ts` can import it without creating a circular
94: * dependency.
95: */
96: export type InstallationMethod =
97: | "curl"
98: | "brew"
99: | "npm"
100: | "pnpm"
101: | "bun"
102: | "yarn"
103: | "unknown";
104:
105: /** A repository pair that hosts CLI stable releases and nightly OCI images. */
106: export type UpgradeSource = {
107: /** GitHub `owner/repository` containing CLI release assets. */
108: readonly githubRepo: string;
109: /** GHCR `owner/package` containing CLI nightly images and delta patches. */
110: readonly ghcrRepo: string;
111: /** Prefix attached to CLI release tags in this repository. ...
Found 52 matches
/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/packages/cli/src/lib/upgrade.ts:
Line 36: isNightlyVersion,
Line 81: /** The git tag used for the rolling nightly GitHub release (stable fallback only). */
Line 82: export const NIGHTLY_TAG = "nightly";
Line 457: * Fetch the latest nightly version from GHCR.
Line 460: * `:nightly` tag. The version is extracted from the manifest annotation —
Line 464: * @returns Latest nightly version string (e.g., "0.13.0-dev.1740000000")
Line 489: * - nightly channel: fetches version from GHCR manifest annotation
Line 494: * @param channel - Release channel ("stable" or "nightly"), defaults to "stable"
Line 502: if (channel === "nightly") {
Line 511: * Check if a versioned nightly tag exists in GHCR.
Line 513: * Nightly builds are published to GHCR with tags like `nightly-0.14.0-dev.1772661724`. ...
<path>/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/packages/cli/src/lib/upgrade.ts</path>
<type>file</type>
<content>
1: /**
2: * Upgrade Module
3: *
4: * Detects how the CLI was installed and provides self-upgrade functionality.
5: * Binary management helpers (download URLs, locking, replacement) live in
6: * binary.ts and are shared with the setup --install flow.
7: */
8:
9: import { spawn } from "node:child_process";
10: import {
11: chmodSync,
12: closeSync,
13: existsSync,
14: openSync,
15: realpathSync,
16: statSync,
17: unlinkSync,
18: writeSync,
19: } from "node:fs";
20: import { writeFile } from "node:fs/promises";
21: import { homedir } from "node:os";
22: import { dirname, isAbsolute, join, sep } from "node:path";
23: import { setTimeout } from "node:timers/promises";
24: import {
25: acquireLock,
26: cleanupOldBinary,
27: determineInstallDir,
28: fetchWithUpgradeError,
29: ...
<path>/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/packages/cli/src/lib/upgrade.ts</path>
<type>file</type>
<content>
430: * @returns Latest version string
431: * @throws {UpgradeError} When fetch fails or response is invalid
432: */
433: export async function fetchLatestFromNpm(): Promise<string> {
434: const response = await fetchWithUpgradeError(
435: `${NPM_REGISTRY_URL}/latest`,
436: { headers: { Accept: "application/json" } },
437: "npm registry"
438: );
439:
440: if (!response.ok) {
441: throw new UpgradeError(
442: "network_error",
443: `Failed to fetch from npm: ${response.status}`
444: );
445: }
446:
447: const data = (await response.json()) as { version?: string };
448:
449: if (!data.version) {
450: throw new UpgradeError("network_error", "No version found in npm registry");
451: }
452:
453: return data.version;
454: }
455:
456: /**
457: * Fetch the ...
M packages/cli/src/lib/binary.ts
M packages/cli/test/lib/binary.test.ts
M packages/cli/test/lib/ghcr.test.ts
M packages/cli/test/lib/install-script.test.ts
diff --git a/packages/cli/src/lib/binary.ts b/packages/cli/src/lib/binary.ts
index 75582612a..a50bc0949 100644
--- a/packages/cli/src/lib/binary.ts
+++ b/packages/cli/src/lib/binary.ts
@@ -102,6 +102,33 @@ export type InstallationMethod =
| "yarn"
| "unknown";
+/** A repository pair that hosts CLI stable releases and nightly OCI images. */
+export type UpgradeSource = {
+ /** GitHub `owner/repository` containing CLI release assets. */
+ readonly githubRepo: string;
+ /** GHCR `owner/package` containing CLI nightly images and delta patches. */
+ readonly ghcrRepo: string;
+ /** Prefix attached to CLI release tags in this repository. */
+ readonly tagPrefix: string;
+};
+
+/** Ordered CLI release sources. The resolver falls through only on HTTP 404. ...
diff --git a/packages/cli/test/lib/binary.test.ts b/packages/cli/test/lib/binary.test.ts
index 6fcfb3b1a..444fddf77 100644
--- a/packages/cli/test/lib/binary.test.ts
+++ b/packages/cli/test/lib/binary.test.ts
@@ -31,8 +31,10 @@ import {
isDowngrade,
isMusl,
releaseLock,
+ resolveUpgradeSource,
replaceBinarySync,
samePath,
+ UPGRADE_SOURCES,
} from "../../src/lib/binary.js";
import { UpgradeError } from "../../src/lib/errors.js";
@@ -61,6 +63,113 @@ describe("getBinaryDownloadUrl", () => {
});
});
+describe("UPGRADE_SOURCES", () => {
+ test("checks Toolkit before the legacy CLI repository", () => {
+ expect(UPGRADE_SOURCES).toEqual([
+ {
+ githubRepo: "getsentry/toolkit",
+ ghcrRepo: "getsentry/toolkit",
+ tagPrefix: "cli@",
+ },
+ {
+ githubRepo: "getsentry/cli",
+ ghcrRepo: "getsentry/cli",
+ tagPrefix: "",
+ },
+ ]);
+ });
+});
+
+describe("resolveUpgradeSource", () => {
+ test("uses ...
<path>/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/.craft.yml</path> <type>file</type> <content> 1: minVersion: '2.21.1' 2: changelog: 3: policy: auto 4: versioning: 5: policy: auto 6: preReleaseCommand: bash -c 'cd packages/cli && node --experimental-strip-types script/bump-version.ts --pre' 7: postReleaseCommand: bash -c 'cd packages/cli && node --experimental-strip-types script/bump-version.ts --post' 8: artifactProvider: 9: name: github 10: config: 11: artifacts: 12: Build: 13: - '/^sentry-.*$/' 14: - 'npm-package' 15: - 'vercel' 16: targets: 17: - name: npm 18: - name: github 19: - name: vercel 20: projectId: prj_wVkOnIwI3eIQbGD1Gw7qS1MqFFIK 21: - name: registry 22: apps: 23: 'app:sentry': 24: name: 'Sentry CLI' 25: packageUrl: 'https://www.npmjs.com/package/sentry' 26: mainDocsUrl: 'https://cli.sentry.dev' 27: urlTemplate: ...
<path>/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/packages/cli/package.json</path>
<type>file</type>
<content>
1: {
2: "name": "sentry",
3: "version": "0.45.0-dev.0",
4: "description": "Sentry CLI - A command-line interface for using Sentry built by robots and humans for robots and humans",
5: "repository": {
6: "type": "git",
7: "url": "git+https://github.com/getsentry/cli.git"
8: },
9: "main": "./dist/index.cjs",
10: "type": "module",
11: "types": "./dist/index.d.cts",
12: "exports": {
13: ".": {
14: "import": {
15: "types": "./dist/index.d.mts",
16: "default": "./dist/index.mjs"
17: },
18: "require": {
19: "types": "./dist/index.d.cts",
20: "default": "./dist/index.cjs"
21: }
22: }
23: },
24: "bin": {
25: "sentry": "./dist/bin.cjs"
26: },
27: "files": [
28: "dist/bin.cjs",
29: "dist/index.cjs",
30: ...
Found 45 matches /home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/apps/cli-docs/src/fragments/commands/issue.md: Line 220: sentry issue resolve CLI-G5 --in @commit:getsentry/cli@abc123def /home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/pnpm-lock.yaml: Line 1548: '@sentry/cli@2.58.6': Line 4207: trpc-cli@0.12.4: Line 6000: '@sentry/cli@2.58.6': Line 9255: trpc-cli@0.12.4(@trpc/server@11.18.0(typescript@5.9.3))(valibot@1.4.2(typescript@5.9.3))(zod@4.4.3): /home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/packages/cli/plugins/sentry-cli/skills/sentry-cli/references/issue.md: Line 288: sentry issue resolve CLI-G5 --in @commit:getsentry/cli@abc123def /home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/packages/cli/test/lib/binary.test.ts: ...
Found 100 matches (more matches available)
/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade/packages/cli/test/lib/upgrade.test.ts:
Line 499: annotations: { version: "0.0.0-dev.1740393600" },
Line 508: expect(version).toBe("0.0.0-dev.1740393600");
Line 521: annotations: { version: "0.0.0-dev.1740393600" },
Line 530: expect(version).toBe("0.0.0-dev.1740393600");
Line 646: const exists = await versionExists("curl", "0.14.0-dev.1772661724");
Line 662: const exists = await versionExists("curl", "0.14.0-dev.9999999999");
Line 679: const exists = await versionExists("npm", "0.14.0-dev.1772661724");
Line 688: versionExists("curl", "0.14.0-dev.1772661724")
Line 702: versionExists("curl", "0.14.0-dev.1772661724")
Line 1503: expect(isNightlyVersion("0.0.0-dev.1740000000")).toBe(true);
Line 1504: ...
Date: Sep 9, 2026 * 🟡 (09:33) `fetchLatestFromNpm()` in `packages/cli/src/lib/upgrade.ts:433-454` requests `${NPM_REGISTRY_URL}/latest` with `Accept: application/json`; non-OK responses raise `UpgradeError("network_error", "Failed to fetch from npm: <status>")`, missing `version` raises `UpgradeError("network_error", "No version found in npm registry")`, and success returns `data.version`. * 🟡 …
Date: Sep 9, 2026 * 🔴 [requested-read-only-analysis] (09:30) User requested read-only analysis in `/home/byk/.local/share/opencode/worktree/0e8c2f3bbe145a3280d6fb6ed900a5121f382cf0/toolkit-bridge-upgrade`; explicitly instructed not to edit files. * 🟡 (09:30) User asked to analyze `packages/cli/install` and `packages/cli/test/lib/install-script.test.ts`. * 🟡 (09:30) User asked for the smallest …