From c895d4e792b537b65c140813b68331642cfee1bc Mon Sep 17 00:00:00 2001 From: Ramin Tadayon Date: Wed, 25 Jun 2025 15:44:07 -0700 Subject: [PATCH 01/14] Adds support for mcp server installation --- contributions.json | 4 + package.json | 9 + src/constants.commands.generated.ts | 1 + src/constants.storage.ts | 1 + src/env/node/gk/cli/integration.ts | 304 +++++++++++++++++++++++++++- 5 files changed, 317 insertions(+), 2 deletions(-) diff --git a/contributions.json b/contributions.json index ee0b5382a6f5d..19a19a12e9d48 100644 --- a/contributions.json +++ b/contributions.json @@ -320,6 +320,10 @@ "icon": "$(sparkle)", "commandPalette": "gitlens:enabled && !gitlens:untrusted && gitlens:gk:organization:ai:enabled" }, + "gitlens.ai.mcp.install": { + "label": "Install MCP Server", + "commandPalette": "gitlens:enabled && !gitlens:untrusted && gitlens:gk:organization:ai:enabled" + }, "gitlens.ai.rebaseOntoCommit:graph": { "label": "AI Rebase Current Branch onto Commit (Preview)...", "icon": "$(sparkle)", diff --git a/package.json b/package.json index fd6d178556902..8a384ac3fdc71 100644 --- a/package.json +++ b/package.json @@ -6283,6 +6283,11 @@ "category": "GitLens", "icon": "$(sparkle)" }, + { + "command": "gitlens.ai.mcp.install", + "title": "Install MCP Server", + "category": "GitLens" + }, { "command": "gitlens.ai.rebaseOntoCommit:graph", "title": "AI Rebase Current Branch onto Commit (Preview)...", @@ -10847,6 +10852,10 @@ "command": "gitlens.ai.generateRebase", "when": "gitlens:enabled && !gitlens:untrusted && gitlens:gk:organization:ai:enabled" }, + { + "command": "gitlens.ai.mcp.install", + "when": "gitlens:enabled && !gitlens:untrusted && gitlens:gk:organization:ai:enabled" + }, { "command": "gitlens.ai.rebaseOntoCommit:graph", "when": "false" diff --git a/src/constants.commands.generated.ts b/src/constants.commands.generated.ts index 342b3527c021f..deb83a4c7346b 100644 --- a/src/constants.commands.generated.ts +++ b/src/constants.commands.generated.ts @@ -657,6 +657,7 @@ export type ContributedPaletteCommands = | 'gitlens.ai.generateCommitMessage' | 'gitlens.ai.generateCommits' | 'gitlens.ai.generateRebase' + | 'gitlens.ai.mcp.install' | 'gitlens.ai.switchProvider' | 'gitlens.applyPatchFromClipboard' | 'gitlens.associateIssueWithBranch' diff --git a/src/constants.storage.ts b/src/constants.storage.ts index 66d5a647ab089..369985d8cb59e 100644 --- a/src/constants.storage.ts +++ b/src/constants.storage.ts @@ -63,6 +63,7 @@ export type DeprecatedGlobalStorage = { }; export type GlobalStorage = { + 'ai:mcp:attemptInstall': boolean; avatars: [string, StoredAvatar][]; 'confirm:ai:generateCommits': boolean; 'confirm:ai:generateRebase': boolean; diff --git a/src/env/node/gk/cli/integration.ts b/src/env/node/gk/cli/integration.ts index 150d197351aac..8c4e1ec15e00c 100644 --- a/src/env/node/gk/cli/integration.ts +++ b/src/env/node/gk/cli/integration.ts @@ -1,7 +1,13 @@ +import { arch } from 'process'; import type { ConfigurationChangeEvent } from 'vscode'; -import { Disposable } from 'vscode'; +import { Disposable, ProgressLocation, Uri, window, workspace } from 'vscode'; import type { Container } from '../../../../container'; +import { registerCommand } from '../../../../system/-webview/command'; import { configuration } from '../../../../system/-webview/configuration'; +import { getContext } from '../../../../system/-webview/context'; +import { Logger } from '../../../../system/logger'; +import { run } from '../../git/shell'; +import { getPlatform, isWeb } from '../../platform'; import { CliCommandHandlers } from './commands'; import type { IpcServer } from './ipcServer'; import { createIpcServer } from './ipcServer'; @@ -18,9 +24,15 @@ export class GkCliIntegrationProvider implements Disposable { private _runningDisposable: Disposable | undefined; constructor(private readonly container: Container) { - this._disposable = configuration.onDidChange(e => this.onConfigurationChanged(e)); + this._disposable = Disposable.from( + configuration.onDidChange(e => this.onConfigurationChanged(e)), + ...this.registerCommands(), + ); this.onConfigurationChanged(); + setTimeout(() => { + void this.installMCPIfNeeded(true); + }, 10000 + Math.floor(Math.random() * 20000)); } dispose(): void { @@ -56,4 +68,292 @@ export class GkCliIntegrationProvider implements Disposable { this._runningDisposable?.dispose(); this._runningDisposable = undefined; } + + private async installMCPIfNeeded(silent?: boolean): Promise { + try { + if (silent && this.container.storage.get('ai:mcp:attemptInstall', false)) { + return; + } + + // Store the flag to indicate that we have made the attempt + await this.container.storage.store('ai:mcp:attemptInstall', true); + + if (configuration.get('ai.enabled') === false) { + const message = 'Cannot install MCP: AI is disabled in settings'; + Logger.log(message); + if (silent !== true) { + void window.showErrorMessage(message); + } + return; + } + + if ( getContext('gitlens:gk:organization:ai:enabled', true) !== true) { + const message = 'Cannot install MCP: AI is disabled by your organization'; + Logger.log(message); + if (silent !== true) { + void window.showErrorMessage(message); + } + return; + } + + if (isWeb) { + const message = 'Cannot install MCP: web environment is not supported'; + Logger.log(message); + if (silent !== true) { + void window.showErrorMessage(message); + } + return; + } + + // Detect platform and architecture + const platform = getPlatform(); + + // Map platform names for the API and get architecture + let platformName: string; + let architecture: string; + + switch (arch) { + case 'x64': + architecture = 'x64'; + break; + case 'arm64': + architecture = 'arm64'; + break; + default: + architecture = 'x86'; // Default to x86 for other architectures + break; + } + + switch (platform) { + case 'windows': + platformName = 'windows'; + break; + case 'macOS': + platformName = 'darwin'; + break; + case 'linux': + platformName = 'linux'; + break; + default: { + const message = `Skipping MCP installation: unsupported platform ${platform}`; + Logger.log(message); + if (silent !== true) { + void window.showErrorMessage(`Cannot install MCP integration: unsupported platform ${platform}`); + } + return; + } + } + + // Wrap the main installation process with progress indicator if not silent + const installationTask = async () => { + let mcpInstallerPath: Uri | undefined; + let mcpExtractedFolderPath: Uri | undefined; + let mcpExtractedPath: Uri | undefined; + + try { + // Download the MCP proxy installer + const proxyUrl = `https://api.gitkraken.dev/releases/gkcli-proxy/production/${platformName}/${architecture}/active`; + + let response = await fetch(proxyUrl); + if (!response.ok) { + const errorMsg = `Failed to get MCP installer proxy: ${response.status} ${response.statusText}`; + Logger.error(errorMsg); + throw new Error(errorMsg); + } + + let downloadUrl: string | undefined; + try { + const mcpInstallerInfo: { version?: string; packages?: { zip?: string } } | undefined = await response.json() as any; + downloadUrl = mcpInstallerInfo?.packages?.zip; + } catch (ex) { + const errorMsg = `Failed to parse MCP installer info: ${ex}`; + Logger.error(errorMsg); + throw new Error(errorMsg); + } + + if (downloadUrl == null) { + const errorMsg = 'Failed to find download URL for MCP proxy installer'; + Logger.error(errorMsg); + throw new Error(errorMsg); + } + + response = await fetch(downloadUrl); + if (!response.ok) { + const errorMsg = `Failed to download MCP proxy installer: ${response.status} ${response.statusText}`; + Logger.error(errorMsg); + throw new Error(errorMsg); + } + + const installerData = await response.arrayBuffer(); + if (installerData.byteLength === 0) { + const errorMsg = 'Downloaded installer is empty'; + Logger.error(errorMsg); + throw new Error(errorMsg); + } + // installer file name is the last part of the download URL + const installerFileName = downloadUrl.substring(downloadUrl.lastIndexOf('/') + 1); + mcpInstallerPath = Uri.joinPath(this.container.context.globalStorageUri, installerFileName); + + // Ensure the global storage directory exists + await workspace.fs.createDirectory(this.container.context.globalStorageUri); + + // Write the installer to the extension storage + await workspace.fs.writeFile(mcpInstallerPath, new Uint8Array(installerData)); + Logger.log(`Downloaded MCP proxy installer successfully`); + + try { + // Use the run function to extract the installer file from the installer zip + if (platform === 'windows') { + // On Windows, use PowerShell to extract the zip file + await run( + 'powershell.exe', + ['-Command', `Expand-Archive -Path "${mcpInstallerPath.fsPath}" -DestinationPath "${this.container.context.globalStorageUri.fsPath}"`], + 'utf8', + ); + } else { + // On Unix-like systems, use the unzip command to extract the zip file + await run( + 'unzip', + ['-o', mcpInstallerPath.fsPath, '-d', this.container.context.globalStorageUri.fsPath], + 'utf8', + ); + } + // The gk.exe file should be in a subfolder named after the installer file name + const extractedFolderName = installerFileName.replace(/\.zip$/, ''); + mcpExtractedFolderPath = Uri.joinPath(this.container.context.globalStorageUri, extractedFolderName); + mcpExtractedPath = Uri.joinPath(mcpExtractedFolderPath, 'gk.exe'); + + // Check using stat to make sure the newly extracted file exists. + await workspace.fs.stat(mcpExtractedPath); + } catch (error) { + const errorMsg = `Failed to extract MCP installer: ${error}`; + Logger.error(errorMsg); + throw new Error(errorMsg); + } + + // Get the VS Code settings.json file path + // TODO: Make this path point to the current vscode profile's settings.json once the API supports it + const settingsPath = `${this.container.context.globalStorageUri.fsPath}\\..\\..\\settings.json`; + + // Configure the MCP server in settings.json + try { + await run(mcpExtractedPath.fsPath, ['mcp', 'install', 'vscode', '--file-path', settingsPath], 'utf8'); + } catch { + // Try alternative execution methods based on platform + try { + Logger.log('Attempting alternative execution method for MCP install...'); + if (platform === 'windows') { + // On Windows, try running with cmd.exe + await run( + 'cmd.exe', + [ + '/c', + `"${mcpExtractedPath.fsPath}"`, + 'mcp', + 'install', + 'vscode', + '--file-path', + `"${settingsPath}"`, + ], + 'utf8', + ); + } else { + // On Unix-like systems, try running with sh + await run( + '/bin/sh', + ['-c', `"${mcpExtractedPath.fsPath}" mcp install vscode --file-path "${settingsPath}"`], + 'utf8', + ); + } + } catch (altError) { + const errorMsg = `MCP server configuration failed: ${altError}`; + Logger.error(errorMsg); + throw new Error(errorMsg); + } + } + + // Verify that the MCP server was actually configured in settings.json + try { + const settingsUri = Uri.file(settingsPath); + const settingsData = await workspace.fs.readFile(settingsUri); + const settingsJson = JSON.parse(settingsData.toString()); + + if (!settingsJson?.['mcp']?.['servers']?.['GitKraken']) { + const errorMsg = 'MCP server configuration verification failed: Unable to update MCP settings'; + Logger.error(errorMsg); + throw new Error(errorMsg); + } + + Logger.log('MCP configured successfully - GitKraken server verified in settings.json'); + } catch (verifyError) { + if (verifyError instanceof Error && verifyError.message.includes('verification failed')) { + // Re-throw verification errors as-is + throw verifyError; + } + // Handle file read/parse errors + const errorMsg = `Failed to verify MCP configuration in settings.json: ${verifyError}`; + Logger.error(errorMsg); + throw new Error(errorMsg); + } + } finally { + // Always clean up downloaded/extracted files, even if something failed + if (mcpInstallerPath != null) { + try { + await workspace.fs.delete(mcpInstallerPath); + } catch (error) { + Logger.warn(`Failed to delete MCP installer zip file: ${error}`); + } + } + + if (mcpExtractedPath != null) { + try { + await workspace.fs.delete(mcpExtractedPath); + } catch (error) { + Logger.warn(`Failed to delete MCP extracted executable: ${error}`); + } + } + + if (mcpExtractedFolderPath != null) { + try { + await workspace.fs.delete(Uri.joinPath(mcpExtractedFolderPath, 'README.md')); + await workspace.fs.delete(mcpExtractedFolderPath); + } catch (error) { + Logger.warn(`Failed to delete MCP extracted folder: ${error}`); + } + } + } + }; + + // Execute the installation task with or without progress indicator + if (silent !== true) { + await window.withProgress( + { + location: ProgressLocation.Notification, + title: 'Installing MCP integration...', + cancellable: false, + }, + async () => { + await installationTask(); + } + ); + + // Show success notification if not silent + void window.showInformationMessage('MCP integration installed successfully'); + } else { + await installationTask(); + } + + } catch (error) { + Logger.error(`Error during MCP installation: ${error}`); + + // Show error notification if not silent + if (silent !== true) { + void window.showErrorMessage(`Failed to install MCP integration: ${error instanceof Error ? error.message : String(error)}`); + } + } + } + + private registerCommands(): Disposable[] { + return [registerCommand('gitlens.ai.mcp.install', () => this.installMCPIfNeeded())]; + } } From 589d83154506ecd8330b9a04c4a0f334d86dd0e8 Mon Sep 17 00:00:00 2001 From: Ramin Tadayon Date: Thu, 26 Jun 2025 13:13:05 -0700 Subject: [PATCH 02/14] Updates command and params --- src/env/node/gk/cli/integration.ts | 61 +++++++++++++++++------------- 1 file changed, 34 insertions(+), 27 deletions(-) diff --git a/src/env/node/gk/cli/integration.ts b/src/env/node/gk/cli/integration.ts index 8c4e1ec15e00c..52ca58ee7286e 100644 --- a/src/env/node/gk/cli/integration.ts +++ b/src/env/node/gk/cli/integration.ts @@ -1,6 +1,6 @@ import { arch } from 'process'; import type { ConfigurationChangeEvent } from 'vscode'; -import { Disposable, ProgressLocation, Uri, window, workspace } from 'vscode'; +import { Disposable, env, ProgressLocation, Uri, window, workspace } from 'vscode'; import type { Container } from '../../../../container'; import { registerCommand } from '../../../../system/-webview/command'; import { configuration } from '../../../../system/-webview/configuration'; @@ -231,13 +231,33 @@ export class GkCliIntegrationProvider implements Disposable { throw new Error(errorMsg); } + // Get the app name + let appName = 'vscode'; + switch (env.appName) { + case 'Visual Studio Code': + case 'Visual Studio Code - Insiders': + appName = 'vscode'; + break; + case 'Cursor': + appName = 'cursor'; + break; + case 'Windsurf': + appName = 'windsurf'; + break; + default: { + const errorMsg = `Failed to install MCP: unsupported app name - ${env.appName}`; + Logger.error(errorMsg); + throw new Error(errorMsg); + } + } + // Get the VS Code settings.json file path - // TODO: Make this path point to the current vscode profile's settings.json once the API supports it - const settingsPath = `${this.container.context.globalStorageUri.fsPath}\\..\\..\\settings.json`; + // TODO: Use this path to point to the current vscode profile's settings.json once the API supports it. + // const settingsPath = `${this.container.context.globalStorageUri.fsPath}\\..\\..\\settings.json`; // Configure the MCP server in settings.json try { - await run(mcpExtractedPath.fsPath, ['mcp', 'install', 'vscode', '--file-path', settingsPath], 'utf8'); + await run('gk.exe', ['mcp', 'install', appName/*, '--file-path', settingsPath*/], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); } catch { // Try alternative execution methods based on platform try { @@ -251,9 +271,9 @@ export class GkCliIntegrationProvider implements Disposable { `"${mcpExtractedPath.fsPath}"`, 'mcp', 'install', - 'vscode', - '--file-path', - `"${settingsPath}"`, + appName, + /*'--file-path', + settingsPath,*/ ], 'utf8', ); @@ -261,7 +281,8 @@ export class GkCliIntegrationProvider implements Disposable { // On Unix-like systems, try running with sh await run( '/bin/sh', - ['-c', `"${mcpExtractedPath.fsPath}" mcp install vscode --file-path "${settingsPath}"`], + // ['-c', `"${mcpExtractedPath.fsPath}" mcp install vscode --file-path "${settingsPath}"`], + ['-c', `"${mcpExtractedPath.fsPath}" mcp install ${appName}`], 'utf8', ); } @@ -273,28 +294,14 @@ export class GkCliIntegrationProvider implements Disposable { } // Verify that the MCP server was actually configured in settings.json - try { - const settingsUri = Uri.file(settingsPath); - const settingsData = await workspace.fs.readFile(settingsUri); - const settingsJson = JSON.parse(settingsData.toString()); - - if (!settingsJson?.['mcp']?.['servers']?.['GitKraken']) { - const errorMsg = 'MCP server configuration verification failed: Unable to update MCP settings'; - Logger.error(errorMsg); - throw new Error(errorMsg); - } - - Logger.log('MCP configured successfully - GitKraken server verified in settings.json'); - } catch (verifyError) { - if (verifyError instanceof Error && verifyError.message.includes('verification failed')) { - // Re-throw verification errors as-is - throw verifyError; - } - // Handle file read/parse errors - const errorMsg = `Failed to verify MCP configuration in settings.json: ${verifyError}`; + const setting = workspace.getConfiguration('mcp.servers.GitKraken'); + if (!setting?.get('type') || !setting?.get('args') || !setting?.get('command')) { + const errorMsg = 'MCP server configuration verification failed: Unable to update MCP settings'; Logger.error(errorMsg); throw new Error(errorMsg); } + + Logger.log('MCP configured successfully - GitKraken server verified in settings.json'); } finally { // Always clean up downloaded/extracted files, even if something failed if (mcpInstallerPath != null) { From 72ce5a9c81082c73852367582d4a3b3499f237de Mon Sep 17 00:00:00 2001 From: Ramin Tadayon Date: Fri, 27 Jun 2025 12:22:13 -0700 Subject: [PATCH 03/14] Removes vscode-specific check --- src/env/node/gk/cli/integration.ts | 10 +--------- 1 file changed, 1 insertion(+), 9 deletions(-) diff --git a/src/env/node/gk/cli/integration.ts b/src/env/node/gk/cli/integration.ts index 52ca58ee7286e..d6ff5aea437bc 100644 --- a/src/env/node/gk/cli/integration.ts +++ b/src/env/node/gk/cli/integration.ts @@ -293,15 +293,7 @@ export class GkCliIntegrationProvider implements Disposable { } } - // Verify that the MCP server was actually configured in settings.json - const setting = workspace.getConfiguration('mcp.servers.GitKraken'); - if (!setting?.get('type') || !setting?.get('args') || !setting?.get('command')) { - const errorMsg = 'MCP server configuration verification failed: Unable to update MCP settings'; - Logger.error(errorMsg); - throw new Error(errorMsg); - } - - Logger.log('MCP configured successfully - GitKraken server verified in settings.json'); + Logger.log('MCP configuration completed'); } finally { // Always clean up downloaded/extracted files, even if something failed if (mcpInstallerPath != null) { From 556ca7b1b7cd26f7104c0f82843aa5fd5094c250 Mon Sep 17 00:00:00 2001 From: Ramin Tadayon Date: Mon, 30 Jun 2025 13:14:21 -0700 Subject: [PATCH 04/14] Updates url --- src/env/node/gk/cli/integration.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/env/node/gk/cli/integration.ts b/src/env/node/gk/cli/integration.ts index d6ff5aea437bc..4bd26fcd66def 100644 --- a/src/env/node/gk/cli/integration.ts +++ b/src/env/node/gk/cli/integration.ts @@ -152,7 +152,7 @@ export class GkCliIntegrationProvider implements Disposable { try { // Download the MCP proxy installer - const proxyUrl = `https://api.gitkraken.dev/releases/gkcli-proxy/production/${platformName}/${architecture}/active`; + const proxyUrl = this.container.urls.getGkApiUrl('releases', 'gkcli-proxy', 'production', platformName, architecture, 'active'); let response = await fetch(proxyUrl); if (!response.ok) { From eb0da385699ffc17343627cbd5a76ab8fd09fd6a Mon Sep 17 00:00:00 2001 From: Ramin Tadayon Date: Mon, 7 Jul 2025 10:16:17 -0700 Subject: [PATCH 05/14] Fixes install path on vscode insiders and updates PATH --- src/constants.storage.ts | 1 + src/env/node/gk/cli/integration.ts | 39 +++++++++++++++++++++++++++--- 2 files changed, 36 insertions(+), 4 deletions(-) diff --git a/src/constants.storage.ts b/src/constants.storage.ts index 369985d8cb59e..e18cbc2d2ab9d 100644 --- a/src/constants.storage.ts +++ b/src/constants.storage.ts @@ -81,6 +81,7 @@ export type GlobalStorage = { preVersion: string; 'product:config': Stored; 'confirm:draft:storage': boolean; + 'gk:cli:installedPath': string; 'home:sections:collapsed': string[]; 'home:walkthrough:dismissed': boolean; 'launchpad:groups:collapsed': StoredLaunchpadGroup[]; diff --git a/src/env/node/gk/cli/integration.ts b/src/env/node/gk/cli/integration.ts index 4bd26fcd66def..2cd7fd7be4f35 100644 --- a/src/env/node/gk/cli/integration.ts +++ b/src/env/node/gk/cli/integration.ts @@ -233,10 +233,12 @@ export class GkCliIntegrationProvider implements Disposable { // Get the app name let appName = 'vscode'; + let isInsiders = false; switch (env.appName) { case 'Visual Studio Code': + break; case 'Visual Studio Code - Insiders': - appName = 'vscode'; + isInsiders = true; break; case 'Cursor': appName = 'cursor'; @@ -251,13 +253,42 @@ export class GkCliIntegrationProvider implements Disposable { } } - // Get the VS Code settings.json file path + // Get the VS Code settings.json file path in case we are on VSCode Insiders // TODO: Use this path to point to the current vscode profile's settings.json once the API supports it. - // const settingsPath = `${this.container.context.globalStorageUri.fsPath}\\..\\..\\settings.json`; + const settingsPath = `${this.container.context.globalStorageUri.fsPath}\\..\\..\\settings.json`; // Configure the MCP server in settings.json try { - await run('gk.exe', ['mcp', 'install', appName/*, '--file-path', settingsPath*/], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); + const installOutput = await run('gk.exe', ['install'], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); + const directory = installOutput.match(/Directory: (.*)/); + if (directory != null) { + try { + const directoryPath = directory[1]; + await this.container.storage.store('gk:cli:installedPath', directoryPath); + if (platform === 'windows') { + await run( + 'powershell.exe', + [ + '-Command', + `[Environment]::SetEnvironmentVariable('Path', $env:Path + ';${directoryPath}', [EnvironmentVariableTarget]::User)`, + ], + 'utf8', + ); + } else { + await run( + 'export', + [`PATH=$PATH:${directoryPath}`], + 'utf8', + ); + } + } catch (error) { + Logger.warn(`Failed to add GK directory to PATH: ${error}`); + } + } else { + Logger.warn('Failed to find directory in GK install output'); + } + + await run('gk.exe', ['mcp', 'install', appName, ...isInsiders ? ['--file-path', settingsPath] : []], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); } catch { // Try alternative execution methods based on platform try { From 4d37400262a8161cfe30a0555521e25cb314946b Mon Sep 17 00:00:00 2001 From: Ramin Tadayon Date: Mon, 7 Jul 2025 10:16:32 -0700 Subject: [PATCH 06/14] Always sends success notification when installed --- src/env/node/gk/cli/integration.ts | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/src/env/node/gk/cli/integration.ts b/src/env/node/gk/cli/integration.ts index 2cd7fd7be4f35..d1de30bd41b74 100644 --- a/src/env/node/gk/cli/integration.ts +++ b/src/env/node/gk/cli/integration.ts @@ -366,13 +366,12 @@ export class GkCliIntegrationProvider implements Disposable { await installationTask(); } ); - - // Show success notification if not silent - void window.showInformationMessage('MCP integration installed successfully'); } else { await installationTask(); } + // Show success notification if not silent + void window.showInformationMessage('GitKraken MCP integration installed successfully'); } catch (error) { Logger.error(`Error during MCP installation: ${error}`); From 05f4372423601b5e7354661b290c52bbbda4c60a Mon Sep 17 00:00:00 2001 From: Ramin Tadayon Date: Tue, 8 Jul 2025 10:00:43 -0700 Subject: [PATCH 07/14] Also includes auth step if auth is available --- src/env/node/gk/cli/integration.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/src/env/node/gk/cli/integration.ts b/src/env/node/gk/cli/integration.ts index d1de30bd41b74..940b37b3d69ff 100644 --- a/src/env/node/gk/cli/integration.ts +++ b/src/env/node/gk/cli/integration.ts @@ -289,6 +289,12 @@ export class GkCliIntegrationProvider implements Disposable { } await run('gk.exe', ['mcp', 'install', appName, ...isInsiders ? ['--file-path', settingsPath] : []], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); + + const gkAuth = (await this.container.subscription.getAuthenticationSession())?.accessToken; + if (gkAuth != null) { + const output = await run('gk.exe', ['auth', 'login', '-t', gkAuth], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); + console.log(output); + } } catch { // Try alternative execution methods based on platform try { From ac63c628f6d0f1688fac995e4ee0c7c730287a0e Mon Sep 17 00:00:00 2001 From: Ramin Tadayon Date: Wed, 9 Jul 2025 15:15:03 -0700 Subject: [PATCH 08/14] Syncs auth to account changes --- src/constants.storage.ts | 2 +- src/env/node/gk/cli/integration.ts | 32 +++++++++++++++++++++++------- 2 files changed, 26 insertions(+), 8 deletions(-) diff --git a/src/constants.storage.ts b/src/constants.storage.ts index e18cbc2d2ab9d..542cf13e038de 100644 --- a/src/constants.storage.ts +++ b/src/constants.storage.ts @@ -63,7 +63,7 @@ export type DeprecatedGlobalStorage = { }; export type GlobalStorage = { - 'ai:mcp:attemptInstall': boolean; + 'ai:mcp:attemptInstall': string; avatars: [string, StoredAvatar][]; 'confirm:ai:generateCommits': boolean; 'confirm:ai:generateRebase': boolean; diff --git a/src/env/node/gk/cli/integration.ts b/src/env/node/gk/cli/integration.ts index 940b37b3d69ff..fac264ce5de6a 100644 --- a/src/env/node/gk/cli/integration.ts +++ b/src/env/node/gk/cli/integration.ts @@ -2,6 +2,7 @@ import { arch } from 'process'; import type { ConfigurationChangeEvent } from 'vscode'; import { Disposable, env, ProgressLocation, Uri, window, workspace } from 'vscode'; import type { Container } from '../../../../container'; +import type { SubscriptionChangeEvent } from '../../../../plus/gk/subscriptionService'; import { registerCommand } from '../../../../system/-webview/command'; import { configuration } from '../../../../system/-webview/configuration'; import { getContext } from '../../../../system/-webview/context'; @@ -27,6 +28,7 @@ export class GkCliIntegrationProvider implements Disposable { this._disposable = Disposable.from( configuration.onDidChange(e => this.onConfigurationChanged(e)), ...this.registerCommands(), + this.container.subscription.onDidChange(this.onSubscriptionChanged, this), ); this.onConfigurationChanged(); @@ -71,12 +73,11 @@ export class GkCliIntegrationProvider implements Disposable { private async installMCPIfNeeded(silent?: boolean): Promise { try { - if (silent && this.container.storage.get('ai:mcp:attemptInstall', false)) { + if (silent && this.container.storage.get('ai:mcp:attemptInstall')) { return; } - // Store the flag to indicate that we have made the attempt - await this.container.storage.store('ai:mcp:attemptInstall', true); + await this.container.storage.store('ai:mcp:attemptInstall', 'attempted'); if (configuration.get('ai.enabled') === false) { const message = 'Cannot install MCP: AI is disabled in settings'; @@ -292,8 +293,7 @@ export class GkCliIntegrationProvider implements Disposable { const gkAuth = (await this.container.subscription.getAuthenticationSession())?.accessToken; if (gkAuth != null) { - const output = await run('gk.exe', ['auth', 'login', '-t', gkAuth], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); - console.log(output); + await run('gk.exe', ['auth', 'login', '-t', gkAuth], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); } } catch { // Try alternative execution methods based on platform @@ -377,6 +377,7 @@ export class GkCliIntegrationProvider implements Disposable { } // Show success notification if not silent + await this.container.storage.store('ai:mcp:attemptInstall', 'completed'); void window.showInformationMessage('GitKraken MCP integration installed successfully'); } catch (error) { Logger.error(`Error during MCP installation: ${error}`); @@ -388,7 +389,24 @@ export class GkCliIntegrationProvider implements Disposable { } } - private registerCommands(): Disposable[] { - return [registerCommand('gitlens.ai.mcp.install', () => this.installMCPIfNeeded())]; + private async onSubscriptionChanged(e: SubscriptionChangeEvent): Promise { + const mcpInstallStatus = this.container.storage.get('ai:mcp:attemptInstall'); + if (e.current?.account?.id !== e.previous?.account?.id && mcpInstallStatus === 'completed') { + try { + await run('gk', ['auth', 'logout'], 'utf8'); + } catch {} + if (e.current?.account?.id !== null) { + const currentSessionToken = (await this.container.subscription.getAuthenticationSession())?.accessToken; + if (currentSessionToken != null) { + try { + await run('gk', ['auth', 'login', '-t', currentSessionToken], 'utf8'); + } catch {} + } + } } + } + + private registerCommands(): Disposable[] { + return [registerCommand('gitlens.ai.mcp.install', () => this.installMCPIfNeeded())]; + } } From edc0d0a196d825774d73ee380b563d23f7249b1e Mon Sep 17 00:00:00 2001 From: Ramin Tadayon Date: Wed, 9 Jul 2025 16:59:04 -0700 Subject: [PATCH 09/14] Reverts account sync and fixes mac/linux filename --- src/env/node/gk/cli/integration.ts | 36 ++++++++---------------------- 1 file changed, 9 insertions(+), 27 deletions(-) diff --git a/src/env/node/gk/cli/integration.ts b/src/env/node/gk/cli/integration.ts index fac264ce5de6a..eb84974711def 100644 --- a/src/env/node/gk/cli/integration.ts +++ b/src/env/node/gk/cli/integration.ts @@ -2,7 +2,6 @@ import { arch } from 'process'; import type { ConfigurationChangeEvent } from 'vscode'; import { Disposable, env, ProgressLocation, Uri, window, workspace } from 'vscode'; import type { Container } from '../../../../container'; -import type { SubscriptionChangeEvent } from '../../../../plus/gk/subscriptionService'; import { registerCommand } from '../../../../system/-webview/command'; import { configuration } from '../../../../system/-webview/configuration'; import { getContext } from '../../../../system/-webview/context'; @@ -28,7 +27,6 @@ export class GkCliIntegrationProvider implements Disposable { this._disposable = Disposable.from( configuration.onDidChange(e => this.onConfigurationChanged(e)), ...this.registerCommands(), - this.container.subscription.onDidChange(this.onSubscriptionChanged, this), ); this.onConfigurationChanged(); @@ -145,6 +143,8 @@ export class GkCliIntegrationProvider implements Disposable { } } + const mcpFileName = platform === 'windows' ? 'gk.exe' : 'gk'; + // Wrap the main installation process with progress indicator if not silent const installationTask = async () => { let mcpInstallerPath: Uri | undefined; @@ -219,10 +219,10 @@ export class GkCliIntegrationProvider implements Disposable { 'utf8', ); } - // The gk.exe file should be in a subfolder named after the installer file name + // The gk file should be in a subfolder named after the installer file name const extractedFolderName = installerFileName.replace(/\.zip$/, ''); mcpExtractedFolderPath = Uri.joinPath(this.container.context.globalStorageUri, extractedFolderName); - mcpExtractedPath = Uri.joinPath(mcpExtractedFolderPath, 'gk.exe'); + mcpExtractedPath = Uri.joinPath(mcpExtractedFolderPath, mcpFileName); // Check using stat to make sure the newly extracted file exists. await workspace.fs.stat(mcpExtractedPath); @@ -260,7 +260,7 @@ export class GkCliIntegrationProvider implements Disposable { // Configure the MCP server in settings.json try { - const installOutput = await run('gk.exe', ['install'], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); + const installOutput = await run(mcpFileName, ['install'], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); const directory = installOutput.match(/Directory: (.*)/); if (directory != null) { try { @@ -289,11 +289,11 @@ export class GkCliIntegrationProvider implements Disposable { Logger.warn('Failed to find directory in GK install output'); } - await run('gk.exe', ['mcp', 'install', appName, ...isInsiders ? ['--file-path', settingsPath] : []], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); + await run(mcpFileName, ['mcp', 'install', appName, ...isInsiders ? ['--file-path', settingsPath] : []], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); const gkAuth = (await this.container.subscription.getAuthenticationSession())?.accessToken; if (gkAuth != null) { - await run('gk.exe', ['auth', 'login', '-t', gkAuth], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); + await run(mcpFileName, ['auth', 'login', '-t', gkAuth], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); } } catch { // Try alternative execution methods based on platform @@ -309,8 +309,7 @@ export class GkCliIntegrationProvider implements Disposable { 'mcp', 'install', appName, - /*'--file-path', - settingsPath,*/ + ...isInsiders ? ['--file-path', settingsPath] : [], ], 'utf8', ); @@ -319,7 +318,7 @@ export class GkCliIntegrationProvider implements Disposable { await run( '/bin/sh', // ['-c', `"${mcpExtractedPath.fsPath}" mcp install vscode --file-path "${settingsPath}"`], - ['-c', `"${mcpExtractedPath.fsPath}" mcp install ${appName}`], + ['-c', `"${mcpExtractedPath.fsPath}" mcp install ${appName} ${isInsiders ? `--file-path ${settingsPath}` : ''}`], 'utf8', ); } @@ -389,23 +388,6 @@ export class GkCliIntegrationProvider implements Disposable { } } - private async onSubscriptionChanged(e: SubscriptionChangeEvent): Promise { - const mcpInstallStatus = this.container.storage.get('ai:mcp:attemptInstall'); - if (e.current?.account?.id !== e.previous?.account?.id && mcpInstallStatus === 'completed') { - try { - await run('gk', ['auth', 'logout'], 'utf8'); - } catch {} - if (e.current?.account?.id !== null) { - const currentSessionToken = (await this.container.subscription.getAuthenticationSession())?.accessToken; - if (currentSessionToken != null) { - try { - await run('gk', ['auth', 'login', '-t', currentSessionToken], 'utf8'); - } catch {} - } - } - } - } - private registerCommands(): Disposable[] { return [registerCommand('gitlens.ai.mcp.install', () => this.installMCPIfNeeded())]; } From 6fa7aba239060c5869e8c933491307164e4bced6 Mon Sep 17 00:00:00 2001 From: Ramin Tadayon Date: Thu, 10 Jul 2025 17:00:48 -0700 Subject: [PATCH 10/14] Improves path support, auth on future login --- src/env/node/gk/cli/integration.ts | 105 ++++++++++++++++------------- 1 file changed, 60 insertions(+), 45 deletions(-) diff --git a/src/env/node/gk/cli/integration.ts b/src/env/node/gk/cli/integration.ts index eb84974711def..f99ce97e08184 100644 --- a/src/env/node/gk/cli/integration.ts +++ b/src/env/node/gk/cli/integration.ts @@ -1,7 +1,9 @@ +import { homedir } from 'os'; import { arch } from 'process'; import type { ConfigurationChangeEvent } from 'vscode'; import { Disposable, env, ProgressLocation, Uri, window, workspace } from 'vscode'; import type { Container } from '../../../../container'; +import type { SubscriptionChangeEvent } from '../../../../plus/gk/subscriptionService'; import { registerCommand } from '../../../../system/-webview/command'; import { configuration } from '../../../../system/-webview/configuration'; import { getContext } from '../../../../system/-webview/context'; @@ -26,6 +28,7 @@ export class GkCliIntegrationProvider implements Disposable { constructor(private readonly container: Container) { this._disposable = Disposable.from( configuration.onDidChange(e => this.onConfigurationChanged(e)), + this.container.subscription.onDidChange(this.onSubscriptionChanged, this), ...this.registerCommands(), ); @@ -260,7 +263,7 @@ export class GkCliIntegrationProvider implements Disposable { // Configure the MCP server in settings.json try { - const installOutput = await run(mcpFileName, ['install'], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); + const installOutput = await run(platform === 'windows' ? mcpFileName : `./${mcpFileName}`, ['install'], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); const directory = installOutput.match(/Directory: (.*)/); if (directory != null) { try { @@ -276,60 +279,57 @@ export class GkCliIntegrationProvider implements Disposable { 'utf8', ); } else { - await run( - 'export', - [`PATH=$PATH:${directoryPath}`], - 'utf8', - ); + // For Unix-like systems, detect and modify the appropriate shell profile + const homeDir = homedir(); + // Try to detect which shell profile exists and is in use + const possibleProfiles = [ + { path: `${homeDir}/.zshrc`, shell: 'zsh' }, + { path: `${homeDir}/.zprofile`, shell: 'zsh' }, + { path: `${homeDir}/.bashrc`, shell: 'bash' }, + { path: `${homeDir}/.profile`, shell: 'sh' } + ]; + + // Find the first profile that exists + let shellProfile; + for (const profile of possibleProfiles) { + try { + await workspace.fs.stat(Uri.file(profile.path)); + shellProfile = profile.path; + break; + } catch { + // Profile doesn't exist, try next one + } + } + + if (shellProfile != null) { + await run( + 'sh', + ['-c', `echo '# Added by GitLens for MCP support' >> ${shellProfile} && echo 'export PATH="$PATH:${directoryPath}"' >> ${shellProfile}`], + 'utf8', + ); + } else { + Logger.warn('MCP Install: Failed to find shell profile to update PATH'); + } } } catch (error) { - Logger.warn(`Failed to add GK directory to PATH: ${error}`); + Logger.warn(`MCP Install: Failed to add directory to PATH: ${error}`); } } else { - Logger.warn('Failed to find directory in GK install output'); + Logger.warn('MCP Install: Failed to find directory in install output'); } - await run(mcpFileName, ['mcp', 'install', appName, ...isInsiders ? ['--file-path', settingsPath] : []], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); - + await run(platform === 'windows' ? mcpFileName : `./${mcpFileName}`, ['mcp', 'install', appName, ...isInsiders ? ['--file-path', settingsPath] : []], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); const gkAuth = (await this.container.subscription.getAuthenticationSession())?.accessToken; if (gkAuth != null) { - await run(mcpFileName, ['auth', 'login', '-t', gkAuth], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); - } - } catch { - // Try alternative execution methods based on platform - try { - Logger.log('Attempting alternative execution method for MCP install...'); - if (platform === 'windows') { - // On Windows, try running with cmd.exe - await run( - 'cmd.exe', - [ - '/c', - `"${mcpExtractedPath.fsPath}"`, - 'mcp', - 'install', - appName, - ...isInsiders ? ['--file-path', settingsPath] : [], - ], - 'utf8', - ); - } else { - // On Unix-like systems, try running with sh - await run( - '/bin/sh', - // ['-c', `"${mcpExtractedPath.fsPath}" mcp install vscode --file-path "${settingsPath}"`], - ['-c', `"${mcpExtractedPath.fsPath}" mcp install ${appName} ${isInsiders ? `--file-path ${settingsPath}` : ''}`], - 'utf8', - ); - } - } catch (altError) { - const errorMsg = `MCP server configuration failed: ${altError}`; - Logger.error(errorMsg); - throw new Error(errorMsg); + await run(platform === 'windows' ? mcpFileName : `./${mcpFileName}`, ['auth', 'login', '-t', gkAuth], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); } - } - Logger.log('MCP configuration completed'); + Logger.log('MCP configuration completed'); + } catch (error) { + const errorMsg = `MCP server configuration failed: ${error}`; + Logger.error(errorMsg); + throw new Error(errorMsg); + } } finally { // Always clean up downloaded/extracted files, even if something failed if (mcpInstallerPath != null) { @@ -388,6 +388,21 @@ export class GkCliIntegrationProvider implements Disposable { } } + private async onSubscriptionChanged(e: SubscriptionChangeEvent): Promise { + const mcpInstallStatus = this.container.storage.get('ai:mcp:attemptInstall'); + const mcpDirectoryPath = this.container.storage.get('gk:cli:installedPath'); + const platform = getPlatform(); + if (e.current?.account?.id != null && e.current.account.id !== e.previous?.account?.id && mcpInstallStatus === 'completed' && mcpDirectoryPath != null) { + const currentSessionToken = (await this.container.subscription.getAuthenticationSession())?.accessToken; + if (currentSessionToken != null) { + try { + await run(platform === 'windows' ? 'gk.exe' : './gk', ['auth', 'login', '-t', currentSessionToken], 'utf8', { cwd: mcpDirectoryPath }); + } catch {} + } + } + } + + private registerCommands(): Disposable[] { return [registerCommand('gitlens.ai.mcp.install', () => this.installMCPIfNeeded())]; } From fc373ebd1aad0a8f227b421e0f5417565dc21bcf Mon Sep 17 00:00:00 2001 From: Ramin Tadayon Date: Fri, 11 Jul 2025 14:04:35 -0700 Subject: [PATCH 11/14] Fixes formatting and updates to vscode link style installation --- src/env/node/gk/cli/integration.ts | 157 +++++++++++++++++++++-------- 1 file changed, 117 insertions(+), 40 deletions(-) diff --git a/src/env/node/gk/cli/integration.ts b/src/env/node/gk/cli/integration.ts index f99ce97e08184..17abcde5f208f 100644 --- a/src/env/node/gk/cli/integration.ts +++ b/src/env/node/gk/cli/integration.ts @@ -1,13 +1,15 @@ import { homedir } from 'os'; import { arch } from 'process'; import type { ConfigurationChangeEvent } from 'vscode'; -import { Disposable, env, ProgressLocation, Uri, window, workspace } from 'vscode'; +import { version as codeVersion, Disposable, env, ProgressLocation, Uri, window, workspace } from 'vscode'; import type { Container } from '../../../../container'; import type { SubscriptionChangeEvent } from '../../../../plus/gk/subscriptionService'; import { registerCommand } from '../../../../system/-webview/command'; import { configuration } from '../../../../system/-webview/configuration'; import { getContext } from '../../../../system/-webview/context'; +import { openUrl } from '../../../../system/-webview/vscode/uris'; import { Logger } from '../../../../system/logger'; +import { compare } from '../../../../system/version'; import { run } from '../../git/shell'; import { getPlatform, isWeb } from '../../platform'; import { CliCommandHandlers } from './commands'; @@ -33,9 +35,12 @@ export class GkCliIntegrationProvider implements Disposable { ); this.onConfigurationChanged(); - setTimeout(() => { - void this.installMCPIfNeeded(true); - }, 10000 + Math.floor(Math.random() * 20000)); + setTimeout( + () => { + void this.installMCPIfNeeded(true); + }, + 10000 + Math.floor(Math.random() * 20000), + ); } dispose(): void { @@ -74,6 +79,16 @@ export class GkCliIntegrationProvider implements Disposable { private async installMCPIfNeeded(silent?: boolean): Promise { try { + if ( + (env.appName === 'Visual Studio Code' || env.appName === 'Visual Studio Code - Insiders') && + compare(codeVersion, '1.102') < 0 + ) { + if (!silent) { + void window.showInformationMessage('Use of this command requires VS Code 1.102 or later.'); + } + return; + } + if (silent && this.container.storage.get('ai:mcp:attemptInstall')) { return; } @@ -89,7 +104,7 @@ export class GkCliIntegrationProvider implements Disposable { return; } - if ( getContext('gitlens:gk:organization:ai:enabled', true) !== true) { + if (getContext('gitlens:gk:organization:ai:enabled', true) !== true) { const message = 'Cannot install MCP: AI is disabled by your organization'; Logger.log(message); if (silent !== true) { @@ -140,7 +155,9 @@ export class GkCliIntegrationProvider implements Disposable { const message = `Skipping MCP installation: unsupported platform ${platform}`; Logger.log(message); if (silent !== true) { - void window.showErrorMessage(`Cannot install MCP integration: unsupported platform ${platform}`); + void window.showErrorMessage( + `Cannot install MCP integration: unsupported platform ${platform}`, + ); } return; } @@ -156,7 +173,14 @@ export class GkCliIntegrationProvider implements Disposable { try { // Download the MCP proxy installer - const proxyUrl = this.container.urls.getGkApiUrl('releases', 'gkcli-proxy', 'production', platformName, architecture, 'active'); + const proxyUrl = this.container.urls.getGkApiUrl( + 'releases', + 'gkcli-proxy', + 'production', + platformName, + architecture, + 'active', + ); let response = await fetch(proxyUrl); if (!response.ok) { @@ -167,7 +191,8 @@ export class GkCliIntegrationProvider implements Disposable { let downloadUrl: string | undefined; try { - const mcpInstallerInfo: { version?: string; packages?: { zip?: string } } | undefined = await response.json() as any; + const mcpInstallerInfo: { version?: string; packages?: { zip?: string } } | undefined = + (await response.json()) as any; downloadUrl = mcpInstallerInfo?.packages?.zip; } catch (ex) { const errorMsg = `Failed to parse MCP installer info: ${ex}`; @@ -211,7 +236,10 @@ export class GkCliIntegrationProvider implements Disposable { // On Windows, use PowerShell to extract the zip file await run( 'powershell.exe', - ['-Command', `Expand-Archive -Path "${mcpInstallerPath.fsPath}" -DestinationPath "${this.container.context.globalStorageUri.fsPath}"`], + [ + '-Command', + `Expand-Archive -Path "${mcpInstallerPath.fsPath}" -DestinationPath "${this.container.context.globalStorageUri.fsPath}"`, + ], 'utf8', ); } else { @@ -224,7 +252,10 @@ export class GkCliIntegrationProvider implements Disposable { } // The gk file should be in a subfolder named after the installer file name const extractedFolderName = installerFileName.replace(/\.zip$/, ''); - mcpExtractedFolderPath = Uri.joinPath(this.container.context.globalStorageUri, extractedFolderName); + mcpExtractedFolderPath = Uri.joinPath( + this.container.context.globalStorageUri, + extractedFolderName, + ); mcpExtractedPath = Uri.joinPath(mcpExtractedFolderPath, mcpFileName); // Check using stat to make sure the newly extracted file exists. @@ -263,12 +294,19 @@ export class GkCliIntegrationProvider implements Disposable { // Configure the MCP server in settings.json try { - const installOutput = await run(platform === 'windows' ? mcpFileName : `./${mcpFileName}`, ['install'], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); + const installOutput = await run( + platform === 'windows' ? mcpFileName : `./${mcpFileName}`, + ['install'], + 'utf8', + { cwd: mcpExtractedFolderPath.fsPath }, + ); const directory = installOutput.match(/Directory: (.*)/); + let directoryPath; if (directory != null) { try { - const directoryPath = directory[1]; + directoryPath = directory[1]; await this.container.storage.store('gk:cli:installedPath', directoryPath); + // Add to PATH if (platform === 'windows') { await run( 'powershell.exe', @@ -279,32 +317,35 @@ export class GkCliIntegrationProvider implements Disposable { 'utf8', ); } else { - // For Unix-like systems, detect and modify the appropriate shell profile - const homeDir = homedir(); - // Try to detect which shell profile exists and is in use - const possibleProfiles = [ - { path: `${homeDir}/.zshrc`, shell: 'zsh' }, + // For Unix-like systems, detect and modify the appropriate shell profile + const homeDir = homedir(); + // Try to detect which shell profile exists and is in use + const possibleProfiles = [ + { path: `${homeDir}/.zshrc`, shell: 'zsh' }, { path: `${homeDir}/.zprofile`, shell: 'zsh' }, - { path: `${homeDir}/.bashrc`, shell: 'bash' }, - { path: `${homeDir}/.profile`, shell: 'sh' } - ]; - - // Find the first profile that exists - let shellProfile; - for (const profile of possibleProfiles) { - try { - await workspace.fs.stat(Uri.file(profile.path)); - shellProfile = profile.path; - break; - } catch { - // Profile doesn't exist, try next one - } - } + { path: `${homeDir}/.bashrc`, shell: 'bash' }, + { path: `${homeDir}/.profile`, shell: 'sh' }, + ]; + + // Find the first profile that exists + let shellProfile; + for (const profile of possibleProfiles) { + try { + await workspace.fs.stat(Uri.file(profile.path)); + shellProfile = profile.path; + break; + } catch { + // Profile doesn't exist, try next one + } + } if (shellProfile != null) { await run( 'sh', - ['-c', `echo '# Added by GitLens for MCP support' >> ${shellProfile} && echo 'export PATH="$PATH:${directoryPath}"' >> ${shellProfile}`], + [ + '-c', + `echo '# Added by GitLens for MCP support' >> ${shellProfile} && echo 'export PATH="$PATH:${directoryPath}"' >> ${shellProfile}`, + ], 'utf8', ); } else { @@ -316,12 +357,37 @@ export class GkCliIntegrationProvider implements Disposable { } } else { Logger.warn('MCP Install: Failed to find directory in install output'); + if (appName === 'vscode') { + throw new Error('MCP command path not availavle'); + } + } + + if (appName === 'vscode') { + const config = { + name: 'GitKraken', + command: Uri.file(`${directoryPath}\\${mcpFileName}`).fsPath, + args: ['mcp'], + type: 'stdio', + }; + const installDeepLinkUrl = `${isInsiders ? 'vscode-insiders' : 'vscode'}:mcp/install?${encodeURIComponent(JSON.stringify(config))}`; + await openUrl(installDeepLinkUrl); + } else { + await run( + platform === 'windows' ? mcpFileName : `./${mcpFileName}`, + ['mcp', 'install', appName, ...(isInsiders ? ['--file-path', settingsPath] : [])], + 'utf8', + { cwd: mcpExtractedFolderPath.fsPath }, + ); } - await run(platform === 'windows' ? mcpFileName : `./${mcpFileName}`, ['mcp', 'install', appName, ...isInsiders ? ['--file-path', settingsPath] : []], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); const gkAuth = (await this.container.subscription.getAuthenticationSession())?.accessToken; if (gkAuth != null) { - await run(platform === 'windows' ? mcpFileName : `./${mcpFileName}`, ['auth', 'login', '-t', gkAuth], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }); + await run( + platform === 'windows' ? mcpFileName : `./${mcpFileName}`, + ['auth', 'login', '-t', gkAuth], + 'utf8', + { cwd: mcpExtractedFolderPath.fsPath }, + ); } Logger.log('MCP configuration completed'); @@ -369,7 +435,7 @@ export class GkCliIntegrationProvider implements Disposable { }, async () => { await installationTask(); - } + }, ); } else { await installationTask(); @@ -383,7 +449,9 @@ export class GkCliIntegrationProvider implements Disposable { // Show error notification if not silent if (silent !== true) { - void window.showErrorMessage(`Failed to install MCP integration: ${error instanceof Error ? error.message : String(error)}`); + void window.showErrorMessage( + `Failed to install MCP integration: ${error instanceof Error ? error.message : String(error)}`, + ); } } } @@ -392,17 +460,26 @@ export class GkCliIntegrationProvider implements Disposable { const mcpInstallStatus = this.container.storage.get('ai:mcp:attemptInstall'); const mcpDirectoryPath = this.container.storage.get('gk:cli:installedPath'); const platform = getPlatform(); - if (e.current?.account?.id != null && e.current.account.id !== e.previous?.account?.id && mcpInstallStatus === 'completed' && mcpDirectoryPath != null) { + if ( + e.current?.account?.id != null && + e.current.account.id !== e.previous?.account?.id && + mcpInstallStatus === 'completed' && + mcpDirectoryPath != null + ) { const currentSessionToken = (await this.container.subscription.getAuthenticationSession())?.accessToken; if (currentSessionToken != null) { try { - await run(platform === 'windows' ? 'gk.exe' : './gk', ['auth', 'login', '-t', currentSessionToken], 'utf8', { cwd: mcpDirectoryPath }); + await run( + platform === 'windows' ? 'gk.exe' : './gk', + ['auth', 'login', '-t', currentSessionToken], + 'utf8', + { cwd: mcpDirectoryPath }, + ); } catch {} } } } - private registerCommands(): Disposable[] { return [registerCommand('gitlens.ai.mcp.install', () => this.installMCPIfNeeded())]; } From 5c2ba99742f45fbfacdbb30d846efb0be8d0d9aa Mon Sep 17 00:00:00 2001 From: Ramin Tadayon Date: Mon, 14 Jul 2025 10:45:56 -0700 Subject: [PATCH 12/14] Keeps mcp proxy around, uses later for CLI auth --- src/constants.storage.ts | 1 + src/env/node/gk/cli/integration.ts | 26 +++++--------------------- 2 files changed, 6 insertions(+), 21 deletions(-) diff --git a/src/constants.storage.ts b/src/constants.storage.ts index 542cf13e038de..d025c700bbd58 100644 --- a/src/constants.storage.ts +++ b/src/constants.storage.ts @@ -64,6 +64,7 @@ export type DeprecatedGlobalStorage = { export type GlobalStorage = { 'ai:mcp:attemptInstall': string; + 'ai:mcp:installPath': string; avatars: [string, StoredAvatar][]; 'confirm:ai:generateCommits': boolean; 'confirm:ai:generateRebase': boolean; diff --git a/src/env/node/gk/cli/integration.ts b/src/env/node/gk/cli/integration.ts index 17abcde5f208f..0cc045f417fa9 100644 --- a/src/env/node/gk/cli/integration.ts +++ b/src/env/node/gk/cli/integration.ts @@ -260,6 +260,7 @@ export class GkCliIntegrationProvider implements Disposable { // Check using stat to make sure the newly extracted file exists. await workspace.fs.stat(mcpExtractedPath); + await this.container.storage.store('ai:mcp:installPath', mcpExtractedFolderPath.fsPath); } catch (error) { const errorMsg = `Failed to extract MCP installer: ${error}`; Logger.error(errorMsg); @@ -397,7 +398,6 @@ export class GkCliIntegrationProvider implements Disposable { throw new Error(errorMsg); } } finally { - // Always clean up downloaded/extracted files, even if something failed if (mcpInstallerPath != null) { try { await workspace.fs.delete(mcpInstallerPath); @@ -405,23 +405,6 @@ export class GkCliIntegrationProvider implements Disposable { Logger.warn(`Failed to delete MCP installer zip file: ${error}`); } } - - if (mcpExtractedPath != null) { - try { - await workspace.fs.delete(mcpExtractedPath); - } catch (error) { - Logger.warn(`Failed to delete MCP extracted executable: ${error}`); - } - } - - if (mcpExtractedFolderPath != null) { - try { - await workspace.fs.delete(Uri.joinPath(mcpExtractedFolderPath, 'README.md')); - await workspace.fs.delete(mcpExtractedFolderPath); - } catch (error) { - Logger.warn(`Failed to delete MCP extracted folder: ${error}`); - } - } } }; @@ -458,13 +441,14 @@ export class GkCliIntegrationProvider implements Disposable { private async onSubscriptionChanged(e: SubscriptionChangeEvent): Promise { const mcpInstallStatus = this.container.storage.get('ai:mcp:attemptInstall'); - const mcpDirectoryPath = this.container.storage.get('gk:cli:installedPath'); + const mcpInstallPath = this.container.storage.get('ai:mcp:installPath'); + const platform = getPlatform(); if ( e.current?.account?.id != null && e.current.account.id !== e.previous?.account?.id && mcpInstallStatus === 'completed' && - mcpDirectoryPath != null + mcpInstallPath != null ) { const currentSessionToken = (await this.container.subscription.getAuthenticationSession())?.accessToken; if (currentSessionToken != null) { @@ -473,7 +457,7 @@ export class GkCliIntegrationProvider implements Disposable { platform === 'windows' ? 'gk.exe' : './gk', ['auth', 'login', '-t', currentSessionToken], 'utf8', - { cwd: mcpDirectoryPath }, + { cwd: mcpInstallPath }, ); } catch {} } From b6abf395cb0b04fbcbcf833536501e7c1d2ee314 Mon Sep 17 00:00:00 2001 From: Ramin Tadayon Date: Fri, 18 Jul 2025 10:48:20 -0700 Subject: [PATCH 13/14] Removes PATH update, stops awaiting stores --- src/env/node/gk/cli/integration.ts | 69 +++--------------------------- 1 file changed, 7 insertions(+), 62 deletions(-) diff --git a/src/env/node/gk/cli/integration.ts b/src/env/node/gk/cli/integration.ts index 0cc045f417fa9..66cf782b4c424 100644 --- a/src/env/node/gk/cli/integration.ts +++ b/src/env/node/gk/cli/integration.ts @@ -1,4 +1,3 @@ -import { homedir } from 'os'; import { arch } from 'process'; import type { ConfigurationChangeEvent } from 'vscode'; import { version as codeVersion, Disposable, env, ProgressLocation, Uri, window, workspace } from 'vscode'; @@ -93,7 +92,7 @@ export class GkCliIntegrationProvider implements Disposable { return; } - await this.container.storage.store('ai:mcp:attemptInstall', 'attempted'); + void this.container.storage.store('ai:mcp:attemptInstall', 'attempted').catch(); if (configuration.get('ai.enabled') === false) { const message = 'Cannot install MCP: AI is disabled in settings'; @@ -260,7 +259,7 @@ export class GkCliIntegrationProvider implements Disposable { // Check using stat to make sure the newly extracted file exists. await workspace.fs.stat(mcpExtractedPath); - await this.container.storage.store('ai:mcp:installPath', mcpExtractedFolderPath.fsPath); + void this.container.storage.store('ai:mcp:installPath', mcpExtractedFolderPath.fsPath).catch(); } catch (error) { const errorMsg = `Failed to extract MCP installer: ${error}`; Logger.error(errorMsg); @@ -289,10 +288,6 @@ export class GkCliIntegrationProvider implements Disposable { } } - // Get the VS Code settings.json file path in case we are on VSCode Insiders - // TODO: Use this path to point to the current vscode profile's settings.json once the API supports it. - const settingsPath = `${this.container.context.globalStorageUri.fsPath}\\..\\..\\settings.json`; - // Configure the MCP server in settings.json try { const installOutput = await run( @@ -303,59 +298,9 @@ export class GkCliIntegrationProvider implements Disposable { ); const directory = installOutput.match(/Directory: (.*)/); let directoryPath; - if (directory != null) { - try { - directoryPath = directory[1]; - await this.container.storage.store('gk:cli:installedPath', directoryPath); - // Add to PATH - if (platform === 'windows') { - await run( - 'powershell.exe', - [ - '-Command', - `[Environment]::SetEnvironmentVariable('Path', $env:Path + ';${directoryPath}', [EnvironmentVariableTarget]::User)`, - ], - 'utf8', - ); - } else { - // For Unix-like systems, detect and modify the appropriate shell profile - const homeDir = homedir(); - // Try to detect which shell profile exists and is in use - const possibleProfiles = [ - { path: `${homeDir}/.zshrc`, shell: 'zsh' }, - { path: `${homeDir}/.zprofile`, shell: 'zsh' }, - { path: `${homeDir}/.bashrc`, shell: 'bash' }, - { path: `${homeDir}/.profile`, shell: 'sh' }, - ]; - - // Find the first profile that exists - let shellProfile; - for (const profile of possibleProfiles) { - try { - await workspace.fs.stat(Uri.file(profile.path)); - shellProfile = profile.path; - break; - } catch { - // Profile doesn't exist, try next one - } - } - - if (shellProfile != null) { - await run( - 'sh', - [ - '-c', - `echo '# Added by GitLens for MCP support' >> ${shellProfile} && echo 'export PATH="$PATH:${directoryPath}"' >> ${shellProfile}`, - ], - 'utf8', - ); - } else { - Logger.warn('MCP Install: Failed to find shell profile to update PATH'); - } - } - } catch (error) { - Logger.warn(`MCP Install: Failed to add directory to PATH: ${error}`); - } + if (directory != null && directory.length > 1) { + directoryPath = directory[1]; + void this.container.storage.store('gk:cli:installedPath', directoryPath).catch(); } else { Logger.warn('MCP Install: Failed to find directory in install output'); if (appName === 'vscode') { @@ -375,7 +320,7 @@ export class GkCliIntegrationProvider implements Disposable { } else { await run( platform === 'windows' ? mcpFileName : `./${mcpFileName}`, - ['mcp', 'install', appName, ...(isInsiders ? ['--file-path', settingsPath] : [])], + ['mcp', 'install', appName], 'utf8', { cwd: mcpExtractedFolderPath.fsPath }, ); @@ -425,7 +370,7 @@ export class GkCliIntegrationProvider implements Disposable { } // Show success notification if not silent - await this.container.storage.store('ai:mcp:attemptInstall', 'completed'); + void this.container.storage.store('ai:mcp:attemptInstall', 'completed').catch(); void window.showInformationMessage('GitKraken MCP integration installed successfully'); } catch (error) { Logger.error(`Error during MCP installation: ${error}`); From 97a65269647611ffca3b00f123db21f9b6557fa3 Mon Sep 17 00:00:00 2001 From: Ramin Tadayon Date: Fri, 18 Jul 2025 10:52:30 -0700 Subject: [PATCH 14/14] Updates telemetry docs --- docs/telemetry-events.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/telemetry-events.md b/docs/telemetry-events.md index 6272c9f934931..b92610c3272d5 100644 --- a/docs/telemetry-events.md +++ b/docs/telemetry-events.md @@ -2290,7 +2290,7 @@ or ```typescript { 'usage.count': number, - 'usage.key': 'rebaseEditor:shown' | 'graphWebview:shown' | 'patchDetailsWebview:shown' | 'settingsWebview:shown' | 'timelineWebview:shown' | 'graphView:shown' | 'patchDetailsView:shown' | 'timelineView:shown' | 'commitDetailsView:shown' | 'graphDetailsView:shown' | 'homeView:shown' | 'pullRequestView:shown' | 'commitsView:shown' | 'stashesView:shown' | 'tagsView:shown' | 'launchpadView:shown' | 'worktreesView:shown' | 'branchesView:shown' | 'contributorsView:shown' | 'draftsView:shown' | 'fileHistoryView:shown' | 'scm.groupedView:shown' | 'lineHistoryView:shown' | 'remotesView:shown' | 'repositoriesView:shown' | 'searchAndCompareView:shown' | 'workspacesView:shown' | 'command:gitlens.key.alt+,:executed' | 'command:gitlens.key.alt+.:executed' | 'command:gitlens.key.alt+enter:executed' | 'command:gitlens.key.alt+left:executed' | 'command:gitlens.key.alt+right:executed' | 'command:gitlens.key.ctrl+enter:executed' | 'command:gitlens.key.ctrl+left:executed' | 'command:gitlens.key.ctrl+right:executed' | 'command:gitlens.key.escape:executed' | 'command:gitlens.key.left:executed' | 'command:gitlens.key.right:executed' | 'command:gitlens.addAuthors:executed' | 'command:gitlens.ai.explainBranch:executed' | 'command:gitlens.ai.explainCommit:executed' | 'command:gitlens.ai.explainStash:executed' | 'command:gitlens.ai.explainWip:executed' | 'command:gitlens.ai.generateChangelog:executed' | 'command:gitlens.ai.generateCommitMessage:executed' | 'command:gitlens.ai.generateCommits:executed' | 'command:gitlens.ai.generateRebase:executed' | 'command:gitlens.ai.switchProvider:executed' | 'command:gitlens.applyPatchFromClipboard:executed' | 'command:gitlens.associateIssueWithBranch:executed' | 'command:gitlens.browseRepoAtRevision:executed' | 'command:gitlens.browseRepoAtRevisionInNewWindow:executed' | 'command:gitlens.browseRepoBeforeRevision:executed' | 'command:gitlens.browseRepoBeforeRevisionInNewWindow:executed' | 'command:gitlens.changeBranchMergeTarget:executed' | 'command:gitlens.clearFileAnnotations:executed' | 'command:gitlens.closeUnchangedFiles:executed' | 'command:gitlens.compareHeadWith:executed' | 'command:gitlens.compareWith:executed' | 'command:gitlens.compareWorkingWith:executed' | 'command:gitlens.connectRemoteProvider:executed' | 'command:gitlens.copyCurrentBranch:executed' | 'command:gitlens.copyDeepLinkToRepo:executed' | 'command:gitlens.copyMessageToClipboard:executed' | 'command:gitlens.copyPatchToClipboard:executed' | 'command:gitlens.copyRelativePathToClipboard:executed' | 'command:gitlens.copyRemoteCommitUrl:executed' | 'command:gitlens.copyRemoteFileUrlFrom:executed' | 'command:gitlens.copyRemoteFileUrlToClipboard:executed' | 'command:gitlens.copyShaToClipboard:executed' | 'command:gitlens.copyWorkingChangesToWorktree:executed' | 'command:gitlens.createCloudPatch:executed' | 'command:gitlens.createPatch:executed' | 'command:gitlens.createPullRequestOnRemote:executed' | 'command:gitlens.diffDirectory:executed' | 'command:gitlens.diffDirectoryWithHead:executed' | 'command:gitlens.diffFolderWithRevision:executed' | 'command:gitlens.diffFolderWithRevisionFrom:executed' | 'command:gitlens.diffLineWithPrevious:executed' | 'command:gitlens.diffLineWithWorking:executed' | 'command:gitlens.diffWithNext:executed' | 'command:gitlens.diffWithPrevious:executed' | 'command:gitlens.diffWithRevision:executed' | 'command:gitlens.diffWithRevisionFrom:executed' | 'command:gitlens.diffWithWorking:executed' | 'command:gitlens.disableDebugLogging:executed' | 'command:gitlens.disableRebaseEditor:executed' | 'command:gitlens.disconnectRemoteProvider:executed' | 'command:gitlens.enableDebugLogging:executed' | 'command:gitlens.enableRebaseEditor:executed' | 'command:gitlens.externalDiff:executed' | 'command:gitlens.externalDiffAll:executed' | 'command:gitlens.fetchRepositories:executed' | 'command:gitlens.getStarted:executed' | 'command:gitlens.gitCommands:executed' | 'command:gitlens.gitCommands.branch:executed' | 'command:gitlens.gitCommands.branch.create:executed' | 'command:gitlens.gitCommands.branch.delete:executed' | 'command:gitlens.gitCommands.branch.prune:executed' | 'command:gitlens.gitCommands.branch.rename:executed' | 'command:gitlens.gitCommands.checkout:executed' | 'command:gitlens.gitCommands.cherryPick:executed' | 'command:gitlens.gitCommands.history:executed' | 'command:gitlens.gitCommands.merge:executed' | 'command:gitlens.gitCommands.rebase:executed' | 'command:gitlens.gitCommands.remote:executed' | 'command:gitlens.gitCommands.remote.add:executed' | 'command:gitlens.gitCommands.remote.prune:executed' | 'command:gitlens.gitCommands.remote.remove:executed' | 'command:gitlens.gitCommands.reset:executed' | 'command:gitlens.gitCommands.revert:executed' | 'command:gitlens.gitCommands.show:executed' | 'command:gitlens.gitCommands.stash:executed' | 'command:gitlens.gitCommands.stash.drop:executed' | 'command:gitlens.gitCommands.stash.list:executed' | 'command:gitlens.gitCommands.stash.pop:executed' | 'command:gitlens.gitCommands.stash.push:executed' | 'command:gitlens.gitCommands.stash.rename:executed' | 'command:gitlens.gitCommands.status:executed' | 'command:gitlens.gitCommands.switch:executed' | 'command:gitlens.gitCommands.tag:executed' | 'command:gitlens.gitCommands.tag.create:executed' | 'command:gitlens.gitCommands.tag.delete:executed' | 'command:gitlens.gitCommands.worktree:executed' | 'command:gitlens.gitCommands.worktree.create:executed' | 'command:gitlens.gitCommands.worktree.delete:executed' | 'command:gitlens.gitCommands.worktree.open:executed' | 'command:gitlens.gk.switchOrganization:executed' | 'command:gitlens.graph.split:executed' | 'command:gitlens.graph.switchToEditorLayout:executed' | 'command:gitlens.graph.switchToPanelLayout:executed' | 'command:gitlens.launchpad.indicator.toggle:executed' | 'command:gitlens.openAssociatedPullRequestOnRemote:executed' | 'command:gitlens.openBlamePriorToChange:executed' | 'command:gitlens.openBranchOnRemote:executed' | 'command:gitlens.openBranchesOnRemote:executed' | 'command:gitlens.openChangedFiles:executed' | 'command:gitlens.openCommitOnRemote:executed' | 'command:gitlens.openCurrentBranchOnRemote:executed' | 'command:gitlens.openFileFromRemote:executed' | 'command:gitlens.openFileHistory:executed' | 'command:gitlens.openFileOnRemote:executed' | 'command:gitlens.openFileOnRemoteFrom:executed' | 'command:gitlens.openFileRevision:executed' | 'command:gitlens.openFileRevisionFrom:executed' | 'command:gitlens.openOnlyChangedFiles:executed' | 'command:gitlens.openPatch:executed' | 'command:gitlens.openRepoOnRemote:executed' | 'command:gitlens.openRevisionFile:executed' | 'command:gitlens.openRevisionFromRemote:executed' | 'command:gitlens.openWorkingFile:executed' | 'command:gitlens.pastePatchFromClipboard:executed' | 'command:gitlens.plus.cloudIntegrations.manage:executed' | 'command:gitlens.plus.hide:executed' | 'command:gitlens.plus.login:executed' | 'command:gitlens.plus.logout:executed' | 'command:gitlens.plus.manage:executed' | 'command:gitlens.plus.reactivateProTrial:executed' | 'command:gitlens.plus.referFriend:executed' | 'command:gitlens.plus.refreshRepositoryAccess:executed' | 'command:gitlens.plus.restore:executed' | 'command:gitlens.plus.signUp:executed' | 'command:gitlens.plus.simulateSubscription:executed' | 'command:gitlens.plus.upgrade:executed' | 'command:gitlens.pullRepositories:executed' | 'command:gitlens.pushRepositories:executed' | 'command:gitlens.quickOpenFileHistory:executed' | 'command:gitlens.reset:executed' | 'command:gitlens.resetViewsLayout:executed' | 'command:gitlens.revealCommitInView:executed' | 'command:gitlens.shareAsCloudPatch:executed' | 'command:gitlens.showAccountView:executed' | 'command:gitlens.showBranchesView:executed' | 'command:gitlens.showCommitDetailsView:executed' | 'command:gitlens.showCommitInView:executed' | 'command:gitlens.showCommitSearch:executed' | 'command:gitlens.showCommitsInView:executed' | 'command:gitlens.showCommitsView:executed' | 'command:gitlens.showContributorsView:executed' | 'command:gitlens.showDraftsView:executed' | 'command:gitlens.showFileHistoryView:executed' | 'command:gitlens.showGraph:executed' | 'command:gitlens.showGraphPage:executed' | 'command:gitlens.showGraphView:executed' | 'command:gitlens.showHomeView:executed' | 'command:gitlens.showLastQuickPick:executed' | 'command:gitlens.showLaunchpad:executed' | 'command:gitlens.showLaunchpadView:executed' | 'command:gitlens.showLineCommitInView:executed' | 'command:gitlens.showLineHistoryView:executed' | 'command:gitlens.showPatchDetailsPage:executed' | 'command:gitlens.showQuickBranchHistory:executed' | 'command:gitlens.showQuickCommitFileDetails:executed' | 'command:gitlens.showQuickFileHistory:executed' | 'command:gitlens.showQuickRepoHistory:executed' | 'command:gitlens.showQuickRepoStatus:executed' | 'command:gitlens.showQuickRevisionDetails:executed' | 'command:gitlens.showQuickStashList:executed' | 'command:gitlens.showRemotesView:executed' | 'command:gitlens.showRepositoriesView:executed' | 'command:gitlens.showSearchAndCompareView:executed' | 'command:gitlens.showSettingsPage:executed' | 'command:gitlens.showSettingsPage!autolinks:executed' | 'command:gitlens.showStashesView:executed' | 'command:gitlens.showTagsView:executed' | 'command:gitlens.showTimelinePage:executed' | 'command:gitlens.showTimelineView:executed' | 'command:gitlens.showWorkspacesView:executed' | 'command:gitlens.showWorktreesView:executed' | 'command:gitlens.startWork:executed' | 'command:gitlens.stashSave:executed' | 'command:gitlens.stashSave.staged:scm:executed' | 'command:gitlens.stashSave.unstaged:scm:executed' | 'command:gitlens.stashSave:scm:executed' | 'command:gitlens.stashesApply:executed' | 'command:gitlens.switchMode:executed' | 'command:gitlens.timeline.split:executed' | 'command:gitlens.toggleCodeLens:executed' | 'command:gitlens.toggleFileBlame:executed' | 'command:gitlens.toggleFileChanges:executed' | 'command:gitlens.toggleFileHeatmap:executed' | 'command:gitlens.toggleGraph:executed' | 'command:gitlens.toggleLineBlame:executed' | 'command:gitlens.toggleMaximizedGraph:executed' | 'command:gitlens.toggleReviewMode:executed' | 'command:gitlens.toggleZenMode:executed' | 'command:gitlens.views.workspaces.create:executed' | 'command:gitlens.visualizeHistory.file:executed' | 'command:gitlens.ai.explainBranch:graph:executed' | 'command:gitlens.ai.explainBranch:views:executed' | 'command:gitlens.ai.explainCommit:graph:executed' | 'command:gitlens.ai.explainCommit:views:executed' | 'command:gitlens.ai.explainStash:graph:executed' | 'command:gitlens.ai.explainStash:views:executed' | 'command:gitlens.ai.explainWip:graph:executed' | 'command:gitlens.ai.explainWip:views:executed' | 'command:gitlens.ai.feedback.helpful:executed' | 'command:gitlens.ai.feedback.helpful.chosen:executed' | 'command:gitlens.ai.feedback.unhelpful:executed' | 'command:gitlens.ai.feedback.unhelpful.chosen:executed' | 'command:gitlens.ai.generateChangelog:views:executed' | 'command:gitlens.ai.generateChangelogFrom:graph:executed' | 'command:gitlens.ai.generateChangelogFrom:views:executed' | 'command:gitlens.ai.generateCommitMessage:graph:executed' | 'command:gitlens.ai.generateCommitMessage:scm:executed' | 'command:gitlens.ai.generateCommits:graph:executed' | 'command:gitlens.ai.generateCommits:views:executed' | 'command:gitlens.ai.rebaseOntoCommit:graph:executed' | 'command:gitlens.ai.rebaseOntoCommit:views:executed' | 'command:gitlens.ai.undoGenerateRebase:executed' | 'command:gitlens.annotations.nextChange:executed' | 'command:gitlens.annotations.previousChange:executed' | 'command:gitlens.computingFileAnnotations:executed' | 'command:gitlens.copyDeepLinkToBranch:executed' | 'command:gitlens.copyDeepLinkToCommit:executed' | 'command:gitlens.copyDeepLinkToComparison:executed' | 'command:gitlens.copyDeepLinkToFile:executed' | 'command:gitlens.copyDeepLinkToFileAtRevision:executed' | 'command:gitlens.copyDeepLinkToLines:executed' | 'command:gitlens.copyDeepLinkToTag:executed' | 'command:gitlens.copyDeepLinkToWorkspace:executed' | 'command:gitlens.copyRemoteBranchUrl:executed' | 'command:gitlens.copyRemoteBranchesUrl:executed' | 'command:gitlens.copyRemoteComparisonUrl:executed' | 'command:gitlens.copyRemoteFileUrlWithoutRange:executed' | 'command:gitlens.copyRemotePullRequestUrl:executed' | 'command:gitlens.copyRemoteRepositoryUrl:executed' | 'command:gitlens.copyWorkingChangesToWorktree:views:executed' | 'command:gitlens.ghpr.views.openOrCreateWorktree:executed' | 'command:gitlens.graph.addAuthor:executed' | 'command:gitlens.graph.associateIssueWithBranch:executed' | 'command:gitlens.graph.cherryPick:executed' | 'command:gitlens.graph.cherryPick.multi:executed' | 'command:gitlens.graph.columnAuthorOff:executed' | 'command:gitlens.graph.columnAuthorOn:executed' | 'command:gitlens.graph.columnChangesOff:executed' | 'command:gitlens.graph.columnChangesOn:executed' | 'command:gitlens.graph.columnDateTimeOff:executed' | 'command:gitlens.graph.columnDateTimeOn:executed' | 'command:gitlens.graph.columnGraphCompact:executed' | 'command:gitlens.graph.columnGraphDefault:executed' | 'command:gitlens.graph.columnGraphOff:executed' | 'command:gitlens.graph.columnGraphOn:executed' | 'command:gitlens.graph.columnMessageOff:executed' | 'command:gitlens.graph.columnMessageOn:executed' | 'command:gitlens.graph.columnRefOff:executed' | 'command:gitlens.graph.columnRefOn:executed' | 'command:gitlens.graph.columnShaOff:executed' | 'command:gitlens.graph.columnShaOn:executed' | 'command:gitlens.graph.commitViaSCM:executed' | 'command:gitlens.graph.compareAncestryWithWorking:executed' | 'command:gitlens.graph.compareBranchWithHead:executed' | 'command:gitlens.graph.compareSelectedCommits.multi:executed' | 'command:gitlens.graph.compareWithHead:executed' | 'command:gitlens.graph.compareWithMergeBase:executed' | 'command:gitlens.graph.compareWithUpstream:executed' | 'command:gitlens.graph.compareWithWorking:executed' | 'command:gitlens.graph.copy:executed' | 'command:gitlens.graph.copyDeepLinkToBranch:executed' | 'command:gitlens.graph.copyDeepLinkToCommit:executed' | 'command:gitlens.graph.copyDeepLinkToRepo:executed' | 'command:gitlens.graph.copyDeepLinkToTag:executed' | 'command:gitlens.graph.copyMessage:executed' | 'command:gitlens.graph.copyRemoteBranchUrl:executed' | 'command:gitlens.graph.copyRemoteCommitUrl:executed' | 'command:gitlens.graph.copyRemoteCommitUrl.multi:executed' | 'command:gitlens.graph.copySha:executed' | 'command:gitlens.graph.copyWorkingChangesToWorktree:executed' | 'command:gitlens.graph.createBranch:executed' | 'command:gitlens.graph.createCloudPatch:executed' | 'command:gitlens.graph.createPatch:executed' | 'command:gitlens.graph.createPullRequest:executed' | 'command:gitlens.graph.createTag:executed' | 'command:gitlens.graph.createWorktree:executed' | 'command:gitlens.graph.deleteBranch:executed' | 'command:gitlens.graph.deleteTag:executed' | 'command:gitlens.graph.fetch:executed' | 'command:gitlens.graph.hideLocalBranch:executed' | 'command:gitlens.graph.hideRefGroup:executed' | 'command:gitlens.graph.hideRemote:executed' | 'command:gitlens.graph.hideRemoteBranch:executed' | 'command:gitlens.graph.hideTag:executed' | 'command:gitlens.graph.mergeBranchInto:executed' | 'command:gitlens.graph.openBranchOnRemote:executed' | 'command:gitlens.graph.openChangedFileDiffs:executed' | 'command:gitlens.graph.openChangedFileDiffsIndividually:executed' | 'command:gitlens.graph.openChangedFileDiffsWithMergeBase:executed' | 'command:gitlens.graph.openChangedFileDiffsWithWorking:executed' | 'command:gitlens.graph.openChangedFileDiffsWithWorkingIndividually:executed' | 'command:gitlens.graph.openChangedFileRevisions:executed' | 'command:gitlens.graph.openChangedFiles:executed' | 'command:gitlens.graph.openCommitOnRemote:executed' | 'command:gitlens.graph.openCommitOnRemote.multi:executed' | 'command:gitlens.graph.openInWorktree:executed' | 'command:gitlens.graph.openOnlyChangedFiles:executed' | 'command:gitlens.graph.openPullRequest:executed' | 'command:gitlens.graph.openPullRequestChanges:executed' | 'command:gitlens.graph.openPullRequestComparison:executed' | 'command:gitlens.graph.openPullRequestOnRemote:executed' | 'command:gitlens.graph.openWorktree:executed' | 'command:gitlens.graph.openWorktreeInNewWindow:executed' | 'command:gitlens.graph.publishBranch:executed' | 'command:gitlens.graph.pull:executed' | 'command:gitlens.graph.push:executed' | 'command:gitlens.graph.pushWithForce:executed' | 'command:gitlens.graph.rebaseOntoBranch:executed' | 'command:gitlens.graph.rebaseOntoCommit:executed' | 'command:gitlens.graph.rebaseOntoUpstream:executed' | 'command:gitlens.graph.refresh:executed' | 'command:gitlens.graph.renameBranch:executed' | 'command:gitlens.graph.resetColumnsCompact:executed' | 'command:gitlens.graph.resetColumnsDefault:executed' | 'command:gitlens.graph.resetCommit:executed' | 'command:gitlens.graph.resetToCommit:executed' | 'command:gitlens.graph.resetToTag:executed' | 'command:gitlens.graph.resetToTip:executed' | 'command:gitlens.graph.revert:executed' | 'command:gitlens.graph.scrollMarkerLocalBranchOff:executed' | 'command:gitlens.graph.scrollMarkerLocalBranchOn:executed' | 'command:gitlens.graph.scrollMarkerPullRequestOff:executed' | 'command:gitlens.graph.scrollMarkerPullRequestOn:executed' | 'command:gitlens.graph.scrollMarkerRemoteBranchOff:executed' | 'command:gitlens.graph.scrollMarkerRemoteBranchOn:executed' | 'command:gitlens.graph.scrollMarkerStashOff:executed' | 'command:gitlens.graph.scrollMarkerStashOn:executed' | 'command:gitlens.graph.scrollMarkerTagOff:executed' | 'command:gitlens.graph.scrollMarkerTagOn:executed' | 'command:gitlens.graph.shareAsCloudPatch:executed' | 'command:gitlens.graph.showInDetailsView:executed' | 'command:gitlens.graph.switchToAnotherBranch:executed' | 'command:gitlens.graph.switchToBranch:executed' | 'command:gitlens.graph.switchToCommit:executed' | 'command:gitlens.graph.switchToTag:executed' | 'command:gitlens.graph.undoCommit:executed' | 'command:gitlens.inviteToLiveShare:executed' | 'command:gitlens.openCloudPatch:executed' | 'command:gitlens.openComparisonOnRemote:executed' | 'command:gitlens.openFolderHistory:executed' | 'command:gitlens.openPullRequestOnRemote:executed' | 'command:gitlens.plus.cloudIntegrations.connect:executed' | 'command:gitlens.regenerateMarkdownDocument:executed' | 'command:gitlens.showInCommitGraph:executed' | 'command:gitlens.showInCommitGraphView:executed' | 'command:gitlens.showInDetailsView:executed' | 'command:gitlens.showQuickCommitDetails:executed' | 'command:gitlens.showSettingsPage!branches-view:executed' | 'command:gitlens.showSettingsPage!commit-graph:executed' | 'command:gitlens.showSettingsPage!commits-view:executed' | 'command:gitlens.showSettingsPage!contributors-view:executed' | 'command:gitlens.showSettingsPage!file-annotations:executed' | 'command:gitlens.showSettingsPage!file-history-view:executed' | 'command:gitlens.showSettingsPage!line-history-view:executed' | 'command:gitlens.showSettingsPage!remotes-view:executed' | 'command:gitlens.showSettingsPage!repositories-view:executed' | 'command:gitlens.showSettingsPage!search-compare-view:executed' | 'command:gitlens.showSettingsPage!stashes-view:executed' | 'command:gitlens.showSettingsPage!tags-view:executed' | 'command:gitlens.showSettingsPage!views:executed' | 'command:gitlens.showSettingsPage!worktrees-view:executed' | 'command:gitlens.star.branch.multi:views:executed' | 'command:gitlens.star.branch:graph:executed' | 'command:gitlens.star.branch:views:executed' | 'command:gitlens.star.repository.multi:views:executed' | 'command:gitlens.star.repository:views:executed' | 'command:gitlens.stashApply:graph:executed' | 'command:gitlens.stashApply:views:executed' | 'command:gitlens.stashDelete.multi:views:executed' | 'command:gitlens.stashDelete:graph:executed' | 'command:gitlens.stashDelete:views:executed' | 'command:gitlens.stashRename:graph:executed' | 'command:gitlens.stashRename:views:executed' | 'command:gitlens.stashSave.files:scm:executed' | 'command:gitlens.stashSave.files:views:executed' | 'command:gitlens.stashSave:graph:executed' | 'command:gitlens.stashSave:views:executed' | 'command:gitlens.stashesApply:views:executed' | 'command:gitlens.timeline.refresh:executed' | 'command:gitlens.toggleFileChangesOnly:executed' | 'command:gitlens.toggleFileHeatmapInDiffLeft:executed' | 'command:gitlens.toggleFileHeatmapInDiffRight:executed' | 'command:gitlens.unstar.branch.multi:views:executed' | 'command:gitlens.unstar.branch:graph:executed' | 'command:gitlens.unstar.branch:views:executed' | 'command:gitlens.unstar.repository.multi:views:executed' | 'command:gitlens.unstar.repository:views:executed' | 'command:gitlens.views.abortPausedOperation:executed' | 'command:gitlens.views.addAuthor:executed' | 'command:gitlens.views.addAuthor.multi:executed' | 'command:gitlens.views.addAuthors:executed' | 'command:gitlens.views.addPullRequestRemote:executed' | 'command:gitlens.views.addRemote:executed' | 'command:gitlens.views.applyChanges:executed' | 'command:gitlens.views.associateIssueWithBranch:executed' | 'command:gitlens.views.branches.attach:executed' | 'command:gitlens.views.branches.copy:executed' | 'command:gitlens.views.branches.refresh:executed' | 'command:gitlens.views.branches.setFilesLayoutToAuto:executed' | 'command:gitlens.views.branches.setFilesLayoutToList:executed' | 'command:gitlens.views.branches.setFilesLayoutToTree:executed' | 'command:gitlens.views.branches.setLayoutToList:executed' | 'command:gitlens.views.branches.setLayoutToTree:executed' | 'command:gitlens.views.branches.setShowAvatarsOff:executed' | 'command:gitlens.views.branches.setShowAvatarsOn:executed' | 'command:gitlens.views.branches.setShowBranchComparisonOff:executed' | 'command:gitlens.views.branches.setShowBranchComparisonOn:executed' | 'command:gitlens.views.branches.setShowBranchPullRequestOff:executed' | 'command:gitlens.views.branches.setShowBranchPullRequestOn:executed' | 'command:gitlens.views.branches.setShowRemoteBranchesOff:executed' | 'command:gitlens.views.branches.setShowRemoteBranchesOn:executed' | 'command:gitlens.views.branches.setShowStashesOff:executed' | 'command:gitlens.views.branches.setShowStashesOn:executed' | 'command:gitlens.views.branches.viewOptionsTitle:executed' | 'command:gitlens.views.browseRepoAtRevision:executed' | 'command:gitlens.views.browseRepoAtRevisionInNewWindow:executed' | 'command:gitlens.views.browseRepoBeforeRevision:executed' | 'command:gitlens.views.browseRepoBeforeRevisionInNewWindow:executed' | 'command:gitlens.views.cherryPick:executed' | 'command:gitlens.views.cherryPick.multi:executed' | 'command:gitlens.views.clearComparison:executed' | 'command:gitlens.views.clearReviewed:executed' | 'command:gitlens.views.closeRepository:executed' | 'command:gitlens.views.collapseNode:executed' | 'command:gitlens.views.commitDetails.refresh:executed' | 'command:gitlens.views.commits.attach:executed' | 'command:gitlens.views.commits.copy:executed' | 'command:gitlens.views.commits.refresh:executed' | 'command:gitlens.views.commits.setCommitsFilterAuthors:executed' | 'command:gitlens.views.commits.setCommitsFilterOff:executed' | 'command:gitlens.views.commits.setFilesLayoutToAuto:executed' | 'command:gitlens.views.commits.setFilesLayoutToList:executed' | 'command:gitlens.views.commits.setFilesLayoutToTree:executed' | 'command:gitlens.views.commits.setShowAvatarsOff:executed' | 'command:gitlens.views.commits.setShowAvatarsOn:executed' | 'command:gitlens.views.commits.setShowBranchComparisonOff:executed' | 'command:gitlens.views.commits.setShowBranchComparisonOn:executed' | 'command:gitlens.views.commits.setShowBranchPullRequestOff:executed' | 'command:gitlens.views.commits.setShowBranchPullRequestOn:executed' | 'command:gitlens.views.commits.setShowMergeCommitsOff:executed' | 'command:gitlens.views.commits.setShowMergeCommitsOn:executed' | 'command:gitlens.views.commits.setShowStashesOff:executed' | 'command:gitlens.views.commits.setShowStashesOn:executed' | 'command:gitlens.views.commits.viewOptionsTitle:executed' | 'command:gitlens.views.compareAncestryWithWorking:executed' | 'command:gitlens.views.compareBranchWithHead:executed' | 'command:gitlens.views.compareFileWithSelected:executed' | 'command:gitlens.views.compareWithHead:executed' | 'command:gitlens.views.compareWithMergeBase:executed' | 'command:gitlens.views.compareWithSelected:executed' | 'command:gitlens.views.compareWithUpstream:executed' | 'command:gitlens.views.compareWithWorking:executed' | 'command:gitlens.views.continuePausedOperation:executed' | 'command:gitlens.views.contributors.attach:executed' | 'command:gitlens.views.contributors.copy:executed' | 'command:gitlens.views.contributors.refresh:executed' | 'command:gitlens.views.contributors.setFilesLayoutToAuto:executed' | 'command:gitlens.views.contributors.setFilesLayoutToList:executed' | 'command:gitlens.views.contributors.setFilesLayoutToTree:executed' | 'command:gitlens.views.contributors.setShowAllBranchesOff:executed' | 'command:gitlens.views.contributors.setShowAllBranchesOn:executed' | 'command:gitlens.views.contributors.setShowAvatarsOff:executed' | 'command:gitlens.views.contributors.setShowAvatarsOn:executed' | 'command:gitlens.views.contributors.setShowMergeCommitsOff:executed' | 'command:gitlens.views.contributors.setShowMergeCommitsOn:executed' | 'command:gitlens.views.contributors.setShowStatisticsOff:executed' | 'command:gitlens.views.contributors.setShowStatisticsOn:executed' | 'command:gitlens.views.contributors.viewOptionsTitle:executed' | 'command:gitlens.views.copy:executed' | 'command:gitlens.views.copyAsMarkdown:executed' | 'command:gitlens.views.copyRemoteCommitUrl:executed' | 'command:gitlens.views.copyRemoteCommitUrl.multi:executed' | 'command:gitlens.views.copyUrl:executed' | 'command:gitlens.views.copyUrl.multi:executed' | 'command:gitlens.views.createBranch:executed' | 'command:gitlens.views.createPullRequest:executed' | 'command:gitlens.views.createTag:executed' | 'command:gitlens.views.createWorktree:executed' | 'command:gitlens.views.deleteBranch:executed' | 'command:gitlens.views.deleteBranch.multi:executed' | 'command:gitlens.views.deleteTag:executed' | 'command:gitlens.views.deleteTag.multi:executed' | 'command:gitlens.views.deleteWorktree:executed' | 'command:gitlens.views.deleteWorktree.multi:executed' | 'command:gitlens.views.dismissNode:executed' | 'command:gitlens.views.draft.open:executed' | 'command:gitlens.views.draft.openOnWeb:executed' | 'command:gitlens.views.drafts.copy:executed' | 'command:gitlens.views.drafts.create:executed' | 'command:gitlens.views.drafts.delete:executed' | 'command:gitlens.views.drafts.info:executed' | 'command:gitlens.views.drafts.refresh:executed' | 'command:gitlens.views.drafts.setShowAvatarsOff:executed' | 'command:gitlens.views.drafts.setShowAvatarsOn:executed' | 'command:gitlens.views.editNode:executed' | 'command:gitlens.views.expandNode:executed' | 'command:gitlens.views.fetch:executed' | 'command:gitlens.views.fileHistory.attach:executed' | 'command:gitlens.views.fileHistory.changeBase:executed' | 'command:gitlens.views.fileHistory.copy:executed' | 'command:gitlens.views.fileHistory.refresh:executed' | 'command:gitlens.views.fileHistory.setCursorFollowingOff:executed' | 'command:gitlens.views.fileHistory.setCursorFollowingOn:executed' | 'command:gitlens.views.fileHistory.setEditorFollowingOff:executed' | 'command:gitlens.views.fileHistory.setEditorFollowingOn:executed' | 'command:gitlens.views.fileHistory.setModeCommits:executed' | 'command:gitlens.views.fileHistory.setModeContributors:executed' | 'command:gitlens.views.fileHistory.setRenameFollowingOff:executed' | 'command:gitlens.views.fileHistory.setRenameFollowingOn:executed' | 'command:gitlens.views.fileHistory.setShowAllBranchesOff:executed' | 'command:gitlens.views.fileHistory.setShowAllBranchesOn:executed' | 'command:gitlens.views.fileHistory.setShowAvatarsOff:executed' | 'command:gitlens.views.fileHistory.setShowAvatarsOn:executed' | 'command:gitlens.views.fileHistory.setShowMergeCommitsOff:executed' | 'command:gitlens.views.fileHistory.setShowMergeCommitsOn:executed' | 'command:gitlens.views.fileHistory.viewOptionsTitle:executed' | 'command:gitlens.views.graph.openInTab:executed' | 'command:gitlens.views.graph.refresh:executed' | 'command:gitlens.views.graphDetails.refresh:executed' | 'command:gitlens.views.highlightChanges:executed' | 'command:gitlens.views.highlightRevisionChanges:executed' | 'command:gitlens.views.home.disablePreview:executed' | 'command:gitlens.views.home.discussions:executed' | 'command:gitlens.views.home.enablePreview:executed' | 'command:gitlens.views.home.help:executed' | 'command:gitlens.views.home.info:executed' | 'command:gitlens.views.home.issues:executed' | 'command:gitlens.views.home.previewFeedback:executed' | 'command:gitlens.views.home.refresh:executed' | 'command:gitlens.views.home.whatsNew:executed' | 'command:gitlens.views.launchpad.attach:executed' | 'command:gitlens.views.launchpad.copy:executed' | 'command:gitlens.views.launchpad.info:executed' | 'command:gitlens.views.launchpad.refresh:executed' | 'command:gitlens.views.launchpad.setFilesLayoutToAuto:executed' | 'command:gitlens.views.launchpad.setFilesLayoutToList:executed' | 'command:gitlens.views.launchpad.setFilesLayoutToTree:executed' | 'command:gitlens.views.launchpad.setShowAvatarsOff:executed' | 'command:gitlens.views.launchpad.setShowAvatarsOn:executed' | 'command:gitlens.views.launchpad.viewOptionsTitle:executed' | 'command:gitlens.views.lineHistory.changeBase:executed' | 'command:gitlens.views.lineHistory.copy:executed' | 'command:gitlens.views.lineHistory.refresh:executed' | 'command:gitlens.views.lineHistory.setEditorFollowingOff:executed' | 'command:gitlens.views.lineHistory.setEditorFollowingOn:executed' | 'command:gitlens.views.lineHistory.setShowAvatarsOff:executed' | 'command:gitlens.views.lineHistory.setShowAvatarsOn:executed' | 'command:gitlens.views.loadAllChildren:executed' | 'command:gitlens.views.loadMoreChildren:executed' | 'command:gitlens.views.mergeBranchInto:executed' | 'command:gitlens.views.mergeChangesWithWorking:executed' | 'command:gitlens.views.openBranchOnRemote:executed' | 'command:gitlens.views.openBranchOnRemote.multi:executed' | 'command:gitlens.views.openChangedFileDiffs:executed' | 'command:gitlens.views.openChangedFileDiffsIndividually:executed' | 'command:gitlens.views.openChangedFileDiffsWithMergeBase:executed' | 'command:gitlens.views.openChangedFileDiffsWithWorking:executed' | 'command:gitlens.views.openChangedFileDiffsWithWorkingIndividually:executed' | 'command:gitlens.views.openChangedFileRevisions:executed' | 'command:gitlens.views.openChangedFiles:executed' | 'command:gitlens.views.openChanges:executed' | 'command:gitlens.views.openChangesWithMergeBase:executed' | 'command:gitlens.views.openChangesWithWorking:executed' | 'command:gitlens.views.openCommitOnRemote:executed' | 'command:gitlens.views.openCommitOnRemote.multi:executed' | 'command:gitlens.views.openDirectoryDiff:executed' | 'command:gitlens.views.openDirectoryDiffWithWorking:executed' | 'command:gitlens.views.openFile:executed' | 'command:gitlens.views.openFileRevision:executed' | 'command:gitlens.views.openInIntegratedTerminal:executed' | 'command:gitlens.views.openInTerminal:executed' | 'command:gitlens.views.openInWorktree:executed' | 'command:gitlens.views.openOnlyChangedFiles:executed' | 'command:gitlens.views.openPausedOperationInRebaseEditor:executed' | 'command:gitlens.views.openPreviousChangesWithWorking:executed' | 'command:gitlens.views.openPullRequest:executed' | 'command:gitlens.views.openPullRequestChanges:executed' | 'command:gitlens.views.openPullRequestComparison:executed' | 'command:gitlens.views.openUrl:executed' | 'command:gitlens.views.openUrl.multi:executed' | 'command:gitlens.views.openWorktree:executed' | 'command:gitlens.views.openWorktreeInNewWindow:executed' | 'command:gitlens.views.openWorktreeInNewWindow.multi:executed' | 'command:gitlens.views.patchDetails.close:executed' | 'command:gitlens.views.patchDetails.refresh:executed' | 'command:gitlens.views.pruneRemote:executed' | 'command:gitlens.views.publishBranch:executed' | 'command:gitlens.views.publishRepository:executed' | 'command:gitlens.views.pull:executed' | 'command:gitlens.views.pullRequest.close:executed' | 'command:gitlens.views.pullRequest.copy:executed' | 'command:gitlens.views.pullRequest.refresh:executed' | 'command:gitlens.views.pullRequest.setFilesLayoutToAuto:executed' | 'command:gitlens.views.pullRequest.setFilesLayoutToList:executed' | 'command:gitlens.views.pullRequest.setFilesLayoutToTree:executed' | 'command:gitlens.views.pullRequest.setShowAvatarsOff:executed' | 'command:gitlens.views.pullRequest.setShowAvatarsOn:executed' | 'command:gitlens.views.push:executed' | 'command:gitlens.views.pushToCommit:executed' | 'command:gitlens.views.pushWithForce:executed' | 'command:gitlens.views.rebaseOntoBranch:executed' | 'command:gitlens.views.rebaseOntoCommit:executed' | 'command:gitlens.views.rebaseOntoUpstream:executed' | 'command:gitlens.views.refreshNode:executed' | 'command:gitlens.views.remotes.attach:executed' | 'command:gitlens.views.remotes.copy:executed' | 'command:gitlens.views.remotes.refresh:executed' | 'command:gitlens.views.remotes.setFilesLayoutToAuto:executed' | 'command:gitlens.views.remotes.setFilesLayoutToList:executed' | 'command:gitlens.views.remotes.setFilesLayoutToTree:executed' | 'command:gitlens.views.remotes.setLayoutToList:executed' | 'command:gitlens.views.remotes.setLayoutToTree:executed' | 'command:gitlens.views.remotes.setShowAvatarsOff:executed' | 'command:gitlens.views.remotes.setShowAvatarsOn:executed' | 'command:gitlens.views.remotes.setShowBranchPullRequestOff:executed' | 'command:gitlens.views.remotes.setShowBranchPullRequestOn:executed' | 'command:gitlens.views.remotes.viewOptionsTitle:executed' | 'command:gitlens.views.removeRemote:executed' | 'command:gitlens.views.renameBranch:executed' | 'command:gitlens.views.repositories.attach:executed' | 'command:gitlens.views.repositories.copy:executed' | 'command:gitlens.views.repositories.refresh:executed' | 'command:gitlens.views.repositories.setAutoRefreshToOff:executed' | 'command:gitlens.views.repositories.setAutoRefreshToOn:executed' | 'command:gitlens.views.repositories.setBranchesLayoutToList:executed' | 'command:gitlens.views.repositories.setBranchesLayoutToTree:executed' | 'command:gitlens.views.repositories.setBranchesShowBranchComparisonOff:executed' | 'command:gitlens.views.repositories.setBranchesShowBranchComparisonOn:executed' | 'command:gitlens.views.repositories.setBranchesShowStashesOff:executed' | 'command:gitlens.views.repositories.setBranchesShowStashesOn:executed' | 'command:gitlens.views.repositories.setFilesLayoutToAuto:executed' | 'command:gitlens.views.repositories.setFilesLayoutToList:executed' | 'command:gitlens.views.repositories.setFilesLayoutToTree:executed' | 'command:gitlens.views.repositories.setShowAvatarsOff:executed' | 'command:gitlens.views.repositories.setShowAvatarsOn:executed' | 'command:gitlens.views.repositories.setShowSectionBranchComparisonOff:executed' | 'command:gitlens.views.repositories.setShowSectionBranchComparisonOn:executed' | 'command:gitlens.views.repositories.setShowSectionBranchesOff:executed' | 'command:gitlens.views.repositories.setShowSectionBranchesOn:executed' | 'command:gitlens.views.repositories.setShowSectionCommitsOff:executed' | 'command:gitlens.views.repositories.setShowSectionCommitsOn:executed' | 'command:gitlens.views.repositories.setShowSectionContributorsOff:executed' | 'command:gitlens.views.repositories.setShowSectionContributorsOn:executed' | 'command:gitlens.views.repositories.setShowSectionOff:executed' | 'command:gitlens.views.repositories.setShowSectionRemotesOff:executed' | 'command:gitlens.views.repositories.setShowSectionRemotesOn:executed' | 'command:gitlens.views.repositories.setShowSectionStashesOff:executed' | 'command:gitlens.views.repositories.setShowSectionStashesOn:executed' | 'command:gitlens.views.repositories.setShowSectionTagsOff:executed' | 'command:gitlens.views.repositories.setShowSectionTagsOn:executed' | 'command:gitlens.views.repositories.setShowSectionUpstreamStatusOff:executed' | 'command:gitlens.views.repositories.setShowSectionUpstreamStatusOn:executed' | 'command:gitlens.views.repositories.setShowSectionWorktreesOff:executed' | 'command:gitlens.views.repositories.setShowSectionWorktreesOn:executed' | 'command:gitlens.views.repositories.viewOptionsTitle:executed' | 'command:gitlens.views.resetCommit:executed' | 'command:gitlens.views.resetToCommit:executed' | 'command:gitlens.views.resetToTip:executed' | 'command:gitlens.views.restore:executed' | 'command:gitlens.views.revealRepositoryInExplorer:executed' | 'command:gitlens.views.revealWorktreeInExplorer:executed' | 'command:gitlens.views.revert:executed' | 'command:gitlens.views.scm.grouped.attachAll:executed' | 'command:gitlens.views.scm.grouped.branches:executed' | 'command:gitlens.views.scm.grouped.branches.attach:executed' | 'command:gitlens.views.scm.grouped.branches.detach:executed' | 'command:gitlens.views.scm.grouped.branches.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.branches.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.branches.visibility.show:executed' | 'command:gitlens.views.scm.grouped.commits:executed' | 'command:gitlens.views.scm.grouped.commits.attach:executed' | 'command:gitlens.views.scm.grouped.commits.detach:executed' | 'command:gitlens.views.scm.grouped.commits.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.commits.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.commits.visibility.show:executed' | 'command:gitlens.views.scm.grouped.contributors:executed' | 'command:gitlens.views.scm.grouped.contributors.attach:executed' | 'command:gitlens.views.scm.grouped.contributors.detach:executed' | 'command:gitlens.views.scm.grouped.contributors.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.contributors.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.contributors.visibility.show:executed' | 'command:gitlens.views.scm.grouped.detachAll:executed' | 'command:gitlens.views.scm.grouped.fileHistory:executed' | 'command:gitlens.views.scm.grouped.fileHistory.attach:executed' | 'command:gitlens.views.scm.grouped.fileHistory.detach:executed' | 'command:gitlens.views.scm.grouped.fileHistory.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.fileHistory.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.fileHistory.visibility.show:executed' | 'command:gitlens.views.scm.grouped.launchpad:executed' | 'command:gitlens.views.scm.grouped.launchpad.attach:executed' | 'command:gitlens.views.scm.grouped.launchpad.detach:executed' | 'command:gitlens.views.scm.grouped.launchpad.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.launchpad.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.launchpad.visibility.show:executed' | 'command:gitlens.views.scm.grouped.refresh:executed' | 'command:gitlens.views.scm.grouped.remotes:executed' | 'command:gitlens.views.scm.grouped.remotes.attach:executed' | 'command:gitlens.views.scm.grouped.remotes.detach:executed' | 'command:gitlens.views.scm.grouped.remotes.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.remotes.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.remotes.visibility.show:executed' | 'command:gitlens.views.scm.grouped.repositories:executed' | 'command:gitlens.views.scm.grouped.repositories.attach:executed' | 'command:gitlens.views.scm.grouped.repositories.detach:executed' | 'command:gitlens.views.scm.grouped.repositories.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.repositories.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.repositories.visibility.show:executed' | 'command:gitlens.views.scm.grouped.resetAll:executed' | 'command:gitlens.views.scm.grouped.searchAndCompare:executed' | 'command:gitlens.views.scm.grouped.searchAndCompare.attach:executed' | 'command:gitlens.views.scm.grouped.searchAndCompare.detach:executed' | 'command:gitlens.views.scm.grouped.searchAndCompare.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.searchAndCompare.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.searchAndCompare.visibility.show:executed' | 'command:gitlens.views.scm.grouped.stashes:executed' | 'command:gitlens.views.scm.grouped.stashes.attach:executed' | 'command:gitlens.views.scm.grouped.stashes.detach:executed' | 'command:gitlens.views.scm.grouped.stashes.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.stashes.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.stashes.visibility.show:executed' | 'command:gitlens.views.scm.grouped.tags:executed' | 'command:gitlens.views.scm.grouped.tags.attach:executed' | 'command:gitlens.views.scm.grouped.tags.detach:executed' | 'command:gitlens.views.scm.grouped.tags.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.tags.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.tags.visibility.show:executed' | 'command:gitlens.views.scm.grouped.worktrees:executed' | 'command:gitlens.views.scm.grouped.worktrees.attach:executed' | 'command:gitlens.views.scm.grouped.worktrees.detach:executed' | 'command:gitlens.views.scm.grouped.worktrees.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.worktrees.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.worktrees.visibility.show:executed' | 'command:gitlens.views.searchAndCompare.attach:executed' | 'command:gitlens.views.searchAndCompare.clear:executed' | 'command:gitlens.views.searchAndCompare.copy:executed' | 'command:gitlens.views.searchAndCompare.refresh:executed' | 'command:gitlens.views.searchAndCompare.searchCommits:executed' | 'command:gitlens.views.searchAndCompare.selectForCompare:executed' | 'command:gitlens.views.searchAndCompare.setFilesLayoutToAuto:executed' | 'command:gitlens.views.searchAndCompare.setFilesLayoutToList:executed' | 'command:gitlens.views.searchAndCompare.setFilesLayoutToTree:executed' | 'command:gitlens.views.searchAndCompare.setShowAvatarsOff:executed' | 'command:gitlens.views.searchAndCompare.setShowAvatarsOn:executed' | 'command:gitlens.views.searchAndCompare.swapComparison:executed' | 'command:gitlens.views.searchAndCompare.viewOptionsTitle:executed' | 'command:gitlens.views.selectFileForCompare:executed' | 'command:gitlens.views.selectForCompare:executed' | 'command:gitlens.views.setAsDefault:executed' | 'command:gitlens.views.setBranchComparisonToBranch:executed' | 'command:gitlens.views.setBranchComparisonToWorking:executed' | 'command:gitlens.views.setContributorsStatisticsOff:executed' | 'command:gitlens.views.setContributorsStatisticsOn:executed' | 'command:gitlens.views.setResultsCommitsFilterAuthors:executed' | 'command:gitlens.views.setResultsCommitsFilterOff:executed' | 'command:gitlens.views.setResultsFilesFilterOff:executed' | 'command:gitlens.views.setResultsFilesFilterOnLeft:executed' | 'command:gitlens.views.setResultsFilesFilterOnRight:executed' | 'command:gitlens.views.setShowRelativeDateMarkersOff:executed' | 'command:gitlens.views.setShowRelativeDateMarkersOn:executed' | 'command:gitlens.views.skipPausedOperation:executed' | 'command:gitlens.views.stageDirectory:executed' | 'command:gitlens.views.stageFile:executed' | 'command:gitlens.views.stashes.attach:executed' | 'command:gitlens.views.stashes.copy:executed' | 'command:gitlens.views.stashes.refresh:executed' | 'command:gitlens.views.stashes.setFilesLayoutToAuto:executed' | 'command:gitlens.views.stashes.setFilesLayoutToList:executed' | 'command:gitlens.views.stashes.setFilesLayoutToTree:executed' | 'command:gitlens.views.stashes.viewOptionsTitle:executed' | 'command:gitlens.views.switchToAnotherBranch:executed' | 'command:gitlens.views.switchToBranch:executed' | 'command:gitlens.views.switchToCommit:executed' | 'command:gitlens.views.switchToTag:executed' | 'command:gitlens.views.tags.attach:executed' | 'command:gitlens.views.tags.copy:executed' | 'command:gitlens.views.tags.refresh:executed' | 'command:gitlens.views.tags.setFilesLayoutToAuto:executed' | 'command:gitlens.views.tags.setFilesLayoutToList:executed' | 'command:gitlens.views.tags.setFilesLayoutToTree:executed' | 'command:gitlens.views.tags.setLayoutToList:executed' | 'command:gitlens.views.tags.setLayoutToTree:executed' | 'command:gitlens.views.tags.setShowAvatarsOff:executed' | 'command:gitlens.views.tags.setShowAvatarsOn:executed' | 'command:gitlens.views.tags.viewOptionsTitle:executed' | 'command:gitlens.views.timeline.refresh:executed' | 'command:gitlens.views.title.createBranch:executed' | 'command:gitlens.views.title.createTag:executed' | 'command:gitlens.views.title.createWorktree:executed' | 'command:gitlens.views.undoCommit:executed' | 'command:gitlens.views.unsetAsDefault:executed' | 'command:gitlens.views.unstageDirectory:executed' | 'command:gitlens.views.unstageFile:executed' | 'command:gitlens.views.workspaces.addRepos:executed' | 'command:gitlens.views.workspaces.addReposFromLinked:executed' | 'command:gitlens.views.workspaces.changeAutoAddSetting:executed' | 'command:gitlens.views.workspaces.convert:executed' | 'command:gitlens.views.workspaces.copy:executed' | 'command:gitlens.views.workspaces.createLocal:executed' | 'command:gitlens.views.workspaces.delete:executed' | 'command:gitlens.views.workspaces.info:executed' | 'command:gitlens.views.workspaces.locateAllRepos:executed' | 'command:gitlens.views.workspaces.openLocal:executed' | 'command:gitlens.views.workspaces.openLocalNewWindow:executed' | 'command:gitlens.views.workspaces.refresh:executed' | 'command:gitlens.views.workspaces.repo.addToWindow:executed' | 'command:gitlens.views.workspaces.repo.locate:executed' | 'command:gitlens.views.workspaces.repo.open:executed' | 'command:gitlens.views.workspaces.repo.openInNewWindow:executed' | 'command:gitlens.views.workspaces.repo.remove:executed' | 'command:gitlens.views.worktrees.attach:executed' | 'command:gitlens.views.worktrees.copy:executed' | 'command:gitlens.views.worktrees.refresh:executed' | 'command:gitlens.views.worktrees.setFilesLayoutToAuto:executed' | 'command:gitlens.views.worktrees.setFilesLayoutToList:executed' | 'command:gitlens.views.worktrees.setFilesLayoutToTree:executed' | 'command:gitlens.views.worktrees.setLayoutToList:executed' | 'command:gitlens.views.worktrees.setLayoutToTree:executed' | 'command:gitlens.views.worktrees.setShowAvatarsOff:executed' | 'command:gitlens.views.worktrees.setShowAvatarsOn:executed' | 'command:gitlens.views.worktrees.setShowBranchComparisonOff:executed' | 'command:gitlens.views.worktrees.setShowBranchComparisonOn:executed' | 'command:gitlens.views.worktrees.setShowBranchPullRequestOff:executed' | 'command:gitlens.views.worktrees.setShowBranchPullRequestOn:executed' | 'command:gitlens.views.worktrees.setShowStashesOff:executed' | 'command:gitlens.views.worktrees.setShowStashesOn:executed' | 'command:gitlens.views.worktrees.viewOptionsTitle:executed' | 'command:gitlens.visualizeHistory.file:editor:executed' | 'command:gitlens.visualizeHistory.file:explorer:executed' | 'command:gitlens.visualizeHistory.file:scm:executed' | 'command:gitlens.visualizeHistory.file:views:executed' | 'command:gitlens.visualizeHistory.folder:explorer:executed' | 'command:gitlens.visualizeHistory.folder:scm:executed' | `command:gitlens.action.${string}:executed` | 'command:gitlens.diffWith:executed' | 'command:gitlens.ai.explainCommit:editor:executed' | 'command:gitlens.ai.explainWip:editor:executed' | 'command:gitlens.openOnRemote:executed' | 'command:gitlens.openWalkthrough:executed' | 'command:gitlens.refreshHover:executed' | 'command:gitlens.visualizeHistory:executed' | 'command:gitlens.graph.abortPausedOperation:executed' | 'command:gitlens.graph.continuePausedOperation:executed' | 'command:gitlens.graph.openRebaseEditor:executed' | 'command:gitlens.graph.skipPausedOperation:executed' | 'command:gitlens.visualizeHistory.repo:graph:executed' | 'command:gitlens.ai.explainWip:home:executed' | 'command:gitlens.ai.explainBranch:home:executed' | 'command:gitlens.ai.generateCommits:home:executed' | 'command:gitlens.home.changeBranchMergeTarget:executed' | 'command:gitlens.home.deleteBranchOrWorktree:executed' | 'command:gitlens.home.pushBranch:executed' | 'command:gitlens.home.openMergeTargetComparison:executed' | 'command:gitlens.home.openPullRequestChanges:executed' | 'command:gitlens.home.openPullRequestComparison:executed' | 'command:gitlens.home.openPullRequestOnRemote:executed' | 'command:gitlens.home.openPullRequestDetails:executed' | 'command:gitlens.home.createPullRequest:executed' | 'command:gitlens.home.openWorktree:executed' | 'command:gitlens.home.switchToBranch:executed' | 'command:gitlens.home.fetch:executed' | 'command:gitlens.home.openInGraph:executed' | 'command:gitlens.openInView.branch:home:executed' | 'command:gitlens.home.createBranch:executed' | 'command:gitlens.home.mergeIntoCurrent:executed' | 'command:gitlens.home.rebaseCurrentOnto:executed' | 'command:gitlens.home.startWork:executed' | 'command:gitlens.home.createCloudPatch:executed' | 'command:gitlens.home.skipPausedOperation:executed' | 'command:gitlens.home.continuePausedOperation:executed' | 'command:gitlens.home.abortPausedOperation:executed' | 'command:gitlens.home.openRebaseEditor:executed' | 'command:gitlens.home.enableAi:executed' | 'command:gitlens.visualizeHistory.repo:home:executed' | 'command:gitlens.visualizeHistory.branch:home:executed' | 'command:gitlens.views.home.account.resync:executed' | 'command:gitlens.views.home.ai.allAccess.dismiss:executed' | 'command:gitlens.views.home.publishBranch:executed' | 'command:gitlens.views.home.pull:executed' | 'command:gitlens.views.home.push:executed' | 'command:gitlens.launchpad.indicator.action:executed' | 'command:gitlens.plus.aiAllAccess.optIn:executed' | 'command:gitlens.plus.continueFeaturePreview:executed' | 'command:gitlens.plus.resendVerification:executed' | 'command:gitlens.plus.showPlans:executed' | 'command:gitlens.plus.validate:executed' | 'command:gitlens.views.scm.grouped.welcome.dismiss:executed' | 'command:gitlens.views.scm.grouped.welcome.restore:executed' | 'command:gitlens.views.searchAndCompare.compareWithSelected:executed' | 'command:gitlens.views.timeline.openInTab:executed' | 'command:gitlens.walkthrough.connectIntegrations:executed' | 'command:gitlens.walkthrough.enableAiSetting:executed' | 'command:gitlens.walkthrough.gitlensInspect:executed' | 'command:gitlens.walkthrough.openAcceleratePrReviews:executed' | 'command:gitlens.walkthrough.openAiCustomInstructionsSettings:executed' | 'command:gitlens.walkthrough.openAiSettings:executed' | 'command:gitlens.walkthrough.openCommunityVsPro:executed' | 'command:gitlens.walkthrough.openHelpCenter:executed' | 'command:gitlens.walkthrough.openHomeViewVideo:executed' | 'command:gitlens.walkthrough.openInteractiveCodeHistory:executed' | 'command:gitlens.walkthrough.openLearnAboutAiFeatures:executed' | 'command:gitlens.walkthrough.openStartIntegrations:executed' | 'command:gitlens.walkthrough.openStreamlineCollaboration:executed' | 'command:gitlens.walkthrough.openWalkthrough:executed' | 'command:gitlens.walkthrough.plus.signUp:executed' | 'command:gitlens.walkthrough.plus.upgrade:executed' | 'command:gitlens.walkthrough.plus.reactivate:executed' | 'command:gitlens.walkthrough.showAutolinks:executed' | 'command:gitlens.walkthrough.showDraftsView:executed' | 'command:gitlens.walkthrough.showGraph:executed' | 'command:gitlens.walkthrough.showHomeView:executed' | 'command:gitlens.walkthrough.showLaunchpad:executed' | 'command:gitlens.walkthrough.switchAIProvider:executed' | 'command:gitlens.walkthrough.worktree.create:executed' | 'command:gitlens.walkthrough.openDevExPlatform:executed' | 'command:gitlens.generateCommitMessage:executed' | 'command:gitlens.scm.generateCommitMessage:executed' | 'command:gitlens.scm.ai.generateCommitMessage:executed' | 'command:gitlens.switchAIModel:executed' | 'command:gitlens.diffHeadWith:executed' | 'command:gitlens.diffWorkingWith:executed' | 'command:gitlens.openBranchesInRemote:executed' | 'command:gitlens.openBranchInRemote:executed' | 'command:gitlens.openCommitInRemote:executed' | 'command:gitlens.openFileInRemote:executed' | 'command:gitlens.openInRemote:executed' | 'command:gitlens.openRepoInRemote:executed' | 'command:gitlens.showFileHistoryInView:executed' | 'home:walkthrough:dismissed' + 'usage.key': 'rebaseEditor:shown' | 'graphWebview:shown' | 'patchDetailsWebview:shown' | 'settingsWebview:shown' | 'timelineWebview:shown' | 'graphView:shown' | 'patchDetailsView:shown' | 'timelineView:shown' | 'commitDetailsView:shown' | 'graphDetailsView:shown' | 'homeView:shown' | 'pullRequestView:shown' | 'commitsView:shown' | 'stashesView:shown' | 'tagsView:shown' | 'launchpadView:shown' | 'worktreesView:shown' | 'branchesView:shown' | 'contributorsView:shown' | 'draftsView:shown' | 'fileHistoryView:shown' | 'scm.groupedView:shown' | 'lineHistoryView:shown' | 'remotesView:shown' | 'repositoriesView:shown' | 'searchAndCompareView:shown' | 'workspacesView:shown' | 'command:gitlens.key.alt+,:executed' | 'command:gitlens.key.alt+.:executed' | 'command:gitlens.key.alt+enter:executed' | 'command:gitlens.key.alt+left:executed' | 'command:gitlens.key.alt+right:executed' | 'command:gitlens.key.ctrl+enter:executed' | 'command:gitlens.key.ctrl+left:executed' | 'command:gitlens.key.ctrl+right:executed' | 'command:gitlens.key.escape:executed' | 'command:gitlens.key.left:executed' | 'command:gitlens.key.right:executed' | 'command:gitlens.addAuthors:executed' | 'command:gitlens.ai.explainBranch:executed' | 'command:gitlens.ai.explainCommit:executed' | 'command:gitlens.ai.explainStash:executed' | 'command:gitlens.ai.explainWip:executed' | 'command:gitlens.ai.generateChangelog:executed' | 'command:gitlens.ai.generateCommitMessage:executed' | 'command:gitlens.ai.generateCommits:executed' | 'command:gitlens.ai.generateRebase:executed' | 'command:gitlens.ai.mcp.install:executed' | 'command:gitlens.ai.switchProvider:executed' | 'command:gitlens.applyPatchFromClipboard:executed' | 'command:gitlens.associateIssueWithBranch:executed' | 'command:gitlens.browseRepoAtRevision:executed' | 'command:gitlens.browseRepoAtRevisionInNewWindow:executed' | 'command:gitlens.browseRepoBeforeRevision:executed' | 'command:gitlens.browseRepoBeforeRevisionInNewWindow:executed' | 'command:gitlens.changeBranchMergeTarget:executed' | 'command:gitlens.clearFileAnnotations:executed' | 'command:gitlens.closeUnchangedFiles:executed' | 'command:gitlens.compareHeadWith:executed' | 'command:gitlens.compareWith:executed' | 'command:gitlens.compareWorkingWith:executed' | 'command:gitlens.connectRemoteProvider:executed' | 'command:gitlens.copyCurrentBranch:executed' | 'command:gitlens.copyDeepLinkToRepo:executed' | 'command:gitlens.copyMessageToClipboard:executed' | 'command:gitlens.copyPatchToClipboard:executed' | 'command:gitlens.copyRelativePathToClipboard:executed' | 'command:gitlens.copyRemoteCommitUrl:executed' | 'command:gitlens.copyRemoteFileUrlFrom:executed' | 'command:gitlens.copyRemoteFileUrlToClipboard:executed' | 'command:gitlens.copyShaToClipboard:executed' | 'command:gitlens.copyWorkingChangesToWorktree:executed' | 'command:gitlens.createCloudPatch:executed' | 'command:gitlens.createPatch:executed' | 'command:gitlens.createPullRequestOnRemote:executed' | 'command:gitlens.diffDirectory:executed' | 'command:gitlens.diffDirectoryWithHead:executed' | 'command:gitlens.diffFolderWithRevision:executed' | 'command:gitlens.diffFolderWithRevisionFrom:executed' | 'command:gitlens.diffLineWithPrevious:executed' | 'command:gitlens.diffLineWithWorking:executed' | 'command:gitlens.diffWithNext:executed' | 'command:gitlens.diffWithPrevious:executed' | 'command:gitlens.diffWithRevision:executed' | 'command:gitlens.diffWithRevisionFrom:executed' | 'command:gitlens.diffWithWorking:executed' | 'command:gitlens.disableDebugLogging:executed' | 'command:gitlens.disableRebaseEditor:executed' | 'command:gitlens.disconnectRemoteProvider:executed' | 'command:gitlens.enableDebugLogging:executed' | 'command:gitlens.enableRebaseEditor:executed' | 'command:gitlens.externalDiff:executed' | 'command:gitlens.externalDiffAll:executed' | 'command:gitlens.fetchRepositories:executed' | 'command:gitlens.getStarted:executed' | 'command:gitlens.gitCommands:executed' | 'command:gitlens.gitCommands.branch:executed' | 'command:gitlens.gitCommands.branch.create:executed' | 'command:gitlens.gitCommands.branch.delete:executed' | 'command:gitlens.gitCommands.branch.prune:executed' | 'command:gitlens.gitCommands.branch.rename:executed' | 'command:gitlens.gitCommands.checkout:executed' | 'command:gitlens.gitCommands.cherryPick:executed' | 'command:gitlens.gitCommands.history:executed' | 'command:gitlens.gitCommands.merge:executed' | 'command:gitlens.gitCommands.rebase:executed' | 'command:gitlens.gitCommands.remote:executed' | 'command:gitlens.gitCommands.remote.add:executed' | 'command:gitlens.gitCommands.remote.prune:executed' | 'command:gitlens.gitCommands.remote.remove:executed' | 'command:gitlens.gitCommands.reset:executed' | 'command:gitlens.gitCommands.revert:executed' | 'command:gitlens.gitCommands.show:executed' | 'command:gitlens.gitCommands.stash:executed' | 'command:gitlens.gitCommands.stash.drop:executed' | 'command:gitlens.gitCommands.stash.list:executed' | 'command:gitlens.gitCommands.stash.pop:executed' | 'command:gitlens.gitCommands.stash.push:executed' | 'command:gitlens.gitCommands.stash.rename:executed' | 'command:gitlens.gitCommands.status:executed' | 'command:gitlens.gitCommands.switch:executed' | 'command:gitlens.gitCommands.tag:executed' | 'command:gitlens.gitCommands.tag.create:executed' | 'command:gitlens.gitCommands.tag.delete:executed' | 'command:gitlens.gitCommands.worktree:executed' | 'command:gitlens.gitCommands.worktree.create:executed' | 'command:gitlens.gitCommands.worktree.delete:executed' | 'command:gitlens.gitCommands.worktree.open:executed' | 'command:gitlens.gk.switchOrganization:executed' | 'command:gitlens.graph.split:executed' | 'command:gitlens.graph.switchToEditorLayout:executed' | 'command:gitlens.graph.switchToPanelLayout:executed' | 'command:gitlens.launchpad.indicator.toggle:executed' | 'command:gitlens.openAssociatedPullRequestOnRemote:executed' | 'command:gitlens.openBlamePriorToChange:executed' | 'command:gitlens.openBranchOnRemote:executed' | 'command:gitlens.openBranchesOnRemote:executed' | 'command:gitlens.openChangedFiles:executed' | 'command:gitlens.openCommitOnRemote:executed' | 'command:gitlens.openCurrentBranchOnRemote:executed' | 'command:gitlens.openFileFromRemote:executed' | 'command:gitlens.openFileHistory:executed' | 'command:gitlens.openFileOnRemote:executed' | 'command:gitlens.openFileOnRemoteFrom:executed' | 'command:gitlens.openFileRevision:executed' | 'command:gitlens.openFileRevisionFrom:executed' | 'command:gitlens.openOnlyChangedFiles:executed' | 'command:gitlens.openPatch:executed' | 'command:gitlens.openRepoOnRemote:executed' | 'command:gitlens.openRevisionFile:executed' | 'command:gitlens.openRevisionFromRemote:executed' | 'command:gitlens.openWorkingFile:executed' | 'command:gitlens.pastePatchFromClipboard:executed' | 'command:gitlens.plus.cloudIntegrations.manage:executed' | 'command:gitlens.plus.hide:executed' | 'command:gitlens.plus.login:executed' | 'command:gitlens.plus.logout:executed' | 'command:gitlens.plus.manage:executed' | 'command:gitlens.plus.reactivateProTrial:executed' | 'command:gitlens.plus.referFriend:executed' | 'command:gitlens.plus.refreshRepositoryAccess:executed' | 'command:gitlens.plus.restore:executed' | 'command:gitlens.plus.signUp:executed' | 'command:gitlens.plus.simulateSubscription:executed' | 'command:gitlens.plus.upgrade:executed' | 'command:gitlens.pullRepositories:executed' | 'command:gitlens.pushRepositories:executed' | 'command:gitlens.quickOpenFileHistory:executed' | 'command:gitlens.reset:executed' | 'command:gitlens.resetViewsLayout:executed' | 'command:gitlens.revealCommitInView:executed' | 'command:gitlens.shareAsCloudPatch:executed' | 'command:gitlens.showAccountView:executed' | 'command:gitlens.showBranchesView:executed' | 'command:gitlens.showCommitDetailsView:executed' | 'command:gitlens.showCommitInView:executed' | 'command:gitlens.showCommitSearch:executed' | 'command:gitlens.showCommitsInView:executed' | 'command:gitlens.showCommitsView:executed' | 'command:gitlens.showContributorsView:executed' | 'command:gitlens.showDraftsView:executed' | 'command:gitlens.showFileHistoryView:executed' | 'command:gitlens.showGraph:executed' | 'command:gitlens.showGraphPage:executed' | 'command:gitlens.showGraphView:executed' | 'command:gitlens.showHomeView:executed' | 'command:gitlens.showLastQuickPick:executed' | 'command:gitlens.showLaunchpad:executed' | 'command:gitlens.showLaunchpadView:executed' | 'command:gitlens.showLineCommitInView:executed' | 'command:gitlens.showLineHistoryView:executed' | 'command:gitlens.showPatchDetailsPage:executed' | 'command:gitlens.showQuickBranchHistory:executed' | 'command:gitlens.showQuickCommitFileDetails:executed' | 'command:gitlens.showQuickFileHistory:executed' | 'command:gitlens.showQuickRepoHistory:executed' | 'command:gitlens.showQuickRepoStatus:executed' | 'command:gitlens.showQuickRevisionDetails:executed' | 'command:gitlens.showQuickStashList:executed' | 'command:gitlens.showRemotesView:executed' | 'command:gitlens.showRepositoriesView:executed' | 'command:gitlens.showSearchAndCompareView:executed' | 'command:gitlens.showSettingsPage:executed' | 'command:gitlens.showSettingsPage!autolinks:executed' | 'command:gitlens.showStashesView:executed' | 'command:gitlens.showTagsView:executed' | 'command:gitlens.showTimelinePage:executed' | 'command:gitlens.showTimelineView:executed' | 'command:gitlens.showWorkspacesView:executed' | 'command:gitlens.showWorktreesView:executed' | 'command:gitlens.startWork:executed' | 'command:gitlens.stashSave:executed' | 'command:gitlens.stashSave.staged:scm:executed' | 'command:gitlens.stashSave.unstaged:scm:executed' | 'command:gitlens.stashSave:scm:executed' | 'command:gitlens.stashesApply:executed' | 'command:gitlens.switchMode:executed' | 'command:gitlens.timeline.split:executed' | 'command:gitlens.toggleCodeLens:executed' | 'command:gitlens.toggleFileBlame:executed' | 'command:gitlens.toggleFileChanges:executed' | 'command:gitlens.toggleFileHeatmap:executed' | 'command:gitlens.toggleGraph:executed' | 'command:gitlens.toggleLineBlame:executed' | 'command:gitlens.toggleMaximizedGraph:executed' | 'command:gitlens.toggleReviewMode:executed' | 'command:gitlens.toggleZenMode:executed' | 'command:gitlens.views.workspaces.create:executed' | 'command:gitlens.visualizeHistory.file:executed' | 'command:gitlens.ai.explainBranch:graph:executed' | 'command:gitlens.ai.explainBranch:views:executed' | 'command:gitlens.ai.explainCommit:graph:executed' | 'command:gitlens.ai.explainCommit:views:executed' | 'command:gitlens.ai.explainStash:graph:executed' | 'command:gitlens.ai.explainStash:views:executed' | 'command:gitlens.ai.explainWip:graph:executed' | 'command:gitlens.ai.explainWip:views:executed' | 'command:gitlens.ai.feedback.helpful:executed' | 'command:gitlens.ai.feedback.helpful.chosen:executed' | 'command:gitlens.ai.feedback.unhelpful:executed' | 'command:gitlens.ai.feedback.unhelpful.chosen:executed' | 'command:gitlens.ai.generateChangelog:views:executed' | 'command:gitlens.ai.generateChangelogFrom:graph:executed' | 'command:gitlens.ai.generateChangelogFrom:views:executed' | 'command:gitlens.ai.generateCommitMessage:graph:executed' | 'command:gitlens.ai.generateCommitMessage:scm:executed' | 'command:gitlens.ai.generateCommits:graph:executed' | 'command:gitlens.ai.generateCommits:views:executed' | 'command:gitlens.ai.rebaseOntoCommit:graph:executed' | 'command:gitlens.ai.rebaseOntoCommit:views:executed' | 'command:gitlens.ai.undoGenerateRebase:executed' | 'command:gitlens.annotations.nextChange:executed' | 'command:gitlens.annotations.previousChange:executed' | 'command:gitlens.computingFileAnnotations:executed' | 'command:gitlens.copyDeepLinkToBranch:executed' | 'command:gitlens.copyDeepLinkToCommit:executed' | 'command:gitlens.copyDeepLinkToComparison:executed' | 'command:gitlens.copyDeepLinkToFile:executed' | 'command:gitlens.copyDeepLinkToFileAtRevision:executed' | 'command:gitlens.copyDeepLinkToLines:executed' | 'command:gitlens.copyDeepLinkToTag:executed' | 'command:gitlens.copyDeepLinkToWorkspace:executed' | 'command:gitlens.copyRemoteBranchUrl:executed' | 'command:gitlens.copyRemoteBranchesUrl:executed' | 'command:gitlens.copyRemoteComparisonUrl:executed' | 'command:gitlens.copyRemoteFileUrlWithoutRange:executed' | 'command:gitlens.copyRemotePullRequestUrl:executed' | 'command:gitlens.copyRemoteRepositoryUrl:executed' | 'command:gitlens.copyWorkingChangesToWorktree:views:executed' | 'command:gitlens.ghpr.views.openOrCreateWorktree:executed' | 'command:gitlens.graph.addAuthor:executed' | 'command:gitlens.graph.associateIssueWithBranch:executed' | 'command:gitlens.graph.cherryPick:executed' | 'command:gitlens.graph.cherryPick.multi:executed' | 'command:gitlens.graph.columnAuthorOff:executed' | 'command:gitlens.graph.columnAuthorOn:executed' | 'command:gitlens.graph.columnChangesOff:executed' | 'command:gitlens.graph.columnChangesOn:executed' | 'command:gitlens.graph.columnDateTimeOff:executed' | 'command:gitlens.graph.columnDateTimeOn:executed' | 'command:gitlens.graph.columnGraphCompact:executed' | 'command:gitlens.graph.columnGraphDefault:executed' | 'command:gitlens.graph.columnGraphOff:executed' | 'command:gitlens.graph.columnGraphOn:executed' | 'command:gitlens.graph.columnMessageOff:executed' | 'command:gitlens.graph.columnMessageOn:executed' | 'command:gitlens.graph.columnRefOff:executed' | 'command:gitlens.graph.columnRefOn:executed' | 'command:gitlens.graph.columnShaOff:executed' | 'command:gitlens.graph.columnShaOn:executed' | 'command:gitlens.graph.commitViaSCM:executed' | 'command:gitlens.graph.compareAncestryWithWorking:executed' | 'command:gitlens.graph.compareBranchWithHead:executed' | 'command:gitlens.graph.compareSelectedCommits.multi:executed' | 'command:gitlens.graph.compareWithHead:executed' | 'command:gitlens.graph.compareWithMergeBase:executed' | 'command:gitlens.graph.compareWithUpstream:executed' | 'command:gitlens.graph.compareWithWorking:executed' | 'command:gitlens.graph.copy:executed' | 'command:gitlens.graph.copyDeepLinkToBranch:executed' | 'command:gitlens.graph.copyDeepLinkToCommit:executed' | 'command:gitlens.graph.copyDeepLinkToRepo:executed' | 'command:gitlens.graph.copyDeepLinkToTag:executed' | 'command:gitlens.graph.copyMessage:executed' | 'command:gitlens.graph.copyRemoteBranchUrl:executed' | 'command:gitlens.graph.copyRemoteCommitUrl:executed' | 'command:gitlens.graph.copyRemoteCommitUrl.multi:executed' | 'command:gitlens.graph.copySha:executed' | 'command:gitlens.graph.copyWorkingChangesToWorktree:executed' | 'command:gitlens.graph.createBranch:executed' | 'command:gitlens.graph.createCloudPatch:executed' | 'command:gitlens.graph.createPatch:executed' | 'command:gitlens.graph.createPullRequest:executed' | 'command:gitlens.graph.createTag:executed' | 'command:gitlens.graph.createWorktree:executed' | 'command:gitlens.graph.deleteBranch:executed' | 'command:gitlens.graph.deleteTag:executed' | 'command:gitlens.graph.fetch:executed' | 'command:gitlens.graph.hideLocalBranch:executed' | 'command:gitlens.graph.hideRefGroup:executed' | 'command:gitlens.graph.hideRemote:executed' | 'command:gitlens.graph.hideRemoteBranch:executed' | 'command:gitlens.graph.hideTag:executed' | 'command:gitlens.graph.mergeBranchInto:executed' | 'command:gitlens.graph.openBranchOnRemote:executed' | 'command:gitlens.graph.openChangedFileDiffs:executed' | 'command:gitlens.graph.openChangedFileDiffsIndividually:executed' | 'command:gitlens.graph.openChangedFileDiffsWithMergeBase:executed' | 'command:gitlens.graph.openChangedFileDiffsWithWorking:executed' | 'command:gitlens.graph.openChangedFileDiffsWithWorkingIndividually:executed' | 'command:gitlens.graph.openChangedFileRevisions:executed' | 'command:gitlens.graph.openChangedFiles:executed' | 'command:gitlens.graph.openCommitOnRemote:executed' | 'command:gitlens.graph.openCommitOnRemote.multi:executed' | 'command:gitlens.graph.openInWorktree:executed' | 'command:gitlens.graph.openOnlyChangedFiles:executed' | 'command:gitlens.graph.openPullRequest:executed' | 'command:gitlens.graph.openPullRequestChanges:executed' | 'command:gitlens.graph.openPullRequestComparison:executed' | 'command:gitlens.graph.openPullRequestOnRemote:executed' | 'command:gitlens.graph.openWorktree:executed' | 'command:gitlens.graph.openWorktreeInNewWindow:executed' | 'command:gitlens.graph.publishBranch:executed' | 'command:gitlens.graph.pull:executed' | 'command:gitlens.graph.push:executed' | 'command:gitlens.graph.pushWithForce:executed' | 'command:gitlens.graph.rebaseOntoBranch:executed' | 'command:gitlens.graph.rebaseOntoCommit:executed' | 'command:gitlens.graph.rebaseOntoUpstream:executed' | 'command:gitlens.graph.refresh:executed' | 'command:gitlens.graph.renameBranch:executed' | 'command:gitlens.graph.resetColumnsCompact:executed' | 'command:gitlens.graph.resetColumnsDefault:executed' | 'command:gitlens.graph.resetCommit:executed' | 'command:gitlens.graph.resetToCommit:executed' | 'command:gitlens.graph.resetToTag:executed' | 'command:gitlens.graph.resetToTip:executed' | 'command:gitlens.graph.revert:executed' | 'command:gitlens.graph.scrollMarkerLocalBranchOff:executed' | 'command:gitlens.graph.scrollMarkerLocalBranchOn:executed' | 'command:gitlens.graph.scrollMarkerPullRequestOff:executed' | 'command:gitlens.graph.scrollMarkerPullRequestOn:executed' | 'command:gitlens.graph.scrollMarkerRemoteBranchOff:executed' | 'command:gitlens.graph.scrollMarkerRemoteBranchOn:executed' | 'command:gitlens.graph.scrollMarkerStashOff:executed' | 'command:gitlens.graph.scrollMarkerStashOn:executed' | 'command:gitlens.graph.scrollMarkerTagOff:executed' | 'command:gitlens.graph.scrollMarkerTagOn:executed' | 'command:gitlens.graph.shareAsCloudPatch:executed' | 'command:gitlens.graph.showInDetailsView:executed' | 'command:gitlens.graph.switchToAnotherBranch:executed' | 'command:gitlens.graph.switchToBranch:executed' | 'command:gitlens.graph.switchToCommit:executed' | 'command:gitlens.graph.switchToTag:executed' | 'command:gitlens.graph.undoCommit:executed' | 'command:gitlens.inviteToLiveShare:executed' | 'command:gitlens.openCloudPatch:executed' | 'command:gitlens.openComparisonOnRemote:executed' | 'command:gitlens.openFolderHistory:executed' | 'command:gitlens.openPullRequestOnRemote:executed' | 'command:gitlens.plus.cloudIntegrations.connect:executed' | 'command:gitlens.regenerateMarkdownDocument:executed' | 'command:gitlens.showInCommitGraph:executed' | 'command:gitlens.showInCommitGraphView:executed' | 'command:gitlens.showInDetailsView:executed' | 'command:gitlens.showQuickCommitDetails:executed' | 'command:gitlens.showSettingsPage!branches-view:executed' | 'command:gitlens.showSettingsPage!commit-graph:executed' | 'command:gitlens.showSettingsPage!commits-view:executed' | 'command:gitlens.showSettingsPage!contributors-view:executed' | 'command:gitlens.showSettingsPage!file-annotations:executed' | 'command:gitlens.showSettingsPage!file-history-view:executed' | 'command:gitlens.showSettingsPage!line-history-view:executed' | 'command:gitlens.showSettingsPage!remotes-view:executed' | 'command:gitlens.showSettingsPage!repositories-view:executed' | 'command:gitlens.showSettingsPage!search-compare-view:executed' | 'command:gitlens.showSettingsPage!stashes-view:executed' | 'command:gitlens.showSettingsPage!tags-view:executed' | 'command:gitlens.showSettingsPage!views:executed' | 'command:gitlens.showSettingsPage!worktrees-view:executed' | 'command:gitlens.star.branch.multi:views:executed' | 'command:gitlens.star.branch:graph:executed' | 'command:gitlens.star.branch:views:executed' | 'command:gitlens.star.repository.multi:views:executed' | 'command:gitlens.star.repository:views:executed' | 'command:gitlens.stashApply:graph:executed' | 'command:gitlens.stashApply:views:executed' | 'command:gitlens.stashDelete.multi:views:executed' | 'command:gitlens.stashDelete:graph:executed' | 'command:gitlens.stashDelete:views:executed' | 'command:gitlens.stashRename:graph:executed' | 'command:gitlens.stashRename:views:executed' | 'command:gitlens.stashSave.files:scm:executed' | 'command:gitlens.stashSave.files:views:executed' | 'command:gitlens.stashSave:graph:executed' | 'command:gitlens.stashSave:views:executed' | 'command:gitlens.stashesApply:views:executed' | 'command:gitlens.timeline.refresh:executed' | 'command:gitlens.toggleFileChangesOnly:executed' | 'command:gitlens.toggleFileHeatmapInDiffLeft:executed' | 'command:gitlens.toggleFileHeatmapInDiffRight:executed' | 'command:gitlens.unstar.branch.multi:views:executed' | 'command:gitlens.unstar.branch:graph:executed' | 'command:gitlens.unstar.branch:views:executed' | 'command:gitlens.unstar.repository.multi:views:executed' | 'command:gitlens.unstar.repository:views:executed' | 'command:gitlens.views.abortPausedOperation:executed' | 'command:gitlens.views.addAuthor:executed' | 'command:gitlens.views.addAuthor.multi:executed' | 'command:gitlens.views.addAuthors:executed' | 'command:gitlens.views.addPullRequestRemote:executed' | 'command:gitlens.views.addRemote:executed' | 'command:gitlens.views.applyChanges:executed' | 'command:gitlens.views.associateIssueWithBranch:executed' | 'command:gitlens.views.branches.attach:executed' | 'command:gitlens.views.branches.copy:executed' | 'command:gitlens.views.branches.refresh:executed' | 'command:gitlens.views.branches.setFilesLayoutToAuto:executed' | 'command:gitlens.views.branches.setFilesLayoutToList:executed' | 'command:gitlens.views.branches.setFilesLayoutToTree:executed' | 'command:gitlens.views.branches.setLayoutToList:executed' | 'command:gitlens.views.branches.setLayoutToTree:executed' | 'command:gitlens.views.branches.setShowAvatarsOff:executed' | 'command:gitlens.views.branches.setShowAvatarsOn:executed' | 'command:gitlens.views.branches.setShowBranchComparisonOff:executed' | 'command:gitlens.views.branches.setShowBranchComparisonOn:executed' | 'command:gitlens.views.branches.setShowBranchPullRequestOff:executed' | 'command:gitlens.views.branches.setShowBranchPullRequestOn:executed' | 'command:gitlens.views.branches.setShowRemoteBranchesOff:executed' | 'command:gitlens.views.branches.setShowRemoteBranchesOn:executed' | 'command:gitlens.views.branches.setShowStashesOff:executed' | 'command:gitlens.views.branches.setShowStashesOn:executed' | 'command:gitlens.views.branches.viewOptionsTitle:executed' | 'command:gitlens.views.browseRepoAtRevision:executed' | 'command:gitlens.views.browseRepoAtRevisionInNewWindow:executed' | 'command:gitlens.views.browseRepoBeforeRevision:executed' | 'command:gitlens.views.browseRepoBeforeRevisionInNewWindow:executed' | 'command:gitlens.views.cherryPick:executed' | 'command:gitlens.views.cherryPick.multi:executed' | 'command:gitlens.views.clearComparison:executed' | 'command:gitlens.views.clearReviewed:executed' | 'command:gitlens.views.closeRepository:executed' | 'command:gitlens.views.collapseNode:executed' | 'command:gitlens.views.commitDetails.refresh:executed' | 'command:gitlens.views.commits.attach:executed' | 'command:gitlens.views.commits.copy:executed' | 'command:gitlens.views.commits.refresh:executed' | 'command:gitlens.views.commits.setCommitsFilterAuthors:executed' | 'command:gitlens.views.commits.setCommitsFilterOff:executed' | 'command:gitlens.views.commits.setFilesLayoutToAuto:executed' | 'command:gitlens.views.commits.setFilesLayoutToList:executed' | 'command:gitlens.views.commits.setFilesLayoutToTree:executed' | 'command:gitlens.views.commits.setShowAvatarsOff:executed' | 'command:gitlens.views.commits.setShowAvatarsOn:executed' | 'command:gitlens.views.commits.setShowBranchComparisonOff:executed' | 'command:gitlens.views.commits.setShowBranchComparisonOn:executed' | 'command:gitlens.views.commits.setShowBranchPullRequestOff:executed' | 'command:gitlens.views.commits.setShowBranchPullRequestOn:executed' | 'command:gitlens.views.commits.setShowMergeCommitsOff:executed' | 'command:gitlens.views.commits.setShowMergeCommitsOn:executed' | 'command:gitlens.views.commits.setShowStashesOff:executed' | 'command:gitlens.views.commits.setShowStashesOn:executed' | 'command:gitlens.views.commits.viewOptionsTitle:executed' | 'command:gitlens.views.compareAncestryWithWorking:executed' | 'command:gitlens.views.compareBranchWithHead:executed' | 'command:gitlens.views.compareFileWithSelected:executed' | 'command:gitlens.views.compareWithHead:executed' | 'command:gitlens.views.compareWithMergeBase:executed' | 'command:gitlens.views.compareWithSelected:executed' | 'command:gitlens.views.compareWithUpstream:executed' | 'command:gitlens.views.compareWithWorking:executed' | 'command:gitlens.views.continuePausedOperation:executed' | 'command:gitlens.views.contributors.attach:executed' | 'command:gitlens.views.contributors.copy:executed' | 'command:gitlens.views.contributors.refresh:executed' | 'command:gitlens.views.contributors.setFilesLayoutToAuto:executed' | 'command:gitlens.views.contributors.setFilesLayoutToList:executed' | 'command:gitlens.views.contributors.setFilesLayoutToTree:executed' | 'command:gitlens.views.contributors.setShowAllBranchesOff:executed' | 'command:gitlens.views.contributors.setShowAllBranchesOn:executed' | 'command:gitlens.views.contributors.setShowAvatarsOff:executed' | 'command:gitlens.views.contributors.setShowAvatarsOn:executed' | 'command:gitlens.views.contributors.setShowMergeCommitsOff:executed' | 'command:gitlens.views.contributors.setShowMergeCommitsOn:executed' | 'command:gitlens.views.contributors.setShowStatisticsOff:executed' | 'command:gitlens.views.contributors.setShowStatisticsOn:executed' | 'command:gitlens.views.contributors.viewOptionsTitle:executed' | 'command:gitlens.views.copy:executed' | 'command:gitlens.views.copyAsMarkdown:executed' | 'command:gitlens.views.copyRemoteCommitUrl:executed' | 'command:gitlens.views.copyRemoteCommitUrl.multi:executed' | 'command:gitlens.views.copyUrl:executed' | 'command:gitlens.views.copyUrl.multi:executed' | 'command:gitlens.views.createBranch:executed' | 'command:gitlens.views.createPullRequest:executed' | 'command:gitlens.views.createTag:executed' | 'command:gitlens.views.createWorktree:executed' | 'command:gitlens.views.deleteBranch:executed' | 'command:gitlens.views.deleteBranch.multi:executed' | 'command:gitlens.views.deleteTag:executed' | 'command:gitlens.views.deleteTag.multi:executed' | 'command:gitlens.views.deleteWorktree:executed' | 'command:gitlens.views.deleteWorktree.multi:executed' | 'command:gitlens.views.dismissNode:executed' | 'command:gitlens.views.draft.open:executed' | 'command:gitlens.views.draft.openOnWeb:executed' | 'command:gitlens.views.drafts.copy:executed' | 'command:gitlens.views.drafts.create:executed' | 'command:gitlens.views.drafts.delete:executed' | 'command:gitlens.views.drafts.info:executed' | 'command:gitlens.views.drafts.refresh:executed' | 'command:gitlens.views.drafts.setShowAvatarsOff:executed' | 'command:gitlens.views.drafts.setShowAvatarsOn:executed' | 'command:gitlens.views.editNode:executed' | 'command:gitlens.views.expandNode:executed' | 'command:gitlens.views.fetch:executed' | 'command:gitlens.views.fileHistory.attach:executed' | 'command:gitlens.views.fileHistory.changeBase:executed' | 'command:gitlens.views.fileHistory.copy:executed' | 'command:gitlens.views.fileHistory.refresh:executed' | 'command:gitlens.views.fileHistory.setCursorFollowingOff:executed' | 'command:gitlens.views.fileHistory.setCursorFollowingOn:executed' | 'command:gitlens.views.fileHistory.setEditorFollowingOff:executed' | 'command:gitlens.views.fileHistory.setEditorFollowingOn:executed' | 'command:gitlens.views.fileHistory.setModeCommits:executed' | 'command:gitlens.views.fileHistory.setModeContributors:executed' | 'command:gitlens.views.fileHistory.setRenameFollowingOff:executed' | 'command:gitlens.views.fileHistory.setRenameFollowingOn:executed' | 'command:gitlens.views.fileHistory.setShowAllBranchesOff:executed' | 'command:gitlens.views.fileHistory.setShowAllBranchesOn:executed' | 'command:gitlens.views.fileHistory.setShowAvatarsOff:executed' | 'command:gitlens.views.fileHistory.setShowAvatarsOn:executed' | 'command:gitlens.views.fileHistory.setShowMergeCommitsOff:executed' | 'command:gitlens.views.fileHistory.setShowMergeCommitsOn:executed' | 'command:gitlens.views.fileHistory.viewOptionsTitle:executed' | 'command:gitlens.views.graph.openInTab:executed' | 'command:gitlens.views.graph.refresh:executed' | 'command:gitlens.views.graphDetails.refresh:executed' | 'command:gitlens.views.highlightChanges:executed' | 'command:gitlens.views.highlightRevisionChanges:executed' | 'command:gitlens.views.home.disablePreview:executed' | 'command:gitlens.views.home.discussions:executed' | 'command:gitlens.views.home.enablePreview:executed' | 'command:gitlens.views.home.help:executed' | 'command:gitlens.views.home.info:executed' | 'command:gitlens.views.home.issues:executed' | 'command:gitlens.views.home.previewFeedback:executed' | 'command:gitlens.views.home.refresh:executed' | 'command:gitlens.views.home.whatsNew:executed' | 'command:gitlens.views.launchpad.attach:executed' | 'command:gitlens.views.launchpad.copy:executed' | 'command:gitlens.views.launchpad.info:executed' | 'command:gitlens.views.launchpad.refresh:executed' | 'command:gitlens.views.launchpad.setFilesLayoutToAuto:executed' | 'command:gitlens.views.launchpad.setFilesLayoutToList:executed' | 'command:gitlens.views.launchpad.setFilesLayoutToTree:executed' | 'command:gitlens.views.launchpad.setShowAvatarsOff:executed' | 'command:gitlens.views.launchpad.setShowAvatarsOn:executed' | 'command:gitlens.views.launchpad.viewOptionsTitle:executed' | 'command:gitlens.views.lineHistory.changeBase:executed' | 'command:gitlens.views.lineHistory.copy:executed' | 'command:gitlens.views.lineHistory.refresh:executed' | 'command:gitlens.views.lineHistory.setEditorFollowingOff:executed' | 'command:gitlens.views.lineHistory.setEditorFollowingOn:executed' | 'command:gitlens.views.lineHistory.setShowAvatarsOff:executed' | 'command:gitlens.views.lineHistory.setShowAvatarsOn:executed' | 'command:gitlens.views.loadAllChildren:executed' | 'command:gitlens.views.loadMoreChildren:executed' | 'command:gitlens.views.mergeBranchInto:executed' | 'command:gitlens.views.mergeChangesWithWorking:executed' | 'command:gitlens.views.openBranchOnRemote:executed' | 'command:gitlens.views.openBranchOnRemote.multi:executed' | 'command:gitlens.views.openChangedFileDiffs:executed' | 'command:gitlens.views.openChangedFileDiffsIndividually:executed' | 'command:gitlens.views.openChangedFileDiffsWithMergeBase:executed' | 'command:gitlens.views.openChangedFileDiffsWithWorking:executed' | 'command:gitlens.views.openChangedFileDiffsWithWorkingIndividually:executed' | 'command:gitlens.views.openChangedFileRevisions:executed' | 'command:gitlens.views.openChangedFiles:executed' | 'command:gitlens.views.openChanges:executed' | 'command:gitlens.views.openChangesWithMergeBase:executed' | 'command:gitlens.views.openChangesWithWorking:executed' | 'command:gitlens.views.openCommitOnRemote:executed' | 'command:gitlens.views.openCommitOnRemote.multi:executed' | 'command:gitlens.views.openDirectoryDiff:executed' | 'command:gitlens.views.openDirectoryDiffWithWorking:executed' | 'command:gitlens.views.openFile:executed' | 'command:gitlens.views.openFileRevision:executed' | 'command:gitlens.views.openInIntegratedTerminal:executed' | 'command:gitlens.views.openInTerminal:executed' | 'command:gitlens.views.openInWorktree:executed' | 'command:gitlens.views.openOnlyChangedFiles:executed' | 'command:gitlens.views.openPausedOperationInRebaseEditor:executed' | 'command:gitlens.views.openPreviousChangesWithWorking:executed' | 'command:gitlens.views.openPullRequest:executed' | 'command:gitlens.views.openPullRequestChanges:executed' | 'command:gitlens.views.openPullRequestComparison:executed' | 'command:gitlens.views.openUrl:executed' | 'command:gitlens.views.openUrl.multi:executed' | 'command:gitlens.views.openWorktree:executed' | 'command:gitlens.views.openWorktreeInNewWindow:executed' | 'command:gitlens.views.openWorktreeInNewWindow.multi:executed' | 'command:gitlens.views.patchDetails.close:executed' | 'command:gitlens.views.patchDetails.refresh:executed' | 'command:gitlens.views.pruneRemote:executed' | 'command:gitlens.views.publishBranch:executed' | 'command:gitlens.views.publishRepository:executed' | 'command:gitlens.views.pull:executed' | 'command:gitlens.views.pullRequest.close:executed' | 'command:gitlens.views.pullRequest.copy:executed' | 'command:gitlens.views.pullRequest.refresh:executed' | 'command:gitlens.views.pullRequest.setFilesLayoutToAuto:executed' | 'command:gitlens.views.pullRequest.setFilesLayoutToList:executed' | 'command:gitlens.views.pullRequest.setFilesLayoutToTree:executed' | 'command:gitlens.views.pullRequest.setShowAvatarsOff:executed' | 'command:gitlens.views.pullRequest.setShowAvatarsOn:executed' | 'command:gitlens.views.push:executed' | 'command:gitlens.views.pushToCommit:executed' | 'command:gitlens.views.pushWithForce:executed' | 'command:gitlens.views.rebaseOntoBranch:executed' | 'command:gitlens.views.rebaseOntoCommit:executed' | 'command:gitlens.views.rebaseOntoUpstream:executed' | 'command:gitlens.views.refreshNode:executed' | 'command:gitlens.views.remotes.attach:executed' | 'command:gitlens.views.remotes.copy:executed' | 'command:gitlens.views.remotes.refresh:executed' | 'command:gitlens.views.remotes.setFilesLayoutToAuto:executed' | 'command:gitlens.views.remotes.setFilesLayoutToList:executed' | 'command:gitlens.views.remotes.setFilesLayoutToTree:executed' | 'command:gitlens.views.remotes.setLayoutToList:executed' | 'command:gitlens.views.remotes.setLayoutToTree:executed' | 'command:gitlens.views.remotes.setShowAvatarsOff:executed' | 'command:gitlens.views.remotes.setShowAvatarsOn:executed' | 'command:gitlens.views.remotes.setShowBranchPullRequestOff:executed' | 'command:gitlens.views.remotes.setShowBranchPullRequestOn:executed' | 'command:gitlens.views.remotes.viewOptionsTitle:executed' | 'command:gitlens.views.removeRemote:executed' | 'command:gitlens.views.renameBranch:executed' | 'command:gitlens.views.repositories.attach:executed' | 'command:gitlens.views.repositories.copy:executed' | 'command:gitlens.views.repositories.refresh:executed' | 'command:gitlens.views.repositories.setAutoRefreshToOff:executed' | 'command:gitlens.views.repositories.setAutoRefreshToOn:executed' | 'command:gitlens.views.repositories.setBranchesLayoutToList:executed' | 'command:gitlens.views.repositories.setBranchesLayoutToTree:executed' | 'command:gitlens.views.repositories.setBranchesShowBranchComparisonOff:executed' | 'command:gitlens.views.repositories.setBranchesShowBranchComparisonOn:executed' | 'command:gitlens.views.repositories.setBranchesShowStashesOff:executed' | 'command:gitlens.views.repositories.setBranchesShowStashesOn:executed' | 'command:gitlens.views.repositories.setFilesLayoutToAuto:executed' | 'command:gitlens.views.repositories.setFilesLayoutToList:executed' | 'command:gitlens.views.repositories.setFilesLayoutToTree:executed' | 'command:gitlens.views.repositories.setShowAvatarsOff:executed' | 'command:gitlens.views.repositories.setShowAvatarsOn:executed' | 'command:gitlens.views.repositories.setShowSectionBranchComparisonOff:executed' | 'command:gitlens.views.repositories.setShowSectionBranchComparisonOn:executed' | 'command:gitlens.views.repositories.setShowSectionBranchesOff:executed' | 'command:gitlens.views.repositories.setShowSectionBranchesOn:executed' | 'command:gitlens.views.repositories.setShowSectionCommitsOff:executed' | 'command:gitlens.views.repositories.setShowSectionCommitsOn:executed' | 'command:gitlens.views.repositories.setShowSectionContributorsOff:executed' | 'command:gitlens.views.repositories.setShowSectionContributorsOn:executed' | 'command:gitlens.views.repositories.setShowSectionOff:executed' | 'command:gitlens.views.repositories.setShowSectionRemotesOff:executed' | 'command:gitlens.views.repositories.setShowSectionRemotesOn:executed' | 'command:gitlens.views.repositories.setShowSectionStashesOff:executed' | 'command:gitlens.views.repositories.setShowSectionStashesOn:executed' | 'command:gitlens.views.repositories.setShowSectionTagsOff:executed' | 'command:gitlens.views.repositories.setShowSectionTagsOn:executed' | 'command:gitlens.views.repositories.setShowSectionUpstreamStatusOff:executed' | 'command:gitlens.views.repositories.setShowSectionUpstreamStatusOn:executed' | 'command:gitlens.views.repositories.setShowSectionWorktreesOff:executed' | 'command:gitlens.views.repositories.setShowSectionWorktreesOn:executed' | 'command:gitlens.views.repositories.viewOptionsTitle:executed' | 'command:gitlens.views.resetCommit:executed' | 'command:gitlens.views.resetToCommit:executed' | 'command:gitlens.views.resetToTip:executed' | 'command:gitlens.views.restore:executed' | 'command:gitlens.views.revealRepositoryInExplorer:executed' | 'command:gitlens.views.revealWorktreeInExplorer:executed' | 'command:gitlens.views.revert:executed' | 'command:gitlens.views.scm.grouped.attachAll:executed' | 'command:gitlens.views.scm.grouped.branches:executed' | 'command:gitlens.views.scm.grouped.branches.attach:executed' | 'command:gitlens.views.scm.grouped.branches.detach:executed' | 'command:gitlens.views.scm.grouped.branches.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.branches.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.branches.visibility.show:executed' | 'command:gitlens.views.scm.grouped.commits:executed' | 'command:gitlens.views.scm.grouped.commits.attach:executed' | 'command:gitlens.views.scm.grouped.commits.detach:executed' | 'command:gitlens.views.scm.grouped.commits.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.commits.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.commits.visibility.show:executed' | 'command:gitlens.views.scm.grouped.contributors:executed' | 'command:gitlens.views.scm.grouped.contributors.attach:executed' | 'command:gitlens.views.scm.grouped.contributors.detach:executed' | 'command:gitlens.views.scm.grouped.contributors.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.contributors.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.contributors.visibility.show:executed' | 'command:gitlens.views.scm.grouped.detachAll:executed' | 'command:gitlens.views.scm.grouped.fileHistory:executed' | 'command:gitlens.views.scm.grouped.fileHistory.attach:executed' | 'command:gitlens.views.scm.grouped.fileHistory.detach:executed' | 'command:gitlens.views.scm.grouped.fileHistory.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.fileHistory.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.fileHistory.visibility.show:executed' | 'command:gitlens.views.scm.grouped.launchpad:executed' | 'command:gitlens.views.scm.grouped.launchpad.attach:executed' | 'command:gitlens.views.scm.grouped.launchpad.detach:executed' | 'command:gitlens.views.scm.grouped.launchpad.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.launchpad.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.launchpad.visibility.show:executed' | 'command:gitlens.views.scm.grouped.refresh:executed' | 'command:gitlens.views.scm.grouped.remotes:executed' | 'command:gitlens.views.scm.grouped.remotes.attach:executed' | 'command:gitlens.views.scm.grouped.remotes.detach:executed' | 'command:gitlens.views.scm.grouped.remotes.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.remotes.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.remotes.visibility.show:executed' | 'command:gitlens.views.scm.grouped.repositories:executed' | 'command:gitlens.views.scm.grouped.repositories.attach:executed' | 'command:gitlens.views.scm.grouped.repositories.detach:executed' | 'command:gitlens.views.scm.grouped.repositories.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.repositories.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.repositories.visibility.show:executed' | 'command:gitlens.views.scm.grouped.resetAll:executed' | 'command:gitlens.views.scm.grouped.searchAndCompare:executed' | 'command:gitlens.views.scm.grouped.searchAndCompare.attach:executed' | 'command:gitlens.views.scm.grouped.searchAndCompare.detach:executed' | 'command:gitlens.views.scm.grouped.searchAndCompare.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.searchAndCompare.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.searchAndCompare.visibility.show:executed' | 'command:gitlens.views.scm.grouped.stashes:executed' | 'command:gitlens.views.scm.grouped.stashes.attach:executed' | 'command:gitlens.views.scm.grouped.stashes.detach:executed' | 'command:gitlens.views.scm.grouped.stashes.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.stashes.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.stashes.visibility.show:executed' | 'command:gitlens.views.scm.grouped.tags:executed' | 'command:gitlens.views.scm.grouped.tags.attach:executed' | 'command:gitlens.views.scm.grouped.tags.detach:executed' | 'command:gitlens.views.scm.grouped.tags.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.tags.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.tags.visibility.show:executed' | 'command:gitlens.views.scm.grouped.worktrees:executed' | 'command:gitlens.views.scm.grouped.worktrees.attach:executed' | 'command:gitlens.views.scm.grouped.worktrees.detach:executed' | 'command:gitlens.views.scm.grouped.worktrees.setAsDefault:executed' | 'command:gitlens.views.scm.grouped.worktrees.visibility.hide:executed' | 'command:gitlens.views.scm.grouped.worktrees.visibility.show:executed' | 'command:gitlens.views.searchAndCompare.attach:executed' | 'command:gitlens.views.searchAndCompare.clear:executed' | 'command:gitlens.views.searchAndCompare.copy:executed' | 'command:gitlens.views.searchAndCompare.refresh:executed' | 'command:gitlens.views.searchAndCompare.searchCommits:executed' | 'command:gitlens.views.searchAndCompare.selectForCompare:executed' | 'command:gitlens.views.searchAndCompare.setFilesLayoutToAuto:executed' | 'command:gitlens.views.searchAndCompare.setFilesLayoutToList:executed' | 'command:gitlens.views.searchAndCompare.setFilesLayoutToTree:executed' | 'command:gitlens.views.searchAndCompare.setShowAvatarsOff:executed' | 'command:gitlens.views.searchAndCompare.setShowAvatarsOn:executed' | 'command:gitlens.views.searchAndCompare.swapComparison:executed' | 'command:gitlens.views.searchAndCompare.viewOptionsTitle:executed' | 'command:gitlens.views.selectFileForCompare:executed' | 'command:gitlens.views.selectForCompare:executed' | 'command:gitlens.views.setAsDefault:executed' | 'command:gitlens.views.setBranchComparisonToBranch:executed' | 'command:gitlens.views.setBranchComparisonToWorking:executed' | 'command:gitlens.views.setContributorsStatisticsOff:executed' | 'command:gitlens.views.setContributorsStatisticsOn:executed' | 'command:gitlens.views.setResultsCommitsFilterAuthors:executed' | 'command:gitlens.views.setResultsCommitsFilterOff:executed' | 'command:gitlens.views.setResultsFilesFilterOff:executed' | 'command:gitlens.views.setResultsFilesFilterOnLeft:executed' | 'command:gitlens.views.setResultsFilesFilterOnRight:executed' | 'command:gitlens.views.setShowRelativeDateMarkersOff:executed' | 'command:gitlens.views.setShowRelativeDateMarkersOn:executed' | 'command:gitlens.views.skipPausedOperation:executed' | 'command:gitlens.views.stageDirectory:executed' | 'command:gitlens.views.stageFile:executed' | 'command:gitlens.views.stashes.attach:executed' | 'command:gitlens.views.stashes.copy:executed' | 'command:gitlens.views.stashes.refresh:executed' | 'command:gitlens.views.stashes.setFilesLayoutToAuto:executed' | 'command:gitlens.views.stashes.setFilesLayoutToList:executed' | 'command:gitlens.views.stashes.setFilesLayoutToTree:executed' | 'command:gitlens.views.stashes.viewOptionsTitle:executed' | 'command:gitlens.views.switchToAnotherBranch:executed' | 'command:gitlens.views.switchToBranch:executed' | 'command:gitlens.views.switchToCommit:executed' | 'command:gitlens.views.switchToTag:executed' | 'command:gitlens.views.tags.attach:executed' | 'command:gitlens.views.tags.copy:executed' | 'command:gitlens.views.tags.refresh:executed' | 'command:gitlens.views.tags.setFilesLayoutToAuto:executed' | 'command:gitlens.views.tags.setFilesLayoutToList:executed' | 'command:gitlens.views.tags.setFilesLayoutToTree:executed' | 'command:gitlens.views.tags.setLayoutToList:executed' | 'command:gitlens.views.tags.setLayoutToTree:executed' | 'command:gitlens.views.tags.setShowAvatarsOff:executed' | 'command:gitlens.views.tags.setShowAvatarsOn:executed' | 'command:gitlens.views.tags.viewOptionsTitle:executed' | 'command:gitlens.views.timeline.refresh:executed' | 'command:gitlens.views.title.createBranch:executed' | 'command:gitlens.views.title.createTag:executed' | 'command:gitlens.views.title.createWorktree:executed' | 'command:gitlens.views.undoCommit:executed' | 'command:gitlens.views.unsetAsDefault:executed' | 'command:gitlens.views.unstageDirectory:executed' | 'command:gitlens.views.unstageFile:executed' | 'command:gitlens.views.workspaces.addRepos:executed' | 'command:gitlens.views.workspaces.addReposFromLinked:executed' | 'command:gitlens.views.workspaces.changeAutoAddSetting:executed' | 'command:gitlens.views.workspaces.convert:executed' | 'command:gitlens.views.workspaces.copy:executed' | 'command:gitlens.views.workspaces.createLocal:executed' | 'command:gitlens.views.workspaces.delete:executed' | 'command:gitlens.views.workspaces.info:executed' | 'command:gitlens.views.workspaces.locateAllRepos:executed' | 'command:gitlens.views.workspaces.openLocal:executed' | 'command:gitlens.views.workspaces.openLocalNewWindow:executed' | 'command:gitlens.views.workspaces.refresh:executed' | 'command:gitlens.views.workspaces.repo.addToWindow:executed' | 'command:gitlens.views.workspaces.repo.locate:executed' | 'command:gitlens.views.workspaces.repo.open:executed' | 'command:gitlens.views.workspaces.repo.openInNewWindow:executed' | 'command:gitlens.views.workspaces.repo.remove:executed' | 'command:gitlens.views.worktrees.attach:executed' | 'command:gitlens.views.worktrees.copy:executed' | 'command:gitlens.views.worktrees.refresh:executed' | 'command:gitlens.views.worktrees.setFilesLayoutToAuto:executed' | 'command:gitlens.views.worktrees.setFilesLayoutToList:executed' | 'command:gitlens.views.worktrees.setFilesLayoutToTree:executed' | 'command:gitlens.views.worktrees.setLayoutToList:executed' | 'command:gitlens.views.worktrees.setLayoutToTree:executed' | 'command:gitlens.views.worktrees.setShowAvatarsOff:executed' | 'command:gitlens.views.worktrees.setShowAvatarsOn:executed' | 'command:gitlens.views.worktrees.setShowBranchComparisonOff:executed' | 'command:gitlens.views.worktrees.setShowBranchComparisonOn:executed' | 'command:gitlens.views.worktrees.setShowBranchPullRequestOff:executed' | 'command:gitlens.views.worktrees.setShowBranchPullRequestOn:executed' | 'command:gitlens.views.worktrees.setShowStashesOff:executed' | 'command:gitlens.views.worktrees.setShowStashesOn:executed' | 'command:gitlens.views.worktrees.viewOptionsTitle:executed' | 'command:gitlens.visualizeHistory.file:editor:executed' | 'command:gitlens.visualizeHistory.file:explorer:executed' | 'command:gitlens.visualizeHistory.file:scm:executed' | 'command:gitlens.visualizeHistory.file:views:executed' | 'command:gitlens.visualizeHistory.folder:explorer:executed' | 'command:gitlens.visualizeHistory.folder:scm:executed' | `command:gitlens.action.${string}:executed` | 'command:gitlens.diffWith:executed' | 'command:gitlens.ai.explainCommit:editor:executed' | 'command:gitlens.ai.explainWip:editor:executed' | 'command:gitlens.openOnRemote:executed' | 'command:gitlens.openWalkthrough:executed' | 'command:gitlens.refreshHover:executed' | 'command:gitlens.visualizeHistory:executed' | 'command:gitlens.graph.abortPausedOperation:executed' | 'command:gitlens.graph.continuePausedOperation:executed' | 'command:gitlens.graph.openRebaseEditor:executed' | 'command:gitlens.graph.skipPausedOperation:executed' | 'command:gitlens.visualizeHistory.repo:graph:executed' | 'command:gitlens.ai.explainWip:home:executed' | 'command:gitlens.ai.explainBranch:home:executed' | 'command:gitlens.ai.generateCommits:home:executed' | 'command:gitlens.home.changeBranchMergeTarget:executed' | 'command:gitlens.home.deleteBranchOrWorktree:executed' | 'command:gitlens.home.pushBranch:executed' | 'command:gitlens.home.openMergeTargetComparison:executed' | 'command:gitlens.home.openPullRequestChanges:executed' | 'command:gitlens.home.openPullRequestComparison:executed' | 'command:gitlens.home.openPullRequestOnRemote:executed' | 'command:gitlens.home.openPullRequestDetails:executed' | 'command:gitlens.home.createPullRequest:executed' | 'command:gitlens.home.openWorktree:executed' | 'command:gitlens.home.switchToBranch:executed' | 'command:gitlens.home.fetch:executed' | 'command:gitlens.home.openInGraph:executed' | 'command:gitlens.openInView.branch:home:executed' | 'command:gitlens.home.createBranch:executed' | 'command:gitlens.home.mergeIntoCurrent:executed' | 'command:gitlens.home.rebaseCurrentOnto:executed' | 'command:gitlens.home.startWork:executed' | 'command:gitlens.home.createCloudPatch:executed' | 'command:gitlens.home.skipPausedOperation:executed' | 'command:gitlens.home.continuePausedOperation:executed' | 'command:gitlens.home.abortPausedOperation:executed' | 'command:gitlens.home.openRebaseEditor:executed' | 'command:gitlens.home.enableAi:executed' | 'command:gitlens.visualizeHistory.repo:home:executed' | 'command:gitlens.visualizeHistory.branch:home:executed' | 'command:gitlens.views.home.account.resync:executed' | 'command:gitlens.views.home.ai.allAccess.dismiss:executed' | 'command:gitlens.views.home.publishBranch:executed' | 'command:gitlens.views.home.pull:executed' | 'command:gitlens.views.home.push:executed' | 'command:gitlens.launchpad.indicator.action:executed' | 'command:gitlens.plus.aiAllAccess.optIn:executed' | 'command:gitlens.plus.continueFeaturePreview:executed' | 'command:gitlens.plus.resendVerification:executed' | 'command:gitlens.plus.showPlans:executed' | 'command:gitlens.plus.validate:executed' | 'command:gitlens.views.scm.grouped.welcome.dismiss:executed' | 'command:gitlens.views.scm.grouped.welcome.restore:executed' | 'command:gitlens.views.searchAndCompare.compareWithSelected:executed' | 'command:gitlens.views.timeline.openInTab:executed' | 'command:gitlens.walkthrough.connectIntegrations:executed' | 'command:gitlens.walkthrough.enableAiSetting:executed' | 'command:gitlens.walkthrough.gitlensInspect:executed' | 'command:gitlens.walkthrough.openAcceleratePrReviews:executed' | 'command:gitlens.walkthrough.openAiCustomInstructionsSettings:executed' | 'command:gitlens.walkthrough.openAiSettings:executed' | 'command:gitlens.walkthrough.openCommunityVsPro:executed' | 'command:gitlens.walkthrough.openHelpCenter:executed' | 'command:gitlens.walkthrough.openHomeViewVideo:executed' | 'command:gitlens.walkthrough.openInteractiveCodeHistory:executed' | 'command:gitlens.walkthrough.openLearnAboutAiFeatures:executed' | 'command:gitlens.walkthrough.openStartIntegrations:executed' | 'command:gitlens.walkthrough.openStreamlineCollaboration:executed' | 'command:gitlens.walkthrough.openWalkthrough:executed' | 'command:gitlens.walkthrough.plus.signUp:executed' | 'command:gitlens.walkthrough.plus.upgrade:executed' | 'command:gitlens.walkthrough.plus.reactivate:executed' | 'command:gitlens.walkthrough.showAutolinks:executed' | 'command:gitlens.walkthrough.showDraftsView:executed' | 'command:gitlens.walkthrough.showGraph:executed' | 'command:gitlens.walkthrough.showHomeView:executed' | 'command:gitlens.walkthrough.showLaunchpad:executed' | 'command:gitlens.walkthrough.switchAIProvider:executed' | 'command:gitlens.walkthrough.worktree.create:executed' | 'command:gitlens.walkthrough.openDevExPlatform:executed' | 'command:gitlens.generateCommitMessage:executed' | 'command:gitlens.scm.generateCommitMessage:executed' | 'command:gitlens.scm.ai.generateCommitMessage:executed' | 'command:gitlens.switchAIModel:executed' | 'command:gitlens.diffHeadWith:executed' | 'command:gitlens.diffWorkingWith:executed' | 'command:gitlens.openBranchesInRemote:executed' | 'command:gitlens.openBranchInRemote:executed' | 'command:gitlens.openCommitInRemote:executed' | 'command:gitlens.openFileInRemote:executed' | 'command:gitlens.openInRemote:executed' | 'command:gitlens.openRepoInRemote:executed' | 'command:gitlens.showFileHistoryInView:executed' | 'home:walkthrough:dismissed' } ```