11import { arch } from 'process' ;
22import type { ConfigurationChangeEvent } from 'vscode' ;
33import { version as codeVersion , Disposable , env , ProgressLocation , Uri , window , workspace } from 'vscode' ;
4- import { urls } from '../../../../constants' ;
54import type { Source , Sources } from '../../../../constants.telemetry' ;
65import type { Container } from '../../../../container' ;
76import type { SubscriptionChangeEvent } from '../../../../plus/gk/subscriptionService' ;
@@ -11,18 +10,19 @@ import {
1110} from '../../../../plus/gk/utils/-webview/mcp.utils' ;
1211import { registerCommand } from '../../../../system/-webview/command' ;
1312import { configuration } from '../../../../system/-webview/configuration' ;
14- import { getHostAppName } from '../../../../system/-webview/vscode' ;
13+ import { getHostAppName , isHostVSCode } from '../../../../system/-webview/vscode' ;
1514import { openUrl } from '../../../../system/-webview/vscode/uris' ;
1615import { gate } from '../../../../system/decorators/gate' ;
16+ import { debug , log } from '../../../../system/decorators/log' ;
1717import { Logger } from '../../../../system/logger' ;
18- import { getLogScope } from '../../../../system/logger.scope' ;
18+ import { getLogScope , setLogScopeExit } from '../../../../system/logger.scope' ;
1919import { compare } from '../../../../system/version' ;
2020import { run } from '../../git/shell' ;
2121import { getPlatform , isWeb } from '../../platform' ;
2222import { CliCommandHandlers } from './commands' ;
2323import type { IpcServer } from './ipcServer' ;
2424import { createIpcServer } from './ipcServer' ;
25- import { runCLICommand , toMcpInstallProvider } from './utils' ;
25+ import { runCLICommand , showManualMcpSetupPrompt , toMcpInstallProvider } from './utils' ;
2626
2727const enum CLIInstallErrorReason {
2828 UnsupportedPlatform ,
@@ -107,17 +107,21 @@ export class GkCliIntegrationProvider implements Disposable {
107107 }
108108
109109 @gate ( )
110+ @log ( { exit : true } )
110111 private async setupMCP ( source ?: Sources ) : Promise < void > {
112+ const scope = getLogScope ( ) ;
113+
111114 await this . container . storage . store ( 'mcp:banner:dismissed' , true ) ;
115+
112116 const commandSource = source ?? 'commandPalette' ;
113- const scope = getLogScope ( ) ;
114117 let cliVersion : string | undefined ;
115118 if ( this . container . telemetry . enabled ) {
116119 this . container . telemetry . sendEvent ( 'mcp/setup/started' , { source : commandSource } ) ;
117120 }
118121
119122 if ( isWeb ) {
120- void window . showErrorMessage ( 'GitKraken MCP setup is not supported on this platform.' ) ;
123+ setLogScopeExit ( scope , 'GitKraken MCP setup is not supported on the web' ) ;
124+ void window . showWarningMessage ( 'GitKraken MCP setup is not supported on the web.' ) ;
121125 if ( this . container . telemetry . enabled ) {
122126 this . container . telemetry . sendEvent ( 'mcp/setup/failed' , {
123127 reason : 'web environment unsupported' ,
@@ -127,24 +131,11 @@ export class GkCliIntegrationProvider implements Disposable {
127131 return ;
128132 }
129133
130- const appName = toMcpInstallProvider ( await getHostAppName ( ) ) ;
131- if ( appName == null ) {
132- void window . showInformationMessage ( `Failed to setup the GitKraken MCP: Could not determine app name` ) ;
133- if ( this . container . telemetry . enabled ) {
134- this . container . telemetry . sendEvent ( 'mcp/setup/failed' , {
135- reason : 'no app name' ,
136- source : commandSource ,
137- } ) ;
138- }
139- return ;
140- }
134+ const hostAppName = await getHostAppName ( ) ;
141135
142136 try {
143- if (
144- ( appName === 'vscode' || appName === 'vscode-insiders' || appName === 'vscode-exploration' ) &&
145- compare ( codeVersion , '1.102' ) < 0
146- ) {
147- void window . showInformationMessage ( 'Use of this command requires VS Code 1.102 or later.' ) ;
137+ if ( isHostVSCode ( hostAppName ) && compare ( codeVersion , '1.102' ) < 0 ) {
138+ void window . showWarningMessage ( 'GitKraken MCP setup requires VS Code 1.102 or later.' ) ;
148139 if ( this . container . telemetry . enabled ) {
149140 this . container . telemetry . sendEvent ( 'mcp/setup/failed' , {
150141 reason : 'unsupported vscode version' ,
@@ -193,17 +184,20 @@ export class GkCliIntegrationProvider implements Disposable {
193184 case CLIInstallErrorReason . ProxyExtract :
194185 case CLIInstallErrorReason . CoreDirectory :
195186 case CLIInstallErrorReason . CoreInstall :
196- void window . showErrorMessage ( 'Failed to install the GitKraken MCP server locally.' ) ;
187+ void window . showErrorMessage (
188+ 'Unable to locally install the GitKraken MCP server. Please try again.' ,
189+ ) ;
197190 failureReason = 'local installation failed' ;
198191 break ;
199192 default :
200193 void window . showErrorMessage (
201- `Failed to setup the GitKraken MCP: ${ ex instanceof Error ? ex . message : 'Unknown error.' } ` ,
194+ `Unable to setup the GitKraken MCP: ${ ex instanceof Error ? ex . message : 'Unknown error.' } ` ,
202195 ) ;
203196 break ;
204197 }
205198 }
206199
200+ Logger . error ( ex , scope , `Error during MCP installation: ${ ex } ` ) ;
207201 if ( this . container . telemetry . enabled ) {
208202 this . container . telemetry . sendEvent ( 'mcp/setup/failed' , {
209203 reason : failureReason ,
@@ -215,7 +209,7 @@ export class GkCliIntegrationProvider implements Disposable {
215209 }
216210
217211 if ( cliPath == null ) {
218- void window . showErrorMessage ( 'Failed to setup the GitKraken MCP: Unknown error. ') ;
212+ setLogScopeExit ( scope , undefined , ' GitKraken MCP setup failed; installation failed ') ;
219213 if ( this . container . telemetry . enabled ) {
220214 this . container . telemetry . sendEvent ( 'mcp/setup/failed' , {
221215 reason : 'unknown error' ,
@@ -224,35 +218,39 @@ export class GkCliIntegrationProvider implements Disposable {
224218 'cli.version' : cliVersion ,
225219 } ) ;
226220 }
221+
222+ void window . showErrorMessage (
223+ 'Unable to setup the GitKraken MCP: installation failed. Please try again.' ,
224+ ) ;
227225 return ;
228226 }
229227
230228 // If MCP extension registration is supported, don't proceed with manual setup
231229 if ( supportsMcpExtensionRegistration ( ) ) {
230+ setLogScopeExit ( scope , 'supports provider-based MCP registration' ) ;
232231 return ;
233232 }
234233
235- if ( appName !== 'cursor' && appName !== 'vscode' && appName !== 'vscode-insiders' ) {
236- const confirmation = await window . showInformationMessage (
237- `GitKraken MCP installed successfully. Click 'Finish' to add it to your MCP server list and complete the setup.` ,
238- { modal : true } ,
239- { title : 'Finish' } ,
240- { title : 'Cancel' , isCloseAffordance : true } ,
241- ) ;
242- if ( confirmation == null || confirmation . title === 'Cancel' ) {
243- if ( this . container . telemetry . enabled ) {
244- this . container . telemetry . sendEvent ( 'mcp/setup/failed' , {
245- reason : 'user cancelled' ,
246- source : commandSource ,
247- 'cli.version' : cliVersion ,
248- } ) ;
249- }
250- return ;
234+ const mcpInstallAppName = toMcpInstallProvider ( hostAppName ) ;
235+ if ( mcpInstallAppName == null ) {
236+ setLogScopeExit ( scope , undefined , `GitKraken MCP setup failed; unsupported host: ${ hostAppName } ` ) ;
237+ if ( this . container . telemetry . enabled ) {
238+ this . container . telemetry . sendEvent ( 'mcp/setup/failed' , {
239+ reason : 'no app name' ,
240+ source : commandSource ,
241+ 'cli.version' : cliVersion ,
242+ } ) ;
251243 }
244+
245+ void showManualMcpSetupPrompt (
246+ 'Automatic setup of the GitKraken MCP is not currently supported in this IDE. You may be able to configure it by adding the GitKraken MCP to your configuration manually.' ,
247+ ) ;
248+
249+ return ;
252250 }
253251
254252 let output = await runCLICommand (
255- [ 'mcp' , 'install' , appName , '--source=gitlens' , `--scheme=${ env . uriScheme } ` ] ,
253+ [ 'mcp' , 'install' , mcpInstallAppName , '--source=gitlens' , `--scheme=${ env . uriScheme } ` ] ,
256254 {
257255 cwd : cliPath ,
258256 } ,
@@ -269,34 +267,28 @@ export class GkCliIntegrationProvider implements Disposable {
269267 }
270268 return ;
271269 } else if ( CLIProxyMCPInstallOutputs . notASupportedClient . test ( output ) ) {
270+ setLogScopeExit ( scope , undefined , `GitKraken MCP setup failed; unsupported host: ${ hostAppName } ` ) ;
272271 if ( this . container . telemetry . enabled ) {
273272 this . container . telemetry . sendEvent ( 'mcp/setup/failed' , {
274273 reason : 'unsupported app' ,
275- 'error.message' : `Not a supported MCP client: ${ appName } ` ,
274+ 'error.message' : `Not a supported MCP client: ${ hostAppName } ` ,
276275 source : commandSource ,
277276 'cli.version' : cliVersion ,
278277 } ) ;
279278 }
280279
281- const learnMore = { title : 'View Setup Instructions' } ;
282- const cancel = { title : 'Cancel' , isCloseAffordance : true } ;
283- const result = await window . showInformationMessage (
284- "This application doesn't support automatic MCP setup. Please add the GitKraken MCP to your configuration manually." ,
285- { modal : true } ,
286- learnMore ,
287- cancel ,
280+ void showManualMcpSetupPrompt (
281+ 'Automatic setup of the GitKraken MCP is not currently supported in this IDE. You should be able to configure it by adding the GitKraken MCP to your configuration manually.' ,
288282 ) ;
289- if ( result === learnMore ) {
290- void openUrl ( urls . helpCenterMCP ) ;
291- }
292-
293283 return ;
294284 }
295285
296286 // Check if the output is a valid url. If so, run it
297287 try {
298288 new URL ( output ) ;
299289 } catch {
290+ setLogScopeExit ( scope , undefined , `GitKraken MCP setup failed; unexpected output from mcp install` ) ;
291+ Logger . error ( undefined , scope , `Unexpected output from mcp install command: ${ output } ` ) ;
300292 if ( this . container . telemetry . enabled ) {
301293 this . container . telemetry . sendEvent ( 'mcp/setup/failed' , {
302294 reason : 'unexpected output from mcp install command' ,
@@ -305,8 +297,10 @@ export class GkCliIntegrationProvider implements Disposable {
305297 'cli.version' : cliVersion ,
306298 } ) ;
307299 }
308- Logger . error ( `Unexpected output from mcp install command: ${ output } ` , scope ) ;
309- void window . showErrorMessage ( `Failed to setup the GitKraken MCP: unknown error` ) ;
300+
301+ void showManualMcpSetupPrompt (
302+ 'Unable to setup the GitKraken MCP. If this issue persists, please try adding the GitKraken MCP to your configuration manually.' ,
303+ ) ;
310304 return ;
311305 }
312306
@@ -319,7 +313,7 @@ export class GkCliIntegrationProvider implements Disposable {
319313 } ) ;
320314 }
321315 } catch ( ex ) {
322- Logger . error ( `Error during MCP installation: ${ ex } ` , scope ) ;
316+ Logger . error ( ex , scope , `Error during MCP installation: ${ ex } ` ) ;
323317 if ( this . container . telemetry . enabled ) {
324318 this . container . telemetry . sendEvent ( 'mcp/setup/failed' , {
325319 reason : 'unknown error' ,
@@ -330,16 +324,19 @@ export class GkCliIntegrationProvider implements Disposable {
330324 }
331325
332326 void window . showErrorMessage (
333- `Failed to setup the GitKraken MCP: ${ ex instanceof Error ? ex . message : 'Unknown error' } ` ,
327+ `Unable to setup the GitKraken MCP: ${ ex instanceof Error ? ex . message : 'Unknown error' } ` ,
334328 ) ;
335329 }
336330 }
337331
338332 @gate ( )
333+ @log ( { exit : true } )
339334 private async installCLI (
340335 autoInstall ?: boolean ,
341336 source ?: Sources ,
342337 ) : Promise < { cliVersion ?: string ; cliPath ?: string ; status : 'completed' | 'unsupported' | 'attempted' } > {
338+ const scope = getLogScope ( ) ;
339+
343340 const cliInstall = this . container . storage . get ( 'gk:cli:install' ) ;
344341 let cliInstallAttempts = cliInstall ?. attempts ?? 0 ;
345342 let cliInstallStatus = cliInstall ?. status ?? 'attempted' ;
@@ -427,6 +424,7 @@ export class GkCliIntegrationProvider implements Disposable {
427424 attempts : cliInstallAttempts ,
428425 } )
429426 . catch ( ) ;
427+
430428 throw new CLIInstallError ( CLIInstallErrorReason . UnsupportedPlatform , undefined , platform ) ;
431429 }
432430 }
@@ -624,6 +622,8 @@ export class GkCliIntegrationProvider implements Disposable {
624622 }
625623 } catch ( ex ) {
626624 Logger . error (
625+ ex ,
626+ scope ,
627627 `Failed to ${ autoInstall ? 'auto-install' : 'install' } CLI: ${ ex instanceof Error ? ex . message : 'Unknown error during installation' } ` ,
628628 ) ;
629629 if ( this . container . telemetry . enabled ) {
@@ -645,7 +645,10 @@ export class GkCliIntegrationProvider implements Disposable {
645645 return { cliVersion : cliVersion , cliPath : cliPath , status : cliInstallStatus } ;
646646 }
647647
648+ @debug ( )
648649 private async authCLI ( ) : Promise < void > {
650+ const scope = getLogScope ( ) ;
651+
649652 const cliInstall = this . container . storage . get ( 'gk:cli:install' ) ;
650653 const cliPath = this . container . storage . get ( 'gk:cli:path' ) ;
651654 if ( cliInstall ?. status !== 'completed' || cliPath == null ) {
@@ -660,7 +663,7 @@ export class GkCliIntegrationProvider implements Disposable {
660663 try {
661664 await runCLICommand ( [ 'auth' , 'login' , '-t' , currentSessionToken ] ) ;
662665 } catch ( ex ) {
663- Logger . error ( `Failed to auth CLI: ${ ex instanceof Error ? ex . message : String ( ex ) } ` ) ;
666+ Logger . error ( ex , scope ) ;
664667 }
665668 }
666669
0 commit comments