@codingame/monaco-vscode-katex-common 31.0.1 → 32.0.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +2 -2
- package/vscode/src/vs/platform/actionWidget/browser/actionWidgetDropdown.d.ts +15 -3
- package/vscode/src/vs/platform/actionWidget/browser/actionWidgetDropdown.js +6 -5
- package/vscode/src/vs/platform/actions/browser/buttonbar.d.ts +5 -1
- package/vscode/src/vs/platform/actions/browser/buttonbar.js +45 -14
- package/vscode/src/vs/platform/sandbox/common/terminalSandboxService.d.ts +15 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/accessibility/chatAccessibilityProvider.js +16 -16
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatContinueInAction.js +15 -10
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatElicitationActions.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.js +51 -54
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.js +10 -10
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatToolActions.js +11 -11
- package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatToolPicker.js +13 -13
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionHoverWidget.d.ts +3 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionHoverWidget.js +45 -23
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsControl.js +13 -7
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsFilter.js +9 -9
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsOpener.js +5 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.d.ts +4 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.js +46 -32
- package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentModel.js +8 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentWidgets.d.ts +23 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentWidgets.js +155 -46
- package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatImplicitContext.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatImplicitContext.js +20 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/attachments/implicitContextAttachment.d.ts +4 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/attachments/implicitContextAttachment.js +37 -14
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingActions.js +34 -34
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessionPickerActionItem.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/chatSessions/media/chatSessionPickerActionItem.css +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/tools/chatToolRiskAssessmentService.d.ts +28 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/tools/chatToolRiskAssessmentService.js +250 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/tools/toolSetsContribution.js +13 -13
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatAgentHover.js +14 -11
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatArtifactsWidget.js +10 -10
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAgentCommandContentPart.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAnonymousRateLimitedPart.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAttachmentsContentPart.js +7 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatChangesSummaryPart.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCodeCitationContentPart.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCommandContentPart.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatConfirmationContentPart.js +7 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatConfirmationWidget.d.ts +12 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatConfirmationWidget.js +51 -20
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatDisabledClaudeHooksContentPart.js +3 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatElicitationContentPart.d.ts +6 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatElicitationContentPart.js +56 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatExtensionsContentPart.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatHookContentPart.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/paragraphBuffer.d.ts +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/paragraphBuffer.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/chatIncrementalRendering.d.ts +3 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/chatIncrementalRendering.js +4 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatInlineAnchorWidget.js +13 -13
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownContentPart.js +68 -10
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMcpServersInteractionContentPart.js +8 -8
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMultiDiffContentPart.js +4 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatPlanReviewPart.d.ts +58 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatPlanReviewPart.js +653 -75
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatProgressContentPart.js +28 -10
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuestionCarouselPart.d.ts +5 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuestionCarouselPart.js +91 -54
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuotaExceededPart.js +7 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatReferencesContentPart.js +53 -51
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatResourceGroupWidget.js +5 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSubagentContentPart.js +11 -11
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSuggestNextWidget.js +6 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTextEditContentPart.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingContentPart.d.ts +4 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingContentPart.js +42 -22
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTipContentPart.js +9 -9
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTodoListWidget.js +17 -17
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatToolInputOutputContentPart.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTreeContentPart.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatWorkspaceEditContentPart.js +3 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/codeBlockPart.d.ts +6 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/codeBlockPart.js +93 -35
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatConfirmationWidget.css +5 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatPlanReview.css +169 -27
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatQuestionCarousel.css +13 -4
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatThinkingContent.css +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatToolConfirmationCarousel.css +29 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/abstractToolConfirmationSubPart.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/abstractToolConfirmationSubPart.js +60 -15
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatExtensionsInstallToolSubPart.js +13 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatMcpAppModel.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatMcpAppSubPart.js +3 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatMissingSandboxDepsConfirmationSubPart.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatModifiedFilesConfirmationSubPart.js +15 -8
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolConfirmationSubPart.d.ts +6 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolConfirmationSubPart.js +125 -26
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolProgressPart.d.ts +2 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolProgressPart.js +29 -23
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolConfirmationCarouselPart.d.ts +14 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolConfirmationCarouselPart.js +119 -10
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolConfirmationSubPart.js +6 -6
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolInvocationPart.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolOutputPart.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPartUtilities.js +5 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPostExecuteConfirmationPart.js +5 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/media/toolRiskBadge.css +77 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/toolRiskBadgeWidget.d.ts +38 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/toolRiskBadgeWidget.js +125 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatDragAndDrop.js +11 -11
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.js +132 -59
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatWidget.d.ts +16 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatWidget.js +156 -67
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatFollowups.js +1 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputNotificationService.d.ts +55 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputNotificationService.js +93 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputNotificationWidget.d.ts +21 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputNotificationWidget.js +133 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputPart.d.ts +53 -8
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputPart.js +288 -125
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatModelPicker.d.ts +23 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatModelPicker.js +699 -145
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatModelSelectionLogic.d.ts +12 -8
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatModelSelectionLogic.js +12 -11
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatPhoneInputPresenter.d.ts +62 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatPhoneInputPresenter.js +120 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/delegationSessionPickerActionItem.js +5 -5
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/media/chatInputNotificationWidget.css +191 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/media/chatPhoneInputPresenter.css +22 -0
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/modePickerActionItem.d.ts +3 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/modePickerActionItem.js +9 -25
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/modelPickerActionItem.js +4 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/permissionPickerActionItem.d.ts +20 -1
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/permissionPickerActionItem.js +89 -108
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/sessionTargetPickerActionItem.js +3 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/workspacePickerActionItem.js +3 -3
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/media/chat.css +521 -9
- package/vscode/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/chatContextUsageDetails.js +7 -7
- package/vscode/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/chatContextUsageWidget.js +2 -2
- package/vscode/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/media/chatContextUsageDetails.css +19 -19
- package/vscode/src/vs/workbench/contrib/chat/common/chatImageExtraction.js +6 -6
- package/vscode/src/vs/workbench/contrib/chat/common/chatPermissionStorageKeys.d.ts +2 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatPermissionStorageKeys.js +6 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatPermissionWarnings.d.ts +27 -0
- package/vscode/src/vs/workbench/contrib/chat/common/chatPermissionWarnings.js +82 -0
- package/vscode/src/vs/workbench/contrib/chat/common/widget/chatColors.d.ts +3 -0
- package/vscode/src/vs/workbench/contrib/chat/common/widget/chatColors.js +44 -17
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAffordance.d.ts +1 -3
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAffordance.js +3 -46
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/{inlineChatEditorAffordance.d.ts → inlineChatAffordanceWidget.d.ts} +1 -1
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/{inlineChatEditorAffordance.js → inlineChatAffordanceWidget.js} +6 -6
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.d.ts +2 -18
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.js +19 -400
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionService.d.ts +4 -9
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionService.js +1 -1
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.d.ts +5 -19
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.js +47 -133
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatZoneWidget.d.ts +3 -1
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatZoneWidget.js +103 -25
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/media/inlineChat.css +29 -0
- package/vscode/src/vs/workbench/contrib/inlineChat/common/inlineChat.d.ts +3 -32
- package/vscode/src/vs/workbench/contrib/inlineChat/common/inlineChat.js +39 -92
- package/vscode/src/vs/workbench/contrib/interactive/browser/replInputHintContentWidget.js +3 -3
- package/vscode/src/vs/workbench/contrib/notebook/browser/contrib/cellStatusBar/executionStatusBarItemController.js +7 -7
- package/vscode/src/vs/workbench/contrib/notebook/browser/contrib/find/notebookFindWidget.js +2 -2
- package/vscode/src/vs/workbench/contrib/notebook/browser/controller/cellOperations.js +2 -2
- package/vscode/src/vs/workbench/contrib/notebook/browser/controller/insertCellActions.js +24 -24
- package/vscode/src/vs/workbench/contrib/notebook/browser/diff/diffComponents.js +3 -3
- package/vscode/src/vs/workbench/contrib/notebook/browser/diff/diffElementOutputs.js +7 -7
- package/vscode/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffEditor.js +1 -1
- package/vscode/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffEditorBrowser.js +5 -5
- package/vscode/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffList.js +1 -1
- package/vscode/src/vs/workbench/contrib/replNotebook/browser/replEditor.js +1 -1
- package/vscode/src/vs/workbench/contrib/replNotebook/browser/replEditorInput.js +1 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/basicExecuteStrategy.d.ts +7 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/basicExecuteStrategy.js +99 -32
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/executeStrategy.d.ts +13 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/executeStrategy.js +76 -14
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/noneExecuteStrategy.js +4 -3
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/richExecuteStrategy.d.ts +9 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/richExecuteStrategy.js +89 -28
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/outputHelpers.js +1 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalHelpers.d.ts +11 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalHelpers.js +11 -7
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalToolTelemetry.d.ts +3 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalToolTelemetry.js +7 -3
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/autoApprove/commandLineAutoApprover.js +1 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/autoApprove/npmScriptAutoApprover.js +1 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineAnalyzer.d.ts +1 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineAutoApproveAnalyzer.js +12 -12
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineFileWriteAnalyzer.d.ts +8 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineFileWriteAnalyzer.js +11 -2
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLineBackgroundDetachRewriter.d.ts +20 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLineBackgroundDetachRewriter.js +59 -4
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLineSandboxRewriter.d.ts +8 -1
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLineSandboxRewriter.js +24 -3
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/monitoring/outputMonitor.d.ts +47 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/monitoring/outputMonitor.js +111 -30
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.d.ts +60 -3
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.js +455 -171
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/treeSitterCommandParser.d.ts +33 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/treeSitterCommandParser.js +82 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxCommandRules.d.ts +31 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxCommandRules.js +49 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxReadAllowList.d.ts +18 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxReadAllowList.js +302 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxRuntimeConfigurationPerOperation.d.ts +7 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxRuntimeConfigurationPerOperation.js +118 -0
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxService.d.ts +34 -4
- package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxService.js +233 -48
- package/vscode/src/vs/platform/actions/browser/actionbar.d.ts +0 -16
- package/vscode/src/vs/platform/actions/browser/actionbar.js +0 -22
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorActions.d.ts +0 -46
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorActions.js +0 -539
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorOverlay.d.ts +0 -29
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorOverlay.js +0 -386
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingExplanationWidget.d.ts +0 -101
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingExplanationWidget.js +0 -509
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/media/chatEditingEditorOverlay.css +0 -130
- package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/media/chatEditingExplanationWidget.css +0 -276
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputPartWidgets.d.ts +0 -45
- package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputPartWidgets.js +0 -93
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatOverlayWidget.d.ts +0 -39
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatOverlayWidget.js +0 -617
- package/vscode/src/vs/workbench/contrib/inlineChat/browser/media/inlineChatOverlayWidget.css +0 -231
|
@@ -18,10 +18,12 @@ import { isNumber, isString } from '@codingame/monaco-vscode-api/vscode/vs/base/
|
|
|
18
18
|
import { URI } from '@codingame/monaco-vscode-api/vscode/vs/base/common/uri';
|
|
19
19
|
import { generateUuid } from '@codingame/monaco-vscode-api/vscode/vs/base/common/uuid';
|
|
20
20
|
import { localize } from '@codingame/monaco-vscode-api/vscode/vs/nls';
|
|
21
|
+
import { ConfirmationOptionKind } from '@codingame/monaco-vscode-api/vscode/vs/platform/agentHost/common/state/protocol/state';
|
|
21
22
|
import { IConfigurationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration.service';
|
|
22
23
|
import { IFileService } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service';
|
|
23
24
|
import { IInstantiationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation';
|
|
24
25
|
import { ILabelService } from '@codingame/monaco-vscode-api/vscode/vs/platform/label/common/label.service';
|
|
26
|
+
import { AgentSandboxSettingId } from '@codingame/monaco-vscode-api/vscode/vs/platform/sandbox/common/settings';
|
|
25
27
|
import { StorageScope, StorageTarget } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage';
|
|
26
28
|
import { IStorageService } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage.service';
|
|
27
29
|
import { TerminalCapability } from '@codingame/monaco-vscode-api/vscode/vs/platform/terminal/common/capabilities/capabilities';
|
|
@@ -83,7 +85,7 @@ const TERMINAL_SANDBOX_DOCUMENTATION_URL = "https://aka.ms/vscode-sandboxing";
|
|
|
83
85
|
const TOOL_REFERENCE_NAME = "runInTerminal";
|
|
84
86
|
const LEGACY_TOOL_REFERENCE_FULL_NAMES = ["runCommands/runInTerminal"];
|
|
85
87
|
const INPUT_NEEDED_NOTIFICATION_THROTTLE_MS = 5000;
|
|
86
|
-
function createPowerShellModelDescription(shell, isSandboxEnabled, networkDomains) {
|
|
88
|
+
function createPowerShellModelDescription(shell, isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains) {
|
|
87
89
|
const isWinPwsh = isWindowsPowerShell(shell);
|
|
88
90
|
const parts = [
|
|
89
91
|
`This tool allows you to execute ${isWinPwsh ? "Windows PowerShell 5.1" : "PowerShell"} commands in a persistent terminal session, preserving environment variables, working directory, and other context across multiple commands.`,
|
|
@@ -105,14 +107,15 @@ function createPowerShellModelDescription(shell, isSandboxEnabled, networkDomain
|
|
|
105
107
|
"- Use Get-Command to verify cmdlet/function availability",
|
|
106
108
|
"",
|
|
107
109
|
"Async Mode:",
|
|
108
|
-
"-
|
|
110
|
+
"- Use mode=async ONLY for processes that should keep running while you do other work (servers, watchers, dev daemons)",
|
|
111
|
+
"- For one-shot long-running commands where you have nothing to do until they finish (package installs, builds, downloads, test suites), use mode=sync with a generous timeout (e.g. 600000 / 10 min for installs, longer for big builds) so the command can complete before your turn ends",
|
|
109
112
|
"- Returns a terminal ID for checking status and runtime later",
|
|
110
113
|
"- Use Start-Job for background PowerShell jobs",
|
|
111
114
|
"",
|
|
112
115
|
`Use ${TerminalToolId.SendToTerminal} to send commands or input to a terminal session.`
|
|
113
116
|
];
|
|
114
117
|
if (isSandboxEnabled) {
|
|
115
|
-
parts.push(...createSandboxLines(networkDomains));
|
|
118
|
+
parts.push(...createSandboxLines(allowToRunUnsandboxedCommands, networkDomains));
|
|
116
119
|
}
|
|
117
120
|
parts.push(
|
|
118
121
|
"",
|
|
@@ -130,28 +133,37 @@ function createPowerShellModelDescription(shell, isSandboxEnabled, networkDomain
|
|
|
130
133
|
"- Use Test-Path to check file/directory existence",
|
|
131
134
|
"- Be specific with Select-Object properties to avoid excessive output",
|
|
132
135
|
"- Avoid printing credentials unless absolutely required",
|
|
133
|
-
`- NEVER run Start-Sleep or similar wait commands. You will be automatically notified on your next turn when async terminal commands or timed-out sync commands complete or need input.
|
|
136
|
+
`- NEVER run Start-Sleep or similar wait commands. You will be automatically notified on your next turn when async terminal commands or timed-out sync commands complete or need input. Do NOT poll for completion.`,
|
|
134
137
|
"",
|
|
135
138
|
"Interactive Input Handling:",
|
|
136
139
|
"- When a terminal command is waiting for interactive input, do NOT suggest alternatives or ask the user whether to proceed. Instead, use the vscode_askQuestions tool to collect the needed values from the user, then send them.",
|
|
140
|
+
`- NEVER use vscode_askQuestions to request sensitive input such as passwords, passphrases, API keys, tokens, or other secrets — answers to that tool are sent through the model. If the prompt requires a secret, tell the user to type it directly into the terminal and stop; do not call vscode_askQuestions or ${TerminalToolId.SendToTerminal} for that prompt.`,
|
|
137
141
|
`- Send exactly one answer per prompt using ${TerminalToolId.SendToTerminal}. Never send multiple answers in a single send.`,
|
|
138
142
|
`- After each send, call ${TerminalToolId.GetTerminalOutput} to read the next prompt before sending the next answer.`,
|
|
139
143
|
"- Continue one prompt at a time until the command finishes."
|
|
140
144
|
);
|
|
141
145
|
return parts.join("\n");
|
|
142
146
|
}
|
|
143
|
-
function createSandboxLines(networkDomains) {
|
|
147
|
+
function createSandboxLines(allowToRunUnsandboxedCommands, networkDomains) {
|
|
144
148
|
const lines = [
|
|
145
149
|
"",
|
|
146
150
|
"Sandboxing:",
|
|
147
151
|
"- ATTENTION: Terminal sandboxing is enabled, commands run in a sandbox by default",
|
|
148
152
|
"- When executing commands within the sandboxed environment, all operations requiring a temporary directory must utilize the $TMPDIR environment variable. The /tmp directory is not guaranteed to be accessible or writable and must be avoided",
|
|
149
|
-
"- Tools and scripts should respect the TMPDIR environment variable, which is automatically set to an appropriate path within the sandbox"
|
|
150
|
-
"- When a command fails due to sandbox restrictions, immediately re-run it with requestUnsandboxedExecution=true. Do NOT ask the user for permission — setting this flag automatically shows a confirmation prompt to the user",
|
|
151
|
-
"- Only set requestUnsandboxedExecution=true when there is evidence of failures caused by the sandbox, e.g. 'Operation not permitted' errors, network failures, or file access errors, etc",
|
|
152
|
-
"- Do NOT set requestUnsandboxedExecution=true without first executing the command in sandbox mode. Always try the command in the sandbox first, and only set requestUnsandboxedExecution=true when retrying after that sandboxed execution failed due to sandbox restrictions.",
|
|
153
|
-
"- When setting requestUnsandboxedExecution=true, also provide requestUnsandboxedExecutionReason explaining why the command needs unsandboxed access"
|
|
153
|
+
"- Tools and scripts should respect the TMPDIR environment variable, which is automatically set to an appropriate path within the sandbox"
|
|
154
154
|
];
|
|
155
|
+
if (allowToRunUnsandboxedCommands) {
|
|
156
|
+
lines.push(
|
|
157
|
+
"- When a command fails due to sandbox restrictions, immediately re-run it with requestUnsandboxedExecution=true. Do NOT ask the user for permission — setting this flag automatically shows a confirmation prompt to the user",
|
|
158
|
+
"- Only set requestUnsandboxedExecution=true when there is evidence of failures caused by the sandbox, e.g. 'Operation not permitted' errors, network failures, or file access errors, etc",
|
|
159
|
+
"- Do NOT set requestUnsandboxedExecution=true without first executing the command in sandbox mode. Always try the command in the sandbox first, and only set requestUnsandboxedExecution=true when retrying after that sandboxed execution failed due to sandbox restrictions.",
|
|
160
|
+
"- When setting requestUnsandboxedExecution=true, also provide requestUnsandboxedExecutionReason explaining why the command needs unsandboxed access"
|
|
161
|
+
);
|
|
162
|
+
} else {
|
|
163
|
+
lines.push(
|
|
164
|
+
"- Running commands outside the sandbox is disabled by the current chat.agent.sandbox.allowUnsandboxedCommands setting. Do not set requestUnsandboxedExecution=true."
|
|
165
|
+
);
|
|
166
|
+
}
|
|
155
167
|
if (networkDomains) {
|
|
156
168
|
const deniedSet = ( new Set(networkDomains.deniedDomains));
|
|
157
169
|
const effectiveAllowed = networkDomains.allowedDomains.filter(d => !( deniedSet.has(d)));
|
|
@@ -170,7 +182,7 @@ function createSandboxLines(networkDomains) {
|
|
|
170
182
|
}
|
|
171
183
|
return lines;
|
|
172
184
|
}
|
|
173
|
-
function createGenericDescription(isSandboxEnabled, networkDomains) {
|
|
185
|
+
function createGenericDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains) {
|
|
174
186
|
const parts = [`
|
|
175
187
|
Command Execution:
|
|
176
188
|
- Use && to chain simple commands on one line
|
|
@@ -190,12 +202,15 @@ Program Execution:
|
|
|
190
202
|
- Use which or command -v to verify command availability
|
|
191
203
|
|
|
192
204
|
Async Mode:
|
|
193
|
-
-
|
|
205
|
+
- Use mode=async ONLY for processes that should keep running while you do other work (servers, watchers, dev daemons)
|
|
206
|
+
- For one-shot long-running commands where you have nothing to do until they finish (package installs, builds, downloads, test suites), use mode=sync with a generous timeout (e.g. 600000 / 10 min for installs, longer for big builds) so the command can complete before your turn ends
|
|
194
207
|
- Returns a terminal ID for checking status and runtime later
|
|
195
208
|
|
|
196
209
|
Use ${TerminalToolId.SendToTerminal} to send commands or input to a terminal session.`];
|
|
197
210
|
if (isSandboxEnabled) {
|
|
198
|
-
parts.push(
|
|
211
|
+
parts.push(
|
|
212
|
+
createSandboxLines(allowToRunUnsandboxedCommands, networkDomains).join("\n")
|
|
213
|
+
);
|
|
199
214
|
}
|
|
200
215
|
parts.push(`
|
|
201
216
|
|
|
@@ -210,68 +225,69 @@ Best Practices:
|
|
|
210
225
|
- Use find with -exec or xargs for file operations
|
|
211
226
|
- Be specific with commands to avoid excessive output
|
|
212
227
|
- Avoid printing credentials unless absolutely required
|
|
213
|
-
- NEVER run sleep or similar wait commands in a terminal. You will be automatically notified on your next turn when async terminal commands or timed-out sync commands complete or need input.
|
|
228
|
+
- NEVER run sleep or similar wait commands in a terminal. You will be automatically notified on your next turn when async terminal commands or timed-out sync commands complete or need input. Do NOT poll for completion.
|
|
214
229
|
|
|
215
230
|
Interactive Input Handling:
|
|
216
231
|
- When a terminal command is waiting for interactive input, do NOT suggest alternatives or ask the user whether to proceed. Instead, use the vscode_askQuestions tool to collect the needed values from the user, then send them.
|
|
232
|
+
- NEVER use vscode_askQuestions to request sensitive input such as passwords, passphrases, API keys, tokens, or other secrets — answers to that tool are sent through the model. If the prompt requires a secret, tell the user to type it directly into the terminal and stop; do not call vscode_askQuestions or send_to_terminal for that prompt.
|
|
217
233
|
- Send exactly one answer per prompt using ${TerminalToolId.SendToTerminal}. Never send multiple answers in a single send.
|
|
218
234
|
- After each send, call ${TerminalToolId.GetTerminalOutput} to read the next prompt before sending the next answer.
|
|
219
235
|
- Continue one prompt at a time until the command finishes.`);
|
|
220
236
|
return parts.join("");
|
|
221
237
|
}
|
|
222
|
-
function createBashModelDescription(isSandboxEnabled, networkDomains) {
|
|
238
|
+
function createBashModelDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains) {
|
|
223
239
|
return [
|
|
224
240
|
"This tool allows you to execute shell commands in a persistent bash terminal session, preserving environment variables, working directory, and other context across multiple commands.",
|
|
225
|
-
createGenericDescription(isSandboxEnabled, networkDomains),
|
|
241
|
+
createGenericDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains),
|
|
226
242
|
"- Use [[ ]] for conditional tests instead of [ ]",
|
|
227
|
-
"- Prefer $() over backticks for command substitution"
|
|
228
|
-
"- Use set -e at start of complex commands to exit on errors"
|
|
243
|
+
"- Prefer $() over backticks for command substitution"
|
|
229
244
|
].join("\n");
|
|
230
245
|
}
|
|
231
|
-
function createZshModelDescription(isSandboxEnabled, networkDomains) {
|
|
246
|
+
function createZshModelDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains) {
|
|
232
247
|
return [
|
|
233
248
|
"This tool allows you to execute shell commands in a persistent zsh terminal session, preserving environment variables, working directory, and other context across multiple commands.",
|
|
234
|
-
createGenericDescription(isSandboxEnabled, networkDomains),
|
|
249
|
+
createGenericDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains),
|
|
235
250
|
"- Use type to check command type (builtin, function, alias)",
|
|
236
251
|
"- Use jobs, fg, bg for job control",
|
|
237
252
|
"- Use [[ ]] for conditional tests instead of [ ]",
|
|
238
253
|
"- Prefer $() over backticks for command substitution",
|
|
239
|
-
"- Use setopt errexit for strict error handling",
|
|
240
254
|
"- Take advantage of zsh globbing features (**, extended globs)"
|
|
241
255
|
].join("\n");
|
|
242
256
|
}
|
|
243
|
-
function createFishModelDescription(isSandboxEnabled, networkDomains) {
|
|
257
|
+
function createFishModelDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains) {
|
|
244
258
|
return [
|
|
245
259
|
"This tool allows you to execute shell commands in a persistent fish terminal session, preserving environment variables, working directory, and other context across multiple commands.",
|
|
246
|
-
createGenericDescription(isSandboxEnabled, networkDomains),
|
|
260
|
+
createGenericDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains),
|
|
247
261
|
"- Use type to check command type (builtin, function, alias)",
|
|
248
262
|
"- Use jobs, fg, bg for job control",
|
|
249
263
|
"- Use test expressions for conditionals (no [[ ]] syntax)",
|
|
250
264
|
"- Prefer command substitution with () syntax",
|
|
251
265
|
"- Variables are arrays by default, use $var[1] for first element",
|
|
252
|
-
"- Use set -e for strict error handling",
|
|
253
266
|
"- Take advantage of fish's autosuggestions and completions"
|
|
254
267
|
].join("\n");
|
|
255
268
|
}
|
|
256
269
|
async function createRunInTerminalToolData(accessor) {
|
|
257
270
|
const instantiationService = accessor.get(IInstantiationService);
|
|
258
271
|
const terminalSandboxService = accessor.get(ITerminalSandboxService);
|
|
272
|
+
const configurationService = accessor.get(IConfigurationService);
|
|
273
|
+
const allowToRunUnsandboxedCommands = configurationService.getValue(AgentSandboxSettingId.AgentSandboxAllowUnsandboxedCommands) === true;
|
|
259
274
|
const profileFetcher = instantiationService.createInstance(TerminalProfileFetcher);
|
|
260
|
-
const [shell, os, isSandboxEnabled] = await Promise.all([
|
|
275
|
+
const [shell, os, isSandboxEnabled, isSandboxAllowNetworkEnabled] = await Promise.all([
|
|
261
276
|
profileFetcher.getCopilotShell(),
|
|
262
277
|
profileFetcher.osBackend,
|
|
263
|
-
terminalSandboxService.isEnabled()
|
|
278
|
+
terminalSandboxService.isEnabled(),
|
|
279
|
+
terminalSandboxService.isSandboxAllowNetworkEnabled()
|
|
264
280
|
]);
|
|
265
|
-
const networkDomains = isSandboxEnabled ? terminalSandboxService.getResolvedNetworkDomains() : undefined;
|
|
281
|
+
const networkDomains = isSandboxEnabled && !isSandboxAllowNetworkEnabled ? terminalSandboxService.getResolvedNetworkDomains() : undefined;
|
|
266
282
|
let modelDescription;
|
|
267
283
|
if (shell && os && isPowerShell(shell, os)) {
|
|
268
|
-
modelDescription = createPowerShellModelDescription(shell, isSandboxEnabled, networkDomains);
|
|
284
|
+
modelDescription = createPowerShellModelDescription(shell, isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains);
|
|
269
285
|
} else if (shell && os && isZsh(shell, os)) {
|
|
270
|
-
modelDescription = createZshModelDescription(isSandboxEnabled, networkDomains);
|
|
286
|
+
modelDescription = createZshModelDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains);
|
|
271
287
|
} else if (shell && os && isFish(shell, os)) {
|
|
272
|
-
modelDescription = createFishModelDescription(isSandboxEnabled, networkDomains);
|
|
288
|
+
modelDescription = createFishModelDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains);
|
|
273
289
|
} else {
|
|
274
|
-
modelDescription = createBashModelDescription(isSandboxEnabled, networkDomains);
|
|
290
|
+
modelDescription = createBashModelDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains);
|
|
275
291
|
}
|
|
276
292
|
const sharedProperties = {
|
|
277
293
|
command: {
|
|
@@ -288,6 +304,12 @@ async function createRunInTerminalToolData(accessor) {
|
|
|
288
304
|
}
|
|
289
305
|
};
|
|
290
306
|
const sandboxProperties = isSandboxEnabled ? {
|
|
307
|
+
allowToRunUnsandboxedCommands: {
|
|
308
|
+
type: "boolean",
|
|
309
|
+
const: allowToRunUnsandboxedCommands,
|
|
310
|
+
default: allowToRunUnsandboxedCommands,
|
|
311
|
+
description: "Whether this tool invocation is allowed to run commands outside the terminal sandbox. This value is set by VS Code based on chat.agent.sandbox.allowUnsandboxedCommands."
|
|
312
|
+
},
|
|
291
313
|
requestUnsandboxedExecution: {
|
|
292
314
|
type: "boolean",
|
|
293
315
|
description: "Request that this command run outside the terminal sandbox. Only set this after first executing the command in sandbox and observing that sandboxing caused the failure. The user will be prompted before the command runs unsandboxed."
|
|
@@ -301,9 +323,9 @@ async function createRunInTerminalToolData(accessor) {
|
|
|
301
323
|
id: TerminalToolId.RunInTerminal,
|
|
302
324
|
toolReferenceName: TOOL_REFERENCE_NAME,
|
|
303
325
|
legacyToolReferenceFullNames: LEGACY_TOOL_REFERENCE_FULL_NAMES,
|
|
304
|
-
displayName: ( localize(
|
|
305
|
-
modelDescription: `${modelDescription}\n\nExecution mode:\n- mode='sync': wait for completion
|
|
306
|
-
userDescription: ( localize(
|
|
326
|
+
displayName: ( localize(14352, "Run in Terminal")),
|
|
327
|
+
modelDescription: `${modelDescription}\n\nExecution mode:\n- mode='sync': wait for completion (optionally capped by timeout); if still running when timeout elapses, return with a terminal ID.\n- mode='async': wait for an initial idle/output signal, then return with terminal output snapshot and ID. Timeout caps how long to wait for the initial idle/output signal.\n- Prefer mode='sync' for commands that will prompt for interactive input (e.g., npm init, interactive installers, configuration wizards).\n\nTimeout parameter: For one-shot long-running commands, set a generous timeout as a safety net (e.g. 600000 for installs, longer for big builds). Omit timeout only for processes that should run indefinitely (servers, daemons). If the timeout elapses, you get a terminal ID and can check output later.\n\nTerminal notifications: When an async command finishes or a sync command times out, you will be automatically notified on your next turn with the exit code and terminal output. You will also be notified if the terminal needs input. Do NOT poll or sleep to wait for completion.`,
|
|
328
|
+
userDescription: ( localize(14353, "Run commands in the terminal")),
|
|
307
329
|
source: ToolDataSource.Internal,
|
|
308
330
|
icon: Codicon.terminal,
|
|
309
331
|
inputSchema: {
|
|
@@ -326,10 +348,10 @@ async function createRunInTerminalToolData(accessor) {
|
|
|
326
348
|
},
|
|
327
349
|
timeout: {
|
|
328
350
|
type: "number",
|
|
329
|
-
description: "
|
|
351
|
+
description: "Optional hard cap in milliseconds on how long the tool tracks the command before returning. Omit to let the command run to completion (recommended for package installs, builds, and long-running scripts). Use 0 to explicitly indicate no timeout."
|
|
330
352
|
}
|
|
331
353
|
},
|
|
332
|
-
required: ["command", "explanation", "goal", "mode"
|
|
354
|
+
required: ["command", "explanation", "goal", "mode"]
|
|
333
355
|
}
|
|
334
356
|
};
|
|
335
357
|
}
|
|
@@ -338,12 +360,12 @@ var TerminalToolStorageKeysInternal;
|
|
|
338
360
|
TerminalToolStorageKeysInternal["TerminalSession"] = "chat.terminalSessions";
|
|
339
361
|
})(TerminalToolStorageKeysInternal || (TerminalToolStorageKeysInternal = {}));
|
|
340
362
|
function shouldAutomaticallyRetryUnsandboxed(options) {
|
|
341
|
-
return options.didSandboxWrapCommand && options.requestUnsandboxedExecution !== true && !options.isPersistentSession && !options.isBackgroundExecution && !options.didTimeout && options.exitCode !== 0 && outputLooksSandboxBlocked(options.output);
|
|
363
|
+
return options.allowUnsandboxedCommands && options.didSandboxWrapCommand && options.requestUnsandboxedExecution !== true && !options.isPersistentSession && !options.isBackgroundExecution && !options.didTimeout && options.exitCode !== 0 && outputLooksSandboxBlocked(options.output);
|
|
342
364
|
}
|
|
343
365
|
const telemetryIgnoredSequences = [
|
|
344
366
|
"\u001b[I",
|
|
345
367
|
"\u001b[O"];
|
|
346
|
-
const altBufferMessage = "\n" + ( localize(
|
|
368
|
+
const altBufferMessage = "\n" + ( localize(14354, "The command opened the alternate buffer."));
|
|
347
369
|
let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
348
370
|
static {
|
|
349
371
|
RunInTerminalTool_1 = this;
|
|
@@ -351,6 +373,9 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
351
373
|
static {
|
|
352
374
|
this._activeExecutions = ( new Map());
|
|
353
375
|
}
|
|
376
|
+
static {
|
|
377
|
+
this._killedByTool = ( new Set());
|
|
378
|
+
}
|
|
354
379
|
static getBackgroundOutput(id) {
|
|
355
380
|
const execution = RunInTerminalTool_1._activeExecutions.get(id);
|
|
356
381
|
if (!execution) {
|
|
@@ -370,6 +395,9 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
370
395
|
RunInTerminalTool_1._activeExecutions.delete(id);
|
|
371
396
|
return true;
|
|
372
397
|
}
|
|
398
|
+
static markKilledByTool(id) {
|
|
399
|
+
RunInTerminalTool_1._killedByTool.add(id);
|
|
400
|
+
}
|
|
373
401
|
_resolveExecutionOptions(args) {
|
|
374
402
|
const mode = args.mode ?? (args.isBackground ? "async" : "sync");
|
|
375
403
|
switch (mode) {
|
|
@@ -388,6 +416,27 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
388
416
|
};
|
|
389
417
|
}
|
|
390
418
|
}
|
|
419
|
+
get _allowUnsandboxedCommands() {
|
|
420
|
+
return this._configurationService.getValue(AgentSandboxSettingId.AgentSandboxAllowUnsandboxedCommands) === true;
|
|
421
|
+
}
|
|
422
|
+
get _autoApproveUnsandboxedCommands() {
|
|
423
|
+
return this._allowUnsandboxedCommands && this._configurationService.getValue(AgentSandboxSettingId.AgentSandboxAutoApproveUnsandboxedCommands) === true;
|
|
424
|
+
}
|
|
425
|
+
get _allowSandboxAutoApprove() {
|
|
426
|
+
return this._configurationService.getValue(AgentSandboxSettingId.AgentSandboxAllowAutoApprove) === true;
|
|
427
|
+
}
|
|
428
|
+
_getAllowToRunUnsandboxedCommands(args) {
|
|
429
|
+
return (args.allowToRunUnsandboxedCommands ?? this._allowUnsandboxedCommands) === true && this._allowUnsandboxedCommands;
|
|
430
|
+
}
|
|
431
|
+
_shouldRejectUnsandboxedExecutionRequest(isSandboxEnabled, allowUnsandboxedCommands, args) {
|
|
432
|
+
return isSandboxEnabled && args.requestUnsandboxedExecution === true && !allowUnsandboxedCommands;
|
|
433
|
+
}
|
|
434
|
+
_getUnsandboxedExecutionDisabledMessage() {
|
|
435
|
+
return localize(
|
|
436
|
+
14355,
|
|
437
|
+
"The command was not executed because it requested to run outside the terminal sandbox, but running commands outside the sandbox is disabled by chat.agent.sandbox.allowUnsandboxedCommands. Run the command in the sandbox instead, or enable the setting to allow unsandboxed execution."
|
|
438
|
+
);
|
|
439
|
+
}
|
|
391
440
|
get _enableCommandLineSandboxRewriting() {
|
|
392
441
|
return true;
|
|
393
442
|
}
|
|
@@ -444,9 +493,9 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
444
493
|
)
|
|
445
494
|
];
|
|
446
495
|
if (this._enableCommandLineSandboxRewriting) {
|
|
447
|
-
this._commandLineRewriters.push(
|
|
448
|
-
this.
|
|
449
|
-
);
|
|
496
|
+
this._commandLineRewriters.push(this._register(
|
|
497
|
+
this._instantiationService.createInstance(CommandLineSandboxRewriter, this._treeSitterCommandParser)
|
|
498
|
+
));
|
|
450
499
|
}
|
|
451
500
|
this._commandLineRewriters.push(this._register(
|
|
452
501
|
this._instantiationService.createInstance(CommandLineBackgroundDetachRewriter)
|
|
@@ -504,13 +553,13 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
504
553
|
const partialInput = context.rawInput;
|
|
505
554
|
if (partialInput && typeof partialInput === "object" && partialInput.command) {
|
|
506
555
|
const truncatedCommand = buildCommandDisplayText(partialInput.command);
|
|
507
|
-
const invocationMessage = ( new MarkdownString(( localize(
|
|
556
|
+
const invocationMessage = ( new MarkdownString(( localize(14356, "Running `{0}`", escapeMarkdownSyntaxTokens(truncatedCommand)))));
|
|
508
557
|
return {
|
|
509
558
|
invocationMessage
|
|
510
559
|
};
|
|
511
560
|
}
|
|
512
561
|
return {
|
|
513
|
-
invocationMessage: ( localize(
|
|
562
|
+
invocationMessage: ( localize(14357, "Running command"))
|
|
514
563
|
};
|
|
515
564
|
}
|
|
516
565
|
async prepareToolInvocation(context, token) {
|
|
@@ -527,26 +576,58 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
527
576
|
const [os, shell, cwd, sandboxPrereqs] = await Promise.all([this._osBackend, this._profileFetcher.getCopilotShell(), (async () => {
|
|
528
577
|
let cwd = await instance?.getCwdResource();
|
|
529
578
|
if (!cwd) {
|
|
530
|
-
const
|
|
531
|
-
|
|
532
|
-
|
|
579
|
+
const sessionModel = chatSessionResource ? this._chatService.getSession(chatSessionResource) : undefined;
|
|
580
|
+
if (sessionModel?.workingDirectory) {
|
|
581
|
+
cwd = sessionModel.workingDirectory;
|
|
582
|
+
} else {
|
|
583
|
+
const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot();
|
|
584
|
+
const workspaceFolder = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) ?? undefined : undefined;
|
|
585
|
+
cwd = workspaceFolder?.uri;
|
|
586
|
+
}
|
|
533
587
|
}
|
|
534
588
|
return cwd;
|
|
535
589
|
})(), this._terminalSandboxService.checkForSandboxingPrereqs()]);
|
|
536
590
|
const language = os === OperatingSystem.Windows ? "pwsh" : "sh";
|
|
537
|
-
const
|
|
538
|
-
const
|
|
591
|
+
const isSandboxEnabled = sandboxPrereqs.enabled;
|
|
592
|
+
const allowUnsandboxedCommands = this._getAllowToRunUnsandboxedCommands(args);
|
|
593
|
+
const explicitUnsandboxRequest = isSandboxEnabled && allowUnsandboxedCommands && args.requestUnsandboxedExecution === true;
|
|
539
594
|
let requiresUnsandboxConfirmation = explicitUnsandboxRequest;
|
|
540
595
|
let requestUnsandboxedExecutionReason = explicitUnsandboxRequest ? args.requestUnsandboxedExecutionReason : undefined;
|
|
541
596
|
const missingDependencies = sandboxPrereqs.failedCheck === TerminalSandboxPrerequisiteCheck.Dependencies && sandboxPrereqs.missingDependencies?.length ? sandboxPrereqs.missingDependencies : undefined;
|
|
542
597
|
const terminalToolSessionId = generateUuid();
|
|
543
598
|
const terminalCommandId = `tool-${generateUuid()}`;
|
|
599
|
+
if (this._shouldRejectUnsandboxedExecutionRequest(isSandboxEnabled, allowUnsandboxedCommands, args)) {
|
|
600
|
+
const commandToDisplay = normalizeTerminalCommandForDisplay(args.command);
|
|
601
|
+
return {
|
|
602
|
+
invocationMessage: ( new MarkdownString(( localize(
|
|
603
|
+
14358,
|
|
604
|
+
"Not running `{0}` because unsandboxed execution is disabled",
|
|
605
|
+
escapeMarkdownSyntaxTokens(buildCommandDisplayText(commandToDisplay))
|
|
606
|
+
)))),
|
|
607
|
+
icon: Codicon.error,
|
|
608
|
+
confirmationMessages: undefined,
|
|
609
|
+
toolSpecificData: {
|
|
610
|
+
kind: "terminal",
|
|
611
|
+
terminalToolSessionId,
|
|
612
|
+
terminalCommandId,
|
|
613
|
+
commandLine: {
|
|
614
|
+
original: args.command,
|
|
615
|
+
forDisplay: commandToDisplay
|
|
616
|
+
},
|
|
617
|
+
cwd,
|
|
618
|
+
language,
|
|
619
|
+
isBackground: executionOptions.persistentSession,
|
|
620
|
+
requestUnsandboxedExecution: false,
|
|
621
|
+
requestUnsandboxedExecutionReason: undefined
|
|
622
|
+
}
|
|
623
|
+
};
|
|
624
|
+
}
|
|
544
625
|
const rewriteResult = await this._rewriteCommandLine(args.command, {
|
|
545
626
|
cwd,
|
|
546
627
|
shell,
|
|
547
628
|
os,
|
|
548
629
|
isBackground: executionOptions.persistentSession,
|
|
549
|
-
requestUnsandboxedExecution: requiresUnsandboxConfirmation,
|
|
630
|
+
requestUnsandboxedExecution: allowUnsandboxedCommands ? requiresUnsandboxConfirmation : false,
|
|
550
631
|
requestUnsandboxedExecutionReason
|
|
551
632
|
});
|
|
552
633
|
const rewrittenCommand = rewriteResult.rewrittenCommand;
|
|
@@ -576,13 +657,21 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
576
657
|
if (missingDependencies) {
|
|
577
658
|
const depsList = missingDependencies.join(", ");
|
|
578
659
|
sandboxConfirmationMessageForMissingDeps = {
|
|
579
|
-
title: ( localize(
|
|
660
|
+
title: ( localize(14359, "Missing Sandbox Dependencies")),
|
|
580
661
|
message: ( new MarkdownString(( localize(
|
|
581
|
-
|
|
662
|
+
14360,
|
|
582
663
|
"The following dependencies required for sandboxed execution are not installed: {0}. Would you like to install them?",
|
|
583
664
|
depsList
|
|
584
665
|
)))),
|
|
585
|
-
|
|
666
|
+
customOptions: [{
|
|
667
|
+
id: "install",
|
|
668
|
+
label: ( localize(14361, "Install")),
|
|
669
|
+
kind: ConfirmationOptionKind.Approve
|
|
670
|
+
}, {
|
|
671
|
+
id: "cancel",
|
|
672
|
+
label: ( localize(14362, "Cancel")),
|
|
673
|
+
kind: ConfirmationOptionKind.Deny
|
|
674
|
+
}]
|
|
586
675
|
};
|
|
587
676
|
}
|
|
588
677
|
const alternativeRecommendation = getRecommendedToolsOverRunInTerminal(args.command, this._languageModelToolsService);
|
|
@@ -615,7 +704,8 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
615
704
|
treeSitterLanguage: isPowerShell(shell, os) ? TreeSitterCommandParserLanguage.PowerShell : TreeSitterCommandParserLanguage.Bash,
|
|
616
705
|
terminalToolSessionId,
|
|
617
706
|
chatSessionResource,
|
|
618
|
-
requiresUnsandboxConfirmation
|
|
707
|
+
requiresUnsandboxConfirmation,
|
|
708
|
+
hasSessionAutoApproval: !!chatSessionResource && this._terminalChatService.hasChatSessionAutoApproval(chatSessionResource)
|
|
619
709
|
};
|
|
620
710
|
const isSessionAutoApproved = chatSessionResource && isSessionAutoApproveLevel(
|
|
621
711
|
chatSessionResource,
|
|
@@ -653,7 +743,9 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
653
743
|
const isAutoApprovedByRules =
|
|
654
744
|
(isAutoApproveAllowed &&
|
|
655
745
|
wouldBeAutoApproved);
|
|
656
|
-
const
|
|
746
|
+
const isUnsandboxedAutoApproved = isSandboxEnabled && requiresUnsandboxConfirmation === true && this._autoApproveUnsandboxedCommands;
|
|
747
|
+
const isSandboxAutoApproved = isSandboxEnabled && toolSpecificData.commandLine.isSandboxWrapped === true && this._allowSandboxAutoApprove;
|
|
748
|
+
const isFinalAutoApproved = isUnsandboxedAutoApproved || isSandboxAutoApproved || isAutoApprovedByRules || ( commandLineAnalyzerResults.some(e => e.forceAutoApproval));
|
|
657
749
|
if (isFinalAutoApproved || (isAutoApproveEnabled && ( commandLineAnalyzerResults.some(e => e.autoApproveInfo)))) {
|
|
658
750
|
toolSpecificData.autoApproveInfo = commandLineAnalyzerResults.find(e => e.autoApproveInfo)?.autoApproveInfo;
|
|
659
751
|
}
|
|
@@ -674,12 +766,12 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
674
766
|
cwdLabel: directoryLabel,
|
|
675
767
|
cdPrefix
|
|
676
768
|
};
|
|
677
|
-
confirmationTitle = ( localize(
|
|
769
|
+
confirmationTitle = ( localize(14363, "Run `{0}` command within `{1}`?", shellType, directoryLabel));
|
|
678
770
|
} else {
|
|
679
771
|
toolSpecificData.confirmation = {
|
|
680
772
|
commandLine: commandToDisplay
|
|
681
773
|
};
|
|
682
|
-
confirmationTitle = ( localize(
|
|
774
|
+
confirmationTitle = ( localize(14364, "Run `{0}` command?", shellType));
|
|
683
775
|
}
|
|
684
776
|
const commandForPresenter = extractedCd?.command ?? commandToDisplay;
|
|
685
777
|
let presenterInput = commandForPresenter;
|
|
@@ -700,7 +792,7 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
700
792
|
if (extractedCd && toolSpecificData.confirmation?.cwdLabel) {
|
|
701
793
|
if (presenterResult.languageDisplayName) {
|
|
702
794
|
confirmationTitle = ( localize(
|
|
703
|
-
|
|
795
|
+
14365,
|
|
704
796
|
"Run `{0}` command in `{1}` within `{2}`?",
|
|
705
797
|
presenterResult.languageDisplayName,
|
|
706
798
|
shellType,
|
|
@@ -708,7 +800,7 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
708
800
|
));
|
|
709
801
|
} else {
|
|
710
802
|
confirmationTitle = ( localize(
|
|
711
|
-
|
|
803
|
+
14366,
|
|
712
804
|
"Run command in `{0}` within `{1}`?",
|
|
713
805
|
shellType,
|
|
714
806
|
toolSpecificData.confirmation.cwdLabel
|
|
@@ -717,13 +809,13 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
717
809
|
} else {
|
|
718
810
|
if (presenterResult.languageDisplayName) {
|
|
719
811
|
confirmationTitle = ( localize(
|
|
720
|
-
|
|
812
|
+
14367,
|
|
721
813
|
"Run `{0}` command in `{1}`?",
|
|
722
814
|
presenterResult.languageDisplayName,
|
|
723
815
|
shellType
|
|
724
816
|
));
|
|
725
817
|
} else {
|
|
726
|
-
confirmationTitle = ( localize(
|
|
818
|
+
confirmationTitle = ( localize(14368, "Run command in `{0}`?", shellType));
|
|
727
819
|
}
|
|
728
820
|
}
|
|
729
821
|
if (!presenterResult.processOtherPresenters) {
|
|
@@ -734,29 +826,28 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
734
826
|
}
|
|
735
827
|
if (requiresUnsandboxConfirmation) {
|
|
736
828
|
confirmationTitle = blockedDomains?.length ? ( localize(
|
|
737
|
-
|
|
829
|
+
14369,
|
|
738
830
|
"Run `{0}` command outside the [sandbox]({1}) to access {2}?",
|
|
739
831
|
shellType,
|
|
740
832
|
TERMINAL_SANDBOX_DOCUMENTATION_URL,
|
|
741
833
|
this._formatBlockedDomainsForTitle(blockedDomains)
|
|
742
834
|
)) : ( localize(
|
|
743
|
-
|
|
835
|
+
14370,
|
|
744
836
|
"Run `{0}` command outside the [sandbox]({1})?",
|
|
745
837
|
shellType,
|
|
746
838
|
TERMINAL_SANDBOX_DOCUMENTATION_URL
|
|
747
839
|
));
|
|
748
840
|
}
|
|
749
841
|
const shouldShowConfirmation = (!isFinalAutoApproved && !isSessionAutoApproved) || context.forceConfirmationReason !== undefined;
|
|
750
|
-
|
|
751
|
-
const
|
|
752
|
-
const goal = args.goal || ( localize(14056, "No goal provided"));
|
|
842
|
+
const explanation = args.explanation || ( localize(14371, "No explanation provided"));
|
|
843
|
+
const goal = args.goal || ( localize(14372, "No goal provided"));
|
|
753
844
|
const confirmationMessage = requiresUnsandboxConfirmation ? ( new MarkdownString(( localize(
|
|
754
|
-
|
|
845
|
+
14373,
|
|
755
846
|
"Explanation: {0}\n\nGoal: {1}\n\nReason for leaving the sandbox: {2}",
|
|
756
847
|
explanation,
|
|
757
848
|
goal,
|
|
758
|
-
requestUnsandboxedExecutionReason || ( localize(
|
|
759
|
-
)))) : ( new MarkdownString(( localize(
|
|
849
|
+
requestUnsandboxedExecutionReason || ( localize(14374, "The model indicated that this command needs unsandboxed access."))
|
|
850
|
+
)))) : ( new MarkdownString(( localize(14375, "Explanation: {0}\n\nGoal: {1}", explanation, goal))));
|
|
760
851
|
const confirmationMessages = shouldShowConfirmation ? {
|
|
761
852
|
title: confirmationTitle,
|
|
762
853
|
message: confirmationMessage,
|
|
@@ -767,10 +858,10 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
767
858
|
const rawDisplayCommand = toolSpecificData.commandLine.forDisplay ?? toolSpecificData.commandLine.toolEdited ?? toolSpecificData.commandLine.original;
|
|
768
859
|
const displayCommand = rawDisplayCommand.length > 80 ? rawDisplayCommand.substring(0, 77) + "..." : rawDisplayCommand;
|
|
769
860
|
const invocationMessage = toolSpecificData.commandLine.isSandboxWrapped ? ( new MarkdownString(( localize(
|
|
770
|
-
|
|
861
|
+
14376,
|
|
771
862
|
"Running `{0}` in sandbox",
|
|
772
863
|
escapeMarkdownSyntaxTokens(displayCommand)
|
|
773
|
-
)))) : ( new MarkdownString(( localize(
|
|
864
|
+
)))) : ( new MarkdownString(( localize(14377, "Running `{0}`", escapeMarkdownSyntaxTokens(displayCommand)))));
|
|
774
865
|
return {
|
|
775
866
|
invocationMessage,
|
|
776
867
|
icon: toolSpecificData.commandLine.isSandboxWrapped ? Codicon.terminalSecure : Codicon.terminal,
|
|
@@ -783,7 +874,7 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
783
874
|
return `\`${blockedDomains[0]}\``;
|
|
784
875
|
}
|
|
785
876
|
return localize(
|
|
786
|
-
|
|
877
|
+
14378,
|
|
787
878
|
"`{0}` and {1} more domains",
|
|
788
879
|
blockedDomains[0],
|
|
789
880
|
blockedDomains.length - 1
|
|
@@ -793,13 +884,13 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
793
884
|
if (deniedDomains.length === blockedDomains.length && deniedDomains.length > 0) {
|
|
794
885
|
if (blockedDomains.length === 1) {
|
|
795
886
|
return localize(
|
|
796
|
-
|
|
887
|
+
14379,
|
|
797
888
|
"This command accesses {0}, which is blocked by chat.agent.deniedNetworkDomains.",
|
|
798
889
|
blockedDomains[0]
|
|
799
890
|
);
|
|
800
891
|
}
|
|
801
892
|
return localize(
|
|
802
|
-
|
|
893
|
+
14380,
|
|
803
894
|
"This command accesses {0} and {1} more domains that are blocked by chat.agent.deniedNetworkDomains.",
|
|
804
895
|
blockedDomains[0],
|
|
805
896
|
blockedDomains.length - 1
|
|
@@ -808,13 +899,13 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
808
899
|
if (deniedDomains.length > 0) {
|
|
809
900
|
if (blockedDomains.length === 1) {
|
|
810
901
|
return localize(
|
|
811
|
-
|
|
902
|
+
14381,
|
|
812
903
|
"This command accesses {0}, which is blocked by chat.agent.deniedNetworkDomains or not added to chat.agent.allowedNetworkDomains.",
|
|
813
904
|
blockedDomains[0]
|
|
814
905
|
);
|
|
815
906
|
}
|
|
816
907
|
return localize(
|
|
817
|
-
|
|
908
|
+
14382,
|
|
818
909
|
"This command accesses {0} and {1} more domains that are blocked by chat.agent.deniedNetworkDomains or not added to chat.agent.allowedNetworkDomains.",
|
|
819
910
|
blockedDomains[0],
|
|
820
911
|
blockedDomains.length - 1
|
|
@@ -822,13 +913,13 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
822
913
|
}
|
|
823
914
|
if (blockedDomains.length === 1) {
|
|
824
915
|
return localize(
|
|
825
|
-
|
|
916
|
+
14383,
|
|
826
917
|
"This command accesses {0}, which is not permitted by the current chat.agent.sandbox configuration.",
|
|
827
918
|
blockedDomains[0]
|
|
828
919
|
);
|
|
829
920
|
}
|
|
830
921
|
return localize(
|
|
831
|
-
|
|
922
|
+
14384,
|
|
832
923
|
"This command accesses {0} and {1} more domains that are not permitted by the current chat.agent.sandbox configuration.",
|
|
833
924
|
blockedDomains[0],
|
|
834
925
|
blockedDomains.length - 1
|
|
@@ -879,21 +970,22 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
879
970
|
blockedDomains
|
|
880
971
|
};
|
|
881
972
|
}
|
|
882
|
-
async _confirmAutomaticUnsandboxRetry(
|
|
883
|
-
|
|
884
|
-
command,
|
|
885
|
-
shell,
|
|
886
|
-
blockedDomains,
|
|
887
|
-
requiresConfirmationForRetry,
|
|
888
|
-
token
|
|
889
|
-
) {
|
|
890
|
-
if (requiresConfirmationForRetry === false) {
|
|
973
|
+
async _confirmAutomaticUnsandboxRetry(sessionResource, command, shell, blockedDomains, riskAssessment, token) {
|
|
974
|
+
if (this._autoApproveUnsandboxedCommands) {
|
|
891
975
|
return true;
|
|
892
976
|
}
|
|
893
977
|
const chatModel = sessionResource && this._chatService.getSession(sessionResource);
|
|
894
978
|
if (!(chatModel instanceof ChatModel)) {
|
|
895
979
|
return false;
|
|
896
980
|
}
|
|
981
|
+
if (sessionResource && isSessionAutoApproveLevel(
|
|
982
|
+
sessionResource,
|
|
983
|
+
this._configurationService,
|
|
984
|
+
this._chatWidgetService,
|
|
985
|
+
this._chatService
|
|
986
|
+
)) {
|
|
987
|
+
return true;
|
|
988
|
+
}
|
|
897
989
|
const request = chatModel.getRequests().at(-1);
|
|
898
990
|
if (!request) {
|
|
899
991
|
return false;
|
|
@@ -916,13 +1008,13 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
916
1008
|
const part = ( new ChatElicitationRequestPart(
|
|
917
1009
|
this._getAutomaticUnsandboxRetryTitle(shellType, blockedDomains),
|
|
918
1010
|
( new MarkdownString(( localize(
|
|
919
|
-
|
|
1011
|
+
14385,
|
|
920
1012
|
"`{0}`",
|
|
921
1013
|
escapeMarkdownSyntaxTokens(buildCommandDisplayText(command))
|
|
922
1014
|
)))),
|
|
923
1015
|
"",
|
|
924
|
-
( localize(
|
|
925
|
-
( localize(
|
|
1016
|
+
( localize(14386, "Allow")),
|
|
1017
|
+
( localize(14387, "Skip")),
|
|
926
1018
|
async () => {
|
|
927
1019
|
resolveOnce(true);
|
|
928
1020
|
part.hide();
|
|
@@ -935,7 +1027,8 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
935
1027
|
},
|
|
936
1028
|
undefined,
|
|
937
1029
|
undefined,
|
|
938
|
-
() => resolveOnce(false)
|
|
1030
|
+
() => resolveOnce(false),
|
|
1031
|
+
riskAssessment
|
|
939
1032
|
));
|
|
940
1033
|
chatModel.acceptResponseProgress(request, part);
|
|
941
1034
|
store.add(token.onCancellationRequested(() => resolveOnce(false)));
|
|
@@ -946,11 +1039,91 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
946
1039
|
}
|
|
947
1040
|
_getAutomaticUnsandboxRetryTitle(shellType, blockedDomains) {
|
|
948
1041
|
return blockedDomains?.length ? ( new MarkdownString(( localize(
|
|
949
|
-
|
|
1042
|
+
14388,
|
|
950
1043
|
"Run `{0}` command outside the sandbox to access {1}?",
|
|
951
1044
|
shellType,
|
|
952
1045
|
this._formatBlockedDomainsForTitle(blockedDomains)
|
|
953
|
-
)))) : ( new MarkdownString(( localize(
|
|
1046
|
+
)))) : ( new MarkdownString(( localize(14389, "Run `{0}` command outside the sandbox?", shellType))));
|
|
1047
|
+
}
|
|
1048
|
+
_registerSensitiveInputElicitation(
|
|
1049
|
+
chatSessionResource,
|
|
1050
|
+
terminalInstance,
|
|
1051
|
+
outputMonitor,
|
|
1052
|
+
cancelExecution,
|
|
1053
|
+
onAutoCancelled
|
|
1054
|
+
) {
|
|
1055
|
+
const store = ( new DisposableStore());
|
|
1056
|
+
let pending;
|
|
1057
|
+
let autoCancelled = false;
|
|
1058
|
+
store.add(outputMonitor.onDidDetectSensitiveInputNeeded(() => {
|
|
1059
|
+
if (pending || autoCancelled) {
|
|
1060
|
+
return;
|
|
1061
|
+
}
|
|
1062
|
+
const isAutoApproved = chatSessionResource && isSessionAutoApproveLevel(
|
|
1063
|
+
chatSessionResource,
|
|
1064
|
+
this._configurationService,
|
|
1065
|
+
this._chatWidgetService,
|
|
1066
|
+
this._chatService
|
|
1067
|
+
);
|
|
1068
|
+
const chatModel = chatSessionResource && this._chatService.getSession(chatSessionResource);
|
|
1069
|
+
if (isAutoApproved) {
|
|
1070
|
+
autoCancelled = true;
|
|
1071
|
+
if (chatModel instanceof ChatModel) {
|
|
1072
|
+
const request = chatModel.getRequests().at(-1);
|
|
1073
|
+
if (request) {
|
|
1074
|
+
const infoPart = ( new ChatElicitationRequestPart(( new MarkdownString(( localize(14390, "Terminal command cancelled — sensitive input required")))), ( new MarkdownString(( localize(
|
|
1075
|
+
14391,
|
|
1076
|
+
"The terminal command was prompting for a password or other secret. Auto-approve / autopilot mode cannot safely supply secrets, so the command was cancelled. Run the command interactively if you want to provide the secret."
|
|
1077
|
+
)))), "", ( localize(14392, "Dismiss")), "", async () => {
|
|
1078
|
+
infoPart.hide();
|
|
1079
|
+
return ElicitationState.Accepted;
|
|
1080
|
+
}, async () => {
|
|
1081
|
+
infoPart.hide();
|
|
1082
|
+
return ElicitationState.Rejected;
|
|
1083
|
+
}, undefined, undefined, undefined, undefined));
|
|
1084
|
+
chatModel.acceptResponseProgress(request, infoPart);
|
|
1085
|
+
}
|
|
1086
|
+
}
|
|
1087
|
+
onAutoCancelled?.();
|
|
1088
|
+
cancelExecution();
|
|
1089
|
+
return;
|
|
1090
|
+
}
|
|
1091
|
+
if (!(chatModel instanceof ChatModel)) {
|
|
1092
|
+
this._terminalService.setActiveInstance(terminalInstance);
|
|
1093
|
+
this._terminalService.revealTerminal(terminalInstance, true).catch(() => {});
|
|
1094
|
+
terminalInstance.focus();
|
|
1095
|
+
return;
|
|
1096
|
+
}
|
|
1097
|
+
const request = chatModel.getRequests().at(-1);
|
|
1098
|
+
if (!request) {
|
|
1099
|
+
return;
|
|
1100
|
+
}
|
|
1101
|
+
const part = ( new ChatElicitationRequestPart(( new MarkdownString(( localize(14393, "Terminal is waiting for sensitive input")))), ( new MarkdownString(( localize(
|
|
1102
|
+
14394,
|
|
1103
|
+
"The terminal command appears to be prompting for a password or other sensitive value. Focus the terminal to type it directly — secrets must not be sent through chat."
|
|
1104
|
+
)))), "", ( localize(14395, "Focus Terminal")), ( localize(14396, "Cancel Command")), async () => {
|
|
1105
|
+
pending = undefined;
|
|
1106
|
+
part.hide();
|
|
1107
|
+
try {
|
|
1108
|
+
this._terminalService.setActiveInstance(terminalInstance);
|
|
1109
|
+
await this._terminalService.revealTerminal(terminalInstance, true);
|
|
1110
|
+
terminalInstance.focus();
|
|
1111
|
+
} catch (err) {
|
|
1112
|
+
this._logService.warn(`RunInTerminalTool: failed to reveal terminal for sensitive input`, err);
|
|
1113
|
+
}
|
|
1114
|
+
return ElicitationState.Accepted;
|
|
1115
|
+
}, async () => {
|
|
1116
|
+
pending = undefined;
|
|
1117
|
+
part.hide();
|
|
1118
|
+
cancelExecution();
|
|
1119
|
+
return ElicitationState.Rejected;
|
|
1120
|
+
}, undefined, undefined, () => {
|
|
1121
|
+
pending = undefined;
|
|
1122
|
+
}, undefined));
|
|
1123
|
+
pending = part;
|
|
1124
|
+
chatModel.acceptResponseProgress(request, part);
|
|
1125
|
+
}));
|
|
1126
|
+
return store;
|
|
954
1127
|
}
|
|
955
1128
|
_acceptAutomaticUnsandboxRetryToolInvocationUpdate(
|
|
956
1129
|
sessionResource,
|
|
@@ -973,10 +1146,10 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
973
1146
|
const progress = {
|
|
974
1147
|
kind: "externalToolInvocationUpdate",
|
|
975
1148
|
toolCallId,
|
|
976
|
-
toolName: ( localize(
|
|
1149
|
+
toolName: ( localize(14352, "Run in Terminal")),
|
|
977
1150
|
isComplete,
|
|
978
1151
|
invocationMessage: ( new MarkdownString(( localize(
|
|
979
|
-
|
|
1152
|
+
14397,
|
|
980
1153
|
"Running `{0}` outside the sandbox",
|
|
981
1154
|
escapeMarkdownSyntaxTokens(displayCommand)
|
|
982
1155
|
)))),
|
|
@@ -1002,9 +1175,30 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1002
1175
|
}]
|
|
1003
1176
|
};
|
|
1004
1177
|
}
|
|
1178
|
+
const args = invocation.parameters;
|
|
1179
|
+
const allowUnsandboxedCommands = this._getAllowToRunUnsandboxedCommands(args);
|
|
1180
|
+
const isSandboxEnabled = await this._terminalSandboxService.isEnabled();
|
|
1181
|
+
if (this._shouldRejectUnsandboxedExecutionRequest(isSandboxEnabled, allowUnsandboxedCommands, args)) {
|
|
1182
|
+
const message = this._getUnsandboxedExecutionDisabledMessage();
|
|
1183
|
+
return {
|
|
1184
|
+
toolResultError: message,
|
|
1185
|
+
toolResultDetails: {
|
|
1186
|
+
input: args.command,
|
|
1187
|
+
output: [{
|
|
1188
|
+
type: "embed",
|
|
1189
|
+
isText: true,
|
|
1190
|
+
value: message
|
|
1191
|
+
}],
|
|
1192
|
+
isError: true
|
|
1193
|
+
},
|
|
1194
|
+
content: [{
|
|
1195
|
+
kind: "text",
|
|
1196
|
+
value: message
|
|
1197
|
+
}]
|
|
1198
|
+
};
|
|
1199
|
+
}
|
|
1005
1200
|
if (toolSpecificData.missingSandboxDependencies?.length) {
|
|
1006
|
-
|
|
1007
|
-
if (invocation.selectedCustomButton === installButton) {
|
|
1201
|
+
if (invocation.selectedCustomButton === "install") {
|
|
1008
1202
|
const sessionResource = invocation.context.sessionResource;
|
|
1009
1203
|
const {
|
|
1010
1204
|
exitCode
|
|
@@ -1021,7 +1215,7 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1021
1215
|
content: [{
|
|
1022
1216
|
kind: "text",
|
|
1023
1217
|
value: ( localize(
|
|
1024
|
-
|
|
1218
|
+
14398,
|
|
1025
1219
|
"Sandbox dependency installation failed (exit code {0}). The command was not executed.",
|
|
1026
1220
|
exitCode
|
|
1027
1221
|
))
|
|
@@ -1033,7 +1227,7 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1033
1227
|
content: [{
|
|
1034
1228
|
kind: "text",
|
|
1035
1229
|
value: ( localize(
|
|
1036
|
-
|
|
1230
|
+
14399,
|
|
1037
1231
|
"Could not determine whether sandbox dependency installation succeeded. The command was not executed."
|
|
1038
1232
|
))
|
|
1039
1233
|
}]
|
|
@@ -1047,12 +1241,11 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1047
1241
|
return {
|
|
1048
1242
|
content: [{
|
|
1049
1243
|
kind: "text",
|
|
1050
|
-
value: ( localize(
|
|
1244
|
+
value: ( localize(14400, "Sandbox dependency installation was cancelled by the user."))
|
|
1051
1245
|
}]
|
|
1052
1246
|
};
|
|
1053
1247
|
}
|
|
1054
1248
|
}
|
|
1055
|
-
const args = invocation.parameters;
|
|
1056
1249
|
const executionOptions = this._resolveExecutionOptions(args);
|
|
1057
1250
|
this._logService.debug(`RunInTerminalTool: Invoking with options ${JSON.stringify(args)}`);
|
|
1058
1251
|
let toolResultMessage;
|
|
@@ -1065,16 +1258,7 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1065
1258
|
};
|
|
1066
1259
|
}
|
|
1067
1260
|
if (executionOptions.mode === "sync" && args.timeout === undefined) {
|
|
1068
|
-
|
|
1069
|
-
args.timeout = 0;
|
|
1070
|
-
} else {
|
|
1071
|
-
return {
|
|
1072
|
-
content: [{
|
|
1073
|
-
kind: "text",
|
|
1074
|
-
value: "Error: timeout is required for mode=sync and must be provided in milliseconds (use 0 for no timeout)."
|
|
1075
|
-
}]
|
|
1076
|
-
};
|
|
1077
|
-
}
|
|
1261
|
+
args.timeout = 0;
|
|
1078
1262
|
}
|
|
1079
1263
|
const chatSessionResource = invocation.context.sessionResource;
|
|
1080
1264
|
const shouldSendNotifications = !invocation.subAgentInvocationId;
|
|
@@ -1083,14 +1267,13 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1083
1267
|
const didToolEditCommand = (!didUserEditCommand && toolSpecificData.commandLine.toolEdited !== undefined && toolSpecificData.commandLine.toolEdited !== toolSpecificData.commandLine.original &&
|
|
1084
1268
|
normalizeTerminalCommandForDisplay(toolSpecificData.commandLine.toolEdited).trim() !== normalizeTerminalCommandForDisplay(toolSpecificData.commandLine.original).trim());
|
|
1085
1269
|
const didSandboxWrapCommand = toolSpecificData.commandLine.isSandboxWrapped === true;
|
|
1086
|
-
const isSandboxEnabled = await this._terminalSandboxService.isEnabled();
|
|
1087
1270
|
const commandLineForMetadata = isSandboxEnabled ? toolSpecificData.commandLine.forDisplay ?? toolSpecificData.commandLine.original : undefined;
|
|
1088
1271
|
if (token.isCancellationRequested) {
|
|
1089
1272
|
throw ( new CancellationError());
|
|
1090
1273
|
}
|
|
1091
1274
|
let error;
|
|
1092
1275
|
const automaticUnsandboxRetryReason = ( localize(
|
|
1093
|
-
|
|
1276
|
+
14401,
|
|
1094
1277
|
"The sandboxed execution output indicated the sandbox blocked the command."
|
|
1095
1278
|
));
|
|
1096
1279
|
const isNewSession = !executionOptions.persistentSession && !( this._sessionTerminalAssociations.has(chatSessionResource));
|
|
@@ -1129,6 +1312,7 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1129
1312
|
let altBufferResult;
|
|
1130
1313
|
let didTimeout = false;
|
|
1131
1314
|
let didInputNeeded = false;
|
|
1315
|
+
let didSensitiveAutoCancelled = false;
|
|
1132
1316
|
let isBackgroundExecution = executionOptions.persistentSession;
|
|
1133
1317
|
let timeoutPromise;
|
|
1134
1318
|
let timeoutRacePromise;
|
|
@@ -1237,16 +1421,7 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1237
1421
|
resultText += `${outputAnalyzerMessage}\n`;
|
|
1238
1422
|
}
|
|
1239
1423
|
resultText += pollingResult.output;
|
|
1240
|
-
|
|
1241
|
-
chatSessionResource,
|
|
1242
|
-
this._configurationService,
|
|
1243
|
-
this._chatWidgetService,
|
|
1244
|
-
this._chatService
|
|
1245
|
-
)) {
|
|
1246
|
-
resultText += `\nIf the command is waiting for input (not a normal shell prompt), determine the answer and call ${TerminalToolId.SendToTerminal}. Then call ${TerminalToolId.GetTerminalOutput} to read the next prompt. Repeat one prompt at a time.`;
|
|
1247
|
-
} else {
|
|
1248
|
-
resultText += `\nIf the command is waiting for input (not a normal shell prompt), call the vscode_askQuestions tool to ask the user. Then send each answer using ${TerminalToolId.SendToTerminal}, calling ${TerminalToolId.GetTerminalOutput} between each.`;
|
|
1249
|
-
}
|
|
1424
|
+
resultText += `\n${this._buildInputNeededSteeringText(chatSessionResource, termId, false)}`;
|
|
1250
1425
|
} else if (pollingResult) {
|
|
1251
1426
|
resultText += `\n The command is still running, with output:\n`;
|
|
1252
1427
|
if (outputAnalyzerMessage) {
|
|
@@ -1269,6 +1444,19 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1269
1444
|
};
|
|
1270
1445
|
} else {
|
|
1271
1446
|
const raceCleanup = ( new DisposableStore());
|
|
1447
|
+
startMarkerPromise.then(() => {
|
|
1448
|
+
if (outputMonitor && !raceCleanup.isDisposed) {
|
|
1449
|
+
raceCleanup.add(this._registerSensitiveInputElicitation(
|
|
1450
|
+
chatSessionResource,
|
|
1451
|
+
toolTerminal.instance,
|
|
1452
|
+
outputMonitor,
|
|
1453
|
+
() => executeCancellation.cancel(),
|
|
1454
|
+
() => {
|
|
1455
|
+
didSensitiveAutoCancelled = true;
|
|
1456
|
+
}
|
|
1457
|
+
));
|
|
1458
|
+
}
|
|
1459
|
+
});
|
|
1272
1460
|
const raceCandidates = [executionPromise.then(result => ({
|
|
1273
1461
|
type: "completed",
|
|
1274
1462
|
result
|
|
@@ -1416,7 +1604,15 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1416
1604
|
}
|
|
1417
1605
|
});
|
|
1418
1606
|
if (shouldSendNotifications) {
|
|
1419
|
-
|
|
1607
|
+
const alreadyNotifiedInputNeededOutput = didInputNeeded ? terminalResult : undefined;
|
|
1608
|
+
this._registerCompletionNotification(
|
|
1609
|
+
toolTerminal.instance,
|
|
1610
|
+
termId,
|
|
1611
|
+
chatSessionResource,
|
|
1612
|
+
command,
|
|
1613
|
+
outputMonitor,
|
|
1614
|
+
alreadyNotifiedInputNeededOutput
|
|
1615
|
+
);
|
|
1420
1616
|
} else {
|
|
1421
1617
|
outputMonitor?.dispose();
|
|
1422
1618
|
}
|
|
@@ -1459,6 +1655,7 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1459
1655
|
return altBufferResult;
|
|
1460
1656
|
}
|
|
1461
1657
|
const shouldAutoRetryUnsandboxed = shouldAutomaticallyRetryUnsandboxed({
|
|
1658
|
+
allowUnsandboxedCommands,
|
|
1462
1659
|
didSandboxWrapCommand,
|
|
1463
1660
|
requestUnsandboxedExecution: args.requestUnsandboxedExecution === true,
|
|
1464
1661
|
isPersistentSession: executionOptions.persistentSession,
|
|
@@ -1468,6 +1665,7 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1468
1665
|
output: terminalResult
|
|
1469
1666
|
});
|
|
1470
1667
|
if (shouldAutoRetryUnsandboxed) {
|
|
1668
|
+
const requestUnsandboxedExecution = allowUnsandboxedCommands;
|
|
1471
1669
|
const [os, shell] = await Promise.all([this._osBackend, this._profileFetcher.getCopilotShell()]);
|
|
1472
1670
|
const retryReason = automaticUnsandboxRetryReason;
|
|
1473
1671
|
const retryRewriteResult = await this._rewriteCommandLine(args.command, {
|
|
@@ -1475,17 +1673,26 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1475
1673
|
shell,
|
|
1476
1674
|
os,
|
|
1477
1675
|
isBackground: executionOptions.persistentSession,
|
|
1478
|
-
requestUnsandboxedExecution
|
|
1676
|
+
requestUnsandboxedExecution,
|
|
1479
1677
|
requestUnsandboxedExecutionReason: retryReason
|
|
1480
1678
|
});
|
|
1481
1679
|
const rewrittenRetryReason = retryRewriteResult.requestUnsandboxedExecutionReason ?? retryReason;
|
|
1482
1680
|
const retryConfirmationCommand = toolSpecificData.presentationOverrides?.commandLine ?? command;
|
|
1681
|
+
const retryRiskAssessment = {
|
|
1682
|
+
toolId: TerminalToolId.RunInTerminal,
|
|
1683
|
+
parameters: {
|
|
1684
|
+
...args,
|
|
1685
|
+
command: retryRewriteResult.rewrittenCommand,
|
|
1686
|
+
allowToRunUnsandboxedCommands: allowUnsandboxedCommands,
|
|
1687
|
+
requestUnsandboxedExecution
|
|
1688
|
+
}
|
|
1689
|
+
};
|
|
1483
1690
|
const shouldRetry = await this._confirmAutomaticUnsandboxRetry(
|
|
1484
1691
|
invocation.context.sessionResource,
|
|
1485
1692
|
retryConfirmationCommand,
|
|
1486
1693
|
shell,
|
|
1487
1694
|
retryRewriteResult.blockedDomains,
|
|
1488
|
-
|
|
1695
|
+
retryRiskAssessment,
|
|
1489
1696
|
token
|
|
1490
1697
|
);
|
|
1491
1698
|
if (shouldRetry) {
|
|
@@ -1498,7 +1705,7 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1498
1705
|
forDisplay: retryRewriteResult.forDisplayCommand ?? normalizeTerminalCommandForDisplay(retryRewriteResult.rewrittenCommand ?? args.command),
|
|
1499
1706
|
isSandboxWrapped: retryRewriteResult.isSandboxWrapped
|
|
1500
1707
|
},
|
|
1501
|
-
requestUnsandboxedExecution
|
|
1708
|
+
requestUnsandboxedExecution,
|
|
1502
1709
|
requestUnsandboxedExecutionReason: rewrittenRetryReason,
|
|
1503
1710
|
terminalCommandUri: undefined,
|
|
1504
1711
|
terminalCommandOutput: undefined,
|
|
@@ -1518,7 +1725,8 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1518
1725
|
parameters: {
|
|
1519
1726
|
...args,
|
|
1520
1727
|
command: args.command,
|
|
1521
|
-
|
|
1728
|
+
allowToRunUnsandboxedCommands: allowUnsandboxedCommands,
|
|
1729
|
+
requestUnsandboxedExecution,
|
|
1522
1730
|
requestUnsandboxedExecutionReason: rewrittenRetryReason
|
|
1523
1731
|
},
|
|
1524
1732
|
toolSpecificData: retryToolSpecificData
|
|
@@ -1536,11 +1744,13 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1536
1744
|
if (!didSandboxWrapCommand) {
|
|
1537
1745
|
if (didUserEditCommand) {
|
|
1538
1746
|
resultText.push(
|
|
1539
|
-
`Note: The user manually edited the command to \`${command}
|
|
1747
|
+
`Note: The user manually edited the command to \`${command}\` (terminal ID=${termId}), and this is the output of running that command instead:\n`
|
|
1540
1748
|
);
|
|
1541
1749
|
} else if (didToolEditCommand) {
|
|
1750
|
+
const wasDetachedToBackground = /(^|\s)nohup\s|Start-Process\b/.test(command);
|
|
1751
|
+
const stdinHint = wasDetachedToBackground ? " Note that stdin is closed for detached background processes; do not try to send input via send_to_terminal — re-run with mode=\"sync\" instead if interactive input is required." : "";
|
|
1542
1752
|
resultText.push(
|
|
1543
|
-
`Note: The tool simplified the command to \`${command}
|
|
1753
|
+
`Note: The tool simplified the command to \`${command}\` (terminal ID=${termId}).${stdinHint} This is the output of running that command instead:\n`
|
|
1544
1754
|
);
|
|
1545
1755
|
}
|
|
1546
1756
|
if (isBackgroundExecution && !executionOptions.persistentSession) {
|
|
@@ -1549,27 +1759,18 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1549
1759
|
);
|
|
1550
1760
|
}
|
|
1551
1761
|
}
|
|
1552
|
-
|
|
1553
|
-
|
|
1554
|
-
|
|
1555
|
-
|
|
1556
|
-
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
resultText.push(
|
|
1561
|
-
`Note: The command is running in terminal ID ${termId} and may be waiting for input. If it IS waiting for input (not a normal shell prompt), determine the answer and call ${TerminalToolId.SendToTerminal}. Then call ${TerminalToolId.GetTerminalOutput} to read the next prompt. Repeat one prompt at a time.\n\n`
|
|
1562
|
-
);
|
|
1563
|
-
} else {
|
|
1564
|
-
resultText.push(
|
|
1565
|
-
`Note: The command is running in terminal ID ${termId} and may be waiting for input. If it IS waiting for input (not a normal shell prompt), call the vscode_askQuestions tool to ask the user. Then send each answer using ${TerminalToolId.SendToTerminal}, calling ${TerminalToolId.GetTerminalOutput} between each.\n\n`
|
|
1566
|
-
);
|
|
1567
|
-
}
|
|
1762
|
+
if (didSensitiveAutoCancelled) {
|
|
1763
|
+
resultText.push(
|
|
1764
|
+
`Note: The command in terminal ID ${termId} was prompting for a password, passphrase, or other secret. The user is unavailable (auto-approve / autopilot mode is on, so no human can focus the terminal to type a secret) and the command has been cancelled. Stop, do NOT retry the command, do NOT call ${TerminalToolId.SendToTerminal}, and do NOT call vscode_askQuestions for the secret. Tell the user to run the command interactively when they are available.\n\n`
|
|
1765
|
+
);
|
|
1766
|
+
} else if (didInputNeeded) {
|
|
1767
|
+
resultText.push(
|
|
1768
|
+
`Note: The command is running in terminal ID ${termId} and may be waiting for input.\n${this._buildInputNeededSteeringText(chatSessionResource, termId, false)}\n\n`
|
|
1769
|
+
);
|
|
1568
1770
|
} else if (didTimeout && timeoutValue !== undefined && timeoutValue > 0) {
|
|
1569
1771
|
const notificationHint = shouldSendNotifications ? " You will be automatically notified on your next turn when it completes." : "";
|
|
1570
|
-
const inputAction = isAutoApproved ? `If it IS waiting for input (not a normal shell prompt), determine the answer and call ${TerminalToolId.SendToTerminal}. Then call ${TerminalToolId.GetTerminalOutput} to read the next prompt. Repeat one prompt at a time.` : `If it IS waiting for input (not a normal shell prompt), call the vscode_askQuestions tool to ask the user. Then send each answer using ${TerminalToolId.SendToTerminal}, calling ${TerminalToolId.GetTerminalOutput} between each.`;
|
|
1571
1772
|
resultText.push(
|
|
1572
|
-
`Note: Command timed out after ${timeoutValue}ms. The command may still be running in terminal ID ${termId}.${notificationHint}
|
|
1773
|
+
`Note: Command timed out after ${timeoutValue}ms. The command may still be running in terminal ID ${termId}.${notificationHint}\n${this._buildInputNeededSteeringText(chatSessionResource, termId, true)}\n\n`
|
|
1573
1774
|
);
|
|
1574
1775
|
}
|
|
1575
1776
|
const outputAnalyzerMessage = await this._getOutputAnalyzerMessage(exitCode, terminalResult, command, didSandboxWrapCommand);
|
|
@@ -1588,7 +1789,8 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1588
1789
|
terminalId: toolTerminal.instance.instanceId,
|
|
1589
1790
|
cwd: endCwd?.toString(),
|
|
1590
1791
|
timedOut: didTimeout || undefined,
|
|
1591
|
-
timeoutMs: didTimeout ? timeoutValue : undefined
|
|
1792
|
+
timeoutMs: didTimeout ? timeoutValue : undefined,
|
|
1793
|
+
inputNeeded: didInputNeeded || undefined
|
|
1592
1794
|
},
|
|
1593
1795
|
toolResultDetails: isError ? {
|
|
1594
1796
|
input: command,
|
|
@@ -1605,6 +1807,39 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1605
1807
|
}, ...imageContent]
|
|
1606
1808
|
};
|
|
1607
1809
|
}
|
|
1810
|
+
_buildInputNeededSteeringText(chatSessionResource, termId, mentionTimeout) {
|
|
1811
|
+
const isAutoApproved = isSessionAutoApproveLevel(
|
|
1812
|
+
chatSessionResource,
|
|
1813
|
+
this._configurationService,
|
|
1814
|
+
this._chatWidgetService,
|
|
1815
|
+
this._chatService
|
|
1816
|
+
);
|
|
1817
|
+
const lines = [];
|
|
1818
|
+
lines.push(
|
|
1819
|
+
`This note is not a signal to end the turn — pick one of the actions below and continue.`
|
|
1820
|
+
);
|
|
1821
|
+
if (isAutoApproved) {
|
|
1822
|
+
lines.push(
|
|
1823
|
+
` 1. If the output clearly ends with a non-secret input prompt (Continue? (y/n), Enter selection, etc. — a normal shell prompt like \`$\` or \`#\` does NOT count), determine the answer and immediately call ${TerminalToolId.SendToTerminal} with id="${termId}" (which returns the next few lines of output). Repeat one prompt at a time. Never guess passwords, passphrases, tokens, or other secrets — if the prompt requires a secret you do not have, inform the user and stop.`
|
|
1824
|
+
);
|
|
1825
|
+
lines.push(
|
|
1826
|
+
` 2. If the command may still be producing output or the shell prompt has not returned, call ${TerminalToolId.GetTerminalOutput} with id="${termId}" to continue polling.`
|
|
1827
|
+
);
|
|
1828
|
+
} else {
|
|
1829
|
+
lines.push(
|
|
1830
|
+
` 1. If the command may still be producing output or the shell prompt has not returned, call ${TerminalToolId.GetTerminalOutput} with id="${termId}" to continue polling. This is the default and safest action when unsure.`
|
|
1831
|
+
);
|
|
1832
|
+
lines.push(
|
|
1833
|
+
` 2. Only if the output clearly ends with a real non-secret input prompt (Continue? (y/n), Enter selection, etc. — a normal shell prompt like \`$\` or \`#\` does NOT count), call the vscode_askQuestions tool to ask the user, then send each answer using ${TerminalToolId.SendToTerminal} with id="${termId}" (which returns the next few lines of output). Repeat one prompt at a time. NEVER route secret prompts (passwords, passphrases, tokens, API keys, etc.) through vscode_askQuestions — answers to that tool are sent through the model. For secret prompts, tell the user to type the value directly into the terminal and stop.`
|
|
1834
|
+
);
|
|
1835
|
+
}
|
|
1836
|
+
if (mentionTimeout) {
|
|
1837
|
+
lines.push(
|
|
1838
|
+
` 3. A timeout does not mean the command failed — call ${TerminalToolId.GetTerminalOutput} with id="${termId}" to continue polling. Only call ${TerminalToolId.KillTerminal} if the command is genuinely hung and you need to retry with a different approach.`
|
|
1839
|
+
);
|
|
1840
|
+
}
|
|
1841
|
+
return lines.join("\n");
|
|
1842
|
+
}
|
|
1608
1843
|
async _getOutputAnalyzerMessage(exitCode, exitResult, commandLine, isSandboxWrapped) {
|
|
1609
1844
|
for (const analyzer of this._outputAnalyzers) {
|
|
1610
1845
|
const message = await analyzer.analyze({
|
|
@@ -1679,12 +1914,20 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1679
1914
|
if (!isBackground) {
|
|
1680
1915
|
const cachedTerminal = this._sessionTerminalAssociations.get(chatSessionResource);
|
|
1681
1916
|
if (cachedTerminal && !cachedTerminal.isBackground && !cachedTerminal.instance.isDisposed) {
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1917
|
+
if (cachedTerminal.instance.exitCode !== undefined) {
|
|
1918
|
+
this._logService.info(
|
|
1919
|
+
`RunInTerminalTool: Cached terminal shell has exited (code=${cachedTerminal.instance.exitCode}), creating a new terminal`
|
|
1920
|
+
);
|
|
1921
|
+
this._sessionTerminalAssociations.delete(chatSessionResource);
|
|
1922
|
+
} else {
|
|
1923
|
+
this._logService.debug(
|
|
1924
|
+
`RunInTerminalTool: Using cached terminal with session resource \`${chatSessionResource}\``
|
|
1925
|
+
);
|
|
1926
|
+
this._terminalToolCreator.refreshShellIntegrationQuality(cachedTerminal);
|
|
1927
|
+
this._terminalChatService.registerTerminalInstanceWithToolSession(terminalToolSessionId, cachedTerminal.instance);
|
|
1928
|
+
this._backgroundNotifications.deleteAndDispose(cachedTerminal.instance.instanceId);
|
|
1929
|
+
return cachedTerminal;
|
|
1930
|
+
}
|
|
1688
1931
|
}
|
|
1689
1932
|
}
|
|
1690
1933
|
this._logService.debug(
|
|
@@ -1905,8 +2148,16 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1905
2148
|
RunInTerminalTool_1._activeExecutions.delete(termId);
|
|
1906
2149
|
}
|
|
1907
2150
|
}
|
|
1908
|
-
_registerCompletionNotification(
|
|
1909
|
-
|
|
2151
|
+
_registerCompletionNotification(
|
|
2152
|
+
terminalInstance,
|
|
2153
|
+
termId,
|
|
2154
|
+
chatSessionResource,
|
|
2155
|
+
commandName,
|
|
2156
|
+
outputMonitor,
|
|
2157
|
+
alreadyNotifiedInputNeededOutput
|
|
2158
|
+
) {
|
|
2159
|
+
const notificationKey = terminalInstance.instanceId;
|
|
2160
|
+
this._backgroundNotifications.deleteAndDispose(notificationKey);
|
|
1910
2161
|
const commandDetection = terminalInstance.capabilities.get(TerminalCapability.CommandDetection);
|
|
1911
2162
|
if (!commandDetection) {
|
|
1912
2163
|
outputMonitor?.dispose();
|
|
@@ -1931,7 +2182,7 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1931
2182
|
}
|
|
1932
2183
|
const store = ( new DisposableStore());
|
|
1933
2184
|
let userIsReplyingDirectly = false;
|
|
1934
|
-
const disposeNotification = () => this._backgroundNotifications.deleteAndDispose(
|
|
2185
|
+
const disposeNotification = () => this._backgroundNotifications.deleteAndDispose(notificationKey);
|
|
1935
2186
|
const handleSessionCancelled = () => {
|
|
1936
2187
|
if (sessionRef.object.lastRequest?.response?.isCanceled) {
|
|
1937
2188
|
disposeNotification();
|
|
@@ -1951,8 +2202,8 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1951
2202
|
}));
|
|
1952
2203
|
}));
|
|
1953
2204
|
if (outputMonitor) {
|
|
1954
|
-
let lastInputNeededOutput = "";
|
|
1955
|
-
let lastInputNeededNotificationTime = 0;
|
|
2205
|
+
let lastInputNeededOutput = alreadyNotifiedInputNeededOutput ?? "";
|
|
2206
|
+
let lastInputNeededNotificationTime = alreadyNotifiedInputNeededOutput !== undefined ? Date.now() : 0;
|
|
1956
2207
|
const bgCts = ( new CancellationTokenSource());
|
|
1957
2208
|
store.add(toDisposable(() => {
|
|
1958
2209
|
bgCts.cancel();
|
|
@@ -1960,6 +2211,12 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1960
2211
|
}));
|
|
1961
2212
|
store.add(outputMonitor);
|
|
1962
2213
|
outputMonitor.continueMonitoringAsync(bgCts.token);
|
|
2214
|
+
store.add(
|
|
2215
|
+
this._registerSensitiveInputElicitation(chatSessionResource, terminalInstance, outputMonitor, () => {
|
|
2216
|
+
const execution = RunInTerminalTool_1._activeExecutions.get(termId);
|
|
2217
|
+
execution?.dispose();
|
|
2218
|
+
})
|
|
2219
|
+
);
|
|
1963
2220
|
store.add(outputMonitor.onDidDetectInputNeeded(() => {
|
|
1964
2221
|
if (userIsReplyingDirectly) {
|
|
1965
2222
|
this._logService.debug(
|
|
@@ -1982,14 +2239,8 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1982
2239
|
}
|
|
1983
2240
|
lastInputNeededOutput = currentOutput;
|
|
1984
2241
|
lastInputNeededNotificationTime = now;
|
|
1985
|
-
const
|
|
1986
|
-
|
|
1987
|
-
this._configurationService,
|
|
1988
|
-
this._chatWidgetService,
|
|
1989
|
-
this._chatService
|
|
1990
|
-
);
|
|
1991
|
-
const inputAction = isAutoApproved ? `Determine the answer and call ${TerminalToolId.SendToTerminal}. Then call ${TerminalToolId.GetTerminalOutput} to read the next prompt. Repeat one prompt at a time. A normal shell prompt does NOT count as waiting for input.` : `Call the vscode_askQuestions tool to ask the user. Then send each answer using ${TerminalToolId.SendToTerminal}, calling ${TerminalToolId.GetTerminalOutput} between each. A normal shell prompt does NOT count as waiting for input.`;
|
|
1992
|
-
const message = `[Terminal ${termId} notification: command is waiting for input. ${inputAction}]\nTerminal output:\n${currentOutput}`;
|
|
2242
|
+
const inputAction = this._buildInputNeededSteeringText(chatSessionResource, termId, false);
|
|
2243
|
+
const message = `[Terminal ${termId} notification: command may be waiting for input — assess the output below.]\n${inputAction}\nTerminal output:\n${currentOutput}`;
|
|
1993
2244
|
this._logService.debug(
|
|
1994
2245
|
`RunInTerminalTool: Input needed in background terminal ${termId}, notifying chat session`
|
|
1995
2246
|
);
|
|
@@ -1997,7 +2248,7 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
1997
2248
|
...sendOptions,
|
|
1998
2249
|
queue: ChatRequestQueueKind.Steering,
|
|
1999
2250
|
isSystemInitiated: true,
|
|
2000
|
-
systemInitiatedLabel: ( localize(
|
|
2251
|
+
systemInitiatedLabel: ( localize(14402, "`{0}` may need input", commandName)),
|
|
2001
2252
|
terminalExecutionId: termId
|
|
2002
2253
|
}).catch(e => {
|
|
2003
2254
|
this._logService.warn(
|
|
@@ -2036,7 +2287,7 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
2036
2287
|
...sendOptions,
|
|
2037
2288
|
queue: ChatRequestQueueKind.Steering,
|
|
2038
2289
|
isSystemInitiated: true,
|
|
2039
|
-
systemInitiatedLabel: ( localize(
|
|
2290
|
+
systemInitiatedLabel: ( localize(14403, "`{0}` completed", commandName)),
|
|
2040
2291
|
terminalExecutionId: termId
|
|
2041
2292
|
}).catch(e => {
|
|
2042
2293
|
this._logService.warn(
|
|
@@ -2045,8 +2296,35 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
2045
2296
|
);
|
|
2046
2297
|
});
|
|
2047
2298
|
}));
|
|
2299
|
+
const executionForDisposal = RunInTerminalTool_1._activeExecutions.get(termId);
|
|
2048
2300
|
store.add(terminalInstance.onDisposed(() => {
|
|
2301
|
+
if (( RunInTerminalTool_1._killedByTool.has(termId))) {
|
|
2302
|
+
disposeNotification();
|
|
2303
|
+
return;
|
|
2304
|
+
}
|
|
2305
|
+
if (handleSessionCancelled()) {
|
|
2306
|
+
return;
|
|
2307
|
+
}
|
|
2308
|
+
const currentOutput = executionForDisposal?.getOutput() ?? "";
|
|
2309
|
+
const exitCode = terminalInstance.exitCode;
|
|
2310
|
+
const exitCodeText = exitCode !== undefined ? ` with exit code ${exitCode}` : "";
|
|
2049
2311
|
disposeNotification();
|
|
2312
|
+
const message = `[Terminal ${termId} notification: terminal exited${exitCodeText}. The terminal process ended before the command could complete normally; further commands cannot be sent to this terminal ID.]\nTerminal output:\n${currentOutput}`;
|
|
2313
|
+
this._logService.debug(
|
|
2314
|
+
`RunInTerminalTool: Background terminal ${termId} disposed${exitCodeText}, notifying chat session`
|
|
2315
|
+
);
|
|
2316
|
+
this._chatService.sendRequest(chatSessionResource, message, {
|
|
2317
|
+
...sendOptions,
|
|
2318
|
+
queue: ChatRequestQueueKind.Steering,
|
|
2319
|
+
isSystemInitiated: true,
|
|
2320
|
+
systemInitiatedLabel: ( localize(14404, "`{0}` terminal exited", commandName)),
|
|
2321
|
+
terminalExecutionId: termId
|
|
2322
|
+
}).catch(e => {
|
|
2323
|
+
this._logService.warn(
|
|
2324
|
+
`RunInTerminalTool: Failed to send terminal-exited notification for terminal ${termId}`,
|
|
2325
|
+
e
|
|
2326
|
+
);
|
|
2327
|
+
});
|
|
2050
2328
|
}));
|
|
2051
2329
|
store.add(sessionRef.object.onDidChange(e => {
|
|
2052
2330
|
if (e.kind === "removeRequest") {
|
|
@@ -2059,7 +2337,7 @@ let RunInTerminalTool = class RunInTerminalTool extends Disposable {
|
|
|
2059
2337
|
terminalInstance.dispose();
|
|
2060
2338
|
}
|
|
2061
2339
|
}));
|
|
2062
|
-
this._backgroundNotifications.set(
|
|
2340
|
+
this._backgroundNotifications.set(notificationKey, store);
|
|
2063
2341
|
}
|
|
2064
2342
|
_dismissPendingCarouselsForTerminal(chatSessionResource, termId) {
|
|
2065
2343
|
const model = this._chatService.getSession(chatSessionResource);
|
|
@@ -2128,6 +2406,7 @@ let ActiveTerminalExecution = class ActiveTerminalExecution extends Disposable {
|
|
|
2128
2406
|
}));
|
|
2129
2407
|
}
|
|
2130
2408
|
_createStrategy(commandDetection) {
|
|
2409
|
+
const isSyncMode = !this._isBackground;
|
|
2131
2410
|
switch (this._toolTerminal.shellIntegrationQuality) {
|
|
2132
2411
|
case ShellIntegrationQuality.None:
|
|
2133
2412
|
return this._instantiationService.createInstance(
|
|
@@ -2143,7 +2422,12 @@ let ActiveTerminalExecution = class ActiveTerminalExecution extends Disposable {
|
|
|
2143
2422
|
commandDetection
|
|
2144
2423
|
);
|
|
2145
2424
|
case ShellIntegrationQuality.Rich:
|
|
2146
|
-
return this._instantiationService.createInstance(
|
|
2425
|
+
return this._instantiationService.createInstance(
|
|
2426
|
+
RichExecuteStrategy,
|
|
2427
|
+
this._toolTerminal.instance,
|
|
2428
|
+
commandDetection,
|
|
2429
|
+
isSyncMode
|
|
2430
|
+
);
|
|
2147
2431
|
}
|
|
2148
2432
|
}
|
|
2149
2433
|
async start(commandLine, token, commandId, commandLineForMetadata) {
|