@codingame/monaco-vscode-katex-common 33.0.9 → 34.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 (255) hide show
  1. package/package.json +2 -2
  2. package/vscode/src/vs/base/browser/ui/pixelSpinner/pixelSpinner.css +169 -0
  3. package/vscode/src/vs/base/browser/ui/pixelSpinner/pixelSpinner.d.ts +28 -0
  4. package/vscode/src/vs/base/browser/ui/pixelSpinner/pixelSpinner.js +61 -0
  5. package/vscode/src/vs/platform/actions/browser/actionWidgetDropdownActionViewItem.d.ts +1 -1
  6. package/vscode/src/vs/platform/actions/browser/actionWidgetDropdownActionViewItem.js +1 -1
  7. package/vscode/src/vs/platform/actions/browser/buttonbar.js +2 -2
  8. package/vscode/src/vs/workbench/contrib/chat/browser/accessibility/chatAccessibilityProvider.js +18 -17
  9. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatContinueInAction.js +9 -9
  10. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatElicitationActions.js +1 -1
  11. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.js +40 -38
  12. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatTitleActions.js +10 -10
  13. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatToolActions.js +11 -11
  14. package/vscode/src/vs/workbench/contrib/chat/browser/actions/chatToolPicker.js +14 -14
  15. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostChatInputPicker.contribution.d.ts +1 -16
  16. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostChatInputPicker.contribution.js +4 -48
  17. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostChatInputPicker.d.ts +16 -18
  18. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostChatInputPicker.js +81 -69
  19. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostGenericConfigChips.d.ts +1 -3
  20. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostGenericConfigChips.js +5 -22
  21. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionUri.d.ts +2 -0
  22. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/agentHostSessionUri.js +21 -0
  23. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentHost/media/agentHostChatInputPicker.css +18 -28
  24. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionHoverWidget.js +8 -8
  25. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsControl.js +2 -2
  26. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsFilter.js +9 -9
  27. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsOpener.js +1 -1
  28. package/vscode/src/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsViewer.js +30 -30
  29. package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentWidgets.d.ts +13 -2
  30. package/vscode/src/vs/workbench/contrib/chat/browser/attachments/chatAttachmentWidgets.js +177 -80
  31. package/vscode/src/vs/workbench/contrib/chat/browser/attachments/implicitContextAttachment.js +15 -15
  32. package/vscode/src/vs/workbench/contrib/chat/browser/chatEditing/chatEditingActions.js +34 -34
  33. package/vscode/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessionPickerActionItem.d.ts +7 -2
  34. package/vscode/src/vs/workbench/contrib/chat/browser/chatSessions/chatSessionPickerActionItem.js +69 -5
  35. package/vscode/src/vs/workbench/contrib/chat/browser/tools/chatToolRiskAssessmentService.js +3 -3
  36. package/vscode/src/vs/workbench/contrib/chat/browser/tools/toolSetsContribution.js +13 -13
  37. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatAgentHover.js +2 -2
  38. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatArtifactsWidget.js +10 -10
  39. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentMarkdownRenderer.js +25 -1
  40. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAgentCommandContentPart.js +1 -1
  41. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatAnonymousRateLimitedPart.js +2 -2
  42. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatChangesSummaryPart.js +1 -1
  43. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCodeCitationContentPart.js +1 -1
  44. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCollapsibleContentPart.d.ts +2 -1
  45. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCollapsibleContentPart.js +4 -2
  46. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatCommandContentPart.js +1 -1
  47. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatConfirmationContentPart.js +2 -2
  48. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatConfirmationWidget.js +2 -2
  49. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatDisabledClaudeHooksContentPart.js +3 -3
  50. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatEditPillElement.d.ts +93 -0
  51. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatEditPillElement.js +140 -0
  52. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatExtensionsContentPart.js +1 -1
  53. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatExternalEditContentPart.d.ts +46 -0
  54. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatExternalEditContentPart.js +134 -0
  55. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatHookContentPart.js +1 -1
  56. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatInlineAnchorWidget.js +13 -13
  57. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownContentPart.d.ts +2 -15
  58. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMarkdownContentPart.js +49 -117
  59. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMcpServersInteractionContentPart.js +8 -8
  60. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatMultiDiffContentPart.js +4 -4
  61. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatPlanReviewPart.js +30 -30
  62. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatProgressContentPart.d.ts +2 -0
  63. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatProgressContentPart.js +47 -4
  64. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuestionCarouselPart.d.ts +3 -1
  65. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuestionCarouselPart.js +52 -51
  66. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatQuotaExceededPart.js +18 -14
  67. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatReferencesContentPart.js +6 -6
  68. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatResourceGroupWidget.js +23 -13
  69. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSubagentContentPart.js +13 -11
  70. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSuggestNextWidget.d.ts +15 -1
  71. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatSuggestNextWidget.js +87 -11
  72. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTextEditContentPart.js +1 -1
  73. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingContentPart.d.ts +21 -4
  74. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatThinkingContentPart.js +102 -35
  75. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTipContentPart.js +9 -9
  76. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTodoListWidget.js +17 -17
  77. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatToolInputOutputContentPart.js +2 -2
  78. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatTreeContentPart.js +1 -1
  79. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/chatWorkspaceEditContentPart.js +3 -3
  80. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/codeBlockPart.js +14 -14
  81. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatCodeBlockPill.css +1 -1
  82. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatTerminalToolProgressPart.css +22 -1
  83. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/media/chatThinkingContent.css +22 -0
  84. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/abstractToolConfirmationSubPart.js +6 -2
  85. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatExtensionsInstallToolSubPart.js +4 -4
  86. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatInputOutputMarkdownProgressPart.js +1 -1
  87. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatMcpAppModel.js +21 -2
  88. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatMcpAppSubPart.js +3 -3
  89. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatMissingSandboxDepsConfirmationSubPart.js +2 -2
  90. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatModifiedFilesConfirmationSubPart.js +6 -6
  91. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatSimpleToolProgressPart.js +1 -1
  92. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolConfirmationSubPart.js +35 -18
  93. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolProgressPart.d.ts +1 -0
  94. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolProgressPart.js +62 -35
  95. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolConfirmationCarouselPart.js +8 -8
  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/chatToolOutputPart.js +2 -2
  98. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPartUtilities.d.ts +2 -2
  99. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolPartUtilities.js +15 -12
  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/chatToolProgressPart.d.ts +1 -0
  102. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/chatToolProgressPart.js +10 -3
  103. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/terminalToolAutoExpand.d.ts +2 -2
  104. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/terminalToolAutoExpand.js +13 -15
  105. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatContentParts/toolInvocationParts/toolRiskBadgeWidget.js +4 -4
  106. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatDragAndDrop.js +11 -11
  107. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.d.ts +19 -1
  108. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatListRenderer.js +154 -59
  109. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatListWidget.d.ts +6 -0
  110. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatListWidget.js +21 -0
  111. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatOptions.d.ts +4 -3
  112. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatOptions.js +6 -0
  113. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatWidget.d.ts +17 -2
  114. package/vscode/src/vs/workbench/contrib/chat/browser/widget/chatWidget.js +113 -23
  115. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatFollowups.js +1 -1
  116. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatGoalBannerWidget.d.ts +21 -0
  117. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatGoalBannerWidget.js +64 -0
  118. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputNotificationService.d.ts +10 -1
  119. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputNotificationService.js +7 -1
  120. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputNotificationWidget.d.ts +11 -1
  121. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputNotificationWidget.js +18 -7
  122. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputPart.d.ts +26 -0
  123. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputPart.js +361 -66
  124. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputPickerActionItem.d.ts +2 -2
  125. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputPickerActionItem.js +4 -4
  126. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputStatusActionViewItem.d.ts +30 -0
  127. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatInputStatusActionViewItem.js +147 -0
  128. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatModelPicker.d.ts +11 -5
  129. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatModelPicker.js +133 -87
  130. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/chatPhoneInputPresenter.js +2 -4
  131. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/delegationSessionPickerActionItem.d.ts +4 -2
  132. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/delegationSessionPickerActionItem.js +13 -7
  133. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/media/chatGoalBannerWidget.css +81 -0
  134. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/media/chatInputNotificationWidget.css +32 -18
  135. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/modePickerActionItem.js +6 -6
  136. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/modelPickerActionItem.js +2 -2
  137. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/permissionPickerActionItem.js +39 -40
  138. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/sessionTargetPickerActionItem.d.ts +23 -2
  139. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/sessionTargetPickerActionItem.js +66 -11
  140. package/vscode/src/vs/workbench/contrib/chat/browser/widget/input/workspacePickerActionItem.js +3 -6
  141. package/vscode/src/vs/workbench/contrib/chat/browser/widget/media/chat.css +373 -32
  142. package/vscode/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/chatContextUsageDetails.js +7 -7
  143. package/vscode/src/vs/workbench/contrib/chat/browser/widgetHosts/viewPane/chatContextUsageWidget.js +5 -3
  144. package/vscode/src/vs/workbench/contrib/chat/common/chatArtifactExtraction.js +18 -0
  145. package/vscode/src/vs/workbench/contrib/chat/common/chatImageExtraction.js +7 -7
  146. package/vscode/src/vs/workbench/contrib/chat/common/chatPermissionWarnings.js +6 -6
  147. package/vscode/src/vs/workbench/contrib/chat/common/widget/chatColors.js +18 -18
  148. package/vscode/src/vs/workbench/contrib/chat/common/widget/chatWidgetHistoryService.d.ts +12 -2
  149. package/vscode/src/vs/workbench/contrib/chat/common/widget/chatWidgetHistoryService.js +54 -11
  150. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatController.js +3 -3
  151. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatWidget.js +5 -5
  152. package/vscode/src/vs/workbench/contrib/inlineChat/browser/inlineChatZoneWidget.js +1 -1
  153. package/vscode/src/vs/workbench/contrib/inlineChat/common/inlineChat.js +30 -30
  154. package/vscode/src/vs/workbench/contrib/interactive/browser/replInputHintContentWidget.js +3 -3
  155. package/vscode/src/vs/workbench/contrib/notebook/browser/contrib/cellStatusBar/executionStatusBarItemController.js +7 -7
  156. package/vscode/src/vs/workbench/contrib/notebook/browser/contrib/find/notebookFindWidget.js +2 -2
  157. package/vscode/src/vs/workbench/contrib/notebook/browser/controller/cellOperations.js +2 -2
  158. package/vscode/src/vs/workbench/contrib/notebook/browser/controller/insertCellActions.js +24 -24
  159. package/vscode/src/vs/workbench/contrib/notebook/browser/diff/diffComponents.js +3 -3
  160. package/vscode/src/vs/workbench/contrib/notebook/browser/diff/diffElementOutputs.js +7 -7
  161. package/vscode/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffEditor.js +1 -1
  162. package/vscode/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffEditorBrowser.js +5 -5
  163. package/vscode/src/vs/workbench/contrib/notebook/browser/diff/notebookDiffList.js +1 -1
  164. package/vscode/src/vs/workbench/contrib/replNotebook/browser/replEditor.js +1 -1
  165. package/vscode/src/vs/workbench/contrib/replNotebook/browser/replEditorInput.js +1 -1
  166. package/vscode/src/vs/platform/actionWidget/browser/actionWidgetDropdown.d.ts +0 -76
  167. package/vscode/src/vs/platform/actionWidget/browser/actionWidgetDropdown.js +0 -191
  168. package/vscode/src/vs/platform/networkFilter/common/domainMatcher.d.ts +0 -50
  169. package/vscode/src/vs/platform/networkFilter/common/domainMatcher.js +0 -138
  170. package/vscode/src/vs/platform/networkFilter/common/settings.d.ts +0 -12
  171. package/vscode/src/vs/platform/networkFilter/common/settings.js +0 -14
  172. package/vscode/src/vs/platform/sandbox/common/sandboxHelperIpc.d.ts +0 -18
  173. package/vscode/src/vs/platform/sandbox/common/sandboxHelperIpc.js +0 -13
  174. package/vscode/src/vs/platform/sandbox/common/terminalSandboxService.d.ts +0 -87
  175. package/vscode/src/vs/platform/sandbox/common/terminalSandboxService.js +0 -10
  176. package/vscode/src/vs/workbench/contrib/terminal/terminalContribChatExports.d.ts +0 -2
  177. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/alternativeRecommendation.d.ts +0 -2
  178. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/alternativeRecommendation.js +0 -41
  179. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/commandParsers/commandFileWriteParser.d.ts +0 -24
  180. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/commandParsers/sedFileWriteParser.d.ts +0 -26
  181. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/commandParsers/sedFileWriteParser.js +0 -142
  182. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/basicExecuteStrategy.d.ts +0 -52
  183. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/basicExecuteStrategy.js +0 -232
  184. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/executeStrategy.d.ts +0 -65
  185. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/executeStrategy.js +0 -225
  186. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/noneExecuteStrategy.d.ts +0 -27
  187. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/noneExecuteStrategy.js +0 -143
  188. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/richExecuteStrategy.d.ts +0 -37
  189. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/richExecuteStrategy.js +0 -205
  190. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/strategyHelpers.d.ts +0 -40
  191. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/executeStrategy/strategyHelpers.js +0 -174
  192. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/outputHelpers.d.ts +0 -7
  193. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/outputHelpers.js +0 -43
  194. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalHelpers.d.ts +0 -52
  195. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalHelpers.js +0 -260
  196. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalToolTelemetry.d.ts +0 -44
  197. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/runInTerminalToolTelemetry.js +0 -98
  198. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/toolTerminalCreator.d.ts +0 -42
  199. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/toolTerminalCreator.js +0 -225
  200. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/autoApprove/commandLineAutoApprover.d.ts +0 -31
  201. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/autoApprove/commandLineAutoApprover.js +0 -392
  202. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/autoApprove/npmScriptAutoApprover.d.ts +0 -45
  203. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/autoApprove/npmScriptAutoApprover.js +0 -243
  204. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineAnalyzer.d.ts +0 -53
  205. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineAnalyzer.js +0 -10
  206. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineAutoApproveAnalyzer.d.ts +0 -20
  207. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineAutoApproveAnalyzer.js +0 -310
  208. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineFileWriteAnalyzer.d.ts +0 -27
  209. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineFileWriteAnalyzer.js +0 -177
  210. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineSandboxAnalyzer.d.ts +0 -11
  211. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineAnalyzer/commandLineSandboxAnalyzer.js +0 -33
  212. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLinePresenter/commandLinePresenter.d.ts +0 -41
  213. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLinePresenter/nodeCommandLinePresenter.d.ts +0 -19
  214. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLinePresenter/nodeCommandLinePresenter.js +0 -37
  215. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLinePresenter/pythonCommandLinePresenter.d.ts +0 -19
  216. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLinePresenter/pythonCommandLinePresenter.js +0 -37
  217. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLinePresenter/rubyCommandLinePresenter.d.ts +0 -19
  218. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLinePresenter/rubyCommandLinePresenter.js +0 -44
  219. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLinePresenter/sandboxedCommandLinePresenter.d.ts +0 -13
  220. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLinePresenter/sandboxedCommandLinePresenter.js +0 -22
  221. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLineBackgroundDetachRewriter.d.ts +0 -42
  222. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLineBackgroundDetachRewriter.js +0 -102
  223. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLineCdPrefixRewriter.d.ts +0 -5
  224. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLineCdPrefixRewriter.js +0 -27
  225. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLinePreventHistoryRewriter.d.ts +0 -14
  226. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLinePreventHistoryRewriter.js +0 -29
  227. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLinePwshChainOperatorRewriter.d.ts +0 -8
  228. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLinePwshChainOperatorRewriter.js +0 -33
  229. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLineRewriter.d.ts +0 -24
  230. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLineSandboxRewriter.d.ts +0 -15
  231. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/commandLineRewriter/commandLineSandboxRewriter.js +0 -53
  232. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/monitoring/outputMonitor.d.ts +0 -177
  233. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/monitoring/outputMonitor.js +0 -512
  234. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/monitoring/types.d.ts +0 -42
  235. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/monitoring/types.js +0 -23
  236. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/outputAnalyzer.d.ts +0 -9
  237. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.d.ts +0 -258
  238. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/runInTerminalTool.js +0 -2623
  239. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/sandboxOutputAnalyzer.d.ts +0 -22
  240. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/sandboxOutputAnalyzer.js +0 -43
  241. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/terminalCommandArtifactCollector.d.ts +0 -17
  242. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/terminalCommandArtifactCollector.js +0 -118
  243. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/terminalToolAutoApprove.d.ts +0 -22
  244. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/terminalToolAutoApprove.js +0 -44
  245. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/tools/toolIds.d.ts +0 -1
  246. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/treeSitterCommandParser.d.ts +0 -58
  247. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/browser/treeSitterCommandParser.js +0 -223
  248. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxCommandRules.d.ts +0 -31
  249. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxCommandRules.js +0 -49
  250. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxReadAllowList.d.ts +0 -18
  251. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxReadAllowList.js +0 -302
  252. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxRuntimeConfigurationPerOperation.d.ts +0 -7
  253. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxRuntimeConfigurationPerOperation.js +0 -118
  254. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxService.d.ts +0 -114
  255. package/vscode/src/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalSandboxService.js +0 -788
@@ -1,2623 +0,0 @@
1
-
2
- import { __decorate, __param } from '@codingame/monaco-vscode-api/external/tslib/tslib.es6';
3
- import { timeout, DeferredPromise, RunOnceScheduler } from '@codingame/monaco-vscode-api/vscode/vs/base/common/async';
4
- import { CancellationTokenSource } from '@codingame/monaco-vscode-api/vscode/vs/base/common/cancellation';
5
- import { Codicon } from '@codingame/monaco-vscode-api/vscode/vs/base/common/codicons';
6
- import { CancellationError } from '@codingame/monaco-vscode-api/vscode/vs/base/common/errors';
7
- import { Event } from '@codingame/monaco-vscode-api/vscode/vs/base/common/event';
8
- import { MarkdownString, escapeMarkdownSyntaxTokens } from '@codingame/monaco-vscode-api/vscode/vs/base/common/htmlContent';
9
- import { Disposable, MutableDisposable, DisposableMap, DisposableStore, toDisposable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/lifecycle';
10
- import { ResourceMap } from '@codingame/monaco-vscode-api/vscode/vs/base/common/map';
11
- import { getMediaMime } from '@codingame/monaco-vscode-api/vscode/vs/base/common/mime';
12
- import { clamp } from '@codingame/monaco-vscode-api/vscode/vs/base/common/numbers';
13
- import '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/index';
14
- import { basename, win32, posix } from '@codingame/monaco-vscode-api/vscode/vs/base/common/path';
15
- import { OS, OperatingSystem } from '@codingame/monaco-vscode-api/vscode/vs/base/common/platform';
16
- import { count } from '@codingame/monaco-vscode-api/vscode/vs/base/common/strings';
17
- import { isNumber, isString } from '@codingame/monaco-vscode-api/vscode/vs/base/common/types';
18
- import { URI } from '@codingame/monaco-vscode-api/vscode/vs/base/common/uri';
19
- import { generateUuid } from '@codingame/monaco-vscode-api/vscode/vs/base/common/uuid';
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';
22
- import { IConfigurationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/configuration/common/configuration.service';
23
- import { IFileService } from '@codingame/monaco-vscode-api/vscode/vs/platform/files/common/files.service';
24
- import { IInstantiationService } from '@codingame/monaco-vscode-api/vscode/vs/platform/instantiation/common/instantiation';
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';
27
- import { StorageScope, StorageTarget } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage';
28
- import { IStorageService } from '@codingame/monaco-vscode-api/vscode/vs/platform/storage/common/storage.service';
29
- import { TerminalCapability } from '@codingame/monaco-vscode-api/vscode/vs/platform/terminal/common/capabilities/capabilities';
30
- import { ITerminalLogService } from '@codingame/monaco-vscode-api/vscode/vs/platform/terminal/common/terminal.service';
31
- import { IWorkspaceContextService } from '@codingame/monaco-vscode-api/vscode/vs/platform/workspace/common/workspace.service';
32
- import { IHistoryService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/history/common/history.service';
33
- import { ILifecycleService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/lifecycle/common/lifecycle.service';
34
- import { IRemoteAgentService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/services/remote/common/remoteAgentService.service';
35
- import { IAgentSessionsService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/browser/agentSessions/agentSessionsService.service';
36
- import { IChatWidgetService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/browser/chat.service';
37
- import { TerminalToolConfirmationStorageKeys } from '../../../../chat/browser/widget/chatContentParts/toolInvocationParts/chatTerminalToolConfirmationSubPart.js';
38
- import { ElicitationState, ChatRequestQueueKind } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/chatService/chatService';
39
- import { IChatService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/chatService/chatService.service';
40
- import { LanguageModelPartAudience } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/languageModels';
41
- import { ChatModel } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/model/chatModel';
42
- import { ChatElicitationRequestPart } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/model/chatProgressTypes/chatElicitationRequestPart';
43
- import { ChatQuestionCarouselData } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/model/chatProgressTypes/chatQuestionCarouselData';
44
- import { LocalChatSessionUri, chatSessionResourceToId } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/model/chatUri';
45
- import { ToolDataSource, ToolInvocationPresentation } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/tools/languageModelToolsService';
46
- import { ILanguageModelToolsService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/tools/languageModelToolsService.service';
47
- import { ITerminalChatService, ITerminalService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/terminal/browser/terminal.service';
48
- import { ITerminalProfileResolverService } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/terminal/common/terminal.service';
49
- import { TerminalChatCommandId } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/terminalContrib/chat/browser/terminalChat';
50
- import { TerminalChatAgentToolsSettingId } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/terminalContrib/chatAgentTools/common/terminalChatAgentToolsConfiguration';
51
- import '../../common/terminalSandboxService.js';
52
- import { getRecommendedToolsOverRunInTerminal } from '../alternativeRecommendation.js';
53
- import { BasicExecuteStrategy } from '../executeStrategy/basicExecuteStrategy.js';
54
- import { NoneExecuteStrategy } from '../executeStrategy/noneExecuteStrategy.js';
55
- import { RichExecuteStrategy } from '../executeStrategy/richExecuteStrategy.js';
56
- import { getOutput } from '../outputHelpers.js';
57
- import { isWindowsPowerShell, isPowerShell, isZsh, isFish, buildCommandDisplayText, normalizeTerminalCommandForDisplay, extractCdPrefix } from '../runInTerminalHelpers.js';
58
- import { RunInTerminalToolTelemetry } from '../runInTerminalToolTelemetry.js';
59
- import { ToolTerminalCreator, ShellIntegrationQuality } from '../toolTerminalCreator.js';
60
- import { TreeSitterCommandParser, TreeSitterCommandParserLanguage } from '../treeSitterCommandParser.js';
61
- import { CommandLineAutoApproveAnalyzer } from './commandLineAnalyzer/commandLineAutoApproveAnalyzer.js';
62
- import { CommandLineFileWriteAnalyzer } from './commandLineAnalyzer/commandLineFileWriteAnalyzer.js';
63
- import { CommandLineSandboxAnalyzer } from './commandLineAnalyzer/commandLineSandboxAnalyzer.js';
64
- import { NodeCommandLinePresenter } from './commandLinePresenter/nodeCommandLinePresenter.js';
65
- import { PythonCommandLinePresenter } from './commandLinePresenter/pythonCommandLinePresenter.js';
66
- import { RubyCommandLinePresenter } from './commandLinePresenter/rubyCommandLinePresenter.js';
67
- import { SandboxedCommandLinePresenter } from './commandLinePresenter/sandboxedCommandLinePresenter.js';
68
- import { CommandLineBackgroundDetachRewriter } from './commandLineRewriter/commandLineBackgroundDetachRewriter.js';
69
- import { CommandLineCdPrefixRewriter } from './commandLineRewriter/commandLineCdPrefixRewriter.js';
70
- import { CommandLinePreventHistoryRewriter } from './commandLineRewriter/commandLinePreventHistoryRewriter.js';
71
- import { CommandLinePwshChainOperatorRewriter } from './commandLineRewriter/commandLinePwshChainOperatorRewriter.js';
72
- import { CommandLineSandboxRewriter } from './commandLineRewriter/commandLineSandboxRewriter.js';
73
- import { OutputMonitor } from './monitoring/outputMonitor.js';
74
- import { OutputMonitorState } from './monitoring/types.js';
75
- import { outputLooksSandboxBlocked, SandboxOutputAnalyzer } from './sandboxOutputAnalyzer.js';
76
- import { TerminalCommandArtifactCollector } from './terminalCommandArtifactCollector.js';
77
- import { isToolEligibleForTerminalAutoApproval, isTerminalAutoApproveAllowed, isSessionAutoApproveLevel } from './terminalToolAutoApprove.js';
78
- import { TerminalToolId } from '@codingame/monaco-vscode-api/vscode/vs/workbench/contrib/chat/common/tools/terminalToolIds';
79
- import { TerminalSandboxPrerequisiteCheck } from '../../../../../../platform/sandbox/common/terminalSandboxService.js';
80
- import { autorun } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/reactions/autorun';
81
- import { ITerminalSandboxService } from '@codingame/monaco-vscode-api/vscode/vs/platform/sandbox/common/terminalSandboxService.service';
82
- import { constObservable } from '@codingame/monaco-vscode-api/vscode/vs/base/common/observableInternal/observables/constObservable';
83
-
84
- var RunInTerminalTool_1;
85
- const TERMINAL_SANDBOX_DOCUMENTATION_URL = "https://aka.ms/vscode-sandboxing";
86
- const TOOL_REFERENCE_NAME = "runInTerminal";
87
- const LEGACY_TOOL_REFERENCE_FULL_NAMES = ["runCommands/runInTerminal"];
88
- const INPUT_NEEDED_NOTIFICATION_THROTTLE_MS = 5000;
89
- function createPowerShellModelDescription(shell, isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains) {
90
- const isWinPwsh = isWindowsPowerShell(shell);
91
- const parts = [
92
- `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.`,
93
- "",
94
- "Command Execution:",
95
- isWinPwsh ? "- Use semicolons ; to chain commands on one line, NEVER use && even when asked explicitly" : "- Prefer ; when chaining commands on one line",
96
- "- Prefer pipelines | for object-based data flow",
97
- "- Never create a sub-shell (eg. powershell -c \"command\") unless explicitly asked",
98
- "",
99
- "Directory Management:",
100
- "- Prefer relative paths when navigating directories, only use absolute when the path is far away or the current cwd is not expected",
101
- "- By default (mode=sync), shell and cwd are reused by subsequent sync commands",
102
- "- Use $PWD or Get-Location for current directory",
103
- "- Use Push-Location/Pop-Location for directory stack",
104
- "",
105
- "Program Execution:",
106
- "- Supports .NET, Python, Node.js, and other executables",
107
- "- Install modules via Install-Module, Install-Package",
108
- "- Use Get-Command to verify cmdlet/function availability",
109
- "",
110
- "Async Mode:",
111
- "- Use mode=async ONLY for processes that should keep running while you do other work (servers, watchers, dev daemons)",
112
- "- 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",
113
- "- Returns a terminal ID for checking status and runtime later",
114
- "- Use Start-Job for background PowerShell jobs",
115
- "",
116
- `Use ${TerminalToolId.SendToTerminal} to send commands or input to a terminal session.`
117
- ];
118
- if (isSandboxEnabled) {
119
- parts.push(...createSandboxLines(allowToRunUnsandboxedCommands, networkDomains));
120
- }
121
- parts.push(
122
- "",
123
- "Output Management:",
124
- "- Output is automatically truncated if longer than 60KB to prevent context overflow",
125
- "- Use Select-Object, Where-Object, Format-Table to filter output",
126
- "- Use -First/-Last parameters to limit results",
127
- "- For pager commands, add | Out-String or | Format-List",
128
- "",
129
- "Best Practices:",
130
- "- Use proper cmdlet names instead of aliases in scripts",
131
- "- Quote paths with spaces: \"C:\\Path With Spaces\"",
132
- "- Prefer PowerShell cmdlets over external commands when available",
133
- "- Prefer idiomatic PowerShell like Get-ChildItem instead of dir or ls for file listings",
134
- "- Use Test-Path to check file/directory existence",
135
- "- Be specific with Select-Object properties to avoid excessive output",
136
- "- Avoid printing credentials unless absolutely required",
137
- `- 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.`,
138
- "",
139
- "Interactive Input Handling:",
140
- "- 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.",
141
- `- 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.`,
142
- `- Send exactly one answer per prompt using ${TerminalToolId.SendToTerminal}. Never send multiple answers in a single send.`,
143
- `- After each send, call ${TerminalToolId.GetTerminalOutput} to read the next prompt before sending the next answer.`,
144
- "- Continue one prompt at a time until the command finishes."
145
- );
146
- return parts.join("\n");
147
- }
148
- function createSandboxLines(allowToRunUnsandboxedCommands, networkDomains) {
149
- const lines = [
150
- "",
151
- "Sandboxing:",
152
- "- ATTENTION: Terminal sandboxing is enabled, commands run in a sandbox by default",
153
- "- 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",
154
- "- Tools and scripts should respect the TMPDIR environment variable, which is automatically set to an appropriate path within the sandbox"
155
- ];
156
- if (allowToRunUnsandboxedCommands) {
157
- lines.push(
158
- "- 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",
159
- "- 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",
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
- }
167
- if (networkDomains) {
168
- const deniedSet = ( new Set(networkDomains.deniedDomains));
169
- const effectiveAllowed = networkDomains.allowedDomains.filter(d => !( deniedSet.has(d)));
170
- if (effectiveAllowed.length === 0) {
171
- lines.push("- All network access is blocked in the sandbox");
172
- } else {
173
- lines.push(
174
- `- Only the following domains are accessible in the sandbox (all other network access is blocked): ${effectiveAllowed.join(", ")}`
175
- );
176
- }
177
- if (networkDomains.deniedDomains.length > 0) {
178
- lines.push(
179
- `- The following domains are explicitly blocked in the sandbox: ${networkDomains.deniedDomains.join(", ")}`
180
- );
181
- }
182
- }
183
- return lines;
184
- }
185
- function createGenericDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains) {
186
- const parts = [`
187
- Command Execution:
188
- - Use && to chain simple commands on one line
189
- - Prefer pipelines | over temporary files for data flow
190
- - Never create a sub-shell (eg. bash -c "command") unless explicitly asked
191
-
192
- Directory Management:
193
- - Prefer relative paths when navigating directories, only use absolute when the path is far away or the current cwd is not expected
194
- - By default (mode=sync), shell and cwd are reused by subsequent sync commands
195
- - Use $PWD for current directory references
196
- - Consider using pushd/popd for directory stack management
197
- - Supports directory shortcuts like ~ and -
198
-
199
- Program Execution:
200
- - Supports Python, Node.js, and other executables
201
- - Install packages via package managers (brew, apt, etc.)
202
- - Use which or command -v to verify command availability
203
-
204
- Async Mode:
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
207
- - Returns a terminal ID for checking status and runtime later
208
-
209
- Use ${TerminalToolId.SendToTerminal} to send commands or input to a terminal session.`];
210
- if (isSandboxEnabled) {
211
- parts.push(
212
- createSandboxLines(allowToRunUnsandboxedCommands, networkDomains).join("\n")
213
- );
214
- }
215
- parts.push(`
216
-
217
- Output Management:
218
- - Output is automatically truncated if longer than 60KB to prevent context overflow
219
- - Use head, tail, grep, awk to filter and limit output size
220
- - For pager commands, disable paging: git --no-pager or add | cat
221
- - Use wc -l to count lines before displaying large outputs
222
-
223
- Best Practices:
224
- - Quote variables: "$var" instead of $var to handle spaces
225
- - Use find with -exec or xargs for file operations
226
- - Be specific with commands to avoid excessive output
227
- - Avoid printing credentials unless absolutely required
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.
229
-
230
- Interactive Input Handling:
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.
233
- - Send exactly one answer per prompt using ${TerminalToolId.SendToTerminal}. Never send multiple answers in a single send.
234
- - After each send, call ${TerminalToolId.GetTerminalOutput} to read the next prompt before sending the next answer.
235
- - Continue one prompt at a time until the command finishes.`);
236
- return parts.join("");
237
- }
238
- function createBashModelDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains) {
239
- return [
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.",
241
- createGenericDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains),
242
- "- Use [[ ]] for conditional tests instead of [ ]",
243
- "- Prefer $() over backticks for command substitution"
244
- ].join("\n");
245
- }
246
- function createZshModelDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains) {
247
- return [
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.",
249
- createGenericDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains),
250
- "- Use type to check command type (builtin, function, alias)",
251
- "- Use jobs, fg, bg for job control",
252
- "- Use [[ ]] for conditional tests instead of [ ]",
253
- "- Prefer $() over backticks for command substitution",
254
- "- Take advantage of zsh globbing features (**, extended globs). Note: unmatched globs fail by default (zsh: no matches found) — use a glob qualifier like *(N) or quote the glob if it should be literal",
255
- "",
256
- "zsh pitfalls — these WILL cause errors or hangs:",
257
- "- NEVER use bare == or === as separators (e.g. echo === triggers zsh equals expansion). Quote them: echo '==='",
258
- "- NEVER use status as a variable name (it is read-only in zsh). Use exit_code or ret instead"
259
- ].join("\n");
260
- }
261
- function createFishModelDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains) {
262
- return [
263
- "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.",
264
- createGenericDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains),
265
- "- Use type to check command type (builtin, function, alias)",
266
- "- Use jobs, fg, bg for job control",
267
- "- Use test expressions for conditionals (no [[ ]] syntax)",
268
- "- Prefer command substitution with () syntax",
269
- "- Variables are arrays by default, use $var[1] for first element",
270
- "- Take advantage of fish's autosuggestions and completions"
271
- ].join("\n");
272
- }
273
- async function createRunInTerminalToolData(accessor) {
274
- const instantiationService = accessor.get(IInstantiationService);
275
- const terminalSandboxService = accessor.get(ITerminalSandboxService);
276
- const configurationService = accessor.get(IConfigurationService);
277
- const allowToRunUnsandboxedCommands = configurationService.getValue(AgentSandboxSettingId.AgentSandboxAllowUnsandboxedCommands) === true;
278
- const profileFetcher = instantiationService.createInstance(TerminalProfileFetcher);
279
- const [shell, os, isSandboxEnabled, isSandboxAllowNetworkEnabled] = await Promise.all([
280
- profileFetcher.getCopilotShell(),
281
- profileFetcher.osBackend,
282
- terminalSandboxService.isEnabled(),
283
- terminalSandboxService.isSandboxAllowNetworkEnabled()
284
- ]);
285
- const networkDomains = isSandboxEnabled && !isSandboxAllowNetworkEnabled ? terminalSandboxService.getResolvedNetworkDomains() : undefined;
286
- let modelDescription;
287
- if (shell && os && isPowerShell(shell, os)) {
288
- modelDescription = createPowerShellModelDescription(shell, isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains);
289
- } else if (shell && os && isZsh(shell, os)) {
290
- modelDescription = createZshModelDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains);
291
- } else if (shell && os && isFish(shell, os)) {
292
- modelDescription = createFishModelDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains);
293
- } else {
294
- modelDescription = createBashModelDescription(isSandboxEnabled, allowToRunUnsandboxedCommands, networkDomains);
295
- }
296
- const sharedProperties = {
297
- command: {
298
- type: "string",
299
- description: "The command to run in the terminal."
300
- },
301
- explanation: {
302
- type: "string",
303
- description: "A one-sentence description of what the command does. This will be shown to the user before the command is run."
304
- },
305
- goal: {
306
- type: "string",
307
- description: "A short description of the goal or purpose of the command (e.g., \"Install dependencies\", \"Start development server\")."
308
- }
309
- };
310
- const sandboxProperties = isSandboxEnabled ? {
311
- allowToRunUnsandboxedCommands: {
312
- type: "boolean",
313
- const: allowToRunUnsandboxedCommands,
314
- default: allowToRunUnsandboxedCommands,
315
- 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."
316
- },
317
- requestUnsandboxedExecution: {
318
- type: "boolean",
319
- description: "Request that this command run outside the terminal sandbox. Only set this when the command clearly needs unsandboxed access. The user will be prompted before the command runs unsandboxed."
320
- },
321
- requestUnsandboxedExecutionReason: {
322
- type: "string",
323
- description: "A short explanation of why this command must run outside the terminal sandbox. Only provide this when requestUnsandboxedExecution is true."
324
- }
325
- } : {};
326
- return {
327
- id: TerminalToolId.RunInTerminal,
328
- toolReferenceName: TOOL_REFERENCE_NAME,
329
- legacyToolReferenceFullNames: LEGACY_TOOL_REFERENCE_FULL_NAMES,
330
- displayName: ( localize(14482, "Run in Terminal")),
331
- 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.`,
332
- userDescription: ( localize(14483, "Run commands in the terminal")),
333
- source: ToolDataSource.Internal,
334
- icon: Codicon.terminal,
335
- inputSchema: {
336
- type: "object",
337
- properties: {
338
- ...sharedProperties,
339
- ...sandboxProperties,
340
- mode: {
341
- type: "string",
342
- enum: ["sync", "async"],
343
- enumDescriptions: [
344
- "Wait for completion up to timeout, then return with collected output. If still running at timeout, the terminal session continues in the background.",
345
- "Wait for an initial idle/output signal, then return with a terminal ID and output snapshot while the session may continue running."
346
- ],
347
- description: "Execution mode for this command."
348
- },
349
- isBackground: {
350
- type: "boolean",
351
- description: "Legacy execution mode flag. Deprecated in favor of \"mode\". If true, equivalent to mode=async. If false, equivalent to mode=sync."
352
- },
353
- timeout: {
354
- type: "number",
355
- 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."
356
- }
357
- },
358
- required: ["command", "explanation", "goal", "mode"]
359
- }
360
- };
361
- }
362
- var TerminalToolStorageKeysInternal;
363
- (function(TerminalToolStorageKeysInternal) {
364
- TerminalToolStorageKeysInternal["TerminalSession"] = "chat.terminalSessions";
365
- })(TerminalToolStorageKeysInternal || (TerminalToolStorageKeysInternal = {}));
366
- function shouldAutomaticallyRetryUnsandboxed(options) {
367
- return options.allowUnsandboxedCommands && options.didSandboxWrapCommand && options.requestUnsandboxedExecution !== true && !options.isPersistentSession && !options.isBackgroundExecution && !options.didTimeout && options.exitCode !== 0 && outputLooksSandboxBlocked(options.output);
368
- }
369
- const telemetryIgnoredSequences = [
370
- "\u001b[I",
371
- "\u001b[O"];
372
- const altBufferMessage = "\n" + ( localize(14484, "The command opened the alternate buffer."));
373
- let RunInTerminalTool = class RunInTerminalTool extends Disposable {
374
- static {
375
- RunInTerminalTool_1 = this;
376
- }
377
- static {
378
- this._activeExecutions = ( new Map());
379
- }
380
- static {
381
- this._killedByTool = ( new Set());
382
- }
383
- static getBackgroundOutput(id) {
384
- const execution = RunInTerminalTool_1._activeExecutions.get(id);
385
- if (!execution) {
386
- throw ( new Error("Invalid terminal ID"));
387
- }
388
- return execution.getOutput();
389
- }
390
- static getExecution(id) {
391
- return RunInTerminalTool_1._activeExecutions.get(id);
392
- }
393
- static removeExecution(id) {
394
- const execution = RunInTerminalTool_1._activeExecutions.get(id);
395
- if (!execution) {
396
- return false;
397
- }
398
- execution.dispose();
399
- RunInTerminalTool_1._activeExecutions.delete(id);
400
- return true;
401
- }
402
- static markKilledByTool(id) {
403
- RunInTerminalTool_1._killedByTool.add(id);
404
- }
405
- _resolveExecutionOptions(args) {
406
- const mode = args.mode ?? (args.isBackground ? "async" : "sync");
407
- switch (mode) {
408
- case "async":
409
- return {
410
- mode: "async",
411
- persistentSession: true,
412
- waitStrategy: "idle"
413
- };
414
- case "sync":
415
- default:
416
- return {
417
- mode: "sync",
418
- persistentSession: false,
419
- waitStrategy: "completion"
420
- };
421
- }
422
- }
423
- get _allowUnsandboxedCommands() {
424
- return this._configurationService.getValue(AgentSandboxSettingId.AgentSandboxAllowUnsandboxedCommands) === true;
425
- }
426
- get _autoApproveUnsandboxedCommands() {
427
- return this._allowUnsandboxedCommands && this._configurationService.getValue(AgentSandboxSettingId.AgentSandboxAutoApproveUnsandboxedCommands) === true;
428
- }
429
- get _allowSandboxAutoApprove() {
430
- return this._configurationService.getValue(AgentSandboxSettingId.AgentSandboxAllowAutoApprove) === true;
431
- }
432
- _getAllowToRunUnsandboxedCommands(args) {
433
- return (args.allowToRunUnsandboxedCommands ?? this._allowUnsandboxedCommands) === true && this._allowUnsandboxedCommands;
434
- }
435
- _shouldRejectUnsandboxedExecutionRequest(isSandboxEnabled, allowUnsandboxedCommands, args) {
436
- return isSandboxEnabled && args.requestUnsandboxedExecution === true && !allowUnsandboxedCommands;
437
- }
438
- _getUnsandboxedExecutionDisabledMessage() {
439
- return localize(
440
- 14485,
441
- "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."
442
- );
443
- }
444
- get _enableCommandLineSandboxRewriting() {
445
- return true;
446
- }
447
- constructor(
448
- _chatService,
449
- _configurationService,
450
- _fileService,
451
- _historyService,
452
- _instantiationService,
453
- _labelService,
454
- _languageModelToolsService,
455
- _remoteAgentService,
456
- _storageService,
457
- _terminalChatService,
458
- _logService,
459
- _terminalService,
460
- _terminalSandboxService,
461
- _workspaceContextService,
462
- _chatWidgetService,
463
- _agentSessionsService,
464
- lifecycleService
465
- ) {
466
- super();
467
- this._chatService = _chatService;
468
- this._configurationService = _configurationService;
469
- this._fileService = _fileService;
470
- this._historyService = _historyService;
471
- this._instantiationService = _instantiationService;
472
- this._labelService = _labelService;
473
- this._languageModelToolsService = _languageModelToolsService;
474
- this._remoteAgentService = _remoteAgentService;
475
- this._storageService = _storageService;
476
- this._terminalChatService = _terminalChatService;
477
- this._logService = _logService;
478
- this._terminalService = _terminalService;
479
- this._terminalSandboxService = _terminalSandboxService;
480
- this._workspaceContextService = _workspaceContextService;
481
- this._chatWidgetService = _chatWidgetService;
482
- this._agentSessionsService = _agentSessionsService;
483
- this._archivedSessionListener = this._register(( new MutableDisposable()));
484
- this._sessionTerminalAssociations = ( new ResourceMap());
485
- this._sessionTerminalInstances = ( new ResourceMap());
486
- this._terminalsBeingDisposedBySessionCleanup = ( new Set());
487
- this._backgroundNotifications = this._register(( new DisposableMap()));
488
- this._isShuttingDown = false;
489
- this._register(lifecycleService.onWillShutdown(() => {
490
- this._isShuttingDown = true;
491
- }));
492
- this._osBackend = this._remoteAgentService.getEnvironment().then(remoteEnv => remoteEnv?.os ?? OS);
493
- this._terminalToolCreator = this._instantiationService.createInstance(ToolTerminalCreator);
494
- this._treeSitterCommandParser = this._register(this._instantiationService.createInstance(TreeSitterCommandParser));
495
- this._telemetry = this._instantiationService.createInstance(RunInTerminalToolTelemetry);
496
- this._commandArtifactCollector = this._instantiationService.createInstance(TerminalCommandArtifactCollector);
497
- this._profileFetcher = this._instantiationService.createInstance(TerminalProfileFetcher);
498
- this._commandLineRewriters = [
499
- this._register(this._instantiationService.createInstance(CommandLineCdPrefixRewriter)),
500
- this._register(
501
- this._instantiationService.createInstance(CommandLinePwshChainOperatorRewriter, this._treeSitterCommandParser)
502
- )
503
- ];
504
- if (this._enableCommandLineSandboxRewriting) {
505
- this._commandLineRewriters.push(this._register(
506
- this._instantiationService.createInstance(CommandLineSandboxRewriter, this._treeSitterCommandParser)
507
- ));
508
- }
509
- this._commandLineRewriters.push(this._register(
510
- this._instantiationService.createInstance(CommandLineBackgroundDetachRewriter)
511
- ));
512
- this._commandLineRewriters.push(this._register(
513
- this._instantiationService.createInstance(CommandLinePreventHistoryRewriter)
514
- ));
515
- this._commandLineAnalyzers = [this._register(this._instantiationService.createInstance(
516
- CommandLineFileWriteAnalyzer,
517
- this._treeSitterCommandParser,
518
- (message, args) => this._logService.info(`RunInTerminalTool#CommandLineFileWriteAnalyzer: ${message}`, args)
519
- )), this._register(this._instantiationService.createInstance(
520
- CommandLineAutoApproveAnalyzer,
521
- this._treeSitterCommandParser,
522
- this._telemetry,
523
- (message, args) => this._logService.info(`RunInTerminalTool#CommandLineAutoApproveAnalyzer: ${message}`, args)
524
- ))];
525
- if (this._enableCommandLineSandboxRewriting) {
526
- this._commandLineAnalyzers.push(
527
- this._register(this._instantiationService.createInstance(CommandLineSandboxAnalyzer))
528
- );
529
- }
530
- this._commandLinePresenters = [
531
- this._instantiationService.createInstance(SandboxedCommandLinePresenter),
532
- ( new NodeCommandLinePresenter()),
533
- ( new PythonCommandLinePresenter()),
534
- ( new RubyCommandLinePresenter())
535
- ];
536
- this._outputAnalyzers = [
537
- this._register(this._instantiationService.createInstance(SandboxOutputAnalyzer))
538
- ];
539
- this._register(
540
- Event.runAndSubscribe(this._configurationService.onDidChangeConfiguration, e => {
541
- if (!e || e.affectsConfiguration(TerminalChatAgentToolsSettingId.EnableAutoApprove)) {
542
- if (this._configurationService.getValue(TerminalChatAgentToolsSettingId.EnableAutoApprove) !== true) {
543
- this._storageService.remove(
544
- TerminalToolConfirmationStorageKeys.TerminalAutoApproveWarningAccepted,
545
- StorageScope.APPLICATION
546
- );
547
- }
548
- }
549
- })
550
- );
551
- this._restoreTerminalAssociations();
552
- this._register(this._terminalService.onDidDisposeInstance(e => {
553
- this._removeTerminalAssociations(e);
554
- }));
555
- this._register(this._chatService.onDidDisposeSession(e => {
556
- for (const resource of e.sessionResources) {
557
- this._cleanupSessionTerminals(resource);
558
- }
559
- }));
560
- }
561
- async handleToolStream(context, _token) {
562
- const partialInput = context.rawInput;
563
- if (partialInput && typeof partialInput === "object" && partialInput.command) {
564
- const truncatedCommand = buildCommandDisplayText(partialInput.command);
565
- const invocationMessage = ( new MarkdownString(( localize(14486, "Running `{0}`", escapeMarkdownSyntaxTokens(truncatedCommand)))));
566
- return {
567
- invocationMessage
568
- };
569
- }
570
- return {
571
- invocationMessage: ( localize(14487, "Running command"))
572
- };
573
- }
574
- async prepareToolInvocation(context, token) {
575
- const args = context.parameters;
576
- const executionOptions = this._resolveExecutionOptions(args);
577
- const chatSessionResource = context.chatSessionResource;
578
- let instance;
579
- if (chatSessionResource) {
580
- const toolTerminal = this._sessionTerminalAssociations.get(chatSessionResource);
581
- if (toolTerminal && !toolTerminal.isBackground) {
582
- instance = toolTerminal.instance;
583
- }
584
- }
585
- const [os, shell, cwd, sandboxPrereqs] = await Promise.all([this._osBackend, this._profileFetcher.getCopilotShell(), (async () => {
586
- let cwd = await instance?.getCwdResource();
587
- if (!cwd) {
588
- const sessionModel = chatSessionResource ? this._chatService.getSession(chatSessionResource) : undefined;
589
- if (sessionModel?.workingDirectory) {
590
- cwd = sessionModel.workingDirectory;
591
- } else {
592
- const activeWorkspaceRootUri = this._historyService.getLastActiveWorkspaceRoot();
593
- const workspaceFolder = activeWorkspaceRootUri ? this._workspaceContextService.getWorkspaceFolder(activeWorkspaceRootUri) ?? undefined : undefined;
594
- cwd = workspaceFolder?.uri;
595
- }
596
- }
597
- return cwd;
598
- })(), this._terminalSandboxService.checkForSandboxingPrereqs()]);
599
- const language = os === OperatingSystem.Windows ? "pwsh" : "sh";
600
- const isSandboxEnabled = sandboxPrereqs.enabled;
601
- const allowUnsandboxedCommands = this._getAllowToRunUnsandboxedCommands(args);
602
- const explicitUnsandboxRequest = isSandboxEnabled && allowUnsandboxedCommands && args.requestUnsandboxedExecution === true;
603
- let requiresUnsandboxConfirmation = explicitUnsandboxRequest;
604
- let requestUnsandboxedExecutionReason = explicitUnsandboxRequest ? args.requestUnsandboxedExecutionReason : undefined;
605
- const missingDependencies = sandboxPrereqs.failedCheck === TerminalSandboxPrerequisiteCheck.Dependencies && sandboxPrereqs.missingDependencies?.length ? sandboxPrereqs.missingDependencies : undefined;
606
- const terminalToolSessionId = generateUuid();
607
- const terminalCommandId = `tool-${generateUuid()}`;
608
- if (this._shouldRejectUnsandboxedExecutionRequest(isSandboxEnabled, allowUnsandboxedCommands, args)) {
609
- const commandToDisplay = normalizeTerminalCommandForDisplay(args.command);
610
- return {
611
- invocationMessage: ( new MarkdownString(( localize(
612
- 14488,
613
- "Not running `{0}` because unsandboxed execution is disabled",
614
- escapeMarkdownSyntaxTokens(buildCommandDisplayText(commandToDisplay))
615
- )))),
616
- icon: Codicon.error,
617
- confirmationMessages: undefined,
618
- toolSpecificData: {
619
- kind: "terminal",
620
- terminalToolSessionId,
621
- terminalCommandId,
622
- commandLine: {
623
- original: args.command,
624
- forDisplay: commandToDisplay
625
- },
626
- cwd,
627
- language,
628
- isBackground: executionOptions.persistentSession,
629
- requestUnsandboxedExecution: false,
630
- requestUnsandboxedExecutionReason: undefined
631
- }
632
- };
633
- }
634
- const rewriteResult = await this._rewriteCommandLine(args.command, {
635
- cwd,
636
- shell,
637
- os,
638
- isBackground: executionOptions.persistentSession,
639
- requestUnsandboxedExecution: allowUnsandboxedCommands ? requiresUnsandboxConfirmation : false,
640
- requestUnsandboxedExecutionReason
641
- });
642
- const rewrittenCommand = rewriteResult.rewrittenCommand;
643
- const forDisplayCommand = rewriteResult.forDisplayCommand;
644
- const isSandboxWrapped = rewriteResult.isSandboxWrapped;
645
- requiresUnsandboxConfirmation = rewriteResult.requiresUnsandboxConfirmation;
646
- requestUnsandboxedExecutionReason = rewriteResult.requestUnsandboxedExecutionReason;
647
- const blockedDomains = rewriteResult.blockedDomains;
648
- const toolSpecificData = {
649
- kind: "terminal",
650
- terminalToolSessionId,
651
- terminalCommandId,
652
- commandLine: {
653
- original: args.command,
654
- toolEdited: rewrittenCommand === args.command ? undefined : rewrittenCommand,
655
- forDisplay: forDisplayCommand ?? normalizeTerminalCommandForDisplay(rewrittenCommand ?? args.command),
656
- isSandboxWrapped
657
- },
658
- cwd,
659
- language,
660
- isBackground: executionOptions.persistentSession,
661
- requestUnsandboxedExecution: requiresUnsandboxConfirmation,
662
- requestUnsandboxedExecutionReason,
663
- missingSandboxDependencies: missingDependencies
664
- };
665
- let sandboxConfirmationMessageForMissingDeps = undefined;
666
- if (missingDependencies) {
667
- const depsList = missingDependencies.join(", ");
668
- sandboxConfirmationMessageForMissingDeps = {
669
- title: ( localize(14489, "Missing Sandbox Dependencies")),
670
- message: ( new MarkdownString(( localize(
671
- 14490,
672
- "The following dependencies required for sandboxed execution are not installed: {0}. Would you like to install them?",
673
- depsList
674
- )))),
675
- customOptions: [{
676
- id: "install",
677
- label: ( localize(14491, "Install")),
678
- kind: ConfirmationOptionKind.Approve
679
- }, {
680
- id: "cancel",
681
- label: ( localize(14492, "Cancel")),
682
- kind: ConfirmationOptionKind.Deny
683
- }]
684
- };
685
- }
686
- const alternativeRecommendation = getRecommendedToolsOverRunInTerminal(args.command, this._languageModelToolsService);
687
- if (alternativeRecommendation) {
688
- toolSpecificData.alternativeRecommendation = alternativeRecommendation;
689
- return {
690
- confirmationMessages: undefined,
691
- presentation: ToolInvocationPresentation.Hidden,
692
- toolSpecificData
693
- };
694
- }
695
- const commandLine = forDisplayCommand ?? rewrittenCommand ?? args.command;
696
- const isEligibleForAutoApproval = () => isToolEligibleForTerminalAutoApproval(
697
- TOOL_REFERENCE_NAME,
698
- this._configurationService,
699
- LEGACY_TOOL_REFERENCE_FULL_NAMES
700
- );
701
- const isAutoApproveEnabled = this._configurationService.getValue(TerminalChatAgentToolsSettingId.EnableAutoApprove) === true;
702
- const isAutoApproveAllowed = isTerminalAutoApproveAllowed(
703
- TOOL_REFERENCE_NAME,
704
- this._configurationService,
705
- this._storageService,
706
- LEGACY_TOOL_REFERENCE_FULL_NAMES
707
- );
708
- const commandLineAnalyzerOptions = {
709
- commandLine,
710
- cwd,
711
- os,
712
- shell,
713
- treeSitterLanguage: isPowerShell(shell, os) ? TreeSitterCommandParserLanguage.PowerShell : TreeSitterCommandParserLanguage.Bash,
714
- terminalToolSessionId,
715
- chatSessionResource,
716
- requiresUnsandboxConfirmation,
717
- hasSessionAutoApproval: !!chatSessionResource && this._terminalChatService.hasChatSessionAutoApproval(chatSessionResource)
718
- };
719
- const isSessionAutoApproved = chatSessionResource && isSessionAutoApproveLevel(
720
- chatSessionResource,
721
- this._configurationService,
722
- this._chatWidgetService,
723
- this._chatService
724
- );
725
- const commandLineAnalyzers = isSessionAutoApproved ? this._commandLineAnalyzers.filter(e => !(e instanceof CommandLineAutoApproveAnalyzer)) : this._commandLineAnalyzers;
726
- const commandLineAnalyzerResults = await Promise.all(( commandLineAnalyzers.map(e => e.analyze(commandLineAnalyzerOptions))));
727
- const disclaimersRaw = ( commandLineAnalyzerResults.map(e => e.disclaimers)).filter(e => !!e).flatMap(e => e);
728
- let disclaimer;
729
- if (disclaimersRaw.length > 0) {
730
- const disclaimerTexts = ( disclaimersRaw.map(d => typeof d === "string" ? d : d.value));
731
- const hasMarkdownDisclaimer = ( disclaimersRaw.some(d => typeof d !== "string"));
732
- const mdOptions = hasMarkdownDisclaimer ? {
733
- supportThemeIcons: true,
734
- isTrusted: {
735
- enabledCommands: [TerminalChatCommandId.OpenTerminalSettingsLink]
736
- }
737
- } : {
738
- supportThemeIcons: true
739
- };
740
- disclaimer = ( new MarkdownString(`$(${Codicon.info.id}) ` + disclaimerTexts.join(" "), mdOptions));
741
- }
742
- const analyzersIsAutoApproveAllowed = commandLineAnalyzerResults.every(e => e.isAutoApproveAllowed);
743
- const customActions = isEligibleForAutoApproval() && analyzersIsAutoApproveAllowed ? ( commandLineAnalyzerResults.map(e => e.customActions ?? [])).flat() : undefined;
744
- let shellType = basename(shell, ".exe");
745
- if (shellType === "powershell") {
746
- shellType = "pwsh";
747
- }
748
- const wouldBeAutoApproved =
749
- (( commandLineAnalyzerResults.some(e => e.isAutoApproved)) &&
750
- commandLineAnalyzerResults.every(e => e.isAutoApproved !== false) &&
751
- analyzersIsAutoApproveAllowed);
752
- const isAutoApprovedByRules =
753
- (isAutoApproveAllowed &&
754
- wouldBeAutoApproved);
755
- const isUnsandboxedAutoApproved = isSandboxEnabled && requiresUnsandboxConfirmation === true && this._autoApproveUnsandboxedCommands;
756
- const isSandboxAutoApproved = isSandboxEnabled && toolSpecificData.commandLine.isSandboxWrapped === true && this._allowSandboxAutoApprove;
757
- const isFinalAutoApproved = isUnsandboxedAutoApproved || isSandboxAutoApproved || isAutoApprovedByRules || ( commandLineAnalyzerResults.some(e => e.forceAutoApproval));
758
- if (isFinalAutoApproved || (isAutoApproveEnabled && ( commandLineAnalyzerResults.some(e => e.autoApproveInfo)))) {
759
- toolSpecificData.autoApproveInfo = commandLineAnalyzerResults.find(e => e.autoApproveInfo)?.autoApproveInfo;
760
- }
761
- const commandToDisplay = (toolSpecificData.commandLine.forDisplay ?? toolSpecificData.commandLine.userEdited ?? toolSpecificData.commandLine.toolEdited ?? toolSpecificData.commandLine.original).trimStart();
762
- const extractedCd = extractCdPrefix(commandToDisplay, shell, os);
763
- let confirmationTitle;
764
- if (extractedCd && cwd) {
765
- const isAbsolutePath = os === OperatingSystem.Windows ? win32.isAbsolute(extractedCd.directory) : posix.isAbsolute(extractedCd.directory);
766
- const directoryUri = isAbsolutePath ? ( URI.from({
767
- scheme: cwd.scheme,
768
- authority: cwd.authority,
769
- path: extractedCd.directory
770
- })) : URI.joinPath(cwd, extractedCd.directory);
771
- const directoryLabel = this._labelService.getUriLabel(directoryUri);
772
- const cdPrefix = commandToDisplay.substring(0, commandToDisplay.length - extractedCd.command.length);
773
- toolSpecificData.confirmation = {
774
- commandLine: extractedCd.command,
775
- cwdLabel: directoryLabel,
776
- cdPrefix
777
- };
778
- confirmationTitle = ( localize(14493, "Run `{0}` command within `{1}`?", shellType, directoryLabel));
779
- } else {
780
- toolSpecificData.confirmation = {
781
- commandLine: commandToDisplay
782
- };
783
- confirmationTitle = ( localize(14494, "Run `{0}` command?", shellType));
784
- }
785
- const commandForPresenter = extractedCd?.command ?? commandToDisplay;
786
- let presenterInput = commandForPresenter;
787
- for (const presenter of this._commandLinePresenters) {
788
- const presenterResult = await presenter.present({
789
- commandLine: {
790
- original: args.command,
791
- forDisplay: presenterInput
792
- },
793
- shell,
794
- os
795
- });
796
- if (presenterResult) {
797
- toolSpecificData.presentationOverrides = {
798
- commandLine: presenterResult.commandLine,
799
- language: presenterResult.language ?? undefined
800
- };
801
- if (extractedCd && toolSpecificData.confirmation?.cwdLabel) {
802
- if (presenterResult.languageDisplayName) {
803
- confirmationTitle = ( localize(
804
- 14495,
805
- "Run `{0}` command in `{1}` within `{2}`?",
806
- presenterResult.languageDisplayName,
807
- shellType,
808
- toolSpecificData.confirmation.cwdLabel
809
- ));
810
- } else {
811
- confirmationTitle = ( localize(
812
- 14496,
813
- "Run command in `{0}` within `{1}`?",
814
- shellType,
815
- toolSpecificData.confirmation.cwdLabel
816
- ));
817
- }
818
- } else {
819
- if (presenterResult.languageDisplayName) {
820
- confirmationTitle = ( localize(
821
- 14497,
822
- "Run `{0}` command in `{1}`?",
823
- presenterResult.languageDisplayName,
824
- shellType
825
- ));
826
- } else {
827
- confirmationTitle = ( localize(14498, "Run command in `{0}`?", shellType));
828
- }
829
- }
830
- if (!presenterResult.processOtherPresenters) {
831
- break;
832
- }
833
- presenterInput = presenterResult.commandLine;
834
- }
835
- }
836
- if (requiresUnsandboxConfirmation) {
837
- confirmationTitle = blockedDomains?.length ? ( localize(
838
- 14499,
839
- "Run `{0}` command outside the [sandbox]({1}) to access {2}?",
840
- shellType,
841
- TERMINAL_SANDBOX_DOCUMENTATION_URL,
842
- this._formatBlockedDomainsForTitle(blockedDomains)
843
- )) : ( localize(
844
- 14500,
845
- "Run `{0}` command outside the [sandbox]({1})?",
846
- shellType,
847
- TERMINAL_SANDBOX_DOCUMENTATION_URL
848
- ));
849
- }
850
- const shouldShowConfirmation = (!isFinalAutoApproved && !isSessionAutoApproved) || context.forceConfirmationReason !== undefined;
851
- const explanation = args.explanation || ( localize(14501, "No explanation provided"));
852
- const goal = args.goal || ( localize(14502, "No goal provided"));
853
- const confirmationMessage = requiresUnsandboxConfirmation ? ( new MarkdownString(( localize(
854
- 14503,
855
- "Explanation: {0}\n\nGoal: {1}\n\nReason for leaving the sandbox: {2}",
856
- explanation,
857
- goal,
858
- requestUnsandboxedExecutionReason || ( localize(14504, "The model indicated that this command needs unsandboxed access."))
859
- )))) : ( new MarkdownString(( localize(14505, "Explanation: {0}\n\nGoal: {1}", explanation, goal))));
860
- const confirmationMessages = shouldShowConfirmation ? {
861
- title: confirmationTitle,
862
- message: confirmationMessage,
863
- disclaimer,
864
- allowAutoConfirm: undefined,
865
- terminalCustomActions: customActions
866
- } : undefined;
867
- const rawDisplayCommand = toolSpecificData.commandLine.forDisplay ?? toolSpecificData.commandLine.toolEdited ?? toolSpecificData.commandLine.original;
868
- const displayCommand = rawDisplayCommand.length > 80 ? rawDisplayCommand.substring(0, 77) + "..." : rawDisplayCommand;
869
- const invocationMessage = toolSpecificData.commandLine.isSandboxWrapped ? ( new MarkdownString(( localize(
870
- 14506,
871
- "Running `{0}` in sandbox",
872
- escapeMarkdownSyntaxTokens(displayCommand)
873
- )))) : ( new MarkdownString(( localize(14507, "Running `{0}`", escapeMarkdownSyntaxTokens(displayCommand)))));
874
- return {
875
- invocationMessage,
876
- icon: toolSpecificData.commandLine.isSandboxWrapped ? Codicon.terminalSecure : Codicon.terminal,
877
- confirmationMessages: sandboxConfirmationMessageForMissingDeps ?? confirmationMessages,
878
- toolSpecificData
879
- };
880
- }
881
- _formatBlockedDomainsForTitle(blockedDomains) {
882
- if (blockedDomains.length === 1) {
883
- return `\`${blockedDomains[0]}\``;
884
- }
885
- return localize(
886
- 14508,
887
- "`{0}` and {1} more domains",
888
- blockedDomains[0],
889
- blockedDomains.length - 1
890
- );
891
- }
892
- _getBlockedDomainReason(blockedDomains, deniedDomains = []) {
893
- if (deniedDomains.length === blockedDomains.length && deniedDomains.length > 0) {
894
- if (blockedDomains.length === 1) {
895
- return localize(
896
- 14509,
897
- "This command accesses {0}, which is blocked by chat.agent.deniedNetworkDomains.",
898
- blockedDomains[0]
899
- );
900
- }
901
- return localize(
902
- 14510,
903
- "This command accesses {0} and {1} more domains that are blocked by chat.agent.deniedNetworkDomains.",
904
- blockedDomains[0],
905
- blockedDomains.length - 1
906
- );
907
- }
908
- if (deniedDomains.length > 0) {
909
- if (blockedDomains.length === 1) {
910
- return localize(
911
- 14511,
912
- "This command accesses {0}, which is blocked by chat.agent.deniedNetworkDomains or not added to chat.agent.allowedNetworkDomains.",
913
- blockedDomains[0]
914
- );
915
- }
916
- return localize(
917
- 14512,
918
- "This command accesses {0} and {1} more domains that are blocked by chat.agent.deniedNetworkDomains or not added to chat.agent.allowedNetworkDomains.",
919
- blockedDomains[0],
920
- blockedDomains.length - 1
921
- );
922
- }
923
- if (blockedDomains.length === 1) {
924
- return localize(
925
- 14513,
926
- "This command accesses {0}, which is not permitted by the current chat.agent.sandbox configuration.",
927
- blockedDomains[0]
928
- );
929
- }
930
- return localize(
931
- 14514,
932
- "This command accesses {0} and {1} more domains that are not permitted by the current chat.agent.sandbox configuration.",
933
- blockedDomains[0],
934
- blockedDomains.length - 1
935
- );
936
- }
937
- async _rewriteCommandLine(commandLine, options) {
938
- let rewrittenCommand = commandLine;
939
- let forDisplayCommand = undefined;
940
- let isSandboxWrapped = false;
941
- let requiresUnsandboxConfirmation = options.requestUnsandboxedExecution;
942
- let requestUnsandboxedExecutionReason = options.requestUnsandboxedExecution ? options.requestUnsandboxedExecutionReason : undefined;
943
- let blockedDomains;
944
- for (const rewriter of this._commandLineRewriters) {
945
- const rewriteResult = await rewriter.rewrite({
946
- commandLine: rewrittenCommand,
947
- cwd: options.cwd,
948
- shell: options.shell,
949
- os: options.os,
950
- isBackground: options.isBackground,
951
- requestUnsandboxedExecution: requiresUnsandboxConfirmation
952
- });
953
- if (rewriteResult) {
954
- rewrittenCommand = rewriteResult.rewritten;
955
- forDisplayCommand = forDisplayCommand ?? rewriteResult.forDisplay;
956
- if (rewriteResult.isSandboxWrapped) {
957
- isSandboxWrapped = true;
958
- } else if (rewriteResult.isSandboxWrapped === false) {
959
- isSandboxWrapped = false;
960
- }
961
- if (rewriteResult.requiresUnsandboxConfirmation) {
962
- requiresUnsandboxConfirmation = true;
963
- }
964
- if (rewriteResult.blockedDomains?.length) {
965
- blockedDomains = rewriteResult.blockedDomains;
966
- requestUnsandboxedExecutionReason = this._getBlockedDomainReason(rewriteResult.blockedDomains, rewriteResult.deniedDomains);
967
- }
968
- this._logService.info(
969
- `RunInTerminalTool: Command rewritten by ${rewriter.constructor.name}: ${rewriteResult.reasoning}`
970
- );
971
- }
972
- }
973
- return {
974
- rewrittenCommand,
975
- forDisplayCommand,
976
- isSandboxWrapped,
977
- requiresUnsandboxConfirmation,
978
- requestUnsandboxedExecutionReason,
979
- blockedDomains
980
- };
981
- }
982
- async _confirmAutomaticUnsandboxRetry(sessionResource, command, shell, blockedDomains, riskAssessment, token) {
983
- if (this._autoApproveUnsandboxedCommands) {
984
- return true;
985
- }
986
- const chatModel = sessionResource && this._chatService.getSession(sessionResource);
987
- if (!(chatModel instanceof ChatModel)) {
988
- return false;
989
- }
990
- if (sessionResource && isSessionAutoApproveLevel(
991
- sessionResource,
992
- this._configurationService,
993
- this._chatWidgetService,
994
- this._chatService
995
- )) {
996
- return true;
997
- }
998
- const request = chatModel.getRequests().at(-1);
999
- if (!request) {
1000
- return false;
1001
- }
1002
- let shellType = basename(shell, ".exe");
1003
- if (shellType === "powershell") {
1004
- shellType = "pwsh";
1005
- }
1006
- const store = ( new DisposableStore());
1007
- return (new Promise(resolve => {
1008
- let resolved = false;
1009
- const resolveOnce = value => {
1010
- if (resolved) {
1011
- return;
1012
- }
1013
- resolved = true;
1014
- store.dispose();
1015
- resolve(value);
1016
- };
1017
- const part = ( new ChatElicitationRequestPart(
1018
- this._getAutomaticUnsandboxRetryTitle(shellType, blockedDomains),
1019
- ( new MarkdownString(( localize(
1020
- 14515,
1021
- "`{0}`",
1022
- escapeMarkdownSyntaxTokens(buildCommandDisplayText(command))
1023
- )))),
1024
- "",
1025
- ( localize(14516, "Allow")),
1026
- ( localize(14517, "Skip")),
1027
- async () => {
1028
- resolveOnce(true);
1029
- part.hide();
1030
- return ElicitationState.Accepted;
1031
- },
1032
- async () => {
1033
- resolveOnce(false);
1034
- part.hide();
1035
- return ElicitationState.Rejected;
1036
- },
1037
- undefined,
1038
- undefined,
1039
- () => resolveOnce(false),
1040
- riskAssessment
1041
- ));
1042
- chatModel.acceptResponseProgress(request, part);
1043
- store.add(token.onCancellationRequested(() => resolveOnce(false)));
1044
- store.add({
1045
- dispose: () => part.hide()
1046
- });
1047
- }));
1048
- }
1049
- _getAutomaticUnsandboxRetryTitle(shellType, blockedDomains) {
1050
- return blockedDomains?.length ? ( new MarkdownString(( localize(
1051
- 14518,
1052
- "Run `{0}` command outside the sandbox to access {1}?",
1053
- shellType,
1054
- this._formatBlockedDomainsForTitle(blockedDomains)
1055
- )))) : ( new MarkdownString(( localize(14519, "Run `{0}` command outside the sandbox?", shellType))));
1056
- }
1057
- _registerSensitiveInputElicitation(
1058
- chatSessionResource,
1059
- terminalInstance,
1060
- outputMonitor,
1061
- cancelExecution,
1062
- onAutoCancelled
1063
- ) {
1064
- const store = ( new DisposableStore());
1065
- let pending;
1066
- let autoCancelled = false;
1067
- store.add(outputMonitor.onDidDetectSensitiveInputNeeded(() => {
1068
- if (pending || autoCancelled) {
1069
- return;
1070
- }
1071
- const isAutoApproved = chatSessionResource && isSessionAutoApproveLevel(
1072
- chatSessionResource,
1073
- this._configurationService,
1074
- this._chatWidgetService,
1075
- this._chatService
1076
- );
1077
- const chatModel = chatSessionResource && this._chatService.getSession(chatSessionResource);
1078
- if (isAutoApproved) {
1079
- autoCancelled = true;
1080
- if (chatModel instanceof ChatModel) {
1081
- const request = chatModel.getRequests().at(-1);
1082
- if (request) {
1083
- const infoPart = ( new ChatElicitationRequestPart(( new MarkdownString(( localize(14520, "Terminal command cancelled — sensitive input required")))), ( new MarkdownString(( localize(
1084
- 14521,
1085
- "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."
1086
- )))), "", ( localize(14522, "Dismiss")), "", async () => {
1087
- infoPart.hide();
1088
- return ElicitationState.Accepted;
1089
- }, async () => {
1090
- infoPart.hide();
1091
- return ElicitationState.Rejected;
1092
- }, undefined, undefined, undefined, undefined));
1093
- chatModel.acceptResponseProgress(request, infoPart);
1094
- }
1095
- }
1096
- onAutoCancelled?.();
1097
- cancelExecution();
1098
- return;
1099
- }
1100
- if (!(chatModel instanceof ChatModel)) {
1101
- this._terminalService.setActiveInstance(terminalInstance);
1102
- this._terminalService.revealTerminal(terminalInstance, true).catch(() => {});
1103
- terminalInstance.focus();
1104
- return;
1105
- }
1106
- const request = chatModel.getRequests().at(-1);
1107
- if (!request) {
1108
- return;
1109
- }
1110
- const part = ( new ChatElicitationRequestPart(( new MarkdownString(( localize(14523, "Terminal is waiting for sensitive input")))), ( new MarkdownString(( localize(
1111
- 14524,
1112
- "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."
1113
- )))), "", ( localize(14525, "Focus Terminal")), ( localize(14526, "Cancel Command")), async () => {
1114
- pending = undefined;
1115
- part.hide();
1116
- try {
1117
- this._terminalService.setActiveInstance(terminalInstance);
1118
- await this._terminalService.revealTerminal(terminalInstance, true);
1119
- terminalInstance.focus();
1120
- } catch (err) {
1121
- this._logService.warn(`RunInTerminalTool: failed to reveal terminal for sensitive input`, err);
1122
- }
1123
- return ElicitationState.Accepted;
1124
- }, async () => {
1125
- pending = undefined;
1126
- part.hide();
1127
- cancelExecution();
1128
- return ElicitationState.Rejected;
1129
- }, undefined, undefined, () => {
1130
- pending = undefined;
1131
- }, undefined));
1132
- pending = part;
1133
- chatModel.acceptResponseProgress(request, part);
1134
- }));
1135
- return store;
1136
- }
1137
- _acceptAutomaticUnsandboxRetryToolInvocationUpdate(
1138
- sessionResource,
1139
- toolCallId,
1140
- toolSpecificData,
1141
- isComplete,
1142
- toolResultMessage
1143
- ) {
1144
- const chatModel = sessionResource && this._chatService.getSession(sessionResource);
1145
- if (!(chatModel instanceof ChatModel)) {
1146
- return;
1147
- }
1148
- const request = chatModel.getRequests().at(-1);
1149
- if (!request) {
1150
- return;
1151
- }
1152
- const displayCommand = buildCommandDisplayText(
1153
- toolSpecificData.commandLine.forDisplay ?? toolSpecificData.commandLine.toolEdited ?? toolSpecificData.commandLine.original
1154
- );
1155
- const progress = {
1156
- kind: "externalToolInvocationUpdate",
1157
- toolCallId,
1158
- toolName: ( localize(14482, "Run in Terminal")),
1159
- isComplete,
1160
- invocationMessage: ( new MarkdownString(( localize(
1161
- 14527,
1162
- "Running `{0}` outside the sandbox",
1163
- escapeMarkdownSyntaxTokens(displayCommand)
1164
- )))),
1165
- pastTenseMessage: toolResultMessage,
1166
- toolSpecificData
1167
- };
1168
- chatModel.acceptResponseProgress(request, progress);
1169
- }
1170
- async invoke(invocation, _countTokens, _progress, token) {
1171
- const toolSpecificData = invocation.toolSpecificData;
1172
- if (!toolSpecificData) {
1173
- throw ( new Error("toolSpecificData must be provided for this tool"));
1174
- }
1175
- if (!invocation.context) {
1176
- throw ( new Error("Invocation context must be provided for this tool"));
1177
- }
1178
- const commandId = toolSpecificData.terminalCommandId;
1179
- if (toolSpecificData.alternativeRecommendation) {
1180
- return {
1181
- content: [{
1182
- kind: "text",
1183
- value: toolSpecificData.alternativeRecommendation
1184
- }]
1185
- };
1186
- }
1187
- const args = invocation.parameters;
1188
- const allowUnsandboxedCommands = this._getAllowToRunUnsandboxedCommands(args);
1189
- const isSandboxEnabled = await this._terminalSandboxService.isEnabled();
1190
- if (this._shouldRejectUnsandboxedExecutionRequest(isSandboxEnabled, allowUnsandboxedCommands, args)) {
1191
- const message = this._getUnsandboxedExecutionDisabledMessage();
1192
- return {
1193
- toolResultError: message,
1194
- toolResultDetails: {
1195
- input: args.command,
1196
- output: [{
1197
- type: "embed",
1198
- isText: true,
1199
- value: message
1200
- }],
1201
- isError: true
1202
- },
1203
- content: [{
1204
- kind: "text",
1205
- value: message
1206
- }]
1207
- };
1208
- }
1209
- if (toolSpecificData.missingSandboxDependencies?.length) {
1210
- if (invocation.selectedCustomButton === "install") {
1211
- const sessionResource = invocation.context.sessionResource;
1212
- const {
1213
- exitCode
1214
- } = await this._terminalSandboxService.installMissingSandboxDependencies(toolSpecificData.missingSandboxDependencies, sessionResource, token, {
1215
- createTerminal: async () => this._terminalService.createTerminal({}),
1216
- focusTerminal: async terminal => {
1217
- this._terminalService.setActiveInstance(terminal);
1218
- await this._terminalService.revealTerminal(terminal, true);
1219
- terminal.focus();
1220
- }
1221
- });
1222
- if (exitCode !== undefined && exitCode !== 0) {
1223
- return {
1224
- content: [{
1225
- kind: "text",
1226
- value: ( localize(
1227
- 14528,
1228
- "Sandbox dependency installation failed (exit code {0}). The command was not executed.",
1229
- exitCode
1230
- ))
1231
- }]
1232
- };
1233
- }
1234
- if (exitCode === undefined) {
1235
- return {
1236
- content: [{
1237
- kind: "text",
1238
- value: ( localize(
1239
- 14529,
1240
- "Could not determine whether sandbox dependency installation succeeded. The command was not executed."
1241
- ))
1242
- }]
1243
- };
1244
- }
1245
- this._logService.info(
1246
- "RunInTerminalTool: Sandbox dependency installation succeeded, proceeding with command execution"
1247
- );
1248
- } else {
1249
- this._logService.info("RunInTerminalTool: User cancelled sandbox dependency installation");
1250
- return {
1251
- content: [{
1252
- kind: "text",
1253
- value: ( localize(14530, "Sandbox dependency installation was cancelled by the user."))
1254
- }]
1255
- };
1256
- }
1257
- }
1258
- const executionOptions = this._resolveExecutionOptions(args);
1259
- this._logService.debug(`RunInTerminalTool: Invoking with options ${JSON.stringify(args)}`);
1260
- let toolResultMessage;
1261
- if (args.timeout !== undefined && (Number.isNaN(args.timeout) || args.timeout < 0)) {
1262
- return {
1263
- content: [{
1264
- kind: "text",
1265
- value: "Error: timeout must be a non-negative number of milliseconds (use 0 for no timeout)."
1266
- }]
1267
- };
1268
- }
1269
- if (executionOptions.mode === "sync" && args.timeout === undefined) {
1270
- args.timeout = 0;
1271
- }
1272
- const chatSessionResource = invocation.context.sessionResource;
1273
- const shouldSendNotifications = !invocation.subAgentInvocationId;
1274
- const command = toolSpecificData.commandLine.userEdited ?? toolSpecificData.commandLine.toolEdited ?? toolSpecificData.commandLine.original;
1275
- const didUserEditCommand = (toolSpecificData.commandLine.userEdited !== undefined && toolSpecificData.commandLine.userEdited !== toolSpecificData.commandLine.original);
1276
- const didToolEditCommand = (!didUserEditCommand && toolSpecificData.commandLine.toolEdited !== undefined && toolSpecificData.commandLine.toolEdited !== toolSpecificData.commandLine.original &&
1277
- normalizeTerminalCommandForDisplay(toolSpecificData.commandLine.toolEdited).trim() !== normalizeTerminalCommandForDisplay(toolSpecificData.commandLine.original).trim());
1278
- const didSandboxWrapCommand = toolSpecificData.commandLine.isSandboxWrapped === true;
1279
- const commandLineForMetadata = isSandboxEnabled ? toolSpecificData.commandLine.forDisplay ?? toolSpecificData.commandLine.original : undefined;
1280
- if (token.isCancellationRequested) {
1281
- throw ( new CancellationError());
1282
- }
1283
- let error;
1284
- const automaticUnsandboxRetryReason = ( localize(
1285
- 14531,
1286
- "The sandboxed execution output indicated the sandbox blocked the command."
1287
- ));
1288
- const isNewSession = !executionOptions.persistentSession && !( this._sessionTerminalAssociations.has(chatSessionResource));
1289
- const timingStart = Date.now();
1290
- const termId = generateUuid();
1291
- const terminalToolSessionId = toolSpecificData.terminalToolSessionId;
1292
- const store = ( new DisposableStore());
1293
- this._logService.debug(
1294
- `RunInTerminalTool: Creating ${executionOptions.persistentSession ? "background" : "foreground"} terminal. termId=${termId}, chatSessionResource=${chatSessionResource}`
1295
- );
1296
- const toolTerminal = await this._initTerminal(
1297
- chatSessionResource,
1298
- termId,
1299
- terminalToolSessionId,
1300
- executionOptions.persistentSession,
1301
- token
1302
- );
1303
- this._handleTerminalVisibility(toolTerminal, chatSessionResource);
1304
- const timingConnectMs = Date.now() - timingStart;
1305
- const xterm = await toolTerminal.instance.xtermReadyPromise;
1306
- if (!xterm) {
1307
- throw ( new Error("Instance was disposed before xterm.js was ready"));
1308
- }
1309
- const commandDetection = toolTerminal.instance.capabilities.get(TerminalCapability.CommandDetection);
1310
- let inputUserChars = 0;
1311
- let inputUserSigint = false;
1312
- store.add(xterm.raw.onData(data => {
1313
- if (!telemetryIgnoredSequences.includes(data)) {
1314
- inputUserChars += data.length;
1315
- }
1316
- inputUserSigint ||= data === "\u0003";
1317
- }));
1318
- let terminalResult = "";
1319
- let outputLineCount = -1;
1320
- let exitCode;
1321
- let altBufferResult;
1322
- let didTimeout = false;
1323
- let didIdleSilence = false;
1324
- let didInputNeeded = false;
1325
- let didSensitiveAutoCancelled = false;
1326
- let isBackgroundExecution = executionOptions.persistentSession;
1327
- let timeoutPromise;
1328
- let timeoutRacePromise;
1329
- let outputMonitor;
1330
- let pollingResult;
1331
- const executeCancellation = store.add(( new CancellationTokenSource(token)));
1332
- const timeoutValue = args.timeout !== undefined ? clamp(args.timeout, 0, Number.MAX_SAFE_INTEGER) : undefined;
1333
- if (timeoutValue !== undefined && timeoutValue > 0) {
1334
- const shouldEnforceTimeout = executionOptions.waitStrategy === "idle" || this._configurationService.getValue(TerminalChatAgentToolsSettingId.EnforceTimeoutFromModel) === true;
1335
- if (shouldEnforceTimeout) {
1336
- timeoutPromise = timeout(timeoutValue);
1337
- timeoutRacePromise = timeoutPromise.then(() => ({
1338
- type: "timeout"
1339
- })).catch(() => ({
1340
- type: "timeout"
1341
- }));
1342
- }
1343
- }
1344
- let continueInBackgroundResolve;
1345
- const continueInBackgroundPromise = ( new Promise(resolve => {
1346
- continueInBackgroundResolve = resolve;
1347
- }));
1348
- if (terminalToolSessionId) {
1349
- store.add(this._terminalChatService.onDidContinueInBackground(sessionId => {
1350
- if (sessionId === terminalToolSessionId) {
1351
- const execution = RunInTerminalTool_1._activeExecutions.get(termId);
1352
- execution?.setBackground?.();
1353
- isBackgroundExecution = true;
1354
- continueInBackgroundResolve?.();
1355
- }
1356
- }));
1357
- }
1358
- let executionPromise;
1359
- try {
1360
- const execution = this._instantiationService.createInstance(
1361
- ActiveTerminalExecution,
1362
- chatSessionResource,
1363
- termId,
1364
- toolTerminal,
1365
- commandDetection,
1366
- executionOptions.persistentSession
1367
- );
1368
- this._logService.info(
1369
- `RunInTerminalTool: Using \`${execution.strategy.type}\` execute strategy for command \`${command}\``
1370
- );
1371
- store.add(execution);
1372
- RunInTerminalTool_1._activeExecutions.set(termId, execution);
1373
- const startMarkerPromise = Event.toPromise(execution.strategy.onDidCreateStartMarker);
1374
- const outputMonitorPollFn = executionOptions.persistentSession ? async executionForPoll => ({
1375
- output: executionForPoll.getOutput(),
1376
- state: OutputMonitorState.Idle
1377
- }) : undefined;
1378
- store.add(execution.strategy.onDidCreateStartMarker(startMarker => {
1379
- if (!outputMonitor) {
1380
- outputMonitor = this._instantiationService.createInstance(OutputMonitor, {
1381
- instance: toolTerminal.instance,
1382
- sessionResource: chatSessionResource,
1383
- getOutput: marker => execution.getOutput(marker ?? startMarker)
1384
- }, outputMonitorPollFn, invocation.context, token, command);
1385
- }
1386
- }));
1387
- executionPromise = execution.start(command, executeCancellation.token, commandId, commandLineForMetadata);
1388
- if (executionOptions.waitStrategy === "idle") {
1389
- this._logService.debug(
1390
- `RunInTerminalTool: Starting persistent execution with idle wait strategy \`${command}\``
1391
- );
1392
- await startMarkerPromise;
1393
- let idleTimedOut = false;
1394
- if (outputMonitor) {
1395
- if (timeoutRacePromise) {
1396
- const idleRace = await Promise.race([Event.toPromise(outputMonitor.onDidFinishCommand).then(() => ({
1397
- type: "idle"
1398
- })), timeoutRacePromise]);
1399
- if (idleRace.type === "timeout") {
1400
- idleTimedOut = true;
1401
- this._logService.debug(
1402
- `RunInTerminalTool: Timeout reached waiting for idle signal, returning output collected so far`
1403
- );
1404
- } else {
1405
- pollingResult = outputMonitor.pollingResult;
1406
- }
1407
- } else {
1408
- await Event.toPromise(outputMonitor.onDidFinishCommand);
1409
- pollingResult = outputMonitor.pollingResult;
1410
- }
1411
- }
1412
- await this._commandArtifactCollector.capture(toolSpecificData, toolTerminal.instance, commandId);
1413
- if (token.isCancellationRequested) {
1414
- throw ( new CancellationError());
1415
- }
1416
- const state = toolSpecificData.terminalCommandState ?? {};
1417
- state.timestamp = state.timestamp ?? timingStart;
1418
- toolSpecificData.terminalCommandState = state;
1419
- let resultText = (didSandboxWrapCommand ? `Command is now running in terminal with ID=${termId}` : didUserEditCommand ? `Note: The user manually edited the command to \`${command}\`, and that command is now running in terminal with ID=${termId}` : didToolEditCommand ? `Note: The tool simplified the command to \`${command}\`, and that command is now running in terminal with ID=${termId}` : `Command is running in terminal with ID=${termId}`);
1420
- const backgroundOutput = pollingResult?.output ?? (idleTimedOut ? execution.getOutput() : undefined);
1421
- const outputAnalyzerMessage = backgroundOutput ? await this._getOutputAnalyzerMessage(undefined, backgroundOutput, command, didSandboxWrapCommand) : undefined;
1422
- if (idleTimedOut) {
1423
- resultText += `\n Timed out waiting for the command to become idle. The command is still running, with output:\n`;
1424
- if (outputAnalyzerMessage) {
1425
- resultText += `${outputAnalyzerMessage}\n`;
1426
- }
1427
- resultText += backgroundOutput ?? "";
1428
- } else if (pollingResult && pollingResult.state === OutputMonitorState.Idle) {
1429
- resultText += `\n The command became idle with output:\n`;
1430
- if (outputAnalyzerMessage) {
1431
- resultText += `${outputAnalyzerMessage}\n`;
1432
- }
1433
- resultText += pollingResult.output;
1434
- resultText += `\n${this._buildInputNeededSteeringText(chatSessionResource, termId, "none")}`;
1435
- } else if (pollingResult) {
1436
- resultText += `\n The command is still running, with output:\n`;
1437
- if (outputAnalyzerMessage) {
1438
- resultText += `${outputAnalyzerMessage}\n`;
1439
- }
1440
- resultText += pollingResult.output;
1441
- }
1442
- const endCwd = await toolTerminal.instance.getCwdResource();
1443
- return {
1444
- toolMetadata: {
1445
- exitCode: undefined,
1446
- id: termId,
1447
- terminalId: toolTerminal.instance.instanceId,
1448
- cwd: endCwd?.toString()
1449
- },
1450
- content: [{
1451
- kind: "text",
1452
- value: resultText
1453
- }]
1454
- };
1455
- } else {
1456
- const raceCleanup = ( new DisposableStore());
1457
- startMarkerPromise.then(() => {
1458
- if (outputMonitor && !raceCleanup.isDisposed) {
1459
- raceCleanup.add(this._registerSensitiveInputElicitation(
1460
- chatSessionResource,
1461
- toolTerminal.instance,
1462
- outputMonitor,
1463
- () => executeCancellation.cancel(),
1464
- () => {
1465
- didSensitiveAutoCancelled = true;
1466
- }
1467
- ));
1468
- }
1469
- });
1470
- const raceCandidates = [executionPromise.then(result => ({
1471
- type: "completed",
1472
- result
1473
- })), continueInBackgroundPromise.then(() => ({
1474
- type: "background"
1475
- })), ( new Promise(resolve => {
1476
- startMarkerPromise.then(() => {
1477
- if (outputMonitor && !raceCleanup.isDisposed) {
1478
- raceCleanup.add(outputMonitor.onDidDetectInputNeeded(() => resolve({
1479
- type: "inputNeeded"
1480
- })));
1481
- }
1482
- });
1483
- }))];
1484
- if (timeoutRacePromise) {
1485
- raceCandidates.push(timeoutRacePromise);
1486
- }
1487
- const idleSilenceMs = this._configurationService.getValue(TerminalChatAgentToolsSettingId.IdleSilenceTimeoutMs) ?? 60000;
1488
- if (idleSilenceMs > 0) {
1489
- const idleSilenceDeferred = ( new DeferredPromise());
1490
- const idleSilenceScheduler = raceCleanup.add(( new RunOnceScheduler(() => idleSilenceDeferred.complete({
1491
- type: "idleSilence"
1492
- }), idleSilenceMs)));
1493
- raceCleanup.add(toolTerminal.instance.onData(() => idleSilenceScheduler.schedule()));
1494
- idleSilenceScheduler.schedule();
1495
- raceCandidates.push(idleSilenceDeferred.p);
1496
- }
1497
- let raceResult;
1498
- try {
1499
- raceResult = await Promise.race(raceCandidates);
1500
- } finally {
1501
- raceCleanup.dispose();
1502
- }
1503
- if (raceResult.type === "inputNeeded") {
1504
- this._logService.debug(
1505
- `RunInTerminalTool: Output monitor detected input needed in foreground terminal, returning output to agent`
1506
- );
1507
- error = "inputNeeded";
1508
- didInputNeeded = true;
1509
- const idleOutput = execution.getOutput();
1510
- outputLineCount = idleOutput ? count(idleOutput.trim(), "\n") + 1 : 0;
1511
- terminalResult = idleOutput ?? "";
1512
- } else if (raceResult.type === "background") {
1513
- this._logService.debug(
1514
- `RunInTerminalTool: Continue in background triggered, returning output collected so far`
1515
- );
1516
- error = "continueInBackground";
1517
- const backgroundOutput = execution.getOutput();
1518
- outputLineCount = backgroundOutput ? count(backgroundOutput.trim(), "\n") + 1 : 0;
1519
- terminalResult = backgroundOutput;
1520
- } else if (raceResult.type === "timeout") {
1521
- this._logService.debug(`RunInTerminalTool: Timeout reached, returning output collected so far`);
1522
- error = "timeout";
1523
- didTimeout = true;
1524
- isBackgroundExecution = true;
1525
- toolTerminal.isBackground = true;
1526
- toolSpecificData.didContinueInBackground = true;
1527
- this._sessionTerminalAssociations.delete(chatSessionResource);
1528
- await this._associateProcessIdWithSession(
1529
- toolTerminal.instance,
1530
- chatSessionResource,
1531
- termId,
1532
- toolTerminal.shellIntegrationQuality,
1533
- true
1534
- );
1535
- const timeoutOutput = execution.getOutput();
1536
- outputLineCount = timeoutOutput ? count(timeoutOutput.trim(), "\n") + 1 : 0;
1537
- terminalResult = timeoutOutput ?? "";
1538
- } else if (raceResult.type === "idleSilence") {
1539
- this._logService.debug(
1540
- `RunInTerminalTool: Idle silence reached (${idleSilenceMs}ms), promoting to background`
1541
- );
1542
- error = "idleSilence";
1543
- didIdleSilence = true;
1544
- isBackgroundExecution = true;
1545
- toolTerminal.isBackground = true;
1546
- toolSpecificData.didContinueInBackground = true;
1547
- this._sessionTerminalAssociations.delete(chatSessionResource);
1548
- await this._associateProcessIdWithSession(
1549
- toolTerminal.instance,
1550
- chatSessionResource,
1551
- termId,
1552
- toolTerminal.shellIntegrationQuality,
1553
- true
1554
- );
1555
- const idleSilenceOutput = execution.getOutput();
1556
- outputLineCount = idleSilenceOutput ? count(idleSilenceOutput.trim(), "\n") + 1 : 0;
1557
- terminalResult = idleSilenceOutput ?? "";
1558
- } else {
1559
- const executeResult = raceResult.result;
1560
- toolTerminal.receivedUserInput = false;
1561
- if (token.isCancellationRequested) {
1562
- throw ( new CancellationError());
1563
- }
1564
- if (executeResult.didEnterAltBuffer) {
1565
- const state = toolSpecificData.terminalCommandState ?? {};
1566
- state.timestamp = state.timestamp ?? timingStart;
1567
- toolSpecificData.terminalCommandState = state;
1568
- toolResultMessage = altBufferMessage;
1569
- outputLineCount = 0;
1570
- error = executeResult.error ?? "alternateBuffer";
1571
- const altBufferCwd = await toolTerminal.instance.getCwdResource();
1572
- altBufferResult = {
1573
- toolResultMessage,
1574
- toolMetadata: {
1575
- exitCode: undefined,
1576
- id: termId,
1577
- terminalId: toolTerminal.instance.instanceId,
1578
- cwd: altBufferCwd?.toString()
1579
- },
1580
- content: [{
1581
- kind: "text",
1582
- value: altBufferMessage
1583
- }]
1584
- };
1585
- } else {
1586
- await this._commandArtifactCollector.capture(toolSpecificData, toolTerminal.instance, commandId);
1587
- {
1588
- const state = toolSpecificData.terminalCommandState ?? {};
1589
- state.timestamp = state.timestamp ?? timingStart;
1590
- if (executeResult.exitCode !== undefined) {
1591
- state.exitCode = executeResult.exitCode;
1592
- if (state.timestamp !== undefined) {
1593
- state.duration = state.duration ?? Math.max(0, Date.now() - state.timestamp);
1594
- }
1595
- }
1596
- toolSpecificData.terminalCommandState = state;
1597
- }
1598
- this._logService.info(
1599
- `RunInTerminalTool: Finished \`${execution.strategy.type}\` execute strategy with exitCode \`${executeResult.exitCode}\`, result.length \`${executeResult.output?.length}\`, error \`${executeResult.error}\``
1600
- );
1601
- outputLineCount = executeResult.output === undefined ? 0 : count(executeResult.output.trim(), "\n") + 1;
1602
- exitCode = executeResult.exitCode;
1603
- error = executeResult.error;
1604
- const resultArr = [];
1605
- if (executeResult.output !== undefined) {
1606
- resultArr.push(executeResult.output);
1607
- }
1608
- if (executeResult.additionalInformation) {
1609
- resultArr.push(executeResult.additionalInformation);
1610
- }
1611
- terminalResult = resultArr.join("\n\n");
1612
- }
1613
- }
1614
- }
1615
- } catch (e) {
1616
- if (didTimeout && e instanceof CancellationError) {
1617
- this._logService.debug(`RunInTerminalTool: Timeout reached, returning output collected so far`);
1618
- error = "timeout";
1619
- isBackgroundExecution = true;
1620
- toolTerminal.isBackground = true;
1621
- toolSpecificData.didContinueInBackground = true;
1622
- this._sessionTerminalAssociations.delete(chatSessionResource);
1623
- const timeoutOutput = getOutput(toolTerminal.instance, undefined);
1624
- outputLineCount = timeoutOutput ? count(timeoutOutput.trim(), "\n") + 1 : 0;
1625
- terminalResult = timeoutOutput ?? "";
1626
- } else {
1627
- this._logService.debug(`RunInTerminalTool: Threw exception`);
1628
- if (e instanceof CancellationError) {
1629
- await this._commandArtifactCollector.capture(toolSpecificData, toolTerminal.instance, commandId);
1630
- const state = toolSpecificData.terminalCommandState ?? {};
1631
- if (state.exitCode === undefined) {
1632
- state.exitCode = -1;
1633
- state.timestamp = state.timestamp ?? timingStart;
1634
- state.duration = state.duration ?? Math.max(0, Date.now() - state.timestamp);
1635
- }
1636
- toolSpecificData.terminalCommandState = state;
1637
- }
1638
- RunInTerminalTool_1._activeExecutions.get(termId)?.dispose();
1639
- RunInTerminalTool_1._activeExecutions.delete(termId);
1640
- toolTerminal.instance.dispose();
1641
- error = e instanceof CancellationError ? "canceled" : "unexpectedException";
1642
- throw e;
1643
- }
1644
- } finally {
1645
- timeoutPromise?.cancel();
1646
- if ((isBackgroundExecution || didInputNeeded) && executionPromise) {
1647
- executionPromise.catch(e => {
1648
- if (!(e instanceof CancellationError)) {
1649
- this._logService.error(`RunInTerminalTool: Background execution error`, e);
1650
- }
1651
- });
1652
- if (shouldSendNotifications) {
1653
- const alreadyNotifiedInputNeededOutput = didInputNeeded ? terminalResult : undefined;
1654
- this._registerCompletionNotification(
1655
- toolTerminal.instance,
1656
- termId,
1657
- chatSessionResource,
1658
- command,
1659
- toolSpecificData,
1660
- outputMonitor,
1661
- alreadyNotifiedInputNeededOutput
1662
- );
1663
- } else {
1664
- outputMonitor?.dispose();
1665
- }
1666
- } else {
1667
- RunInTerminalTool_1._activeExecutions.get(termId)?.dispose();
1668
- RunInTerminalTool_1._activeExecutions.delete(termId);
1669
- outputMonitor?.dispose();
1670
- }
1671
- store.dispose();
1672
- const timingExecuteMs = Date.now() - timingStart;
1673
- this._telemetry.logInvoke(toolTerminal.instance, {
1674
- terminalToolSessionId: toolSpecificData.terminalToolSessionId,
1675
- didUserEditCommand,
1676
- didToolEditCommand,
1677
- isBackground: executionOptions.persistentSession,
1678
- isSandboxWrapped: toolSpecificData.commandLine.isSandboxWrapped === true,
1679
- requestUnsandboxedExecutionReason: args.requestUnsandboxedExecutionReason,
1680
- shellIntegrationQuality: toolTerminal.shellIntegrationQuality,
1681
- error,
1682
- isNewSession,
1683
- outputLineCount,
1684
- exitCode,
1685
- timingExecuteMs,
1686
- timingConnectMs,
1687
- inputUserChars,
1688
- inputUserSigint,
1689
- terminalExecutionIdleBeforeTimeout: pollingResult?.state === OutputMonitorState.Idle,
1690
- pollDurationMs: pollingResult?.pollDurationMs,
1691
- inputToolManualAcceptCount: outputMonitor?.outputMonitorTelemetryCounters?.inputToolManualAcceptCount,
1692
- inputToolManualRejectCount: outputMonitor?.outputMonitorTelemetryCounters?.inputToolManualRejectCount,
1693
- inputToolManualChars: outputMonitor?.outputMonitorTelemetryCounters?.inputToolManualChars,
1694
- inputToolAutoAcceptCount: outputMonitor?.outputMonitorTelemetryCounters?.inputToolAutoAcceptCount,
1695
- inputToolAutoChars: outputMonitor?.outputMonitorTelemetryCounters?.inputToolAutoChars,
1696
- inputToolManualShownCount: outputMonitor?.outputMonitorTelemetryCounters?.inputToolManualShownCount,
1697
- inputToolFreeFormInputCount: outputMonitor?.outputMonitorTelemetryCounters?.inputToolFreeFormInputCount,
1698
- inputToolFreeFormInputShownCount: outputMonitor?.outputMonitorTelemetryCounters?.inputToolFreeFormInputShownCount
1699
- });
1700
- }
1701
- if (altBufferResult) {
1702
- return altBufferResult;
1703
- }
1704
- const shouldAutoRetryUnsandboxed = shouldAutomaticallyRetryUnsandboxed({
1705
- allowUnsandboxedCommands,
1706
- didSandboxWrapCommand,
1707
- requestUnsandboxedExecution: args.requestUnsandboxedExecution === true,
1708
- isPersistentSession: executionOptions.persistentSession,
1709
- isBackgroundExecution: isBackgroundExecution || didInputNeeded,
1710
- didTimeout,
1711
- exitCode,
1712
- output: terminalResult
1713
- });
1714
- if (shouldAutoRetryUnsandboxed) {
1715
- const requestUnsandboxedExecution = allowUnsandboxedCommands;
1716
- const [os, shell] = await Promise.all([this._osBackend, this._profileFetcher.getCopilotShell()]);
1717
- const retryReason = automaticUnsandboxRetryReason;
1718
- const retryRewriteResult = await this._rewriteCommandLine(args.command, {
1719
- cwd: toolSpecificData.cwd ? URI.revive(toolSpecificData.cwd) : undefined,
1720
- shell,
1721
- os,
1722
- isBackground: executionOptions.persistentSession,
1723
- requestUnsandboxedExecution,
1724
- requestUnsandboxedExecutionReason: retryReason
1725
- });
1726
- const rewrittenRetryReason = retryRewriteResult.requestUnsandboxedExecutionReason ?? retryReason;
1727
- const retryConfirmationCommand = toolSpecificData.presentationOverrides?.commandLine ?? command;
1728
- const retryRiskAssessment = {
1729
- toolId: TerminalToolId.RunInTerminal,
1730
- parameters: {
1731
- ...args,
1732
- command: retryRewriteResult.rewrittenCommand,
1733
- allowToRunUnsandboxedCommands: allowUnsandboxedCommands,
1734
- requestUnsandboxedExecution
1735
- }
1736
- };
1737
- const shouldRetry = await this._confirmAutomaticUnsandboxRetry(
1738
- invocation.context.sessionResource,
1739
- retryConfirmationCommand,
1740
- shell,
1741
- retryRewriteResult.blockedDomains,
1742
- retryRiskAssessment,
1743
- token
1744
- );
1745
- if (shouldRetry) {
1746
- const retryToolSpecificData = {
1747
- ...toolSpecificData,
1748
- terminalCommandId: `tool-${generateUuid()}`,
1749
- commandLine: {
1750
- original: args.command,
1751
- toolEdited: retryRewriteResult.rewrittenCommand === args.command ? undefined : retryRewriteResult.rewrittenCommand,
1752
- forDisplay: retryRewriteResult.forDisplayCommand ?? normalizeTerminalCommandForDisplay(retryRewriteResult.rewrittenCommand ?? args.command),
1753
- isSandboxWrapped: retryRewriteResult.isSandboxWrapped
1754
- },
1755
- requestUnsandboxedExecution,
1756
- requestUnsandboxedExecutionReason: rewrittenRetryReason,
1757
- terminalCommandUri: undefined,
1758
- terminalCommandOutput: undefined,
1759
- terminalTheme: undefined,
1760
- terminalCommandState: undefined,
1761
- didContinueInBackground: undefined
1762
- };
1763
- const retryToolCallId = `automatic-unsandbox-retry-${generateUuid()}`;
1764
- this._acceptAutomaticUnsandboxRetryToolInvocationUpdate(
1765
- invocation.context.sessionResource,
1766
- retryToolCallId,
1767
- retryToolSpecificData,
1768
- false
1769
- );
1770
- return await this.invoke({
1771
- ...invocation,
1772
- parameters: {
1773
- ...args,
1774
- command: args.command,
1775
- allowToRunUnsandboxedCommands: allowUnsandboxedCommands,
1776
- requestUnsandboxedExecution,
1777
- requestUnsandboxedExecutionReason: rewrittenRetryReason
1778
- },
1779
- toolSpecificData: retryToolSpecificData
1780
- }, _countTokens, _progress, token);
1781
- }
1782
- }
1783
- this._terminalToolCreator.refreshShellIntegrationQuality(toolTerminal);
1784
- this._logService.info(
1785
- `RunInTerminalTool: shellIntegrationQuality=${toolTerminal.shellIntegrationQuality} at banner decision time`
1786
- );
1787
- if (!toolResultMessage && toolTerminal.shellIntegrationQuality === ShellIntegrationQuality.None) {
1788
- toolResultMessage = "$(info) Enable [shell integration](https://code.visualstudio.com/docs/terminal/shell-integration) to improve command detection";
1789
- }
1790
- const resultText = [];
1791
- if (!didSandboxWrapCommand) {
1792
- if (didUserEditCommand) {
1793
- resultText.push(
1794
- `Note: The user manually edited the command to \`${command}\` (terminal ID=${termId}), and this is the output of running that command instead:\n`
1795
- );
1796
- } else if (didToolEditCommand) {
1797
- const wasDetachedToBackground = /(^|\s)nohup\s|Start-Process\b/.test(command);
1798
- 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." : "";
1799
- resultText.push(
1800
- `Note: The tool simplified the command to \`${command}\` (terminal ID=${termId}).${stdinHint} This is the output of running that command instead:\n`
1801
- );
1802
- }
1803
- if (isBackgroundExecution && !executionOptions.persistentSession) {
1804
- resultText.push(
1805
- `Note: This terminal execution was moved to the background using the ID ${termId}\n`
1806
- );
1807
- }
1808
- }
1809
- if (didSensitiveAutoCancelled) {
1810
- resultText.push(
1811
- `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`
1812
- );
1813
- } else if (didInputNeeded) {
1814
- resultText.push(
1815
- `Note: The command is running in terminal ID ${termId} and may be waiting for input.\n${this._buildInputNeededSteeringText(chatSessionResource, termId, "none")}\n\n`
1816
- );
1817
- } else if (didTimeout && timeoutValue !== undefined && timeoutValue > 0) {
1818
- const notificationHint = shouldSendNotifications ? " You will be automatically notified on your next turn when it completes." : "";
1819
- resultText.push(
1820
- `Note: Command timed out after ${timeoutValue}ms. The command may still be running in terminal ID ${termId}.${notificationHint}\n${this._buildInputNeededSteeringText(chatSessionResource, termId, "timeout")}\n\n`
1821
- );
1822
- } else if (didIdleSilence) {
1823
- const notificationHint = shouldSendNotifications ? " You will be automatically notified on your next turn when it completes." : "";
1824
- resultText.push(
1825
- `Note: The command produced no new output for an extended period and was moved to background terminal ID ${termId}; the process is still running and has not been killed.${notificationHint}\n${this._buildInputNeededSteeringText(chatSessionResource, termId, "idleSilence")}\n\n`
1826
- );
1827
- }
1828
- const outputAnalyzerMessage = await this._getOutputAnalyzerMessage(exitCode, terminalResult, command, didSandboxWrapCommand);
1829
- if (outputAnalyzerMessage) {
1830
- resultText.push(`${outputAnalyzerMessage}\n`);
1831
- }
1832
- resultText.push(terminalResult);
1833
- const isError = exitCode !== undefined && exitCode !== 0;
1834
- const endCwd = await toolTerminal.instance.getCwdResource();
1835
- const imageContent = await this._extractImagesFromOutput(terminalResult, endCwd);
1836
- return {
1837
- toolResultMessage,
1838
- toolMetadata: {
1839
- exitCode: exitCode,
1840
- id: termId,
1841
- terminalId: toolTerminal.instance.instanceId,
1842
- cwd: endCwd?.toString(),
1843
- timedOut: didTimeout || undefined,
1844
- timeoutMs: didTimeout ? timeoutValue : undefined,
1845
- inputNeeded: didInputNeeded || undefined
1846
- },
1847
- toolResultDetails: isError ? {
1848
- input: command,
1849
- output: [{
1850
- type: "embed",
1851
- isText: true,
1852
- value: terminalResult
1853
- }],
1854
- isError: true
1855
- } : undefined,
1856
- content: [{
1857
- kind: "text",
1858
- value: resultText.join("")
1859
- }, ...imageContent]
1860
- };
1861
- }
1862
- _buildInputNeededSteeringText(chatSessionResource, termId, hungHint) {
1863
- const isAutoApproved = isSessionAutoApproveLevel(
1864
- chatSessionResource,
1865
- this._configurationService,
1866
- this._chatWidgetService,
1867
- this._chatService
1868
- );
1869
- const lines = [];
1870
- lines.push(
1871
- `This note is not a signal to end the turn — pick one of the actions below and continue.`
1872
- );
1873
- if (isAutoApproved) {
1874
- lines.push(
1875
- ` 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.`
1876
- );
1877
- lines.push(
1878
- ` 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.`
1879
- );
1880
- } else {
1881
- lines.push(
1882
- ` 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.`
1883
- );
1884
- lines.push(
1885
- ` 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.`
1886
- );
1887
- }
1888
- if (hungHint === "timeout") {
1889
- lines.push(
1890
- ` 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.`
1891
- );
1892
- } else if (hungHint === "idleSilence") {
1893
- lines.push(
1894
- ` 3. Producing no output for an extended period 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.`
1895
- );
1896
- }
1897
- return lines.join("\n");
1898
- }
1899
- async _getOutputAnalyzerMessage(exitCode, exitResult, commandLine, isSandboxWrapped) {
1900
- for (const analyzer of this._outputAnalyzers) {
1901
- const message = await analyzer.analyze({
1902
- exitCode,
1903
- exitResult,
1904
- commandLine,
1905
- isSandboxWrapped
1906
- });
1907
- if (message) {
1908
- return message;
1909
- }
1910
- }
1911
- return undefined;
1912
- }
1913
- static {
1914
- this._maxImageFileSize = 5 * 1024 * 1024;
1915
- }
1916
- async _extractImagesFromOutput(output, cwd) {
1917
- const pathPattern = /[^\s/\\]*(?:[/\\][^\s/\\]*)+\.(?:png|jpe?g|gif|webp|bmp)/gi;
1918
- const matches = ( new Set());
1919
- for (const line of output.split(/\r?\n/)) {
1920
- if (line.length > 10_000) {
1921
- continue;
1922
- }
1923
- for (const match of line.matchAll(pathPattern)) {
1924
- matches.add(match[0]);
1925
- }
1926
- }
1927
- if (matches.size === 0) {
1928
- return [];
1929
- }
1930
- const results = [];
1931
- for (const filePath of matches) {
1932
- try {
1933
- const mimeType = getMediaMime(filePath);
1934
- if (!mimeType || !mimeType.startsWith("image/")) {
1935
- continue;
1936
- }
1937
- let fileUri;
1938
- if (/^\/|^[A-Za-z]:[\\\/]/.test(filePath)) {
1939
- fileUri = URI.file(filePath);
1940
- } else if (cwd) {
1941
- fileUri = URI.joinPath(cwd, filePath);
1942
- } else {
1943
- continue;
1944
- }
1945
- const stat = await this._fileService.stat(fileUri).catch(() => undefined);
1946
- if (!stat || stat.isDirectory || stat.size > RunInTerminalTool_1._maxImageFileSize) {
1947
- continue;
1948
- }
1949
- const fileContent = await this._fileService.readFile(fileUri);
1950
- results.push({
1951
- kind: "data",
1952
- value: {
1953
- mimeType,
1954
- data: fileContent.value
1955
- },
1956
- audience: [LanguageModelPartAudience.User]
1957
- });
1958
- } catch {}
1959
- }
1960
- return results;
1961
- }
1962
- _handleTerminalVisibility(toolTerminal, chatSessionResource) {
1963
- const chatSessionOpenInWidget = !!this._chatWidgetService.getWidgetBySessionResource(chatSessionResource);
1964
- if (this._configurationService.getValue(TerminalChatAgentToolsSettingId.OutputLocation) === "terminal" && chatSessionOpenInWidget) {
1965
- this._terminalService.setActiveInstance(toolTerminal.instance);
1966
- this._terminalService.revealTerminal(toolTerminal.instance, true);
1967
- }
1968
- }
1969
- async _initTerminal(chatSessionResource, termId, terminalToolSessionId, isBackground, token) {
1970
- if (!isBackground) {
1971
- const cachedTerminal = this._sessionTerminalAssociations.get(chatSessionResource);
1972
- if (cachedTerminal && !cachedTerminal.isBackground && !cachedTerminal.instance.isDisposed) {
1973
- if (cachedTerminal.instance.exitCode !== undefined) {
1974
- this._logService.info(
1975
- `RunInTerminalTool: Cached terminal shell has exited (code=${cachedTerminal.instance.exitCode}), creating a new terminal`
1976
- );
1977
- this._sessionTerminalAssociations.delete(chatSessionResource);
1978
- } else {
1979
- this._logService.debug(
1980
- `RunInTerminalTool: Using cached terminal with session resource \`${chatSessionResource}\``
1981
- );
1982
- this._terminalToolCreator.refreshShellIntegrationQuality(cachedTerminal);
1983
- this._terminalChatService.registerTerminalInstanceWithToolSession(terminalToolSessionId, cachedTerminal.instance);
1984
- this._backgroundNotifications.deleteAndDispose(cachedTerminal.instance.instanceId);
1985
- return cachedTerminal;
1986
- }
1987
- }
1988
- }
1989
- this._logService.debug(
1990
- `RunInTerminalTool: Creating ${isBackground ? "background" : "foreground"} terminal with ID=${termId}`
1991
- );
1992
- const profile = await this._profileFetcher.getCopilotProfile();
1993
- const os = await this._osBackend;
1994
- const toolTerminal = await this._terminalToolCreator.createTerminal(profile, os, token);
1995
- toolTerminal.isBackground = isBackground;
1996
- this._terminalChatService.registerTerminalInstanceWithToolSession(terminalToolSessionId, toolTerminal.instance);
1997
- this._terminalChatService.registerTerminalInstanceWithChatSession(chatSessionResource, toolTerminal.instance);
1998
- this._registerInputListener(toolTerminal);
1999
- this._addSessionTerminalAssociation(chatSessionResource, toolTerminal);
2000
- if (token.isCancellationRequested) {
2001
- toolTerminal.instance.dispose();
2002
- throw ( new CancellationError());
2003
- }
2004
- await this._setupProcessIdAssociation(toolTerminal, chatSessionResource, termId, isBackground);
2005
- return toolTerminal;
2006
- }
2007
- _registerInputListener(toolTerminal) {
2008
- const disposable = toolTerminal.instance.onData(data => {
2009
- if (!telemetryIgnoredSequences.includes(data)) {
2010
- toolTerminal.receivedUserInput = data.length > 0;
2011
- }
2012
- });
2013
- Event.once(toolTerminal.instance.onDisposed)(() => disposable.dispose());
2014
- }
2015
- _restoreTerminalAssociations() {
2016
- const storedAssociations = this._storageService.get(
2017
- TerminalToolStorageKeysInternal.TerminalSession,
2018
- StorageScope.WORKSPACE,
2019
- "{}"
2020
- );
2021
- try {
2022
- const associations = JSON.parse(storedAssociations);
2023
- for (const instance of this._terminalService.instances) {
2024
- if (instance.processId) {
2025
- const association = associations[instance.processId];
2026
- if (association) {
2027
- const chatSessionResource = LocalChatSessionUri.forSession(association.sessionId);
2028
- this._logService.debug(
2029
- `RunInTerminalTool: Restored terminal association for PID ${instance.processId}, session ${association.sessionId}`
2030
- );
2031
- const toolTerminal = {
2032
- instance,
2033
- shellIntegrationQuality: association.shellIntegrationQuality,
2034
- isBackground: association.isBackground
2035
- };
2036
- this._addSessionTerminalAssociation(chatSessionResource, toolTerminal);
2037
- this._terminalChatService.registerTerminalInstanceWithChatSession(chatSessionResource, instance);
2038
- if (association.id) {
2039
- RunInTerminalTool_1._activeExecutions.set(association.id, this._register(( new RestoredTerminalExecution(instance))));
2040
- }
2041
- Event.once(instance.onDisposed)(() => {
2042
- this._removeProcessIdAssociation(instance.processId);
2043
- this._removeExecutionAssociations(instance);
2044
- });
2045
- }
2046
- }
2047
- }
2048
- } catch (error) {
2049
- this._logService.debug(`RunInTerminalTool: Failed to restore terminal associations: ${error}`);
2050
- }
2051
- }
2052
- async _setupProcessIdAssociation(toolTerminal, chatSessionResource, termId, isBackground) {
2053
- await this._associateProcessIdWithSession(
2054
- toolTerminal.instance,
2055
- chatSessionResource,
2056
- termId,
2057
- toolTerminal.shellIntegrationQuality,
2058
- isBackground
2059
- );
2060
- Event.once(toolTerminal.instance.onDisposed)(() => {
2061
- if (toolTerminal.instance.processId) {
2062
- this._removeProcessIdAssociation(toolTerminal.instance.processId);
2063
- }
2064
- });
2065
- }
2066
- async _associateProcessIdWithSession(terminal, chatSessionResource, id, shellIntegrationQuality, isBackground) {
2067
- try {
2068
- const pid = await Promise.race([
2069
- terminal.processReady.then(() => terminal.processId),
2070
- timeout(5000).then(() => {
2071
- throw ( new Error("Timeout"));
2072
- })
2073
- ]);
2074
- if (isNumber(pid)) {
2075
- const storedAssociations = this._storageService.get(
2076
- TerminalToolStorageKeysInternal.TerminalSession,
2077
- StorageScope.WORKSPACE,
2078
- "{}"
2079
- );
2080
- const associations = JSON.parse(storedAssociations);
2081
- const sessionId = chatSessionResourceToId(chatSessionResource);
2082
- const existingAssociation = associations[pid] || {};
2083
- associations[pid] = {
2084
- ...existingAssociation,
2085
- sessionId,
2086
- shellIntegrationQuality,
2087
- id,
2088
- isBackground
2089
- };
2090
- this._storageService.store(
2091
- TerminalToolStorageKeysInternal.TerminalSession,
2092
- JSON.stringify(associations),
2093
- StorageScope.WORKSPACE,
2094
- StorageTarget.USER
2095
- );
2096
- this._logService.debug(
2097
- `RunInTerminalTool: Associated terminal PID ${pid} with session ${sessionId}`
2098
- );
2099
- }
2100
- } catch (error) {
2101
- this._logService.debug(`RunInTerminalTool: Failed to associate terminal with session: ${error}`);
2102
- }
2103
- }
2104
- async _removeProcessIdAssociation(pid) {
2105
- try {
2106
- const storedAssociations = this._storageService.get(
2107
- TerminalToolStorageKeysInternal.TerminalSession,
2108
- StorageScope.WORKSPACE,
2109
- "{}"
2110
- );
2111
- const associations = JSON.parse(storedAssociations);
2112
- if (associations[pid]) {
2113
- delete associations[pid];
2114
- this._storageService.store(
2115
- TerminalToolStorageKeysInternal.TerminalSession,
2116
- JSON.stringify(associations),
2117
- StorageScope.WORKSPACE,
2118
- StorageTarget.USER
2119
- );
2120
- this._logService.debug(`RunInTerminalTool: Removed terminal association for PID ${pid}`);
2121
- }
2122
- } catch (error) {
2123
- this._logService.debug(`RunInTerminalTool: Failed to remove terminal association: ${error}`);
2124
- }
2125
- }
2126
- _cleanupSessionTerminals(chatSessionResource) {
2127
- const sessionTerminals = this._sessionTerminalInstances.get(chatSessionResource);
2128
- const toolTerminal = this._sessionTerminalAssociations.get(chatSessionResource);
2129
- const terminalsToDispose = sessionTerminals ?? (toolTerminal ? ( new Set([toolTerminal.instance])) : undefined);
2130
- if (!terminalsToDispose || terminalsToDispose.size === 0) {
2131
- return;
2132
- }
2133
- this._logService.debug(
2134
- `RunInTerminalTool: Cleaning up ${terminalsToDispose.size} terminal(s) for ended chat session ${chatSessionResource}`
2135
- );
2136
- this._sessionTerminalAssociations.delete(chatSessionResource);
2137
- this._sessionTerminalInstances.delete(chatSessionResource);
2138
- for (const terminal of terminalsToDispose) {
2139
- this._terminalsBeingDisposedBySessionCleanup.add(terminal);
2140
- terminal.dispose();
2141
- }
2142
- const terminalToRemove = [];
2143
- for (const [termId, execution] of RunInTerminalTool_1._activeExecutions.entries()) {
2144
- if (( terminalsToDispose.has(execution.instance))) {
2145
- execution.dispose();
2146
- terminalToRemove.push(termId);
2147
- }
2148
- }
2149
- for (const termId of terminalToRemove) {
2150
- RunInTerminalTool_1._activeExecutions.delete(termId);
2151
- }
2152
- }
2153
- _addSessionTerminalAssociation(chatSessionResource, toolTerminal) {
2154
- this._ensureArchivedSessionListener();
2155
- let sessionTerminals = this._sessionTerminalInstances.get(chatSessionResource);
2156
- if (!sessionTerminals) {
2157
- sessionTerminals = ( new Set());
2158
- this._sessionTerminalInstances.set(chatSessionResource, sessionTerminals);
2159
- }
2160
- sessionTerminals.add(toolTerminal.instance);
2161
- if (!toolTerminal.isBackground) {
2162
- this._sessionTerminalAssociations.set(chatSessionResource, toolTerminal);
2163
- }
2164
- }
2165
- _ensureArchivedSessionListener() {
2166
- if (this._archivedSessionListener.value) {
2167
- return;
2168
- }
2169
- this._archivedSessionListener.value = this._agentSessionsService.onDidChangeSessionArchivedState(session => {
2170
- if (session.isArchived()) {
2171
- this._cleanupSessionTerminals(session.resource);
2172
- }
2173
- });
2174
- }
2175
- _removeTerminalAssociations(terminal) {
2176
- if (this._terminalsBeingDisposedBySessionCleanup.delete(terminal)) {
2177
- this._removeExecutionAssociations(terminal);
2178
- return;
2179
- }
2180
- for (const [sessionResource, toolTerminal] of this._sessionTerminalAssociations.entries()) {
2181
- if (terminal === toolTerminal.instance) {
2182
- this._sessionTerminalAssociations.delete(sessionResource);
2183
- }
2184
- }
2185
- for (const [sessionResource, sessionTerminals] of this._sessionTerminalInstances.entries()) {
2186
- if (!sessionTerminals.delete(terminal)) {
2187
- continue;
2188
- }
2189
- if (sessionTerminals.size === 0) {
2190
- this._sessionTerminalInstances.delete(sessionResource);
2191
- }
2192
- }
2193
- this._removeExecutionAssociations(terminal);
2194
- }
2195
- _removeExecutionAssociations(terminal) {
2196
- const executionIdsToRemove = [];
2197
- for (const [termId, execution] of RunInTerminalTool_1._activeExecutions.entries()) {
2198
- if (execution.instance === terminal) {
2199
- execution.dispose();
2200
- executionIdsToRemove.push(termId);
2201
- }
2202
- }
2203
- for (const termId of executionIdsToRemove) {
2204
- RunInTerminalTool_1._activeExecutions.delete(termId);
2205
- }
2206
- }
2207
- _registerCompletionNotification(
2208
- terminalInstance,
2209
- termId,
2210
- chatSessionResource,
2211
- commandName,
2212
- toolSpecificData,
2213
- outputMonitor,
2214
- alreadyNotifiedInputNeededOutput
2215
- ) {
2216
- const notificationKey = terminalInstance.instanceId;
2217
- this._backgroundNotifications.deleteAndDispose(notificationKey);
2218
- const commandDetection = terminalInstance.capabilities.get(TerminalCapability.CommandDetection);
2219
- if (!commandDetection) {
2220
- outputMonitor?.dispose();
2221
- return;
2222
- }
2223
- const sessionRef = this._chatService.acquireExistingSession(chatSessionResource, "RunInTerminalTool#completionNotification");
2224
- if (!sessionRef) {
2225
- this._logService.warn(
2226
- `RunInTerminalTool: Cannot register completion notification for terminal ${termId} - session already disposed`
2227
- );
2228
- outputMonitor?.dispose();
2229
- return;
2230
- }
2231
- const lastRequest = sessionRef.object.lastRequest;
2232
- const sendOptions = {};
2233
- if (lastRequest) {
2234
- sendOptions.userSelectedModelId = lastRequest.modelId;
2235
- sendOptions.modeInfo = lastRequest.modeInfo;
2236
- if (lastRequest.userSelectedTools) {
2237
- sendOptions.userSelectedTools = constObservable(lastRequest.userSelectedTools);
2238
- }
2239
- }
2240
- const store = ( new DisposableStore());
2241
- let userIsReplyingDirectly = false;
2242
- const disposeNotification = () => this._backgroundNotifications.deleteAndDispose(notificationKey);
2243
- const handleSessionCancelled = () => {
2244
- if (sessionRef.object.lastRequest?.response?.isCanceled) {
2245
- disposeNotification();
2246
- return true;
2247
- }
2248
- return false;
2249
- };
2250
- store.add(autorun(reader => {
2251
- const request = sessionRef.object.lastRequestObs.read(reader);
2252
- if (!request?.response) {
2253
- return;
2254
- }
2255
- reader.store.add(request.response.onDidChange(ev => {
2256
- if (ev.reason === "completedRequest" && request.response.isCanceled) {
2257
- disposeNotification();
2258
- }
2259
- }));
2260
- }));
2261
- if (outputMonitor) {
2262
- let lastInputNeededOutput = alreadyNotifiedInputNeededOutput ?? "";
2263
- let lastInputNeededNotificationTime = alreadyNotifiedInputNeededOutput !== undefined ? Date.now() : 0;
2264
- const bgCts = ( new CancellationTokenSource());
2265
- store.add(toDisposable(() => {
2266
- bgCts.cancel();
2267
- bgCts.dispose();
2268
- }));
2269
- store.add(outputMonitor);
2270
- outputMonitor.continueMonitoringAsync(bgCts.token);
2271
- store.add(
2272
- this._registerSensitiveInputElicitation(chatSessionResource, terminalInstance, outputMonitor, () => {
2273
- const execution = RunInTerminalTool_1._activeExecutions.get(termId);
2274
- execution?.dispose();
2275
- })
2276
- );
2277
- store.add(outputMonitor.onDidDetectInputNeeded(() => {
2278
- if (userIsReplyingDirectly) {
2279
- this._logService.debug(
2280
- `RunInTerminalTool: Suppressing input-needed notification for terminal ${termId} because user is replying directly`
2281
- );
2282
- return;
2283
- }
2284
- if (terminalInstance.isDisposed) {
2285
- this._logService.debug(
2286
- `RunInTerminalTool: Suppressing input-needed notification for terminal ${termId} because the terminal is disposed`
2287
- );
2288
- return;
2289
- }
2290
- if (handleSessionCancelled()) {
2291
- return;
2292
- }
2293
- const execution = RunInTerminalTool_1._activeExecutions.get(termId);
2294
- if (!execution) {
2295
- return;
2296
- }
2297
- const currentOutput = execution.getOutput();
2298
- const now = Date.now();
2299
- const isDuplicate = currentOutput === lastInputNeededOutput && now - lastInputNeededNotificationTime < INPUT_NEEDED_NOTIFICATION_THROTTLE_MS;
2300
- if (isDuplicate) {
2301
- return;
2302
- }
2303
- lastInputNeededOutput = currentOutput;
2304
- lastInputNeededNotificationTime = now;
2305
- const inputAction = this._buildInputNeededSteeringText(chatSessionResource, termId, "none");
2306
- const message = `[Terminal ${termId} notification: command may be waiting for input — assess the output below.]\n${inputAction}\nTerminal output:\n${currentOutput}`;
2307
- this._logService.debug(
2308
- `RunInTerminalTool: Input needed in background terminal ${termId}, notifying chat session`
2309
- );
2310
- this._chatService.sendRequest(chatSessionResource, message, {
2311
- ...sendOptions,
2312
- queue: ChatRequestQueueKind.Steering,
2313
- isSystemInitiated: true,
2314
- systemInitiatedLabel: ( localize(14532, "`{0}` may need input", commandName)),
2315
- terminalExecutionId: termId
2316
- }).catch(e => {
2317
- this._logService.warn(
2318
- `RunInTerminalTool: Failed to send input-needed notification for terminal ${termId}`,
2319
- e
2320
- );
2321
- });
2322
- }));
2323
- }
2324
- store.add(terminalInstance.onDidInputData(() => {
2325
- if (userIsReplyingDirectly) {
2326
- return;
2327
- }
2328
- userIsReplyingDirectly = true;
2329
- this._dismissPendingCarouselsForTerminal(chatSessionResource, termId);
2330
- }));
2331
- store.add(sessionRef);
2332
- store.add(commandDetection.onCommandFinished(command => {
2333
- const execution = RunInTerminalTool_1._activeExecutions.get(termId);
2334
- if (!execution) {
2335
- disposeNotification();
2336
- return;
2337
- }
2338
- if (handleSessionCancelled()) {
2339
- return;
2340
- }
2341
- disposeNotification();
2342
- const exitCode = command.exitCode;
2343
- const exitCodeText = exitCode !== undefined ? ` with exit code ${exitCode}` : "";
2344
- const currentOutput = execution.getOutput();
2345
- const isUserVisible = this._terminalService.foregroundInstances.includes(terminalInstance);
2346
- const message = isUserVisible ? `[Terminal ${termId} notification: command completed${exitCodeText}. Use send_to_terminal to send another command or kill_terminal to stop it.]\nTerminal output:\n${currentOutput}` : `[Terminal ${termId} notification: command completed${exitCodeText}. The terminal has been cleaned up.]\nTerminal output:\n${currentOutput}`;
2347
- this._logService.debug(
2348
- `RunInTerminalTool: Command completed in background terminal ${termId}, notifying chat session`
2349
- );
2350
- this._chatService.sendRequest(chatSessionResource, message, {
2351
- ...sendOptions,
2352
- queue: ChatRequestQueueKind.Steering,
2353
- isSystemInitiated: true,
2354
- systemInitiatedLabel: ( localize(14533, "`{0}` completed", commandName)),
2355
- terminalExecutionId: termId
2356
- }).catch(e => {
2357
- this._logService.warn(
2358
- `RunInTerminalTool: Failed to send completion notification for terminal ${termId}`,
2359
- e
2360
- );
2361
- });
2362
- this._commandArtifactCollector.capture(toolSpecificData, terminalInstance, command.id).then(() => {
2363
- if (this._terminalService.foregroundInstances.includes(terminalInstance)) {
2364
- this._logService.debug(
2365
- `RunInTerminalTool: Background terminal ${termId} was revealed by user, skipping disposal`
2366
- );
2367
- return;
2368
- }
2369
- this._logService.debug(`RunInTerminalTool: Disposing finished background terminal ${termId}`);
2370
- RunInTerminalTool_1._killedByTool.add(termId);
2371
- execution.dispose();
2372
- RunInTerminalTool_1._activeExecutions.delete(termId);
2373
- terminalInstance.dispose();
2374
- });
2375
- }));
2376
- const executionForDisposal = RunInTerminalTool_1._activeExecutions.get(termId);
2377
- store.add(terminalInstance.onDisposed(() => {
2378
- if (( RunInTerminalTool_1._killedByTool.has(termId))) {
2379
- disposeNotification();
2380
- return;
2381
- }
2382
- if (this._isShuttingDown) {
2383
- disposeNotification();
2384
- return;
2385
- }
2386
- if (handleSessionCancelled()) {
2387
- return;
2388
- }
2389
- const currentOutput = executionForDisposal?.getOutput() ?? "";
2390
- const exitCode = terminalInstance.exitCode;
2391
- const exitCodeText = exitCode !== undefined ? ` with exit code ${exitCode}` : "";
2392
- disposeNotification();
2393
- 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}`;
2394
- this._logService.debug(
2395
- `RunInTerminalTool: Background terminal ${termId} disposed${exitCodeText}, notifying chat session`
2396
- );
2397
- this._chatService.sendRequest(chatSessionResource, message, {
2398
- ...sendOptions,
2399
- queue: ChatRequestQueueKind.Steering,
2400
- isSystemInitiated: true,
2401
- systemInitiatedLabel: ( localize(14534, "`{0}` terminal exited", commandName)),
2402
- terminalExecutionId: termId
2403
- }).catch(e => {
2404
- this._logService.warn(
2405
- `RunInTerminalTool: Failed to send terminal-exited notification for terminal ${termId}`,
2406
- e
2407
- );
2408
- });
2409
- }));
2410
- store.add(sessionRef.object.onDidChange(e => {
2411
- if (e.kind === "removeRequest") {
2412
- this._logService.debug(
2413
- `RunInTerminalTool: Request removed from session, cleaning up background terminal ${termId}`
2414
- );
2415
- RunInTerminalTool_1._activeExecutions.get(termId)?.dispose();
2416
- RunInTerminalTool_1._activeExecutions.delete(termId);
2417
- disposeNotification();
2418
- terminalInstance.dispose();
2419
- }
2420
- }));
2421
- this._backgroundNotifications.set(notificationKey, store);
2422
- }
2423
- _dismissPendingCarouselsForTerminal(chatSessionResource, termId) {
2424
- const model = this._chatService.getSession(chatSessionResource);
2425
- if (!model) {
2426
- return;
2427
- }
2428
- const requests = model.getRequests();
2429
- for (let i = requests.length - 1; i >= 0; i--) {
2430
- const response = requests[i].response;
2431
- if (!response) {
2432
- continue;
2433
- }
2434
- const parts = response.response.value;
2435
- for (let j = parts.length - 1; j >= 0; j--) {
2436
- const part = parts[j];
2437
- if (part instanceof ChatQuestionCarouselData && part.terminalId === termId && !part.isUsed) {
2438
- this._logService.debug(
2439
- `RunInTerminalTool: Dismissing pending carousel for terminal ${termId} because user typed directly in terminal`
2440
- );
2441
- part.data = {};
2442
- part.isUsed = true;
2443
- part.dismissedByTerminalInput = true;
2444
- part.completion.complete({
2445
- answers: undefined
2446
- });
2447
- return;
2448
- }
2449
- }
2450
- }
2451
- }
2452
- };
2453
- RunInTerminalTool = RunInTerminalTool_1 = ( __decorate([( __param(0, IChatService)), ( __param(1, IConfigurationService)), ( __param(2, IFileService)), ( __param(3, IHistoryService)), ( __param(4, IInstantiationService)), ( __param(5, ILabelService)), ( __param(6, ILanguageModelToolsService)), ( __param(7, IRemoteAgentService)), ( __param(8, IStorageService)), ( __param(9, ITerminalChatService)), ( __param(10, ITerminalLogService)), ( __param(11, ITerminalService)), ( __param(12, ITerminalSandboxService)), ( __param(13, IWorkspaceContextService)), ( __param(14, IChatWidgetService)), ( __param(15, IAgentSessionsService)), ( __param(16, ILifecycleService))], RunInTerminalTool));
2454
- let ActiveTerminalExecution = class ActiveTerminalExecution extends Disposable {
2455
- get completionPromise() {
2456
- return this._completionDeferred.p;
2457
- }
2458
- get isBackground() {
2459
- return this._isBackground;
2460
- }
2461
- get startMarker() {
2462
- return this._startMarker;
2463
- }
2464
- get instance() {
2465
- return this._toolTerminal.instance;
2466
- }
2467
- constructor(
2468
- sessionResource,
2469
- termId,
2470
- toolTerminal,
2471
- commandDetection,
2472
- isBackground,
2473
- _instantiationService
2474
- ) {
2475
- super();
2476
- this.sessionResource = sessionResource;
2477
- this.termId = termId;
2478
- this._instantiationService = _instantiationService;
2479
- this._toolTerminal = toolTerminal;
2480
- this._isBackground = isBackground;
2481
- this._completionDeferred = ( new DeferredPromise());
2482
- this.strategy = this._register(this._createStrategy(commandDetection));
2483
- this._register(this.strategy.onDidCreateStartMarker(marker => {
2484
- if (marker) {
2485
- this._startMarker = marker;
2486
- }
2487
- }));
2488
- }
2489
- _createStrategy(commandDetection) {
2490
- const isSyncMode = !this._isBackground;
2491
- switch (this._toolTerminal.shellIntegrationQuality) {
2492
- case ShellIntegrationQuality.None:
2493
- return this._instantiationService.createInstance(
2494
- NoneExecuteStrategy,
2495
- this._toolTerminal.instance,
2496
- () => this._toolTerminal.receivedUserInput ?? false
2497
- );
2498
- case ShellIntegrationQuality.Basic:
2499
- return this._instantiationService.createInstance(
2500
- BasicExecuteStrategy,
2501
- this._toolTerminal.instance,
2502
- () => this._toolTerminal.receivedUserInput ?? false,
2503
- commandDetection
2504
- );
2505
- case ShellIntegrationQuality.Rich:
2506
- return this._instantiationService.createInstance(
2507
- RichExecuteStrategy,
2508
- this._toolTerminal.instance,
2509
- commandDetection,
2510
- isSyncMode
2511
- );
2512
- }
2513
- }
2514
- async start(commandLine, token, commandId, commandLineForMetadata) {
2515
- try {
2516
- const result = await this.strategy.execute(commandLine, token, commandId, commandLineForMetadata);
2517
- this._completionDeferred.complete(result);
2518
- return result;
2519
- } catch (e) {
2520
- this._completionDeferred.error(e);
2521
- throw e;
2522
- }
2523
- }
2524
- setForeground() {
2525
- this._isBackground = false;
2526
- }
2527
- setBackground() {
2528
- this._isBackground = true;
2529
- }
2530
- getOutput(marker) {
2531
- return getOutput(this.instance, marker ?? this._startMarker);
2532
- }
2533
- };
2534
- ActiveTerminalExecution = ( __decorate([( __param(5, IInstantiationService))], ActiveTerminalExecution));
2535
- class RestoredTerminalExecution extends Disposable {
2536
- constructor(instance) {
2537
- super();
2538
- this.instance = instance;
2539
- this.completionPromise = Promise.resolve({
2540
- output: undefined,
2541
- error: "restoredTerminalExecutionNotAwaitable"
2542
- });
2543
- }
2544
- getOutput(marker) {
2545
- return getOutput(this.instance, marker);
2546
- }
2547
- }
2548
- let TerminalProfileFetcher = class TerminalProfileFetcher {
2549
- constructor(
2550
- _configurationService,
2551
- _terminalProfileResolverService,
2552
- _remoteAgentService
2553
- ) {
2554
- this._configurationService = _configurationService;
2555
- this._terminalProfileResolverService = _terminalProfileResolverService;
2556
- this._remoteAgentService = _remoteAgentService;
2557
- this.osBackend = this._remoteAgentService.getEnvironment().then(remoteEnv => remoteEnv?.os ?? OS);
2558
- }
2559
- async getCopilotProfile() {
2560
- const os = await this.osBackend;
2561
- const customChatAgentProfile = this._getChatTerminalProfile(os);
2562
- if (customChatAgentProfile) {
2563
- return customChatAgentProfile;
2564
- }
2565
- const defaultProfile = await this._terminalProfileResolverService.getDefaultProfile({
2566
- os,
2567
- remoteAuthority: this._remoteAgentService.getConnection()?.remoteAuthority
2568
- });
2569
- if (basename(defaultProfile.path) === "cmd.exe") {
2570
- return {
2571
- ...defaultProfile,
2572
- path: "C:\\WINDOWS\\System32\\WindowsPowerShell\\v1.0\\powershell.exe",
2573
- profileName: "PowerShell"
2574
- };
2575
- }
2576
- if (defaultProfile.path === "/bin/sh") {
2577
- return {
2578
- ...defaultProfile,
2579
- path: "/bin/bash",
2580
- profileName: "bash"
2581
- };
2582
- }
2583
- return {
2584
- ...defaultProfile,
2585
- icon: undefined
2586
- };
2587
- }
2588
- async getCopilotShell() {
2589
- return (await this.getCopilotProfile()).path;
2590
- }
2591
- _getChatTerminalProfile(os) {
2592
- let profileSetting;
2593
- switch (os) {
2594
- case OperatingSystem.Windows:
2595
- profileSetting = TerminalChatAgentToolsSettingId.TerminalProfileWindows;
2596
- break;
2597
- case OperatingSystem.Macintosh:
2598
- profileSetting = TerminalChatAgentToolsSettingId.TerminalProfileMacOs;
2599
- break;
2600
- case OperatingSystem.Linux:
2601
- default:
2602
- profileSetting = TerminalChatAgentToolsSettingId.TerminalProfileLinux;
2603
- break;
2604
- }
2605
- const profile = this._configurationService.getValue(profileSetting);
2606
- if (this._isValidChatAgentTerminalProfile(profile)) {
2607
- return profile;
2608
- }
2609
- return undefined;
2610
- }
2611
- _isValidChatAgentTerminalProfile(profile) {
2612
- if (profile === null || profile === undefined || typeof profile !== "object") {
2613
- return false;
2614
- }
2615
- if ("path" in profile && isString(profile.path)) {
2616
- return true;
2617
- }
2618
- return false;
2619
- }
2620
- };
2621
- TerminalProfileFetcher = ( __decorate([( __param(0, IConfigurationService)), ( __param(1, ITerminalProfileResolverService)), ( __param(2, IRemoteAgentService))], TerminalProfileFetcher));
2622
-
2623
- export { RunInTerminalTool, TerminalProfileFetcher, createRunInTerminalToolData, shouldAutomaticallyRetryUnsandboxed };