@codingame/monaco-vscode-workbench-service-override 37.6.0 → 38.0.0
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.js +2 -0
- package/index.js +9 -10
- package/package.json +10 -10
- package/session.js +45 -42
- package/vscode/src/vs/platform/agentHost/common/sessionComparisonPrompts.d.ts +1 -0
- package/vscode/src/vs/platform/agentHost/common/sessionComparisonPrompts.js +12 -0
- package/vscode/src/vs/sessions/browser/{singlePaneWorkbench.d.ts → desktopWorkbench.d.ts} +6 -5
- package/vscode/src/vs/sessions/browser/{singlePaneWorkbench.js → desktopWorkbench.js} +23 -25
- package/vscode/src/vs/sessions/browser/dockedAuxiliaryBarController.d.ts +5 -2
- package/vscode/src/vs/sessions/browser/dockedAuxiliaryBarController.js +41 -3
- package/vscode/src/vs/sessions/browser/layoutActions.js +25 -41
- package/vscode/src/vs/sessions/browser/mobileWorkbench.d.ts +4 -0
- package/vscode/src/vs/sessions/browser/mobileWorkbench.js +10 -0
- package/vscode/src/vs/sessions/browser/parts/chatCompositeBar.d.ts +10 -5
- package/vscode/src/vs/sessions/browser/parts/chatCompositeBar.js +138 -34
- package/vscode/src/vs/sessions/browser/parts/chatGroupDropTarget.d.ts +2 -0
- package/vscode/src/vs/sessions/browser/parts/chatGroupDropTarget.js +13 -5
- package/vscode/src/vs/sessions/browser/parts/chatGroupView.d.ts +27 -5
- package/vscode/src/vs/sessions/browser/parts/chatGroupView.js +129 -28
- package/vscode/src/vs/sessions/browser/parts/chatGroupsView.d.ts +22 -7
- package/vscode/src/vs/sessions/browser/parts/chatGroupsView.js +260 -21
- package/vscode/src/vs/sessions/browser/parts/chatHeader.d.ts +25 -0
- package/vscode/src/vs/sessions/browser/parts/chatHeader.js +42 -0
- package/vscode/src/vs/sessions/browser/parts/customViewGridPart.js +9 -1
- package/vscode/src/vs/sessions/browser/parts/customViewNode.js +1 -1
- package/vscode/src/vs/sessions/browser/parts/{singlePaneAuxiliaryBarPart.d.ts → desktopAuxiliaryBarPart.d.ts} +4 -4
- package/vscode/src/vs/sessions/browser/parts/desktopAuxiliaryBarPart.js +26 -0
- package/vscode/src/vs/sessions/browser/parts/{singlePaneEditorPart.d.ts → desktopEditorPart.d.ts} +8 -6
- package/vscode/src/vs/sessions/browser/parts/{singlePaneEditorPart.js → desktopEditorPart.js} +25 -5
- package/vscode/src/vs/sessions/browser/parts/editorPart.js +16 -4
- package/vscode/src/vs/sessions/browser/parts/editorParts.d.ts +1 -1
- package/vscode/src/vs/sessions/browser/parts/editorParts.js +7 -6
- package/vscode/src/vs/sessions/browser/parts/gridGap.d.ts +14 -0
- package/vscode/src/vs/sessions/browser/parts/gridGap.js +69 -0
- package/vscode/src/vs/sessions/browser/parts/media/chatCompositeBar.css +132 -4
- package/vscode/src/vs/sessions/browser/parts/media/chatGroupsView.css +10 -0
- package/vscode/src/vs/sessions/browser/parts/media/editorPart.css +46 -2
- package/vscode/src/vs/sessions/browser/parts/media/sessionReadOnlyBanner.css +3 -3
- package/vscode/src/vs/sessions/browser/parts/media/sessionView.css +45 -48
- package/vscode/src/vs/sessions/browser/parts/media/sessionsPart.css +15 -0
- package/vscode/src/vs/sessions/browser/parts/menubar.contribution.js +8 -8
- package/vscode/src/vs/sessions/browser/parts/mobile/mobileSessionsPart.js +1 -1
- package/vscode/src/vs/sessions/browser/parts/remoteHostUnavailableEmptyState.d.ts +9 -1
- package/vscode/src/vs/sessions/browser/parts/remoteHostUnavailableEmptyState.js +21 -3
- package/vscode/src/vs/sessions/browser/parts/sessionBarStyles.js +1 -1
- package/vscode/src/vs/sessions/browser/parts/sessionDropTarget.d.ts +4 -3
- package/vscode/src/vs/sessions/browser/parts/sessionDropTarget.js +29 -15
- package/vscode/src/vs/sessions/browser/parts/sessionGridLayout.d.ts +67 -0
- package/vscode/src/vs/sessions/browser/parts/sessionGridLayout.js +598 -0
- package/vscode/src/vs/sessions/browser/parts/sessionHeader.d.ts +11 -84
- package/vscode/src/vs/sessions/browser/parts/sessionHeader.js +37 -317
- package/vscode/src/vs/sessions/browser/parts/sessionHeaderBar.d.ts +103 -0
- package/vscode/src/vs/sessions/browser/parts/sessionHeaderBar.js +391 -0
- package/vscode/src/vs/sessions/browser/parts/sessionReadOnlyBanner.d.ts +6 -4
- package/vscode/src/vs/sessions/browser/parts/sessionReadOnlyBanner.js +58 -28
- package/vscode/src/vs/sessions/browser/parts/sessionRemoteConnection.d.ts +4 -0
- package/vscode/src/vs/sessions/browser/parts/sessionRemoteConnection.js +66 -23
- package/vscode/src/vs/sessions/browser/parts/sessionView.d.ts +24 -5
- package/vscode/src/vs/sessions/browser/parts/sessionView.js +143 -33
- package/vscode/src/vs/sessions/browser/parts/sessionsPart.d.ts +25 -19
- package/vscode/src/vs/sessions/browser/parts/sessionsPart.js +157 -58
- package/vscode/src/vs/sessions/browser/parts/sessionsParts.d.ts +12 -3
- package/vscode/src/vs/sessions/browser/parts/sessionsParts.js +17 -2
- package/vscode/src/vs/sessions/browser/sessionWorkspace.d.ts +6 -3
- package/vscode/src/vs/sessions/browser/sessionWorkspace.js +2 -2
- package/vscode/src/vs/sessions/browser/sessionsSetUpService.js +66 -20
- package/vscode/src/vs/sessions/browser/sessionsSignInDialog.d.ts +1 -0
- package/vscode/src/vs/sessions/browser/sessionsSignInDialog.js +5 -4
- package/vscode/src/vs/sessions/browser/workbenchFactory.d.ts +12 -0
- package/vscode/src/vs/sessions/browser/workbenchFactory.js +17 -0
- package/vscode/src/vs/sessions/contrib/accountMenu/browser/account.contribution.d.ts +85 -1
- package/vscode/src/vs/sessions/contrib/accountMenu/browser/account.contribution.js +118 -100
- package/vscode/src/vs/sessions/contrib/accountMenu/browser/chatPetAchievementBadges.d.ts +3 -2
- package/vscode/src/vs/sessions/contrib/accountMenu/browser/chatPetAchievementBadges.js +39 -34
- package/vscode/src/vs/sessions/contrib/accountMenu/browser/media/accountTitleBarWidget.css +6 -0
- package/vscode/src/vs/sessions/contrib/agentFeedback/browser/nullAgentFeedbackService.contribution.d.ts +3 -0
- package/vscode/src/vs/sessions/contrib/agentFeedback/browser/nullAgentFeedbackService.contribution.js +6 -0
- package/vscode/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationTreeView.contribution.js +18 -18
- package/vscode/src/vs/sessions/contrib/aiCustomizationTreeView/browser/aiCustomizationTreeViewViews.js +12 -12
- package/vscode/src/vs/sessions/contrib/applyCommitsToParentRepo/browser/applyChangesToParentRepo.js +7 -7
- package/vscode/src/vs/sessions/contrib/aquarium/browser/aquarium.contribution.js +12 -12
- package/vscode/src/vs/sessions/contrib/aquarium/browser/aquariumOverlay.js +10 -10
- package/vscode/src/vs/sessions/contrib/automations/browser/automationDialog.d.ts +78 -8
- package/vscode/src/vs/sessions/contrib/automations/browser/automationDialog.js +1166 -202
- package/vscode/src/vs/sessions/contrib/automations/browser/automationDialogService.d.ts +11 -1
- package/vscode/src/vs/sessions/contrib/automations/browser/automationDialogService.js +190 -69
- package/vscode/src/vs/sessions/contrib/automations/browser/automationRunner.d.ts +11 -9
- package/vscode/src/vs/sessions/contrib/automations/browser/automationRunner.js +122 -233
- package/vscode/src/vs/sessions/contrib/automations/browser/automationTelemetry.d.ts +22 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationTelemetry.js +62 -0
- package/vscode/src/vs/sessions/contrib/automations/browser/automationTools.d.ts +7 -2
- package/vscode/src/vs/sessions/contrib/automations/browser/automationTools.js +172 -84
- package/vscode/src/vs/sessions/contrib/automations/browser/automations.contribution.js +17 -7
- package/vscode/src/vs/sessions/contrib/automations/browser/media/automationDialog.css +242 -60
- package/vscode/src/vs/sessions/contrib/automations/browser/providerAutomationService.d.ts +24 -36
- package/vscode/src/vs/sessions/contrib/automations/browser/providerAutomationService.js +104 -420
- package/vscode/src/vs/sessions/contrib/changes/browser/changes.contribution.js +15 -14
- package/vscode/src/vs/sessions/contrib/changes/browser/changesActions.d.ts +13 -3
- package/vscode/src/vs/sessions/contrib/changes/browser/changesActions.js +66 -43
- package/vscode/src/vs/sessions/contrib/changes/browser/changesMultiDiffSourceResolver.js +2 -7
- package/vscode/src/vs/sessions/contrib/changes/browser/changesViewActions.js +54 -59
- package/vscode/src/vs/sessions/contrib/changes/browser/changesetReviewActions.js +7 -7
- package/vscode/src/vs/sessions/contrib/changes/browser/media/changesActions.css +6 -0
- package/vscode/src/vs/sessions/contrib/changes/browser/sessionSyncChanges.js +25 -21
- package/vscode/src/vs/sessions/contrib/changes/browser/sessionsChangesAccessibilityHelp.js +21 -27
- package/vscode/src/vs/sessions/contrib/chat/browser/sessionChatInputToolbarDebug.js +17 -17
- package/vscode/src/vs/sessions/contrib/chat/browser/sessionTaskRunner.d.ts +5 -5
- package/vscode/src/vs/sessions/contrib/chat/browser/sessionTaskRunner.js +2 -2
- package/vscode/src/vs/sessions/contrib/chatDebug/browser/chatDebug.contribution.js +2 -2
- package/vscode/src/vs/sessions/contrib/codeReview/browser/codeReview.contributions.js +9 -16
- package/vscode/src/vs/sessions/contrib/customViewTest/browser/customViewTest.contribution.js +7 -7
- package/vscode/src/vs/sessions/contrib/editor/browser/addTabActions.js +15 -13
- package/vscode/src/vs/sessions/contrib/editor/browser/editor.contribution.d.ts +13 -1
- package/vscode/src/vs/sessions/contrib/editor/browser/editor.contribution.js +104 -117
- package/vscode/src/vs/sessions/contrib/editor/browser/emptyFileEditor.contribution.js +8 -7
- package/vscode/src/vs/sessions/contrib/editor/browser/emptyFileEditor.js +5 -5
- package/vscode/src/vs/sessions/contrib/editor/browser/emptyFileEditorInput.js +1 -1
- package/vscode/src/vs/sessions/contrib/editor/browser/media/editorBreadcrumbs.css +0 -1
- package/vscode/src/vs/sessions/contrib/editor/browser/media/editorHeader.css +1 -1
- package/vscode/src/vs/sessions/contrib/files/browser/files.contribution.d.ts +7 -0
- package/vscode/src/vs/sessions/contrib/files/browser/files.contribution.js +77 -13
- package/vscode/src/vs/sessions/contrib/files/browser/filesView.d.ts +2 -1
- package/vscode/src/vs/sessions/contrib/files/browser/filesView.js +14 -4
- package/vscode/src/vs/sessions/contrib/layout/browser/baseSessionLayoutController.d.ts +45 -10
- package/vscode/src/vs/sessions/contrib/layout/browser/baseSessionLayoutController.js +527 -96
- package/vscode/src/vs/sessions/contrib/layout/browser/chatLayoutOwnerKeys.d.ts +18 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/chatLayoutOwnerKeys.js +95 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneDetailPanelCoordinator.d.ts → desktop/desktopDetailPanelCoordinator.d.ts} +5 -4
- package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneDetailPanelCoordinator.js → desktop/desktopDetailPanelCoordinator.js} +10 -7
- package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneDockedTabsCoordinator.d.ts → desktop/desktopDockedTabsCoordinator.d.ts} +15 -12
- package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneDockedTabsCoordinator.js → desktop/desktopDockedTabsCoordinator.js} +91 -44
- package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneDraftSessionStrategy.d.ts → desktop/desktopDraftSessionStrategy.d.ts} +10 -5
- package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneDraftSessionStrategy.js → desktop/desktopDraftSessionStrategy.js} +95 -22
- package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneExistingSessionStrategy.d.ts → desktop/desktopExistingSessionStrategy.d.ts} +13 -11
- package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneExistingSessionStrategy.js → desktop/desktopExistingSessionStrategy.js} +137 -57
- package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneLayoutStrategy.d.ts → desktop/desktopLayoutStrategy.d.ts} +22 -13
- package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneLayoutStrategy.js → desktop/desktopLayoutStrategy.js} +2 -2
- package/vscode/src/vs/sessions/contrib/layout/browser/desktop/desktopOwnerCompositionStore.d.ts +22 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/desktop/desktopOwnerCompositionStore.js +136 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneSharedHelpers.d.ts → desktop/desktopSharedHelpers.d.ts} +9 -2
- package/vscode/src/vs/sessions/contrib/layout/browser/desktop/desktopSharedHelpers.js +56 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneVisibilityProfileStore.d.ts → desktop/desktopVisibilityProfileStore.d.ts} +3 -2
- package/vscode/src/vs/sessions/contrib/layout/browser/{singlePane/singlePaneVisibilityProfileStore.js → desktop/desktopVisibilityProfileStore.js} +10 -9
- package/vscode/src/vs/sessions/contrib/layout/browser/desktopLayoutController.d.ts +71 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/desktopLayoutController.js +201 -0
- package/vscode/src/vs/sessions/contrib/layout/browser/sessions.layout.contribution.d.ts +8 -1
- package/vscode/src/vs/sessions/contrib/layout/browser/sessions.layout.contribution.js +35 -35
- package/vscode/src/vs/sessions/contrib/layout/common/sessionEditorWorkingSet.d.ts +39 -0
- package/vscode/src/vs/sessions/contrib/layout/common/sessionEditorWorkingSet.js +73 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionTourContribution.d.ts +42 -1
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionTourContribution.js +14 -10
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewTourContribution.js +3 -4
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewTourTrigger.d.ts +2 -2
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewTourTrigger.js +13 -9
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewV2TourContribution.js +20 -5
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewV2TourVariation.d.ts +8 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewV2TourVariation.js +19 -0
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/newSessionViewV3Prompt.js +21 -20
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionTour.js +10 -5
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewTour.js +12 -8
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewTourShared.d.ts +3 -1
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewTourShared.js +12 -7
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewV2Tour.d.ts +9 -1
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewV2Tour.js +46 -19
- package/vscode/src/vs/sessions/contrib/onboardingTours/browser/tours/newSessionViewV3Tour.js +2 -0
- package/vscode/src/vs/sessions/contrib/policyBlocked/browser/media/sessionsPolicyBlocked.css +33 -0
- package/vscode/src/vs/sessions/contrib/policyBlocked/browser/policyBlocked.contribution.d.ts +4 -2
- package/vscode/src/vs/sessions/contrib/policyBlocked/browser/policyBlocked.contribution.js +29 -8
- package/vscode/src/vs/sessions/contrib/policyBlocked/browser/sessionsPolicyBlocked.d.ts +15 -2
- package/vscode/src/vs/sessions/contrib/policyBlocked/browser/sessionsPolicyBlocked.js +169 -32
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostForkActions.js +30 -8
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostSessionBranchActions.js +8 -34
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentMergeActions.js +63 -49
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/exportDebugLogsAction.js +1 -1
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileChatInputConfigPicker.js +31 -17
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/connectionDiagnostics.contribution.d.ts +32 -0
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/connectionDiagnostics.contribution.js +250 -0
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/connectionDiagnosticsLogs.d.ts +6 -0
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/connectionDiagnosticsLogs.js +52 -0
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/connectionDiagnosticsReport.d.ts +51 -0
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/connectionDiagnosticsReport.js +439 -0
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/connectionDiagnosticsService.d.ts +45 -0
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/connectionDiagnosticsService.js +595 -0
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/devContainerAgentHostService.d.ts +20 -3
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/devContainerAgentHostService.js +360 -46
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/devContainerSource.d.ts +9 -0
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/devContainerSource.js +59 -0
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/media/connectionDiagnostics.css +201 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/getRemoteSessionTool.d.ts +10 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/getRemoteSessionTool.js +70 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionChatService.d.ts +20 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionChatService.js +104 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionInspector.d.ts +15 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionInspector.js +152 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionMessageRouter.d.ts +49 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionMessageRouter.js +340 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionService.d.ts +41 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionService.js +400 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionSource.d.ts +28 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionSource.js +178 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionTools.d.ts +17 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessionTools.js +206 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessions.contribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/remoteSessions.contribution.js +58 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/sendRemoteMessageTool.d.ts +10 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/browser/sendRemoteMessageTool.js +90 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/common/remoteSessionInspection.d.ts +38 -0
- package/vscode/src/vs/sessions/contrib/remoteSessions/common/remoteSessionInspection.js +58 -0
- package/vscode/src/vs/sessions/contrib/search/browser/search.contribution.js +4 -5
- package/vscode/src/vs/sessions/contrib/search/browser/searchEditorEmptyState.contribution.js +1 -1
- package/vscode/src/vs/sessions/contrib/sessionComparison/browser/sessionComparison.contribution.d.ts +1 -0
- package/vscode/src/vs/sessions/contrib/sessionComparison/browser/sessionComparison.contribution.js +33 -0
- package/vscode/src/vs/sessions/contrib/sessionComparison/browser/sessionComparisonGridController.d.ts +30 -0
- package/vscode/src/vs/sessions/contrib/sessionComparison/browser/sessionComparisonGridController.js +190 -0
- package/vscode/src/vs/sessions/contrib/sessionComparison/browser/sessionComparisonTool.d.ts +31 -0
- package/vscode/src/vs/sessions/contrib/sessionComparison/browser/sessionComparisonTool.js +559 -0
- package/vscode/src/vs/sessions/contrib/sessionComparison/browser/sessionComparisonViewService.d.ts +12 -0
- package/vscode/src/vs/sessions/contrib/sessionComparison/browser/sessionComparisonViewService.js +38 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/blockedSessionsIndicatorModel.d.ts +13 -4
- package/vscode/src/vs/sessions/contrib/sessions/browser/blockedSessionsIndicatorModel.js +155 -22
- package/vscode/src/vs/sessions/contrib/sessions/browser/blockedSessionsList.js +9 -5
- package/vscode/src/vs/sessions/contrib/sessions/browser/media/automationsCards.css +90 -25
- package/vscode/src/vs/sessions/contrib/sessions/browser/media/sessionsTitleBarWidget.css +21 -4
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionDetailsAction.d.ts +2 -1
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionDetailsAction.js +11 -7
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessions.contribution.d.ts +116 -1
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessions.contribution.js +126 -30
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsAccountTelemetry.d.ts +26 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsAccountTelemetry.js +160 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsActions.d.ts +14 -6
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsActions.js +555 -151
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsLifecycleTracker.d.ts +192 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsLifecycleTracker.js +510 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsTelemetry.contribution.d.ts +6 -7
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsTelemetry.contribution.js +64 -57
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsTitleBarWidget.d.ts +5 -3
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsTitleBarWidget.js +83 -51
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsWindowNotifier.d.ts +5 -1
- package/vscode/src/vs/sessions/contrib/sessions/browser/sessionsWindowNotifier.js +33 -12
- package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationCataloguePresentation.d.ts +3 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationCataloguePresentation.js +53 -0
- package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationTemplates.js +10 -10
- package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationsAccessibility.d.ts +2 -2
- package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationsAccessibility.js +103 -55
- package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationsView.d.ts +7 -1
- package/vscode/src/vs/sessions/contrib/sessions/browser/views/automationsView.js +679 -325
- package/vscode/src/vs/sessions/contrib/sessions/browser/views/sessionsViewActions.d.ts +27 -1
- package/vscode/src/vs/sessions/contrib/sessions/browser/views/sessionsViewActions.js +508 -163
- package/vscode/src/vs/sessions/contrib/terminal/browser/agentHostSessionTaskRunner.d.ts +20 -2
- package/vscode/src/vs/sessions/contrib/terminal/browser/agentHostSessionTaskRunner.js +100 -17
- package/vscode/src/vs/sessions/contrib/terminal/browser/sessionsTerminalContribution.d.ts +5 -1
- package/vscode/src/vs/sessions/contrib/terminal/browser/sessionsTerminalContribution.js +108 -30
- package/vscode/src/vs/sessions/contrib/workspace/browser/workspaceFolderManagement.d.ts +5 -3
- package/vscode/src/vs/sessions/contrib/workspace/browser/workspaceFolderManagement.js +47 -35
- package/vscode/src/vs/sessions/services/agentHostFilter/browser/agentHostFilterService.d.ts +9 -4
- package/vscode/src/vs/sessions/services/agentHostFilter/browser/agentHostFilterService.js +75 -25
- package/vscode/src/vs/sessions/services/customView/browser/customViewService.d.ts +11 -4
- package/vscode/src/vs/sessions/services/customView/browser/customViewService.js +17 -9
- package/vscode/src/vs/sessions/services/sessions/browser/closedItemHistory.d.ts +5 -0
- package/vscode/src/vs/sessions/services/sessions/browser/closedItemHistory.js +20 -2
- package/vscode/src/vs/sessions/services/sessions/browser/sessionComparisonService.d.ts +75 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionComparisonService.js +1135 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionGridState.d.ts +17 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionGridState.js +99 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionGroupsService.d.ts +4 -0
- package/vscode/src/vs/sessions/services/sessions/browser/sessionGroupsService.js +88 -23
- package/vscode/src/vs/sessions/services/sessions/browser/sessionNavigation.d.ts +19 -26
- package/vscode/src/vs/sessions/services/sessions/browser/sessionNavigation.js +115 -74
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsListModelService.js +1 -1
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsManagementService.d.ts +22 -7
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsManagementService.js +278 -60
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsRecencyHistory.d.ts +17 -20
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsRecencyHistory.js +33 -22
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsService.d.ts +28 -8
- package/vscode/src/vs/sessions/services/sessions/browser/sessionsService.js +673 -160
- package/vscode/src/vs/sessions/services/sessions/browser/visibleSessions.d.ts +13 -4
- package/vscode/src/vs/sessions/services/sessions/browser/visibleSessions.js +105 -15
- package/vscode/src/vs/sessions/services/sessions/common/sessionContextKeys.js +53 -34
- package/vscode/src/vs/sessions/services/workspaceFolderLabel/browser/workspaceFolderLabelService.js +1 -1
- package/vscode/src/vs/workbench/browser/layout.d.ts +46 -70
- package/vscode/src/vs/workbench/browser/layout.js +243 -44
- package/vscode/src/vs/workbench/browser/workbench.d.ts +1 -3
- package/vscode/src/vs/workbench/browser/workbench.js +26 -24
- package/vscode/src/vs/workbench/contrib/chat/common/automations/schedule.d.ts +6 -0
- package/vscode/src/vs/workbench/contrib/chat/common/automations/schedule.js +41 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatUsage.d.ts +15 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatUsage.js +56 -0
- package/vscode/src/vs/platform/agentHost/common/meta/agentCheckoutOperationMeta.d.ts +0 -18
- package/vscode/src/vs/platform/agentHost/common/meta/agentCheckoutOperationMeta.js +0 -27
- package/vscode/src/vs/sessions/browser/parts/singlePaneAuxiliaryBarPart.js +0 -36
- package/vscode/src/vs/sessions/contrib/automations/browser/automationLeaderElection.d.ts +0 -37
- package/vscode/src/vs/sessions/contrib/automations/browser/automationLeaderElection.js +0 -126
- package/vscode/src/vs/sessions/contrib/automations/browser/automationScheduler.d.ts +0 -59
- package/vscode/src/vs/sessions/contrib/automations/browser/automationScheduler.js +0 -232
- package/vscode/src/vs/sessions/contrib/automations/browser/automationStorageService.d.ts +0 -13
- package/vscode/src/vs/sessions/contrib/automations/browser/automationStorageService.js +0 -22
- package/vscode/src/vs/sessions/contrib/blockedSessions/browser/blockedSessions.d.ts +0 -45
- package/vscode/src/vs/sessions/contrib/blockedSessions/browser/blockedSessions.js +0 -110
- package/vscode/src/vs/sessions/contrib/layout/browser/desktopSessionLayoutController.d.ts +0 -112
- package/vscode/src/vs/sessions/contrib/layout/browser/desktopSessionLayoutController.js +0 -444
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePane/singlePaneSharedHelpers.js +0 -43
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePaneLayoutController.d.ts +0 -55
- package/vscode/src/vs/sessions/contrib/layout/browser/singlePaneLayoutController.js +0 -91
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostClaudePermissionModePicker.d.ts +0 -26
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostClaudePermissionModePicker.js +0 -98
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostCodexApprovalsPicker.d.ts +0 -33
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostCodexApprovalsPicker.js +0 -98
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostModeIcon.d.ts +0 -2
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostModeIcon.js +0 -13
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostModePicker.d.ts +0 -122
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostModePicker.js +0 -464
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostPermissionPickerActionItem.d.ts +0 -35
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostPermissionPickerActionItem.js +0 -90
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostPermissionPickerDelegate.d.ts +0 -84
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostPermissionPickerDelegate.js +0 -328
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostSessionConfigPicker.d.ts +0 -174
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/agentHostSessionConfigPicker.js +0 -1390
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/media/agentHostSessionConfigPicker.css +0 -44
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileAgentHostModePicker.d.ts +0 -30
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileAgentHostModePicker.js +0 -78
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileChatPhoneInputTarget.d.ts +0 -11
- package/vscode/src/vs/sessions/contrib/providers/agentHost/browser/mobile/mobileChatPhoneInputTarget.js +0 -26
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/remoteAgentHostConnectionCustomization.d.ts +0 -27
- package/vscode/src/vs/sessions/contrib/providers/remoteAgentHost/browser/remoteAgentHostConnectionCustomization.js +0 -26
|
@@ -1,19 +1,23 @@
|
|
|
1
1
|
|
|
2
2
|
import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
|
|
3
|
-
import { $ as $$1, isEditableElement, addDisposableListener, EventType, clearNode, append,
|
|
3
|
+
import { $ as $$1, isEditableElement, addDisposableListener, EventType, clearNode, append, hide, getWindow, DisposableResizeObserver, show, reset } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/dom';
|
|
4
4
|
import { raceCancellationError, raceTimeout } from '@codingame/monaco-vscode-api/vscode/vs/base/common/async';
|
|
5
5
|
import { BaseActionViewItem } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/ui/actionbar/actionViewItems';
|
|
6
6
|
import { renderIcon } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/ui/iconLabel/iconLabels';
|
|
7
|
+
import { Button, unthemedButtonStyles } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/ui/button/button';
|
|
8
|
+
import { Checkbox } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/ui/toggle/toggle';
|
|
7
9
|
import { InputBox } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/ui/inputbox/inputBox';
|
|
10
|
+
import '@codingame/monaco-vscode-api/vscode/vs/base/browser/ui/contextview/contextview';
|
|
8
11
|
import { SelectBox } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/ui/selectBox/selectBox';
|
|
9
|
-
import {
|
|
10
|
-
import { CancellationToken, CancellationTokenSource } from '@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation';
|
|
12
|
+
import { CancellationToken, CancellationTokenSource, cancelOnDispose } from '@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation';
|
|
11
13
|
import { Codicon } from '@codingame/monaco-vscode-api/vscode/vs/base/common/codicons';
|
|
12
14
|
import { Emitter, Event } from '@codingame/monaco-vscode-api/vscode/vs/base/common/event';
|
|
15
|
+
import { onUnexpectedError, isCancellationError, getErrorMessage } from '@codingame/monaco-vscode-api/vscode/vs/base/common/errors';
|
|
13
16
|
import { KeyCode } from '@codingame/monaco-vscode-api/vscode/vs/base/common/keyCodes';
|
|
14
17
|
import { DisposableStore, Disposable, MutableDisposable, toDisposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
|
|
15
18
|
import '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/index';
|
|
16
|
-
import { isEqual } from '@codingame/monaco-vscode-api/vscode/vs/base/common/resources';
|
|
19
|
+
import { isEqual, getComparisonKey } from '@codingame/monaco-vscode-api/vscode/vs/base/common/resources';
|
|
20
|
+
import { isStringArray } from '@codingame/monaco-vscode-api/vscode/vs/base/common/types';
|
|
17
21
|
import { ICodeEditorService } from '@codingame/monaco-vscode-api/vscode/vs/editor/browser/services/codeEditorService.service';
|
|
18
22
|
import { EditorOptions } from '@codingame/monaco-vscode-api/vscode/vs/editor/common/config/editorOptions';
|
|
19
23
|
import { EditorContextKeys } from '@codingame/monaco-vscode-api/vscode/vs/editor/common/editorContextKeys';
|
|
@@ -30,26 +34,28 @@ import { ServiceCollection } from '@codingame/monaco-vscode-api/vscode/vs/platfo
|
|
|
30
34
|
import { KeybindingsRegistry, KeybindingWeight } from '@codingame/monaco-vscode-api/vscode/vs/platform/keybinding/common/keybindingsRegistry';
|
|
31
35
|
import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
|
|
32
36
|
import { MenuWorkbenchToolBar, HiddenItemStrategy } from '@codingame/monaco-vscode-api/vscode/vs/platform/actions/browser/toolbar';
|
|
33
|
-
import {
|
|
37
|
+
import { getInputBoxStyle, defaultSelectBoxStyles, defaultButtonStyles, defaultCheckboxStyles } from '@codingame/monaco-vscode-api/vscode/vs/platform/theme/browser/defaultStyles';
|
|
34
38
|
import { hasNativeContextMenu } from '@codingame/monaco-vscode-api/vscode/vs/platform/window/common/window';
|
|
35
39
|
import { WorkspacePicker } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/chat/browser/sessionWorkspacePicker';
|
|
36
|
-
import { BranchPicker } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/chat/browser/branchPicker';
|
|
40
|
+
import { BranchPicker, NEW_WORKTREE_LABEL } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/chat/browser/branchPicker';
|
|
37
41
|
import { MobileSessionTypePicker } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/chat/browser/mobile/mobileSessionTypePicker';
|
|
38
42
|
import { isMobilePickerSheetTarget } from '@codingame/monaco-vscode-api/vscode/vs/sessions/browser/parts/mobile/mobilePickerSheet';
|
|
39
|
-
import { SESSION_WORKSPACE_GROUP_LOCAL } from '@codingame/monaco-vscode-api/vscode/vs/sessions/services/sessions/common/session';
|
|
43
|
+
import { GITHUB_REMOTE_FILE_SCHEME, SESSION_WORKSPACE_GROUP_LOCAL } from '@codingame/monaco-vscode-api/vscode/vs/sessions/services/sessions/common/session';
|
|
40
44
|
import { IGitService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/git/common/gitService.service';
|
|
41
|
-
import { DAYS_OF_WEEK } from '
|
|
45
|
+
import { DAYS_OF_WEEK, automationScheduleToUTC } from '../../../../workbench/contrib/chat/common/automations/schedule.js';
|
|
42
46
|
import { ChatContextKeys } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/actions/chatContextKeys';
|
|
43
47
|
import { ChatAgentLocation } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/constants';
|
|
48
|
+
import { SessionType } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/chatSessionsService';
|
|
44
49
|
import { ChatInputPart } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/browser/widget/input/chatInputPart';
|
|
45
50
|
import { ChatInputPickerResponsiveLayout } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/browser/widget/input/chatInputPickerResponsiveLayout';
|
|
51
|
+
import { settingsTextInputBorder, settingsTextInputForeground, settingsTextInputBackground } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/preferences/common/settingsEditorColorRegistry';
|
|
46
52
|
import { normalizeAutomationBranchNames, AutomationIsolationModel } from '../common/isolationGroupModel.js';
|
|
47
53
|
import { ISessionsManagementService } from '@codingame/monaco-vscode-api/vscode/vs/sessions/services/sessions/common/sessionsManagement.service';
|
|
48
54
|
import { shouldUseMobileWorkspacePickerSheet, showMobileWorkspacePickerSheet } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/chat/browser/mobile/mobileWorkspacePickerSheet';
|
|
49
55
|
import { AutomationInputCompletions } from './automationInputCompletions.js';
|
|
50
56
|
import { NewChatModelPickerService } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/chat/browser/newChatModelPicker';
|
|
51
57
|
import { INewChatModelPickerService } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/chat/browser/newChatModelPicker.service';
|
|
52
|
-
import {
|
|
58
|
+
import { createNewSessionControlToolbar } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/chat/browser/newSessionConfigToolbars';
|
|
53
59
|
import { SessionModelSelection } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/chat/browser/sessionModelSelection';
|
|
54
60
|
import { ISessionModelSelection } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/chat/browser/sessionModelSelection.service';
|
|
55
61
|
import { SessionContext } from '@codingame/monaco-vscode-api/vscode/vs/sessions/services/sessions/browser/sessionContext';
|
|
@@ -59,24 +65,35 @@ import { setActiveSessionContextKeys } from '../../../services/sessions/common/s
|
|
|
59
65
|
import { SessionUsesCombinedConfigPickerContext } from '@codingame/monaco-vscode-api/vscode/vs/sessions/common/contextkeys';
|
|
60
66
|
import { Menus } from '@codingame/monaco-vscode-api/vscode/vs/sessions/browser/menus';
|
|
61
67
|
import { derived } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/derived';
|
|
62
|
-
import {
|
|
63
|
-
import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
|
|
68
|
+
import { AnchorPosition } from '@codingame/monaco-vscode-api/vscode/vs/base/common/layout';
|
|
64
69
|
import { observableValue, disposableObservableValue } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/observableValue';
|
|
65
70
|
import { observableSignalFromEvent } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/observableSignalFromEvent';
|
|
71
|
+
import { constObservable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/constObservable';
|
|
72
|
+
import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
|
|
73
|
+
import { transaction } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/transaction';
|
|
74
|
+
import { waitForState } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/utils/utilsCancellation';
|
|
66
75
|
|
|
67
76
|
const $ = $$1;
|
|
77
|
+
const automationNameInputBoxStyles = getInputBoxStyle({
|
|
78
|
+
inputBackground: settingsTextInputBackground,
|
|
79
|
+
inputForeground: settingsTextInputForeground,
|
|
80
|
+
inputBorder: settingsTextInputBorder
|
|
81
|
+
});
|
|
68
82
|
const INTERVALS = [{
|
|
69
83
|
value: "manual",
|
|
70
|
-
label: ( localize(
|
|
84
|
+
label: ( localize(3670, "Manual"))
|
|
71
85
|
}, {
|
|
72
86
|
value: "hourly",
|
|
73
|
-
label: ( localize(
|
|
87
|
+
label: ( localize(3671, "Hourly"))
|
|
74
88
|
}, {
|
|
75
89
|
value: "daily",
|
|
76
|
-
label: ( localize(
|
|
90
|
+
label: ( localize(3672, "Daily"))
|
|
91
|
+
}, {
|
|
92
|
+
value: "weekdays",
|
|
93
|
+
label: ( localize(3673, "Weekdays"))
|
|
77
94
|
}, {
|
|
78
95
|
value: "weekly",
|
|
79
|
-
label: ( localize(
|
|
96
|
+
label: ( localize(3674, "Weekly"))
|
|
80
97
|
}];
|
|
81
98
|
function isAutomationDialogPopupTarget(relatedTarget) {
|
|
82
99
|
return isMobilePickerSheetTarget(relatedTarget) || !!relatedTarget.closest(
|
|
@@ -102,7 +119,7 @@ async function canSelectAutomationWorkspace(
|
|
|
102
119
|
return !!(await workspaceTrustRequestService.requestResourcesTrust({
|
|
103
120
|
uri: folderUri,
|
|
104
121
|
message: ( localize(
|
|
105
|
-
|
|
122
|
+
3675,
|
|
106
123
|
"An agent session will be able to read files, run commands, and make changes in this folder."
|
|
107
124
|
))
|
|
108
125
|
}));
|
|
@@ -184,6 +201,20 @@ function registerAutomationDialogKeyboardNavigation(
|
|
|
184
201
|
dispose: () => store.dispose()
|
|
185
202
|
};
|
|
186
203
|
}
|
|
204
|
+
function getAutomationDialogProviders(automationService, existing) {
|
|
205
|
+
return derived(reader => {
|
|
206
|
+
if (existing === undefined) {
|
|
207
|
+
return automationService.availableProviders.read(reader).map(provider => provider.id);
|
|
208
|
+
}
|
|
209
|
+
automationService.automations.read(reader);
|
|
210
|
+
automationService.catalogueState.read(reader);
|
|
211
|
+
const providerId = existing.target.providerId;
|
|
212
|
+
if (providerId === undefined || !automationService.canUpdateAutomation(existing.id)) {
|
|
213
|
+
return [];
|
|
214
|
+
}
|
|
215
|
+
return [providerId];
|
|
216
|
+
});
|
|
217
|
+
}
|
|
187
218
|
const AUTOMATION_CONFIGURATION_CAPTURE_TIMEOUT_MS = 5_000;
|
|
188
219
|
const AUTOMATION_CONFIGURATION_RETARGET_CAPTURE_TIMEOUT_MS = 1_000;
|
|
189
220
|
class AutomationSessionDraftSynchronizer extends Disposable {
|
|
@@ -471,9 +502,6 @@ function getAutomationToolbarResponsiveItems(toolbar, options = {}) {
|
|
|
471
502
|
isCompact: () => element.classList.contains("compact-picker"),
|
|
472
503
|
setCompact: compact => {
|
|
473
504
|
element.classList.toggle("compact-picker", compact);
|
|
474
|
-
if (action.id === "sessions.modelPicker") {
|
|
475
|
-
options.compactModelPicker?.set(compact, undefined);
|
|
476
|
-
}
|
|
477
505
|
}
|
|
478
506
|
});
|
|
479
507
|
}
|
|
@@ -511,6 +539,7 @@ let AutomationIsolationGroupActionViewItem = class AutomationIsolationGroupActio
|
|
|
511
539
|
this.branchLoadState = "noFolder";
|
|
512
540
|
this.branches = [];
|
|
513
541
|
this.worktreeCapabilityResolved = false;
|
|
542
|
+
this.visibleFromInput = true;
|
|
514
543
|
this.branchPicker = this._register(instantiationService.createInstance(BranchPicker, {
|
|
515
544
|
user: "automationBranchPicker",
|
|
516
545
|
slotClassName: "automation-form-branch-picker-slot",
|
|
@@ -528,8 +557,8 @@ let AutomationIsolationGroupActionViewItem = class AutomationIsolationGroupActio
|
|
|
528
557
|
void this.reloadRepository(this.isolationModel.folderUri);
|
|
529
558
|
},
|
|
530
559
|
isolation: {
|
|
531
|
-
label:
|
|
532
|
-
ariaLabel: ( localize(
|
|
560
|
+
label: NEW_WORKTREE_LABEL,
|
|
561
|
+
ariaLabel: ( localize(3676, "Worktree isolation")),
|
|
533
562
|
onToggle: checked => {
|
|
534
563
|
this.isolationModel.selectIsolationMode(checked ? "worktree" : "workspace");
|
|
535
564
|
this.renderBranchControl();
|
|
@@ -543,10 +572,12 @@ let AutomationIsolationGroupActionViewItem = class AutomationIsolationGroupActio
|
|
|
543
572
|
this.cancelBranchRequest();
|
|
544
573
|
clearNode(container);
|
|
545
574
|
container.style.marginLeft = "auto";
|
|
575
|
+
this.container = container;
|
|
546
576
|
const visible = this.visible;
|
|
547
577
|
if (visible) {
|
|
548
578
|
this.renderDisposables.add(autorun(reader => {
|
|
549
|
-
|
|
579
|
+
this.visibleFromInput = visible.read(reader);
|
|
580
|
+
this.updateVisibility();
|
|
550
581
|
}));
|
|
551
582
|
}
|
|
552
583
|
const isolationGroup = append(container, $("span.automation-form-isolation-group"));
|
|
@@ -573,6 +604,14 @@ let AutomationIsolationGroupActionViewItem = class AutomationIsolationGroupActio
|
|
|
573
604
|
showPicker(anchor) {
|
|
574
605
|
this.branchPicker.showPicker(anchor);
|
|
575
606
|
}
|
|
607
|
+
updateVisibility() {
|
|
608
|
+
if (this.container) {
|
|
609
|
+
setAutomationControlVisible(
|
|
610
|
+
this.container,
|
|
611
|
+
this.visibleFromInput && this.branchLoadState !== "noRepository"
|
|
612
|
+
);
|
|
613
|
+
}
|
|
614
|
+
}
|
|
576
615
|
refreshTargetCapability() {
|
|
577
616
|
const folderUri = this.isolationModel.folderUri;
|
|
578
617
|
const sessionTypeId = this.state.sessionTypeId;
|
|
@@ -631,29 +670,30 @@ let AutomationIsolationGroupActionViewItem = class AutomationIsolationGroupActio
|
|
|
631
670
|
disabledReason: worktreeUnavailableReason
|
|
632
671
|
}
|
|
633
672
|
});
|
|
673
|
+
this.updateVisibility();
|
|
634
674
|
this.revalidate();
|
|
635
675
|
}
|
|
636
676
|
getBranchPresentation() {
|
|
637
677
|
const displayBranch = this.isolationModel.displayBranch;
|
|
638
678
|
if (!this.isolationModel.folderUri) {
|
|
639
679
|
return {
|
|
640
|
-
label: ( localize(
|
|
641
|
-
reason: ( localize(
|
|
680
|
+
label: ( localize(3677, "—")),
|
|
681
|
+
reason: ( localize(3678, "Select a folder to determine its Git branch.")),
|
|
642
682
|
missing: true
|
|
643
683
|
};
|
|
644
684
|
}
|
|
645
685
|
if (!this.worktreeCapabilityResolved) {
|
|
646
686
|
return {
|
|
647
|
-
label: displayBranch ?? ( localize(
|
|
648
|
-
reason: ( localize(
|
|
687
|
+
label: displayBranch ?? ( localize(3677, "—")),
|
|
688
|
+
reason: ( localize(3679, "Session capabilities are loading.")),
|
|
649
689
|
missing: !displayBranch
|
|
650
690
|
};
|
|
651
691
|
}
|
|
652
692
|
if (!this.isolationModel.supportsWorktreeConfiguration) {
|
|
653
693
|
return {
|
|
654
|
-
label: displayBranch ?? ( localize(
|
|
694
|
+
label: displayBranch ?? ( localize(3677, "—")),
|
|
655
695
|
reason: ( localize(
|
|
656
|
-
|
|
696
|
+
3680,
|
|
657
697
|
"The selected session type does not support Worktree branch configuration."
|
|
658
698
|
)),
|
|
659
699
|
missing: !displayBranch
|
|
@@ -661,15 +701,15 @@ let AutomationIsolationGroupActionViewItem = class AutomationIsolationGroupActio
|
|
|
661
701
|
}
|
|
662
702
|
if (this.branchLoadState === "error") {
|
|
663
703
|
return {
|
|
664
|
-
label: displayBranch ?? ( localize(
|
|
665
|
-
reason: ( localize(
|
|
704
|
+
label: displayBranch ?? ( localize(3681, "Unable to load branches")),
|
|
705
|
+
reason: ( localize(3682, "Open the branch picker to retry loading local branches.")),
|
|
666
706
|
missing: !displayBranch
|
|
667
707
|
};
|
|
668
708
|
}
|
|
669
709
|
if (this.isolationModel.isolationMode !== "worktree") {
|
|
670
710
|
return {
|
|
671
|
-
label: displayBranch ?? this.detachedCommit ?? ( localize(
|
|
672
|
-
reason: ( localize(
|
|
711
|
+
label: displayBranch ?? this.detachedCommit ?? ( localize(3677, "—")),
|
|
712
|
+
reason: ( localize(3683, "Select Worktree to choose a branch.")),
|
|
673
713
|
missing: !displayBranch && !this.detachedCommit
|
|
674
714
|
};
|
|
675
715
|
}
|
|
@@ -677,32 +717,32 @@ let AutomationIsolationGroupActionViewItem = class AutomationIsolationGroupActio
|
|
|
677
717
|
case "loadingRepository":
|
|
678
718
|
case "loadingBranches":
|
|
679
719
|
return {
|
|
680
|
-
label: displayBranch ?? ( localize(
|
|
681
|
-
reason: ( localize(
|
|
720
|
+
label: displayBranch ?? ( localize(3684, "Loading branches…")),
|
|
721
|
+
reason: ( localize(3685, "Local branches are loading.")),
|
|
682
722
|
missing: !displayBranch
|
|
683
723
|
};
|
|
684
724
|
case "noRepository":
|
|
685
725
|
return {
|
|
686
|
-
label: displayBranch ?? ( localize(
|
|
687
|
-
reason: ( localize(
|
|
726
|
+
label: displayBranch ?? ( localize(3686, "no git repo")),
|
|
727
|
+
reason: ( localize(3687, "No Git repository was found for the selected folder.")),
|
|
688
728
|
missing: !displayBranch
|
|
689
729
|
};
|
|
690
730
|
case "empty":
|
|
691
731
|
return {
|
|
692
|
-
label: displayBranch ?? ( localize(
|
|
693
|
-
reason: ( localize(
|
|
732
|
+
label: displayBranch ?? ( localize(3688, "No local branches")),
|
|
733
|
+
reason: ( localize(3689, "No local branches were found in this repository.")),
|
|
694
734
|
missing: !displayBranch
|
|
695
735
|
};
|
|
696
736
|
case "ready":
|
|
697
737
|
return {
|
|
698
|
-
label: displayBranch ?? ( localize(
|
|
699
|
-
reason: ( localize(
|
|
738
|
+
label: displayBranch ?? ( localize(3690, "Select branch")),
|
|
739
|
+
reason: ( localize(3691, "Choose the local branch to use as the Worktree base.")),
|
|
700
740
|
missing: !displayBranch
|
|
701
741
|
};
|
|
702
742
|
case "noFolder":
|
|
703
743
|
return {
|
|
704
|
-
label: ( localize(
|
|
705
|
-
reason: ( localize(
|
|
744
|
+
label: ( localize(3677, "—")),
|
|
745
|
+
reason: ( localize(3678, "Select a folder to determine its Git branch.")),
|
|
706
746
|
missing: true
|
|
707
747
|
};
|
|
708
748
|
}
|
|
@@ -715,13 +755,13 @@ let AutomationIsolationGroupActionViewItem = class AutomationIsolationGroupActio
|
|
|
715
755
|
}
|
|
716
756
|
getWorktreeUnavailableReason() {
|
|
717
757
|
if (!this.isolationModel.folderUri) {
|
|
718
|
-
return localize(
|
|
758
|
+
return localize(3692, "Select a folder to use Worktree isolation.");
|
|
719
759
|
}
|
|
720
760
|
if (!this.worktreeCapabilityResolved) {
|
|
721
|
-
return localize(
|
|
761
|
+
return localize(3679, "Session capabilities are loading.");
|
|
722
762
|
}
|
|
723
763
|
if (!this.isolationModel.supportsWorktreeConfiguration) {
|
|
724
|
-
return localize(
|
|
764
|
+
return localize(3693, "Not supported by the selected session type");
|
|
725
765
|
}
|
|
726
766
|
if (this.isolationModel.selectedBranch) {
|
|
727
767
|
return undefined;
|
|
@@ -729,17 +769,17 @@ let AutomationIsolationGroupActionViewItem = class AutomationIsolationGroupActio
|
|
|
729
769
|
switch (this.branchLoadState) {
|
|
730
770
|
case "loadingRepository":
|
|
731
771
|
case "loadingBranches":
|
|
732
|
-
return localize(
|
|
772
|
+
return localize(3685, "Local branches are loading.");
|
|
733
773
|
case "noRepository":
|
|
734
|
-
return localize(
|
|
774
|
+
return localize(3687, "No Git repository was found for the selected folder.");
|
|
735
775
|
case "error":
|
|
736
|
-
return localize(
|
|
776
|
+
return localize(3682, "Open the branch picker to retry loading local branches.");
|
|
737
777
|
case "empty":
|
|
738
|
-
return localize(
|
|
778
|
+
return localize(3689, "No local branches were found in this repository.");
|
|
739
779
|
case "ready":
|
|
740
|
-
return this.branches.length > 0 ? undefined : ( localize(
|
|
780
|
+
return this.branches.length > 0 ? undefined : ( localize(3689, "No local branches were found in this repository."));
|
|
741
781
|
case "noFolder":
|
|
742
|
-
return localize(
|
|
782
|
+
return localize(3692, "Select a folder to use Worktree isolation.");
|
|
743
783
|
}
|
|
744
784
|
}
|
|
745
785
|
cancelBranchRequest() {
|
|
@@ -783,6 +823,9 @@ let AutomationIsolationGroupActionViewItem = class AutomationIsolationGroupActio
|
|
|
783
823
|
}
|
|
784
824
|
if (!repo) {
|
|
785
825
|
this.branchLoadState = "noRepository";
|
|
826
|
+
if (this.isolationModel.isolationMode === "worktree") {
|
|
827
|
+
this.isolationModel.selectIsolationMode("workspace");
|
|
828
|
+
}
|
|
786
829
|
this.renderBranchControl();
|
|
787
830
|
return;
|
|
788
831
|
}
|
|
@@ -794,7 +837,7 @@ let AutomationIsolationGroupActionViewItem = class AutomationIsolationGroupActio
|
|
|
794
837
|
this.detachedCommit = undefined;
|
|
795
838
|
this.isolationModel.setHeadBranch(head.name);
|
|
796
839
|
} else if (head?.commit) {
|
|
797
|
-
this.detachedCommit = ( localize(
|
|
840
|
+
this.detachedCommit = ( localize(3694, "({0})", head.commit.slice(0, 7)));
|
|
798
841
|
this.isolationModel.setHeadBranch(undefined);
|
|
799
842
|
} else {
|
|
800
843
|
this.detachedCommit = undefined;
|
|
@@ -846,7 +889,7 @@ registerAction2(class OpenAutomationsHarnessChipAction extends Action2 {
|
|
|
846
889
|
constructor() {
|
|
847
890
|
super({
|
|
848
891
|
id: AUTOMATIONS_HARNESS_CHIP_ACTION_ID,
|
|
849
|
-
title: ( localize2(
|
|
892
|
+
title: ( localize2(3695, "Automations Harness Chip")),
|
|
850
893
|
f1: false,
|
|
851
894
|
precondition: ChatContextKeys.enabled,
|
|
852
895
|
menu: [{
|
|
@@ -863,7 +906,7 @@ registerAction2(class OpenAutomationsWorkspacePickerAction extends Action2 {
|
|
|
863
906
|
constructor() {
|
|
864
907
|
super({
|
|
865
908
|
id: AUTOMATIONS_WORKSPACE_PICKER_ACTION_ID,
|
|
866
|
-
title: ( localize2(
|
|
909
|
+
title: ( localize2(3696, "Automations Workspace Picker")),
|
|
867
910
|
f1: false,
|
|
868
911
|
precondition: ChatContextKeys.enabled,
|
|
869
912
|
menu: [{
|
|
@@ -880,7 +923,7 @@ registerAction2(class OpenAutomationsIsolationGroupAction extends Action2 {
|
|
|
880
923
|
constructor() {
|
|
881
924
|
super({
|
|
882
925
|
id: AUTOMATIONS_ISOLATION_GROUP_ACTION_ID,
|
|
883
|
-
title: ( localize2(
|
|
926
|
+
title: ( localize2(3697, "Automations Isolation Group")),
|
|
884
927
|
f1: false,
|
|
885
928
|
precondition: ChatContextKeys.enabled,
|
|
886
929
|
menu: [{
|
|
@@ -909,27 +952,45 @@ function renderForm(
|
|
|
909
952
|
workspaceTrustRequestService,
|
|
910
953
|
initialPrompt,
|
|
911
954
|
initialTarget,
|
|
912
|
-
initialSessionConfiguration
|
|
955
|
+
initialSessionConfiguration,
|
|
956
|
+
allowedProviders,
|
|
957
|
+
getProviderConfiguration = () => undefined,
|
|
958
|
+
isEdit = false,
|
|
959
|
+
customizations,
|
|
960
|
+
notifyError = onUnexpectedError,
|
|
961
|
+
quickInputService
|
|
913
962
|
) {
|
|
963
|
+
let reloadCustomizations = () => {};
|
|
964
|
+
const validateForm = revalidate;
|
|
965
|
+
revalidate = () => {
|
|
966
|
+
reloadCustomizations();
|
|
967
|
+
validateForm();
|
|
968
|
+
};
|
|
914
969
|
const formContent = append(form, $(".automation-form-content"));
|
|
915
970
|
const nameRow = append(formContent, $(".automation-form-row"));
|
|
916
|
-
append(nameRow, $("span.automation-form-label", undefined, ( localize(
|
|
971
|
+
append(nameRow, $("span.automation-form-label", undefined, ( localize(3698, "Name"))));
|
|
917
972
|
const nameInputContainer = append(nameRow, $(".automation-form-input-host"));
|
|
918
973
|
const nameInput = disposables.add(( new InputBox(nameInputContainer, contextViewService, {
|
|
919
|
-
inputBoxStyles:
|
|
920
|
-
placeholder: ( localize(
|
|
921
|
-
ariaLabel: ( localize(
|
|
974
|
+
inputBoxStyles: automationNameInputBoxStyles,
|
|
975
|
+
placeholder: ( localize(3699, "e.g. Morning standup notes")),
|
|
976
|
+
ariaLabel: ( localize(3698, "Name"))
|
|
922
977
|
})));
|
|
923
978
|
nameInput.value = state.name;
|
|
924
979
|
disposables.add(nameInput.onDidChange(value => {
|
|
925
980
|
state.name = value;
|
|
926
981
|
revalidate();
|
|
927
982
|
}));
|
|
983
|
+
const sessionSection = append(formContent, $(".automation-session-section"));
|
|
928
984
|
const scheduleRow = append(formContent, $(".automation-form-row.automation-form-schedule-row"));
|
|
929
|
-
const
|
|
985
|
+
const scheduleSelectOptions = {
|
|
986
|
+
useCustomDrawn: !hasNativeContextMenu(configurationService),
|
|
987
|
+
anchorPosition: AnchorPosition.ABOVE,
|
|
988
|
+
maxVisibleOptions: 6
|
|
989
|
+
};
|
|
930
990
|
const intervalGroup = append(scheduleRow, $(".automation-form-schedule-group"));
|
|
931
|
-
append(intervalGroup, $("span.automation-form-label", undefined, ( localize(
|
|
932
|
-
|
|
991
|
+
append(intervalGroup, $("span.automation-form-label", undefined, ( localize(3700, "Schedule"))));
|
|
992
|
+
let intervals = INTERVALS;
|
|
993
|
+
const intervalOptions = intervals.map(item => ({
|
|
933
994
|
text: item.label
|
|
934
995
|
}));
|
|
935
996
|
const intervalIndex = Math.max(0, INTERVALS.findIndex(item => item.value === state.interval));
|
|
@@ -939,8 +1000,8 @@ function renderForm(
|
|
|
939
1000
|
contextViewService,
|
|
940
1001
|
defaultSelectBoxStyles,
|
|
941
1002
|
{
|
|
942
|
-
|
|
943
|
-
|
|
1003
|
+
...scheduleSelectOptions,
|
|
1004
|
+
ariaLabel: ( localize(3700, "Schedule"))
|
|
944
1005
|
}
|
|
945
1006
|
)));
|
|
946
1007
|
const intervalSelectContainer = append(intervalGroup, $(".automation-form-schedule-select-container"));
|
|
@@ -949,16 +1010,14 @@ function renderForm(
|
|
|
949
1010
|
scheduleRow,
|
|
950
1011
|
$(".automation-form-schedule-group.automation-form-time-group")
|
|
951
1012
|
);
|
|
952
|
-
append(timeGroup, $("span.automation-form-label", undefined, ( localize(
|
|
953
|
-
const timeOptions = buildTimeOptions();
|
|
954
|
-
const initialTimeIndex =
|
|
955
|
-
state.hour = timeOptions[initialTimeIndex].hour;
|
|
956
|
-
state.minute = timeOptions[initialTimeIndex].minute;
|
|
1013
|
+
const timeLabel = append(timeGroup, $("span.automation-form-label", undefined, ( localize(3701, "Time"))));
|
|
1014
|
+
const timeOptions = buildTimeOptions(state.hour, state.minute);
|
|
1015
|
+
const initialTimeIndex = timeOptions.findIndex(option => option.hour === state.hour && option.minute === state.minute);
|
|
957
1016
|
const timeSelect = disposables.add(( new SelectBox(timeOptions.map(opt => ({
|
|
958
1017
|
text: opt.label
|
|
959
1018
|
})), initialTimeIndex, contextViewService, defaultSelectBoxStyles, {
|
|
960
|
-
|
|
961
|
-
|
|
1019
|
+
...scheduleSelectOptions,
|
|
1020
|
+
ariaLabel: ( localize(3701, "Time"))
|
|
962
1021
|
})));
|
|
963
1022
|
const timeSelectContainer = append(timeGroup, $(
|
|
964
1023
|
".automation-form-schedule-select-container.automation-form-time-select-container"
|
|
@@ -968,12 +1027,13 @@ function renderForm(
|
|
|
968
1027
|
const opt = timeOptions[e.index];
|
|
969
1028
|
state.hour = opt.hour;
|
|
970
1029
|
state.minute = opt.minute;
|
|
1030
|
+
revalidate();
|
|
971
1031
|
}));
|
|
972
1032
|
const dayGroup = append(
|
|
973
1033
|
scheduleRow,
|
|
974
1034
|
$(".automation-form-schedule-group.automation-form-day-group")
|
|
975
1035
|
);
|
|
976
|
-
append(dayGroup, $("span.automation-form-label", undefined, ( localize(
|
|
1036
|
+
append(dayGroup, $("span.automation-form-label", undefined, ( localize(3702, "Day of week"))));
|
|
977
1037
|
const dayOptions = DAYS_OF_WEEK.map(d => ({
|
|
978
1038
|
text: d
|
|
979
1039
|
}));
|
|
@@ -983,34 +1043,92 @@ function renderForm(
|
|
|
983
1043
|
contextViewService,
|
|
984
1044
|
defaultSelectBoxStyles,
|
|
985
1045
|
{
|
|
986
|
-
|
|
987
|
-
|
|
1046
|
+
...scheduleSelectOptions,
|
|
1047
|
+
ariaLabel: ( localize(3702, "Day of week"))
|
|
988
1048
|
}
|
|
989
1049
|
)));
|
|
990
1050
|
const daySelectContainer = append(dayGroup, $(".automation-form-schedule-select-container"));
|
|
991
1051
|
daySelect.render(daySelectContainer);
|
|
992
1052
|
disposables.add(daySelect.onDidSelect(e => {
|
|
993
1053
|
state.day = e.index;
|
|
1054
|
+
revalidate();
|
|
1055
|
+
}));
|
|
1056
|
+
const scheduleError = append(formContent, $("span.automation-target-error", {
|
|
1057
|
+
role: "status",
|
|
1058
|
+
"aria-live": "polite"
|
|
994
1059
|
}));
|
|
1060
|
+
hide(scheduleError);
|
|
995
1061
|
const applyIntervalVisibility = () => {
|
|
996
|
-
const showTime = state.interval === "daily" || state.interval === "weekly";
|
|
1062
|
+
const showTime = state.interval === "daily" || state.interval === "weekdays" || state.interval === "weekly";
|
|
997
1063
|
const showDay = state.interval === "weekly";
|
|
998
1064
|
timeGroup.style.display = showTime ? "" : "none";
|
|
999
1065
|
dayGroup.style.display = showDay ? "" : "none";
|
|
1000
1066
|
};
|
|
1067
|
+
const updateIntervalOptions = cloud => {
|
|
1068
|
+
intervals = INTERVALS.filter(item => !cloud || item.value !== "weekdays");
|
|
1069
|
+
const unsupportedInterval = !( intervals.some(item => item.value === state.interval));
|
|
1070
|
+
if (unsupportedInterval) {
|
|
1071
|
+
intervals = [{
|
|
1072
|
+
value: state.interval,
|
|
1073
|
+
label: ( localize(3703, "Choose a schedule"))
|
|
1074
|
+
}, ...intervals];
|
|
1075
|
+
}
|
|
1076
|
+
intervalSelect.setOptions(intervals.map(item => ({
|
|
1077
|
+
text: item.label,
|
|
1078
|
+
isDisabled: unsupportedInterval && item.value === state.interval
|
|
1079
|
+
})), Math.max(0, intervals.findIndex(item => item.value === state.interval)));
|
|
1080
|
+
applyIntervalVisibility();
|
|
1081
|
+
};
|
|
1001
1082
|
applyIntervalVisibility();
|
|
1002
1083
|
disposables.add(intervalSelect.onDidSelect(e => {
|
|
1003
|
-
state.interval =
|
|
1004
|
-
|
|
1084
|
+
state.interval = intervals[e.index].value;
|
|
1085
|
+
updateIntervalOptions(getProviderConfiguration(state.providerId) !== undefined);
|
|
1086
|
+
revalidate();
|
|
1005
1087
|
}));
|
|
1088
|
+
const initialProviderConfiguration = getProviderConfiguration(state.providerId);
|
|
1089
|
+
const selectedProvider = observableValue(form, state.providerId);
|
|
1090
|
+
const cloudProvider = derived(
|
|
1091
|
+
reader => allowedProviders.read(reader).find(id => getProviderConfiguration(id) !== undefined) ?? (isEdit ? undefined : sessionsManagementService.getAllProviderSessionTypes().find(
|
|
1092
|
+
type => getProviderConfiguration(type.providerId)?.sessionTypes.includes(type.sessionType.id)
|
|
1093
|
+
)?.providerId)
|
|
1094
|
+
);
|
|
1095
|
+
const availableCloudConfiguration = derived(reader => getProviderConfiguration(cloudProvider.read(reader)));
|
|
1096
|
+
const cloudConfiguration = derived(reader => {
|
|
1097
|
+
allowedProviders.read(reader);
|
|
1098
|
+
return getProviderConfiguration(selectedProvider.read(reader));
|
|
1099
|
+
});
|
|
1100
|
+
const runInCloud = derived(reader => cloudConfiguration.read(reader) !== undefined);
|
|
1101
|
+
const sessionConfigurationErrorMessage = observableValue(form, undefined);
|
|
1102
|
+
let switchingTarget = false;
|
|
1103
|
+
let localTarget = {
|
|
1104
|
+
...state
|
|
1105
|
+
};
|
|
1006
1106
|
const isolationModel = ( new AutomationIsolationModel(state));
|
|
1007
1107
|
const workspaceControlsVisible = derived(
|
|
1008
|
-
reader => !isolationModel.isQuickChatObs.read(reader) && isolationModel.folderUriObs.read(reader) !== undefined
|
|
1108
|
+
reader => !runInCloud.read(reader) && !isolationModel.isQuickChatObs.read(reader) && isolationModel.folderUriObs.read(reader)?.scheme !== GITHUB_REMOTE_FILE_SCHEME && isolationModel.folderUriObs.read(reader) !== undefined
|
|
1009
1109
|
);
|
|
1110
|
+
const sessionTypesChanged = observableSignalFromEvent(form, sessionsManagementService.onDidChangeSessionTypes);
|
|
1111
|
+
const sessionTypes = derived(reader => {
|
|
1112
|
+
sessionTypesChanged.read(reader);
|
|
1113
|
+
const folder = isolationModel.folderUriObs.read(reader);
|
|
1114
|
+
const quickChat = isolationModel.isQuickChatObs.read(reader);
|
|
1115
|
+
return quickChat ? sessionsManagementService.getQuickChatSessionTypes() : folder ? sessionsManagementService.getSessionTypesForFolder(folder) : [];
|
|
1116
|
+
});
|
|
1117
|
+
const pickerProviders = derived(reader => {
|
|
1118
|
+
const folder = isolationModel.folderUriObs.read(reader);
|
|
1119
|
+
const allowed = allowedProviders.read(reader);
|
|
1120
|
+
const cloud = cloudProvider.read(reader);
|
|
1121
|
+
return [...allowed, ...(cloud && !allowed.includes(cloud) ? [cloud] : [])].filter(
|
|
1122
|
+
id => isEdit || !getProviderConfiguration(id)?.getWorkspaceTarget(folder).read(reader).isPublicRepository
|
|
1123
|
+
);
|
|
1124
|
+
});
|
|
1010
1125
|
const sessionTypePicker = disposables.add(
|
|
1011
1126
|
instantiationService.createInstance(MobileSessionTypePicker, constObservable(undefined), {
|
|
1012
1127
|
persistSelection: false,
|
|
1013
|
-
|
|
1128
|
+
preserveUnavailableSelection: true,
|
|
1129
|
+
telemetrySource: "AutomationSessionTypePicker",
|
|
1130
|
+
allowedProviders: pickerProviders,
|
|
1131
|
+
prepareSessionTypeSelection: () => workspacePicker.onWillSelectWorkspace()
|
|
1014
1132
|
})
|
|
1015
1133
|
);
|
|
1016
1134
|
sessionTypePicker.setQuickChatSource(isolationModel.isQuickChatObs);
|
|
@@ -1028,9 +1146,51 @@ function renderForm(
|
|
|
1028
1146
|
onDidChangeActiveSessionProvider: onDidChangeSessionType.event
|
|
1029
1147
|
};
|
|
1030
1148
|
const syncStateFromPicker = () => {
|
|
1031
|
-
|
|
1149
|
+
if (switchingTarget) {
|
|
1150
|
+
return;
|
|
1151
|
+
}
|
|
1152
|
+
let pick = sessionTypePicker.selectedPick;
|
|
1153
|
+
if (!isEdit && pick && getProviderConfiguration(pick.providerId)?.getWorkspaceTarget(state.folderUri).get().isPublicRepository) {
|
|
1154
|
+
const localTypes = sessionTypes.get().filter(
|
|
1155
|
+
type => pickerProviders.get().includes(type.providerId) && !getProviderConfiguration(type.providerId)
|
|
1156
|
+
);
|
|
1157
|
+
const fallback = localTypes.find(type => type.sessionType.id === SessionType.CopilotCLI) ?? localTypes.find(
|
|
1158
|
+
type => type.providerId === localTarget.providerId && type.sessionType.id === localTarget.sessionTypeId
|
|
1159
|
+
) ?? localTypes[0];
|
|
1160
|
+
if (fallback) {
|
|
1161
|
+
sessionTypePicker.setFolderSource(isolationModel.folderUriObs, {
|
|
1162
|
+
initialPick: {
|
|
1163
|
+
providerId: fallback.providerId,
|
|
1164
|
+
sessionTypeId: fallback.sessionType.id
|
|
1165
|
+
}
|
|
1166
|
+
});
|
|
1167
|
+
pick = sessionTypePicker.selectedPick;
|
|
1168
|
+
}
|
|
1169
|
+
}
|
|
1032
1170
|
state.providerId = pick?.providerId;
|
|
1033
1171
|
state.sessionTypeId = pick?.sessionTypeId;
|
|
1172
|
+
const wasCloud = selectedProvider.get() !== undefined && getProviderConfiguration(selectedProvider.get()) !== undefined;
|
|
1173
|
+
selectedProvider.set(state.providerId, undefined);
|
|
1174
|
+
const configuration = cloudConfiguration.get();
|
|
1175
|
+
const target = configuration?.getWorkspaceTarget(state.folderUri).get();
|
|
1176
|
+
state.resolvedFolderUri = target?.workspace;
|
|
1177
|
+
state.targetPending = target?.pending ? {
|
|
1178
|
+
message: target.disabledReason ?? ( localize(3704, "Checking target availability..."))
|
|
1179
|
+
} : undefined;
|
|
1180
|
+
state.targetDisabledReason = target?.pending ? undefined : target?.disabledReason;
|
|
1181
|
+
state.timeZone = configuration?.timeZone;
|
|
1182
|
+
if (runInCloud.get()) {
|
|
1183
|
+
state.isolationMode = undefined;
|
|
1184
|
+
state.branch = undefined;
|
|
1185
|
+
if (configuration && isEdit && initialTarget?.kind === "workspace" && target?.workspace && !isEqual(initialTarget.folderUri, target.workspace)) {
|
|
1186
|
+
state.targetDisabledReason = configuration.targetChangeDisabledReason;
|
|
1187
|
+
}
|
|
1188
|
+
} else if (wasCloud && isEqual(state.folderUri, localTarget.folderUri)) {
|
|
1189
|
+
state.isolationMode = localTarget.isolationMode;
|
|
1190
|
+
if (localTarget.branch) {
|
|
1191
|
+
isolationModel.selectBranch(localTarget.branch);
|
|
1192
|
+
}
|
|
1193
|
+
}
|
|
1034
1194
|
onDidChangeSessionTarget.fire();
|
|
1035
1195
|
};
|
|
1036
1196
|
disposables.add(autorun(reader => {
|
|
@@ -1043,7 +1203,9 @@ function renderForm(
|
|
|
1043
1203
|
const workspacePicker = disposables.add(instantiationService.createInstance(MobileAutomationsWorkspacePicker, {
|
|
1044
1204
|
restoreFromSessions: false,
|
|
1045
1205
|
canRestoreWorkspace: () => false,
|
|
1046
|
-
canSelectWorkspace: (folderUri, preferredProviderId) =>
|
|
1206
|
+
canSelectWorkspace: (folderUri, preferredProviderId) => folderUri.scheme === GITHUB_REMOTE_FILE_SCHEME ? Promise.resolve(
|
|
1207
|
+
availableCloudConfiguration.get()?.getWorkspaceTarget(folderUri).get().workspace !== undefined
|
|
1208
|
+
) : canSelectAutomationWorkspace(
|
|
1047
1209
|
folderUri,
|
|
1048
1210
|
preferredProviderId,
|
|
1049
1211
|
sessionsManagementService,
|
|
@@ -1052,6 +1214,14 @@ function renderForm(
|
|
|
1052
1214
|
}));
|
|
1053
1215
|
workspacePicker.setTargetModel(isolationModel);
|
|
1054
1216
|
workspacePicker.setLayoutService(layoutService);
|
|
1217
|
+
workspacePicker.setCloudConfiguration(availableCloudConfiguration);
|
|
1218
|
+
if (isEdit && initialProviderConfiguration) {
|
|
1219
|
+
workspacePicker.setDisabledReason(initialProviderConfiguration.targetChangeDisabledReason);
|
|
1220
|
+
}
|
|
1221
|
+
workspacePicker.onSelectionError = error => {
|
|
1222
|
+
logService.error("[AutomationDialog] Workspace selection failed.", error);
|
|
1223
|
+
notifyError(error);
|
|
1224
|
+
};
|
|
1055
1225
|
const automationSessionDraftSynchronizer = disposables.add(( new AutomationSessionDraftSynchronizer(
|
|
1056
1226
|
sessionsManagementService,
|
|
1057
1227
|
(folderUri, preferredProviderId) => canSelectAutomationWorkspace(
|
|
@@ -1082,10 +1252,13 @@ function renderForm(
|
|
|
1082
1252
|
return initialSessionConfiguration;
|
|
1083
1253
|
};
|
|
1084
1254
|
const updateAutomationSessionTarget = () => {
|
|
1085
|
-
|
|
1255
|
+
if (switchingTarget) {
|
|
1256
|
+
return;
|
|
1257
|
+
}
|
|
1258
|
+
const folderUri = runInCloud.get() ? state.resolvedFolderUri : isolationModel.folderUriObs.get();
|
|
1086
1259
|
const pick = sessionTypePicker.selectedPick;
|
|
1087
1260
|
const isQuickChat = isolationModel.isQuickChatObs.get();
|
|
1088
|
-
if (!pick ||
|
|
1261
|
+
if (!pick || state.targetDisabledReason || state.targetPending || pick.providerId === undefined || !allowedProviders.get().includes(pick.providerId) || (!isQuickChat && !folderUri)) {
|
|
1089
1262
|
automationSessionDraftSynchronizer.update(undefined);
|
|
1090
1263
|
return;
|
|
1091
1264
|
}
|
|
@@ -1114,38 +1287,144 @@ function renderForm(
|
|
|
1114
1287
|
updateAutomationSessionTarget();
|
|
1115
1288
|
revalidate();
|
|
1116
1289
|
}));
|
|
1117
|
-
disposables.add(
|
|
1118
|
-
|
|
1119
|
-
|
|
1290
|
+
disposables.add(sessionsManagementService.onDidChangeSessionTypes(() => {
|
|
1291
|
+
updateAutomationSessionTarget();
|
|
1292
|
+
revalidate();
|
|
1293
|
+
}));
|
|
1294
|
+
disposables.add(autorun(reader => {
|
|
1295
|
+
allowedProviders.read(reader);
|
|
1296
|
+
pickerProviders.read(reader);
|
|
1297
|
+
sessionTypes.read(reader);
|
|
1298
|
+
cloudConfiguration.read(reader)?.getWorkspaceTarget(isolationModel.folderUriObs.read(reader)).read(reader);
|
|
1299
|
+
syncStateFromPicker();
|
|
1300
|
+
updateAutomationSessionTarget();
|
|
1301
|
+
revalidate();
|
|
1302
|
+
}));
|
|
1120
1303
|
if (state.folderUri) {
|
|
1121
1304
|
workspacePicker.setSelectedWorkspace(state.folderUri, {
|
|
1122
1305
|
fireEvent: false,
|
|
1123
1306
|
persist: false
|
|
1124
1307
|
});
|
|
1125
1308
|
}
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
|
|
1309
|
+
const targetSwitchCancellation = cancelOnDispose(disposables);
|
|
1310
|
+
workspacePicker.onWillSelectWorkspace = async () => {
|
|
1311
|
+
if (switchingTarget) {
|
|
1312
|
+
return false;
|
|
1130
1313
|
}
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1314
|
+
if (!runInCloud.get()) {
|
|
1315
|
+
localTarget = {
|
|
1316
|
+
...state,
|
|
1317
|
+
branch: isolationModel.persistedBranch
|
|
1318
|
+
};
|
|
1319
|
+
}
|
|
1320
|
+
switchingTarget = true;
|
|
1321
|
+
formContent.toggleAttribute("inert", true);
|
|
1322
|
+
formContent.setAttribute("aria-busy", "true");
|
|
1323
|
+
state.targetDisabledReason = undefined;
|
|
1324
|
+
state.targetPending = {
|
|
1325
|
+
message: ( localize(3705, "Saving the current session configuration..."))
|
|
1326
|
+
};
|
|
1327
|
+
revalidate();
|
|
1328
|
+
try {
|
|
1329
|
+
const capture = await automationSessionDraftSynchronizer.getSessionConfiguration(targetSwitchCancellation);
|
|
1330
|
+
if (capture.kind === "failed") {
|
|
1331
|
+
throw capture.error;
|
|
1332
|
+
}
|
|
1333
|
+
return !disposables.isDisposed;
|
|
1334
|
+
} catch (error) {
|
|
1335
|
+
if (!isCancellationError(error) && !disposables.isDisposed) {
|
|
1336
|
+
logService.error(
|
|
1337
|
+
"[AutomationDialog] Failed to capture the outgoing session configuration.",
|
|
1338
|
+
error
|
|
1339
|
+
);
|
|
1340
|
+
sessionConfigurationErrorMessage.set(getErrorMessage(error), undefined);
|
|
1341
|
+
}
|
|
1342
|
+
return false;
|
|
1343
|
+
} finally {
|
|
1344
|
+
switchingTarget = false;
|
|
1345
|
+
if (!disposables.isDisposed) {
|
|
1346
|
+
formContent.toggleAttribute("inert", false);
|
|
1347
|
+
formContent.setAttribute("aria-busy", "false");
|
|
1348
|
+
syncStateFromPicker();
|
|
1349
|
+
updateAutomationSessionTarget();
|
|
1350
|
+
revalidate();
|
|
1351
|
+
}
|
|
1352
|
+
}
|
|
1353
|
+
};
|
|
1354
|
+
const applyWorkspaceTarget = uri => {
|
|
1355
|
+
if (switchingTarget) {
|
|
1356
|
+
return;
|
|
1357
|
+
}
|
|
1358
|
+
switchingTarget = true;
|
|
1359
|
+
transaction(() => {
|
|
1360
|
+
const wasCloud = runInCloud.get();
|
|
1361
|
+
const currentPick = sessionTypePicker.selectedPick;
|
|
1362
|
+
isolationModel.setQuickChat(!uri, uri);
|
|
1363
|
+
const types = sessionTypes.get().filter(type => pickerProviders.get().includes(type.providerId));
|
|
1364
|
+
const preferred = workspacePicker.isSelectingRepository ? types.find(
|
|
1365
|
+
type => getProviderConfiguration(type.providerId)?.sessionTypes.includes(type.sessionType.id)
|
|
1366
|
+
) : types.find(
|
|
1367
|
+
type => type.providerId === currentPick?.providerId && type.sessionType.id === currentPick.sessionTypeId
|
|
1368
|
+
) ?? types.find(
|
|
1369
|
+
type => type.providerId === localTarget.providerId && type.sessionType.id === localTarget.sessionTypeId
|
|
1370
|
+
);
|
|
1371
|
+
const first = preferred ?? types[0];
|
|
1372
|
+
const pick = first ? {
|
|
1373
|
+
providerId: first.providerId,
|
|
1374
|
+
sessionTypeId: first.sessionType.id
|
|
1375
|
+
} : undefined;
|
|
1376
|
+
sessionTypePicker.setFolderSource(isolationModel.folderUriObs, {
|
|
1377
|
+
initialPick: pick
|
|
1378
|
+
});
|
|
1379
|
+
state.providerId = pick?.providerId;
|
|
1380
|
+
state.sessionTypeId = pick?.sessionTypeId;
|
|
1381
|
+
selectedProvider.set(state.providerId, undefined);
|
|
1382
|
+
if (!runInCloud.get() && wasCloud && isEqual(uri, localTarget.folderUri)) {
|
|
1383
|
+
state.isolationMode = localTarget.isolationMode;
|
|
1384
|
+
if (localTarget.branch) {
|
|
1385
|
+
isolationModel.selectBranch(localTarget.branch);
|
|
1386
|
+
}
|
|
1387
|
+
}
|
|
1388
|
+
});
|
|
1389
|
+
switchingTarget = false;
|
|
1390
|
+
syncStateFromPicker();
|
|
1134
1391
|
updateAutomationSessionTarget();
|
|
1135
1392
|
revalidate();
|
|
1393
|
+
};
|
|
1394
|
+
disposables.add(workspacePicker.onDidSelectWorkspace(applyWorkspaceTarget));
|
|
1395
|
+
disposables.add(autorun(reader => {
|
|
1396
|
+
if (isolationModel.isQuickChatObs.read(reader)) {
|
|
1397
|
+
applyWorkspaceTarget(undefined);
|
|
1398
|
+
}
|
|
1136
1399
|
}));
|
|
1137
|
-
const sessionSection = append(formContent, $(".automation-session-section"));
|
|
1138
1400
|
const targetRow = append(sessionSection, $(".automation-form-row.automation-target-row"));
|
|
1139
|
-
const targetLabel = append(targetRow, $("span.automation-form-label", {
|
|
1140
|
-
id: "automation-target-label"
|
|
1141
|
-
}, ( localize(3330, "Target"))));
|
|
1142
1401
|
const targetContainer = append(targetRow, $(".automation-target-toolbar", {
|
|
1143
1402
|
role: "group",
|
|
1144
|
-
"aria-
|
|
1403
|
+
"aria-label": ( localize(3706, "Target"))
|
|
1145
1404
|
}));
|
|
1405
|
+
const targetError = append(targetRow, $("span.automation-target-error", {
|
|
1406
|
+
id: "automation-target-error",
|
|
1407
|
+
role: "status",
|
|
1408
|
+
"aria-live": "polite",
|
|
1409
|
+
"aria-atomic": "true"
|
|
1410
|
+
}));
|
|
1411
|
+
hide(targetError);
|
|
1412
|
+
const targetProgress = append(targetRow, $("span.automation-target-progress", {
|
|
1413
|
+
id: "automation-target-progress",
|
|
1414
|
+
role: "status",
|
|
1415
|
+
"aria-live": "polite",
|
|
1416
|
+
"aria-atomic": "true"
|
|
1417
|
+
}));
|
|
1418
|
+
hide(targetProgress);
|
|
1419
|
+
if (isEdit && initialProviderConfiguration) {
|
|
1420
|
+
append(targetRow, $(
|
|
1421
|
+
"span.automation-form-hint",
|
|
1422
|
+
undefined,
|
|
1423
|
+
initialProviderConfiguration.targetChangeDisabledReason
|
|
1424
|
+
));
|
|
1425
|
+
}
|
|
1146
1426
|
const promptSection = append(sessionSection, $(".automation-prompt-section"));
|
|
1147
1427
|
const promptRow = append(promptSection, $(".automation-form-row"));
|
|
1148
|
-
append(promptRow, $("span.automation-form-label", undefined, ( localize(3331, "Prompt"))));
|
|
1149
1428
|
const promptHost = append(promptRow, $(".automation-form-prompt-host.interactive-session"));
|
|
1150
1429
|
const editorOverflowWidgetsDomNode = layoutService.getContainer(getWindow(promptHost)).appendChild($(".chat-editor-overflow.automation-dialog-editor-overflow.monaco-editor"));
|
|
1151
1430
|
disposables.add(toDisposable(() => editorOverflowWidgetsDomNode.remove()));
|
|
@@ -1171,7 +1450,6 @@ function renderForm(
|
|
|
1171
1450
|
[ISessionModelSelection, sessionModelSelection]
|
|
1172
1451
|
))));
|
|
1173
1452
|
const usesCombinedConfigPicker = SessionUsesCombinedConfigPickerContext.bindTo(scopedContextKeyService);
|
|
1174
|
-
const sessionTypesChanged = observableSignalFromEvent(form, sessionsManagementService.onDidChangeSessionTypes);
|
|
1175
1453
|
disposables.add(autorun(reader => {
|
|
1176
1454
|
sessionTypesChanged.read(reader);
|
|
1177
1455
|
const session = activeAutomationSession.read(reader);
|
|
@@ -1185,7 +1463,7 @@ function renderForm(
|
|
|
1185
1463
|
targetContainer,
|
|
1186
1464
|
Menus.AutomationsDialogTargetToolbar,
|
|
1187
1465
|
{
|
|
1188
|
-
ariaLabel: ( localize(
|
|
1466
|
+
ariaLabel: ( localize(3707, "Automation target options")),
|
|
1189
1467
|
telemetrySource: "automations.dialog",
|
|
1190
1468
|
hiddenItemStrategy: HiddenItemStrategy.NoHide,
|
|
1191
1469
|
responsiveBehavior: {
|
|
@@ -1280,42 +1558,19 @@ function renderForm(
|
|
|
1280
1558
|
));
|
|
1281
1559
|
chatInput.render(promptHost, initialPrompt, stubWidget);
|
|
1282
1560
|
chatInput.inputEditor.updateOptions({
|
|
1283
|
-
placeholder: ( localize(
|
|
1561
|
+
placeholder: ( localize(3708, "Describe what you want to automate"))
|
|
1284
1562
|
});
|
|
1285
1563
|
disposables.add(
|
|
1286
1564
|
scopedInstantiationService.createInstance(AutomationInputCompletions, chatInput.inputEditor)
|
|
1287
1565
|
);
|
|
1288
|
-
const
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1292
|
-
const sessionConfiguration = append(sessionConfigurationRow, $(".automation-session-configuration", {
|
|
1293
|
-
role: "group",
|
|
1294
|
-
"aria-labelledby": sessionConfigurationLabel.id
|
|
1295
|
-
}));
|
|
1296
|
-
const sessionConfigContainer = append(
|
|
1297
|
-
sessionConfiguration,
|
|
1298
|
-
$(".automation-session-config.sessions-chat-config-toolbar")
|
|
1299
|
-
);
|
|
1300
|
-
const compactModelPicker = observableValue(sessionConfigContainer, false);
|
|
1301
|
-
const sessionConfigToolbar = disposables.add(createNewSessionConfigToolbar(
|
|
1302
|
-
sessionConfigContainer,
|
|
1303
|
-
scopedInstantiationService,
|
|
1304
|
-
compactModelPicker,
|
|
1305
|
-
( localize(3335, "Session configuration options"))
|
|
1306
|
-
));
|
|
1566
|
+
const sessionConfigContainer = chatInput.inputToolbarElement;
|
|
1567
|
+
sessionConfigContainer.classList.add("automation-session-config", "sessions-chat-config-toolbar");
|
|
1568
|
+
chatInput.setInputToolbarAriaLabel(( localize(3709, "Session configuration options")));
|
|
1569
|
+
const sessionConfiguration = append(promptSection, $(".automation-session-configuration"));
|
|
1307
1570
|
const sessionControlsContainer = append(sessionConfiguration, $(".automation-session-controls"));
|
|
1308
1571
|
const sessionControlsToolbar = disposables.add(
|
|
1309
|
-
createNewSessionControlToolbar(sessionControlsContainer, scopedInstantiationService, ( localize(
|
|
1572
|
+
createNewSessionControlToolbar(sessionControlsContainer, scopedInstantiationService, ( localize(3710, "Session controls")))
|
|
1310
1573
|
);
|
|
1311
|
-
const sessionConfigLayout = disposables.add(( new ChatInputPickerResponsiveLayout("AutomationDialog.sessionConfig", sessionConfigContainer, {
|
|
1312
|
-
getItems: () => getAutomationToolbarResponsiveItems(sessionConfigToolbar, {
|
|
1313
|
-
compactModelPicker
|
|
1314
|
-
}),
|
|
1315
|
-
hasOverflow: () => sessionConfigToolbar.hasOverflow(),
|
|
1316
|
-
relayout: () => sessionConfigToolbar.relayout()
|
|
1317
|
-
})));
|
|
1318
|
-
sessionConfigLayout.layout();
|
|
1319
1574
|
const sessionControlsLayout = disposables.add(( new ChatInputPickerResponsiveLayout("AutomationDialog.sessionControls", sessionControlsContainer, {
|
|
1320
1575
|
getItems: () => getAutomationToolbarResponsiveItems(sessionControlsToolbar),
|
|
1321
1576
|
hasOverflow: () => sessionControlsToolbar.hasOverflow(),
|
|
@@ -1329,24 +1584,24 @@ function renderForm(
|
|
|
1329
1584
|
"aria-atomic": "true"
|
|
1330
1585
|
})
|
|
1331
1586
|
);
|
|
1332
|
-
const sessionConfigurationError = append(sessionConfiguration, $("span.automation-session-configuration-error", {
|
|
1333
|
-
role: "alert",
|
|
1334
|
-
tabindex: "-1"
|
|
1335
|
-
}));
|
|
1336
|
-
hide(sessionConfigurationError);
|
|
1337
1587
|
disposables.add(autorun(reader => {
|
|
1338
1588
|
const hasTarget = isolationModel.isQuickChatObs.read(reader) || isolationModel.folderUriObs.read(reader) !== undefined;
|
|
1339
|
-
|
|
1589
|
+
const cloud = runInCloud.read(reader);
|
|
1590
|
+
setAutomationControlVisible(sessionConfigContainer, hasTarget);
|
|
1591
|
+
setAutomationControlVisible(sessionControlsContainer, hasTarget && !cloud);
|
|
1340
1592
|
const availability = automationSessionDraftSynchronizer.availability.read(reader);
|
|
1341
1593
|
const pending = availability === "pending";
|
|
1342
1594
|
const controlsUnavailable = availability !== "available";
|
|
1343
|
-
sessionConfiguration
|
|
1595
|
+
setAutomationControlVisible(sessionConfiguration, hasTarget && (!cloud || controlsUnavailable));
|
|
1344
1596
|
for (const container of [sessionConfigContainer, sessionControlsContainer]) {
|
|
1597
|
+
container.classList.toggle("controls-unavailable", controlsUnavailable);
|
|
1345
1598
|
container.toggleAttribute("inert", controlsUnavailable);
|
|
1346
|
-
container.setAttribute("aria-hidden", String(
|
|
1599
|
+
container.setAttribute("aria-hidden", String(
|
|
1600
|
+
!hasTarget || controlsUnavailable || cloud && container === sessionControlsContainer
|
|
1601
|
+
));
|
|
1347
1602
|
container.setAttribute("aria-busy", String(pending));
|
|
1348
1603
|
}
|
|
1349
|
-
sessionConfigurationUnavailable.textContent = pending ? ( localize(
|
|
1604
|
+
sessionConfigurationUnavailable.textContent = pending ? ( localize(3711, "Loading session configuration…")) : hasTarget && controlsUnavailable ? ( localize(3712, "Session configuration unavailable")) : "";
|
|
1350
1605
|
}));
|
|
1351
1606
|
disposables.add(chatInput.inputEditor.onDidChangeModelContent(() => {
|
|
1352
1607
|
revalidate();
|
|
@@ -1374,61 +1629,302 @@ function renderForm(
|
|
|
1374
1629
|
}, getWindow(promptHost))
|
|
1375
1630
|
);
|
|
1376
1631
|
disposables.add(resizeObserver.observe(promptHost));
|
|
1377
|
-
const
|
|
1378
|
-
|
|
1379
|
-
|
|
1380
|
-
|
|
1381
|
-
|
|
1382
|
-
|
|
1383
|
-
|
|
1384
|
-
|
|
1385
|
-
|
|
1386
|
-
|
|
1387
|
-
|
|
1388
|
-
|
|
1389
|
-
|
|
1632
|
+
const providerDetails = append(promptSection, $(".automation-provider-details.automation-form-row", {
|
|
1633
|
+
role: "group",
|
|
1634
|
+
"aria-labelledby": "automation-tools-label"
|
|
1635
|
+
}));
|
|
1636
|
+
append(providerDetails, $("span.automation-form-label", {
|
|
1637
|
+
id: "automation-tools-label"
|
|
1638
|
+
}, ( localize(3713, "Tools"))));
|
|
1639
|
+
append(providerDetails, $("p", {
|
|
1640
|
+
id: "automation-tools-description"
|
|
1641
|
+
}, ( localize(
|
|
1642
|
+
3714,
|
|
1643
|
+
"Select which tools the agent can use. Built-in tools are always available."
|
|
1644
|
+
))));
|
|
1645
|
+
const toolsContainer = append(providerDetails, $(".automation-provider-tools"));
|
|
1646
|
+
const toolsButton = disposables.add(( new Button(toolsContainer, {
|
|
1647
|
+
...defaultButtonStyles,
|
|
1648
|
+
secondary: true
|
|
1649
|
+
})));
|
|
1650
|
+
toolsButton.label = ( localize(3715, "Configure allowed tools"));
|
|
1651
|
+
toolsButton.element.setAttribute("aria-haspopup", "dialog");
|
|
1652
|
+
toolsButton.element.setAttribute("aria-describedby", "automation-tools-description");
|
|
1653
|
+
const toolsNotReported = append(toolsContainer, $("p", undefined, ( localize(
|
|
1654
|
+
3716,
|
|
1655
|
+
"GitHub did not report the saved tool selection. Unchanged permissions will be preserved. Select tools to replace it explicitly."
|
|
1656
|
+
))));
|
|
1657
|
+
const toolsStatus = append(providerDetails, $(".automation-provider-tools-status", {
|
|
1658
|
+
role: "status",
|
|
1659
|
+
"aria-live": "polite"
|
|
1660
|
+
}));
|
|
1661
|
+
const toolsStatusText = append(toolsStatus, $("span"));
|
|
1662
|
+
const toolsRetry = disposables.add(( new Button(toolsStatus, {
|
|
1663
|
+
...defaultButtonStyles,
|
|
1664
|
+
secondary: true
|
|
1665
|
+
})));
|
|
1666
|
+
toolsRetry.label = ( localize(3717, "Retry"));
|
|
1667
|
+
const toolsPicker = disposables.add(( new MutableDisposable()));
|
|
1668
|
+
let selectedTools;
|
|
1669
|
+
let selectAllCatalogTools = false;
|
|
1670
|
+
let toolsInitialized = false;
|
|
1671
|
+
let toolCatalog = {
|
|
1672
|
+
kind: "loading"
|
|
1390
1673
|
};
|
|
1391
|
-
|
|
1392
|
-
|
|
1674
|
+
const catalogToolIds = catalog => catalog.kind === "ready" ? [...( new Set(catalog.groups.flatMap(group => group.tools.map(tool => tool.id))))] : [];
|
|
1675
|
+
const updateToolsControls = () => {
|
|
1676
|
+
const ready = toolCatalog.kind === "ready";
|
|
1677
|
+
if (ready && selectAllCatalogTools) {
|
|
1678
|
+
selectedTools = catalogToolIds(toolCatalog);
|
|
1679
|
+
selectAllCatalogTools = false;
|
|
1680
|
+
}
|
|
1681
|
+
toolsButton.enabled = ready && !!quickInputService;
|
|
1682
|
+
const ids = ( new Set([...catalogToolIds(toolCatalog), ...(selectedTools ?? [])]));
|
|
1683
|
+
if (ready && selectedTools) {
|
|
1684
|
+
toolsButton.element.setAttribute("aria-description", ( localize(3718, "{0} of {1} tools selected", selectedTools.length, ids.size)));
|
|
1685
|
+
} else {
|
|
1686
|
+
toolsButton.element.removeAttribute("aria-description");
|
|
1687
|
+
}
|
|
1688
|
+
setAutomationControlVisible(toolsNotReported, selectedTools === undefined && !selectAllCatalogTools);
|
|
1689
|
+
toolsStatusText.textContent = toolCatalog.kind === "loading" ? ( localize(3719, "Loading available tools...")) : toolCatalog.kind === "error" ? toolCatalog.message : "";
|
|
1690
|
+
setAutomationControlVisible(toolsStatus, !ready);
|
|
1691
|
+
setAutomationControlVisible(toolsRetry.element, toolCatalog.kind === "error");
|
|
1692
|
+
};
|
|
1693
|
+
disposables.add(toolsRetry.onDidClick(() => cloudConfiguration.get()?.loadTools()));
|
|
1694
|
+
disposables.add(toolsButton.onDidClick(() => {
|
|
1695
|
+
if (!quickInputService || toolCatalog.kind !== "ready") {
|
|
1696
|
+
return;
|
|
1697
|
+
}
|
|
1698
|
+
const store = ( new DisposableStore());
|
|
1699
|
+
let disposing = false;
|
|
1700
|
+
store.add(toDisposable(() => disposing = true));
|
|
1701
|
+
toolsPicker.value = store;
|
|
1702
|
+
const shown = ( new Set());
|
|
1703
|
+
const toItem = tool => {
|
|
1704
|
+
shown.add(tool.id);
|
|
1705
|
+
return {
|
|
1706
|
+
id: tool.id,
|
|
1707
|
+
label: tool.label,
|
|
1708
|
+
description: tool.description,
|
|
1709
|
+
checked: selectedTools?.includes(tool.id) === true
|
|
1710
|
+
};
|
|
1711
|
+
};
|
|
1712
|
+
const items = [];
|
|
1713
|
+
for (const group of toolCatalog.groups) {
|
|
1714
|
+
const children = group.tools.filter(tool => !( shown.has(tool.id))).map(toItem);
|
|
1715
|
+
if (children.length) {
|
|
1716
|
+
items.push({
|
|
1717
|
+
label: group.label,
|
|
1718
|
+
children
|
|
1719
|
+
});
|
|
1720
|
+
}
|
|
1721
|
+
}
|
|
1722
|
+
const unknown = (selectedTools ?? []).filter(id => !( shown.has(id)));
|
|
1723
|
+
if (unknown.length) {
|
|
1724
|
+
items.push({
|
|
1725
|
+
label: ( localize(3720, "Other Saved Tools")),
|
|
1726
|
+
children: unknown.map(id => toItem({
|
|
1727
|
+
id,
|
|
1728
|
+
label: id
|
|
1729
|
+
}))
|
|
1730
|
+
});
|
|
1731
|
+
}
|
|
1732
|
+
const picker = store.add(quickInputService.createQuickTree());
|
|
1733
|
+
picker.title = ( localize(3721, "Allowed Tools"));
|
|
1734
|
+
picker.placeholder = ( localize(3722, "Search tools"));
|
|
1735
|
+
picker.matchOnDescription = true;
|
|
1736
|
+
picker.sortByLabel = false;
|
|
1737
|
+
picker.setItemTree(items);
|
|
1738
|
+
store.add(picker.onDidAccept(() => {
|
|
1739
|
+
selectedTools = picker.checkedLeafItems.flatMap(item => item.id ? [item.id] : []);
|
|
1740
|
+
updateToolsControls();
|
|
1741
|
+
picker.hide();
|
|
1742
|
+
}));
|
|
1743
|
+
store.add(picker.onDidHide(() => {
|
|
1744
|
+
if (disposing) {
|
|
1745
|
+
return;
|
|
1746
|
+
}
|
|
1747
|
+
toolsPicker.clear();
|
|
1748
|
+
toolsButton.focus();
|
|
1749
|
+
}));
|
|
1750
|
+
picker.show();
|
|
1393
1751
|
}));
|
|
1394
|
-
disposables.add(
|
|
1395
|
-
|
|
1752
|
+
disposables.add(autorun(reader => {
|
|
1753
|
+
const configuration = cloudConfiguration.read(reader);
|
|
1754
|
+
toolsPicker.clear();
|
|
1755
|
+
updateIntervalOptions(configuration !== undefined);
|
|
1756
|
+
setAutomationControlVisible(providerDetails, configuration !== undefined);
|
|
1757
|
+
timeLabel.textContent = configuration?.timeZone === "UTC" ? ( localize(3723, "Time (Local)")) : ( localize(3701, "Time"));
|
|
1758
|
+
timeSelect.setAriaLabel(timeLabel.textContent);
|
|
1759
|
+
if (!configuration) {
|
|
1760
|
+
return;
|
|
1761
|
+
}
|
|
1762
|
+
if (!toolsInitialized) {
|
|
1763
|
+
const stored = initialProviderConfiguration ? initialSessionConfiguration?.sessionTemplate?.config?.tools : undefined;
|
|
1764
|
+
selectedTools = isStringArray(stored) ? [...stored] : undefined;
|
|
1765
|
+
selectAllCatalogTools = selectedTools === undefined && !(isEdit && initialProviderConfiguration);
|
|
1766
|
+
toolsInitialized = true;
|
|
1767
|
+
}
|
|
1768
|
+
}));
|
|
1769
|
+
disposables.add(autorun(reader => {
|
|
1770
|
+
const configuration = cloudConfiguration.read(reader);
|
|
1771
|
+
toolCatalog = configuration?.tools.read(reader) ?? {
|
|
1772
|
+
kind: "loading"
|
|
1773
|
+
};
|
|
1774
|
+
if (toolCatalog.kind === "loading") {
|
|
1775
|
+
configuration?.loadTools();
|
|
1776
|
+
}
|
|
1777
|
+
updateToolsControls();
|
|
1778
|
+
}));
|
|
1779
|
+
const resolveSelectedTools = async (configuration, token) => {
|
|
1780
|
+
if (!selectAllCatalogTools) {
|
|
1781
|
+
return selectedTools;
|
|
1782
|
+
}
|
|
1783
|
+
configuration.loadTools();
|
|
1784
|
+
const cts = ( new CancellationTokenSource(token));
|
|
1785
|
+
let catalog;
|
|
1786
|
+
try {
|
|
1787
|
+
catalog = await waitForState(
|
|
1788
|
+
configuration.tools,
|
|
1789
|
+
catalog => catalog.kind !== "loading",
|
|
1790
|
+
undefined,
|
|
1791
|
+
cts.token
|
|
1792
|
+
);
|
|
1793
|
+
} finally {
|
|
1794
|
+
cts.dispose(true);
|
|
1795
|
+
}
|
|
1796
|
+
if (catalog.kind === "error") {
|
|
1797
|
+
throw ( new Error(catalog.message));
|
|
1798
|
+
}
|
|
1799
|
+
updateToolsControls();
|
|
1800
|
+
return selectedTools;
|
|
1801
|
+
};
|
|
1802
|
+
const customizationSelection = customizations ? disposables.add(( new AutomationCustomizationSelection(
|
|
1803
|
+
formContent,
|
|
1804
|
+
customizations.service,
|
|
1805
|
+
customizations.hoverService,
|
|
1806
|
+
logService,
|
|
1807
|
+
customizations.existingId
|
|
1808
|
+
))) : undefined;
|
|
1809
|
+
reloadCustomizations = () => customizationSelection?.updateTarget(
|
|
1810
|
+
state.providerId && state.sessionTypeId && allowedProviders.get().includes(state.providerId) ? createAutomationTarget(state, isolationModel.persistedBranch) : undefined
|
|
1811
|
+
);
|
|
1812
|
+
disposables.add(onDidChangeSessionTarget.event(reloadCustomizations));
|
|
1813
|
+
disposables.add(autorun(reader => {
|
|
1814
|
+
isolationModel.isQuickChatObs.read(reader);
|
|
1815
|
+
isolationModel.folderUriObs.read(reader);
|
|
1816
|
+
allowedProviders.read(reader);
|
|
1817
|
+
reloadCustomizations();
|
|
1396
1818
|
}));
|
|
1397
1819
|
const saveStatus = append(form, $("span.automation-form-save-status", {
|
|
1398
1820
|
role: "status",
|
|
1399
1821
|
"aria-atomic": "true"
|
|
1400
1822
|
}));
|
|
1823
|
+
const saveIcon = append(saveStatus, renderIcon(Codicon.loading));
|
|
1824
|
+
saveIcon.classList.add("codicon-modifier-spin");
|
|
1825
|
+
saveIcon.setAttribute("aria-hidden", "true");
|
|
1826
|
+
const saveStatusText = append(saveStatus, $("span"));
|
|
1401
1827
|
hide(saveStatus);
|
|
1828
|
+
const saveError = append(form, $(".automation-form-save-error", {
|
|
1829
|
+
role: "alert",
|
|
1830
|
+
tabindex: "-1"
|
|
1831
|
+
}));
|
|
1832
|
+
append(saveError, renderIcon(Codicon.error)).setAttribute("aria-hidden", "true");
|
|
1833
|
+
const saveErrorText = append(saveError, $("span"));
|
|
1834
|
+
hide(saveError);
|
|
1835
|
+
disposables.add(autorun(reader => {
|
|
1836
|
+
const message = sessionConfigurationErrorMessage.read(reader);
|
|
1837
|
+
setAutomationControlVisible(saveError, !!message);
|
|
1838
|
+
saveErrorText.textContent = message ?? "";
|
|
1839
|
+
}));
|
|
1402
1840
|
return {
|
|
1403
1841
|
getPrompt: () => chatInput.inputEditor.getValue(),
|
|
1404
|
-
getSessionConfiguration: token =>
|
|
1842
|
+
getSessionConfiguration: async token => {
|
|
1843
|
+
const captured = await automationSessionDraftSynchronizer.getSessionConfiguration(token);
|
|
1844
|
+
const configuration = cloudConfiguration.get();
|
|
1845
|
+
if (captured.kind === "failed" || !configuration) {
|
|
1846
|
+
return captured;
|
|
1847
|
+
}
|
|
1848
|
+
let tools;
|
|
1849
|
+
try {
|
|
1850
|
+
tools = await resolveSelectedTools(configuration, token);
|
|
1851
|
+
} catch (error) {
|
|
1852
|
+
return {
|
|
1853
|
+
kind: "failed",
|
|
1854
|
+
error
|
|
1855
|
+
};
|
|
1856
|
+
}
|
|
1857
|
+
if (tools === undefined) {
|
|
1858
|
+
return captured;
|
|
1859
|
+
}
|
|
1860
|
+
return {
|
|
1861
|
+
kind: "captured",
|
|
1862
|
+
configuration: {
|
|
1863
|
+
...captured.configuration,
|
|
1864
|
+
sessionTemplate: {
|
|
1865
|
+
...captured.configuration?.sessionTemplate,
|
|
1866
|
+
config: {
|
|
1867
|
+
...captured.configuration?.sessionTemplate?.config,
|
|
1868
|
+
tools
|
|
1869
|
+
}
|
|
1870
|
+
}
|
|
1871
|
+
}
|
|
1872
|
+
};
|
|
1873
|
+
},
|
|
1405
1874
|
getBranch: () => isolationModel.persistedBranch,
|
|
1875
|
+
providerDescription: derived(reader => cloudConfiguration.read(reader)?.description),
|
|
1876
|
+
showScheduleValidationError: message => {
|
|
1877
|
+
scheduleError.textContent = message ?? "";
|
|
1878
|
+
setAutomationControlVisible(scheduleError, message !== undefined);
|
|
1879
|
+
},
|
|
1880
|
+
getCustomizationIds: () => customizationSelection?.getSelectedIds(),
|
|
1881
|
+
waitForCustomizationChoices: async token => customizationSelection?.waitForChoices(token),
|
|
1882
|
+
showTargetValidationError: message => {
|
|
1883
|
+
const text = message ?? "";
|
|
1884
|
+
const pending = state.targetPending;
|
|
1885
|
+
setAutomationControlVisible(targetProgress, !!pending && message === undefined);
|
|
1886
|
+
const progressText = pending?.message ?? "";
|
|
1887
|
+
if (targetProgress.textContent !== progressText) {
|
|
1888
|
+
targetProgress.textContent = progressText;
|
|
1889
|
+
}
|
|
1890
|
+
targetContainer.setAttribute("aria-busy", String(!!pending));
|
|
1891
|
+
if (message !== undefined) {
|
|
1892
|
+
show(targetError);
|
|
1893
|
+
targetContainer.setAttribute("aria-describedby", targetError.id);
|
|
1894
|
+
targetContainer.setAttribute("aria-invalid", "true");
|
|
1895
|
+
} else {
|
|
1896
|
+
hide(targetError);
|
|
1897
|
+
if (pending) {
|
|
1898
|
+
targetContainer.setAttribute("aria-describedby", targetProgress.id);
|
|
1899
|
+
} else {
|
|
1900
|
+
targetContainer.removeAttribute("aria-describedby");
|
|
1901
|
+
}
|
|
1902
|
+
targetContainer.removeAttribute("aria-invalid");
|
|
1903
|
+
}
|
|
1904
|
+
if (targetError.textContent !== text) {
|
|
1905
|
+
targetError.textContent = text;
|
|
1906
|
+
}
|
|
1907
|
+
},
|
|
1406
1908
|
waitForAutomationSessionSync: token => {
|
|
1407
1909
|
updateAutomationSessionTarget();
|
|
1408
1910
|
return automationSessionDraftSynchronizer.waitForSync(token);
|
|
1409
1911
|
},
|
|
1410
|
-
setSaving: saving => {
|
|
1912
|
+
setSaving: (saving, committing) => {
|
|
1411
1913
|
formContent.toggleAttribute("inert", saving);
|
|
1412
1914
|
formContent.setAttribute("aria-busy", String(saving));
|
|
1413
1915
|
form.classList.toggle("saving", saving);
|
|
1414
1916
|
if (saving) {
|
|
1415
1917
|
show(saveStatus);
|
|
1416
|
-
|
|
1918
|
+
saveStatusText.textContent = committing && customizationSelection?.getSelectedIds()?.length ? ( localize(3724, "Syncing customizations…")) : ( localize(3725, "Saving automation…"));
|
|
1417
1919
|
} else {
|
|
1418
1920
|
hide(saveStatus);
|
|
1419
|
-
|
|
1921
|
+
saveStatusText.textContent = "";
|
|
1420
1922
|
}
|
|
1421
1923
|
},
|
|
1422
|
-
|
|
1423
|
-
|
|
1424
|
-
show(sessionConfigurationError);
|
|
1425
|
-
sessionConfigurationError.textContent = message;
|
|
1426
|
-
} else {
|
|
1427
|
-
hide(sessionConfigurationError);
|
|
1428
|
-
sessionConfigurationError.textContent = "";
|
|
1429
|
-
}
|
|
1924
|
+
showSaveError: message => {
|
|
1925
|
+
sessionConfigurationErrorMessage.set(message, undefined);
|
|
1430
1926
|
},
|
|
1431
|
-
|
|
1927
|
+
focusSaveError: () => saveError.focus(),
|
|
1432
1928
|
getFocusableElements: () => {
|
|
1433
1929
|
return Array.from(
|
|
1434
1930
|
form.querySelectorAll("input, select, textarea, button, a[href], [tabindex]")
|
|
@@ -1452,10 +1948,229 @@ function renderForm(
|
|
|
1452
1948
|
}
|
|
1453
1949
|
};
|
|
1454
1950
|
}
|
|
1455
|
-
|
|
1951
|
+
class AutomationCustomizationSelection extends Disposable {
|
|
1952
|
+
constructor(container, service, hoverService, logService, existingId) {
|
|
1953
|
+
super();
|
|
1954
|
+
this.service = service;
|
|
1955
|
+
this.hoverService = hoverService;
|
|
1956
|
+
this.logService = logService;
|
|
1957
|
+
this.existingId = existingId;
|
|
1958
|
+
this.rows = this._register(( new DisposableStore()));
|
|
1959
|
+
this.request = this._register(( new MutableDisposable()));
|
|
1960
|
+
this.toggles = ( new Map());
|
|
1961
|
+
this.loading = Promise.resolve();
|
|
1962
|
+
this.expanded = false;
|
|
1963
|
+
this._register(toDisposable(() => this.request.value?.cancel()));
|
|
1964
|
+
this.section = append(container, $(".automation-advanced"));
|
|
1965
|
+
this.disclosure = this._register(( new Button(this.section, {
|
|
1966
|
+
...unthemedButtonStyles,
|
|
1967
|
+
secondary: true
|
|
1968
|
+
})));
|
|
1969
|
+
this.disclosure.element.classList.add("automation-advanced-disclosure", "automation-form-label");
|
|
1970
|
+
this.chevron = append(this.disclosure.element, $("span.automation-advanced-chevron", {
|
|
1971
|
+
"aria-hidden": "true"
|
|
1972
|
+
}));
|
|
1973
|
+
append(this.chevron, renderIcon(Codicon.chevronRight));
|
|
1974
|
+
append(this.disclosure.element, $("span", undefined, ( localize(3726, "Advanced"))));
|
|
1975
|
+
this.summary = append(this.disclosure.element, $("span.automation-advanced-summary"));
|
|
1976
|
+
this.content = append(this.section, $(".automation-customizations", {
|
|
1977
|
+
id: "automation-customizations"
|
|
1978
|
+
}));
|
|
1979
|
+
this.disclosure.element.setAttribute("aria-controls", this.content.id);
|
|
1980
|
+
this.disclosure.element.setAttribute("aria-expanded", "false");
|
|
1981
|
+
hide(this.section, this.content);
|
|
1982
|
+
this._register(this.disclosure.onDidClick(() => {
|
|
1983
|
+
this.expanded = !this.expanded;
|
|
1984
|
+
this.disclosure.element.setAttribute("aria-expanded", String(this.expanded));
|
|
1985
|
+
reset(
|
|
1986
|
+
this.chevron,
|
|
1987
|
+
renderIcon(this.expanded ? Codicon.chevronDown : Codicon.chevronRight)
|
|
1988
|
+
);
|
|
1989
|
+
this.content.hidden = !this.expanded;
|
|
1990
|
+
this.content.style.display = this.expanded ? "" : "none";
|
|
1991
|
+
this.summary.hidden = this.expanded;
|
|
1992
|
+
}));
|
|
1993
|
+
}
|
|
1994
|
+
getSelectedIds() {
|
|
1995
|
+
return this.choices?.filter(choice => this.toggles.get(choice.id) ?? choice.selected).map(choice => choice.id);
|
|
1996
|
+
}
|
|
1997
|
+
async waitForChoices(token) {
|
|
1998
|
+
await raceCancellationError(this.loading, token);
|
|
1999
|
+
}
|
|
2000
|
+
updateTarget(target) {
|
|
2001
|
+
const key = target ? JSON.stringify({
|
|
2002
|
+
kind: target.kind,
|
|
2003
|
+
providerId: target.providerId,
|
|
2004
|
+
sessionTypeId: target.sessionTypeId,
|
|
2005
|
+
folder: target.kind === "workspace" ? getComparisonKey(target.folderUri) : undefined,
|
|
2006
|
+
isolation: target.kind === "workspace" ? target.isolation : undefined
|
|
2007
|
+
}) : undefined;
|
|
2008
|
+
if (key === this.targetKey) {
|
|
2009
|
+
return;
|
|
2010
|
+
}
|
|
2011
|
+
this.targetKey = key;
|
|
2012
|
+
this.request.value?.cancel();
|
|
2013
|
+
this.request.clear();
|
|
2014
|
+
this.choices = undefined;
|
|
2015
|
+
this.rows.clear();
|
|
2016
|
+
clearNode(this.content);
|
|
2017
|
+
if (!target || !target.providerId || !target.sessionTypeId || !this.service.getCustomizationChoices) {
|
|
2018
|
+
hide(this.section);
|
|
2019
|
+
return;
|
|
2020
|
+
}
|
|
2021
|
+
show(this.section);
|
|
2022
|
+
this.summary.textContent = ( localize(3727, "Loading…"));
|
|
2023
|
+
const loading = append(this.content, $(".automation-customizations-message", {
|
|
2024
|
+
role: "status"
|
|
2025
|
+
}));
|
|
2026
|
+
const icon = append(loading, renderIcon(Codicon.loading));
|
|
2027
|
+
icon.classList.add("codicon-modifier-spin");
|
|
2028
|
+
icon.setAttribute("aria-hidden", "true");
|
|
2029
|
+
append(loading, $("span", undefined, ( localize(3728, "Loading customizations…"))));
|
|
2030
|
+
const request = ( new CancellationTokenSource());
|
|
2031
|
+
this.request.value = request;
|
|
2032
|
+
this.loading = this.load(target, request);
|
|
2033
|
+
}
|
|
2034
|
+
async load(target, request) {
|
|
2035
|
+
try {
|
|
2036
|
+
const choices = await this.service.getCustomizationChoices?.(target, this.existingId, request.token);
|
|
2037
|
+
if (request.token.isCancellationRequested || this._store.isDisposed) {
|
|
2038
|
+
return;
|
|
2039
|
+
}
|
|
2040
|
+
this.choices = choices;
|
|
2041
|
+
if (choices === undefined) {
|
|
2042
|
+
hide(this.section);
|
|
2043
|
+
return;
|
|
2044
|
+
}
|
|
2045
|
+
this.renderChoices(choices);
|
|
2046
|
+
} catch (error) {
|
|
2047
|
+
if (!request.token.isCancellationRequested && !this._store.isDisposed) {
|
|
2048
|
+
this.logService.error("[AutomationDialog] Failed to load customization choices.", error);
|
|
2049
|
+
hide(this.section);
|
|
2050
|
+
}
|
|
2051
|
+
}
|
|
2052
|
+
}
|
|
2053
|
+
updateSummary() {
|
|
2054
|
+
const outdated = this.choices?.filter(choice => choice.outdated).length ?? 0;
|
|
2055
|
+
this.summary.textContent = outdated ? ( localize(
|
|
2056
|
+
3729,
|
|
2057
|
+
"{0} of {1} customizations · {2} outdated",
|
|
2058
|
+
this.getSelectedIds()?.length ?? 0,
|
|
2059
|
+
this.choices?.length ?? 0,
|
|
2060
|
+
outdated
|
|
2061
|
+
)) : ( localize(
|
|
2062
|
+
3730,
|
|
2063
|
+
"{0} of {1} customizations",
|
|
2064
|
+
this.getSelectedIds()?.length ?? 0,
|
|
2065
|
+
this.choices?.length ?? 0
|
|
2066
|
+
));
|
|
2067
|
+
}
|
|
2068
|
+
renderChoices(choices) {
|
|
2069
|
+
clearNode(this.content);
|
|
2070
|
+
append(this.content, $("span.automation-form-label", undefined, ( localize(3731, "Customizations"))));
|
|
2071
|
+
append(
|
|
2072
|
+
this.content,
|
|
2073
|
+
$("p.automation-customizations-description", undefined, ( localize(
|
|
2074
|
+
3732,
|
|
2075
|
+
"Choose which plugins and customizations runs of this automation can use."
|
|
2076
|
+
)))
|
|
2077
|
+
);
|
|
2078
|
+
if (!choices.length) {
|
|
2079
|
+
append(
|
|
2080
|
+
this.content,
|
|
2081
|
+
$("p.automation-customizations-description", undefined, ( localize(3733, "No customizations are available for this target.")))
|
|
2082
|
+
);
|
|
2083
|
+
}
|
|
2084
|
+
for (const [index, choice] of choices.entries()) {
|
|
2085
|
+
const row = append(this.content, $(".automation-customization-row"));
|
|
2086
|
+
const checkbox = this.rows.add(( new Checkbox(
|
|
2087
|
+
choice.label,
|
|
2088
|
+
this.toggles.get(choice.id) ?? choice.selected,
|
|
2089
|
+
defaultCheckboxStyles
|
|
2090
|
+
)));
|
|
2091
|
+
row.appendChild(checkbox.domNode);
|
|
2092
|
+
const text = append(row, $(".automation-customization-text"));
|
|
2093
|
+
const label = append(text, $("span.automation-customization-label", {
|
|
2094
|
+
id: `automation-customization-${index}`
|
|
2095
|
+
}, choice.label));
|
|
2096
|
+
checkbox.domNode.setAttribute("aria-labelledby", label.id);
|
|
2097
|
+
this.rows.add(this.hoverService.setupDelayedHover(label, {
|
|
2098
|
+
content: choice.label
|
|
2099
|
+
}));
|
|
2100
|
+
if (choice.description) {
|
|
2101
|
+
const description = append(text, $("span.automation-customization-description", {
|
|
2102
|
+
id: `automation-customization-description-${index}`
|
|
2103
|
+
}, choice.description));
|
|
2104
|
+
checkbox.domNode.setAttribute("aria-describedby", description.id);
|
|
2105
|
+
this.rows.add(this.hoverService.setupDelayedHover(description, {
|
|
2106
|
+
content: choice.description
|
|
2107
|
+
}));
|
|
2108
|
+
}
|
|
2109
|
+
if (choice.outdated) {
|
|
2110
|
+
const outdated = append(row, $("span.automation-customization-outdated", {
|
|
2111
|
+
id: `automation-customization-outdated-${index}`
|
|
2112
|
+
}, ( localize(3734, "Outdated"))));
|
|
2113
|
+
checkbox.domNode.setAttribute(
|
|
2114
|
+
"aria-describedby",
|
|
2115
|
+
choice.description ? `automation-customization-description-${index} ${outdated.id}` : outdated.id
|
|
2116
|
+
);
|
|
2117
|
+
}
|
|
2118
|
+
this.rows.add(checkbox.onChange(() => {
|
|
2119
|
+
this.toggles.set(choice.id, checkbox.checked);
|
|
2120
|
+
this.updateSummary();
|
|
2121
|
+
}));
|
|
2122
|
+
this.rows.add(addDisposableListener(text, EventType.CLICK, () => {
|
|
2123
|
+
checkbox.checked = !checkbox.checked;
|
|
2124
|
+
this.toggles.set(choice.id, checkbox.checked);
|
|
2125
|
+
this.updateSummary();
|
|
2126
|
+
checkbox.focus();
|
|
2127
|
+
}));
|
|
2128
|
+
}
|
|
2129
|
+
if (( choices.some(choice => choice.outdated))) {
|
|
2130
|
+
const hint = append(this.content, $(".automation-customizations-message"));
|
|
2131
|
+
append(hint, renderIcon(Codicon.info)).setAttribute("aria-hidden", "true");
|
|
2132
|
+
append(hint, $("span", undefined, ( localize(
|
|
2133
|
+
3735,
|
|
2134
|
+
"Outdated customizations will be updated when the automation is saved."
|
|
2135
|
+
))));
|
|
2136
|
+
}
|
|
2137
|
+
this.updateSummary();
|
|
2138
|
+
}
|
|
2139
|
+
}
|
|
2140
|
+
function createAutomationTarget(state, branch) {
|
|
2141
|
+
if (state.isQuickChat) {
|
|
2142
|
+
return state.providerId && state.sessionTypeId ? {
|
|
2143
|
+
kind: "quickChat",
|
|
2144
|
+
providerId: state.providerId,
|
|
2145
|
+
sessionTypeId: state.sessionTypeId
|
|
2146
|
+
} : undefined;
|
|
2147
|
+
}
|
|
2148
|
+
if (!state.folderUri) {
|
|
2149
|
+
return undefined;
|
|
2150
|
+
}
|
|
2151
|
+
const isolation = state.isolationMode === "worktree" ? (branch ? {
|
|
2152
|
+
kind: "worktree",
|
|
2153
|
+
branch
|
|
2154
|
+
} : undefined) : state.isolationMode === "workspace" ? {
|
|
2155
|
+
kind: "folder"
|
|
2156
|
+
} : {
|
|
2157
|
+
kind: "default"
|
|
2158
|
+
};
|
|
2159
|
+
return isolation ? {
|
|
2160
|
+
kind: "workspace",
|
|
2161
|
+
folderUri: state.resolvedFolderUri ?? state.folderUri,
|
|
2162
|
+
providerId: state.providerId,
|
|
2163
|
+
sessionTypeId: state.sessionTypeId,
|
|
2164
|
+
isolation
|
|
2165
|
+
} : undefined;
|
|
2166
|
+
}
|
|
2167
|
+
function buildTimeOptions(initialHour, initialMinute) {
|
|
1456
2168
|
const options = [];
|
|
1457
2169
|
for (let hour = 0; hour < 24; hour++) {
|
|
1458
|
-
for (let minute = 0; minute < 60; minute
|
|
2170
|
+
for (let minute = 0; minute < 60; minute++) {
|
|
2171
|
+
if (minute % 15 !== 0 && (hour !== initialHour || minute !== initialMinute)) {
|
|
2172
|
+
continue;
|
|
2173
|
+
}
|
|
1459
2174
|
const period = hour < 12 ? "AM" : "PM";
|
|
1460
2175
|
const hour12 = hour === 0 ? 12 : (hour > 12 ? hour - 12 : hour);
|
|
1461
2176
|
const minuteText = ( minute.toString()).padStart(2, "0");
|
|
@@ -1468,22 +2183,67 @@ function buildTimeOptions() {
|
|
|
1468
2183
|
}
|
|
1469
2184
|
return options;
|
|
1470
2185
|
}
|
|
1471
|
-
function
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
|
|
1483
|
-
validation.
|
|
1484
|
-
|
|
2186
|
+
function updateSaveButtonState(
|
|
2187
|
+
saveButton,
|
|
2188
|
+
state,
|
|
2189
|
+
validation,
|
|
2190
|
+
form,
|
|
2191
|
+
getPrompt,
|
|
2192
|
+
getBranch,
|
|
2193
|
+
sessionsManagementService,
|
|
2194
|
+
providerAvailable = true,
|
|
2195
|
+
originalProviderId,
|
|
2196
|
+
requireName = true
|
|
2197
|
+
) {
|
|
2198
|
+
validation.nameError = requireName && state.name.trim() === "" ? ( localize(3736, "Name is required.")) : undefined;
|
|
2199
|
+
validation.promptError = getPrompt().trim() === "" ? ( localize(3737, "Prompt is required.")) : undefined;
|
|
2200
|
+
validation.folderError = !state.folderUri && !state.isQuickChat ? ( localize(3738, "Workspace folder is required.")) : undefined;
|
|
2201
|
+
if (originalProviderId !== undefined && state.providerId !== originalProviderId) {
|
|
2202
|
+
validation.sessionTypeError = ( localize(
|
|
2203
|
+
3739,
|
|
2204
|
+
"To use another Agent Host, duplicate this automation. The original keeps its schedule until you disable it."
|
|
2205
|
+
));
|
|
2206
|
+
} else if (state.targetPending) {
|
|
2207
|
+
validation.sessionTypeError = undefined;
|
|
2208
|
+
} else if (state.targetDisabledReason !== undefined) {
|
|
2209
|
+
validation.sessionTypeError = state.targetDisabledReason;
|
|
2210
|
+
} else if (!providerAvailable) {
|
|
2211
|
+
validation.sessionTypeError = ( localize(3740, "Choose an available Agent Host that supports automations."));
|
|
2212
|
+
} else if (!state.sessionTypeId || !state.providerId) {
|
|
2213
|
+
validation.sessionTypeError = ( localize(3741, "Session type is required."));
|
|
2214
|
+
} else {
|
|
2215
|
+
const target = {
|
|
2216
|
+
providerId: state.providerId,
|
|
2217
|
+
sessionTypeId: state.sessionTypeId
|
|
2218
|
+
};
|
|
2219
|
+
if (state.isQuickChat && !sessionsManagementService.isQuickChatTargetAvailable(target)) {
|
|
2220
|
+
validation.sessionTypeError = ( localize(
|
|
2221
|
+
3742,
|
|
2222
|
+
"The selected Agent Host and session type cannot run without a workspace. Choose a workspace or another session type."
|
|
2223
|
+
));
|
|
2224
|
+
} else if (!state.isQuickChat && state.folderUri !== undefined && !sessionsManagementService.isNewSessionTargetAvailable(state.resolvedFolderUri ?? state.folderUri, target)) {
|
|
2225
|
+
validation.sessionTypeError = ( localize(
|
|
2226
|
+
3743,
|
|
2227
|
+
"The selected Agent Host and session type cannot use this workspace. Choose another workspace or session type."
|
|
2228
|
+
));
|
|
2229
|
+
} else {
|
|
2230
|
+
validation.sessionTypeError = undefined;
|
|
2231
|
+
}
|
|
2232
|
+
}
|
|
2233
|
+
validation.branchError = !state.isQuickChat && state.isolationMode === "worktree" && !getBranch() ? ( localize(3744, "A branch is required for Worktree isolation.")) : undefined;
|
|
2234
|
+
const utcSchedule = state.timeZone === "UTC" ? automationScheduleToUTC({
|
|
2235
|
+
interval: state.interval,
|
|
2236
|
+
scheduleHour: state.hour,
|
|
2237
|
+
scheduleMinute: state.minute,
|
|
2238
|
+
scheduleDay: state.day
|
|
2239
|
+
}, state.timezoneOffset) : undefined;
|
|
2240
|
+
validation.scheduleError = !( INTERVALS.some(item => item.value === state.interval)) ? ( localize(3745, "Choose a supported schedule.")) : utcSchedule && state.interval === "weekdays" ? ( localize(
|
|
2241
|
+
3746,
|
|
2242
|
+
"Weekdays is only available for local automations. Choose a supported schedule for Cloud."
|
|
2243
|
+
)) : utcSchedule && (state.interval === "daily" || state.interval === "weekly") && utcSchedule.scheduleMinute % 15 !== 0 ? ( localize(3747, "Choose a time that corresponds to minute 00, 15, 30, or 45 in UTC.")) : undefined;
|
|
2244
|
+
const valid = !validation.nameError && !validation.promptError && !validation.folderError && !validation.sessionTypeError && !validation.branchError && !validation.scheduleError;
|
|
1485
2245
|
if (saveButton) {
|
|
1486
|
-
saveButton.enabled = valid;
|
|
2246
|
+
saveButton.enabled = valid && !state.targetPending;
|
|
1487
2247
|
}
|
|
1488
2248
|
form.classList.toggle("automation-form-invalid", !valid);
|
|
1489
2249
|
}
|
|
@@ -1491,6 +2251,63 @@ class AutomationsWorkspacePicker extends WorkspacePicker {
|
|
|
1491
2251
|
constructor() {
|
|
1492
2252
|
super(...arguments);
|
|
1493
2253
|
this.targetModelWatch = this._register(( new MutableDisposable()));
|
|
2254
|
+
this.eligibilityWatch = this._register(( new MutableDisposable()));
|
|
2255
|
+
this.cloudConfiguration = constObservable(undefined);
|
|
2256
|
+
this.repositorySelection = this._register(( new MutableDisposable()));
|
|
2257
|
+
this.selectionGeneration = 0;
|
|
2258
|
+
this.selectingRepository = false;
|
|
2259
|
+
this.onSelectionError = onUnexpectedError;
|
|
2260
|
+
this.onWillSelectWorkspace = async () => true;
|
|
2261
|
+
}
|
|
2262
|
+
get isSelectingRepository() {
|
|
2263
|
+
return this.selectingRepository;
|
|
2264
|
+
}
|
|
2265
|
+
setDisabledReason(reason) {
|
|
2266
|
+
this.disabledReason = reason;
|
|
2267
|
+
if (reason !== undefined) {
|
|
2268
|
+
this.selectionGeneration++;
|
|
2269
|
+
this.repositorySelection.clear();
|
|
2270
|
+
}
|
|
2271
|
+
this._updateTriggerLabel();
|
|
2272
|
+
}
|
|
2273
|
+
setCloudConfiguration(configuration) {
|
|
2274
|
+
this.cloudConfiguration = configuration;
|
|
2275
|
+
this.eligibilityWatch.value = autorun(reader => {
|
|
2276
|
+
const value = configuration.read(reader);
|
|
2277
|
+
for (const item of super._buildItems()) {
|
|
2278
|
+
if (item.item?.folderUri?.scheme === GITHUB_REMOTE_FILE_SCHEME) {
|
|
2279
|
+
value?.getWorkspaceTarget(item.item.folderUri).read(reader);
|
|
2280
|
+
}
|
|
2281
|
+
}
|
|
2282
|
+
if (this.actionWidgetService.isVisible && this._triggerElement?.getAttribute("aria-expanded") === "true") {
|
|
2283
|
+
this.actionWidgetService.updateItems(this._buildItems(), undefined, {
|
|
2284
|
+
preserveHover: true,
|
|
2285
|
+
preserveScrollPosition: true
|
|
2286
|
+
});
|
|
2287
|
+
}
|
|
2288
|
+
});
|
|
2289
|
+
}
|
|
2290
|
+
showPicker(force = false, anchor) {
|
|
2291
|
+
if (this.disabledReason !== undefined) {
|
|
2292
|
+
return;
|
|
2293
|
+
}
|
|
2294
|
+
this.setCloudConfiguration(this.cloudConfiguration);
|
|
2295
|
+
super.showPicker(force, anchor);
|
|
2296
|
+
}
|
|
2297
|
+
async waitForWorkspaceTargets(token) {
|
|
2298
|
+
const configuration = this.cloudConfiguration.get();
|
|
2299
|
+
if (!configuration) {
|
|
2300
|
+
return true;
|
|
2301
|
+
}
|
|
2302
|
+
await Promise.all(super._buildItems().flatMap(
|
|
2303
|
+
item => item.item?.folderUri?.scheme === GITHUB_REMOTE_FILE_SCHEME ? [waitForState(
|
|
2304
|
+
configuration.getWorkspaceTarget(item.item.folderUri),
|
|
2305
|
+
target => !target.pending,
|
|
2306
|
+
undefined,
|
|
2307
|
+
token
|
|
2308
|
+
)] : []
|
|
2309
|
+
));
|
|
2310
|
+
return !token.isCancellationRequested && configuration === this.cloudConfiguration.get();
|
|
1494
2311
|
}
|
|
1495
2312
|
setTargetModel(model) {
|
|
1496
2313
|
this.targetModel = model;
|
|
@@ -1506,11 +2323,47 @@ class AutomationsWorkspacePicker extends WorkspacePicker {
|
|
|
1506
2323
|
return false;
|
|
1507
2324
|
}
|
|
1508
2325
|
_buildItems() {
|
|
1509
|
-
const
|
|
2326
|
+
const configuration = this.cloudConfiguration.get();
|
|
2327
|
+
const items = super._buildItems().map(item => {
|
|
2328
|
+
if (item.item?.folderUri?.scheme !== GITHUB_REMOTE_FILE_SCHEME) {
|
|
2329
|
+
return item;
|
|
2330
|
+
}
|
|
2331
|
+
const reason = configuration ? configuration.getWorkspaceTarget(item.item.folderUri).get().disabledReason : ( localize(3748, "Cloud automations are unavailable."));
|
|
2332
|
+
return {
|
|
2333
|
+
...item,
|
|
2334
|
+
submenuActions: undefined,
|
|
2335
|
+
group: {
|
|
2336
|
+
title: "",
|
|
2337
|
+
icon: Codicon.repo
|
|
2338
|
+
},
|
|
2339
|
+
...(reason === undefined ? {} : {
|
|
2340
|
+
disabled: true,
|
|
2341
|
+
description: reason,
|
|
2342
|
+
ariaDescription: reason,
|
|
2343
|
+
tooltip: reason,
|
|
2344
|
+
hover: {
|
|
2345
|
+
content: reason
|
|
2346
|
+
}
|
|
2347
|
+
})
|
|
2348
|
+
};
|
|
2349
|
+
});
|
|
2350
|
+
if (configuration) {
|
|
2351
|
+
items.unshift({
|
|
2352
|
+
kind: ActionListItemKind.Action,
|
|
2353
|
+
label: ( localize(3749, "Work in GitHub")),
|
|
2354
|
+
group: {
|
|
2355
|
+
title: "",
|
|
2356
|
+
icon: Codicon.github
|
|
2357
|
+
},
|
|
2358
|
+
item: {
|
|
2359
|
+
id: "automation.workInGitHub"
|
|
2360
|
+
}
|
|
2361
|
+
});
|
|
2362
|
+
}
|
|
1510
2363
|
const noWorkspace = {
|
|
1511
2364
|
kind: ActionListItemKind.Action,
|
|
1512
|
-
label: (
|
|
1513
|
-
description: ( localize(
|
|
2365
|
+
label: this._getNoWorkspaceLabel(),
|
|
2366
|
+
description: ( localize(3750, "Run without a backing workspace")),
|
|
1514
2367
|
group: {
|
|
1515
2368
|
title: "",
|
|
1516
2369
|
icon: Codicon.commentDiscussion
|
|
@@ -1526,45 +2379,156 @@ class AutomationsWorkspacePicker extends WorkspacePicker {
|
|
|
1526
2379
|
}, ...items] : [noWorkspace];
|
|
1527
2380
|
}
|
|
1528
2381
|
async _dispatchPickerItem(item) {
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
2382
|
+
if (this.disabledReason !== undefined) {
|
|
2383
|
+
return false;
|
|
2384
|
+
}
|
|
2385
|
+
const generation = ++this.selectionGeneration;
|
|
2386
|
+
this.repositorySelection.clear();
|
|
2387
|
+
const resources = ( new DisposableStore());
|
|
2388
|
+
this.repositorySelection.value = resources;
|
|
2389
|
+
const token = cancelOnDispose(resources);
|
|
2390
|
+
try {
|
|
2391
|
+
const configuration = this.cloudConfiguration.get();
|
|
2392
|
+
if (item.id === "automation.workInGitHub") {
|
|
2393
|
+
if (!configuration) {
|
|
2394
|
+
throw ( new Error(( localize(3748, "Cloud automations are unavailable."))));
|
|
2395
|
+
}
|
|
2396
|
+
const folderUri = await configuration.pickWorkspace(token);
|
|
2397
|
+
if (!folderUri || token.isCancellationRequested || generation !== this.selectionGeneration) {
|
|
2398
|
+
return false;
|
|
2399
|
+
}
|
|
2400
|
+
item = {
|
|
2401
|
+
folderUri
|
|
2402
|
+
};
|
|
2403
|
+
}
|
|
2404
|
+
if (item.folderUri?.scheme === GITHUB_REMOTE_FILE_SCHEME) {
|
|
2405
|
+
if (!configuration) {
|
|
2406
|
+
throw ( new Error(( localize(3748, "Cloud automations are unavailable."))));
|
|
2407
|
+
}
|
|
2408
|
+
const target = await waitForState(
|
|
2409
|
+
configuration.getWorkspaceTarget(item.folderUri),
|
|
2410
|
+
target => !target.pending,
|
|
2411
|
+
undefined,
|
|
2412
|
+
token
|
|
2413
|
+
);
|
|
2414
|
+
if (!target.workspace || target.disabledReason) {
|
|
2415
|
+
throw ( new Error(target.disabledReason ?? ( localize(3751, "The repository must be private."))));
|
|
2416
|
+
}
|
|
2417
|
+
if (configuration !== this.cloudConfiguration.get()) {
|
|
2418
|
+
return false;
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2421
|
+
if (!(await this.onWillSelectWorkspace()) || token.isCancellationRequested || generation !== this.selectionGeneration) {
|
|
2422
|
+
return false;
|
|
2423
|
+
}
|
|
2424
|
+
this.selectingRepository = item.folderUri?.scheme === GITHUB_REMOTE_FILE_SCHEME;
|
|
2425
|
+
if (this.selectingRepository && item.folderUri) {
|
|
2426
|
+
const repositoryUri = item.folderUri;
|
|
2427
|
+
const workspace = this.sessionsProvidersService.getProviders().map(provider => provider.resolveWorkspace(repositoryUri)).find(workspace => workspace !== undefined);
|
|
2428
|
+
const related = workspace && this._findRelatedLocalWorkspace(workspace);
|
|
2429
|
+
if (related && this.offersCloud(related.workspace.folders[0].root, configuration)) {
|
|
2430
|
+
item = {
|
|
2431
|
+
folderUri: related.workspace.folders[0].root,
|
|
2432
|
+
providerId: related.providerId
|
|
2433
|
+
};
|
|
2434
|
+
}
|
|
2435
|
+
}
|
|
2436
|
+
const applied = await super._dispatchPickerItem(item);
|
|
2437
|
+
const selectedFolder = this.selectedFolderUri;
|
|
2438
|
+
if (applied && selectedFolder && (item.folderUri || item.browseActionIndex !== undefined)) {
|
|
2439
|
+
this.targetModel?.setQuickChat(false, selectedFolder);
|
|
2440
|
+
}
|
|
2441
|
+
return applied;
|
|
2442
|
+
} catch (error) {
|
|
2443
|
+
if (!isCancellationError(error) && !token.isCancellationRequested) {
|
|
2444
|
+
this.onSelectionError(error instanceof Error ? error : ( new Error(getErrorMessage(error))));
|
|
2445
|
+
}
|
|
2446
|
+
return false;
|
|
2447
|
+
} finally {
|
|
2448
|
+
if (this.repositorySelection.value === resources) {
|
|
2449
|
+
this.selectingRepository = false;
|
|
2450
|
+
this.repositorySelection.clear();
|
|
2451
|
+
}
|
|
1533
2452
|
}
|
|
1534
|
-
return applied;
|
|
1535
2453
|
}
|
|
1536
2454
|
_isSelectedFolder(folderUri) {
|
|
1537
2455
|
return !this.targetModel?.isQuickChat && super._isSelectedFolder(folderUri);
|
|
1538
2456
|
}
|
|
2457
|
+
offersCloud(folderUri, configuration) {
|
|
2458
|
+
return !!configuration && ( this.sessionsProvidersService.getProviders().some(provider => provider.resolveWorkspace(folderUri) && ( provider.getSessionTypes(folderUri).some(type => configuration.sessionTypes.includes(type.id)))));
|
|
2459
|
+
}
|
|
1539
2460
|
_renderTriggerLabel(trigger) {
|
|
1540
2461
|
clearNode(trigger);
|
|
1541
2462
|
const workspace = this.selectedResolved?.workspace;
|
|
1542
2463
|
const noWorkspace = this.targetModel?.isQuickChat === true;
|
|
1543
|
-
const label = noWorkspace ? (
|
|
2464
|
+
const label = noWorkspace ? this._getNoWorkspaceLabel() : workspace?.label ?? ( localize(3752, "Select workspace"));
|
|
1544
2465
|
const icon = noWorkspace ? Codicon.commentDiscussion : workspace?.icon ?? Codicon.project;
|
|
1545
|
-
trigger.setAttribute("aria-label", workspace || noWorkspace ? ( localize(
|
|
2466
|
+
trigger.setAttribute("aria-label", workspace || noWorkspace ? ( localize(3753, "Automation target, {0}", label)) : ( localize(3754, "Pick a workspace for this automation")));
|
|
2467
|
+
const disabled = this.disabledReason !== undefined;
|
|
2468
|
+
trigger.setAttribute("aria-disabled", String(disabled));
|
|
2469
|
+
trigger.tabIndex = disabled ? -1 : 0;
|
|
2470
|
+
trigger.parentElement?.classList.toggle("disabled", disabled);
|
|
2471
|
+
if (disabled) {
|
|
2472
|
+
trigger.removeAttribute("aria-haspopup");
|
|
2473
|
+
trigger.setAttribute("aria-expanded", "false");
|
|
2474
|
+
trigger.setAttribute("aria-label", ( localize(3755, "Automation target, {0}. {1}", label, this.disabledReason)));
|
|
2475
|
+
} else {
|
|
2476
|
+
trigger.setAttribute("aria-haspopup", "listbox");
|
|
2477
|
+
}
|
|
1546
2478
|
const renderedIcon = append(trigger, renderIcon(icon));
|
|
1547
2479
|
renderedIcon.setAttribute("aria-hidden", "true");
|
|
1548
2480
|
append(trigger, $("span.sessions-chat-dropdown-label", undefined, label));
|
|
1549
|
-
|
|
1550
|
-
|
|
1551
|
-
|
|
2481
|
+
if (!disabled) {
|
|
2482
|
+
const chevron = append(trigger, renderIcon(Codicon.chevronDownCompact));
|
|
2483
|
+
chevron.classList.add("sessions-chat-dropdown-chevron");
|
|
2484
|
+
chevron.setAttribute("aria-hidden", "true");
|
|
2485
|
+
}
|
|
1552
2486
|
}
|
|
1553
2487
|
_getAllBrowseActions() {
|
|
1554
2488
|
return super._getAllBrowseActions().filter(a => a.group === SESSION_WORKSPACE_GROUP_LOCAL);
|
|
1555
2489
|
}
|
|
1556
2490
|
}
|
|
1557
2491
|
class MobileAutomationsWorkspacePicker extends AutomationsWorkspacePicker {
|
|
2492
|
+
constructor() {
|
|
2493
|
+
super(...arguments);
|
|
2494
|
+
this.pendingPicker = this._register(( new MutableDisposable()));
|
|
2495
|
+
}
|
|
1558
2496
|
setLayoutService(layoutService) {
|
|
1559
2497
|
this.layoutService = layoutService;
|
|
1560
2498
|
}
|
|
1561
2499
|
showPicker(force = false, anchor) {
|
|
2500
|
+
if (this.disabledReason !== undefined) {
|
|
2501
|
+
return;
|
|
2502
|
+
}
|
|
1562
2503
|
const triggerElement = anchor ?? this._triggerElement;
|
|
1563
2504
|
if (!triggerElement || !this.layoutService || !shouldUseMobileWorkspacePickerSheet(this.layoutService)) {
|
|
1564
2505
|
super.showPicker(force, anchor);
|
|
1565
2506
|
return;
|
|
1566
2507
|
}
|
|
1567
|
-
|
|
2508
|
+
this.pendingPicker.clear();
|
|
2509
|
+
const pending = ( new DisposableStore());
|
|
2510
|
+
this.pendingPicker.value = pending;
|
|
2511
|
+
const cancellation = cancelOnDispose(pending);
|
|
2512
|
+
pending.add(toDisposable(() => {
|
|
2513
|
+
triggerElement.removeAttribute("aria-busy");
|
|
2514
|
+
}));
|
|
2515
|
+
triggerElement.setAttribute("aria-busy", "true");
|
|
2516
|
+
void this.showReadyMobilePicker(triggerElement, this.layoutService, cancellation).catch(error => {
|
|
2517
|
+
if (!isCancellationError(error)) {
|
|
2518
|
+
this.onSelectionError(error instanceof Error ? error : ( new Error(getErrorMessage(error))));
|
|
2519
|
+
}
|
|
2520
|
+
}).finally(() => {
|
|
2521
|
+
if (this.pendingPicker.value === pending) {
|
|
2522
|
+
this.pendingPicker.clear();
|
|
2523
|
+
}
|
|
2524
|
+
});
|
|
2525
|
+
}
|
|
2526
|
+
async showReadyMobilePicker(trigger, layoutService, token) {
|
|
2527
|
+
if (!(await this.waitForWorkspaceTargets(token)) || !trigger.isConnected || this.disabledReason !== undefined) {
|
|
2528
|
+
return;
|
|
2529
|
+
}
|
|
2530
|
+
trigger.removeAttribute("aria-busy");
|
|
2531
|
+
await showMobileWorkspacePickerSheet(layoutService, trigger, this._buildItems(), item => {
|
|
1568
2532
|
void this._dispatchPickerItem(item);
|
|
1569
2533
|
}, this._getAllBrowseActions());
|
|
1570
2534
|
}
|
|
@@ -1586,4 +2550,4 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
|
|
1586
2550
|
}
|
|
1587
2551
|
});
|
|
1588
2552
|
|
|
1589
|
-
export { AutomationIsolationGroupActionViewItem, AutomationSessionDraftSynchronizer, AutomationsWorkspacePicker, MobileAutomationsWorkspacePicker, canSelectAutomationWorkspace, isAutomationDialogPopupTarget, registerAutomationDialogKeyboardNavigation, renderForm, shouldPassThroughAutomationDialogCommand, updateSaveButtonState };
|
|
2553
|
+
export { AutomationCustomizationSelection, AutomationIsolationGroupActionViewItem, AutomationSessionDraftSynchronizer, AutomationsWorkspacePicker, MobileAutomationsWorkspacePicker, canSelectAutomationWorkspace, createAutomationTarget, getAutomationDialogProviders, isAutomationDialogPopupTarget, registerAutomationDialogKeyboardNavigation, renderForm, shouldPassThroughAutomationDialogCommand, updateSaveButtonState };
|