From 8db2948361519eb262e681bbc4dfaf6ea97e608a Mon Sep 17 00:00:00 2001 From: Bryan Morgan Date: Wed, 18 Mar 2026 21:52:23 -0400 Subject: [PATCH] fix(cli): correctly handle auto-update for standalone binaries (#23038) --- packages/cli/src/utils/handleAutoUpdate.test.ts | 7 ++++++- packages/cli/src/utils/handleAutoUpdate.ts | 9 ++++++--- packages/cli/src/utils/installationInfo.test.ts | 13 +++++++++++++ packages/cli/src/utils/installationInfo.ts | 11 +++++++++++ 4 files changed, 36 insertions(+), 4 deletions(-) diff --git a/packages/cli/src/utils/handleAutoUpdate.test.ts b/packages/cli/src/utils/handleAutoUpdate.test.ts index b10204834b..94795bf94e 100644 --- a/packages/cli/src/utils/handleAutoUpdate.test.ts +++ b/packages/cli/src/utils/handleAutoUpdate.test.ts @@ -202,7 +202,12 @@ describe('handleAutoUpdate', () => { expect(mockSpawn).not.toHaveBeenCalled(); }); - it.each([PackageManager.NPX, PackageManager.PNPX, PackageManager.BUNX])( + it.each([ + PackageManager.NPX, + PackageManager.PNPX, + PackageManager.BUNX, + PackageManager.BINARY, + ])( 'should suppress update notifications when running via %s', (packageManager) => { mockGetInstallationInfo.mockReturnValue({ diff --git a/packages/cli/src/utils/handleAutoUpdate.ts b/packages/cli/src/utils/handleAutoUpdate.ts index 348acd33b0..bd0effa53b 100644 --- a/packages/cli/src/utils/handleAutoUpdate.ts +++ b/packages/cli/src/utils/handleAutoUpdate.ts @@ -87,9 +87,12 @@ export function handleAutoUpdate( ); if ( - [PackageManager.NPX, PackageManager.PNPX, PackageManager.BUNX].includes( - installationInfo.packageManager, - ) + [ + PackageManager.NPX, + PackageManager.PNPX, + PackageManager.BUNX, + PackageManager.BINARY, + ].includes(installationInfo.packageManager) ) { return; } diff --git a/packages/cli/src/utils/installationInfo.test.ts b/packages/cli/src/utils/installationInfo.test.ts index ca1120c0e3..fbebec8bf7 100644 --- a/packages/cli/src/utils/installationInfo.test.ts +++ b/packages/cli/src/utils/installationInfo.test.ts @@ -58,6 +58,19 @@ describe('getInstallationInfo', () => { process.argv = originalArgv; }); + it('should detect running as a standalone binary', () => { + vi.stubEnv('IS_BINARY', 'true'); + process.argv[1] = '/path/to/binary'; + const info = getInstallationInfo(projectRoot, true); + expect(info.packageManager).toBe(PackageManager.BINARY); + expect(info.isGlobal).toBe(true); + expect(info.updateMessage).toBe( + 'Running as a standalone binary. Please update by downloading the latest version from GitHub.', + ); + expect(info.updateCommand).toBeUndefined(); + vi.unstubAllEnvs(); + }); + it('should return UNKNOWN when cliPath is not available', () => { process.argv[1] = ''; const info = getInstallationInfo(projectRoot, true); diff --git a/packages/cli/src/utils/installationInfo.ts b/packages/cli/src/utils/installationInfo.ts index a682cc75e1..39d77ba640 100644 --- a/packages/cli/src/utils/installationInfo.ts +++ b/packages/cli/src/utils/installationInfo.ts @@ -21,6 +21,7 @@ export enum PackageManager { BUNX = 'bunx', HOMEBREW = 'homebrew', NPX = 'npx', + BINARY = 'binary', UNKNOWN = 'unknown', } @@ -41,6 +42,16 @@ export function getInstallationInfo( } try { + // Check for standalone binary first + if (process.env['IS_BINARY'] === 'true') { + return { + packageManager: PackageManager.BINARY, + isGlobal: true, + updateMessage: + 'Running as a standalone binary. Please update by downloading the latest version from GitHub.', + }; + } + // Normalize path separators to forward slashes for consistent matching. const realPath = fs.realpathSync(cliPath).replace(/\\/g, '/'); const normalizedProjectRoot = projectRoot?.replace(/\\/g, '/');