@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
|
@@ -3,7 +3,7 @@ import { registerCss } from '@codingame/monaco-vscode-api/css';
|
|
|
3
3
|
import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
|
|
4
4
|
import * as automationsCards from '../media/automationsCards.css';
|
|
5
5
|
import './automationsAccessibility.js';
|
|
6
|
-
import { $ as $$1, trackFocus, append, DragAndDropObserver, addDisposableListener, EventType, isHTMLElement, getWindow, EventHelper, getActiveElement, isActiveElement, isAncestor, clearNode, isAncestorOfActiveElement
|
|
6
|
+
import { $ as $$1, trackFocus, append, DragAndDropObserver, addDisposableListener, EventType, isHTMLElement, getWindow, EventHelper, getActiveElement, isActiveElement, isAncestor, reset, clearNode, isAncestorOfActiveElement } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/dom';
|
|
7
7
|
import { VSBuffer } from '@codingame/monaco-vscode-api/vscode/vs/base/common/buffer';
|
|
8
8
|
import { ButtonBar, Button } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/ui/button/button';
|
|
9
9
|
import { getDefaultHoverDelegate } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/ui/hover/hoverDelegateFactory';
|
|
@@ -17,18 +17,23 @@ import { generateUuid } from '@codingame/monaco-vscode-api/vscode/vs/base/common
|
|
|
17
17
|
import { localize, localize2 } from '@codingame/monaco-vscode-api/vscode/vs/nls';
|
|
18
18
|
import { IInstantiationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation';
|
|
19
19
|
import { IHoverService } from '@codingame/monaco-vscode-api/vscode/vs/platform/hover/browser/hover.service';
|
|
20
|
+
import { IOpenerService } from '@codingame/monaco-vscode-api/vscode/vs/platform/opener/common/opener.service';
|
|
21
|
+
import { WorkbenchToolBar } from '@codingame/monaco-vscode-api/vscode/vs/platform/actions/browser/toolbar';
|
|
20
22
|
import { IUriIdentityService } from '@codingame/monaco-vscode-api/vscode/vs/platform/uriIdentity/common/uriIdentity.service';
|
|
21
23
|
import { IAutomationService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/automations/automationService.service';
|
|
22
24
|
import { CHAT_AUTOMATIONS_ENABLED_SETTING, ChatAutomationsEnabledContext } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/automations/automationsEnabled';
|
|
23
25
|
import { IAutomationRunner } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/automations/automationRunner.service';
|
|
24
26
|
import { IAutomationDialogService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/automations/automationDialogService.service';
|
|
25
27
|
import { AutomationBlueprintParseError, AUTOMATION_BLUEPRINT_FILE_SUFFIX, parseAutomationBlueprint, createAutomationBlueprintFileName, serializeAutomationBlueprint, automationToBlueprint } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/automations/automationBlueprint';
|
|
26
|
-
import { DAYS_OF_WEEK } from '
|
|
28
|
+
import { automationScheduleToLocal, DAYS_OF_WEEK } from '../../../../../workbench/contrib/chat/common/automations/schedule.js';
|
|
27
29
|
import { IAgentPluginService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/plugins/agentPluginService.service';
|
|
28
30
|
import { AgentSessionApprovalModel } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/browser/agentSessions/agentSessionApprovalModel';
|
|
29
31
|
import { isEqual, basename, joinPath, dirname } from '@codingame/monaco-vscode-api/vscode/vs/base/common/resources';
|
|
30
32
|
import { CancellationToken } from '@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation';
|
|
33
|
+
import { isCancellationError } from '@codingame/monaco-vscode-api/vscode/vs/base/common/errors';
|
|
31
34
|
import { ILogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/log/common/log.service';
|
|
35
|
+
import { INotificationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/notification/common/notification.service';
|
|
36
|
+
import { ITelemetryService } from '@codingame/monaco-vscode-api/vscode/vs/platform/telemetry/common/telemetry.service';
|
|
32
37
|
import { IDialogService, IFileDialogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/dialogs/common/dialogs.service';
|
|
33
38
|
import { IFileService } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service';
|
|
34
39
|
import { StorageScope, StorageTarget } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage';
|
|
@@ -52,11 +57,14 @@ import { MenuItemAction, MenuRegistry, registerAction2, Action2 } from '@codinga
|
|
|
52
57
|
import { IActionViewItemService } from '@codingame/monaco-vscode-api/vscode/vs/platform/actions/browser/actionViewItemService.service';
|
|
53
58
|
import { getChatSessionArchiveActionWording, ChatSessionArchiveActionWordingSettingId, getChatSessionArchiveActionPresentation } from '@codingame/monaco-vscode-api/vscode/vs/platform/chat/common/sessionArchiveActions';
|
|
54
59
|
import { BaseActionViewItem } from '@codingame/monaco-vscode-api/vscode/vs/base/browser/ui/actionbar/actionViewItems';
|
|
60
|
+
import { Action } from '@codingame/monaco-vscode-api/vscode/vs/base/common/actions';
|
|
55
61
|
import { AutomationsCustomViewFocusContext, AutomationsHasItemsContext, SessionIsReadContext, SessionIsArchivedContext, SessionSupportsRenameContext } from '@codingame/monaco-vscode-api/vscode/vs/sessions/common/contextkeys';
|
|
56
|
-
import { SessionsFlatList, SessionItemStatusContext } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/sessions/browser/views/sessionsList';
|
|
62
|
+
import { SessionsFlatList, formatSessionListTime, SessionItemStatusContext } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/sessions/browser/views/sessionsList';
|
|
57
63
|
import { AUTOMATIONS_CUSTOM_VIEW_ID } from '@codingame/monaco-vscode-api/vscode/vs/sessions/contrib/sessions/browser/automationsConstants';
|
|
58
64
|
import { ARCHIVE_SESSION_COMMAND_ID, MARK_SESSION_READ_COMMAND_ID, MARK_SESSION_UNREAD_COMMAND_ID, RENAME_SESSION_COMMAND_ID, UNARCHIVE_SESSION_COMMAND_ID } from '@codingame/monaco-vscode-api/vscode/vs/sessions/common/sessionCommands';
|
|
59
65
|
import { readAutomationTemplates } from './automationTemplates.js';
|
|
66
|
+
import { getUnavailableAutomationsReasons } from './automationCataloguePresentation.js';
|
|
67
|
+
import { logAutomationViewShown, withAutomationDialogPersistenceTelemetry } from '../../../automations/browser/automationTelemetry.js';
|
|
60
68
|
import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
|
|
61
69
|
import { constObservable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/constObservable';
|
|
62
70
|
import { observableValue } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/observableValue';
|
|
@@ -69,6 +77,7 @@ const STOP_AUTOMATION_RUN_SESSION_COMMAND_ID = "sessions.automations.stopRunSess
|
|
|
69
77
|
const SEEN_PLUGIN_AUTOMATION_TEMPLATES_STORAGE_KEY = "sessions.automations.seenPluginTemplateIds";
|
|
70
78
|
const AutomationCardCanDeleteContext = new RawContextKey("sessionsAutomationCardCanDelete", false);
|
|
71
79
|
const AutomationCardCanUpdateContext = new RawContextKey("sessionsAutomationCardCanUpdate", false);
|
|
80
|
+
const AutomationCardHasExternalResourceContext = new RawContextKey("sessionsAutomationCardHasExternalResource", false);
|
|
72
81
|
const AutomationCardEnabledContext = new RawContextKey("sessionsAutomationCardEnabled", false);
|
|
73
82
|
function areAutomationTemplatesEqual(first, second) {
|
|
74
83
|
return first.length === second.length && first.every((template, index) => {
|
|
@@ -86,14 +95,21 @@ let AutomationsCardsWidget = class AutomationsCardsWidget extends Disposable {
|
|
|
86
95
|
sessionsManagementService,
|
|
87
96
|
instantiationService,
|
|
88
97
|
contextKeyService,
|
|
89
|
-
uriIdentityService
|
|
98
|
+
uriIdentityService,
|
|
99
|
+
telemetryService,
|
|
100
|
+
logService,
|
|
101
|
+
notificationService
|
|
90
102
|
) {
|
|
91
103
|
super();
|
|
92
104
|
this.automationService = automationService;
|
|
93
105
|
this.agentPluginService = agentPluginService;
|
|
94
106
|
this.sessionsManagementService = sessionsManagementService;
|
|
95
107
|
this.uriIdentityService = uriIdentityService;
|
|
108
|
+
this.telemetryService = telemetryService;
|
|
109
|
+
this.logService = logService;
|
|
110
|
+
this.notificationService = notificationService;
|
|
96
111
|
this.isMarkingAllRead = observableValue(this, false);
|
|
112
|
+
logAutomationViewShown(this.telemetryService);
|
|
97
113
|
this.element = $(".automations-cards-widget");
|
|
98
114
|
this.element.tabIndex = -1;
|
|
99
115
|
const focusContext = AutomationsCustomViewFocusContext.bindTo(contextKeyService);
|
|
@@ -105,6 +121,24 @@ let AutomationsCardsWidget = class AutomationsCardsWidget extends Disposable {
|
|
|
105
121
|
this.cardsSection = this._register(
|
|
106
122
|
instantiationService.createInstance(AutomationCardsSection, scrollContent, this.element)
|
|
107
123
|
);
|
|
124
|
+
const historyState = append(scrollContent, $(".automations-history-state", {
|
|
125
|
+
role: "status"
|
|
126
|
+
}));
|
|
127
|
+
this._register(autorun(reader => {
|
|
128
|
+
const state = this.automationService.historyState?.read(reader);
|
|
129
|
+
const catalogueState = this.automationService.catalogueState.read(reader);
|
|
130
|
+
const hasAutomations = this.automationService.automations.read(reader).length > 0;
|
|
131
|
+
const hasRuns = this.automationService.runs.read(reader).length > 0;
|
|
132
|
+
const message = state === "error" ? hasRuns ? ( localize(
|
|
133
|
+
5964,
|
|
134
|
+
"Run history could not be refreshed. Showing the last available history. Use Refresh to try again."
|
|
135
|
+
)) : ( localize(5965, "Run history could not be loaded. Use Refresh to try again.")) : catalogueState === "ready" && (state === undefined || state === "ready") && hasAutomations && !hasRuns ? ( localize(
|
|
136
|
+
5966,
|
|
137
|
+
"No runs yet. Run an automation now or wait for its next scheduled run."
|
|
138
|
+
)) : "";
|
|
139
|
+
historyState.textContent = message;
|
|
140
|
+
historyState.style.display = message ? "" : "none";
|
|
141
|
+
}));
|
|
108
142
|
this.historySection = this._register(instantiationService.createInstance(
|
|
109
143
|
AutomationHistorySection,
|
|
110
144
|
scrollContent,
|
|
@@ -113,9 +147,11 @@ let AutomationsCardsWidget = class AutomationsCardsWidget extends Disposable {
|
|
|
113
147
|
));
|
|
114
148
|
this._register(autorun(reader => {
|
|
115
149
|
const catalogueState = this.automationService.catalogueState.read(reader);
|
|
150
|
+
this.automationService.availableProviders.read(reader);
|
|
151
|
+
const unavailableProviders = this.automationService.unavailableProviders.read(reader);
|
|
116
152
|
const items = this.automationService.automations.read(reader);
|
|
117
153
|
const templates = readAutomationTemplates(this.agentPluginService.plugins.read(reader), reader);
|
|
118
|
-
this.cardsSection.render(items, catalogueState, templates);
|
|
154
|
+
this.cardsSection.render(items, catalogueState, unavailableProviders, templates);
|
|
119
155
|
}));
|
|
120
156
|
const sessionDeleted = observableSignalFromEvent(this, this.sessionsManagementService.onDidDeleteSession);
|
|
121
157
|
const sessionsChanged = observableSignalFromEvent(this, this.sessionsManagementService.onDidChangeSessions);
|
|
@@ -125,6 +161,8 @@ let AutomationsCardsWidget = class AutomationsCardsWidget extends Disposable {
|
|
|
125
161
|
}
|
|
126
162
|
sessionDeleted.read(reader);
|
|
127
163
|
sessionsChanged.read(reader);
|
|
164
|
+
this.automationService.availableProviders.read(reader);
|
|
165
|
+
this.automationService.catalogueState.read(reader);
|
|
128
166
|
this.automationService.automations.read(reader);
|
|
129
167
|
const allRuns = this.automationService.runs.read(reader);
|
|
130
168
|
const sessionsByResource = ( new Map(this.sessionsManagementService.getSessions().map(
|
|
@@ -142,6 +180,7 @@ let AutomationsCardsWidget = class AutomationsCardsWidget extends Disposable {
|
|
|
142
180
|
}
|
|
143
181
|
this.historySection.render(allRuns, sessions);
|
|
144
182
|
}));
|
|
183
|
+
void refreshAutomations(this.automationService, this.logService, this.notificationService);
|
|
145
184
|
}
|
|
146
185
|
layout(width, height) {
|
|
147
186
|
this.element.style.width = `${width}px`;
|
|
@@ -151,7 +190,7 @@ let AutomationsCardsWidget = class AutomationsCardsWidget extends Disposable {
|
|
|
151
190
|
this.element.focus();
|
|
152
191
|
}
|
|
153
192
|
};
|
|
154
|
-
AutomationsCardsWidget = ( __decorate([( __param(0, IAutomationService)), ( __param(1, IAgentPluginService)), ( __param(2, ISessionsManagementService)), ( __param(3, IInstantiationService)), ( __param(4, IContextKeyService)), ( __param(5, IUriIdentityService))], AutomationsCardsWidget));
|
|
193
|
+
AutomationsCardsWidget = ( __decorate([( __param(0, IAutomationService)), ( __param(1, IAgentPluginService)), ( __param(2, ISessionsManagementService)), ( __param(3, IInstantiationService)), ( __param(4, IContextKeyService)), ( __param(5, IUriIdentityService)), ( __param(6, ITelemetryService)), ( __param(7, ILogService)), ( __param(8, INotificationService))], AutomationsCardsWidget));
|
|
155
194
|
let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
156
195
|
constructor(
|
|
157
196
|
parent,
|
|
@@ -166,7 +205,8 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
166
205
|
storageService,
|
|
167
206
|
configurationService,
|
|
168
207
|
contextKeyService,
|
|
169
|
-
contextMenuService
|
|
208
|
+
contextMenuService,
|
|
209
|
+
telemetryService
|
|
170
210
|
) {
|
|
171
211
|
super();
|
|
172
212
|
this.focusRoot = focusRoot;
|
|
@@ -181,6 +221,7 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
181
221
|
this.configurationService = configurationService;
|
|
182
222
|
this.contextKeyService = contextKeyService;
|
|
183
223
|
this.contextMenuService = contextMenuService;
|
|
224
|
+
this.telemetryService = telemetryService;
|
|
184
225
|
this.persistentCards = ( new Map());
|
|
185
226
|
this.latestAutomations = ( new Map());
|
|
186
227
|
this.emptyStateDisposables = this._register(( new DisposableStore()));
|
|
@@ -193,6 +234,7 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
193
234
|
this.pluginTemplatesUserToggled = false;
|
|
194
235
|
this.currentPluginTemplateIds = ( new Set());
|
|
195
236
|
this.partialState = "ready";
|
|
237
|
+
this.partialUnavailableProviders = [];
|
|
196
238
|
this.focusRequestGeneration = 0;
|
|
197
239
|
this.seenPluginTemplateIds = this.readSeenPluginTemplateIds();
|
|
198
240
|
this._register(this.storageService.onDidChangeValue(
|
|
@@ -203,22 +245,19 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
203
245
|
this.seenPluginTemplateIds = this.readSeenPluginTemplateIds();
|
|
204
246
|
this.updatePluginTemplateUnreadState(false);
|
|
205
247
|
}));
|
|
248
|
+
this.container = append(parent, $(".automations-cards-grid"));
|
|
249
|
+
this.container.style.display = "none";
|
|
206
250
|
this.partialStateContainer = append(parent, $(".automations-cards-partial-state"));
|
|
207
251
|
this.partialStateContainer.setAttribute("role", "status");
|
|
208
252
|
this.partialStateContainer.setAttribute("aria-live", "polite");
|
|
209
253
|
this.partialStateContainer.style.display = "none";
|
|
210
|
-
this.partialLoadingIcon = append(this.partialStateContainer, $("span.automations-cards-partial-state-icon"));
|
|
211
|
-
this.partialLoadingIcon.classList.add(...ThemeIcon.asClassNameArray(Codicon.loading), "codicon-modifier-spin");
|
|
212
|
-
this.partialLoadingIcon.setAttribute("aria-hidden", "true");
|
|
213
254
|
this.partialErrorIcon = append(this.partialStateContainer, $("span.automations-cards-partial-state-icon"));
|
|
214
255
|
this.partialErrorIcon.classList.add(...ThemeIcon.asClassNameArray(Codicon.warning));
|
|
215
256
|
this.partialErrorIcon.setAttribute("aria-hidden", "true");
|
|
216
257
|
this.partialStateMessage = append(
|
|
217
258
|
this.partialStateContainer,
|
|
218
|
-
$("
|
|
259
|
+
$("div.automations-cards-partial-state-message")
|
|
219
260
|
);
|
|
220
|
-
this.container = append(parent, $(".automations-cards-grid"));
|
|
221
|
-
this.container.style.display = "none";
|
|
222
261
|
this.emptyContainer = append(parent, $(".automations-cards-empty"));
|
|
223
262
|
this.emptyContainer.style.display = "none";
|
|
224
263
|
this.loadingContainer = append(parent, $(".automations-cards-state.automations-cards-loading"));
|
|
@@ -226,7 +265,9 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
226
265
|
this.loadingCreateButton = this.renderLoadingState();
|
|
227
266
|
this.unavailableContainer = append(parent, $(".automations-cards-state.automations-cards-unavailable"));
|
|
228
267
|
this.unavailableContainer.style.display = "none";
|
|
229
|
-
|
|
268
|
+
const unavailableState = this.renderUnavailableState();
|
|
269
|
+
this.unavailableCreateButton = unavailableState.createButton;
|
|
270
|
+
this.unavailableDescription = unavailableState.description;
|
|
230
271
|
this.errorContainer = append(parent, $(".automations-cards-state.automations-cards-error"));
|
|
231
272
|
this.errorContainer.style.display = "none";
|
|
232
273
|
this.errorCreateButton = this.renderErrorState();
|
|
@@ -239,9 +280,9 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
239
280
|
dropIcon.classList.add(...ThemeIcon.asClassNameArray(Codicon.cloudUpload));
|
|
240
281
|
dropIcon.setAttribute("aria-hidden", "true");
|
|
241
282
|
const dropTitle = append(this.dropOverlay, $("span.automations-drop-overlay-title"));
|
|
242
|
-
dropTitle.textContent = ( localize(
|
|
283
|
+
dropTitle.textContent = ( localize(5967, "Drop to import automation"));
|
|
243
284
|
const dropDescription = append(this.dropOverlay, $("span.automations-drop-overlay-description"));
|
|
244
|
-
dropDescription.textContent = ( localize(
|
|
285
|
+
dropDescription.textContent = ( localize(5968, "You can review the Automation before creating it."));
|
|
245
286
|
this._register(new DragAndDropObserver(this.focusRoot, {
|
|
246
287
|
onDragEnter: event => this.updateDropOverlay(event),
|
|
247
288
|
onDragOver: event => this.updateDropOverlay(event),
|
|
@@ -298,8 +339,8 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
298
339
|
}
|
|
299
340
|
EventHelper.stop(event, true);
|
|
300
341
|
if (dropData.kind === "invalid") {
|
|
301
|
-
const detail = dropData.reason === "multiple" ? ( localize(
|
|
302
|
-
void this.dialogService.error(( localize(
|
|
342
|
+
const detail = dropData.reason === "multiple" ? ( localize(5969, "Drop one Automation blueprint file at a time.")) : ( localize(5970, "Only .automation.md files can be imported."));
|
|
343
|
+
void this.dialogService.error(( localize(5971, "Unable to import automation.")), detail);
|
|
303
344
|
return;
|
|
304
345
|
}
|
|
305
346
|
const readContent = dropData.kind === "resource" ? async () => ( (await this.fileService.readFile(dropData.resource)).value.toString()) : async () => ( VSBuffer.wrap(( new Uint8Array(await dropData.file.arrayBuffer()))).toString());
|
|
@@ -309,10 +350,11 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
309
350
|
this.automationService,
|
|
310
351
|
this.configurationService,
|
|
311
352
|
this.dialogService,
|
|
312
|
-
this.logService
|
|
353
|
+
this.logService,
|
|
354
|
+
this.telemetryService
|
|
313
355
|
);
|
|
314
356
|
}
|
|
315
|
-
render(automations, catalogueState, templates) {
|
|
357
|
+
render(automations, catalogueState, unavailableProviders, templates) {
|
|
316
358
|
const activeElement = getActiveElement();
|
|
317
359
|
const contentOwnedFocus = isHTMLElement(activeElement) && (this.visibleContainer?.contains(activeElement) || this.templatesContainer.contains(activeElement));
|
|
318
360
|
const activeAutomationIds = ( new Set(automations.map(automation => automation.id)));
|
|
@@ -333,7 +375,7 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
333
375
|
if (!card) {
|
|
334
376
|
card = this.renderCard(automation);
|
|
335
377
|
this.persistentCards.set(automation.id, card);
|
|
336
|
-
} else
|
|
378
|
+
} else {
|
|
337
379
|
this.updateCard(card, automation, prev);
|
|
338
380
|
}
|
|
339
381
|
const currentElement = this.container.children.item(index);
|
|
@@ -369,13 +411,21 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
369
411
|
);
|
|
370
412
|
const showTemplateSections = templates.length > 0;
|
|
371
413
|
this.templatesContainer.style.display = showTemplateSections ? "" : "none";
|
|
414
|
+
if (unavailableProviders.length > 0) {
|
|
415
|
+
this.renderUnavailableMessage(this.unavailableDescription, unavailableProviders);
|
|
416
|
+
} else {
|
|
417
|
+
this.unavailableDescription.textContent = ( localize(
|
|
418
|
+
5972,
|
|
419
|
+
"One or more providers are disconnected, disabled, or do not support automations."
|
|
420
|
+
));
|
|
421
|
+
}
|
|
372
422
|
const nextContainer = automations.length === 0 ? this.getEmptyStateContainer(catalogueState) : this.container;
|
|
373
423
|
const previousContainer = this.visibleContainer;
|
|
374
424
|
if (previousContainer !== nextContainer) {
|
|
375
425
|
nextContainer.style.display = "";
|
|
376
426
|
this.visibleContainer = nextContainer;
|
|
377
427
|
}
|
|
378
|
-
this.renderPartialState(automations.length > 0 ? catalogueState : "ready");
|
|
428
|
+
this.renderPartialState(automations.length > 0 ? catalogueState : "ready", unavailableProviders);
|
|
379
429
|
if (!this.focusPendingAutomation() && contentOwnedFocus && isHTMLElement(activeElement)) {
|
|
380
430
|
if (!nextContainer.contains(activeElement) && !(showTemplateSections && this.isVisibleTemplateElement(activeElement))) {
|
|
381
431
|
this.focusVisibleState(automations, catalogueState);
|
|
@@ -419,6 +469,7 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
419
469
|
const cardContextKeyService = disposables.add(this.contextKeyService.createScoped(card));
|
|
420
470
|
const canDeleteContext = AutomationCardCanDeleteContext.bindTo(cardContextKeyService);
|
|
421
471
|
const canUpdateContext = AutomationCardCanUpdateContext.bindTo(cardContextKeyService);
|
|
472
|
+
const hasExternalResourceContext = AutomationCardHasExternalResourceContext.bindTo(cardContextKeyService);
|
|
422
473
|
const enabledContext = AutomationCardEnabledContext.bindTo(cardContextKeyService);
|
|
423
474
|
disposables.add(Gesture.addTarget(card));
|
|
424
475
|
const main = append(card, $("button.automations-card-main", {
|
|
@@ -426,42 +477,53 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
426
477
|
}));
|
|
427
478
|
const nameRow = append(main, $(".automations-card-name"));
|
|
428
479
|
const nameTextEl = append(nameRow, $("span.automations-card-name-text"));
|
|
429
|
-
const
|
|
430
|
-
|
|
480
|
+
const promptEl = append(main, $(".automations-card-prompt"));
|
|
481
|
+
const promptHover = disposables.add(this.hoverService.setupManagedHover(
|
|
482
|
+
getDefaultHoverDelegate("element"),
|
|
483
|
+
promptEl,
|
|
484
|
+
() => promptEl.textContent ?? ""
|
|
485
|
+
));
|
|
486
|
+
disposables.add(addDisposableListener(main, EventType.FOCUS, () => {
|
|
487
|
+
if (main.matches(":focus-visible")) {
|
|
488
|
+
promptHover.show();
|
|
489
|
+
}
|
|
490
|
+
}));
|
|
491
|
+
disposables.add(
|
|
492
|
+
addDisposableListener(main, EventType.BLUR, () => promptHover.hide())
|
|
493
|
+
);
|
|
431
494
|
const metaEl = append(main, $(".automations-card-meta"));
|
|
432
495
|
const scheduleEl = append(metaEl, $("span.automations-card-meta-item.automations-card-schedule"));
|
|
433
496
|
const folderEl = append(metaEl, $("span.automations-card-meta-item.automations-card-folder"));
|
|
434
497
|
const folderHover = disposables.add(( new MutableDisposable()));
|
|
435
|
-
const promptEl = append(main, $(".automations-card-prompt"));
|
|
436
498
|
const actions = append(card, $(".automations-card-actions"));
|
|
437
499
|
actions.setAttribute("role", "group");
|
|
438
500
|
const buttonBar = disposables.add(( new ButtonBar(actions)));
|
|
439
|
-
const runNowLabel = ( localize(
|
|
440
|
-
const runningLabel = ( localize(
|
|
501
|
+
const runNowLabel = ( localize(5973, "Run now"));
|
|
502
|
+
const runningLabel = ( localize(5974, "Running"));
|
|
441
503
|
const runBtn = this.createIconButton(
|
|
442
504
|
buttonBar,
|
|
443
505
|
Codicon.play,
|
|
444
506
|
runNowLabel,
|
|
445
|
-
this.automationService.canRunAutomation
|
|
507
|
+
!this.automationService.canRunAutomation(automation.id)
|
|
446
508
|
);
|
|
447
509
|
runBtn.element.classList.add("automations-card-run-button");
|
|
448
510
|
disposables.add(runBtn.onDidClick(e => {
|
|
449
511
|
e?.stopPropagation();
|
|
450
512
|
const currentAutomation = this.latestAutomations.get(automation.id);
|
|
451
|
-
if (!currentAutomation || this.automationService.canRunAutomation
|
|
513
|
+
if (!currentAutomation || !this.automationService.canRunAutomation(automation.id)) {
|
|
452
514
|
return;
|
|
453
515
|
}
|
|
454
516
|
runBtn.enabled = false;
|
|
455
517
|
runBtn.setAriaLabel(runningLabel);
|
|
456
518
|
runBtn.setTitle(runningLabel);
|
|
457
519
|
disposableTimeout(() => {
|
|
458
|
-
runBtn.enabled = this.automationService.canRunAutomation
|
|
520
|
+
runBtn.enabled = this.automationService.canRunAutomation(automation.id);
|
|
459
521
|
runBtn.setAriaLabel(runNowLabel);
|
|
460
522
|
runBtn.setTitle(runNowLabel);
|
|
461
523
|
}, 10_000, disposables);
|
|
462
524
|
void this.runNow(currentAutomation);
|
|
463
525
|
}));
|
|
464
|
-
const moreActionsButton = this.createIconButton(buttonBar, Codicon.kebabVertical, ( localize(
|
|
526
|
+
const moreActionsButton = this.createIconButton(buttonBar, Codicon.kebabVertical, ( localize(5975, "More Actions...")), false);
|
|
465
527
|
moreActionsButton.element.classList.add("automations-card-more-actions-button");
|
|
466
528
|
moreActionsButton.element.setAttribute("aria-haspopup", "menu");
|
|
467
529
|
moreActionsButton.element.setAttribute("aria-expanded", "false");
|
|
@@ -494,7 +556,7 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
494
556
|
return;
|
|
495
557
|
}
|
|
496
558
|
const currentAutomation = this.latestAutomations.get(automation.id);
|
|
497
|
-
if (!currentAutomation || this.automationService.canUpdateAutomation
|
|
559
|
+
if (!currentAutomation || !this.automationService.canUpdateAutomation(automation.id)) {
|
|
498
560
|
return;
|
|
499
561
|
}
|
|
500
562
|
void this.openEditDialog(currentAutomation);
|
|
@@ -508,6 +570,7 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
508
570
|
runButton: runBtn,
|
|
509
571
|
moreActionsButton,
|
|
510
572
|
canDeleteContext,
|
|
573
|
+
hasExternalResourceContext,
|
|
511
574
|
canUpdateContext,
|
|
512
575
|
enabledContext,
|
|
513
576
|
nameText: nameTextEl,
|
|
@@ -515,46 +578,56 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
515
578
|
folderEl,
|
|
516
579
|
folderHover,
|
|
517
580
|
promptEl,
|
|
518
|
-
disabledBadge,
|
|
519
581
|
disposables
|
|
520
582
|
};
|
|
521
583
|
this.updateCard(entry, automation);
|
|
522
584
|
return entry;
|
|
523
585
|
}
|
|
524
586
|
updateCard(card, automation, previous) {
|
|
525
|
-
card.main.disabled = this.automationService.canUpdateAutomation
|
|
526
|
-
card.runButton.enabled = this.automationService.canRunAutomation
|
|
527
|
-
card.canDeleteContext.set(this.automationService.canDeleteAutomation
|
|
528
|
-
card.
|
|
587
|
+
card.main.disabled = !this.automationService.canUpdateAutomation(automation.id);
|
|
588
|
+
card.runButton.enabled = this.automationService.canRunAutomation(automation.id);
|
|
589
|
+
card.canDeleteContext.set(this.automationService.canDeleteAutomation(automation.id));
|
|
590
|
+
card.hasExternalResourceContext.set(automation.externalResource !== undefined);
|
|
591
|
+
card.canUpdateContext.set(this.automationService.canUpdateAutomation(automation.id));
|
|
529
592
|
card.enabledContext.set(automation.enabled);
|
|
530
|
-
const schedule = formatSchedule(automation.schedule);
|
|
531
|
-
const
|
|
593
|
+
const schedule = automation.enabled ? formatSchedule(automation.schedule) : ( localize(5976, "Disabled"));
|
|
594
|
+
const enabledChanged = !previous || previous.enabled !== automation.enabled;
|
|
595
|
+
const scheduleChanged = !previous || enabledChanged || formatSchedule(previous.schedule) !== formatSchedule(automation.schedule);
|
|
532
596
|
const nameChanged = !previous || previous.name !== automation.name;
|
|
533
597
|
if (nameChanged || scheduleChanged) {
|
|
534
|
-
card.card.setAttribute("aria-label", ( localize(
|
|
598
|
+
card.card.setAttribute("aria-label", ( localize(5977, "{0} — {1}", automation.name, schedule)));
|
|
535
599
|
}
|
|
536
600
|
if (nameChanged) {
|
|
537
|
-
card.main.setAttribute("aria-label", ( localize(
|
|
538
|
-
card.actions.setAttribute("aria-label", ( localize(
|
|
539
|
-
const moreActionsLabel = ( localize(
|
|
601
|
+
card.main.setAttribute("aria-label", ( localize(5978, "Edit automation {0}", automation.name)));
|
|
602
|
+
card.actions.setAttribute("aria-label", ( localize(5979, "Actions for {0}", automation.name)));
|
|
603
|
+
const moreActionsLabel = ( localize(5980, "More Actions for {0}", automation.name));
|
|
540
604
|
card.moreActionsButton.setAriaLabel(moreActionsLabel);
|
|
541
|
-
card.moreActionsButton.setTitle(moreActionsLabel);
|
|
542
605
|
card.nameText.textContent = automation.name;
|
|
543
606
|
}
|
|
544
|
-
if (
|
|
545
|
-
card.
|
|
607
|
+
if (enabledChanged) {
|
|
608
|
+
card.card.classList.toggle("automation-disabled", !automation.enabled);
|
|
546
609
|
}
|
|
547
610
|
if (scheduleChanged) {
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
611
|
+
const icon = !automation.enabled ? Codicon.circleSlash : automation.schedule.interval === "manual" ? Codicon.person : Codicon.clockface;
|
|
612
|
+
reset(card.scheduleEl, $("span" + ThemeIcon.asCSSSelector(icon), {
|
|
613
|
+
"aria-hidden": "true"
|
|
614
|
+
}), $("span.automations-card-meta-label", undefined, schedule));
|
|
615
|
+
}
|
|
616
|
+
const folderLabel = automation.targetDisplay?.label ?? getAutomationTargetLabel(automation.target);
|
|
617
|
+
if (!previous || enabledChanged || previous.targetDisplay !== automation.targetDisplay || getAutomationTargetLabel(previous.target) !== folderLabel) {
|
|
618
|
+
const showFolder = (automation.enabled || !!automation.targetDisplay) && automation.target.kind === "workspace";
|
|
619
|
+
card.folderEl.style.display = showFolder ? "" : "none";
|
|
620
|
+
reset(card.folderEl, $(
|
|
621
|
+
"span" + ThemeIcon.asCSSSelector(automation.targetDisplay?.icon ?? Codicon.folder),
|
|
622
|
+
{
|
|
623
|
+
"aria-hidden": "true"
|
|
624
|
+
}
|
|
625
|
+
), $("span.automations-card-meta-label", undefined, folderLabel));
|
|
626
|
+
card.folderEl.setAttribute("aria-label", folderLabel);
|
|
627
|
+
card.folderHover.value = showFolder ? this.hoverService.setupManagedHover(getDefaultHoverDelegate("element"), card.folderEl, folderLabel) : undefined;
|
|
554
628
|
}
|
|
555
629
|
if (!previous || previous.prompt !== automation.prompt) {
|
|
556
|
-
|
|
557
|
-
card.promptEl.textContent = automation.prompt.length > maxLength ? automation.prompt.slice(0, maxLength) + "…" : automation.prompt;
|
|
630
|
+
card.promptEl.textContent = automation.prompt;
|
|
558
631
|
}
|
|
559
632
|
}
|
|
560
633
|
createIconButton(buttonBar, icon, tooltip, disabled) {
|
|
@@ -573,39 +646,43 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
573
646
|
return;
|
|
574
647
|
}
|
|
575
648
|
try {
|
|
576
|
-
const operation = this.automationRunner.runOnce(automation,
|
|
649
|
+
const operation = this.automationRunner.runOnce(automation, CancellationToken.None);
|
|
577
650
|
const dispatch = await operation.whenDispatched;
|
|
578
651
|
switch (dispatch.kind) {
|
|
652
|
+
case "accepted":
|
|
653
|
+
status(( localize(
|
|
654
|
+
5981,
|
|
655
|
+
"Run requested for {0}. Its history will update when available.",
|
|
656
|
+
automation.name
|
|
657
|
+
)));
|
|
658
|
+
break;
|
|
579
659
|
case "started":
|
|
580
|
-
status(( localize(
|
|
660
|
+
status(( localize(5982, "Started automation {0}", automation.name)));
|
|
581
661
|
break;
|
|
582
662
|
case "alreadyRunning":
|
|
583
|
-
status(( localize(
|
|
663
|
+
status(( localize(5983, "Automation {0} is already running", automation.name)));
|
|
584
664
|
break;
|
|
585
665
|
case "notStarted":
|
|
586
|
-
status(( localize(
|
|
666
|
+
status(( localize(5984, "Automation {0} did not start", automation.name)));
|
|
587
667
|
break;
|
|
588
668
|
}
|
|
589
669
|
await operation.whenCompleted;
|
|
590
670
|
} catch (error) {
|
|
591
671
|
this.logService.error("[AutomationsCards] Failed to run automation", error);
|
|
592
|
-
await this.dialogService.error(( localize(
|
|
672
|
+
await this.dialogService.error(( localize(5985, "Failed to run automation.")), getErrorMessage(error));
|
|
593
673
|
}
|
|
594
674
|
}
|
|
595
675
|
renderEmptyState() {
|
|
596
676
|
const title = append(this.emptyContainer, $("h3.automations-cards-empty-title"));
|
|
597
|
-
title.textContent = ( localize(
|
|
677
|
+
title.textContent = ( localize(5986, "No automations yet"));
|
|
598
678
|
const desc = append(this.emptyContainer, $("p.automations-cards-empty-description"));
|
|
599
|
-
desc.textContent = ( localize(
|
|
600
|
-
4796,
|
|
601
|
-
"Create an automation to schedule an agent session to run on a cadence you choose."
|
|
602
|
-
));
|
|
679
|
+
desc.textContent = ( localize(5987, "Describe what you want to automate, then choose when it runs."));
|
|
603
680
|
const createButton = this.emptyStateDisposables.add(( new Button(this.emptyContainer, {
|
|
604
681
|
...defaultButtonStyles,
|
|
605
|
-
title: ( localize(
|
|
682
|
+
title: ( localize(5988, "Create Automation"))
|
|
606
683
|
})));
|
|
607
684
|
this.emptyCreateButton = createButton;
|
|
608
|
-
createButton.label = ( localize(
|
|
685
|
+
createButton.label = ( localize(5988, "Create Automation"));
|
|
609
686
|
createButton.element.classList.add("automations-cards-create-button");
|
|
610
687
|
this.emptyStateDisposables.add(createButton.onDidClick(() => this.openCreateDialog()));
|
|
611
688
|
}
|
|
@@ -620,9 +697,9 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
620
697
|
this.pluginTemplatesUnreadIndicator = undefined;
|
|
621
698
|
this.builtInTemplatesSection = this.renderTemplateSection({
|
|
622
699
|
className: "automations-built-in-templates",
|
|
623
|
-
title: ( localize(
|
|
700
|
+
title: ( localize(5989, "Built-in Templates")),
|
|
624
701
|
description: ( localize(
|
|
625
|
-
|
|
702
|
+
5990,
|
|
626
703
|
"Choose a starting point, then review and customize it before creating."
|
|
627
704
|
)),
|
|
628
705
|
templates: builtInTemplates,
|
|
@@ -637,8 +714,8 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
637
714
|
if (pluginTemplates.length > 0) {
|
|
638
715
|
const rendered = this.renderTemplateSection({
|
|
639
716
|
className: "automations-plugin-templates",
|
|
640
|
-
title: ( localize(
|
|
641
|
-
description: ( localize(
|
|
717
|
+
title: ( localize(5991, "Templates from Plugins")),
|
|
718
|
+
description: ( localize(5992, "Templates provided by enabled plugins start disabled.")),
|
|
642
719
|
templates: pluginTemplates,
|
|
643
720
|
expanded: this.pluginTemplatesExpanded ?? false,
|
|
644
721
|
showUnreadIndicator: true,
|
|
@@ -701,7 +778,7 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
701
778
|
if (unreadCount === 0) {
|
|
702
779
|
this.pluginTemplatesSummary.removeAttribute("aria-label");
|
|
703
780
|
} else {
|
|
704
|
-
this.pluginTemplatesSummary.setAttribute("aria-label", unreadCount === 1 ? ( localize(
|
|
781
|
+
this.pluginTemplatesSummary.setAttribute("aria-label", unreadCount === 1 ? ( localize(5993, "Templates from Plugins, 1 new template")) : ( localize(5994, "Templates from Plugins, {0} new templates", unreadCount)));
|
|
705
782
|
}
|
|
706
783
|
}
|
|
707
784
|
markCurrentPluginTemplatesSeen() {
|
|
@@ -739,9 +816,9 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
739
816
|
icon.classList.add(...ThemeIcon.asClassNameArray(Codicon.loading), "codicon-modifier-spin");
|
|
740
817
|
icon.setAttribute("aria-hidden", "true");
|
|
741
818
|
const title = append(this.loadingContainer, $("h3.automations-cards-state-title"));
|
|
742
|
-
title.textContent = ( localize(
|
|
819
|
+
title.textContent = ( localize(5995, "Loading automations..."));
|
|
743
820
|
const description = append(this.loadingContainer, $("p.automations-cards-state-description"));
|
|
744
|
-
description.textContent = ( localize(
|
|
821
|
+
description.textContent = ( localize(5996, "You can create a new automation while existing automations load."));
|
|
745
822
|
return this.renderStateCreateButton(this.loadingContainer);
|
|
746
823
|
}
|
|
747
824
|
renderUnavailableState() {
|
|
@@ -749,13 +826,16 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
749
826
|
icon.classList.add(...ThemeIcon.asClassNameArray(Codicon.debugDisconnect));
|
|
750
827
|
icon.setAttribute("aria-hidden", "true");
|
|
751
828
|
const title = append(this.unavailableContainer, $("h3.automations-cards-state-title"));
|
|
752
|
-
title.textContent = ( localize(
|
|
753
|
-
const description = append(this.unavailableContainer, $("
|
|
829
|
+
title.textContent = ( localize(5997, "Some automations are unavailable"));
|
|
830
|
+
const description = append(this.unavailableContainer, $("div.automations-cards-state-description"));
|
|
754
831
|
description.textContent = ( localize(
|
|
755
|
-
|
|
832
|
+
5972,
|
|
756
833
|
"One or more providers are disconnected, disabled, or do not support automations."
|
|
757
834
|
));
|
|
758
|
-
return
|
|
835
|
+
return {
|
|
836
|
+
createButton: this.renderStateCreateButton(this.unavailableContainer),
|
|
837
|
+
description
|
|
838
|
+
};
|
|
759
839
|
}
|
|
760
840
|
renderErrorState() {
|
|
761
841
|
this.errorContainer.setAttribute("role", "alert");
|
|
@@ -763,37 +843,56 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
763
843
|
icon.classList.add(...ThemeIcon.asClassNameArray(Codicon.error));
|
|
764
844
|
icon.setAttribute("aria-hidden", "true");
|
|
765
845
|
const title = append(this.errorContainer, $("h3.automations-cards-state-title"));
|
|
766
|
-
title.textContent = ( localize(
|
|
846
|
+
title.textContent = ( localize(5998, "Unable to load automations"));
|
|
767
847
|
const description = append(this.errorContainer, $("p.automations-cards-state-description"));
|
|
768
|
-
description.textContent = ( localize(
|
|
848
|
+
description.textContent = ( localize(5999, "The complete automation catalogue could not be read."));
|
|
769
849
|
return this.renderStateCreateButton(this.errorContainer);
|
|
770
850
|
}
|
|
771
851
|
renderStateCreateButton(container) {
|
|
772
852
|
const createButton = this.stateDisposables.add(( new Button(container, {
|
|
773
853
|
...defaultButtonStyles,
|
|
774
|
-
title: ( localize(
|
|
854
|
+
title: ( localize(5988, "Create Automation"))
|
|
775
855
|
})));
|
|
776
|
-
createButton.label = ( localize(
|
|
856
|
+
createButton.label = ( localize(5988, "Create Automation"));
|
|
777
857
|
createButton.element.classList.add("automations-cards-state-create-button");
|
|
778
858
|
this.stateDisposables.add(createButton.onDidClick(() => this.openCreateDialog()));
|
|
779
859
|
return createButton;
|
|
780
860
|
}
|
|
781
|
-
renderPartialState(catalogueState) {
|
|
782
|
-
|
|
861
|
+
renderPartialState(catalogueState, unavailableProviders) {
|
|
862
|
+
const unavailableProvidersChanged = catalogueState === "unavailable" && (unavailableProviders.length !== this.partialUnavailableProviders.length || ( unavailableProviders.some(
|
|
863
|
+
(provider, index) => provider.id !== this.partialUnavailableProviders[index].id || provider.label !== this.partialUnavailableProviders[index].label || provider.unavailableReasonCode !== this.partialUnavailableProviders[index].unavailableReasonCode || provider.unavailableReason !== this.partialUnavailableProviders[index].unavailableReason
|
|
864
|
+
)));
|
|
865
|
+
if (this.partialState === catalogueState && !unavailableProvidersChanged) {
|
|
783
866
|
return;
|
|
784
867
|
}
|
|
785
868
|
this.partialState = catalogueState;
|
|
786
|
-
|
|
869
|
+
this.partialUnavailableProviders = catalogueState === "unavailable" ? [...unavailableProviders] : [];
|
|
870
|
+
if (catalogueState === "ready" || catalogueState === "loading") {
|
|
787
871
|
this.partialStateContainer.style.display = "none";
|
|
788
872
|
return;
|
|
789
873
|
}
|
|
790
874
|
const isError = catalogueState === "error";
|
|
791
|
-
const isLoading = catalogueState === "loading";
|
|
792
875
|
this.partialStateContainer.style.display = "";
|
|
793
876
|
this.partialStateContainer.classList.toggle("automations-cards-partial-state-error", isError);
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
877
|
+
if (catalogueState === "unavailable") {
|
|
878
|
+
this.renderUnavailableMessage(this.partialStateMessage, unavailableProviders);
|
|
879
|
+
} else {
|
|
880
|
+
this.partialStateMessage.textContent = ( localize(6000, "Some automations could not be loaded."));
|
|
881
|
+
}
|
|
882
|
+
}
|
|
883
|
+
renderUnavailableMessage(container, unavailableProviders) {
|
|
884
|
+
const reasons = getUnavailableAutomationsReasons(unavailableProviders);
|
|
885
|
+
if (reasons.length === 1) {
|
|
886
|
+
container.textContent = reasons[0];
|
|
887
|
+
} else if (reasons.length > 1) {
|
|
888
|
+
reset(container, $(
|
|
889
|
+
"ul.automations-unavailable-reasons",
|
|
890
|
+
undefined,
|
|
891
|
+
...reasons.map(reason => $("li", undefined, reason))
|
|
892
|
+
));
|
|
893
|
+
} else {
|
|
894
|
+
container.textContent = ( localize(6001, "Some automations are unavailable."));
|
|
895
|
+
}
|
|
797
896
|
}
|
|
798
897
|
renderTemplateCard(container, template) {
|
|
799
898
|
const card = append(container, $("button.automations-template-card", {
|
|
@@ -801,12 +900,12 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
801
900
|
}));
|
|
802
901
|
const schedule = formatSchedule(template.schedule);
|
|
803
902
|
card.setAttribute("aria-label", template.source ? ( localize(
|
|
804
|
-
|
|
903
|
+
6002,
|
|
805
904
|
"Use template: {0}, {1}, from {2}",
|
|
806
905
|
template.name,
|
|
807
906
|
schedule,
|
|
808
907
|
template.source.label
|
|
809
|
-
)) : ( localize(
|
|
908
|
+
)) : ( localize(6003, "Use template: {0}, {1}", template.name, schedule)));
|
|
810
909
|
const nameRow = append(card, $(".automations-template-card-name"));
|
|
811
910
|
const name = append(nameRow, $("span.automations-template-card-name-text"));
|
|
812
911
|
name.textContent = template.name;
|
|
@@ -814,17 +913,15 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
814
913
|
content: template.name
|
|
815
914
|
}));
|
|
816
915
|
const badge = append(nameRow, $("span.automations-template-card-badge"));
|
|
817
|
-
badge.textContent = template.source ? ( localize(
|
|
916
|
+
badge.textContent = template.source ? ( localize(6004, "Plugin")) : ( localize(6005, "Template"));
|
|
818
917
|
badge.setAttribute("aria-hidden", "true");
|
|
819
918
|
if (template.source) {
|
|
820
919
|
const source = append(card, $("span.automations-template-card-source"));
|
|
821
|
-
source.textContent = ( localize(
|
|
920
|
+
source.textContent = ( localize(6006, "From {0}", template.source.label));
|
|
822
921
|
this.templateDisposables.add(this.hoverService.setupDelayedHover(source, {
|
|
823
922
|
content: template.source.label
|
|
824
923
|
}));
|
|
825
924
|
}
|
|
826
|
-
const scheduleElement = append(card, $("span.automations-template-card-schedule"));
|
|
827
|
-
scheduleElement.textContent = schedule;
|
|
828
925
|
const description = append(card, $("span.automations-template-card-prompt"));
|
|
829
926
|
description.id = `automations-template-${this.templateAriaId}-${template.id}-description`;
|
|
830
927
|
description.textContent = template.description;
|
|
@@ -832,6 +929,8 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
832
929
|
content: template.prompt
|
|
833
930
|
}));
|
|
834
931
|
card.setAttribute("aria-describedby", description.id);
|
|
932
|
+
const scheduleElement = append(card, $("span.automations-template-card-schedule"));
|
|
933
|
+
scheduleElement.textContent = schedule;
|
|
835
934
|
this.templateDisposables.add(addDisposableListener(card, EventType.CLICK, () => {
|
|
836
935
|
void this.openCreateDialog({
|
|
837
936
|
name: template.name,
|
|
@@ -849,26 +948,43 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
849
948
|
return;
|
|
850
949
|
}
|
|
851
950
|
try {
|
|
852
|
-
|
|
853
|
-
|
|
854
|
-
|
|
855
|
-
|
|
856
|
-
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
860
|
-
|
|
951
|
+
let created;
|
|
952
|
+
let restoreFocus = false;
|
|
953
|
+
let focusRequestGeneration = this.focusRequestGeneration;
|
|
954
|
+
const result = await this.automationDialogService.showAutomationDialog({
|
|
955
|
+
...(initialValues ? {
|
|
956
|
+
initialValues
|
|
957
|
+
} : {}),
|
|
958
|
+
commit: async result => {
|
|
959
|
+
if (result.kind === "create") {
|
|
960
|
+
if (this._store.isDisposed) {
|
|
961
|
+
throw ( new Error(( localize(
|
|
962
|
+
6007,
|
|
963
|
+
"The automations view was closed before the automation could be saved."
|
|
964
|
+
))));
|
|
965
|
+
}
|
|
966
|
+
this.throwIfDisabled();
|
|
967
|
+
restoreFocus = isAncestorOfActiveElement(this.focusRoot) || !!this.focusRoot.closest(".automation-dialog-open");
|
|
968
|
+
focusRequestGeneration = this.focusRequestGeneration;
|
|
969
|
+
created = await withAutomationDialogPersistenceTelemetry(
|
|
970
|
+
this.telemetryService,
|
|
971
|
+
"create",
|
|
972
|
+
() => this.automationService.createAutomation(result.value, () => this.throwIfDisabled())
|
|
973
|
+
);
|
|
974
|
+
}
|
|
975
|
+
}
|
|
976
|
+
});
|
|
977
|
+
if (!result || !created || this._store.isDisposed) {
|
|
861
978
|
return;
|
|
862
979
|
}
|
|
863
|
-
const created = await this.automationService.createAutomation(result.value, () => this.throwIfDisabled());
|
|
864
980
|
if (restoreFocus && focusRequestGeneration === this.focusRequestGeneration && !this._store.isDisposed && isAncestorOfActiveElement(this.focusRoot)) {
|
|
865
981
|
this.pendingFocusAutomationId = created.id;
|
|
866
982
|
this.focusPendingAutomation();
|
|
867
983
|
}
|
|
868
|
-
status(( localize(
|
|
984
|
+
status(( localize(6008, "Created automation {0}", created.name)));
|
|
869
985
|
} catch (err) {
|
|
870
986
|
this.logService.error("[AutomationsCards] Failed to create automation", err);
|
|
871
|
-
await this.dialogService.error(( localize(
|
|
987
|
+
await this.dialogService.error(( localize(6009, "Failed to create automation.")), getErrorMessage(err));
|
|
872
988
|
}
|
|
873
989
|
}
|
|
874
990
|
clearPendingFocus() {
|
|
@@ -916,25 +1032,32 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
916
1032
|
}
|
|
917
1033
|
try {
|
|
918
1034
|
const result = await this.automationDialogService.showAutomationDialog({
|
|
919
|
-
existing: automation
|
|
1035
|
+
existing: automation,
|
|
1036
|
+
commit: async result => {
|
|
1037
|
+
if (result.kind !== "update") {
|
|
1038
|
+
return;
|
|
1039
|
+
}
|
|
1040
|
+
this.throwIfDisabled();
|
|
1041
|
+
const updateResult = await withAutomationDialogPersistenceTelemetry(
|
|
1042
|
+
this.telemetryService,
|
|
1043
|
+
"update",
|
|
1044
|
+
() => this.automationService.updateAutomationIfUnchanged(result.id, result.value, automation, () => this.throwIfDisabled())
|
|
1045
|
+
);
|
|
1046
|
+
if (updateResult.kind === "conflict") {
|
|
1047
|
+
throw ( new Error(updateResult.current ? ( localize(
|
|
1048
|
+
6010,
|
|
1049
|
+
"This automation changed while the dialog was open. Reopen it to review the latest values."
|
|
1050
|
+
)) : ( localize(6011, "This automation was deleted while the dialog was open."))));
|
|
1051
|
+
}
|
|
1052
|
+
}
|
|
920
1053
|
});
|
|
921
1054
|
if (!result || result.kind !== "update") {
|
|
922
1055
|
return;
|
|
923
1056
|
}
|
|
924
|
-
|
|
925
|
-
return;
|
|
926
|
-
}
|
|
927
|
-
const updateResult = await this.automationService.updateAutomationIfUnchanged(result.id, result.value, automation, () => this.throwIfDisabled());
|
|
928
|
-
if (updateResult.kind === "conflict") {
|
|
929
|
-
throw ( new Error(updateResult.current ? ( localize(
|
|
930
|
-
4820,
|
|
931
|
-
"This automation changed while the dialog was open. Reopen it to review the latest values."
|
|
932
|
-
)) : ( localize(4821, "This automation was deleted while the dialog was open."))));
|
|
933
|
-
}
|
|
934
|
-
status(( localize(4822, "Updated automation {0}", automation.name)));
|
|
1057
|
+
status(( localize(6012, "Updated automation {0}", automation.name)));
|
|
935
1058
|
} catch (err) {
|
|
936
1059
|
this.logService.error("[AutomationsCards] Failed to update automation", err);
|
|
937
|
-
await this.dialogService.error(( localize(
|
|
1060
|
+
await this.dialogService.error(( localize(6013, "Failed to update automation.")), getErrorMessage(err));
|
|
938
1061
|
}
|
|
939
1062
|
}
|
|
940
1063
|
isEnabled() {
|
|
@@ -949,11 +1072,11 @@ let AutomationCardsSection = class AutomationCardsSection extends Disposable {
|
|
|
949
1072
|
}
|
|
950
1073
|
throwIfDisabled() {
|
|
951
1074
|
if (!this.isEnabled()) {
|
|
952
|
-
throw ( new Error(( localize(
|
|
1075
|
+
throw ( new Error(( localize(6014, "Automations were disabled before the change could be saved."))));
|
|
953
1076
|
}
|
|
954
1077
|
}
|
|
955
1078
|
};
|
|
956
|
-
AutomationCardsSection = ( __decorate([( __param(2, IAutomationService)), ( __param(3, IAutomationRunner)), ( __param(4, IAutomationDialogService)), ( __param(5, IHoverService)), ( __param(6, ILogService)), ( __param(7, IDialogService)), ( __param(8, IFileService)), ( __param(9, IStorageService)), ( __param(10, IConfigurationService)), ( __param(11, IContextKeyService)), ( __param(12, IContextMenuService))], AutomationCardsSection));
|
|
1079
|
+
AutomationCardsSection = ( __decorate([( __param(2, IAutomationService)), ( __param(3, IAutomationRunner)), ( __param(4, IAutomationDialogService)), ( __param(5, IHoverService)), ( __param(6, ILogService)), ( __param(7, IDialogService)), ( __param(8, IFileService)), ( __param(9, IStorageService)), ( __param(10, IConfigurationService)), ( __param(11, IContextKeyService)), ( __param(12, IContextMenuService)), ( __param(13, ITelemetryService))], AutomationCardsSection));
|
|
957
1080
|
let AutomationHistorySection = class AutomationHistorySection extends Disposable {
|
|
958
1081
|
dispose() {
|
|
959
1082
|
this.disposeAllGroups();
|
|
@@ -968,7 +1091,9 @@ let AutomationHistorySection = class AutomationHistorySection extends Disposable
|
|
|
968
1091
|
sessionsManagementService,
|
|
969
1092
|
logService,
|
|
970
1093
|
dialogService,
|
|
971
|
-
instantiationService
|
|
1094
|
+
instantiationService,
|
|
1095
|
+
openerService,
|
|
1096
|
+
hoverService
|
|
972
1097
|
) {
|
|
973
1098
|
super();
|
|
974
1099
|
this.focusFallback = focusFallback;
|
|
@@ -979,6 +1104,8 @@ let AutomationHistorySection = class AutomationHistorySection extends Disposable
|
|
|
979
1104
|
this.logService = logService;
|
|
980
1105
|
this.dialogService = dialogService;
|
|
981
1106
|
this.instantiationService = instantiationService;
|
|
1107
|
+
this.openerService = openerService;
|
|
1108
|
+
this.hoverService = hoverService;
|
|
982
1109
|
this.headerDisposables = this._register(( new DisposableStore()));
|
|
983
1110
|
this.persistentGroups = ( new Map());
|
|
984
1111
|
this.runFocusTargets = ( new Map());
|
|
@@ -992,14 +1119,22 @@ let AutomationHistorySection = class AutomationHistorySection extends Disposable
|
|
|
992
1119
|
}
|
|
993
1120
|
render(runs, sessions) {
|
|
994
1121
|
const sessionRuns = runs.filter(run => ( sessions.has(run.id)));
|
|
995
|
-
const visibleRuns = runs.filter(run => ( sessions.has(run.id)) || isTemporaryAutomationRun(run) || (!!run.sessionResource && !!this.sessionsManagementService.getSession(run.sessionResource)));
|
|
1122
|
+
const visibleRuns = runs.filter(run => ( sessions.has(run.id)) || !!run.externalResource || isTemporaryAutomationRun(run) || (!!run.sessionResource && !!this.sessionsManagementService.getSession(run.sessionResource)));
|
|
996
1123
|
transaction(tx => {
|
|
997
1124
|
this.currentRuns.set(sessionRuns, tx);
|
|
998
1125
|
this.currentSessions.set(sessions, tx);
|
|
999
1126
|
});
|
|
1127
|
+
const activeElement = getActiveElement();
|
|
1128
|
+
const historyOwnedFocus = isHTMLElement(activeElement) && this.groupsContainer.contains(activeElement);
|
|
1129
|
+
const focusedRunId = historyOwnedFocus ? [...this.runFocusTargets].find(
|
|
1130
|
+
([, target]) => target.container.contains(activeElement) && target.list.getFocusedSession() === target.session
|
|
1131
|
+
)?.[0] : undefined;
|
|
1000
1132
|
this.runFocusTargets.clear();
|
|
1001
1133
|
this.renderedFocusableRunIds = [];
|
|
1002
1134
|
if (visibleRuns.length === 0) {
|
|
1135
|
+
if (historyOwnedFocus) {
|
|
1136
|
+
this.focusFallback.focus();
|
|
1137
|
+
}
|
|
1003
1138
|
this.container.style.display = "none";
|
|
1004
1139
|
this.disposeAllGroups();
|
|
1005
1140
|
this.restoreFocusAfterRender();
|
|
@@ -1018,43 +1153,40 @@ let AutomationHistorySection = class AutomationHistorySection extends Disposable
|
|
|
1018
1153
|
}
|
|
1019
1154
|
let index = 0;
|
|
1020
1155
|
for (const group of groups) {
|
|
1021
|
-
const sessionItems = this.resolveSessionItems(group.runs, sessions);
|
|
1022
|
-
const temporaryRuns = group.runs.filter(run => !( sessions.has(run.id)));
|
|
1023
1156
|
let entry = this.persistentGroups.get(group.key);
|
|
1024
1157
|
if (entry) {
|
|
1025
1158
|
if (entry.header.textContent !== group.label) {
|
|
1026
1159
|
entry.header.textContent = group.label;
|
|
1027
1160
|
}
|
|
1028
|
-
this.updateTemporaryRuns(entry, temporaryRuns);
|
|
1029
|
-
this.updateGroupSessions(entry, sessionItems);
|
|
1030
1161
|
} else {
|
|
1031
|
-
entry = this.createGroup(group.key, group.label
|
|
1162
|
+
entry = this.createGroup(group.key, group.label);
|
|
1032
1163
|
}
|
|
1164
|
+
this.updateGroupRuns(entry, group.runs, sessions);
|
|
1033
1165
|
const currentElement = this.groupsContainer.children.item(index);
|
|
1034
1166
|
if (currentElement !== entry.element) {
|
|
1035
1167
|
this.groupsContainer.insertBefore(entry.element, currentElement);
|
|
1036
|
-
|
|
1037
|
-
this.layoutSessionList(
|
|
1168
|
+
for (const block of ( entry.sessionLists.values())) {
|
|
1169
|
+
this.layoutSessionList(block.listContainer, block.list);
|
|
1038
1170
|
}
|
|
1039
1171
|
}
|
|
1040
1172
|
index++;
|
|
1041
|
-
for (const item of sessionItems) {
|
|
1042
|
-
if (!entry.list) {
|
|
1043
|
-
continue;
|
|
1044
|
-
}
|
|
1045
|
-
this.renderedFocusableRunIds.push(item.run.id);
|
|
1046
|
-
this.runFocusTargets.set(item.run.id, {
|
|
1047
|
-
list: entry.list,
|
|
1048
|
-
session: item.session
|
|
1049
|
-
});
|
|
1050
|
-
}
|
|
1051
1173
|
}
|
|
1052
1174
|
this.restoreFocusAfterRender();
|
|
1175
|
+
if (historyOwnedFocus && isHTMLElement(activeElement) && !this.groupsContainer.contains(getActiveElement())) {
|
|
1176
|
+
const target = focusedRunId ? this.runFocusTargets.get(focusedRunId) : undefined;
|
|
1177
|
+
if (activeElement.isConnected) {
|
|
1178
|
+
activeElement.focus();
|
|
1179
|
+
} else if (target) {
|
|
1180
|
+
target.list.focusSession(target.session);
|
|
1181
|
+
} else {
|
|
1182
|
+
this.focusFallback.focus();
|
|
1183
|
+
}
|
|
1184
|
+
}
|
|
1053
1185
|
}
|
|
1054
1186
|
layout() {
|
|
1055
1187
|
for (const entry of ( this.persistentGroups.values())) {
|
|
1056
|
-
|
|
1057
|
-
this.layoutSessionList(
|
|
1188
|
+
for (const block of ( entry.sessionLists.values())) {
|
|
1189
|
+
this.layoutSessionList(block.listContainer, block.list);
|
|
1058
1190
|
}
|
|
1059
1191
|
}
|
|
1060
1192
|
}
|
|
@@ -1066,13 +1198,13 @@ let AutomationHistorySection = class AutomationHistorySection extends Disposable
|
|
|
1066
1198
|
this.headerRow = $$1(".automations-history-header");
|
|
1067
1199
|
this.container.insertBefore(this.headerRow, this.groupsContainer);
|
|
1068
1200
|
const headerLabel = append(this.headerRow, $("span"));
|
|
1069
|
-
headerLabel.textContent = ( localize(
|
|
1201
|
+
headerLabel.textContent = ( localize(6015, "History"));
|
|
1070
1202
|
this.markAllButton = this.headerDisposables.add(( new Button(this.headerRow, {
|
|
1071
1203
|
...defaultButtonStyles,
|
|
1072
1204
|
secondary: true,
|
|
1073
|
-
title: ( localize(
|
|
1205
|
+
title: ( localize(6016, "Mark all as read"))
|
|
1074
1206
|
})));
|
|
1075
|
-
this.markAllButton.label = ( localize(
|
|
1207
|
+
this.markAllButton.label = ( localize(6016, "Mark all as read"));
|
|
1076
1208
|
this.markAllButton.element.classList.add("automations-mark-all-read");
|
|
1077
1209
|
this.headerDisposables.add(this.markAllButton.onDidClick(() => {
|
|
1078
1210
|
void this.markAllRunsRead(this.currentRuns.get());
|
|
@@ -1086,101 +1218,125 @@ let AutomationHistorySection = class AutomationHistorySection extends Disposable
|
|
|
1086
1218
|
this.markAllButton.enabled = hasUnread && !isMarkingAllRead;
|
|
1087
1219
|
}));
|
|
1088
1220
|
}
|
|
1089
|
-
|
|
1090
|
-
const items = [];
|
|
1091
|
-
for (const run of runs) {
|
|
1092
|
-
const session = sessions.get(run.id);
|
|
1093
|
-
if (session) {
|
|
1094
|
-
items.push({
|
|
1095
|
-
run,
|
|
1096
|
-
session
|
|
1097
|
-
});
|
|
1098
|
-
}
|
|
1099
|
-
}
|
|
1100
|
-
return items;
|
|
1101
|
-
}
|
|
1102
|
-
createGroup(key, label, temporaryRuns, items) {
|
|
1221
|
+
createGroup(key, label) {
|
|
1103
1222
|
const disposables = ( new DisposableStore());
|
|
1104
1223
|
const element = $(".automations-history-group");
|
|
1105
1224
|
const header = append(element, $(".automations-history-group-header"));
|
|
1106
1225
|
header.textContent = label;
|
|
1107
1226
|
const runsContainer = append(element, $(".automations-history-group-runs"));
|
|
1108
|
-
const temporaryRowsContainer = append(runsContainer, $(".automations-temporary-runs"));
|
|
1109
|
-
const listContainer = append(runsContainer, $(".automations-run-session-list"));
|
|
1110
|
-
const runsBySession = ( new Map());
|
|
1111
1227
|
const entry = {
|
|
1112
1228
|
element,
|
|
1113
1229
|
header,
|
|
1114
|
-
|
|
1230
|
+
runsContainer,
|
|
1115
1231
|
temporaryRows: disposables.add(( new DisposableMap())),
|
|
1116
|
-
|
|
1117
|
-
listDisposables: disposables.add(( new MutableDisposable())),
|
|
1118
|
-
list: undefined,
|
|
1119
|
-
runsBySession,
|
|
1120
|
-
sessions: [],
|
|
1232
|
+
sessionLists: disposables.add(( new DisposableMap())),
|
|
1121
1233
|
disposables
|
|
1122
1234
|
};
|
|
1123
1235
|
this.persistentGroups.set(key, entry);
|
|
1124
|
-
this.updateTemporaryRuns(entry, temporaryRuns);
|
|
1125
|
-
this.updateGroupSessions(entry, items);
|
|
1126
1236
|
return entry;
|
|
1127
1237
|
}
|
|
1128
|
-
|
|
1129
|
-
if (entry.list) {
|
|
1130
|
-
return entry.list;
|
|
1131
|
-
}
|
|
1238
|
+
createSessionList(container) {
|
|
1132
1239
|
const disposables = ( new DisposableStore());
|
|
1240
|
+
const listContainer = append(container, $(".automations-run-session-list"));
|
|
1241
|
+
const runsBySession = ( new Map());
|
|
1133
1242
|
const list = disposables.add(
|
|
1134
|
-
this.instantiationService.createInstance(SessionsFlatList,
|
|
1243
|
+
this.instantiationService.createInstance(SessionsFlatList, listContainer, {
|
|
1135
1244
|
showSessionHover: false,
|
|
1136
1245
|
alwaysConsumeMouseWheel: false,
|
|
1137
1246
|
useCompactQuickChatRows: false,
|
|
1138
1247
|
toolbarMenuId: Menus.AutomationsHistoryItem,
|
|
1248
|
+
toolbarTelemetrySource: "automationsView.historyRow",
|
|
1139
1249
|
contextMenuId: Menus.AutomationsHistoryItemContext,
|
|
1140
1250
|
markSessionReadOnOpen: false,
|
|
1141
1251
|
approvalModel: this.approvalModel,
|
|
1142
1252
|
onSessionOpen: resource => void this.openRunSession(resource),
|
|
1143
|
-
onToolbarAction: (action, session) => this.handleSessionAction(action, session,
|
|
1144
|
-
onContextMenuAction: (action, session) => this.handleSessionAction(action, session,
|
|
1253
|
+
onToolbarAction: (action, session) => this.handleSessionAction(action, session, runsBySession),
|
|
1254
|
+
onContextMenuAction: (action, session) => this.handleSessionAction(action, session, runsBySession)
|
|
1145
1255
|
})
|
|
1146
1256
|
);
|
|
1147
1257
|
disposables.add(
|
|
1148
|
-
list.onDidChangeContentHeight(() => this.layoutSessionList(
|
|
1258
|
+
list.onDidChangeContentHeight(() => this.layoutSessionList(listContainer, list))
|
|
1149
1259
|
);
|
|
1150
|
-
|
|
1151
|
-
|
|
1152
|
-
|
|
1260
|
+
return {
|
|
1261
|
+
listContainer,
|
|
1262
|
+
list,
|
|
1263
|
+
runsBySession,
|
|
1264
|
+
sessions: [],
|
|
1265
|
+
dispose: () => {
|
|
1266
|
+
disposables.dispose();
|
|
1267
|
+
listContainer.remove();
|
|
1268
|
+
}
|
|
1269
|
+
};
|
|
1153
1270
|
}
|
|
1154
|
-
|
|
1155
|
-
const activeRunIds = ( new Set(runs.map(run => run.id)));
|
|
1271
|
+
updateGroupRuns(entry, runs, sessions) {
|
|
1272
|
+
const activeRunIds = ( new Set(runs.filter(run => !( sessions.has(run.id))).map(run => run.id)));
|
|
1156
1273
|
for (const runId of ( entry.temporaryRows.keys())) {
|
|
1157
1274
|
if (!( activeRunIds.has(runId))) {
|
|
1158
1275
|
entry.temporaryRows.deleteAndDispose(runId);
|
|
1159
1276
|
}
|
|
1160
1277
|
}
|
|
1161
|
-
|
|
1162
|
-
|
|
1163
|
-
|
|
1164
|
-
|
|
1165
|
-
|
|
1166
|
-
|
|
1167
|
-
|
|
1168
|
-
|
|
1169
|
-
|
|
1170
|
-
|
|
1278
|
+
const activeLists = ( new Set());
|
|
1279
|
+
let listKey = "";
|
|
1280
|
+
let childIndex = 0;
|
|
1281
|
+
for (let index = 0; index < runs.length; ) {
|
|
1282
|
+
const run = runs[index];
|
|
1283
|
+
let element;
|
|
1284
|
+
if (( sessions.has(run.id))) {
|
|
1285
|
+
const items = [];
|
|
1286
|
+
while (index < runs.length) {
|
|
1287
|
+
const session = sessions.get(runs[index].id);
|
|
1288
|
+
if (!session) {
|
|
1289
|
+
break;
|
|
1290
|
+
}
|
|
1291
|
+
items.push({
|
|
1292
|
+
run: runs[index++],
|
|
1293
|
+
session
|
|
1294
|
+
});
|
|
1295
|
+
}
|
|
1296
|
+
activeLists.add(listKey);
|
|
1297
|
+
let block = entry.sessionLists.get(listKey);
|
|
1298
|
+
if (!block) {
|
|
1299
|
+
block = this.createSessionList(entry.runsContainer);
|
|
1300
|
+
entry.sessionLists.set(listKey, block);
|
|
1301
|
+
}
|
|
1302
|
+
this.updateGroupSessions(block, items);
|
|
1303
|
+
element = block.listContainer;
|
|
1304
|
+
for (const item of items) {
|
|
1305
|
+
this.renderedFocusableRunIds.push(item.run.id);
|
|
1306
|
+
this.runFocusTargets.set(item.run.id, {
|
|
1307
|
+
list: block.list,
|
|
1308
|
+
container: block.listContainer,
|
|
1309
|
+
session: item.session
|
|
1310
|
+
});
|
|
1311
|
+
}
|
|
1312
|
+
} else {
|
|
1313
|
+
const title = this.getAutomationName(run);
|
|
1314
|
+
let row = entry.temporaryRows.get(run.id);
|
|
1315
|
+
if (!row) {
|
|
1316
|
+
row = this.createTemporaryRunRow(run, title);
|
|
1317
|
+
entry.temporaryRows.set(run.id, row);
|
|
1318
|
+
}
|
|
1319
|
+
row.update(run, title);
|
|
1320
|
+
element = row.element;
|
|
1321
|
+
listKey = run.id;
|
|
1322
|
+
index++;
|
|
1171
1323
|
}
|
|
1172
|
-
const currentElement = entry.
|
|
1173
|
-
if (currentElement !==
|
|
1174
|
-
entry.
|
|
1324
|
+
const currentElement = entry.runsContainer.children.item(childIndex++);
|
|
1325
|
+
if (currentElement !== element) {
|
|
1326
|
+
entry.runsContainer.insertBefore(element, currentElement);
|
|
1327
|
+
}
|
|
1328
|
+
}
|
|
1329
|
+
for (const key of ( entry.sessionLists.keys())) {
|
|
1330
|
+
if (!( activeLists.has(key))) {
|
|
1331
|
+
entry.sessionLists.deleteAndDispose(key);
|
|
1175
1332
|
}
|
|
1176
|
-
index++;
|
|
1177
1333
|
}
|
|
1178
1334
|
}
|
|
1179
|
-
createTemporaryRunRow(title) {
|
|
1335
|
+
createTemporaryRunRow(run, title) {
|
|
1336
|
+
let currentRun = run;
|
|
1180
1337
|
const disposables = ( new DisposableStore());
|
|
1181
1338
|
const element = $(".automations-temporary-run.session-item");
|
|
1182
1339
|
element.setAttribute("role", "group");
|
|
1183
|
-
element.setAttribute("aria-label", ( localize(4827, "{0}, Working...", title)));
|
|
1184
1340
|
const icon = append(element, $(".session-icon"));
|
|
1185
1341
|
const statusIcon = disposables.add(this.instantiationService.createInstance(SessionStatusIcon, icon));
|
|
1186
1342
|
statusIcon.setStatus(SessionStatus.InProgress, true, false);
|
|
@@ -1189,10 +1345,126 @@ let AutomationHistorySection = class AutomationHistorySection extends Disposable
|
|
|
1189
1345
|
const titleElement = append(titleRow, $("span.session-title"));
|
|
1190
1346
|
titleElement.textContent = title;
|
|
1191
1347
|
const detailsRow = append(main, $(".session-details-row"));
|
|
1192
|
-
append(detailsRow, $("span.session-
|
|
1348
|
+
const repositoryLabel = run.externalResource ? append(detailsRow, $("span.session-details-icon")) : undefined;
|
|
1349
|
+
if (repositoryLabel) {
|
|
1350
|
+
append(
|
|
1351
|
+
repositoryLabel,
|
|
1352
|
+
$(`span${ThemeIcon.asCSSSelector(Codicon.cloudCompact)}`, {
|
|
1353
|
+
"aria-hidden": "true"
|
|
1354
|
+
})
|
|
1355
|
+
);
|
|
1356
|
+
}
|
|
1357
|
+
const repository = run.externalResource ? append(detailsRow, $("span.session-badge")) : undefined;
|
|
1358
|
+
const statusSeparator = run.externalResource ? append(detailsRow, $("span.session-separator", {
|
|
1359
|
+
"aria-hidden": "true"
|
|
1360
|
+
})) : undefined;
|
|
1361
|
+
const description = append(detailsRow, $("span.session-description"));
|
|
1362
|
+
if (run.externalResource) {
|
|
1363
|
+
append(detailsRow, $("span.session-separator.has-separator", {
|
|
1364
|
+
"aria-hidden": "true"
|
|
1365
|
+
}));
|
|
1366
|
+
}
|
|
1367
|
+
const timestamp = run.externalResource ? append(detailsRow, $("span.session-time")) : undefined;
|
|
1368
|
+
let timeDate = ( new Date(run.updatedAt ?? run.completedAt ?? run.startedAt));
|
|
1369
|
+
if (timestamp) {
|
|
1370
|
+
const targetWindow = getWindow(timestamp);
|
|
1371
|
+
const interval = targetWindow.setInterval(() => timestamp.textContent = formatSessionListTime(timeDate), 60_000);
|
|
1372
|
+
disposables.add(toDisposable(() => targetWindow.clearInterval(interval)));
|
|
1373
|
+
}
|
|
1374
|
+
const titleHover = disposables.add(( new MutableDisposable()));
|
|
1375
|
+
const detailsHover = disposables.add(( new MutableDisposable()));
|
|
1376
|
+
let updateActions;
|
|
1377
|
+
if (run.externalResource) {
|
|
1378
|
+
const actions = append(element, $(".automations-run-actions"));
|
|
1379
|
+
const toolbar = disposables.add(this.instantiationService.createInstance(WorkbenchToolBar, actions, {
|
|
1380
|
+
telemetrySource: "automationRun"
|
|
1381
|
+
}));
|
|
1382
|
+
const external = disposables.add(( new Action("sessions.automations.openRunOnGitHub", ( localize(6017, "Open on GitHub")), ThemeIcon.asClassName(Codicon.linkExternal), true, async () => {
|
|
1383
|
+
try {
|
|
1384
|
+
if (!(await this.openerService.open(currentRun.externalResource, {
|
|
1385
|
+
openExternal: true,
|
|
1386
|
+
allowCommands: false
|
|
1387
|
+
}))) {
|
|
1388
|
+
throw ( new Error(( localize(6018, "The link could not be opened."))));
|
|
1389
|
+
}
|
|
1390
|
+
} catch (error) {
|
|
1391
|
+
this.logService.error("[Automations] Failed to open run on GitHub", error);
|
|
1392
|
+
await this.dialogService.error(( localize(6019, "Failed to open the run on GitHub.")), getErrorMessage(error));
|
|
1393
|
+
}
|
|
1394
|
+
})));
|
|
1395
|
+
let stopping = false;
|
|
1396
|
+
const stop = disposables.add(( new Action(STOP_AUTOMATION_RUN_SESSION_COMMAND_ID, ( localize(6020, "Stop")), ThemeIcon.asClassName(Codicon.stopCircle), true, async () => {
|
|
1397
|
+
if (stopping || !this.automationService.canStopRun?.(currentRun)) {
|
|
1398
|
+
return;
|
|
1399
|
+
}
|
|
1400
|
+
stopping = true;
|
|
1401
|
+
updateActions?.();
|
|
1402
|
+
try {
|
|
1403
|
+
await this.automationService.stopRun(currentRun);
|
|
1404
|
+
status(( localize(
|
|
1405
|
+
6021,
|
|
1406
|
+
"Stop requested for {0}. History will update when available.",
|
|
1407
|
+
titleElement.textContent
|
|
1408
|
+
)));
|
|
1409
|
+
} catch (error) {
|
|
1410
|
+
this.logService.error("[Automations] Failed to stop run", error);
|
|
1411
|
+
await this.dialogService.error(( localize(6022, "Failed to stop the automation run.")), getErrorMessage(error));
|
|
1412
|
+
} finally {
|
|
1413
|
+
stopping = false;
|
|
1414
|
+
updateActions?.();
|
|
1415
|
+
}
|
|
1416
|
+
})));
|
|
1417
|
+
let stopVisible;
|
|
1418
|
+
updateActions = () => {
|
|
1419
|
+
if (disposables.isDisposed) {
|
|
1420
|
+
return;
|
|
1421
|
+
}
|
|
1422
|
+
const canStop = this.automationService.canStopRun?.(currentRun) === true;
|
|
1423
|
+
stop.enabled = canStop && !stopping;
|
|
1424
|
+
if (stopVisible !== canStop) {
|
|
1425
|
+
const hadFocus = actions.contains(getActiveElement());
|
|
1426
|
+
stopVisible = canStop;
|
|
1427
|
+
toolbar.setActions([external, ...(canStop ? [stop] : [])]);
|
|
1428
|
+
if (hadFocus) {
|
|
1429
|
+
toolbar.focus(0);
|
|
1430
|
+
}
|
|
1431
|
+
}
|
|
1432
|
+
};
|
|
1433
|
+
}
|
|
1193
1434
|
return {
|
|
1194
1435
|
element,
|
|
1195
1436
|
title: titleElement,
|
|
1437
|
+
update: (run, title) => {
|
|
1438
|
+
currentRun = run;
|
|
1439
|
+
titleElement.textContent = title;
|
|
1440
|
+
const label = run.externalResource ? run.statusDescription ?? (run.status === "pending" ? ( localize(6023, "Queued on GitHub")) : run.status === "running" ? ( localize(6024, "Running on GitHub")) : run.status === "completed" ? ( localize(6025, "Completed on GitHub")) : ( localize(6026, "Failed on GitHub: {0}", run.errorMessage ?? ""))) : ( localize(6027, "Working..."));
|
|
1441
|
+
description.textContent = run.externalResource && run.status === "completed" ? "" : label;
|
|
1442
|
+
statusSeparator?.classList.toggle("has-separator", !!description.textContent);
|
|
1443
|
+
timeDate = ( new Date(run.updatedAt ?? run.completedAt ?? run.startedAt));
|
|
1444
|
+
let details = label;
|
|
1445
|
+
if (repository && timestamp && run.externalResource) {
|
|
1446
|
+
repository.textContent = run.externalResource.path.split("/").filter(Boolean).slice(0, 2).join("/");
|
|
1447
|
+
timestamp.textContent = formatSessionListTime(timeDate);
|
|
1448
|
+
details = ( localize(
|
|
1449
|
+
6028,
|
|
1450
|
+
"{0}, {1}, {2}",
|
|
1451
|
+
repository.textContent,
|
|
1452
|
+
label,
|
|
1453
|
+
timeDate.toLocaleString()
|
|
1454
|
+
));
|
|
1455
|
+
}
|
|
1456
|
+
element.setAttribute("aria-label", ( localize(6029, "{0}, {1}", title, details)));
|
|
1457
|
+
titleHover.value = this.hoverService.setupManagedHover(getDefaultHoverDelegate("element"), titleElement, title);
|
|
1458
|
+
detailsHover.value = this.hoverService.setupManagedHover(getDefaultHoverDelegate("element"), detailsRow, details);
|
|
1459
|
+
if (run.externalResource) {
|
|
1460
|
+
statusIcon.setStatus(
|
|
1461
|
+
run.status === "completed" ? SessionStatus.Completed : run.status === "failed" ? SessionStatus.Error : run.needsInput ? SessionStatus.NeedsInput : SessionStatus.InProgress,
|
|
1462
|
+
true,
|
|
1463
|
+
false
|
|
1464
|
+
);
|
|
1465
|
+
}
|
|
1466
|
+
updateActions?.();
|
|
1467
|
+
},
|
|
1196
1468
|
dispose: () => {
|
|
1197
1469
|
disposables.dispose();
|
|
1198
1470
|
element.remove();
|
|
@@ -1209,16 +1481,8 @@ let AutomationHistorySection = class AutomationHistorySection extends Disposable
|
|
|
1209
1481
|
return;
|
|
1210
1482
|
}
|
|
1211
1483
|
entry.sessions = sessions;
|
|
1212
|
-
|
|
1213
|
-
|
|
1214
|
-
entry.listDisposables.clear();
|
|
1215
|
-
clearNode(entry.listContainer);
|
|
1216
|
-
entry.listContainer.style.height = "";
|
|
1217
|
-
return;
|
|
1218
|
-
}
|
|
1219
|
-
const list = this.ensureGroupList(entry);
|
|
1220
|
-
list.setSessions(sessions);
|
|
1221
|
-
this.layoutSessionList(entry.listContainer, list);
|
|
1484
|
+
entry.list.setSessions(sessions);
|
|
1485
|
+
this.layoutSessionList(entry.listContainer, entry.list);
|
|
1222
1486
|
}
|
|
1223
1487
|
disposeAllGroups() {
|
|
1224
1488
|
for (const [key, entry] of this.persistentGroups) {
|
|
@@ -1257,7 +1521,7 @@ let AutomationHistorySection = class AutomationHistorySection extends Disposable
|
|
|
1257
1521
|
}
|
|
1258
1522
|
}
|
|
1259
1523
|
getAutomationName(run) {
|
|
1260
|
-
return this.automationService.automations.get().find(automation => automation.id === run.automationId)?.name ?? ( localize(
|
|
1524
|
+
return this.automationService.automations.get().find(automation => automation.id === run.automationId)?.name ?? ( localize(6030, "Unknown"));
|
|
1261
1525
|
}
|
|
1262
1526
|
async openRunSession(resource) {
|
|
1263
1527
|
if (!this.sessionsManagementService.getSession(resource)) {
|
|
@@ -1270,17 +1534,17 @@ let AutomationHistorySection = class AutomationHistorySection extends Disposable
|
|
|
1270
1534
|
});
|
|
1271
1535
|
} catch (error) {
|
|
1272
1536
|
this.logService.error("[AutomationsCards] Failed to open automation run", error);
|
|
1273
|
-
await this.dialogService.error(( localize(
|
|
1537
|
+
await this.dialogService.error(( localize(6031, "Failed to open automation run.")), getErrorMessage(error));
|
|
1274
1538
|
}
|
|
1275
1539
|
}
|
|
1276
1540
|
async stopRunSession(session, automationName, action) {
|
|
1277
1541
|
try {
|
|
1278
1542
|
await this.sessionsManagementService.cancelCurrentRequest(session);
|
|
1279
|
-
status(( localize(
|
|
1543
|
+
status(( localize(6032, "Stopped the session for {0}", automationName)));
|
|
1280
1544
|
} catch (error) {
|
|
1281
1545
|
action.enabled = true;
|
|
1282
1546
|
this.logService.error("[AutomationsCards] Failed to stop automation run session", error);
|
|
1283
|
-
await this.dialogService.error(( localize(
|
|
1547
|
+
await this.dialogService.error(( localize(6033, "Failed to stop the automation run session.")), getErrorMessage(error));
|
|
1284
1548
|
}
|
|
1285
1549
|
}
|
|
1286
1550
|
restoreFocusAfterRender() {
|
|
@@ -1314,13 +1578,13 @@ let AutomationHistorySection = class AutomationHistorySection extends Disposable
|
|
|
1314
1578
|
await this.sessionsManagementService.markAllRead([...( sessions.values())]);
|
|
1315
1579
|
} catch (error) {
|
|
1316
1580
|
this.logService.error("[AutomationsCards] Failed to mark automation runs read", error);
|
|
1317
|
-
await this.dialogService.error(( localize(
|
|
1581
|
+
await this.dialogService.error(( localize(6034, "Failed to mark automation runs as read.")), getErrorMessage(error));
|
|
1318
1582
|
} finally {
|
|
1319
1583
|
this.isMarkingAllRead.set(false, undefined);
|
|
1320
1584
|
}
|
|
1321
1585
|
}
|
|
1322
1586
|
};
|
|
1323
|
-
AutomationHistorySection = ( __decorate([( __param(3, IAutomationService)), ( __param(4, ISessionsService)), ( __param(5, ISessionsManagementService)), ( __param(6, ILogService)), ( __param(7, IDialogService)), ( __param(8, IInstantiationService))], AutomationHistorySection));
|
|
1587
|
+
AutomationHistorySection = ( __decorate([( __param(3, IAutomationService)), ( __param(4, ISessionsService)), ( __param(5, ISessionsManagementService)), ( __param(6, ILogService)), ( __param(7, IDialogService)), ( __param(8, IInstantiationService)), ( __param(9, IOpenerService)), ( __param(10, IHoverService))], AutomationHistorySection));
|
|
1324
1588
|
function isUnreadAutomationRun(run, session, reader) {
|
|
1325
1589
|
return (run.status === "completed" || run.status === "failed") && !!session && !session.isRead.read(reader);
|
|
1326
1590
|
}
|
|
@@ -1328,26 +1592,31 @@ function isTemporaryAutomationRun(run) {
|
|
|
1328
1592
|
return run.status === "pending" || run.status === "running";
|
|
1329
1593
|
}
|
|
1330
1594
|
function formatSchedule(schedule) {
|
|
1595
|
+
const localSchedule = automationScheduleToLocal(schedule);
|
|
1331
1596
|
const {
|
|
1332
1597
|
interval,
|
|
1333
1598
|
scheduleHour,
|
|
1334
1599
|
scheduleMinute
|
|
1335
|
-
} =
|
|
1600
|
+
} = localSchedule;
|
|
1336
1601
|
const time = formatHourMinute(scheduleHour, scheduleMinute);
|
|
1337
1602
|
switch (interval) {
|
|
1338
1603
|
case "hourly":
|
|
1339
|
-
return localize(
|
|
1604
|
+
return localize(6035, "Hourly");
|
|
1340
1605
|
case "daily":
|
|
1341
|
-
return localize(
|
|
1606
|
+
return localize(6036, "Daily at {0}", time);
|
|
1607
|
+
case "weekdays":
|
|
1608
|
+
return localize(6037, "Weekdays at {0}", time);
|
|
1342
1609
|
case "weekly":
|
|
1343
1610
|
{
|
|
1344
|
-
const day = DAYS_OF_WEEK[((
|
|
1345
|
-
return localize(
|
|
1611
|
+
const day = DAYS_OF_WEEK[((localSchedule.scheduleDay % 7) + 7) % 7];
|
|
1612
|
+
return localize(6038, "{0} at {1}", day, time);
|
|
1346
1613
|
}
|
|
1347
1614
|
case "manual":
|
|
1348
|
-
return localize(
|
|
1615
|
+
return localize(6039, "Manual");
|
|
1616
|
+
case "custom":
|
|
1617
|
+
return localize(6040, "Custom schedule");
|
|
1349
1618
|
default:
|
|
1350
|
-
return localize(
|
|
1619
|
+
return localize(6039, "Manual");
|
|
1351
1620
|
}
|
|
1352
1621
|
}
|
|
1353
1622
|
function formatHourMinute(hour, minute) {
|
|
@@ -1365,7 +1634,7 @@ function formatHourMinute(hour, minute) {
|
|
|
1365
1634
|
});
|
|
1366
1635
|
}
|
|
1367
1636
|
function getAutomationTargetLabel(target) {
|
|
1368
|
-
return target.kind === "workspace" ? basename(target.folderUri) :
|
|
1637
|
+
return target.kind === "workspace" ? basename(target.folderUri) : "";
|
|
1369
1638
|
}
|
|
1370
1639
|
function groupRunsByDate(runs) {
|
|
1371
1640
|
const now = ( new Date());
|
|
@@ -1404,21 +1673,21 @@ function getDateBucket(date, today, yesterday, lastWeekStart) {
|
|
|
1404
1673
|
if (date >= today) {
|
|
1405
1674
|
return {
|
|
1406
1675
|
key: "today",
|
|
1407
|
-
label: ( localize(
|
|
1676
|
+
label: ( localize(6041, "Today")),
|
|
1408
1677
|
order: 0
|
|
1409
1678
|
};
|
|
1410
1679
|
}
|
|
1411
1680
|
if (date >= yesterday) {
|
|
1412
1681
|
return {
|
|
1413
1682
|
key: "yesterday",
|
|
1414
|
-
label: ( localize(
|
|
1683
|
+
label: ( localize(6042, "Yesterday")),
|
|
1415
1684
|
order: 1
|
|
1416
1685
|
};
|
|
1417
1686
|
}
|
|
1418
1687
|
if (date >= lastWeekStart) {
|
|
1419
1688
|
return {
|
|
1420
1689
|
key: "week",
|
|
1421
|
-
label: ( localize(
|
|
1690
|
+
label: ( localize(6043, "Last week")),
|
|
1422
1691
|
order: 2
|
|
1423
1692
|
};
|
|
1424
1693
|
}
|
|
@@ -1443,33 +1712,33 @@ function getAutomationBlueprintErrorMessage(error) {
|
|
|
1443
1712
|
}
|
|
1444
1713
|
switch (error.code) {
|
|
1445
1714
|
case "invalidFrontmatter":
|
|
1446
|
-
return localize(
|
|
1715
|
+
return localize(6044, "The file must start with valid YAML frontmatter.");
|
|
1447
1716
|
case "unknownProperty":
|
|
1448
|
-
return localize(
|
|
1717
|
+
return localize(6045, "The property '{0}' is not supported.", error.property ?? "");
|
|
1449
1718
|
case "invalidField":
|
|
1450
|
-
return localize(
|
|
1719
|
+
return localize(6046, "The property '{0}' is missing or invalid.", error.property ?? "");
|
|
1451
1720
|
case "unsupportedVersion":
|
|
1452
1721
|
return localize(
|
|
1453
|
-
|
|
1722
|
+
6047,
|
|
1454
1723
|
"Automation blueprint version {0} is not supported.",
|
|
1455
1724
|
error.property ?? ""
|
|
1456
1725
|
);
|
|
1457
1726
|
case "invalidId":
|
|
1458
|
-
return localize(
|
|
1727
|
+
return localize(6048, "The blueprint id '{0}' is invalid.", error.property ?? "");
|
|
1459
1728
|
case "unsupportedSchedule":
|
|
1460
1729
|
return localize(
|
|
1461
|
-
|
|
1730
|
+
6049,
|
|
1462
1731
|
"The cron expression '{0}' cannot be represented by the current Automation editor.",
|
|
1463
1732
|
error.property ?? ""
|
|
1464
1733
|
);
|
|
1465
1734
|
case "unsupportedTimeZone":
|
|
1466
1735
|
return localize(
|
|
1467
|
-
|
|
1736
|
+
6050,
|
|
1468
1737
|
"The time zone '{0}' is not supported. Use 'local' so the schedule follows the importing user's time zone.",
|
|
1469
1738
|
error.property ?? ""
|
|
1470
1739
|
);
|
|
1471
1740
|
case "missingPrompt":
|
|
1472
|
-
return localize(
|
|
1741
|
+
return localize(6051, "The Automation prompt must follow the frontmatter.");
|
|
1473
1742
|
}
|
|
1474
1743
|
}
|
|
1475
1744
|
function normalizeAutomationBlueprintResource(resource) {
|
|
@@ -1539,7 +1808,8 @@ async function importAutomationBlueprint(
|
|
|
1539
1808
|
automationService,
|
|
1540
1809
|
configurationService,
|
|
1541
1810
|
dialogService,
|
|
1542
|
-
logService
|
|
1811
|
+
logService,
|
|
1812
|
+
telemetryService
|
|
1543
1813
|
) {
|
|
1544
1814
|
const isEnabled = () => configurationService.getValue(CHAT_AUTOMATIONS_ENABLED_SETTING) === true;
|
|
1545
1815
|
if (!isEnabled()) {
|
|
@@ -1551,41 +1821,41 @@ async function importAutomationBlueprint(
|
|
|
1551
1821
|
blueprint = parseAutomationBlueprint(await readContent());
|
|
1552
1822
|
} catch (error) {
|
|
1553
1823
|
logService.error("[Automations] Failed to read Automation blueprint", error);
|
|
1554
|
-
await dialogService.error(( localize(
|
|
1824
|
+
await dialogService.error(( localize(6052, "Failed to import automation.")), getAutomationBlueprintErrorMessage(error));
|
|
1555
1825
|
return;
|
|
1556
1826
|
}
|
|
1827
|
+
let automation;
|
|
1557
1828
|
const result = await automationDialogService.showAutomationDialog({
|
|
1558
1829
|
initialValues: {
|
|
1559
1830
|
name: blueprint.name,
|
|
1560
1831
|
prompt: blueprint.prompt,
|
|
1561
1832
|
schedule: blueprint.schedule,
|
|
1562
1833
|
enabled: false
|
|
1834
|
+
},
|
|
1835
|
+
commit: async result => {
|
|
1836
|
+
if (result.kind === "create") {
|
|
1837
|
+
automation = await withAutomationDialogPersistenceTelemetry(
|
|
1838
|
+
telemetryService,
|
|
1839
|
+
"create",
|
|
1840
|
+
() => automationService.createAutomation(result.value, () => {
|
|
1841
|
+
if (!isEnabled()) {
|
|
1842
|
+
throw ( new Error(( localize(
|
|
1843
|
+
6053,
|
|
1844
|
+
"Automations were disabled before the imported automation could be saved."
|
|
1845
|
+
))));
|
|
1846
|
+
}
|
|
1847
|
+
})
|
|
1848
|
+
);
|
|
1849
|
+
}
|
|
1563
1850
|
}
|
|
1564
1851
|
});
|
|
1565
|
-
if (!result ||
|
|
1566
|
-
return;
|
|
1567
|
-
}
|
|
1568
|
-
if (!isEnabled()) {
|
|
1569
|
-
await showAutomationsDisabled(dialogService);
|
|
1852
|
+
if (!result || !automation) {
|
|
1570
1853
|
return;
|
|
1571
1854
|
}
|
|
1572
|
-
|
|
1573
|
-
const automation = await automationService.createAutomation(result.value, () => {
|
|
1574
|
-
if (!isEnabled()) {
|
|
1575
|
-
throw ( new Error(( localize(
|
|
1576
|
-
4851,
|
|
1577
|
-
"Automations were disabled before the imported automation could be saved."
|
|
1578
|
-
))));
|
|
1579
|
-
}
|
|
1580
|
-
});
|
|
1581
|
-
status(( localize(4852, "Imported automation {0}", automation.name)));
|
|
1582
|
-
} catch (error) {
|
|
1583
|
-
logService.error("[Automations] Failed to import Automation blueprint", error);
|
|
1584
|
-
await dialogService.error(( localize(4853, "Failed to import automation.")), getErrorMessage(error));
|
|
1585
|
-
}
|
|
1855
|
+
status(( localize(6054, "Imported automation {0}", automation.name)));
|
|
1586
1856
|
}
|
|
1587
1857
|
async function showAutomationsDisabled(dialogService) {
|
|
1588
|
-
await dialogService.info(( localize(
|
|
1858
|
+
await dialogService.info(( localize(6055, "Automations are disabled.")), ( localize(6056, "Enable “{0}” to make changes.", CHAT_AUTOMATIONS_ENABLED_SETTING)));
|
|
1589
1859
|
}
|
|
1590
1860
|
async function confirmAndDeleteAutomation(
|
|
1591
1861
|
automation,
|
|
@@ -1594,7 +1864,7 @@ async function confirmAndDeleteAutomation(
|
|
|
1594
1864
|
dialogService,
|
|
1595
1865
|
logService
|
|
1596
1866
|
) {
|
|
1597
|
-
if (automationService.canDeleteAutomation
|
|
1867
|
+
if (!automationService.canDeleteAutomation(automation.id)) {
|
|
1598
1868
|
return;
|
|
1599
1869
|
}
|
|
1600
1870
|
const isEnabled = () => configurationService.getValue(CHAT_AUTOMATIONS_ENABLED_SETTING) === true;
|
|
@@ -1603,9 +1873,9 @@ async function confirmAndDeleteAutomation(
|
|
|
1603
1873
|
return;
|
|
1604
1874
|
}
|
|
1605
1875
|
const confirmed = await dialogService.confirm({
|
|
1606
|
-
message: ( localize(
|
|
1607
|
-
detail: ( localize(
|
|
1608
|
-
primaryButton: ( localize(
|
|
1876
|
+
message: ( localize(6057, "Delete automation \"{0}\"?", automation.name)),
|
|
1877
|
+
detail: ( localize(6058, "This will permanently delete the automation and its run history.")),
|
|
1878
|
+
primaryButton: ( localize(6059, "Delete"))
|
|
1609
1879
|
});
|
|
1610
1880
|
if (!confirmed.confirmed) {
|
|
1611
1881
|
return;
|
|
@@ -1617,22 +1887,22 @@ async function confirmAndDeleteAutomation(
|
|
|
1617
1887
|
try {
|
|
1618
1888
|
await automationService.deleteAutomation(automation.id, () => {
|
|
1619
1889
|
if (!isEnabled()) {
|
|
1620
|
-
throw ( new Error(( localize(
|
|
1890
|
+
throw ( new Error(( localize(6060, "Automations were disabled before the automation could be deleted."))));
|
|
1621
1891
|
}
|
|
1622
1892
|
});
|
|
1623
|
-
status(( localize(
|
|
1893
|
+
status(( localize(6061, "Deleted automation {0}", automation.name)));
|
|
1624
1894
|
} catch (error) {
|
|
1625
1895
|
logService.error("[AutomationsCards] Failed to delete automation", error);
|
|
1626
|
-
await dialogService.error(( localize(
|
|
1896
|
+
await dialogService.error(( localize(6062, "Failed to delete automation.")), getErrorMessage(error));
|
|
1627
1897
|
}
|
|
1628
1898
|
}
|
|
1629
1899
|
let AutomationsCustomView = class AutomationsCustomView extends AbstractCustomView {
|
|
1630
1900
|
constructor(instantiationService) {
|
|
1631
1901
|
super();
|
|
1632
1902
|
this.instantiationService = instantiationService;
|
|
1633
|
-
this.title = constObservable(( localize(
|
|
1903
|
+
this.title = constObservable(( localize(6063, "Automations")));
|
|
1634
1904
|
this.description = constObservable(( localize(
|
|
1635
|
-
|
|
1905
|
+
6064,
|
|
1636
1906
|
"Schedule agent sessions to run automatically on a cadence you choose."
|
|
1637
1907
|
)));
|
|
1638
1908
|
}
|
|
@@ -1711,6 +1981,16 @@ let AutomationsCustomViewContribution = class AutomationsCustomViewContribution
|
|
|
1711
1981
|
return instantiationService.createInstance(AutomationHeaderButtonActionViewItem, undefined, action, options, true);
|
|
1712
1982
|
}
|
|
1713
1983
|
));
|
|
1984
|
+
this._register(actionViewItemService.register(
|
|
1985
|
+
Menus.CustomViewAutomations,
|
|
1986
|
+
"sessions.automations.refresh",
|
|
1987
|
+
(action, options, instantiationService) => {
|
|
1988
|
+
if (!(action instanceof MenuItemAction)) {
|
|
1989
|
+
return undefined;
|
|
1990
|
+
}
|
|
1991
|
+
return instantiationService.createInstance(AutomationHeaderButtonActionViewItem, undefined, action, options, true);
|
|
1992
|
+
}
|
|
1993
|
+
));
|
|
1714
1994
|
}
|
|
1715
1995
|
};
|
|
1716
1996
|
AutomationsCustomViewContribution = ( __decorate([( __param(0, ICustomViewService)), ( __param(1, IActionViewItemService)), ( __param(2, IContextKeyService)), ( __param(3, IAutomationService)), ( __param(4, IConfigurationService))], AutomationsCustomViewContribution));
|
|
@@ -1719,7 +1999,7 @@ function registerAutomationHistoryItemActions(archiveWording) {
|
|
|
1719
1999
|
return combinedDisposable(MenuRegistry.appendMenuItem(Menus.AutomationsHistoryItem, {
|
|
1720
2000
|
command: {
|
|
1721
2001
|
id: STOP_AUTOMATION_RUN_SESSION_COMMAND_ID,
|
|
1722
|
-
title: ( localize(
|
|
2002
|
+
title: ( localize(6020, "Stop")),
|
|
1723
2003
|
icon: Codicon.stopCircle
|
|
1724
2004
|
},
|
|
1725
2005
|
group: "navigation",
|
|
@@ -1728,7 +2008,7 @@ function registerAutomationHistoryItemActions(archiveWording) {
|
|
|
1728
2008
|
}), MenuRegistry.appendMenuItem(Menus.AutomationsHistoryItemContext, {
|
|
1729
2009
|
command: {
|
|
1730
2010
|
id: MARK_SESSION_READ_COMMAND_ID,
|
|
1731
|
-
title: ( localize(
|
|
2011
|
+
title: ( localize(6065, "Mark as Read"))
|
|
1732
2012
|
},
|
|
1733
2013
|
group: "0_read",
|
|
1734
2014
|
order: 1,
|
|
@@ -1736,7 +2016,7 @@ function registerAutomationHistoryItemActions(archiveWording) {
|
|
|
1736
2016
|
}), MenuRegistry.appendMenuItem(Menus.AutomationsHistoryItemContext, {
|
|
1737
2017
|
command: {
|
|
1738
2018
|
id: MARK_SESSION_UNREAD_COMMAND_ID,
|
|
1739
|
-
title: ( localize(
|
|
2019
|
+
title: ( localize(6066, "Mark as Unread"))
|
|
1740
2020
|
},
|
|
1741
2021
|
group: "0_read",
|
|
1742
2022
|
order: 1,
|
|
@@ -1744,7 +2024,7 @@ function registerAutomationHistoryItemActions(archiveWording) {
|
|
|
1744
2024
|
}), MenuRegistry.appendMenuItem(Menus.AutomationsHistoryItemContext, {
|
|
1745
2025
|
command: {
|
|
1746
2026
|
id: RENAME_SESSION_COMMAND_ID,
|
|
1747
|
-
title: ( localize(
|
|
2027
|
+
title: ( localize(6067, "Rename..."))
|
|
1748
2028
|
},
|
|
1749
2029
|
group: "1_edit",
|
|
1750
2030
|
order: 1,
|
|
@@ -1817,11 +2097,44 @@ class AutomationHeaderButtonActionViewItem extends BaseActionViewItem {
|
|
|
1817
2097
|
reset(this.button.element, this._action.label);
|
|
1818
2098
|
}
|
|
1819
2099
|
}
|
|
2100
|
+
async function refreshAutomations(automationService, logService, notificationService) {
|
|
2101
|
+
try {
|
|
2102
|
+
await automationService.refresh?.();
|
|
2103
|
+
} catch (error) {
|
|
2104
|
+
if (!isCancellationError(error)) {
|
|
2105
|
+
logService.error("[Automations] Failed to refresh", error);
|
|
2106
|
+
notificationService.error(( localize(6068, "Could not refresh automations: {0}", getErrorMessage(error))));
|
|
2107
|
+
}
|
|
2108
|
+
}
|
|
2109
|
+
}
|
|
2110
|
+
registerAction2(class RefreshAutomationsAction extends Action2 {
|
|
2111
|
+
constructor() {
|
|
2112
|
+
super({
|
|
2113
|
+
id: "sessions.automations.refresh",
|
|
2114
|
+
title: ( localize2(6069, "Refresh")),
|
|
2115
|
+
icon: Codicon.refresh,
|
|
2116
|
+
precondition: ChatAutomationsEnabledContext,
|
|
2117
|
+
menu: [{
|
|
2118
|
+
id: Menus.CustomViewAutomations,
|
|
2119
|
+
group: "navigation",
|
|
2120
|
+
order: 3,
|
|
2121
|
+
when: ChatAutomationsEnabledContext
|
|
2122
|
+
}]
|
|
2123
|
+
});
|
|
2124
|
+
}
|
|
2125
|
+
async run(accessor) {
|
|
2126
|
+
await refreshAutomations(
|
|
2127
|
+
accessor.get(IAutomationService),
|
|
2128
|
+
accessor.get(ILogService),
|
|
2129
|
+
accessor.get(INotificationService)
|
|
2130
|
+
);
|
|
2131
|
+
}
|
|
2132
|
+
});
|
|
1820
2133
|
registerAction2(class NewAutomationAction extends Action2 {
|
|
1821
2134
|
constructor() {
|
|
1822
2135
|
super({
|
|
1823
2136
|
id: "sessionsView.newAutomation",
|
|
1824
|
-
title: ( localize2(
|
|
2137
|
+
title: ( localize2(6070, "New Automation")),
|
|
1825
2138
|
precondition: ChatAutomationsEnabledContext,
|
|
1826
2139
|
menu: [{
|
|
1827
2140
|
id: Menus.CustomViewAutomations,
|
|
@@ -1836,37 +2149,34 @@ registerAction2(class NewAutomationAction extends Action2 {
|
|
|
1836
2149
|
const automationService = accessor.get(IAutomationService);
|
|
1837
2150
|
const configurationService = accessor.get(IConfigurationService);
|
|
1838
2151
|
const dialogService = accessor.get(IDialogService);
|
|
1839
|
-
const
|
|
2152
|
+
const telemetryService = accessor.get(ITelemetryService);
|
|
1840
2153
|
const isEnabled = () => configurationService.getValue(CHAT_AUTOMATIONS_ENABLED_SETTING) === true;
|
|
1841
2154
|
if (!isEnabled()) {
|
|
1842
2155
|
await showAutomationsDisabled(dialogService);
|
|
1843
2156
|
return;
|
|
1844
2157
|
}
|
|
1845
|
-
|
|
1846
|
-
|
|
1847
|
-
|
|
1848
|
-
|
|
1849
|
-
|
|
1850
|
-
|
|
1851
|
-
|
|
1852
|
-
|
|
1853
|
-
|
|
1854
|
-
|
|
1855
|
-
|
|
1856
|
-
|
|
2158
|
+
await automationDialogService.showAutomationDialog({
|
|
2159
|
+
commit: async result => {
|
|
2160
|
+
if (result.kind === "create") {
|
|
2161
|
+
await withAutomationDialogPersistenceTelemetry(
|
|
2162
|
+
telemetryService,
|
|
2163
|
+
"create",
|
|
2164
|
+
() => automationService.createAutomation(result.value, () => {
|
|
2165
|
+
if (!isEnabled()) {
|
|
2166
|
+
throw ( new Error(( localize(6014, "Automations were disabled before the change could be saved."))));
|
|
2167
|
+
}
|
|
2168
|
+
})
|
|
2169
|
+
);
|
|
1857
2170
|
}
|
|
1858
|
-
}
|
|
1859
|
-
}
|
|
1860
|
-
logService.error("[Automations] Failed to create automation", err);
|
|
1861
|
-
await dialogService.error(( localize(4819, "Failed to create automation.")), getErrorMessage(err));
|
|
1862
|
-
}
|
|
2171
|
+
}
|
|
2172
|
+
});
|
|
1863
2173
|
}
|
|
1864
2174
|
});
|
|
1865
2175
|
registerAction2(class ImportAutomationAction extends Action2 {
|
|
1866
2176
|
constructor() {
|
|
1867
2177
|
super({
|
|
1868
2178
|
id: "sessions.automations.import",
|
|
1869
|
-
title: ( localize2(
|
|
2179
|
+
title: ( localize2(6071, "Import Automation")),
|
|
1870
2180
|
precondition: ChatAutomationsEnabledContext,
|
|
1871
2181
|
menu: [{
|
|
1872
2182
|
id: Menus.CustomViewAutomations,
|
|
@@ -1884,19 +2194,20 @@ registerAction2(class ImportAutomationAction extends Action2 {
|
|
|
1884
2194
|
const logService = accessor.get(ILogService);
|
|
1885
2195
|
const automationDialogService = accessor.get(IAutomationDialogService);
|
|
1886
2196
|
const automationService = accessor.get(IAutomationService);
|
|
2197
|
+
const telemetryService = accessor.get(ITelemetryService);
|
|
1887
2198
|
const isEnabled = () => configurationService.getValue(CHAT_AUTOMATIONS_ENABLED_SETTING) === true;
|
|
1888
2199
|
if (!isEnabled()) {
|
|
1889
2200
|
await showAutomationsDisabled(dialogService);
|
|
1890
2201
|
return;
|
|
1891
2202
|
}
|
|
1892
2203
|
const resources = await fileDialogService.showOpenDialog({
|
|
1893
|
-
title: ( localize(
|
|
1894
|
-
openLabel: ( localize(
|
|
2204
|
+
title: ( localize(6072, "Import Automation")),
|
|
2205
|
+
openLabel: ( localize(6073, "Import")),
|
|
1895
2206
|
canSelectFiles: true,
|
|
1896
2207
|
canSelectFolders: false,
|
|
1897
2208
|
canSelectMany: false,
|
|
1898
2209
|
filters: [{
|
|
1899
|
-
name: ( localize(
|
|
2210
|
+
name: ( localize(6074, "Automation Blueprint")),
|
|
1900
2211
|
extensions: ["automation.md"]
|
|
1901
2212
|
}]
|
|
1902
2213
|
});
|
|
@@ -1905,17 +2216,17 @@ registerAction2(class ImportAutomationAction extends Action2 {
|
|
|
1905
2216
|
return;
|
|
1906
2217
|
}
|
|
1907
2218
|
if (!isAutomationBlueprintResource(resource)) {
|
|
1908
|
-
await dialogService.error(( localize(
|
|
2219
|
+
await dialogService.error(( localize(5971, "Unable to import automation.")), ( localize(5970, "Only .automation.md files can be imported.")));
|
|
1909
2220
|
return;
|
|
1910
2221
|
}
|
|
1911
|
-
await importAutomationBlueprint(async () => ( (await fileService.readFile(resource)).value.toString()), automationDialogService, automationService, configurationService, dialogService, logService);
|
|
2222
|
+
await importAutomationBlueprint(async () => ( (await fileService.readFile(resource)).value.toString()), automationDialogService, automationService, configurationService, dialogService, logService, telemetryService);
|
|
1912
2223
|
}
|
|
1913
2224
|
});
|
|
1914
2225
|
registerAction2(class DuplicateAutomationAction extends Action2 {
|
|
1915
2226
|
constructor() {
|
|
1916
2227
|
super({
|
|
1917
2228
|
id: "sessions.automations.duplicate",
|
|
1918
|
-
title: ( localize2(
|
|
2229
|
+
title: ( localize2(6075, "Duplicate")),
|
|
1919
2230
|
precondition: ChatAutomationsEnabledContext,
|
|
1920
2231
|
menu: [{
|
|
1921
2232
|
id: Menus.AutomationCardContext,
|
|
@@ -1931,6 +2242,7 @@ registerAction2(class DuplicateAutomationAction extends Action2 {
|
|
|
1931
2242
|
const configurationService = accessor.get(IConfigurationService);
|
|
1932
2243
|
const dialogService = accessor.get(IDialogService);
|
|
1933
2244
|
const logService = accessor.get(ILogService);
|
|
2245
|
+
const telemetryService = accessor.get(ITelemetryService);
|
|
1934
2246
|
const isEnabled = () => configurationService.getValue(CHAT_AUTOMATIONS_ENABLED_SETTING) === true;
|
|
1935
2247
|
if (!isEnabled()) {
|
|
1936
2248
|
await showAutomationsDisabled(dialogService);
|
|
@@ -1938,6 +2250,7 @@ registerAction2(class DuplicateAutomationAction extends Action2 {
|
|
|
1938
2250
|
}
|
|
1939
2251
|
try {
|
|
1940
2252
|
const name = getDuplicateAutomationName(automation.name, automationService.automations.get());
|
|
2253
|
+
let duplicate;
|
|
1941
2254
|
const result = await automationDialogService.showAutomationDialog({
|
|
1942
2255
|
initialValues: {
|
|
1943
2256
|
name,
|
|
@@ -1952,24 +2265,28 @@ registerAction2(class DuplicateAutomationAction extends Action2 {
|
|
|
1952
2265
|
permissionLevel: automation.permissionLevel
|
|
1953
2266
|
}),
|
|
1954
2267
|
enabled: automation.enabled
|
|
2268
|
+
},
|
|
2269
|
+
commit: async result => {
|
|
2270
|
+
if (result.kind === "create") {
|
|
2271
|
+
duplicate = await withAutomationDialogPersistenceTelemetry(
|
|
2272
|
+
telemetryService,
|
|
2273
|
+
"create",
|
|
2274
|
+
() => automationService.createAutomation(result.value, () => {
|
|
2275
|
+
if (!isEnabled()) {
|
|
2276
|
+
throw ( new Error(( localize(6076, "Automations were disabled before the duplicate could be saved."))));
|
|
2277
|
+
}
|
|
2278
|
+
})
|
|
2279
|
+
);
|
|
2280
|
+
}
|
|
1955
2281
|
}
|
|
1956
2282
|
});
|
|
1957
|
-
if (!result ||
|
|
1958
|
-
return;
|
|
1959
|
-
}
|
|
1960
|
-
if (!isEnabled()) {
|
|
1961
|
-
await showAutomationsDisabled(dialogService);
|
|
2283
|
+
if (!result || !duplicate) {
|
|
1962
2284
|
return;
|
|
1963
2285
|
}
|
|
1964
|
-
|
|
1965
|
-
if (!isEnabled()) {
|
|
1966
|
-
throw ( new Error(( localize(4874, "Automations were disabled before the duplicate could be saved."))));
|
|
1967
|
-
}
|
|
1968
|
-
});
|
|
1969
|
-
status(( localize(4875, "Created duplicate automation {0}", duplicate.name)));
|
|
2286
|
+
status(( localize(6077, "Created duplicate automation {0}", duplicate.name)));
|
|
1970
2287
|
} catch (error) {
|
|
1971
2288
|
logService.error("[Automations] Failed to duplicate automation", error);
|
|
1972
|
-
await dialogService.error(( localize(
|
|
2289
|
+
await dialogService.error(( localize(6078, "Failed to duplicate automation.")), getErrorMessage(error));
|
|
1973
2290
|
}
|
|
1974
2291
|
}
|
|
1975
2292
|
});
|
|
@@ -1977,7 +2294,7 @@ registerAction2(class ExportAutomationAction extends Action2 {
|
|
|
1977
2294
|
constructor() {
|
|
1978
2295
|
super({
|
|
1979
2296
|
id: "sessions.automations.export",
|
|
1980
|
-
title: ( localize2(
|
|
2297
|
+
title: ( localize2(6079, "Export")),
|
|
1981
2298
|
precondition: ChatAutomationsEnabledContext,
|
|
1982
2299
|
menu: [{
|
|
1983
2300
|
id: Menus.AutomationCardContext,
|
|
@@ -2004,11 +2321,11 @@ registerAction2(class ExportAutomationAction extends Action2 {
|
|
|
2004
2321
|
let resource;
|
|
2005
2322
|
while (true) {
|
|
2006
2323
|
const selectedResource = await fileDialogService.showSaveDialog({
|
|
2007
|
-
title: ( localize(
|
|
2008
|
-
saveLabel: ( localize(
|
|
2324
|
+
title: ( localize(6080, "Export Automation")),
|
|
2325
|
+
saveLabel: ( localize(6081, "Export")),
|
|
2009
2326
|
defaultUri,
|
|
2010
2327
|
filters: [{
|
|
2011
|
-
name: ( localize(
|
|
2328
|
+
name: ( localize(6074, "Automation Blueprint")),
|
|
2012
2329
|
extensions: ["md"]
|
|
2013
2330
|
}]
|
|
2014
2331
|
});
|
|
@@ -2020,16 +2337,53 @@ registerAction2(class ExportAutomationAction extends Action2 {
|
|
|
2020
2337
|
resource = selectedResource;
|
|
2021
2338
|
break;
|
|
2022
2339
|
}
|
|
2023
|
-
await dialogService.error(( localize(
|
|
2340
|
+
await dialogService.error(( localize(6082, "Unable to export automation.")), ( localize(6083, "Use a file name ending in exactly one .automation.md suffix.")));
|
|
2024
2341
|
defaultUri = normalizedResource;
|
|
2025
2342
|
}
|
|
2026
2343
|
try {
|
|
2027
2344
|
const content = serializeAutomationBlueprint(automationToBlueprint(automation));
|
|
2028
2345
|
await fileService.writeFile(resource, VSBuffer.fromString(content));
|
|
2029
|
-
status(( localize(
|
|
2346
|
+
status(( localize(6084, "Exported automation {0}", automation.name)));
|
|
2030
2347
|
} catch (error) {
|
|
2031
2348
|
logService.error("[Automations] Failed to export Automation blueprint", error);
|
|
2032
|
-
await dialogService.error(( localize(
|
|
2349
|
+
await dialogService.error(( localize(6085, "Failed to export automation.")), getErrorMessage(error));
|
|
2350
|
+
}
|
|
2351
|
+
}
|
|
2352
|
+
});
|
|
2353
|
+
registerAction2(class OpenAutomationOnGitHubAction extends Action2 {
|
|
2354
|
+
constructor() {
|
|
2355
|
+
super({
|
|
2356
|
+
id: "sessions.automations.openOnGitHub",
|
|
2357
|
+
title: ( localize2(6086, "Open on GitHub")),
|
|
2358
|
+
icon: Codicon.linkExternal,
|
|
2359
|
+
precondition: ( ContextKeyExpr.and(ChatAutomationsEnabledContext, AutomationCardHasExternalResourceContext)),
|
|
2360
|
+
menu: [{
|
|
2361
|
+
id: Menus.AutomationCardContext,
|
|
2362
|
+
group: "navigation",
|
|
2363
|
+
order: 3.5,
|
|
2364
|
+
when: ( ContextKeyExpr.and(ChatAutomationsEnabledContext, AutomationCardHasExternalResourceContext))
|
|
2365
|
+
}]
|
|
2366
|
+
});
|
|
2367
|
+
}
|
|
2368
|
+
async run(accessor, automation) {
|
|
2369
|
+
const automationService = accessor.get(IAutomationService);
|
|
2370
|
+
const openerService = accessor.get(IOpenerService);
|
|
2371
|
+
const logService = accessor.get(ILogService);
|
|
2372
|
+
const dialogService = accessor.get(IDialogService);
|
|
2373
|
+
try {
|
|
2374
|
+
const resource = automationService.getAutomation(automation.id)?.externalResource;
|
|
2375
|
+
if (!resource) {
|
|
2376
|
+
throw ( new Error(( localize(6087, "This automation is no longer available on GitHub."))));
|
|
2377
|
+
}
|
|
2378
|
+
if (!(await openerService.open(resource, {
|
|
2379
|
+
openExternal: true,
|
|
2380
|
+
allowCommands: false
|
|
2381
|
+
}))) {
|
|
2382
|
+
throw ( new Error(( localize(6088, "The link could not be opened."))));
|
|
2383
|
+
}
|
|
2384
|
+
} catch (error) {
|
|
2385
|
+
logService.error("[Automations] Failed to open automation on GitHub", error);
|
|
2386
|
+
await dialogService.error(( localize(6089, "Failed to open the automation on GitHub.")), getErrorMessage(error));
|
|
2033
2387
|
}
|
|
2034
2388
|
}
|
|
2035
2389
|
});
|
|
@@ -2037,7 +2391,7 @@ registerAction2(class DeleteAutomationAction extends Action2 {
|
|
|
2037
2391
|
constructor() {
|
|
2038
2392
|
super({
|
|
2039
2393
|
id: "sessions.automations.delete",
|
|
2040
|
-
title: ( localize2(
|
|
2394
|
+
title: ( localize2(6090, "Delete")),
|
|
2041
2395
|
precondition: ( ContextKeyExpr.and(ChatAutomationsEnabledContext, AutomationCardCanDeleteContext)),
|
|
2042
2396
|
menu: [{
|
|
2043
2397
|
id: Menus.AutomationCardContext,
|
|
@@ -2061,7 +2415,7 @@ registerAction2(class DisableAutomationAction extends Action2 {
|
|
|
2061
2415
|
constructor() {
|
|
2062
2416
|
super({
|
|
2063
2417
|
id: "sessions.automations.disable",
|
|
2064
|
-
title: ( localize2(
|
|
2418
|
+
title: ( localize2(6091, "Disable")),
|
|
2065
2419
|
precondition: ( ContextKeyExpr.and(ChatAutomationsEnabledContext, AutomationCardCanUpdateContext)),
|
|
2066
2420
|
menu: [{
|
|
2067
2421
|
id: Menus.AutomationCardContext,
|
|
@@ -2079,7 +2433,7 @@ registerAction2(class EnableAutomationAction extends Action2 {
|
|
|
2079
2433
|
constructor() {
|
|
2080
2434
|
super({
|
|
2081
2435
|
id: "sessions.automations.enable",
|
|
2082
|
-
title: ( localize2(
|
|
2436
|
+
title: ( localize2(6092, "Enable")),
|
|
2083
2437
|
precondition: ( ContextKeyExpr.and(ChatAutomationsEnabledContext, AutomationCardCanUpdateContext)),
|
|
2084
2438
|
menu: [{
|
|
2085
2439
|
id: Menus.AutomationCardContext,
|
|
@@ -2095,7 +2449,7 @@ registerAction2(class EnableAutomationAction extends Action2 {
|
|
|
2095
2449
|
});
|
|
2096
2450
|
async function setAutomationEnabled(accessor, automation, enabled) {
|
|
2097
2451
|
const automationService = accessor.get(IAutomationService);
|
|
2098
|
-
if (automation.enabled === enabled || automationService.canUpdateAutomation
|
|
2452
|
+
if (automation.enabled === enabled || !automationService.canUpdateAutomation(automation.id)) {
|
|
2099
2453
|
return;
|
|
2100
2454
|
}
|
|
2101
2455
|
const configurationService = accessor.get(IConfigurationService);
|
|
@@ -2111,29 +2465,29 @@ async function setAutomationEnabled(accessor, automation, enabled) {
|
|
|
2111
2465
|
enabled
|
|
2112
2466
|
}, automation, () => {
|
|
2113
2467
|
if (!automationsEnabled()) {
|
|
2114
|
-
throw ( new Error(enabled ? ( localize(
|
|
2468
|
+
throw ( new Error(enabled ? ( localize(6093, "Automations were disabled before the automation could be enabled.")) : ( localize(6094, "Automations were disabled before the automation could be updated."))));
|
|
2115
2469
|
}
|
|
2116
2470
|
});
|
|
2117
2471
|
if (result.kind === "conflict") {
|
|
2118
|
-
throw ( new Error(result.current ? (enabled ? ( localize(
|
|
2472
|
+
throw ( new Error(result.current ? (enabled ? ( localize(6095, "This automation changed before it could be enabled. Try again.")) : ( localize(6096, "This automation changed before it could be disabled. Try again."))) : (enabled ? ( localize(6097, "This automation was deleted before it could be enabled.")) : ( localize(6098, "This automation was deleted before it could be disabled.")))));
|
|
2119
2473
|
}
|
|
2120
|
-
status(enabled ? ( localize(
|
|
2474
|
+
status(enabled ? ( localize(6099, "Enabled automation {0}", automation.name)) : ( localize(6100, "Disabled automation {0}", automation.name)));
|
|
2121
2475
|
} catch (error) {
|
|
2122
2476
|
logService.error(
|
|
2123
2477
|
enabled ? "[Automations] Failed to enable automation" : "[Automations] Failed to disable automation",
|
|
2124
2478
|
error
|
|
2125
2479
|
);
|
|
2126
|
-
await dialogService.error(enabled ? ( localize(
|
|
2480
|
+
await dialogService.error(enabled ? ( localize(6101, "Failed to enable automation.")) : ( localize(6102, "Failed to disable automation.")), getErrorMessage(error));
|
|
2127
2481
|
}
|
|
2128
2482
|
}
|
|
2129
2483
|
function getDuplicateAutomationName(name, automations) {
|
|
2130
2484
|
const existingNames = ( new Set(automations.map(automation => automation.name)));
|
|
2131
|
-
const copyName = ( localize(
|
|
2485
|
+
const copyName = ( localize(6103, "{0} Copy", name));
|
|
2132
2486
|
if (!( existingNames.has(copyName))) {
|
|
2133
2487
|
return copyName;
|
|
2134
2488
|
}
|
|
2135
2489
|
for (let index = 2; ; index++) {
|
|
2136
|
-
const indexedCopyName = ( localize(
|
|
2490
|
+
const indexedCopyName = ( localize(6104, "{0} Copy {1}", name, index));
|
|
2137
2491
|
if (!( existingNames.has(indexedCopyName))) {
|
|
2138
2492
|
return indexedCopyName;
|
|
2139
2493
|
}
|