Skip to content

Commit 42efa1b

Browse files
axosoft-raminteamodio
authored andcommitted
Improves MCP checks and adds offline check (#4687)
1 parent 14ffd2d commit 42efa1b

File tree

6 files changed

+50
-16
lines changed

6 files changed

+50
-16
lines changed

src/container.ts

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -190,6 +190,7 @@ export class Container {
190190
this._context = context;
191191
this._prerelease = prerelease;
192192
this._version = version;
193+
this._previousVersion = previousVersion;
193194
this.ensureModeApplied();
194195

195196
this._disposables = [
@@ -747,6 +748,11 @@ export class Container {
747748
return this._version;
748749
}
749750

751+
private readonly _previousVersion: string | undefined;
752+
get previousVersion(): string | undefined {
753+
return this._previousVersion;
754+
}
755+
750756
private readonly _views: Views;
751757
get views(): Views {
752758
return this._views;

src/env/browser/platform.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import type { Platform } from '../node/platform';
22

33
export const isWeb = true;
4+
export const isOffline = false;
45

56
const _platform = (navigator as any)?.userAgentData?.platform;
67
const _userAgent = navigator.userAgent;

src/env/node/gk/cli/integration.ts

Lines changed: 38 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,8 @@ import { gate } from '../../../../system/decorators/gate';
1616
import { debug, log } from '../../../../system/decorators/log';
1717
import { Logger } from '../../../../system/logger';
1818
import { getLogScope, setLogScopeExit } from '../../../../system/logger.scope';
19-
import { compare } from '../../../../system/version';
20-
import { getPlatform, isWeb } from '../../platform';
19+
import { compare, fromString, satisfies } from '../../../../system/version';
20+
import { getPlatform, isOffline, isWeb } from '../../platform';
2121
import { CliCommandHandlers } from './commands';
2222
import type { IpcServer } from './ipcServer';
2323
import { createIpcServer } from './ipcServer';
@@ -32,6 +32,7 @@ const enum CLIInstallErrorReason {
3232
ProxyFetch,
3333
GlobalStorageDirectory,
3434
CoreInstall,
35+
Offline,
3536
}
3637

3738
const enum McpSetupErrorReason {
@@ -44,6 +45,7 @@ const enum McpSetupErrorReason {
4445
UnsupportedHost,
4546
UnsupportedClient,
4647
UnexpectedOutput,
48+
Offline,
4749
}
4850

4951
export interface CliCommandRequest {
@@ -118,6 +120,15 @@ export class GkCliIntegrationProvider implements Disposable {
118120
return;
119121
}
120122

123+
// Reset the attempts count if GitLens extension version has changed
124+
if (
125+
reachedMaxAttempts(cliInstall) &&
126+
this.container.version !== this.container.previousVersion &&
127+
satisfies(fromString(this.container.version), '>= 17.6')
128+
) {
129+
void this.container.storage.store('gk:cli:install', undefined);
130+
}
131+
121132
if (!mcpExtensionRegistrationAllowed() || reachedMaxAttempts(cliInstall)) {
122133
return;
123134
}
@@ -164,6 +175,7 @@ export class GkCliIntegrationProvider implements Disposable {
164175
switch (ex.reason) {
165176
case McpSetupErrorReason.WebUnsupported:
166177
case McpSetupErrorReason.VSCodeVersionUnsupported:
178+
case McpSetupErrorReason.Offline:
167179
void window.showWarningMessage(ex.message);
168180
break;
169181
case McpSetupErrorReason.InstallationFailed:
@@ -383,6 +395,12 @@ export class GkCliIntegrationProvider implements Disposable {
383395
message = 'Unable to locally install the GitKraken MCP server. Please try again.';
384396
telemetryReason = 'local installation failed';
385397
break;
398+
case CLIInstallErrorReason.Offline:
399+
reason = McpSetupErrorReason.Offline;
400+
message =
401+
'Unable to setup the GitKraken MCP server when offline. Please try again when you are online.';
402+
telemetryReason = 'offline';
403+
break;
386404
default:
387405
reason = McpSetupErrorReason.CLIUnknownError;
388406
message = 'Unable to setup the GitKraken MCP: Unknown error.';
@@ -446,6 +464,21 @@ export class GkCliIntegrationProvider implements Disposable {
446464
}
447465

448466
try {
467+
if (isWeb) {
468+
void this.container.storage
469+
.store('gk:cli:install', {
470+
status: 'unsupported',
471+
attempts: cliInstallAttempts,
472+
})
473+
.catch();
474+
475+
throw new CLIInstallError(CLIInstallErrorReason.UnsupportedPlatform, undefined, 'web');
476+
}
477+
478+
if (isOffline) {
479+
throw new CLIInstallError(CLIInstallErrorReason.Offline);
480+
}
481+
449482
cliInstallAttempts += 1;
450483
if (this.container.telemetry.enabled) {
451484
this.container.telemetry.sendEvent('cli/install/started', {
@@ -461,17 +494,6 @@ export class GkCliIntegrationProvider implements Disposable {
461494
})
462495
.catch();
463496

464-
if (isWeb) {
465-
void this.container.storage
466-
.store('gk:cli:install', {
467-
status: 'unsupported',
468-
attempts: cliInstallAttempts,
469-
})
470-
.catch();
471-
472-
throw new CLIInstallError(CLIInstallErrorReason.UnsupportedPlatform, undefined, 'web');
473-
}
474-
475497
// Map platform names for the API and get architecture
476498
let platformName: string;
477499
let architecture: string;
@@ -797,6 +819,9 @@ class CLIInstallError extends Error {
797819
case CLIInstallErrorReason.GlobalStorageDirectory:
798820
message = 'Failed to create global storage directory';
799821
break;
822+
case CLIInstallErrorReason.Offline:
823+
message = 'Offline';
824+
break;
800825
default:
801826
message = 'An unknown error occurred';
802827
break;

src/env/node/platform.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
1-
import { tmpdir } from 'os';
1+
import { networkInterfaces, tmpdir } from 'os';
22
import { join } from 'path';
33
import { platform } from 'process';
44
import { env, UIKind } from 'vscode';
55

66
export const isWeb = env.uiKind === UIKind.Web;
7+
export const isOffline = Object.values(networkInterfaces()).every(iface => iface?.every(addr => addr.internal));
78

89
export const isLinux = platform === 'linux';
910
export const isMac = platform === 'darwin';

src/extension.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -395,6 +395,7 @@ async function showWhatsNew(
395395

396396
function showMcp(version: string, previousVersion: string | undefined): void {
397397
if (
398+
isWeb ||
398399
previousVersion == null ||
399400
version === previousVersion ||
400401
compare(version, previousVersion) !== 1 ||

src/plus/gk/utils/-webview/mcp.utils.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
import { env, lm, version } from 'vscode';
2-
import { isWeb } from '@env/platform';
2+
import { isOffline, isWeb } from '@env/platform';
33
import type { Container } from '../../../../container';
44
import { configuration } from '../../../../system/-webview/configuration';
55
import { satisfies } from '../../../../system/version';
@@ -15,7 +15,7 @@ export function isMcpBannerEnabled(container: Container, showAutoRegistration =
1515

1616
const supportedApps = ['Visual Studio Code', 'Visual Studio Code - Insiders', 'Visual Studio Code - Exploration'];
1717
export function supportsMcpExtensionRegistration(): boolean {
18-
if (isWeb || !supportedApps.includes(env.appName)) {
18+
if (isWeb || isOffline || !supportedApps.includes(env.appName)) {
1919
return false;
2020
}
2121

0 commit comments

Comments
 (0)