From 743dbec36d2ebaa2de785410e41ef8d843bffe51 Mon Sep 17 00:00:00 2001 From: 777genius Date: Thu, 16 Apr 2026 22:17:41 +0300 Subject: [PATCH] fix(extensions): surface cli healthcheck failures in action tooltips --- src/shared/utils/extensionNormalizers.ts | 8 ++++++- .../shared/utils/extensionNormalizers.test.ts | 21 ++++++++++++++++--- 2 files changed, 25 insertions(+), 4 deletions(-) diff --git a/src/shared/utils/extensionNormalizers.ts b/src/shared/utils/extensionNormalizers.ts index a5c6420e..ecff2758 100644 --- a/src/shared/utils/extensionNormalizers.ts +++ b/src/shared/utils/extensionNormalizers.ts @@ -149,7 +149,10 @@ export function getInstallationSummaryLabel( */ export function getExtensionActionDisableReason(options: { isInstalled: boolean; - cliStatus: Pick | null; + cliStatus: Pick< + CliInstallationStatus, + 'installed' | 'authLoggedIn' | 'binaryPath' | 'launchError' + > | null; cliStatusLoading: boolean; }): string | null { const { isInstalled, cliStatus, cliStatusLoading } = options; @@ -162,6 +165,9 @@ export function getExtensionActionDisableReason(options: { } if (cliStatus.installed === false) { + if (cliStatus.binaryPath && cliStatus.launchError) { + return 'Claude CLI was found but failed to start. Open the Dashboard to repair or reinstall it.'; + } return 'Claude CLI required. Install it from the Dashboard.'; } diff --git a/test/shared/utils/extensionNormalizers.test.ts b/test/shared/utils/extensionNormalizers.test.ts index 427a22bb..b78f1bdc 100644 --- a/test/shared/utils/extensionNormalizers.test.ts +++ b/test/shared/utils/extensionNormalizers.test.ts @@ -207,7 +207,7 @@ describe('getExtensionActionDisableReason', () => { expect( getExtensionActionDisableReason({ isInstalled: false, - cliStatus: { installed: true, authLoggedIn: false }, + cliStatus: { installed: true, authLoggedIn: false, binaryPath: null, launchError: null }, cliStatusLoading: false, }), ).toContain('not signed in'); @@ -217,7 +217,7 @@ describe('getExtensionActionDisableReason', () => { expect( getExtensionActionDisableReason({ isInstalled: true, - cliStatus: { installed: true, authLoggedIn: false }, + cliStatus: { installed: true, authLoggedIn: false, binaryPath: null, launchError: null }, cliStatusLoading: false, }), ).toBeNull(); @@ -227,11 +227,26 @@ describe('getExtensionActionDisableReason', () => { expect( getExtensionActionDisableReason({ isInstalled: true, - cliStatus: { installed: false, authLoggedIn: false }, + cliStatus: { installed: false, authLoggedIn: false, binaryPath: null, launchError: null }, cliStatusLoading: false, }), ).toContain('Claude CLI required'); }); + + it('surfaces startup health-check failures separately from missing CLI', () => { + expect( + getExtensionActionDisableReason({ + isInstalled: false, + cliStatus: { + installed: false, + authLoggedIn: false, + binaryPath: '/usr/local/bin/claude', + launchError: 'spawn EACCES', + }, + cliStatusLoading: false, + }), + ).toContain('failed to start'); + }); }); describe('sanitizeMcpServerName', () => {