@codingame/monaco-vscode-katex-common 31.0.0 → 32.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (220) hide show
  1. package/package.json +2 -2
  2. package/vscode/src/vs/platform/actionWidget/browser/actionWidgetDropdown.d.ts +15 -3
  3. package/vscode/src/vs/platform/actionWidget/browser/actionWidgetDropdown.js +6 -5
  4. package/vscode/src/vs/platform/actions/browser/buttonbar.d.ts +5 -1
  5. package/vscode/src/vs/platform/actions/browser/buttonbar.js +45 -14
  6. package/vscode/src/vs/platform/sandbox/common/terminalSandboxService.d.ts +15 -1
  7. package/vscode/src/vs/workbench/contrib/chat/browser/accessibility/chatAccessibilityProvider.js +16 -16
  8. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatContinueInAction.js +15 -10
  9. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatElicitationActions.js +1 -1
  10. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.js +51 -54
  11. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.js +10 -10
  12. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatToolActions.js +11 -11
  13. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatToolPicker.js +13 -13
  14. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionHoverWidget.d.ts +3 -1
  15. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionHoverWidget.js +45 -23
  16. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsControl.js +13 -7
  17. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsFilter.js +9 -9
  18. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsOpener.js +5 -3
  19. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.d.ts +4 -1
  20. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.js +46 -32
  21. package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentModel.js +8 -0
  22. package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentWidgets.d.ts +23 -1
  23. package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentWidgets.js +155 -46
  24. package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatImplicitContext.d.ts +1 -0
  25. package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatImplicitContext.js +20 -1
  26. package/vscode/src/vs/workbench/contrib/chat/browser/attachments/implicitContextAttachment.d.ts +4 -1
  27. package/vscode/src/vs/workbench/contrib/chat/browser/attachments/implicitContextAttachment.js +37 -14
  28. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingActions.js +34 -34
  29. package/vscode/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessionPickerActionItem.js +1 -1
  30. package/vscode/src/vs/workbench/contrib/chat/browser/chatSessions/media/chatSessionPickerActionItem.css +1 -0
  31. package/vscode/src/vs/workbench/contrib/chat/browser/tools/chatToolRiskAssessmentService.d.ts +28 -0
  32. package/vscode/src/vs/workbench/contrib/chat/browser/tools/chatToolRiskAssessmentService.js +250 -0
  33. package/vscode/src/vs/workbench/contrib/chat/browser/tools/toolSetsContribution.js +13 -13
  34. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatAgentHover.js +14 -11
  35. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatArtifactsWidget.js +10 -10
  36. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAgentCommandContentPart.js +1 -1
  37. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAnonymousRateLimitedPart.js +2 -2
  38. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAttachmentsContentPart.js +7 -2
  39. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatChangesSummaryPart.js +1 -1
  40. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCodeCitationContentPart.js +1 -1
  41. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCommandContentPart.js +1 -1
  42. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatConfirmationContentPart.js +7 -3
  43. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatConfirmationWidget.d.ts +12 -2
  44. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatConfirmationWidget.js +51 -20
  45. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatDisabledClaudeHooksContentPart.js +3 -3
  46. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatElicitationContentPart.d.ts +6 -1
  47. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatElicitationContentPart.js +56 -3
  48. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatExtensionsContentPart.js +1 -1
  49. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatHookContentPart.js +1 -1
  50. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/paragraphBuffer.d.ts +1 -1
  51. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/buffers/paragraphBuffer.js +2 -2
  52. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/chatIncrementalRendering.d.ts +3 -1
  53. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatIncrementalRendering/chatIncrementalRendering.js +4 -0
  54. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatInlineAnchorWidget.js +13 -13
  55. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownContentPart.js +68 -10
  56. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMcpServersInteractionContentPart.js +8 -8
  57. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMultiDiffContentPart.js +4 -4
  58. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatPlanReviewPart.d.ts +58 -2
  59. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatPlanReviewPart.js +653 -75
  60. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatProgressContentPart.js +28 -10
  61. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuestionCarouselPart.d.ts +5 -1
  62. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuestionCarouselPart.js +91 -54
  63. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuotaExceededPart.js +7 -5
  64. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatReferencesContentPart.js +53 -51
  65. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatResourceGroupWidget.js +5 -5
  66. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSubagentContentPart.js +11 -11
  67. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSuggestNextWidget.js +6 -6
  68. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTextEditContentPart.js +1 -1
  69. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingContentPart.d.ts +4 -1
  70. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingContentPart.js +42 -22
  71. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTipContentPart.js +9 -9
  72. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTodoListWidget.js +17 -17
  73. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatToolInputOutputContentPart.js +2 -2
  74. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTreeContentPart.js +1 -1
  75. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatWorkspaceEditContentPart.js +3 -3
  76. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/codeBlockPart.d.ts +6 -2
  77. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/codeBlockPart.js +93 -35
  78. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatConfirmationWidget.css +5 -0
  79. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatPlanReview.css +169 -27
  80. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatQuestionCarousel.css +13 -4
  81. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatThinkingContent.css +1 -1
  82. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatToolConfirmationCarousel.css +29 -0
  83. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/abstractToolConfirmationSubPart.d.ts +1 -0
  84. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/abstractToolConfirmationSubPart.js +60 -15
  85. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatExtensionsInstallToolSubPart.js +13 -6
  86. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatMcpAppModel.js +1 -1
  87. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatMcpAppSubPart.js +3 -3
  88. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatMissingSandboxDepsConfirmationSubPart.js +2 -2
  89. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatModifiedFilesConfirmationSubPart.js +15 -8
  90. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolConfirmationSubPart.d.ts +6 -1
  91. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolConfirmationSubPart.js +125 -26
  92. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolProgressPart.d.ts +2 -1
  93. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolProgressPart.js +29 -23
  94. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolConfirmationCarouselPart.d.ts +14 -0
  95. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolConfirmationCarouselPart.js +119 -10
  96. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolConfirmationSubPart.js +6 -6
  97. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolInvocationPart.js +1 -1
  98. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolOutputPart.js +2 -2
  99. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPartUtilities.js +5 -5
  100. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPostExecuteConfirmationPart.js +5 -5
  101. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/media/toolRiskBadge.css +77 -0
  102. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/toolRiskBadgeWidget.d.ts +38 -0
  103. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/toolRiskBadgeWidget.js +125 -0
  104. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatDragAndDrop.js +11 -11
  105. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.d.ts +1 -0
  106. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.js +132 -59
  107. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatWidget.d.ts +16 -3
  108. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatWidget.js +156 -67
  109. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatFollowups.js +1 -1
  110. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputNotificationService.d.ts +55 -0
  111. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputNotificationService.js +93 -0
  112. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputNotificationWidget.d.ts +21 -0
  113. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputNotificationWidget.js +133 -0
  114. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputPart.d.ts +53 -8
  115. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputPart.js +288 -125
  116. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatModelPicker.d.ts +23 -2
  117. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatModelPicker.js +699 -145
  118. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatModelSelectionLogic.d.ts +12 -8
  119. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatModelSelectionLogic.js +12 -11
  120. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatPhoneInputPresenter.d.ts +62 -0
  121. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatPhoneInputPresenter.js +120 -0
  122. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/delegationSessionPickerActionItem.js +5 -5
  123. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/media/chatInputNotificationWidget.css +191 -0
  124. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/media/chatPhoneInputPresenter.css +22 -0
  125. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/modePickerActionItem.d.ts +3 -3
  126. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/modePickerActionItem.js +9 -25
  127. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/modelPickerActionItem.js +4 -3
  128. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/permissionPickerActionItem.d.ts +20 -1
  129. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/permissionPickerActionItem.js +89 -108
  130. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/sessionTargetPickerActionItem.js +3 -3
  131. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/workspacePickerActionItem.js +3 -3
  132. package/vscode/src/vs/workbench/contrib/chat/browser/widget/media/chat.css +521 -9
  133. package/vscode/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/chatContextUsageDetails.js +7 -7
  134. package/vscode/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/chatContextUsageWidget.js +2 -2
  135. package/vscode/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/media/chatContextUsageDetails.css +19 -19
  136. package/vscode/src/vs/workbench/contrib/chat/common/chatImageExtraction.js +6 -6
  137. package/vscode/src/vs/workbench/contrib/chat/common/chatPermissionStorageKeys.d.ts +2 -0
  138. package/vscode/src/vs/workbench/contrib/chat/common/chatPermissionStorageKeys.js +6 -0
  139. package/vscode/src/vs/workbench/contrib/chat/common/chatPermissionWarnings.d.ts +27 -0
  140. package/vscode/src/vs/workbench/contrib/chat/common/chatPermissionWarnings.js +82 -0
  141. package/vscode/src/vs/workbench/contrib/chat/common/widget/chatColors.d.ts +3 -0
  142. package/vscode/src/vs/workbench/contrib/chat/common/widget/chatColors.js +44 -17
  143. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAffordance.d.ts +1 -3
  144. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatAffordance.js +3 -46
  145. package/vscode/src/vs/workbench/contrib/inlineChat/browser/{inlineChatEditorAffordance.d.ts → inlineChatAffordanceWidget.d.ts} +1 -1
  146. package/vscode/src/vs/workbench/contrib/inlineChat/browser/{inlineChatEditorAffordance.js → inlineChatAffordanceWidget.js} +6 -6
  147. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.d.ts +2 -18
  148. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.js +19 -400
  149. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionService.d.ts +4 -9
  150. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatSessionService.js +1 -1
  151. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.d.ts +5 -19
  152. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.js +47 -133
  153. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatZoneWidget.d.ts +3 -1
  154. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatZoneWidget.js +103 -25
  155. package/vscode/src/vs/workbench/contrib/inlineChat/browser/media/inlineChat.css +29 -0
  156. package/vscode/src/vs/workbench/contrib/inlineChat/common/inlineChat.d.ts +3 -32
  157. package/vscode/src/vs/workbench/contrib/inlineChat/common/inlineChat.js +39 -92
  158. package/vscode/src/vs/workbench/contrib/interactive/browser/replInputHintContentWidget.js +3 -3
  159. package/vscode/src/vs/workbench/contrib/notebook/browser/contrib/cellStatusBar/executionStatusBarItemController.js +7 -7
  160. package/vscode/src/vs/workbench/contrib/notebook/browser/contrib/find/notebookFindWidget.js +2 -2
  161. package/vscode/src/vs/workbench/contrib/notebook/browser/controller/cellOperations.js +2 -2
  162. package/vscode/src/vs/workbench/contrib/notebook/browser/controller/insertCellActions.js +24 -24
  163. package/vscode/src/vs/workbench/contrib/notebook/browser/diff/diffComponents.js +3 -3
  164. package/vscode/src/vs/workbench/contrib/notebook/browser/diff/diffElementOutputs.js +7 -7
  165. package/vscode/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffEditor.js +1 -1
  166. package/vscode/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffEditorBrowser.js +5 -5
  167. package/vscode/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffList.js +1 -1
  168. package/vscode/src/vs/workbench/contrib/replNotebook/browser/replEditor.js +1 -1
  169. package/vscode/src/vs/workbench/contrib/replNotebook/browser/replEditorInput.js +1 -1
  170. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/basicExecuteStrategy.d.ts +7 -0
  171. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/basicExecuteStrategy.js +99 -32
  172. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/executeStrategy.d.ts +13 -1
  173. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/executeStrategy.js +76 -14
  174. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/noneExecuteStrategy.js +4 -3
  175. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/richExecuteStrategy.d.ts +9 -1
  176. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/richExecuteStrategy.js +89 -28
  177. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/outputHelpers.js +1 -1
  178. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalHelpers.d.ts +11 -1
  179. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalHelpers.js +11 -7
  180. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalToolTelemetry.d.ts +3 -1
  181. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalToolTelemetry.js +7 -3
  182. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/autoApprove/commandLineAutoApprover.js +1 -1
  183. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/autoApprove/npmScriptAutoApprover.js +1 -1
  184. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineAnalyzer.d.ts +1 -0
  185. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineAutoApproveAnalyzer.js +12 -12
  186. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineFileWriteAnalyzer.d.ts +8 -0
  187. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineFileWriteAnalyzer.js +11 -2
  188. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLineBackgroundDetachRewriter.d.ts +20 -0
  189. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLineBackgroundDetachRewriter.js +59 -4
  190. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLineSandboxRewriter.d.ts +8 -1
  191. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLineSandboxRewriter.js +24 -3
  192. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/monitoring/outputMonitor.d.ts +47 -0
  193. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/monitoring/outputMonitor.js +111 -30
  194. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.d.ts +60 -3
  195. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.js +455 -171
  196. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/treeSitterCommandParser.d.ts +33 -0
  197. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/treeSitterCommandParser.js +82 -0
  198. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxCommandRules.d.ts +31 -0
  199. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxCommandRules.js +49 -0
  200. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxReadAllowList.d.ts +18 -0
  201. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxReadAllowList.js +302 -0
  202. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxRuntimeConfigurationPerOperation.d.ts +7 -0
  203. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxRuntimeConfigurationPerOperation.js +118 -0
  204. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxService.d.ts +34 -4
  205. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxService.js +233 -48
  206. package/vscode/src/vs/platform/actions/browser/actionbar.d.ts +0 -16
  207. package/vscode/src/vs/platform/actions/browser/actionbar.js +0 -22
  208. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorActions.d.ts +0 -46
  209. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorActions.js +0 -539
  210. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorOverlay.d.ts +0 -29
  211. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingEditorOverlay.js +0 -386
  212. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingExplanationWidget.d.ts +0 -101
  213. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingExplanationWidget.js +0 -509
  214. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/media/chatEditingEditorOverlay.css +0 -130
  215. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/media/chatEditingExplanationWidget.css +0 -276
  216. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputPartWidgets.d.ts +0 -45
  217. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputPartWidgets.js +0 -93
  218. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatOverlayWidget.d.ts +0 -39
  219. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatOverlayWidget.js +0 -617
  220. 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
- "- For long-running tasks (e.g., servers), use mode=async",
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. Use ${TerminalToolId.GetTerminalOutput} to check output before then`,
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
- - For long-running tasks (e.g., servers), use mode=async
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(createSandboxLines(networkDomains).join("\n"));
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. Use ${TerminalToolId.GetTerminalOutput} to check output before then
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(14038, "Run in Terminal")),
305
- modelDescription: `${modelDescription}\n\nExecution mode:\n- mode='sync': wait for completion up to timeout; if still running, 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\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. Use ${TerminalToolId.GetTerminalOutput} to check output before then. Do NOT poll or sleep to wait for completion.`,
306
- userDescription: ( localize(14039, "Run commands in the terminal")),
326
+ displayName: ( localize(14327, "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(14328, "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: "Timeout in milliseconds that determines how long to wait before returning. Use 0 for no timeout."
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", "timeout"]
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(14040, "The command opened the alternate buffer."));
368
+ const altBufferMessage = "\n" + ( localize(14329, "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
+ 14330,
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._register(this._instantiationService.createInstance(CommandLineSandboxRewriter))
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(14041, "Running `{0}`", escapeMarkdownSyntaxTokens(truncatedCommand)))));
556
+ const invocationMessage = ( new MarkdownString(( localize(14331, "Running `{0}`", escapeMarkdownSyntaxTokens(truncatedCommand)))));
508
557
  return {
509
558
  invocationMessage
510
559
  };
511
560
  }
512
561
  return {
513
- invocationMessage: ( localize(14042, "Running command"))
562
+ invocationMessage: ( localize(14332, "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 activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot();
531
- const workspaceFolder = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) ?? undefined : undefined;
532
- cwd = workspaceFolder?.uri;
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 isTerminalSandboxEnabled = sandboxPrereqs.enabled;
538
- const explicitUnsandboxRequest = isTerminalSandboxEnabled && args.requestUnsandboxedExecution === true;
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
+ 14333,
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(14043, "Missing Sandbox Dependencies")),
660
+ title: ( localize(14334, "Missing Sandbox Dependencies")),
580
661
  message: ( new MarkdownString(( localize(
581
- 14044,
662
+ 14335,
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
- customButtons: [( localize(14045, "Install")), ( localize(14046, "Cancel"))]
666
+ customOptions: [{
667
+ id: "install",
668
+ label: ( localize(14336, "Install")),
669
+ kind: ConfirmationOptionKind.Approve
670
+ }, {
671
+ id: "cancel",
672
+ label: ( localize(14337, "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 isFinalAutoApproved = isAutoApprovedByRules || ( commandLineAnalyzerResults.some(e => e.forceAutoApproval));
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(14047, "Run `{0}` command within `{1}`?", shellType, directoryLabel));
769
+ confirmationTitle = ( localize(14338, "Run `{0}` command within `{1}`?", shellType, directoryLabel));
678
770
  } else {
679
771
  toolSpecificData.confirmation = {
680
772
  commandLine: commandToDisplay
681
773
  };
682
- confirmationTitle = ( localize(14048, "Run `{0}` command?", shellType));
774
+ confirmationTitle = ( localize(14339, "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
- 14049,
795
+ 14340,
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
- 14050,
803
+ 14341,
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
- 14051,
812
+ 14342,
721
813
  "Run `{0}` command in `{1}`?",
722
814
  presenterResult.languageDisplayName,
723
815
  shellType
724
816
  ));
725
817
  } else {
726
- confirmationTitle = ( localize(14052, "Run command in `{0}`?", shellType));
818
+ confirmationTitle = ( localize(14343, "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
- 14053,
829
+ 14344,
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
- 14054,
835
+ 14345,
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
- toolSpecificData.requiresConfirmationForRetry = (!isAutoApprovedByRules && !isSessionAutoApproved) || context.forceConfirmationReason !== undefined;
751
- const explanation = args.explanation || ( localize(14055, "No explanation provided"));
752
- const goal = args.goal || ( localize(14056, "No goal provided"));
842
+ const explanation = args.explanation || ( localize(14346, "No explanation provided"));
843
+ const goal = args.goal || ( localize(14347, "No goal provided"));
753
844
  const confirmationMessage = requiresUnsandboxConfirmation ? ( new MarkdownString(( localize(
754
- 14057,
845
+ 14348,
755
846
  "Explanation: {0}\n\nGoal: {1}\n\nReason for leaving the sandbox: {2}",
756
847
  explanation,
757
848
  goal,
758
- requestUnsandboxedExecutionReason || ( localize(14058, "The model indicated that this command needs unsandboxed access."))
759
- )))) : ( new MarkdownString(( localize(14059, "Explanation: {0}\n\nGoal: {1}", explanation, goal))));
849
+ requestUnsandboxedExecutionReason || ( localize(14349, "The model indicated that this command needs unsandboxed access."))
850
+ )))) : ( new MarkdownString(( localize(14350, "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
- 14060,
861
+ 14351,
771
862
  "Running `{0}` in sandbox",
772
863
  escapeMarkdownSyntaxTokens(displayCommand)
773
- )))) : ( new MarkdownString(( localize(14061, "Running `{0}`", escapeMarkdownSyntaxTokens(displayCommand)))));
864
+ )))) : ( new MarkdownString(( localize(14352, "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
- 14062,
877
+ 14353,
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
- 14063,
887
+ 14354,
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
- 14064,
893
+ 14355,
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
- 14065,
902
+ 14356,
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
- 14066,
908
+ 14357,
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
- 14067,
916
+ 14358,
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
- 14068,
922
+ 14359,
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
- sessionResource,
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
- 14069,
1011
+ 14360,
920
1012
  "`{0}`",
921
1013
  escapeMarkdownSyntaxTokens(buildCommandDisplayText(command))
922
1014
  )))),
923
1015
  "",
924
- ( localize(14070, "Allow")),
925
- ( localize(14071, "Skip")),
1016
+ ( localize(14361, "Allow")),
1017
+ ( localize(14362, "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
- 14072,
1042
+ 14363,
950
1043
  "Run `{0}` command outside the sandbox to access {1}?",
951
1044
  shellType,
952
1045
  this._formatBlockedDomainsForTitle(blockedDomains)
953
- )))) : ( new MarkdownString(( localize(14073, "Run `{0}` command outside the sandbox?", shellType))));
1046
+ )))) : ( new MarkdownString(( localize(14364, "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(14365, "Terminal command cancelled — sensitive input required")))), ( new MarkdownString(( localize(
1075
+ 14366,
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(14367, "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(14368, "Terminal is waiting for sensitive input")))), ( new MarkdownString(( localize(
1102
+ 14369,
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(14370, "Focus Terminal")), ( localize(14371, "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(14038, "Run in Terminal")),
1149
+ toolName: ( localize(14327, "Run in Terminal")),
977
1150
  isComplete,
978
1151
  invocationMessage: ( new MarkdownString(( localize(
979
- 14074,
1152
+ 14372,
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
- const installButton = ( localize(14045, "Install"));
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
- 14075,
1218
+ 14373,
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
- 14076,
1230
+ 14374,
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(14077, "Sandbox dependency installation was cancelled by the user."))
1244
+ value: ( localize(14375, "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
- if (args.isBackground === false) {
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
- 14078,
1276
+ 14376,
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
- if (isSessionAutoApproveLevel(
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
- this._registerCompletionNotification(toolTerminal.instance, termId, chatSessionResource, command, outputMonitor);
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: true,
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
- toolSpecificData.requiresConfirmationForRetry,
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: true,
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
- requestUnsandboxedExecution: true,
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}\`, and this is the output of running that command instead:\n`
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}\`, and this is the output of running that command instead:\n`
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
- const isAutoApproved = isSessionAutoApproveLevel(
1553
- chatSessionResource,
1554
- this._configurationService,
1555
- this._chatWidgetService,
1556
- this._chatService
1557
- );
1558
- if (didInputNeeded) {
1559
- if (isAutoApproved) {
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} Use ${TerminalToolId.GetTerminalOutput} to check output, ${TerminalToolId.SendToTerminal} to send input, or ${TerminalToolId.KillTerminal} to stop it. ${inputAction}\n\n`
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
- this._logService.debug(
1683
- `RunInTerminalTool: Using cached terminal with session resource \`${chatSessionResource}\``
1684
- );
1685
- this._terminalToolCreator.refreshShellIntegrationQuality(cachedTerminal);
1686
- this._terminalChatService.registerTerminalInstanceWithToolSession(terminalToolSessionId, cachedTerminal.instance);
1687
- return cachedTerminal;
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(terminalInstance, termId, chatSessionResource, commandName, outputMonitor) {
1909
- this._backgroundNotifications.deleteAndDispose(termId);
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(termId);
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 isAutoApproved = isSessionAutoApproveLevel(
1986
- chatSessionResource,
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(14079, "`{0}` needs input", commandName)),
2251
+ systemInitiatedLabel: ( localize(14377, "`{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(14080, "`{0}` completed", commandName)),
2290
+ systemInitiatedLabel: ( localize(14378, "`{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(14379, "`{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(termId, store);
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(RichExecuteStrategy, this._toolTerminal.instance, commandDetection);
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) {