@codingame/monaco-vscode-workbench-service-override 37.2.0 → 37.3.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/common.d.ts +3 -0
- package/common.js +29 -0
- package/index.d.ts +1 -1
- package/index.js +25 -32
- package/package.json +18 -8
- package/session.d.ts +4 -0
- package/session.js +260 -0
- package/vscode/src/vs/platform/agentHost/browser/remoteAgentHostLocationPreferenceService.d.ts +24 -0
- package/vscode/src/vs/platform/agentHost/browser/remoteAgentHostLocationPreferenceService.js +71 -0
- package/vscode/src/vs/platform/agentHost/common/remoteAgentHostLocationPreference.d.ts +7 -0
- package/vscode/src/vs/platform/agentHost/common/remoteAgentHostLocationPreference.js +7 -0
- package/vscode/src/vs/sessions/browser/dockedAuxiliaryBarController.d.ts +50 -0
- package/vscode/src/vs/sessions/browser/dockedAuxiliaryBarController.js +120 -0
- package/vscode/src/vs/sessions/browser/media/sessions-logo-dark.svg +6 -0
- package/vscode/src/vs/sessions/browser/media/sessions-logo-light.svg +6 -0
- package/vscode/src/vs/sessions/browser/media/sessionsSetUp.css +72 -0
- package/vscode/src/vs/sessions/browser/parts/chatCompositeBar.d.ts +116 -0
- package/vscode/src/vs/sessions/browser/parts/chatCompositeBar.js +566 -0
- package/vscode/src/vs/sessions/browser/parts/chatGroupDropTarget.d.ts +43 -0
- package/vscode/src/vs/sessions/browser/parts/chatGroupDropTarget.js +308 -0
- package/vscode/src/vs/sessions/browser/parts/chatGroupView.d.ts +108 -0
- package/vscode/src/vs/sessions/browser/parts/chatGroupView.js +324 -0
- package/vscode/src/vs/sessions/browser/parts/chatGroupsView.d.ts +136 -0
- package/vscode/src/vs/sessions/browser/parts/chatGroupsView.js +771 -0
- package/vscode/src/vs/sessions/browser/parts/customViewGridPart.d.ts +43 -0
- package/vscode/src/vs/sessions/browser/parts/customViewGridPart.js +113 -0
- package/vscode/src/vs/sessions/browser/parts/customViewGridParts.d.ts +17 -0
- package/vscode/src/vs/sessions/browser/parts/customViewGridParts.js +31 -0
- package/vscode/src/vs/sessions/browser/parts/customViewNode.d.ts +24 -0
- package/vscode/src/vs/sessions/browser/parts/customViewNode.js +131 -0
- package/vscode/src/vs/sessions/browser/parts/editorPart.d.ts +11 -0
- package/vscode/src/vs/sessions/browser/parts/editorPart.js +36 -0
- package/vscode/src/vs/sessions/browser/parts/editorParts.d.ts +12 -0
- package/vscode/src/vs/sessions/browser/parts/editorParts.js +45 -0
- package/vscode/src/vs/sessions/browser/parts/media/chatCompositeBar.css +559 -0
- package/vscode/src/vs/sessions/browser/parts/media/chatGroupDropTarget.css +27 -0
- package/vscode/src/vs/sessions/browser/parts/media/chatGroupsView.css +60 -0
- package/vscode/src/vs/sessions/browser/parts/media/customViewGridPart.css +108 -0
- package/vscode/src/vs/sessions/browser/parts/media/editorPart.css +210 -0
- package/vscode/src/vs/sessions/browser/parts/media/remoteHostUnavailableEmptyState.css +81 -0
- package/vscode/src/vs/sessions/browser/parts/media/sessionDropTarget.css +31 -0
- package/vscode/src/vs/sessions/browser/parts/media/sessionReadOnlyBanner.css +87 -0
- package/vscode/src/vs/sessions/browser/parts/media/sessionView.css +107 -0
- package/vscode/src/vs/sessions/browser/parts/media/sessionsPart.css +134 -0
- package/vscode/src/vs/sessions/browser/parts/menubar.contribution.d.ts +1 -0
- package/vscode/src/vs/sessions/browser/parts/menubar.contribution.js +79 -0
- package/vscode/src/vs/sessions/browser/parts/mobile/mobileCustomViewGridPart.d.ts +13 -0
- package/vscode/src/vs/sessions/browser/parts/mobile/mobileCustomViewGridPart.js +33 -0
- package/vscode/src/vs/sessions/browser/parts/mobile/mobileSessionsPart.d.ts +14 -0
- package/vscode/src/vs/sessions/browser/parts/mobile/mobileSessionsPart.js +34 -0
- package/vscode/src/vs/sessions/browser/parts/remoteHostUnavailableEmptyState.d.ts +39 -0
- package/vscode/src/vs/sessions/browser/parts/remoteHostUnavailableEmptyState.js +136 -0
- package/vscode/src/vs/sessions/browser/parts/sessionBarStyles.d.ts +9 -0
- package/vscode/src/vs/sessions/browser/parts/sessionBarStyles.js +62 -0
- package/vscode/src/vs/sessions/browser/parts/sessionDropTarget.d.ts +39 -0
- package/vscode/src/vs/sessions/browser/parts/sessionDropTarget.js +261 -0
- package/vscode/src/vs/sessions/browser/parts/sessionHeader.d.ts +97 -0
- package/vscode/src/vs/sessions/browser/parts/sessionHeader.js +345 -0
- package/vscode/src/vs/sessions/browser/parts/sessionReadOnlyBanner.d.ts +43 -0
- package/vscode/src/vs/sessions/browser/parts/sessionReadOnlyBanner.js +69 -0
- package/vscode/src/vs/sessions/browser/parts/sessionRemoteConnection.d.ts +79 -0
- package/vscode/src/vs/sessions/browser/parts/sessionRemoteConnection.js +363 -0
- package/vscode/src/vs/sessions/browser/parts/sessionView.d.ts +125 -0
- package/vscode/src/vs/sessions/browser/parts/sessionView.js +300 -0
- package/vscode/src/vs/sessions/browser/parts/sessionsPart.d.ts +124 -0
- package/vscode/src/vs/sessions/browser/parts/sessionsPart.js +336 -0
- package/vscode/src/vs/sessions/browser/parts/sessionsParts.d.ts +33 -0
- package/vscode/src/vs/sessions/browser/parts/sessionsParts.js +62 -0
- package/vscode/src/vs/sessions/browser/parts/singlePaneAuxiliaryBarPart.d.ts +13 -0
- package/vscode/src/vs/sessions/browser/parts/singlePaneAuxiliaryBarPart.js +36 -0
- package/vscode/src/vs/sessions/browser/parts/singlePaneEditorPart.d.ts +65 -0
- package/vscode/src/vs/sessions/browser/parts/singlePaneEditorPart.js +178 -0
- package/vscode/src/vs/sessions/browser/sessionWorkspace.d.ts +12 -0
- package/vscode/src/vs/sessions/browser/sessionWorkspace.js +19 -0
- package/vscode/src/vs/sessions/browser/sessionsSetUpService.d.ts +24 -0
- package/vscode/src/vs/sessions/browser/sessionsSetUpService.js +598 -0
- package/vscode/src/vs/sessions/browser/sessionsSignInDialog.d.ts +25 -0
- package/vscode/src/vs/sessions/browser/sessionsSignInDialog.js +91 -0
- package/vscode/src/vs/sessions/common/welcome.d.ts +1 -0
- package/vscode/src/vs/sessions/common/welcome.js +5 -0
- package/vscode/src/vs/sessions/contrib/accountMenu/browser/account.contribution.d.ts +11 -0
- package/vscode/src/vs/sessions/contrib/accountMenu/browser/account.contribution.js +1052 -0
- package/vscode/src/vs/sessions/contrib/accountMenu/browser/chatPetAchievementBadges.d.ts +23 -0
- package/vscode/src/vs/sessions/contrib/accountMenu/browser/chatPetAchievementBadges.js +168 -0
- package/vscode/src/vs/sessions/contrib/accountMenu/browser/media/accountTitleBarWidget.css +646 -0
- package/vscode/src/vs/sessions/contrib/accountMenu/browser/media/accountWidget.css +231 -0
- package/vscode/src/vs/sessions/contrib/accountMenu/browser/media/chatPetAchievementBadges.css +120 -0
- package/vscode/src/vs/sessions/contrib/agentFeedback/browser/nullAgentFeedbackService.contribution.d.ts +53 -0
- package/vscode/src/vs/sessions/contrib/agentFeedback/browser/nullAgentFeedbackService.contribution.js +99 -0
- package/vscode/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationTreeView.contribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationTreeView.contribution.js +270 -0
- package/vscode/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationTreeViewViews.d.ts +62 -0
- package/vscode/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationTreeViewViews.js +606 -0
- package/vscode/src/vs/sessions/contrib/aiCustomizationTreeView/browser/media/aiCustomizationTreeView.css +116 -0
- package/vscode/src/vs/sessions/contrib/aquarium/browser/aquarium.contribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/aquarium/browser/aquarium.contribution.js +97 -0
- package/vscode/src/vs/sessions/contrib/aquarium/browser/aquariumOverlay.d.ts +72 -0
- package/vscode/src/vs/sessions/contrib/aquarium/browser/aquariumOverlay.js +776 -0
- package/vscode/src/vs/sessions/contrib/aquarium/browser/fish.d.ts +68 -0
- package/vscode/src/vs/sessions/contrib/aquarium/browser/fish.js +153 -0
- package/vscode/src/vs/sessions/contrib/aquarium/browser/fishFeedingStreak.d.ts +58 -0
- package/vscode/src/vs/sessions/contrib/aquarium/browser/fishFeedingStreak.js +172 -0
- package/vscode/src/vs/sessions/contrib/aquarium/browser/media/aquarium.css +316 -0
- package/vscode/src/vs/sessions/contrib/aquarium/browser/vscodeLogoPath.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/aquarium/browser/vscodeLogoPath.js +5 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationDialog.d.ts +173 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationDialog.js +1589 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationDialogService.d.ts +32 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationDialogService.js +396 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationInputCompletions.d.ts +33 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationInputCompletions.js +216 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationLeaderElection.d.ts +37 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationLeaderElection.js +126 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationRunner.d.ts +21 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationRunner.js +294 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationScheduler.d.ts +59 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationScheduler.js +232 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationStorageService.d.ts +13 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationStorageService.js +22 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationTools.d.ts +60 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationTools.js +1256 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automations.contribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automations.contribution.js +88 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/media/automationDialog.css +746 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/providerAutomationService.d.ts +62 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/providerAutomationService.js +493 -0
- package/vscode/src/vs/sessions/contrib/automations/common/isolationGroupModel.d.ts +38 -0
- package/vscode/src/vs/sessions/contrib/automations/common/isolationGroupModel.js +123 -0
- package/vscode/src/vs/sessions/contrib/blockedSessions/browser/blockedSessions.d.ts +45 -0
- package/vscode/src/vs/sessions/contrib/blockedSessions/browser/blockedSessions.js +110 -0
- package/vscode/src/vs/sessions/contrib/browserView/browser/sessionBrowserView.contribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/browserView/browser/sessionBrowserView.contribution.js +5 -0
- package/vscode/src/vs/sessions/contrib/browserView/browser/sessionBrowserView.d.ts +31 -0
- package/vscode/src/vs/sessions/contrib/browserView/browser/sessionBrowserView.js +137 -0
- package/vscode/src/vs/sessions/contrib/changes/browser/changes.contribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/changes/browser/changes.contribution.js +130 -0
- package/vscode/src/vs/sessions/contrib/changes/browser/changesActions.d.ts +8 -0
- package/vscode/src/vs/sessions/contrib/changes/browser/changesActions.js +385 -0
- package/vscode/src/vs/sessions/contrib/changes/browser/changesMultiDiffSourceResolver.d.ts +28 -0
- package/vscode/src/vs/sessions/contrib/changes/browser/changesMultiDiffSourceResolver.js +76 -0
- package/vscode/src/vs/sessions/contrib/changes/browser/changesViewActions.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/changes/browser/changesViewActions.js +509 -0
- package/vscode/src/vs/sessions/contrib/changes/browser/changesetReviewActions.d.ts +6 -0
- package/vscode/src/vs/sessions/contrib/changes/browser/changesetReviewActions.js +58 -0
- package/vscode/src/vs/sessions/contrib/changes/browser/media/changesActions.css +11 -0
- package/vscode/src/vs/sessions/contrib/changes/browser/sessionSyncChanges.d.ts +24 -0
- package/vscode/src/vs/sessions/contrib/changes/browser/sessionSyncChanges.js +188 -0
- package/vscode/src/vs/sessions/contrib/changes/browser/sessionsChangesAccessibilityHelp.d.ts +15 -0
- package/vscode/src/vs/sessions/contrib/changes/browser/sessionsChangesAccessibilityHelp.js +100 -0
- package/vscode/src/vs/sessions/contrib/chat/browser/chatViewStateService.d.ts +9 -0
- package/vscode/src/vs/sessions/contrib/chat/browser/chatViewStateService.js +18 -0
- package/vscode/src/vs/sessions/contrib/chat/browser/media/sessionChatInputToolbarDebug.css +59 -0
- package/vscode/src/vs/sessions/contrib/chat/browser/sessionChatInputToolbarDebug.d.ts +47 -0
- package/vscode/src/vs/sessions/contrib/chat/browser/sessionChatInputToolbarDebug.js +306 -0
- package/vscode/src/vs/sessions/contrib/chat/browser/sessionTaskRunner.d.ts +41 -0
- package/vscode/src/vs/sessions/contrib/chat/browser/sessionTaskRunner.js +31 -0
- package/vscode/src/vs/sessions/contrib/chatDebug/browser/chatDebug.contribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/chatDebug/browser/chatDebug.contribution.js +84 -0
- package/vscode/src/vs/sessions/contrib/customViewTest/browser/customViewTest.contribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/customViewTest/browser/customViewTest.contribution.js +111 -0
- package/vscode/src/vs/sessions/contrib/customViewTest/browser/media/customViewTest.css +9 -0
- package/vscode/src/vs/sessions/contrib/editor/browser/addTabActions.d.ts +21 -0
- package/vscode/src/vs/sessions/contrib/editor/browser/addTabActions.js +170 -0
- package/vscode/src/vs/sessions/contrib/editor/browser/editor.contribution.d.ts +14 -0
- package/vscode/src/vs/sessions/contrib/editor/browser/editor.contribution.js +425 -0
- package/vscode/src/vs/sessions/contrib/editor/browser/emptyFileEditor.contribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/editor/browser/emptyFileEditor.contribution.js +35 -0
- package/vscode/src/vs/sessions/contrib/editor/browser/emptyFileEditor.d.ts +18 -0
- package/vscode/src/vs/sessions/contrib/editor/browser/emptyFileEditor.js +85 -0
- package/vscode/src/vs/sessions/contrib/editor/browser/emptyFileEditorInput.d.ts +31 -0
- package/vscode/src/vs/sessions/contrib/editor/browser/emptyFileEditorInput.js +125 -0
- package/vscode/src/vs/sessions/contrib/editor/browser/media/editorBreadcrumbs.css +66 -0
- package/vscode/src/vs/sessions/contrib/editor/browser/media/editorHeader.css +113 -0
- package/vscode/src/vs/sessions/contrib/editor/browser/media/emptyFileEditor.css +30 -0
- package/vscode/src/vs/sessions/contrib/fileTreeView/browser/fileTreeView.contribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/fileTreeView/browser/fileTreeView.contribution.js +25 -0
- package/vscode/src/vs/sessions/contrib/fileTreeView/browser/githubFileSystemProvider.d.ts +66 -0
- package/vscode/src/vs/sessions/contrib/fileTreeView/browser/githubFileSystemProvider.js +274 -0
- package/vscode/src/vs/sessions/contrib/files/browser/files.contribution.d.ts +6 -0
- package/vscode/src/vs/sessions/contrib/files/browser/files.contribution.js +100 -0
- package/vscode/src/vs/sessions/contrib/files/browser/filesView.d.ts +21 -0
- package/vscode/src/vs/sessions/contrib/files/browser/filesView.js +76 -0
- package/vscode/src/vs/sessions/contrib/files/browser/media/filesView.css +29 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/baseSessionLayoutController.d.ts +211 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/baseSessionLayoutController.js +587 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/desktopSessionLayoutController.d.ts +112 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/desktopSessionLayoutController.js +444 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/mobileSessionLayoutController.d.ts +13 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/mobileSessionLayoutController.js +8 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/sessions.layout.contribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/sessions.layout.contribution.js +68 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePane/singlePaneDetailPanelCoordinator.d.ts +32 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePane/singlePaneDetailPanelCoordinator.js +81 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePane/singlePaneDockedTabsCoordinator.d.ts +111 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePane/singlePaneDockedTabsCoordinator.js +513 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePane/singlePaneDraftSessionStrategy.d.ts +44 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePane/singlePaneDraftSessionStrategy.js +423 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePane/singlePaneExistingSessionStrategy.d.ts +62 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePane/singlePaneExistingSessionStrategy.js +435 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePane/singlePaneLayoutStrategy.d.ts +46 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePane/singlePaneLayoutStrategy.js +11 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePane/singlePaneSharedHelpers.d.ts +11 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePane/singlePaneSharedHelpers.js +43 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePane/singlePaneVisibilityProfileStore.d.ts +21 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePane/singlePaneVisibilityProfileStore.js +77 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePaneLayoutController.d.ts +55 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePaneLayoutController.js +91 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/agentHostReadinessContext.d.ts +11 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/agentHostReadinessContext.js +39 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionTourContribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionTourContribution.js +109 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewTourContribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewTourContribution.js +123 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewTourTrigger.d.ts +24 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewTourTrigger.js +67 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewV2TourContribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewV2TourContribution.js +47 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewV3Prompt.d.ts +79 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewV3Prompt.js +1277 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewV3TourContribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewV3TourContribution.js +75 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionTour.d.ts +34 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionTour.js +53 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewTour.d.ts +40 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewTour.js +69 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewTourShared.d.ts +4 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewTourShared.js +38 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewV2Tour.d.ts +6 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewV2Tour.js +63 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewV3Tour.d.ts +15 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewV3Tour.js +49 -0
- package/vscode/src/vs/sessions/contrib/policyBlocked/browser/media/sessionsPolicyBlocked.css +125 -0
- package/vscode/src/vs/sessions/contrib/policyBlocked/browser/policyBlocked.contribution.d.ts +20 -0
- package/vscode/src/vs/sessions/contrib/policyBlocked/browser/policyBlocked.contribution.js +98 -0
- package/vscode/src/vs/sessions/contrib/policyBlocked/browser/sessionsPolicyBlocked.d.ts +39 -0
- package/vscode/src/vs/sessions/contrib/policyBlocked/browser/sessionsPolicyBlocked.js +218 -0
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/devContainerAgentHostService.d.ts +53 -0
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/devContainerAgentHostService.js +496 -0
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/remoteAgentHostConnectionCustomization.d.ts +27 -0
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/remoteAgentHostConnectionCustomization.js +26 -0
- package/vscode/src/vs/sessions/contrib/search/browser/media/searchEditorEmptyState.css +15 -0
- package/vscode/src/vs/sessions/contrib/search/browser/search.contribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/search/browser/search.contribution.js +79 -0
- package/vscode/src/vs/sessions/contrib/search/browser/searchEditorEmptyState.contribution.d.ts +7 -0
- package/vscode/src/vs/sessions/contrib/search/browser/searchEditorEmptyState.contribution.js +57 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/blockedSessionsCIFixModel.d.ts +39 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/blockedSessionsCIFixModel.js +155 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/blockedSessionsIndicatorModel.d.ts +117 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/blockedSessionsIndicatorModel.js +320 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/blockedSessionsList.d.ts +65 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/blockedSessionsList.js +129 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/media/automationsCards.css +624 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/media/blockedSessionsList.css +111 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/media/newSessionActionViewItem.css +112 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/media/sessionsTitleBarWidget.css +159 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionActionFeedback.d.ts +26 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionActionFeedback.js +26 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionDetailsAction.d.ts +2 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionDetailsAction.js +77 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessions.contribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessions.contribution.js +162 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsActions.d.ts +111 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsActions.js +1550 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsMouseNavigation.d.ts +13 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsMouseNavigation.js +69 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsPicker.d.ts +10 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsPicker.js +33 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsTelemetry.contribution.d.ts +126 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsTelemetry.contribution.js +724 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsTitleBarWidget.d.ts +150 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsTitleBarWidget.js +526 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsTypedCharactersTracker.d.ts +64 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsTypedCharactersTracker.js +99 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsWindowNotifier.d.ts +37 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsWindowNotifier.js +160 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationTemplates.d.ts +19 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationTemplates.js +74 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationsAccessibility.d.ts +4 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationsAccessibility.js +228 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationsView.d.ts +53 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationsView.js +2143 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/views/sessionsViewActions.d.ts +12 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/views/sessionsViewActions.js +1270 -0
- package/vscode/src/vs/sessions/contrib/workspace/browser/workspace.contribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/workspace/browser/workspace.contribution.js +5 -0
- package/vscode/src/vs/sessions/contrib/workspace/browser/workspaceFolderManagement.d.ts +28 -0
- package/vscode/src/vs/sessions/contrib/workspace/browser/workspaceFolderManagement.js +95 -0
- package/vscode/src/vs/sessions/services/agentHostFilter/browser/agentHostFilterService.d.ts +79 -0
- package/vscode/src/vs/sessions/services/agentHostFilter/browser/agentHostFilterService.js +259 -0
- package/vscode/src/vs/sessions/services/customView/browser/customView.d.ts +42 -0
- package/vscode/src/vs/sessions/services/customView/browser/customView.js +15 -0
- package/vscode/src/vs/sessions/services/customView/browser/customViewService.d.ts +21 -0
- package/vscode/src/vs/sessions/services/customView/browser/customViewService.js +68 -0
- package/vscode/src/vs/sessions/services/sessions/browser/closedItemHistory.d.ts +72 -0
- package/vscode/src/vs/sessions/services/sessions/browser/closedItemHistory.js +115 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionGroupsService.d.ts +77 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionGroupsService.js +330 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionNavigation.d.ts +67 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionNavigation.js +157 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionOpenTelemetryService.d.ts +32 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionOpenTelemetryService.js +162 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionSectionOrderService.d.ts +40 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionSectionOrderService.js +170 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsListModelService.d.ts +63 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsListModelService.js +419 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsManagementService.d.ts +229 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsManagementService.js +1212 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsProvidersService.d.ts +22 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsProvidersService.js +42 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsRecencyHistory.d.ts +43 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsRecencyHistory.js +103 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsService.d.ts +243 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsService.js +1121 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsWindowUsageService.d.ts +8 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsWindowUsageService.js +24 -0
- package/vscode/src/vs/sessions/services/sessions/browser/visibleSessions.d.ts +321 -0
- package/vscode/src/vs/sessions/services/sessions/browser/visibleSessions.js +729 -0
- package/vscode/src/vs/sessions/services/sessions/browser/worktreeTrust.d.ts +23 -0
- package/vscode/src/vs/sessions/services/sessions/browser/worktreeTrust.js +23 -0
- package/vscode/src/vs/sessions/services/sessions/common/sessionContextKeys.d.ts +32 -0
- package/vscode/src/vs/sessions/services/sessions/common/sessionContextKeys.js +103 -0
- package/vscode/src/vs/sessions/services/workspaceFolderLabel/browser/workspaceFolderLabelService.d.ts +16 -0
- package/vscode/src/vs/sessions/services/workspaceFolderLabel/browser/workspaceFolderLabelService.js +41 -0
- package/vscode/src/vs/workbench/browser/layout.js +7 -7
- package/vscode/src/vs/workbench/browser/workbench.js +3 -3
|
@@ -0,0 +1,1277 @@
|
|
|
1
|
+
|
|
2
|
+
import { raceTimeout } from '@codingame/monaco-vscode-api/vscode/vs/base/common/async';
|
|
3
|
+
import { CancellationTokenSource } from '@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation';
|
|
4
|
+
import { Codicon } from '@codingame/monaco-vscode-api/vscode/vs/base/common/codicons';
|
|
5
|
+
import { isCancellationError, CancellationError } from '@codingame/monaco-vscode-api/vscode/vs/base/common/errors';
|
|
6
|
+
import { DisposableStore, MutableDisposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
|
|
7
|
+
import '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/index';
|
|
8
|
+
import { format } from '@codingame/monaco-vscode-api/vscode/vs/base/common/strings';
|
|
9
|
+
import { generateUuid } from '@codingame/monaco-vscode-api/vscode/vs/base/common/uuid';
|
|
10
|
+
import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
|
|
11
|
+
import { getGitHubRemoteInfo } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/git/common/utils';
|
|
12
|
+
import { isOnboardingDeveloperModeEnabled, ONBOARDING_DEVELOPER_MODE_VARIATIONS_CONFIG, getOnboardingDeveloperModeVariation } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/onboarding/common/onboardingScenarioService';
|
|
13
|
+
import { isAgentHostProviderId } from '@codingame/monaco-vscode-api/vscode/vs/sessions/common/agentHostSessionsProvider';
|
|
14
|
+
import { NEW_SESSION_PROMPT_TYPING_DURATION_MS } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/chat/browser/newSessionComposerService';
|
|
15
|
+
import { getGitHubRepositoryFromUri } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/github/common/utils';
|
|
16
|
+
import { GitHubAuthenticationError } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/github/browser/githubApiClient';
|
|
17
|
+
import { computeIssueIcon, GitHubIssueState, GitHubPullRequestState } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/github/common/types';
|
|
18
|
+
import { resolveGitHubRepositoryFromGitConfig } from '@codingame/monaco-vscode-api/vscode/vs/sessions/services/sessions/browser/gitHubRepositoryResolver';
|
|
19
|
+
import { NEW_SESSION_VIEW_V3_TOUR_ID, NEW_SESSION_VIEW_V3_VARIATION_TREATMENT, NEW_SESSION_VIEW_V3_OPTIONS_VARIATION, NEW_SESSION_VIEW_V3_PROMPT_VARIATION, NEW_SESSION_VIEW_V3_GITHUB_PROMPT_VARIATION } from './tours/newSessionViewV3Tour.js';
|
|
20
|
+
import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
|
|
21
|
+
import { computePullRequestIcon } from '@codingame/monaco-vscode-api/vscode/vs/workbench/common/chatPullRequest';
|
|
22
|
+
|
|
23
|
+
const DEFAULT_GITHUB_LOOKUP_TIMEOUTS = {
|
|
24
|
+
totalMs: 10_000,
|
|
25
|
+
summaryMs: 4_000,
|
|
26
|
+
linkageMs: 1_500,
|
|
27
|
+
reviewMs: 3_000
|
|
28
|
+
};
|
|
29
|
+
const LOG_PREFIX = "[NewSessionViewV3Prompt]";
|
|
30
|
+
const PROMPT_TEMPLATE_TREATMENT = "onb.newSessionViewV3.promptTemplate";
|
|
31
|
+
const PLACEHOLDER_TREATMENT = "onb.newSessionViewV3.placeholder";
|
|
32
|
+
const DEFAULT_TASK_PLACEHOLDER = ( localize(4095, "[describe the coding task]"));
|
|
33
|
+
const DEFAULT_PROMPT_TEMPLATE = ( localize(
|
|
34
|
+
4096,
|
|
35
|
+
"Help me complete {0} in this project. First, inspect the relevant files and explain your approach briefly. Then implement the solution using existing project conventions, avoid unrelated changes, and run the most relevant tests or checks. If anything is unclear, make a reasonable assumption and state it. When finished, summarize what changed and mention any remaining issues."
|
|
36
|
+
));
|
|
37
|
+
const PROMPT_OPTION_COUNT = 3;
|
|
38
|
+
const LOOKUP_STAGE_ORDER = ["repository", "issueSummary", "prSummary", "issueLinkage", "prReview"];
|
|
39
|
+
const LOOKUP_STAGE_OUTCOME_SEVERITY = [
|
|
40
|
+
"notRun",
|
|
41
|
+
"skipped",
|
|
42
|
+
"success",
|
|
43
|
+
"cancelled",
|
|
44
|
+
"requestFailed",
|
|
45
|
+
"timeout",
|
|
46
|
+
"noAuthentication"
|
|
47
|
+
];
|
|
48
|
+
const NO_LOOKUP_TELEMETRY = {
|
|
49
|
+
gitHubOptionCount: 0,
|
|
50
|
+
candidatesFound: 0,
|
|
51
|
+
lookupDurationMs: 0,
|
|
52
|
+
repositoryMs: 0,
|
|
53
|
+
issueSummaryMs: 0,
|
|
54
|
+
issueLinkageMs: 0,
|
|
55
|
+
prSummaryMs: 0,
|
|
56
|
+
prReviewMs: 0,
|
|
57
|
+
issueSummaryOutcome: "notRun",
|
|
58
|
+
issueLinkageOutcome: "notRun",
|
|
59
|
+
prSummaryOutcome: "notRun",
|
|
60
|
+
prReviewOutcome: "notRun",
|
|
61
|
+
timedOutStage: "none"
|
|
62
|
+
};
|
|
63
|
+
class GitHubLookupDiagnostics {
|
|
64
|
+
constructor() {
|
|
65
|
+
this._startTime = Date.now();
|
|
66
|
+
this._durations = ( new Map());
|
|
67
|
+
this._outcomes = ( new Map());
|
|
68
|
+
this._pending = ( new Map());
|
|
69
|
+
this._timedOutStage = "none";
|
|
70
|
+
}
|
|
71
|
+
begin(stage) {
|
|
72
|
+
this._pending.set(stage, (this._pending.get(stage) ?? 0) + 1);
|
|
73
|
+
}
|
|
74
|
+
record(stage, outcome, durationMs) {
|
|
75
|
+
const pending = (this._pending.get(stage) ?? 1) - 1;
|
|
76
|
+
if (pending > 0) {
|
|
77
|
+
this._pending.set(stage, pending);
|
|
78
|
+
} else {
|
|
79
|
+
this._pending.delete(stage);
|
|
80
|
+
}
|
|
81
|
+
this._durations.set(stage, Math.max(this._durations.get(stage) ?? 0, durationMs));
|
|
82
|
+
const previous = this._outcomes.get(stage) ?? "notRun";
|
|
83
|
+
if (LOOKUP_STAGE_OUTCOME_SEVERITY.indexOf(outcome) > LOOKUP_STAGE_OUTCOME_SEVERITY.indexOf(previous)) {
|
|
84
|
+
this._outcomes.set(stage, outcome);
|
|
85
|
+
} else if (!( this._outcomes.has(stage))) {
|
|
86
|
+
this._outcomes.set(stage, previous);
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
markTimedOut() {
|
|
90
|
+
this._timedOutStage = [...LOOKUP_STAGE_ORDER].reverse().find(stage => ( this._pending.has(stage))) ?? "unknown";
|
|
91
|
+
}
|
|
92
|
+
summarize(candidatesFound, gitHubOptionCount) {
|
|
93
|
+
return {
|
|
94
|
+
gitHubOptionCount,
|
|
95
|
+
candidatesFound,
|
|
96
|
+
lookupDurationMs: Date.now() - this._startTime,
|
|
97
|
+
repositoryMs: this._durations.get("repository") ?? 0,
|
|
98
|
+
issueSummaryMs: this._durations.get("issueSummary") ?? 0,
|
|
99
|
+
issueLinkageMs: this._durations.get("issueLinkage") ?? 0,
|
|
100
|
+
prSummaryMs: this._durations.get("prSummary") ?? 0,
|
|
101
|
+
prReviewMs: this._durations.get("prReview") ?? 0,
|
|
102
|
+
issueSummaryOutcome: this._outcomes.get("issueSummary") ?? "notRun",
|
|
103
|
+
issueLinkageOutcome: this._outcomes.get("issueLinkage") ?? "notRun",
|
|
104
|
+
prSummaryOutcome: this._outcomes.get("prSummary") ?? "notRun",
|
|
105
|
+
prReviewOutcome: this._outcomes.get("prReview") ?? "notRun",
|
|
106
|
+
timedOutStage: this._timedOutStage
|
|
107
|
+
};
|
|
108
|
+
}
|
|
109
|
+
}
|
|
110
|
+
class NewSessionViewV3PromptRunner {
|
|
111
|
+
constructor(
|
|
112
|
+
_assignmentService,
|
|
113
|
+
_configurationService,
|
|
114
|
+
_sessionsService,
|
|
115
|
+
_newSessionComposerService,
|
|
116
|
+
_gitService,
|
|
117
|
+
_fileService,
|
|
118
|
+
_gitHubService,
|
|
119
|
+
_telemetryService,
|
|
120
|
+
_logService,
|
|
121
|
+
gitHubLookupTimeouts = {}
|
|
122
|
+
) {
|
|
123
|
+
this._assignmentService = _assignmentService;
|
|
124
|
+
this._configurationService = _configurationService;
|
|
125
|
+
this._sessionsService = _sessionsService;
|
|
126
|
+
this._newSessionComposerService = _newSessionComposerService;
|
|
127
|
+
this._gitService = _gitService;
|
|
128
|
+
this._fileService = _fileService;
|
|
129
|
+
this._gitHubService = _gitHubService;
|
|
130
|
+
this._telemetryService = _telemetryService;
|
|
131
|
+
this._logService = _logService;
|
|
132
|
+
this._impressionId = generateUuid();
|
|
133
|
+
this._renderedPromptOptions = [];
|
|
134
|
+
this._gitHubLookupTimeouts = {
|
|
135
|
+
...DEFAULT_GITHUB_LOOKUP_TIMEOUTS,
|
|
136
|
+
...gitHubLookupTimeouts
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
async run(token) {
|
|
140
|
+
this._logService.info(`${LOG_PREFIX} Starting V3 prompt resolution.`);
|
|
141
|
+
this._impressionId = generateUuid();
|
|
142
|
+
this._renderedPromptOptions = [];
|
|
143
|
+
const configuredVariation = await this._resolveConfiguredVariation();
|
|
144
|
+
if (token.isCancellationRequested) {
|
|
145
|
+
this._logService.trace(
|
|
146
|
+
`${LOG_PREFIX} Prompt resolution was cancelled after resolving the configured variation.`
|
|
147
|
+
);
|
|
148
|
+
return false;
|
|
149
|
+
}
|
|
150
|
+
if (configuredVariation === "options" || configuredVariation === "unknown") {
|
|
151
|
+
return this._runPromptOptions(
|
|
152
|
+
configuredVariation,
|
|
153
|
+
token,
|
|
154
|
+
configuredVariation === "unknown" ? "unsupportedVariation" : undefined
|
|
155
|
+
);
|
|
156
|
+
}
|
|
157
|
+
const plan = configuredVariation === "githubPrompt" ? await this._resolveGitHubPromptWithFallback(token) : await this._resolvePrompt("none");
|
|
158
|
+
if (token.isCancellationRequested) {
|
|
159
|
+
this._logService.trace(`${LOG_PREFIX} Prompt resolution was cancelled before prompt insertion.`);
|
|
160
|
+
return false;
|
|
161
|
+
}
|
|
162
|
+
this._logService.info(
|
|
163
|
+
`${LOG_PREFIX} Resolved effective strategy '${plan.effectiveStrategy}' with fallback reason '${plan.fallbackReason}'.`
|
|
164
|
+
);
|
|
165
|
+
const shown = await this._animatePrompt(plan.prompt, plan.taskPlaceholder, token);
|
|
166
|
+
this._logService.info(`${LOG_PREFIX} Prompt insertion completed with shown=${shown}.`);
|
|
167
|
+
this._reportStrategy(configuredVariation, plan.effectiveStrategy, plan.fallbackReason, shown);
|
|
168
|
+
return shown;
|
|
169
|
+
}
|
|
170
|
+
async _resolveConfiguredVariation() {
|
|
171
|
+
const developerModeEnabled = isOnboardingDeveloperModeEnabled(this._configurationService, NEW_SESSION_VIEW_V3_TOUR_ID);
|
|
172
|
+
const developerVariations = this._configurationService.getValue(ONBOARDING_DEVELOPER_MODE_VARIATIONS_CONFIG);
|
|
173
|
+
const configuredDeveloperVariation = typeof developerVariations === "object" && developerVariations !== null ? developerVariations[NEW_SESSION_VIEW_V3_TOUR_ID] : undefined;
|
|
174
|
+
const developerVariation = getOnboardingDeveloperModeVariation(this._configurationService, NEW_SESSION_VIEW_V3_TOUR_ID);
|
|
175
|
+
if (configuredDeveloperVariation && !developerModeEnabled) {
|
|
176
|
+
this._logService.warn(
|
|
177
|
+
`${LOG_PREFIX} Ignoring developer variation '${configuredDeveloperVariation}' because developer mode is not enabled for '${NEW_SESSION_VIEW_V3_TOUR_ID}'.`
|
|
178
|
+
);
|
|
179
|
+
}
|
|
180
|
+
if (developerVariation) {
|
|
181
|
+
this._logService.info(`${LOG_PREFIX} Using developer variation '${developerVariation}'.`);
|
|
182
|
+
return this._normalizeVariation(developerVariation, "developer setting");
|
|
183
|
+
}
|
|
184
|
+
this._logService.trace(
|
|
185
|
+
`${LOG_PREFIX} No active developer variation; resolving treatment '${NEW_SESSION_VIEW_V3_VARIATION_TREATMENT}'.`
|
|
186
|
+
);
|
|
187
|
+
const treatmentVariation = await this._assignmentService.getTreatment(NEW_SESSION_VIEW_V3_VARIATION_TREATMENT);
|
|
188
|
+
this._logService.info(
|
|
189
|
+
`${LOG_PREFIX} Treatment variation resolved to '${treatmentVariation || NEW_SESSION_VIEW_V3_OPTIONS_VARIATION}'.`
|
|
190
|
+
);
|
|
191
|
+
return this._normalizeVariation(treatmentVariation, "treatment");
|
|
192
|
+
}
|
|
193
|
+
_normalizeVariation(variation, source) {
|
|
194
|
+
if (variation === undefined || variation === "" || variation === NEW_SESSION_VIEW_V3_OPTIONS_VARIATION) {
|
|
195
|
+
return "options";
|
|
196
|
+
}
|
|
197
|
+
if (variation === NEW_SESSION_VIEW_V3_PROMPT_VARIATION) {
|
|
198
|
+
return "prompt";
|
|
199
|
+
}
|
|
200
|
+
if (variation === NEW_SESSION_VIEW_V3_GITHUB_PROMPT_VARIATION) {
|
|
201
|
+
return "githubPrompt";
|
|
202
|
+
}
|
|
203
|
+
this._logService.warn(
|
|
204
|
+
`${LOG_PREFIX} Unsupported variation '${variation}' from ${source}; using '${NEW_SESSION_VIEW_V3_OPTIONS_VARIATION}'.`
|
|
205
|
+
);
|
|
206
|
+
return "unknown";
|
|
207
|
+
}
|
|
208
|
+
async _runPromptOptions(configuredVariation, token, configuredFallbackReason) {
|
|
209
|
+
const composer = this._getActiveComposer();
|
|
210
|
+
if (!composer) {
|
|
211
|
+
this._logService.warn(
|
|
212
|
+
`${LOG_PREFIX} Skipping prompt options because no active new-session composer is available.`
|
|
213
|
+
);
|
|
214
|
+
this._reportStrategy(configuredVariation, "options", "noComposer", false);
|
|
215
|
+
return false;
|
|
216
|
+
}
|
|
217
|
+
let latestPlan;
|
|
218
|
+
const resolveOptions = async (refreshToken, progress) => {
|
|
219
|
+
this._renderedPromptOptions = [];
|
|
220
|
+
const publishOptions = options => {
|
|
221
|
+
if (!this._hasRenderedPromptOptionsChanged(options)) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
if (progress?.({
|
|
225
|
+
kind: "resolved",
|
|
226
|
+
options
|
|
227
|
+
}) !== false) {
|
|
228
|
+
this._renderedPromptOptions = options;
|
|
229
|
+
}
|
|
230
|
+
};
|
|
231
|
+
publishOptions(this._createPromptOptions([]));
|
|
232
|
+
latestPlan = await this._resolveGitHubPromptOptionsWithFallback(refreshToken, publishOptions);
|
|
233
|
+
publishOptions(latestPlan.options);
|
|
234
|
+
return {
|
|
235
|
+
kind: "resolved",
|
|
236
|
+
options: latestPlan.options
|
|
237
|
+
};
|
|
238
|
+
};
|
|
239
|
+
if (composer.setPromptOptionsController && composer.refreshPromptOptions) {
|
|
240
|
+
const controller = {
|
|
241
|
+
resolve: resolveOptions,
|
|
242
|
+
onDidSelectOption: option => this._reportPromptOptionInteraction("selected", option),
|
|
243
|
+
onDidClose: () => this._reportPromptOptionInteraction("closed")
|
|
244
|
+
};
|
|
245
|
+
composer.setPromptOptionsController(controller);
|
|
246
|
+
this._logService.info(`${LOG_PREFIX} Showing prompt option loading skeletons.`);
|
|
247
|
+
const shown = await composer.refreshPromptOptions(token);
|
|
248
|
+
const fallbackReason = configuredFallbackReason ?? latestPlan?.fallbackReason ?? (token.isCancellationRequested ? "requestFailed" : "noCandidate");
|
|
249
|
+
this._logService.info(
|
|
250
|
+
`${LOG_PREFIX} Prompt options completed with shown=${shown} and fallback reason '${fallbackReason}'.`
|
|
251
|
+
);
|
|
252
|
+
this._reportStrategy(configuredVariation, "options", fallbackReason, shown, latestPlan?.lookup);
|
|
253
|
+
return shown;
|
|
254
|
+
}
|
|
255
|
+
if (!composer.showPromptOptions({
|
|
256
|
+
kind: "loading"
|
|
257
|
+
})) {
|
|
258
|
+
this._logService.warn(
|
|
259
|
+
`${LOG_PREFIX} Skipping prompt options because the active new-session composer cannot show them.`
|
|
260
|
+
);
|
|
261
|
+
this._reportStrategy(configuredVariation, "options", "noComposer", false);
|
|
262
|
+
return false;
|
|
263
|
+
}
|
|
264
|
+
this._logService.info(`${LOG_PREFIX} Showing prompt option loading skeletons.`);
|
|
265
|
+
const state = await resolveOptions(token);
|
|
266
|
+
if (token.isCancellationRequested || this._newSessionComposerService.activeComposer.get() !== composer || this._sessionsService.activeSession.get()?.isCreated.get()) {
|
|
267
|
+
composer.showPromptOptions(undefined);
|
|
268
|
+
this._logService.trace(
|
|
269
|
+
`${LOG_PREFIX} Prompt option resolution was cancelled or its composer is no longer active.`
|
|
270
|
+
);
|
|
271
|
+
this._reportStrategy(
|
|
272
|
+
configuredVariation,
|
|
273
|
+
"options",
|
|
274
|
+
configuredFallbackReason ?? latestPlan?.fallbackReason ?? "requestFailed",
|
|
275
|
+
false,
|
|
276
|
+
latestPlan?.lookup
|
|
277
|
+
);
|
|
278
|
+
return false;
|
|
279
|
+
}
|
|
280
|
+
const shown = composer.showPromptOptions(state);
|
|
281
|
+
const fallbackReason = configuredFallbackReason ?? latestPlan?.fallbackReason ?? "noCandidate";
|
|
282
|
+
this._logService.info(
|
|
283
|
+
`${LOG_PREFIX} Prompt options completed with shown=${shown} and fallback reason '${fallbackReason}'.`
|
|
284
|
+
);
|
|
285
|
+
this._reportStrategy(configuredVariation, "options", fallbackReason, shown, latestPlan?.lookup);
|
|
286
|
+
return shown;
|
|
287
|
+
}
|
|
288
|
+
_hasRenderedPromptOptionsChanged(options) {
|
|
289
|
+
return this._renderedPromptOptions.length !== options.length || ( options.some((option, index) => this._renderedPromptOptions[index]?.id !== option.id));
|
|
290
|
+
}
|
|
291
|
+
_getActiveComposer() {
|
|
292
|
+
const activeSession = this._sessionsService.activeSession.get();
|
|
293
|
+
if (activeSession?.isCreated.get()) {
|
|
294
|
+
return undefined;
|
|
295
|
+
}
|
|
296
|
+
return this._newSessionComposerService.activeComposer.get();
|
|
297
|
+
}
|
|
298
|
+
async _resolveGitHubPromptOptionsWithFallback(token, reportOptions) {
|
|
299
|
+
this._logService.info(
|
|
300
|
+
`${LOG_PREFIX} Starting GitHub prompt option lookup with a ${this._gitHubLookupTimeouts.totalMs}ms total timeout.`
|
|
301
|
+
);
|
|
302
|
+
const operationCts = ( new CancellationTokenSource(token));
|
|
303
|
+
const diagnostics = ( new GitHubLookupDiagnostics());
|
|
304
|
+
let latestProgress;
|
|
305
|
+
let timedOut = false;
|
|
306
|
+
const createTimeoutPlan = () => {
|
|
307
|
+
const candidates = latestProgress && this._isCurrentRepositoryContext(latestProgress.context) ? [...latestProgress.issueCandidates, ...latestProgress.pullRequestCandidates] : [];
|
|
308
|
+
return this._createPromptOptionsPlan(
|
|
309
|
+
candidates,
|
|
310
|
+
candidates.length === PROMPT_OPTION_COUNT ? "none" : "timeout",
|
|
311
|
+
diagnostics
|
|
312
|
+
);
|
|
313
|
+
};
|
|
314
|
+
try {
|
|
315
|
+
const result = await raceTimeout(
|
|
316
|
+
this._resolveGitHubPromptOptions(operationCts.token, diagnostics, progress => {
|
|
317
|
+
latestProgress = progress;
|
|
318
|
+
reportOptions?.(
|
|
319
|
+
this._createPromptOptions([...progress.issueCandidates, ...progress.pullRequestCandidates])
|
|
320
|
+
);
|
|
321
|
+
}),
|
|
322
|
+
this._gitHubLookupTimeouts.totalMs,
|
|
323
|
+
() => {
|
|
324
|
+
timedOut = true;
|
|
325
|
+
diagnostics.markTimedOut();
|
|
326
|
+
this._logService.warn(
|
|
327
|
+
`${LOG_PREFIX} GitHub prompt option lookup timed out after ${this._gitHubLookupTimeouts.totalMs}ms; filling with standard options.`
|
|
328
|
+
);
|
|
329
|
+
operationCts.cancel();
|
|
330
|
+
}
|
|
331
|
+
);
|
|
332
|
+
if (timedOut || !result) {
|
|
333
|
+
return createTimeoutPlan();
|
|
334
|
+
}
|
|
335
|
+
if (result.kind === "fallback") {
|
|
336
|
+
return this._createPromptOptionsPlan([], result.reason, diagnostics);
|
|
337
|
+
}
|
|
338
|
+
const candidates = [...result.issueCandidates, ...result.pullRequestCandidates];
|
|
339
|
+
const fallbackReason = candidates.slice(0, PROMPT_OPTION_COUNT).length === PROMPT_OPTION_COUNT ? "none" : getLookupFallbackReason(result.failures);
|
|
340
|
+
return this._createPromptOptionsPlan(candidates, fallbackReason, diagnostics);
|
|
341
|
+
} catch (error) {
|
|
342
|
+
if (isCancellationError(error) && timedOut) {
|
|
343
|
+
return createTimeoutPlan();
|
|
344
|
+
}
|
|
345
|
+
if (isCancellationError(error) && token.isCancellationRequested) {
|
|
346
|
+
this._logService.trace(
|
|
347
|
+
`${LOG_PREFIX} GitHub prompt option lookup was cancelled by the onboarding flow.`
|
|
348
|
+
);
|
|
349
|
+
return this._createPromptOptionsPlan([], "requestFailed", diagnostics);
|
|
350
|
+
}
|
|
351
|
+
if (error instanceof GitHubAuthenticationError) {
|
|
352
|
+
this._logService.warn(
|
|
353
|
+
`${LOG_PREFIX} No existing GitHub authentication session is available; filling with standard options without requesting sign-in.`
|
|
354
|
+
);
|
|
355
|
+
return this._createPromptOptionsPlan([], "noAuthentication", diagnostics);
|
|
356
|
+
}
|
|
357
|
+
this._logService.error(
|
|
358
|
+
`${LOG_PREFIX} GitHub prompt option lookup failed; filling with standard options.`,
|
|
359
|
+
error
|
|
360
|
+
);
|
|
361
|
+
return this._createPromptOptionsPlan([], "requestFailed", diagnostics);
|
|
362
|
+
} finally {
|
|
363
|
+
operationCts.dispose();
|
|
364
|
+
}
|
|
365
|
+
}
|
|
366
|
+
async _resolveGitHubPromptOptions(token, diagnostics, reportProgress) {
|
|
367
|
+
while (!token.isCancellationRequested) {
|
|
368
|
+
diagnostics.begin("repository");
|
|
369
|
+
const repositoryStartTime = Date.now();
|
|
370
|
+
const context = await this._resolveGitHubRepository(token);
|
|
371
|
+
diagnostics.record(
|
|
372
|
+
"repository",
|
|
373
|
+
context ? "success" : "skipped",
|
|
374
|
+
Date.now() - repositoryStartTime
|
|
375
|
+
);
|
|
376
|
+
if (!context) {
|
|
377
|
+
this._logService.warn(`${LOG_PREFIX} Could not resolve a GitHub repository for prompt options.`);
|
|
378
|
+
return {
|
|
379
|
+
kind: "fallback",
|
|
380
|
+
reason: "noRepository"
|
|
381
|
+
};
|
|
382
|
+
}
|
|
383
|
+
const lookupCts = ( new CancellationTokenSource(token));
|
|
384
|
+
try {
|
|
385
|
+
const owner = context.repository.owner;
|
|
386
|
+
const repo = context.repository.repo;
|
|
387
|
+
let issueResult;
|
|
388
|
+
let pullRequestResult;
|
|
389
|
+
const publishProgress = () => {
|
|
390
|
+
if (this._isCurrentRepositoryContext(context)) {
|
|
391
|
+
reportProgress({
|
|
392
|
+
context,
|
|
393
|
+
issueCandidates: issueResult?.candidates ?? [],
|
|
394
|
+
pullRequestCandidates: pullRequestResult?.candidates ?? [],
|
|
395
|
+
failures: [...(issueResult?.failures ?? []), ...(pullRequestResult?.failures ?? [])]
|
|
396
|
+
});
|
|
397
|
+
}
|
|
398
|
+
};
|
|
399
|
+
publishProgress();
|
|
400
|
+
const resolveIssues = async () => {
|
|
401
|
+
issueResult = await this._resolveIssuePromptOptionCandidates(owner, repo, lookupCts.token, diagnostics, candidates => {
|
|
402
|
+
issueResult = {
|
|
403
|
+
candidates,
|
|
404
|
+
failures: []
|
|
405
|
+
};
|
|
406
|
+
publishProgress();
|
|
407
|
+
});
|
|
408
|
+
publishProgress();
|
|
409
|
+
return issueResult;
|
|
410
|
+
};
|
|
411
|
+
const resolvePullRequests = async () => {
|
|
412
|
+
pullRequestResult = await this._resolvePullRequestPromptOptionCandidates(owner, repo, lookupCts.token, diagnostics, candidates => {
|
|
413
|
+
pullRequestResult = {
|
|
414
|
+
candidates,
|
|
415
|
+
failures: []
|
|
416
|
+
};
|
|
417
|
+
publishProgress();
|
|
418
|
+
});
|
|
419
|
+
publishProgress();
|
|
420
|
+
return pullRequestResult;
|
|
421
|
+
};
|
|
422
|
+
const [issues, pullRequests] = await Promise.all([resolveIssues(), resolvePullRequests()]);
|
|
423
|
+
if (!this._isCurrentRepositoryContext(context)) {
|
|
424
|
+
this._logService.info(
|
|
425
|
+
`${LOG_PREFIX} The selected workspace changed during prompt option lookup; retrying for the current workspace.`
|
|
426
|
+
);
|
|
427
|
+
continue;
|
|
428
|
+
}
|
|
429
|
+
return {
|
|
430
|
+
kind: "candidates",
|
|
431
|
+
issueCandidates: issues.candidates,
|
|
432
|
+
pullRequestCandidates: pullRequests.candidates,
|
|
433
|
+
failures: [...issues.failures, ...pullRequests.failures]
|
|
434
|
+
};
|
|
435
|
+
} finally {
|
|
436
|
+
lookupCts.dispose(true);
|
|
437
|
+
}
|
|
438
|
+
}
|
|
439
|
+
return {
|
|
440
|
+
kind: "fallback",
|
|
441
|
+
reason: "noRepository"
|
|
442
|
+
};
|
|
443
|
+
}
|
|
444
|
+
async _resolveIssuePromptOptionCandidates(owner, repo, token, diagnostics, reportCandidates = () => undefined) {
|
|
445
|
+
const outcome = await this._resolveIssueCandidates(
|
|
446
|
+
owner,
|
|
447
|
+
repo,
|
|
448
|
+
token,
|
|
449
|
+
diagnostics,
|
|
450
|
+
issues => reportCandidates(toIssuePromptOptionCandidates(issues))
|
|
451
|
+
);
|
|
452
|
+
if (outcome.kind === "failure") {
|
|
453
|
+
return {
|
|
454
|
+
candidates: [],
|
|
455
|
+
failures: [outcome.reason]
|
|
456
|
+
};
|
|
457
|
+
}
|
|
458
|
+
return {
|
|
459
|
+
candidates: toIssuePromptOptionCandidates(outcome.value),
|
|
460
|
+
failures: []
|
|
461
|
+
};
|
|
462
|
+
}
|
|
463
|
+
async _resolvePullRequestPromptOptionCandidates(owner, repo, token, diagnostics, reportCandidates = () => undefined) {
|
|
464
|
+
const summary = await this._runGitHubLookup(
|
|
465
|
+
"authored pull request summaries",
|
|
466
|
+
this._gitHubLookupTimeouts.summaryMs,
|
|
467
|
+
token,
|
|
468
|
+
lookupToken => this._gitHubService.getRecentAuthoredPullRequests(owner, repo, lookupToken),
|
|
469
|
+
"prSummary",
|
|
470
|
+
diagnostics
|
|
471
|
+
);
|
|
472
|
+
if (summary.kind === "failure") {
|
|
473
|
+
return {
|
|
474
|
+
candidates: [],
|
|
475
|
+
failures: [summary.reason]
|
|
476
|
+
};
|
|
477
|
+
}
|
|
478
|
+
const pullRequests = [...summary.value].sort(compareUpdatedAtDescending);
|
|
479
|
+
const directCandidates = pullRequests.map((pullRequest, index) => ({
|
|
480
|
+
index,
|
|
481
|
+
candidate: toDirectPullRequestCandidate(pullRequest)
|
|
482
|
+
})).filter(entry => entry.candidate !== undefined);
|
|
483
|
+
const secondDirectCandidateIndex = directCandidates[1]?.index ?? pullRequests.length;
|
|
484
|
+
const reviewPullRequests = pullRequests.slice(0, secondDirectCandidateIndex).filter(pullRequest => !toDirectPullRequestCandidate(pullRequest));
|
|
485
|
+
const stableCandidates = getCandidatesInPullRequestOrder(pullRequests.slice(
|
|
486
|
+
0,
|
|
487
|
+
reviewPullRequests[0] ? pullRequests.indexOf(reviewPullRequests[0]) : secondDirectCandidateIndex
|
|
488
|
+
), directCandidates.map(entry => entry.candidate)).slice(0, 2);
|
|
489
|
+
if (stableCandidates.length > 0) {
|
|
490
|
+
reportCandidates(stableCandidates);
|
|
491
|
+
}
|
|
492
|
+
const reviewLookup = await this._resolveReviewCandidates(owner, repo, reviewPullRequests, token, diagnostics);
|
|
493
|
+
const candidates = getCandidatesInPullRequestOrder(pullRequests, [
|
|
494
|
+
...directCandidates.map(entry => entry.candidate),
|
|
495
|
+
...reviewLookup.candidates
|
|
496
|
+
]).slice(0, 2);
|
|
497
|
+
reportCandidates(candidates);
|
|
498
|
+
return {
|
|
499
|
+
candidates,
|
|
500
|
+
failures: reviewLookup.failures
|
|
501
|
+
};
|
|
502
|
+
}
|
|
503
|
+
async _resolveGitHubPromptWithFallback(token) {
|
|
504
|
+
this._logService.info(
|
|
505
|
+
`${LOG_PREFIX} Starting GitHub prompt lookup with a ${this._gitHubLookupTimeouts.totalMs}ms total timeout.`
|
|
506
|
+
);
|
|
507
|
+
const operationCts = ( new CancellationTokenSource(token));
|
|
508
|
+
let timedOut = false;
|
|
509
|
+
try {
|
|
510
|
+
const result = await raceTimeout(
|
|
511
|
+
this._resolveGitHubPrompt(operationCts.token),
|
|
512
|
+
this._gitHubLookupTimeouts.totalMs,
|
|
513
|
+
() => {
|
|
514
|
+
timedOut = true;
|
|
515
|
+
this._logService.warn(
|
|
516
|
+
`${LOG_PREFIX} GitHub prompt lookup timed out after ${this._gitHubLookupTimeouts.totalMs}ms; using the prompt variation.`
|
|
517
|
+
);
|
|
518
|
+
operationCts.cancel();
|
|
519
|
+
}
|
|
520
|
+
);
|
|
521
|
+
if (timedOut) {
|
|
522
|
+
return this._resolvePrompt("timeout");
|
|
523
|
+
}
|
|
524
|
+
if (!result) {
|
|
525
|
+
return this._resolvePrompt("timeout");
|
|
526
|
+
}
|
|
527
|
+
if (result.kind === "fallback") {
|
|
528
|
+
this._logService.warn(
|
|
529
|
+
`${LOG_PREFIX} GitHub prompt lookup requested fallback '${result.reason}'; using the prompt variation.`
|
|
530
|
+
);
|
|
531
|
+
return this._resolvePrompt(result.reason);
|
|
532
|
+
}
|
|
533
|
+
this._logService.info(
|
|
534
|
+
`${LOG_PREFIX} Selected GitHub candidate strategy '${result.candidate.strategy}'.`
|
|
535
|
+
);
|
|
536
|
+
return this._createGitHubPrompt(result.candidate);
|
|
537
|
+
} catch (error) {
|
|
538
|
+
if (isCancellationError(error) && timedOut) {
|
|
539
|
+
return this._resolvePrompt("timeout");
|
|
540
|
+
}
|
|
541
|
+
if (isCancellationError(error) && token.isCancellationRequested) {
|
|
542
|
+
this._logService.trace(`${LOG_PREFIX} GitHub prompt lookup was cancelled by the onboarding flow.`);
|
|
543
|
+
return this._resolvePrompt("requestFailed");
|
|
544
|
+
}
|
|
545
|
+
if (error instanceof GitHubAuthenticationError) {
|
|
546
|
+
this._logService.warn(
|
|
547
|
+
`${LOG_PREFIX} No existing GitHub authentication session is available; using the prompt variation without requesting sign-in.`
|
|
548
|
+
);
|
|
549
|
+
return this._resolvePrompt("noAuthentication");
|
|
550
|
+
}
|
|
551
|
+
this._logService.error(
|
|
552
|
+
`${LOG_PREFIX} GitHub prompt lookup failed; using the prompt variation.`,
|
|
553
|
+
error
|
|
554
|
+
);
|
|
555
|
+
return this._resolvePrompt("requestFailed");
|
|
556
|
+
} finally {
|
|
557
|
+
operationCts.dispose();
|
|
558
|
+
}
|
|
559
|
+
}
|
|
560
|
+
async _resolveGitHubPrompt(token) {
|
|
561
|
+
while (!token.isCancellationRequested) {
|
|
562
|
+
const context = await this._resolveGitHubRepository(token);
|
|
563
|
+
if (!context) {
|
|
564
|
+
this._logService.warn(
|
|
565
|
+
`${LOG_PREFIX} Could not resolve a GitHub repository for the selected workspace.`
|
|
566
|
+
);
|
|
567
|
+
return {
|
|
568
|
+
kind: "fallback",
|
|
569
|
+
reason: "noRepository"
|
|
570
|
+
};
|
|
571
|
+
}
|
|
572
|
+
const lookupCts = ( new CancellationTokenSource(token));
|
|
573
|
+
const owner = context.repository.owner;
|
|
574
|
+
const repo = context.repository.repo;
|
|
575
|
+
this._logService.info(
|
|
576
|
+
`${LOG_PREFIX} Starting independent GitHub lookups for '${owner}/${repo}'.`
|
|
577
|
+
);
|
|
578
|
+
const issuesLookup = this._resolveIssueCandidates(owner, repo, lookupCts.token);
|
|
579
|
+
try {
|
|
580
|
+
const pullRequestsLookup = await this._runGitHubLookup(
|
|
581
|
+
"authored pull request summaries",
|
|
582
|
+
this._gitHubLookupTimeouts.summaryMs,
|
|
583
|
+
lookupCts.token,
|
|
584
|
+
lookupToken => this._gitHubService.getRecentAuthoredPullRequests(owner, repo, lookupToken)
|
|
585
|
+
);
|
|
586
|
+
if (!this._isCurrentRepositoryContext(context)) {
|
|
587
|
+
this._logService.info(
|
|
588
|
+
`${LOG_PREFIX} The selected workspace changed during the GitHub lookup; retrying for the current workspace.`
|
|
589
|
+
);
|
|
590
|
+
continue;
|
|
591
|
+
}
|
|
592
|
+
const failures = [];
|
|
593
|
+
if (pullRequestsLookup.kind === "success") {
|
|
594
|
+
const pullRequests = [...pullRequestsLookup.value].sort(compareUpdatedAtDescending);
|
|
595
|
+
const directCandidates = pullRequests.map((pullRequest, index) => ({
|
|
596
|
+
index,
|
|
597
|
+
candidate: toDirectPullRequestCandidate(pullRequest)
|
|
598
|
+
})).filter(entry => entry.candidate !== undefined);
|
|
599
|
+
this._logService.info(
|
|
600
|
+
`${LOG_PREFIX} Pull request summary lookup returned ${pullRequests.length} open authored pull request(s), including ${pullRequests.filter(pullRequest => pullRequest.hasMergeConflicts).length} with merge conflicts and ${pullRequests.filter(isFailingPullRequest).length} with failing CI.`
|
|
601
|
+
);
|
|
602
|
+
if (directCandidates[0]?.index === 0) {
|
|
603
|
+
return {
|
|
604
|
+
kind: "candidate",
|
|
605
|
+
candidate: directCandidates[0].candidate
|
|
606
|
+
};
|
|
607
|
+
}
|
|
608
|
+
const firstDirectCandidateIndex = directCandidates[0]?.index ?? pullRequests.length;
|
|
609
|
+
const reviewPullRequests = pullRequests.slice(0, firstDirectCandidateIndex).filter(pullRequest => !toDirectPullRequestCandidate(pullRequest));
|
|
610
|
+
const reviewLookup = await this._resolveReviewCandidates(owner, repo, reviewPullRequests, lookupCts.token);
|
|
611
|
+
failures.push(...reviewLookup.failures);
|
|
612
|
+
if (!this._isCurrentRepositoryContext(context)) {
|
|
613
|
+
this._logService.info(
|
|
614
|
+
`${LOG_PREFIX} The selected workspace changed during review lookup; retrying for the current workspace.`
|
|
615
|
+
);
|
|
616
|
+
continue;
|
|
617
|
+
}
|
|
618
|
+
const candidate = getCandidatesInPullRequestOrder(pullRequests, [
|
|
619
|
+
...directCandidates.map(entry => entry.candidate),
|
|
620
|
+
...reviewLookup.candidates
|
|
621
|
+
])[0];
|
|
622
|
+
if (candidate) {
|
|
623
|
+
return {
|
|
624
|
+
kind: "candidate",
|
|
625
|
+
candidate
|
|
626
|
+
};
|
|
627
|
+
}
|
|
628
|
+
} else {
|
|
629
|
+
failures.push(pullRequestsLookup.reason);
|
|
630
|
+
}
|
|
631
|
+
const issues = await issuesLookup;
|
|
632
|
+
if (!this._isCurrentRepositoryContext(context)) {
|
|
633
|
+
this._logService.info(
|
|
634
|
+
`${LOG_PREFIX} The selected workspace changed during issue lookup; retrying for the current workspace.`
|
|
635
|
+
);
|
|
636
|
+
continue;
|
|
637
|
+
}
|
|
638
|
+
if (issues.kind === "success") {
|
|
639
|
+
this._logService.info(
|
|
640
|
+
`${LOG_PREFIX} Issue lookup returned ${issues.value.length} unlinked open issue(s) assigned to the user.`
|
|
641
|
+
);
|
|
642
|
+
const issue = [...issues.value].sort(compareUpdatedAtDescending)[0];
|
|
643
|
+
if (issue) {
|
|
644
|
+
return {
|
|
645
|
+
kind: "candidate",
|
|
646
|
+
candidate: {
|
|
647
|
+
number: issue.number,
|
|
648
|
+
title: issue.title,
|
|
649
|
+
url: issue.url,
|
|
650
|
+
strategy: "githubIssue"
|
|
651
|
+
}
|
|
652
|
+
};
|
|
653
|
+
}
|
|
654
|
+
} else {
|
|
655
|
+
failures.push(issues.reason);
|
|
656
|
+
}
|
|
657
|
+
this._logService.warn(
|
|
658
|
+
`${LOG_PREFIX} No eligible GitHub candidate was available from the lookups that completed in time.`
|
|
659
|
+
);
|
|
660
|
+
return {
|
|
661
|
+
kind: "fallback",
|
|
662
|
+
reason: getLookupFallbackReason(failures)
|
|
663
|
+
};
|
|
664
|
+
} finally {
|
|
665
|
+
lookupCts.dispose(true);
|
|
666
|
+
}
|
|
667
|
+
}
|
|
668
|
+
this._logService.trace(`${LOG_PREFIX} GitHub prompt lookup stopped because it was cancelled.`);
|
|
669
|
+
return {
|
|
670
|
+
kind: "fallback",
|
|
671
|
+
reason: "noRepository"
|
|
672
|
+
};
|
|
673
|
+
}
|
|
674
|
+
async _resolveIssueCandidates(owner, repo, token, diagnostics, reportIssues) {
|
|
675
|
+
const issues = await this._runGitHubLookup(
|
|
676
|
+
"assigned issue summaries",
|
|
677
|
+
this._gitHubLookupTimeouts.summaryMs,
|
|
678
|
+
token,
|
|
679
|
+
lookupToken => this._gitHubService.getRecentAssignedIssues(owner, repo, lookupToken),
|
|
680
|
+
"issueSummary",
|
|
681
|
+
diagnostics
|
|
682
|
+
);
|
|
683
|
+
if (issues.kind === "failure" || issues.value.length === 0) {
|
|
684
|
+
diagnostics?.record("issueLinkage", "skipped", 0);
|
|
685
|
+
return issues;
|
|
686
|
+
}
|
|
687
|
+
reportIssues?.(issues.value);
|
|
688
|
+
const linkedIssues = await this._runGitHubLookup(
|
|
689
|
+
"issue pull request linkage",
|
|
690
|
+
this._gitHubLookupTimeouts.linkageMs,
|
|
691
|
+
token,
|
|
692
|
+
lookupToken => this._gitHubService.getIssuesWithLinkedPullRequests(owner, repo, issues.value.map(issue => issue.number), lookupToken),
|
|
693
|
+
"issueLinkage",
|
|
694
|
+
diagnostics
|
|
695
|
+
);
|
|
696
|
+
if (linkedIssues.kind === "success") {
|
|
697
|
+
const unlinkedIssues = issues.value.filter(issue => !( linkedIssues.value.has(issue.number)));
|
|
698
|
+
this._logService.info(
|
|
699
|
+
`${LOG_PREFIX} Issue linkage lookup excluded ${issues.value.length - unlinkedIssues.length} issue(s) with related pull requests.`
|
|
700
|
+
);
|
|
701
|
+
return {
|
|
702
|
+
kind: "success",
|
|
703
|
+
value: unlinkedIssues
|
|
704
|
+
};
|
|
705
|
+
}
|
|
706
|
+
if (linkedIssues.reason === "cancelled" && token.isCancellationRequested) {
|
|
707
|
+
return linkedIssues;
|
|
708
|
+
}
|
|
709
|
+
this._logService.warn(
|
|
710
|
+
`${LOG_PREFIX} Issue linkage was unavailable (${linkedIssues.reason}); treating all assigned issues as having no related pull request.`
|
|
711
|
+
);
|
|
712
|
+
return issues;
|
|
713
|
+
}
|
|
714
|
+
async _resolveReviewCandidates(owner, repo, pullRequests, token, diagnostics) {
|
|
715
|
+
const eligiblePullRequests = pullRequests.filter(pullRequest => !!pullRequest.latestCommitAt);
|
|
716
|
+
if (eligiblePullRequests.length === 0) {
|
|
717
|
+
this._logService.info(
|
|
718
|
+
`${LOG_PREFIX} No pull requests have a latest commit timestamp, so review-thread lookup is unnecessary.`
|
|
719
|
+
);
|
|
720
|
+
diagnostics?.record("prReview", "skipped", 0);
|
|
721
|
+
return {
|
|
722
|
+
candidates: [],
|
|
723
|
+
failures: []
|
|
724
|
+
};
|
|
725
|
+
}
|
|
726
|
+
this._logService.info(
|
|
727
|
+
`${LOG_PREFIX} Starting ${eligiblePullRequests.length} independent review-thread lookup(s).`
|
|
728
|
+
);
|
|
729
|
+
const results = await Promise.all(eligiblePullRequests.map(async pullRequest => {
|
|
730
|
+
const outcome = await this._runGitHubLookup(
|
|
731
|
+
`review threads for pull request #${pullRequest.number}`,
|
|
732
|
+
this._gitHubLookupTimeouts.reviewMs,
|
|
733
|
+
token,
|
|
734
|
+
lookupToken => this._gitHubService.getPullRequestReviewThreads(owner, repo, pullRequest.number, lookupToken),
|
|
735
|
+
"prReview",
|
|
736
|
+
diagnostics
|
|
737
|
+
);
|
|
738
|
+
if (outcome.kind === "success") {
|
|
739
|
+
const completedPullRequest = {
|
|
740
|
+
...pullRequest,
|
|
741
|
+
reviewThreads: outcome.value
|
|
742
|
+
};
|
|
743
|
+
return {
|
|
744
|
+
pullRequest: completedPullRequest,
|
|
745
|
+
outcome
|
|
746
|
+
};
|
|
747
|
+
}
|
|
748
|
+
return {
|
|
749
|
+
pullRequest,
|
|
750
|
+
outcome
|
|
751
|
+
};
|
|
752
|
+
}));
|
|
753
|
+
const completedPullRequests = [];
|
|
754
|
+
const failures = [];
|
|
755
|
+
for (const result of results) {
|
|
756
|
+
if (result.outcome.kind === "success") {
|
|
757
|
+
completedPullRequests.push(result.pullRequest);
|
|
758
|
+
} else {
|
|
759
|
+
failures.push(result.outcome.reason);
|
|
760
|
+
}
|
|
761
|
+
}
|
|
762
|
+
const reviewPullRequests = completedPullRequests.sort(compareUpdatedAtDescending).filter(hasUnaddressedReviewComments);
|
|
763
|
+
this._logService.info(
|
|
764
|
+
`${LOG_PREFIX} Review-thread lookups completed for ${completedPullRequests.length} of ${eligiblePullRequests.length} pull request(s); ${reviewPullRequests.length} eligible pull request(s) were found.`
|
|
765
|
+
);
|
|
766
|
+
return {
|
|
767
|
+
candidates: reviewPullRequests.map(pullRequest => toCandidate(pullRequest, "githubReviewComments")),
|
|
768
|
+
failures
|
|
769
|
+
};
|
|
770
|
+
}
|
|
771
|
+
async _runGitHubLookup(label, timeoutMs, token, lookup, stage, diagnostics) {
|
|
772
|
+
const lookupCts = ( new CancellationTokenSource(token));
|
|
773
|
+
const startTime = Date.now();
|
|
774
|
+
let timedOut = false;
|
|
775
|
+
this._logService.trace(`${LOG_PREFIX} Starting ${label} lookup with a ${timeoutMs}ms timeout.`);
|
|
776
|
+
const record = outcome => {
|
|
777
|
+
const durationMs = Date.now() - startTime;
|
|
778
|
+
if (stage) {
|
|
779
|
+
diagnostics?.record(stage, outcome, durationMs);
|
|
780
|
+
}
|
|
781
|
+
return durationMs;
|
|
782
|
+
};
|
|
783
|
+
if (stage) {
|
|
784
|
+
diagnostics?.begin(stage);
|
|
785
|
+
}
|
|
786
|
+
try {
|
|
787
|
+
const value = await raceTimeout(lookup(lookupCts.token), timeoutMs, () => {
|
|
788
|
+
timedOut = true;
|
|
789
|
+
this._logService.warn(
|
|
790
|
+
`${LOG_PREFIX} ${capitalize(label)} lookup timed out after ${timeoutMs}ms.`
|
|
791
|
+
);
|
|
792
|
+
lookupCts.cancel();
|
|
793
|
+
});
|
|
794
|
+
if (timedOut || value === undefined) {
|
|
795
|
+
record("timeout");
|
|
796
|
+
return {
|
|
797
|
+
kind: "failure",
|
|
798
|
+
reason: "timeout"
|
|
799
|
+
};
|
|
800
|
+
}
|
|
801
|
+
this._logService.info(
|
|
802
|
+
`${LOG_PREFIX} ${capitalize(label)} lookup completed in ${record("success")}ms.`
|
|
803
|
+
);
|
|
804
|
+
return {
|
|
805
|
+
kind: "success",
|
|
806
|
+
value
|
|
807
|
+
};
|
|
808
|
+
} catch (error) {
|
|
809
|
+
if (timedOut) {
|
|
810
|
+
record("timeout");
|
|
811
|
+
return {
|
|
812
|
+
kind: "failure",
|
|
813
|
+
reason: "timeout"
|
|
814
|
+
};
|
|
815
|
+
}
|
|
816
|
+
if (error instanceof GitHubAuthenticationError) {
|
|
817
|
+
this._logService.warn(
|
|
818
|
+
`${LOG_PREFIX} ${capitalize(label)} lookup could not run because no existing GitHub authentication session is available.`
|
|
819
|
+
);
|
|
820
|
+
record("noAuthentication");
|
|
821
|
+
return {
|
|
822
|
+
kind: "failure",
|
|
823
|
+
reason: "noAuthentication"
|
|
824
|
+
};
|
|
825
|
+
}
|
|
826
|
+
if (isCancellationError(error) && token.isCancellationRequested) {
|
|
827
|
+
this._logService.trace(`${LOG_PREFIX} ${capitalize(label)} lookup was cancelled.`);
|
|
828
|
+
record("cancelled");
|
|
829
|
+
return {
|
|
830
|
+
kind: "failure",
|
|
831
|
+
reason: "cancelled"
|
|
832
|
+
};
|
|
833
|
+
}
|
|
834
|
+
this._logService.error(
|
|
835
|
+
`${LOG_PREFIX} ${capitalize(label)} lookup failed after ${record("requestFailed")}ms.`,
|
|
836
|
+
error
|
|
837
|
+
);
|
|
838
|
+
return {
|
|
839
|
+
kind: "failure",
|
|
840
|
+
reason: "requestFailed"
|
|
841
|
+
};
|
|
842
|
+
} finally {
|
|
843
|
+
lookupCts.dispose();
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
async _resolveGitHubRepository(token) {
|
|
847
|
+
while (!token.isCancellationRequested) {
|
|
848
|
+
const activeSession = this._sessionsService.activeSession.get();
|
|
849
|
+
if (!activeSession) {
|
|
850
|
+
this._logService.trace(
|
|
851
|
+
`${LOG_PREFIX} No active draft session is available for repository resolution.`
|
|
852
|
+
);
|
|
853
|
+
return undefined;
|
|
854
|
+
}
|
|
855
|
+
if (activeSession.isCreated.get()) {
|
|
856
|
+
this._logService.trace(
|
|
857
|
+
`${LOG_PREFIX} The active session is already created, so the V3 new-session prompt cannot resolve its repository.`
|
|
858
|
+
);
|
|
859
|
+
return undefined;
|
|
860
|
+
}
|
|
861
|
+
const workspace = activeSession.workspace.get();
|
|
862
|
+
const folder = workspace?.folders[0];
|
|
863
|
+
const enterpriseHost = this._gitHubService.enterpriseHost;
|
|
864
|
+
const supportedHosts = enterpriseHost ? [enterpriseHost] : undefined;
|
|
865
|
+
this._logWorkspaceSnapshot(activeSession);
|
|
866
|
+
if (!workspace || !folder) {
|
|
867
|
+
this._logService.trace(`${LOG_PREFIX} The active draft has no primary workspace folder.`);
|
|
868
|
+
return undefined;
|
|
869
|
+
}
|
|
870
|
+
const gitHubInfo = folder.gitRepository?.gitHubInfo.get();
|
|
871
|
+
if (!enterpriseHost && gitHubInfo) {
|
|
872
|
+
this._logService.info(
|
|
873
|
+
`${LOG_PREFIX} Resolved GitHub repository '${gitHubInfo.owner}/${gitHubInfo.repo}' from session metadata.`
|
|
874
|
+
);
|
|
875
|
+
return this._createRepositoryContext(activeSession, ( workspace.uri.toString()), ( folder.workingDirectory.toString()), {
|
|
876
|
+
owner: gitHubInfo.owner,
|
|
877
|
+
repo: gitHubInfo.repo
|
|
878
|
+
});
|
|
879
|
+
}
|
|
880
|
+
const repositoryFromUri = enterpriseHost ? undefined : getGitHubRepositoryFromUri(folder.root) ?? getGitHubRepositoryFromUri(folder.workingDirectory) ?? (folder.gitRepository ? getGitHubRepositoryFromUri(folder.gitRepository.uri) : undefined);
|
|
881
|
+
if (repositoryFromUri) {
|
|
882
|
+
this._logService.info(
|
|
883
|
+
`${LOG_PREFIX} Resolved GitHub repository '${repositoryFromUri.owner}/${repositoryFromUri.repo}' from the workspace URI.`
|
|
884
|
+
);
|
|
885
|
+
return this._createRepositoryContext(activeSession, ( workspace.uri.toString()), ( folder.workingDirectory.toString()), repositoryFromUri);
|
|
886
|
+
}
|
|
887
|
+
try {
|
|
888
|
+
const repositoryFromConfig = await resolveGitHubRepositoryFromGitConfig(this._fileService, folder.workingDirectory, supportedHosts);
|
|
889
|
+
if (repositoryFromConfig) {
|
|
890
|
+
this._logService.info(
|
|
891
|
+
`${LOG_PREFIX} Resolved GitHub repository '${repositoryFromConfig.owner}/${repositoryFromConfig.repo}' directly from .git/config.`
|
|
892
|
+
);
|
|
893
|
+
return this._createRepositoryContext(activeSession, ( workspace.uri.toString()), ( folder.workingDirectory.toString()), repositoryFromConfig);
|
|
894
|
+
}
|
|
895
|
+
this._logService.trace(
|
|
896
|
+
`${LOG_PREFIX} No supported GitHub remote was found directly in .git/config.`
|
|
897
|
+
);
|
|
898
|
+
} catch (error) {
|
|
899
|
+
this._logService.warn(
|
|
900
|
+
`${LOG_PREFIX} Reading Git repository metadata directly from the selected workspace failed.`,
|
|
901
|
+
error
|
|
902
|
+
);
|
|
903
|
+
}
|
|
904
|
+
if (!enterpriseHost && isAgentHostProviderId(activeSession.providerId)) {
|
|
905
|
+
this._logService.info(`${LOG_PREFIX} Waiting for Agent Host git metadata for the active draft.`);
|
|
906
|
+
const result = await this._waitForAgentHostRepository(activeSession, token);
|
|
907
|
+
if (result.kind === "sessionChanged") {
|
|
908
|
+
this._logService.info(
|
|
909
|
+
`${LOG_PREFIX} The active draft changed while waiting for Agent Host git metadata; retrying.`
|
|
910
|
+
);
|
|
911
|
+
continue;
|
|
912
|
+
}
|
|
913
|
+
if (result.kind === "noGitHubRemote") {
|
|
914
|
+
this._logService.info(
|
|
915
|
+
`${LOG_PREFIX} Agent Host git metadata reports that the selected workspace has no GitHub remote.`
|
|
916
|
+
);
|
|
917
|
+
return undefined;
|
|
918
|
+
}
|
|
919
|
+
if (result.kind === "resolved") {
|
|
920
|
+
this._logService.info(
|
|
921
|
+
`${LOG_PREFIX} Resolved GitHub repository '${result.context.repository.owner}/${result.context.repository.repo}' from asynchronously published Agent Host metadata.`
|
|
922
|
+
);
|
|
923
|
+
return result.context;
|
|
924
|
+
}
|
|
925
|
+
}
|
|
926
|
+
this._logService.trace(
|
|
927
|
+
`${LOG_PREFIX} Session metadata, workspace URIs, and .git/config did not identify GitHub; inspecting Git extension remotes.`
|
|
928
|
+
);
|
|
929
|
+
const repository = await this._gitService.openRepository(folder.workingDirectory);
|
|
930
|
+
if (!repository) {
|
|
931
|
+
this._logService.trace(
|
|
932
|
+
`${LOG_PREFIX} The selected workspace folder could not be opened through the Git extension.`
|
|
933
|
+
);
|
|
934
|
+
return undefined;
|
|
935
|
+
}
|
|
936
|
+
const repositoryFromRemote = getGitHubRemoteInfo(repository.state.get(), supportedHosts);
|
|
937
|
+
if (!repositoryFromRemote) {
|
|
938
|
+
this._logService.trace(
|
|
939
|
+
`${LOG_PREFIX} The selected Git repository has no supported GitHub remote.`
|
|
940
|
+
);
|
|
941
|
+
return undefined;
|
|
942
|
+
}
|
|
943
|
+
this._logService.info(
|
|
944
|
+
`${LOG_PREFIX} Resolved GitHub repository '${repositoryFromRemote.owner}/${repositoryFromRemote.repo}' from Git extension remotes.`
|
|
945
|
+
);
|
|
946
|
+
return this._createRepositoryContext(activeSession, ( workspace.uri.toString()), ( folder.workingDirectory.toString()), repositoryFromRemote);
|
|
947
|
+
}
|
|
948
|
+
return undefined;
|
|
949
|
+
}
|
|
950
|
+
_waitForAgentHostRepository(activeSession, token) {
|
|
951
|
+
return ( new Promise((resolve, reject) => {
|
|
952
|
+
const disposables = ( new DisposableStore());
|
|
953
|
+
const reaction = disposables.add(( new MutableDisposable()));
|
|
954
|
+
const finish = result => {
|
|
955
|
+
disposables.dispose();
|
|
956
|
+
resolve(result);
|
|
957
|
+
};
|
|
958
|
+
reaction.value = autorun(reader => {
|
|
959
|
+
if (this._sessionsService.activeSession.read(reader) !== activeSession || activeSession.isCreated.read(reader)) {
|
|
960
|
+
finish({
|
|
961
|
+
kind: "sessionChanged"
|
|
962
|
+
});
|
|
963
|
+
return;
|
|
964
|
+
}
|
|
965
|
+
const workspace = activeSession.workspace.read(reader);
|
|
966
|
+
const folder = workspace?.folders[0];
|
|
967
|
+
const gitRepository = folder?.gitRepository;
|
|
968
|
+
const gitHubInfo = gitRepository?.gitHubInfo.read(reader);
|
|
969
|
+
if (workspace && folder && gitHubInfo) {
|
|
970
|
+
finish({
|
|
971
|
+
kind: "resolved",
|
|
972
|
+
context: this._createRepositoryContext(activeSession, ( workspace.uri.toString()), ( folder.workingDirectory.toString()), {
|
|
973
|
+
owner: gitHubInfo.owner,
|
|
974
|
+
repo: gitHubInfo.repo
|
|
975
|
+
})
|
|
976
|
+
});
|
|
977
|
+
return;
|
|
978
|
+
}
|
|
979
|
+
if (gitRepository?.hasGitHubRemote === false) {
|
|
980
|
+
finish({
|
|
981
|
+
kind: "noGitHubRemote"
|
|
982
|
+
});
|
|
983
|
+
}
|
|
984
|
+
});
|
|
985
|
+
disposables.add(token.onCancellationRequested(() => {
|
|
986
|
+
disposables.dispose();
|
|
987
|
+
reject(( new CancellationError()));
|
|
988
|
+
}));
|
|
989
|
+
if (token.isCancellationRequested) {
|
|
990
|
+
disposables.dispose();
|
|
991
|
+
reject(( new CancellationError()));
|
|
992
|
+
}
|
|
993
|
+
}));
|
|
994
|
+
}
|
|
995
|
+
_logWorkspaceSnapshot(activeSession) {
|
|
996
|
+
const workspace = activeSession.workspace.get();
|
|
997
|
+
const folder = workspace?.folders[0];
|
|
998
|
+
const gitRepository = folder?.gitRepository;
|
|
999
|
+
const gitHubInfo = gitRepository?.gitHubInfo.get();
|
|
1000
|
+
this._logService.info(
|
|
1001
|
+
`${LOG_PREFIX} Workspace snapshot: provider='${activeSession.providerId}', sessionType='${activeSession.sessionType}', workspace='${workspace?.uri.toString() ?? "none"}', root='${folder?.root.toString() ?? "none"}', workingDirectory='${folder?.workingDirectory.toString() ?? "none"}', gitRepository='${gitRepository?.uri.toString() ?? "none"}', hasGitHubRemote=${String(gitRepository?.hasGitHubRemote)}, gitHubRepository='${gitHubInfo ? `${gitHubInfo.owner}/${gitHubInfo.repo}` : "none"}'.`
|
|
1002
|
+
);
|
|
1003
|
+
}
|
|
1004
|
+
_createRepositoryContext(session, workspaceUri, folderUri, repository) {
|
|
1005
|
+
return {
|
|
1006
|
+
session,
|
|
1007
|
+
workspaceUri,
|
|
1008
|
+
folderUri,
|
|
1009
|
+
repository
|
|
1010
|
+
};
|
|
1011
|
+
}
|
|
1012
|
+
_isCurrentRepositoryContext(context) {
|
|
1013
|
+
const activeSession = this._sessionsService.activeSession.get();
|
|
1014
|
+
const workspace = activeSession?.workspace.get();
|
|
1015
|
+
return activeSession === context.session && workspace?.uri.toString() === context.workspaceUri && workspace.folders[0]?.workingDirectory.toString() === context.folderUri;
|
|
1016
|
+
}
|
|
1017
|
+
async _resolvePrompt(fallbackReason) {
|
|
1018
|
+
const [promptTemplateTreatment, placeholderTreatment] = await Promise.all([
|
|
1019
|
+
this._assignmentService.getTreatment(PROMPT_TEMPLATE_TREATMENT),
|
|
1020
|
+
this._assignmentService.getTreatment(PLACEHOLDER_TREATMENT)
|
|
1021
|
+
]);
|
|
1022
|
+
const hasTreatment = typeof promptTemplateTreatment === "string" && !!promptTemplateTreatment.trim() && typeof placeholderTreatment === "string" && !!placeholderTreatment.trim();
|
|
1023
|
+
const promptTemplate = hasTreatment ? promptTemplateTreatment : DEFAULT_PROMPT_TEMPLATE;
|
|
1024
|
+
const taskPlaceholder = hasTreatment ? placeholderTreatment : DEFAULT_TASK_PLACEHOLDER;
|
|
1025
|
+
if (hasTreatment) {
|
|
1026
|
+
this._logService.info(
|
|
1027
|
+
`${LOG_PREFIX} Using prompt template and placeholder from paired treatments.`
|
|
1028
|
+
);
|
|
1029
|
+
} else {
|
|
1030
|
+
this._logService.info(
|
|
1031
|
+
`${LOG_PREFIX} Prompt treatments were not both set to non-empty strings; using the default prompt template and placeholder.`
|
|
1032
|
+
);
|
|
1033
|
+
}
|
|
1034
|
+
return {
|
|
1035
|
+
prompt: format(promptTemplate, taskPlaceholder),
|
|
1036
|
+
taskPlaceholder,
|
|
1037
|
+
effectiveStrategy: "prompt",
|
|
1038
|
+
fallbackReason
|
|
1039
|
+
};
|
|
1040
|
+
}
|
|
1041
|
+
_createPromptOptionsPlan(candidates, fallbackReason, diagnostics) {
|
|
1042
|
+
const options = this._createPromptOptions(candidates);
|
|
1043
|
+
return {
|
|
1044
|
+
options,
|
|
1045
|
+
fallbackReason,
|
|
1046
|
+
lookup: diagnostics.summarize(candidates.length, Math.min(candidates.length, PROMPT_OPTION_COUNT))
|
|
1047
|
+
};
|
|
1048
|
+
}
|
|
1049
|
+
_createPromptOptions(candidates) {
|
|
1050
|
+
const gitHubOptions = candidates.slice(0, PROMPT_OPTION_COUNT).map(candidate => this._createGitHubPromptOption(candidate));
|
|
1051
|
+
const standardOptions = this._createStandardPromptOptions();
|
|
1052
|
+
return [
|
|
1053
|
+
...gitHubOptions,
|
|
1054
|
+
...standardOptions.slice(0, PROMPT_OPTION_COUNT - gitHubOptions.length)
|
|
1055
|
+
];
|
|
1056
|
+
}
|
|
1057
|
+
_createGitHubPromptOption(candidate) {
|
|
1058
|
+
const plan = this._createGitHubPrompt(candidate);
|
|
1059
|
+
const title = candidate.strategy === "githubIssue" ? ( localize(4097, "Tackle issue")) : candidate.strategy === "githubMergeConflict" ? ( localize(4098, "Resolve conflicts")) : candidate.strategy === "githubCiFailure" ? ( localize(4099, "Fix CI")) : ( localize(4100, "Address PR comments"));
|
|
1060
|
+
const icon = candidate.strategy === "githubIssue" ? computeIssueIcon(GitHubIssueState.Open, undefined) : computePullRequestIcon(GitHubPullRequestState.Open, {
|
|
1061
|
+
hasMergeConflicts: candidate.strategy === "githubMergeConflict",
|
|
1062
|
+
hasFailingChecks: candidate.strategy === "githubCiFailure",
|
|
1063
|
+
hasUnresolvedComments: candidate.strategy === "githubReviewComments"
|
|
1064
|
+
});
|
|
1065
|
+
return {
|
|
1066
|
+
id: `${candidate.strategy}:${candidate.url}`,
|
|
1067
|
+
title,
|
|
1068
|
+
titleDetail: `#${candidate.number}`,
|
|
1069
|
+
description: candidate.title,
|
|
1070
|
+
prompt: plan.prompt,
|
|
1071
|
+
placeholder: "",
|
|
1072
|
+
icon
|
|
1073
|
+
};
|
|
1074
|
+
}
|
|
1075
|
+
_createStandardPromptOptions() {
|
|
1076
|
+
const implementFeaturePlaceholder = ( localize(4101, "[describe the feature]"));
|
|
1077
|
+
const fixBugPlaceholder = ( localize(4102, "[describe the bug]"));
|
|
1078
|
+
const fixCiPlaceholder = ( localize(4103, "[describe the CI failure or paste a link]"));
|
|
1079
|
+
return [{
|
|
1080
|
+
id: "standard:implementFeature",
|
|
1081
|
+
title: ( localize(4104, "Implement a feature")),
|
|
1082
|
+
description: ( localize(4105, "Describe what you want to build")),
|
|
1083
|
+
prompt: ( localize(
|
|
1084
|
+
4106,
|
|
1085
|
+
"Help me implement {0} in this project. Ask me questions if anything is unclear regarding the intended behaviour.",
|
|
1086
|
+
implementFeaturePlaceholder
|
|
1087
|
+
)),
|
|
1088
|
+
placeholder: implementFeaturePlaceholder,
|
|
1089
|
+
icon: Codicon.lightbulbSparkleAutofix
|
|
1090
|
+
}, {
|
|
1091
|
+
id: "standard:fixBug",
|
|
1092
|
+
title: ( localize(4107, "Fix a bug")),
|
|
1093
|
+
description: ( localize(4108, "Describe the unexpected behavior")),
|
|
1094
|
+
prompt: ( localize(
|
|
1095
|
+
4109,
|
|
1096
|
+
"Help me fix {0} in this project. Ask me questions if anything is unclear regarding the bug or the intended behaviour.",
|
|
1097
|
+
fixBugPlaceholder
|
|
1098
|
+
)),
|
|
1099
|
+
placeholder: fixBugPlaceholder,
|
|
1100
|
+
icon: Codicon.bug
|
|
1101
|
+
}, {
|
|
1102
|
+
id: "standard:fixCi",
|
|
1103
|
+
title: ( localize(4110, "Fix CI")),
|
|
1104
|
+
description: ( localize(4111, "Describe a failing check or paste a link")),
|
|
1105
|
+
prompt: ( localize(
|
|
1106
|
+
4112,
|
|
1107
|
+
"Help me fix the failing CI for {0} in this project. Ask me questions if anything is unclear regarding the CI failure or how it should be fixed.",
|
|
1108
|
+
fixCiPlaceholder
|
|
1109
|
+
)),
|
|
1110
|
+
placeholder: fixCiPlaceholder,
|
|
1111
|
+
icon: Codicon.runErrors
|
|
1112
|
+
}];
|
|
1113
|
+
}
|
|
1114
|
+
_createGitHubPrompt(candidate) {
|
|
1115
|
+
const prompt = candidate.strategy === "githubMergeConflict" ? ( localize(
|
|
1116
|
+
4113,
|
|
1117
|
+
"The following pull request has merge conflicts: \"{0}\" ({1}). Resolve the conflicts and update the pull request.",
|
|
1118
|
+
candidate.title,
|
|
1119
|
+
candidate.url
|
|
1120
|
+
)) : candidate.strategy === "githubCiFailure" ? ( localize(
|
|
1121
|
+
4114,
|
|
1122
|
+
"The following pull request has failing CI checks: \"{0}\" ({1}). Investigate the failures and resolve them.",
|
|
1123
|
+
candidate.title,
|
|
1124
|
+
candidate.url
|
|
1125
|
+
)) : candidate.strategy === "githubReviewComments" ? ( localize(
|
|
1126
|
+
4115,
|
|
1127
|
+
"The following pull request has unresolved review comments that have not been addressed by a newer commit: \"{0}\" ({1}). Address the review comments and update the pull request.",
|
|
1128
|
+
candidate.title,
|
|
1129
|
+
candidate.url
|
|
1130
|
+
)) : ( localize(
|
|
1131
|
+
4116,
|
|
1132
|
+
"Tackle the following issue and create a pull request for it: \"{0}\" ({1}).",
|
|
1133
|
+
candidate.title,
|
|
1134
|
+
candidate.url
|
|
1135
|
+
));
|
|
1136
|
+
return {
|
|
1137
|
+
prompt,
|
|
1138
|
+
taskPlaceholder: "",
|
|
1139
|
+
effectiveStrategy: candidate.strategy,
|
|
1140
|
+
fallbackReason: "none"
|
|
1141
|
+
};
|
|
1142
|
+
}
|
|
1143
|
+
_animatePrompt(prompt, taskPlaceholder, token) {
|
|
1144
|
+
const activeSession = this._sessionsService.activeSession.get();
|
|
1145
|
+
if (activeSession?.isCreated.get()) {
|
|
1146
|
+
this._logService.warn(
|
|
1147
|
+
`${LOG_PREFIX} Skipping prompt insertion because the active session was created before animation started.`
|
|
1148
|
+
);
|
|
1149
|
+
return false;
|
|
1150
|
+
}
|
|
1151
|
+
const composer = this._newSessionComposerService.activeComposer.get();
|
|
1152
|
+
if (!composer) {
|
|
1153
|
+
this._logService.warn(
|
|
1154
|
+
`${LOG_PREFIX} Skipping prompt insertion because no active new-session composer is available.`
|
|
1155
|
+
);
|
|
1156
|
+
return false;
|
|
1157
|
+
}
|
|
1158
|
+
this._logService.trace(
|
|
1159
|
+
`${LOG_PREFIX} Animating the resolved prompt in the active new-session composer.`
|
|
1160
|
+
);
|
|
1161
|
+
return composer.animatePrompt(prompt, NEW_SESSION_PROMPT_TYPING_DURATION_MS, taskPlaceholder, token);
|
|
1162
|
+
}
|
|
1163
|
+
_reportStrategy(
|
|
1164
|
+
configuredVariation,
|
|
1165
|
+
effectiveStrategy,
|
|
1166
|
+
fallbackReason,
|
|
1167
|
+
shown,
|
|
1168
|
+
lookup = NO_LOOKUP_TELEMETRY
|
|
1169
|
+
) {
|
|
1170
|
+
this._telemetryService.publicLog2("onboarding.promptStrategy", {
|
|
1171
|
+
scenarioId: NEW_SESSION_VIEW_V3_TOUR_ID,
|
|
1172
|
+
impressionId: this._impressionId,
|
|
1173
|
+
configuredVariation,
|
|
1174
|
+
effectiveStrategy,
|
|
1175
|
+
fallbackReason,
|
|
1176
|
+
shown,
|
|
1177
|
+
...lookup
|
|
1178
|
+
});
|
|
1179
|
+
}
|
|
1180
|
+
_reportPromptOptionInteraction(interaction, option) {
|
|
1181
|
+
this._telemetryService.publicLog2("onboarding.promptOptionInteraction", {
|
|
1182
|
+
scenarioId: NEW_SESSION_VIEW_V3_TOUR_ID,
|
|
1183
|
+
impressionId: this._impressionId,
|
|
1184
|
+
interaction,
|
|
1185
|
+
option: option ? getPromptOptionTelemetryKind(option) : "none",
|
|
1186
|
+
optionIndex: option ? this._renderedPromptOptions.findIndex(candidate => candidate.id === option.id) : -1,
|
|
1187
|
+
optionKindsShown: this._renderedPromptOptions.map(getPromptOptionTelemetryKind).join(",")
|
|
1188
|
+
});
|
|
1189
|
+
}
|
|
1190
|
+
}
|
|
1191
|
+
function isFailingPullRequest(pullRequest) {
|
|
1192
|
+
return pullRequest.statusCheckRollupState === "FAILURE" || pullRequest.statusCheckRollupState === "ERROR";
|
|
1193
|
+
}
|
|
1194
|
+
function toDirectPullRequestCandidate(pullRequest) {
|
|
1195
|
+
if (pullRequest.hasMergeConflicts) {
|
|
1196
|
+
return toCandidate(pullRequest, "githubMergeConflict");
|
|
1197
|
+
}
|
|
1198
|
+
if (isFailingPullRequest(pullRequest)) {
|
|
1199
|
+
return toCandidate(pullRequest, "githubCiFailure");
|
|
1200
|
+
}
|
|
1201
|
+
return undefined;
|
|
1202
|
+
}
|
|
1203
|
+
function hasUnaddressedReviewComments(pullRequest) {
|
|
1204
|
+
const latestCommitAt = pullRequest.latestCommitAt ? Date.parse(pullRequest.latestCommitAt) : NaN;
|
|
1205
|
+
if (!Number.isFinite(latestCommitAt)) {
|
|
1206
|
+
return false;
|
|
1207
|
+
}
|
|
1208
|
+
return ( (pullRequest.reviewThreads ?? []).some(thread => {
|
|
1209
|
+
const latestCommentAt = thread.latestCommentAt ? Date.parse(thread.latestCommentAt) : NaN;
|
|
1210
|
+
return !thread.isResolved && Number.isFinite(latestCommentAt) && latestCommentAt > latestCommitAt;
|
|
1211
|
+
}));
|
|
1212
|
+
}
|
|
1213
|
+
function getLookupFallbackReason(failures) {
|
|
1214
|
+
if (failures.includes("noAuthentication")) {
|
|
1215
|
+
return "noAuthentication";
|
|
1216
|
+
}
|
|
1217
|
+
if (failures.includes("timeout")) {
|
|
1218
|
+
return "timeout";
|
|
1219
|
+
}
|
|
1220
|
+
if (failures.includes("requestFailed")) {
|
|
1221
|
+
return "requestFailed";
|
|
1222
|
+
}
|
|
1223
|
+
return "noCandidate";
|
|
1224
|
+
}
|
|
1225
|
+
function compareUpdatedAtDescending(a, b) {
|
|
1226
|
+
return Date.parse(b.updatedAt) - Date.parse(a.updatedAt);
|
|
1227
|
+
}
|
|
1228
|
+
function getCandidatesInPullRequestOrder(pullRequests, candidates) {
|
|
1229
|
+
const candidatesByNumber = ( new Map(candidates.map(candidate => [candidate.number, candidate])));
|
|
1230
|
+
return pullRequests.map(pullRequest => candidatesByNumber.get(pullRequest.number)).filter(candidate => candidate !== undefined);
|
|
1231
|
+
}
|
|
1232
|
+
function toCandidate(pullRequest, strategy) {
|
|
1233
|
+
return {
|
|
1234
|
+
number: pullRequest.number,
|
|
1235
|
+
title: pullRequest.title,
|
|
1236
|
+
url: pullRequest.url,
|
|
1237
|
+
strategy
|
|
1238
|
+
};
|
|
1239
|
+
}
|
|
1240
|
+
function toIssuePromptOptionCandidates(issues) {
|
|
1241
|
+
return [...issues].sort(compareUpdatedAtDescending).slice(0, 2).map(issue => ({
|
|
1242
|
+
number: issue.number,
|
|
1243
|
+
title: issue.title,
|
|
1244
|
+
url: issue.url,
|
|
1245
|
+
strategy: "githubIssue"
|
|
1246
|
+
}));
|
|
1247
|
+
}
|
|
1248
|
+
function getPromptOptionTelemetryKind(option) {
|
|
1249
|
+
switch (option.id.split(":", 1)[0]) {
|
|
1250
|
+
case "standard":
|
|
1251
|
+
switch (option.id) {
|
|
1252
|
+
case "standard:implementFeature":
|
|
1253
|
+
return "implementFeature";
|
|
1254
|
+
case "standard:fixBug":
|
|
1255
|
+
return "fixBug";
|
|
1256
|
+
case "standard:fixCi":
|
|
1257
|
+
return "fixCI";
|
|
1258
|
+
default:
|
|
1259
|
+
return "unknown";
|
|
1260
|
+
}
|
|
1261
|
+
case "githubIssue":
|
|
1262
|
+
return "githubIssue";
|
|
1263
|
+
case "githubMergeConflict":
|
|
1264
|
+
return "githubPRConflicts";
|
|
1265
|
+
case "githubCiFailure":
|
|
1266
|
+
return "githubPRCI";
|
|
1267
|
+
case "githubReviewComments":
|
|
1268
|
+
return "githubPRComments";
|
|
1269
|
+
default:
|
|
1270
|
+
return "unknown";
|
|
1271
|
+
}
|
|
1272
|
+
}
|
|
1273
|
+
function capitalize(value) {
|
|
1274
|
+
return value.length > 0 ? value[0].toUpperCase() + value.slice(1) : value;
|
|
1275
|
+
}
|
|
1276
|
+
|
|
1277
|
+
export { NewSessionViewV3PromptRunner };
|