diff --git a/docs/telemetry-events.md b/docs/telemetry-events.md index fa32ef07b4094..33a33077d6824 100644 --- a/docs/telemetry-events.md +++ b/docs/telemetry-events.md @@ -372,6 +372,30 @@ or } ``` +### aiAllAccess/bannerDismissed + +> Sent when user dismisses the AI All Access banner + +```typescript +void +``` + +### aiAllAccess/opened + +> Sent when user opens the AI All Access page + +```typescript +void +``` + +### aiAllAccess/optedIn + +> Sent when user opts in to AI All Access + +```typescript +void +``` + ### associateIssueWithBranch/action > Sent when the user chooses to manage integrations @@ -2232,7 +2256,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' | 'commitsView:shown' | 'stashesView:shown' | 'tagsView:shown' | 'launchpadView:shown' | 'worktreesView:shown' | 'branchesView:shown' | 'contributorsView:shown' | 'draftsView:shown' | 'fileHistoryView:shown' | 'scm.groupedView:shown' | 'lineHistoryView:shown' | 'pullRequestView: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.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.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.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.star:executed' | 'command:gitlens.views.star.multi: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.unstar:executed' | 'command:gitlens.views.unstar.multi: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.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.publishBranch:executed' | 'command:gitlens.views.home.pull:executed' | 'command:gitlens.views.home.push:executed' | 'command:gitlens.launchpad.indicator.action: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' | 'commitsView:shown' | 'stashesView:shown' | 'tagsView:shown' | 'launchpadView:shown' | 'worktreesView:shown' | 'branchesView:shown' | 'contributorsView:shown' | 'draftsView:shown' | 'fileHistoryView:shown' | 'scm.groupedView:shown' | 'lineHistoryView:shown' | 'pullRequestView: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.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.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.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.star:executed' | 'command:gitlens.views.star.multi: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.unstar:executed' | 'command:gitlens.views.unstar.multi: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.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' } ``` diff --git a/src/commands/resets.ts b/src/commands/resets.ts index 53cab45215a90..f72e6b1f9f4a2 100644 --- a/src/commands/resets.ts +++ b/src/commands/resets.ts @@ -12,8 +12,10 @@ const resetTypes = [ 'ai', 'ai:confirmations', 'avatars', + 'homeSections', 'integrations', 'previews', + 'promoOptIns', 'repositoryAccess', 'subscription', 'suppressedWarnings', @@ -46,6 +48,11 @@ export class ResetCommand extends GlCommandBase { detail: 'Clears the stored avatar cache', item: 'avatars', }, + { + label: 'Home Sections...', + detail: 'Clears dismissed home view banners and sections', + item: 'homeSections', + }, { label: 'Integrations (Authentication)...', detail: 'Clears any locally stored authentication for integrations', @@ -93,6 +100,11 @@ export class ResetCommand extends GlCommandBase { detail: 'Resets the stored state for feature previews', item: 'previews', }, + { + label: 'Promo Opt-Ins...', + detail: 'Clears any locally stored promo opt-ins', + item: 'promoOptIns' + }, ); } @@ -133,6 +145,10 @@ export class ResetCommand extends GlCommandBase { confirmationMessage = 'Are you sure you want to reset the stored state for feature previews?'; confirm.title = 'Reset Feature Previews'; break; + case 'promoOptIns': + confirmationMessage = 'Are you sure you want to reset all of the locally stored promo opt-ins?'; + confirm.title = 'Reset Promo Opt-Ins'; + break; case 'repositoryAccess': confirmationMessage = 'Are you sure you want to reset the repository access cache?'; confirm.title = 'Reset Repository Access'; @@ -190,10 +206,19 @@ export class ResetCommand extends GlCommandBase { resetAvatarCache('all'); break; + case 'homeSections': + await this.container.storage.delete('home:sections:collapsed'); + await this.container.storage.delete('home:walkthrough:dismissed'); + break; + case 'integrations': await this.container.integrations.reset(); break; + case 'promoOptIns': + await this.container.storage.deleteWithPrefix('gk:promo'); + break; + case 'repositoryAccess': await this.container.git.clearAllRepoVisibilityCaches(); break; diff --git a/src/constants.commands.ts b/src/constants.commands.ts index bc1a12a330c20..9b3445093656f 100644 --- a/src/constants.commands.ts +++ b/src/constants.commands.ts @@ -69,6 +69,7 @@ type InternalHomeWebviewCommands = type InternalHomeWebviewViewCommands = | 'gitlens.views.home.account.resync' + | 'gitlens.views.home.ai.allAccess.dismiss' | 'gitlens.views.home.publishBranch' | 'gitlens.views.home.pull' | 'gitlens.views.home.push'; @@ -76,6 +77,7 @@ type InternalHomeWebviewViewCommands = type InternalLaunchPadCommands = 'gitlens.launchpad.indicator.action'; type InternalPlusCommands = + | 'gitlens.plus.aiAllAccess.optIn' | 'gitlens.plus.continueFeaturePreview' | 'gitlens.plus.resendVerification' | 'gitlens.plus.showPlans' diff --git a/src/constants.storage.ts b/src/constants.storage.ts index de66b1eb8a094..66d5a647ab089 100644 --- a/src/constants.storage.ts +++ b/src/constants.storage.ts @@ -96,6 +96,10 @@ export type GlobalStorage = { >; } & { [key in `provider:authentication:skip:${string}`]: boolean; +} & { + [key in `gk:promo:${string}:ai:allAccess:dismissed`]: boolean; +} & { + [key in `gk:promo:${string}:ai:allAccess:notified`]: boolean; } & { [key in `gk:${string}:checkin`]: Stored } & { [key in `gk:${string}:organizations`]: Stored; } & { [key in `jira:${string}:organizations`]: Stored } & { diff --git a/src/constants.telemetry.ts b/src/constants.telemetry.ts index 0c3ead5b0ae19..c0b72b531aa8c 100644 --- a/src/constants.telemetry.ts +++ b/src/constants.telemetry.ts @@ -66,6 +66,15 @@ export interface TelemetryEvents extends WebviewShowAbortedEvents, WebviewShownE /** Sent when switching ai models */ 'ai/switchModel': AISwitchModelEvent; + /** Sent when user dismisses the AI All Access banner */ + 'aiAllAccess/bannerDismissed': void; + + /** Sent when user opens the AI All Access page */ + 'aiAllAccess/opened': void; + + /** Sent when user opts in to AI All Access */ + 'aiAllAccess/optedIn': void; + /** Sent when connecting to one or more cloud-based integrations */ 'cloudIntegrations/connecting': CloudIntegrationsConnectingEvent; diff --git a/src/plus/ai/aiProviderService.ts b/src/plus/ai/aiProviderService.ts index ed78413d0deec..5b82dab9192dd 100644 --- a/src/plus/ai/aiProviderService.ts +++ b/src/plus/ai/aiProviderService.ts @@ -50,7 +50,9 @@ import { getSettledValue, getSettledValues } from '../../system/promise'; import { PromiseCache } from '../../system/promiseCache'; import type { ServerConnection } from '../gk/serverConnection'; import { ensureFeatureAccess } from '../gk/utils/-webview/acount.utils'; +import { isAiAllAccessPromotionActive } from '../gk/utils/-webview/promo.utils'; import { compareSubscriptionPlans, getSubscriptionPlanName, isSubscriptionPaid } from '../gk/utils/subscription.utils'; +import { GitKrakenProvider } from './gitkrakenProvider'; import type { AIActionType, AIModel, @@ -1149,6 +1151,11 @@ export class AIProviderService implements Disposable { } const cancellation = cancellationSource.token; + const isGkModel = model.provider.id === 'gitkraken'; + if (isGkModel) { + await this.showAiAllAccessNotificationIfNeeded(true); + } + const confirmed = await showConfirmAIProviderToS(this.container.storage); if (!confirmed || cancellation.isCancellationRequested) { this.container.telemetry.sendEvent( @@ -1226,6 +1233,10 @@ export class AIProviderService implements Disposable { source, ); + if (!isGkModel) { + void this.showAiAllAccessNotificationIfNeeded(); + } + return result; } catch (ex) { if (ex instanceof CancellationError) { @@ -1584,8 +1595,69 @@ export class AIProviderService implements Disposable { switchModel(source?: Source): Promise { return this.getModel({ force: true }, source); } + + private async showAiAllAccessNotificationIfNeeded(usingGkProvider?: boolean): Promise { + // Only show during the AI All Access promotion period + if (!isAiAllAccessPromotionActive()) return; + + // Get current subscription to determine user ID + const subscription = await this.container.subscription.getSubscription(true); + const userId = subscription?.account?.id ?? '00000000'; + + // Check if notification has already been shown or if user already completed opt-in + const notificationShown = this.container.storage.get(`gk:promo:${userId}:ai:allAccess:notified`, false); + const alreadyCompleted = this.container.storage.get(`gk:promo:${userId}:ai:allAccess:dismissed`, false); + if (notificationShown || alreadyCompleted) return; + + const hasAdvancedOrHigher = subscription.plan && + (compareSubscriptionPlans(subscription.plan.actual.id, 'advanced') >= 0 || + compareSubscriptionPlans(subscription.plan.effective.id, 'advanced') >= 0); + + let body = 'All Access Week - now until July 11th!'; + const detail = hasAdvancedOrHigher ? 'Opt in now to get unlimited GitKraken AI until July 11th!' : 'Opt in now to try all Advanced GitLens features with unlimited GitKraken AI for FREE until July 11th!'; + + if (!usingGkProvider) { + body += ` ${detail}`; + } + + const optInButton: MessageItem = usingGkProvider ? { title: 'Opt in for Unlimited AI' } : { title: 'Opt in and Switch to GitKraken AI' }; + const dismissButton: MessageItem = { title: 'No, Thanks', isCloseAffordance: true }; + + // Show the notification + const result = await window.showInformationMessage(body, { modal: usingGkProvider, detail: detail }, optInButton, dismissButton); + + // Mark notification as shown regardless of user action + void this.container.storage.store(`gk:promo:${userId}:ai:allAccess:notified`, true); + + // If user clicked the button, trigger the opt-in command + if (result === optInButton) { + void this.allAccessOptIn(usingGkProvider); + } + } + + private async allAccessOptIn(usingGkProvider?: boolean): Promise { + const optIn = await this.container.subscription.aiAllAccessOptIn({ source: 'notification' }); + if (optIn && !usingGkProvider && isProviderEnabledByOrg('gitkraken')) { + const gkProvider = new GitKrakenProvider(this.container, this.connection); + const defaultModel = (await gkProvider.getModels()).find(m => m.default); + if (defaultModel != null) { + this._provider = gkProvider; + this._model = defaultModel; + if (isPrimaryAIProviderModel(defaultModel)) { + await configuration.updateEffective('ai.model', 'gitkraken'); + await configuration.updateEffective(`ai.gitkraken.model`, defaultModel.id); + } else { + await configuration.updateEffective('ai.model', `gitkraken:${defaultModel.id}` as SupportedAIModels); + } + + this._onDidChangeModel.fire({ model: defaultModel }); + } + } + } } + + async function showConfirmAIProviderToS(storage: Storage): Promise { const confirmed = storage.get(`confirm:ai:tos`, false) || storage.getWorkspace(`confirm:ai:tos`, false); if (confirmed) return true; diff --git a/src/plus/gk/subscriptionService.ts b/src/plus/gk/subscriptionService.ts index 8b0ec7003d2d2..999f22ca7fa21 100644 --- a/src/plus/gk/subscriptionService.ts +++ b/src/plus/gk/subscriptionService.ts @@ -74,6 +74,7 @@ import { ensurePlusFeaturesEnabled } from './utils/-webview/plus.utils'; import { getConfiguredActiveOrganizationId, updateActiveOrganizationId } from './utils/-webview/subscription.utils'; import { getSubscriptionFromCheckIn } from './utils/checkin.utils'; import { + AiAllAccessOptInPathPrefix, assertSubscriptionState, compareSubscriptionPlans, computeSubscriptionState, @@ -140,6 +141,7 @@ export class SubscriptionService implements Disposable { } }), container.uri.onDidReceiveSubscriptionUpdatedUri(() => this.checkUpdatedSubscription(undefined), this), + container.uri.onDidReceiveAiAllAccessOptInUri(this.onAiAllAccessOptInUri, this), container.uri.onDidReceiveLoginUri(this.onLoginUri, this), ); @@ -348,6 +350,7 @@ export class SubscriptionService implements Disposable { registerCommand('gitlens.plus.upgrade', (args?: SubscriptionUpgradeCommandArgs) => this.upgrade(args?.plan, args ? { source: args.source, detail: args.detail } : undefined), ), + registerCommand('gitlens.plus.aiAllAccess.optIn', (src?: Source) => this.aiAllAccessOptIn(src)), registerCommand('gitlens.plus.hide', (src?: Source) => this.setProFeaturesVisibility(false, src)), registerCommand('gitlens.plus.restore', (src?: Source) => this.setProFeaturesVisibility(true, src)), @@ -1663,6 +1666,88 @@ export class SubscriptionService implements Disposable { return this._subscription.state; } + + @log() + async aiAllAccessOptIn(source: Source | undefined): Promise { + const scope = getLogScope(); + + if (!(await ensurePlusFeaturesEnabled())) return false; + + const hasAccount = this._session != null; + + const query = new URLSearchParams(); + query.set('source', 'gitlens'); + query.set('product', 'gitlens'); + + try { + if (hasAccount) { + try { + const token = await this.container.accountAuthentication.getExchangeToken( + AiAllAccessOptInPathPrefix, + ); + query.set('token', token); + } catch (ex) { + Logger.error(ex, scope); + } + } else { + const callbackUri = await env.asExternalUri( + Uri.parse(`${env.uriScheme}://${this.container.context.extension.id}/${AiAllAccessOptInPathPrefix}`), + ); + query.set('redirect_uri', callbackUri.toString(true)); + } + + if (this.container.telemetry.enabled) { + this.container.telemetry.sendEvent('aiAllAccess/opened', undefined, source); + } + + if(!(await openUrl(this.container.urls.getGkDevUrl('all-access', query)))) { + return false; + } + } catch (ex) { + Logger.error(ex, scope); + return false; + } + + const completionPromises = [ + new Promise(resolve => setTimeout(() => resolve('cancel'), 5 * 60 * 1000)), + new Promise(resolve => once(this.container.uri.onDidReceiveAiAllAccessOptInUri)(() => resolve(hasAccount ? 'update' : 'login'))), + ]; + + const action = await Promise.race(completionPromises); + + if (action === 'update' && hasAccount) { + void this.checkUpdatedSubscription(source); + void this.container.storage.store(`gk:promo:${this._session?.account.id ?? '00000000'}:ai:allAccess:dismissed`, true).catch(); + void this.container.views.home.refresh(); + } + + if (action !== 'cancel') { + if (this.container.telemetry.enabled) { + this.container.telemetry.sendEvent('aiAllAccess/optedIn', undefined, source); + } + + return true; + } + + return false; + } + + private async onAiAllAccessOptInUri(uri: Uri): Promise { + const queryParams = new URLSearchParams(uri.query); + const code = queryParams.get('code'); + + if (code == null) return; + + // If we don't have an account and received a code, login with the code + if (this._session == null) { + await this.loginWithCode({ code: code }, { source: 'subscription' }); + const newSession = await this.getAuthenticationSession(); + if (newSession?.account?.id != null) { + await this.container.storage.store(`gk:promo:${newSession.account.id}:ai:allAccess:dismissed`, true).catch(); + void this.container.views.home.refresh(); + } + } + } } function flattenFeaturePreview(preview: FeaturePreview): FeaturePreviewEventData { diff --git a/src/plus/gk/utils/-webview/promo.utils.ts b/src/plus/gk/utils/-webview/promo.utils.ts new file mode 100644 index 0000000000000..bb706760fdcaa --- /dev/null +++ b/src/plus/gk/utils/-webview/promo.utils.ts @@ -0,0 +1,8 @@ +export function isAiAllAccessPromotionActive(): boolean { + // AI All Access promotion runs from July 8th through July 12th, 2025 + const now = Date.now(); + const startDate = new Date('2025-07-07T23:59:59-00:00').getTime(); // July 8th, 2025 UTC + const endDate = new Date('2025-07-12T10:00:00-00:00').getTime(); // July 12th, 2025 UTC + + return now >= startDate && now <= endDate; +} diff --git a/src/plus/gk/utils/subscription.utils.ts b/src/plus/gk/utils/subscription.utils.ts index 08993c39aacb3..c9f42ac99411f 100644 --- a/src/plus/gk/utils/subscription.utils.ts +++ b/src/plus/gk/utils/subscription.utils.ts @@ -18,6 +18,7 @@ const orderedPlans: SubscriptionPlanIds[] = [ ]; const orderedPaidPlans: PaidSubscriptionPlanIds[] = ['pro', 'advanced', 'teams', 'enterprise']; export const SubscriptionUpdatedUriPathPrefix = 'did-update-subscription'; +export const AiAllAccessOptInPathPrefix = 'ai-all-access-opt-in'; export function compareSubscriptionPlans( planA: SubscriptionPlanIds | undefined, diff --git a/src/uris/uriService.ts b/src/uris/uriService.ts index 0fb47f479c33f..8092d972e87d5 100644 --- a/src/uris/uriService.ts +++ b/src/uris/uriService.ts @@ -2,7 +2,7 @@ import type { Event, Uri, UriHandler } from 'vscode'; import { Disposable, EventEmitter, window } from 'vscode'; import type { Container } from '../container'; import { AuthenticationUriPathPrefix, LoginUriPathPrefix } from '../plus/gk/authenticationConnection'; -import { SubscriptionUpdatedUriPathPrefix } from '../plus/gk/utils/subscription.utils'; +import { AiAllAccessOptInPathPrefix, SubscriptionUpdatedUriPathPrefix } from '../plus/gk/utils/subscription.utils'; import { CloudIntegrationAuthenticationUriPathPrefix } from '../plus/integrations/authentication/models'; import { log } from '../system/decorators/log'; @@ -30,6 +30,11 @@ export class UriService implements Disposable, UriHandler { return this._onDidReceiveSubscriptionUpdatedUri.event; } + private _onDidReceiveAiAllAccessOptInUri: EventEmitter = new EventEmitter(); + get onDidReceiveAiAllAccessOptInUri(): Event { + return this._onDidReceiveAiAllAccessOptInUri.event; + } + private _onDidReceiveUri: EventEmitter = new EventEmitter(); get onDidReceiveUri(): Event { return this._onDidReceiveUri.event; @@ -43,6 +48,7 @@ export class UriService implements Disposable, UriHandler { this._onDidReceiveCloudIntegrationAuthenticationUri, this._onDidReceiveLoginUri, this._onDidReceiveSubscriptionUpdatedUri, + this._onDidReceiveAiAllAccessOptInUri, this._onDidReceiveUri, window.registerUriHandler(this), ); @@ -64,6 +70,9 @@ export class UriService implements Disposable, UriHandler { } else if (type === SubscriptionUpdatedUriPathPrefix) { this._onDidReceiveSubscriptionUpdatedUri.fire(uri); return; + } else if (type === AiAllAccessOptInPathPrefix) { + this._onDidReceiveAiAllAccessOptInUri.fire(uri); + return; } else if (type === LoginUriPathPrefix) { this._onDidReceiveLoginUri.fire(uri); return; diff --git a/src/webviews/apps/home/components/ai-all-access-banner.ts b/src/webviews/apps/home/components/ai-all-access-banner.ts new file mode 100644 index 0000000000000..22dcb01daceb5 --- /dev/null +++ b/src/webviews/apps/home/components/ai-all-access-banner.ts @@ -0,0 +1,84 @@ +import { consume } from '@lit/context'; +import { css, html, LitElement, nothing } from 'lit'; +import { customElement, state } from 'lit/decorators.js'; +import { compareSubscriptionPlans } from '../../../../plus/gk/utils/subscription.utils'; +import { createCommandLink } from '../../../../system/commands'; +import type { State } from '../../../home/protocol'; +import { DismissAiAllAccessBannerCommand } from '../../../home/protocol'; +import { ipcContext } from '../../shared/contexts/ipc'; +import type { HostIpc } from '../../shared/ipc'; +import { stateContext } from '../context'; +import '../../shared/components/banner/banner'; + +export const aiAllAccessBannerTagName = 'gl-ai-all-access-banner'; + +@customElement(aiAllAccessBannerTagName) +export class GlAiAllAccessBanner extends LitElement { + static override shadowRootOptions: ShadowRootInit = { + ...LitElement.shadowRootOptions, + delegatesFocus: true, + }; + + static override styles = [ + css` + :host { + display: block; + } + + gl-banner { + margin-bottom: 1.2rem; + } + `, + ]; + + @consume({ context: stateContext, subscribe: true }) + @state() + private _state!: State; + + @consume({ context: ipcContext, subscribe: true }) + @state() + private _ipc!: HostIpc; + + private get shouldShow(): boolean { + // Don't show if dismissed or closed + return !(this._state.aiAllAccessBannerCollapsed); + } + + private get bodyLabel(): string { + return this.hasAdvancedOrHigher ? 'Opt in now to get unlimited GitKraken AI until July 11th!' : 'Opt in now to try all Advanced GitLens features with unlimited GitKraken AI for FREE until July 11th!'; + + } + + private get primaryButtonLabel(): string { + return 'Opt In Now'; + } + + private get hasAdvancedOrHigher(): boolean { + return this._state.subscription.plan && compareSubscriptionPlans(this._state.subscription.plan.actual.id, 'advanced') >= 0 || compareSubscriptionPlans(this._state.subscription.plan.effective.id, 'advanced') >= 0; + } + + override render(): unknown { + if (!this.shouldShow) { + return nothing; + } + + return html` + + `; + } + + private onSecondaryClick() { + this._ipc.sendCommand(DismissAiAllAccessBannerCommand, undefined); + } +} diff --git a/src/webviews/apps/home/home.ts b/src/webviews/apps/home/home.ts index bfee2fdecfe4c..b9866f2d7dac1 100644 --- a/src/webviews/apps/home/home.ts +++ b/src/webviews/apps/home/home.ts @@ -16,6 +16,7 @@ import type { GlHomeHeader } from '../plus/shared/components/home-header'; import { GlAppHost } from '../shared/appHost'; import { scrollableBase } from '../shared/components/styles/lit/base.css'; import type { HostIpc } from '../shared/ipc'; +import type { GlAiAllAccessBanner } from './components/ai-all-access-banner'; import { homeBaseStyles, homeStyles } from './home.css'; import { HomeStateProvider } from './stateProvider'; import '../plus/shared/components/home-header'; @@ -23,11 +24,13 @@ import '../plus/home/components/active-work'; import '../plus/home/components/launchpad'; import '../plus/home/components/overview'; import './components/feature-nav'; +import './components/ai-all-access-banner'; import './components/ama-banner'; import './components/integration-banner'; import './components/preview-banner'; import './components/promo-banner'; import './components/repo-alerts'; +import '../shared/components/banner/banner'; @customElement('gl-home-app') export class GlHomeApp extends GlAppHost { @@ -42,6 +45,9 @@ export class GlHomeApp extends GlAppHost { @query('gl-home-header') private _header!: GlHomeHeader; + @query('gl-ai-all-access-banner') + private allAccessPromoBanner!: GlAiAllAccessBanner; + private badgeSource = { source: 'home', detail: 'badge' }; protected override createStateProvider(state: State, ipc: HostIpc): HomeStateProvider { @@ -62,6 +68,7 @@ export class GlHomeApp extends GlAppHost { break; case DidChangeSubscription.is(msg): this._header.refreshPromo(); + this.refreshAiAllAccessPromo(); break; } }), @@ -80,14 +87,22 @@ export class GlHomeApp extends GlAppHost { this.state?.previewEnabled === true, () => html` + `, - () => html``, + () => html` + + + `, )} `; } + + refreshAiAllAccessPromo(): void { + this.allAccessPromoBanner?.requestUpdate(); + } } diff --git a/src/webviews/apps/home/stateProvider.ts b/src/webviews/apps/home/stateProvider.ts index 2cd915b994b7a..8af20eb03126a 100644 --- a/src/webviews/apps/home/stateProvider.ts +++ b/src/webviews/apps/home/stateProvider.ts @@ -1,6 +1,7 @@ import { ContextProvider } from '@lit/context'; import type { State } from '../../home/protocol'; import { + DidChangeAiAllAccessBanner, DidChangeIntegrationsConnections, DidChangeOrgSettings, DidChangePreviewEnabled, @@ -82,6 +83,14 @@ export class HomeStateProvider implements StateProvider { this._state.aiEnabled = msg.params.aiEnabled; this._state.timestamp = Date.now(); + this.provider.setValue(this._state, true); + host.requestUpdate(); + break; + + case DidChangeAiAllAccessBanner.is(msg): + this._state.aiAllAccessBannerCollapsed = msg.params; + this._state.timestamp = Date.now(); + this.provider.setValue(this._state, true); host.requestUpdate(); break; diff --git a/src/webviews/apps/shared/components/banner/banner.css.ts b/src/webviews/apps/shared/components/banner/banner.css.ts new file mode 100644 index 0000000000000..c2e8b4c62ff77 --- /dev/null +++ b/src/webviews/apps/shared/components/banner/banner.css.ts @@ -0,0 +1,233 @@ +import { css } from 'lit'; + +export const bannerStyles = css` + :host { + /* Banner color custom properties */ + --gl-banner-primary-background: var(--vscode-sideBar-background); + --gl-banner-secondary-background: var(--vscode-editor-background); + --gl-banner-primary-emphasis-background: var(--vscode-button-background); + --gl-banner-secondary-emphasis-background: var(--vscode-button-secondaryBackground); + --gl-banner-text-color: var(--vscode-foreground); + --gl-banner-dim-text-color: var(--vscode-descriptionForeground); + --gl-banner-transparency: 0.5; + + /* Layout properties */ + --gl-banner-padding: 1.2rem; + --gl-banner-gap: 0.8rem; + --gl-banner-border-radius: 0.4rem; + + /* Button customization - use 8px horizontal padding, keep original vertical padding */ + --gl-banner-button-padding: 0.4rem 0.8rem; + + display: block; + margin-block-end: 1.2rem; + } + + .banner { + display: flex; + flex-direction: column; + padding: var(--gl-banner-padding); + border-radius: var(--gl-banner-border-radius); + position: relative; + overflow: hidden; + } + + /* Solid display mode - same as card background */ + .banner--solid { + background-color: var(--gl-banner-primary-background); + border: 1px solid color-mix(in lab, var(--gl-banner-primary-background) 100%, var(--vscode-foreground) 12%); + } + + /* Outline display mode - emphasis color outline with secondary background */ + .banner--outline { + background-color: var(--gl-banner-secondary-background); + border: 2px solid var(--gl-banner-primary-emphasis-background); + } + + /* Gradient display mode - horizontal gradient from primary to secondary emphasis */ + .banner--gradient { + background: linear-gradient( + to right, + var(--gl-banner-primary-emphasis-background) 0%, + var(--gl-banner-secondary-emphasis-background) 100% + ); + border: 1px solid color-mix(in lab, var(--gl-banner-primary-emphasis-background) 50%, var(--gl-banner-secondary-emphasis-background) 50%); + } + + /* Gradient transparent display mode - same gradient but with transparency */ + .banner--gradient-transparent { + background: linear-gradient( + to right, + color-mix(in lab, var(--gl-banner-primary-emphasis-background) calc(100% * (1 - var(--gl-banner-transparency))), transparent) 0%, + color-mix(in lab, var(--gl-banner-secondary-emphasis-background) calc(100% * (1 - var(--gl-banner-transparency))), transparent) 100% + ); + border: 1px solid color-mix( + in lab, + color-mix(in lab, var(--gl-banner-primary-emphasis-background) 50%, var(--gl-banner-secondary-emphasis-background) 50%) calc(100% * (1 - var(--gl-banner-transparency))), + transparent + ); + } + + .banner__content { + display: flex; + flex-direction: column; + gap: var(--gl-banner-gap); + align-items: center; + text-align: center; + } + + .banner__title { + font-size: 1.2em; + font-weight: bold; + color: var(--gl-banner-text-color); + margin: 0; + } + + .banner__body { + font-size: 1em; + color: var(--gl-banner-text-color); + margin: 0; + line-height: 1.4; + } + + .banner__buttons { + display: grid; + grid-template-columns: 1fr auto 1fr; + gap: 0.8rem; + margin-top: 0.8rem; + align-items: center; + width: 100%; + } + + .banner__button--primary { + grid-column: 2; + justify-self: center; + white-space: nowrap; + --button-background: color-mix(in lab, var(--gl-banner-primary-background) 10%, #fff 20%); + --button-foreground: var(--gl-banner-text-color); + --button-hover-background: color-mix(in lab, var(--gl-banner-primary-background) 20%, #fff 30%); + --button-padding: var(--gl-banner-button-padding); + font-size: 1.2em; + } + + .banner__button--secondary { + grid-column: 3; + justify-self: end; + white-space: nowrap; + --button-background: transparent; + --button-foreground: var(--gl-banner-dim-text-color); + --button-hover-background: color-mix(in lab, var(--gl-banner-dim-text-color) 10%, transparent); + } + + /* When only primary button exists, center it across the full width */ + .banner__buttons:has(.banner__button--primary):not(:has(.banner__button--secondary)) .banner__button--primary { + grid-column: 1 / -1; + justify-self: center; + } + + /* Theme-specific adjustments */ + + /* Light theme: Brighten gradient colors for better contrast with dark text */ + :host-context(.vscode-light), + :host-context(.vscode-high-contrast-light) { + --gl-banner-primary-emphasis-background: color-mix(in lab, var(--vscode-button-background) 40%, #fff 60%); + --gl-banner-secondary-emphasis-background: color-mix(in lab, var(--vscode-button-secondaryBackground) 40%, #fff 60%); + } + + /* Override text color for high contrast light theme specifically */ + :host-context(.vscode-high-contrast-light) { + --gl-banner-text-color: #000; + } + + :host-context(.vscode-dark) .banner__button--primary, + :host-context(.vscode-high-contrast:not(.vscode-high-contrast-light)) .banner__button--primary { + --button-background: color-mix(in lab, var(--gl-banner-primary-background) 10%, #fff 20%); + --button-hover-background: color-mix(in lab, var(--gl-banner-primary-background) 20%, #fff 30%); + --button-foreground: #fff; + } + + :host-context(.vscode-light) .banner__button--primary, + :host-context(.vscode-high-contrast-light) .banner__button--primary { + --button-background: color-mix(in lab, var(--gl-banner-primary-background) 8%, #fff 25%); + --button-hover-background: color-mix(in lab, var(--gl-banner-primary-background) 15%, #fff 35%); + --button-foreground: #000; + } + + /* Make banner text darker in light themes */ + :host-context(.vscode-light) .banner__body, + :host-context(.vscode-high-contrast-light) .banner__body { + color: color-mix(in lab, var(--gl-banner-text-color) 20%, #000 80%); + } + + /* Strong colors for banner title - pure black/white for maximum contrast */ + :host-context(.vscode-light) .banner__title, + :host-context(.vscode-high-contrast-light) .banner__title { + color: #000 !important; + } + + :host-context(.vscode-dark) .banner__title, + :host-context(.vscode-high-contrast:not(.vscode-high-contrast-light)) .banner__title { + color: #fff !important; + } + + /* Responsive adjustments */ + @media (max-width: 640px) { + .banner__buttons { + flex-direction: column; + width: 100%; + } + + .banner__button { + width: 100%; + } + } + + /* More aggressive responsive layout for narrow sidebars */ + @media (max-width: 400px) { + .banner__buttons { + display: flex; + flex-direction: column; + gap: 0.6rem; + margin-top: 0.8rem; + align-items: center; + width: 100%; + } + + .banner__button--primary, + .banner__button--secondary { + grid-column: unset; + justify-self: unset; + width: 100%; + max-width: 200px; + } + + .banner__button--primary { + order: 1; + } + + .banner__button--secondary { + order: 2; + } + } + + /* Support for custom banner buttons layout */ + :host([data-banner-buttons-layout='column']) .banner__buttons, + .banner__buttons[data-layout='column'] { + display: flex; + flex-direction: column; + gap: 0.6rem; + margin-top: 0.8rem; + align-items: center; + width: 100%; + } + + :host([data-banner-buttons-layout='column']) .banner__button--primary, + :host([data-banner-buttons-layout='column']) .banner__button--secondary, + .banner__buttons[data-layout='column'] .banner__button--primary, + .banner__buttons[data-layout='column'] .banner__button--secondary { + grid-column: unset; + justify-self: unset; + width: 100%; + max-width: 200px; + } +`; diff --git a/src/webviews/apps/shared/components/banner/banner.ts b/src/webviews/apps/shared/components/banner/banner.ts new file mode 100644 index 0000000000000..d03d564250218 --- /dev/null +++ b/src/webviews/apps/shared/components/banner/banner.ts @@ -0,0 +1,152 @@ +import { html, LitElement } from 'lit'; +import { customElement, property } from 'lit/decorators.js'; +import { classMap } from 'lit/directives/class-map.js'; +import { ifDefined } from 'lit/directives/if-defined.js'; +import { bannerStyles } from './banner.css'; +import '../button'; + +export const bannerTagName = 'gl-banner'; + +export type BannerDisplay = 'solid' | 'outline' | 'gradient' | 'gradient-transparent'; + +@customElement(bannerTagName) +export class GlBanner extends LitElement { + static override shadowRootOptions: ShadowRootInit = { + ...LitElement.shadowRootOptions, + delegatesFocus: true, + }; + + static override styles = [bannerStyles]; + + @property({ reflect: true }) + display: BannerDisplay = 'solid'; + + @property({ attribute: 'banner-title' }) + bannerTitle?: string; + + @property() + body?: string; + + @property({ attribute: 'primary-button' }) + primaryButton?: string; + + @property({ attribute: 'primary-button-href' }) + primaryButtonHref?: string; + + @property({ attribute: 'primary-button-command' }) + primaryButtonCommand?: string; + + @property({ attribute: 'secondary-button' }) + secondaryButton?: string; + + @property({ attribute: 'secondary-button-href' }) + secondaryButtonHref?: string; + + @property({ attribute: 'secondary-button-command' }) + secondaryButtonCommand?: string; + + private get classNames() { + return { + banner: true, + [`banner--${this.display}`]: true, + }; + } + + override render(): unknown { + return html` +
+ ${this.renderContent()} +
+ `; + } + + private renderContent() { + return html` + + `; + } + + private renderTitle() { + return html``; + } + + private renderBody() { + return html``; + } + + private renderButtons() { + const hasPrimary = this.primaryButton; + const hasSecondary = this.secondaryButton; + + if (!hasPrimary && !hasSecondary) return ''; + + return html` + + `; + } + + private renderPrimaryButton() { + return html` + + `; + } + + private renderSecondaryButton() { + return html` + + `; + } + + private onPrimaryButtonClick(e: Event) { + if (this.primaryButtonCommand) { + e.preventDefault(); + } + this.dispatchEvent( + new CustomEvent('gl-banner-primary-click', { + detail: { command: this.primaryButtonCommand }, + bubbles: true, + composed: true, + }), + ); + } + + private onSecondaryButtonClick(e: Event) { + if (this.secondaryButtonCommand) { + e.preventDefault(); + } + this.dispatchEvent( + new CustomEvent('gl-banner-secondary-click', { + detail: { command: this.secondaryButtonCommand }, + bubbles: true, + composed: true, + }), + ); + } +} + +declare global { + interface HTMLElementTagNameMap { + [bannerTagName]: GlBanner; + } +} diff --git a/src/webviews/apps/shared/components/banner/index.ts b/src/webviews/apps/shared/components/banner/index.ts new file mode 100644 index 0000000000000..66f8529ae43c9 --- /dev/null +++ b/src/webviews/apps/shared/components/banner/index.ts @@ -0,0 +1,2 @@ +export * from './banner'; +export { bannerStyles } from './banner.css'; diff --git a/src/webviews/apps/shared/components/button.ts b/src/webviews/apps/shared/components/button.ts index 5771b5d370df2..89ca7dfd29a33 100644 --- a/src/webviews/apps/shared/components/button.ts +++ b/src/webviews/apps/shared/components/button.ts @@ -72,6 +72,11 @@ export class GlButton extends LitElement { cursor: pointer; } + /* When truncate is enabled, allow the control to shrink */ + :host([truncate]) .control { + min-width: 0; + } + button.control { appearance: none; background: transparent; @@ -88,6 +93,14 @@ export class GlButton extends LitElement { max-width: 100%; } + /* Text truncation option - enabled via truncate attribute */ + :host([truncate]) .label { + overflow: hidden; + text-overflow: ellipsis; + white-space: nowrap; + display: block; /* Change from flex to block for ellipsis to work */ + } + :host(:hover) { background: var(--button-hover-background); } @@ -220,6 +233,9 @@ export class GlButton extends LitElement { @property() tooltipPlacement?: GlTooltip['placement'] = 'bottom'; + @property({ type: Boolean, reflect: true }) + truncate = false; + override connectedCallback(): void { super.connectedCallback?.(); diff --git a/src/webviews/home/homeWebview.ts b/src/webviews/home/homeWebview.ts index 01634e68540a6..e3b5b3c767722 100644 --- a/src/webviews/home/homeWebview.ts +++ b/src/webviews/home/homeWebview.ts @@ -49,6 +49,7 @@ import type { AIModelChangeEvent } from '../../plus/ai/aiProviderService'; import { showPatchesView } from '../../plus/drafts/actions'; import type { Subscription } from '../../plus/gk/models/subscription'; import type { SubscriptionChangeEvent } from '../../plus/gk/subscriptionService'; +import { isAiAllAccessPromotionActive } from '../../plus/gk/utils/-webview/promo.utils'; import { isSubscriptionTrialOrPaidFromState } from '../../plus/gk/utils/subscription.utils'; import type { ConfiguredIntegrationsChangeEvent } from '../../plus/integrations/authentication/configuredIntegrationService'; import { providersMetadata } from '../../plus/integrations/providers/models'; @@ -103,6 +104,7 @@ import type { import { ChangeOverviewRepositoryCommand, CollapseSectionCommand, + DidChangeAiAllAccessBanner, DidChangeIntegrationsConnections, DidChangeLaunchpad, DidChangeOrgSettings, @@ -115,6 +117,7 @@ import { DidChangeWalkthroughProgress, DidCompleteDiscoveringRepositories, DidFocusAccount, + DismissAiAllAccessBannerCommand, DismissWalkthroughSection, GetActiveOverview, GetInactiveOverview, @@ -337,6 +340,14 @@ export class HomeWebviewProvider implements WebviewProvider this.container.subscription.validate({ force: true }, src), this, ), + + registerCommand( + `${this.host.id}.ai.allAccess.dismiss`, + () => { + void this.dismissAiAllAccessBanner(); + }, + this, + ), registerCommand('gitlens.home.changeBranchMergeTarget', this.changeBranchMergeTarget, this), registerCommand('gitlens.home.deleteBranchOrWorktree', this.deleteBranchOrWorktree, this), registerCommand('gitlens.home.pushBranch', this.pushBranch, this), @@ -381,6 +392,10 @@ export class HomeWebviewProvider implements WebviewProvider { + const subscription = await this.container.subscription.getSubscription(); + return subscription.account?.id ?? '00000000'; + } + + @log() + private async dismissAiAllAccessBanner() { + this.container.telemetry.sendEvent('aiAllAccess/bannerDismissed', undefined, { source: 'home' }); + const userId = await this.getAiAllAccessUserId(); + void this.container.storage.store(`gk:promo:${userId}:ai:allAccess:dismissed`, true).catch(); + // TODO: Add telemetry tracking for AI All Access banner dismiss + await this.onAiAllAccessBannerChanged(); + } + private getOrgSettings(): State['orgSettings'] { return { drafts: getContext('gitlens:gk:organization:drafts:enabled', false), @@ -776,13 +812,16 @@ export class HomeWebviewProvider implements WebviewProvider { - const [subResult, integrationResult, aiModelResult] = await Promise.allSettled([ + const [subResult, integrationResult, aiModelResult, aiAllAccessBannerCollapsed] = await Promise.allSettled([ this.getSubscriptionState(subscription), this.getIntegrationStates(true), this.container.ai.getModel({ silent: true }, { source: 'home' }), + this.getAiAllAccessBannerCollapsed(), ]); if (subResult.status === 'rejected') { @@ -805,6 +844,7 @@ export class HomeWebviewProvider implements WebviewProvider(scop export const DismissWalkthroughSection = new IpcCommand(scope, 'walkthrough/dismiss'); +export const DidChangeAiAllAccessBanner = new IpcNotification(scope, 'ai/allAccess/didChange'); +export const DismissAiAllAccessBannerCommand = new IpcCommand(scope, 'ai/allAccess/dismiss'); + export const SetOverviewFilter = new IpcCommand(scope, 'overview/filter/set'); export type OpenInGraphParams =