(
task: Task,
{
executionId,
command,
customCwd,
terminalShellIntegrationDisabled = true,
commandExecutionTimeout = 0,
agentTimeout = 0,
}: ExecuteCommandOptions,
)
| 212 | } |
| 213 | |
| 214 | export async function executeCommandInTerminal( |
| 215 | task: Task, |
| 216 | { |
| 217 | executionId, |
| 218 | command, |
| 219 | customCwd, |
| 220 | terminalShellIntegrationDisabled = true, |
| 221 | commandExecutionTimeout = 0, |
| 222 | agentTimeout = 0, |
| 223 | }: ExecuteCommandOptions, |
| 224 | ): Promise<[boolean, ToolResponse]> { |
| 225 | // Convert milliseconds back to seconds for display purposes. |
| 226 | const commandExecutionTimeoutSeconds = commandExecutionTimeout / 1000 |
| 227 | let workingDir: string |
| 228 | |
| 229 | if (!customCwd) { |
| 230 | workingDir = task.cwd |
| 231 | } else if (path.isAbsolute(customCwd)) { |
| 232 | workingDir = customCwd |
| 233 | } else { |
| 234 | workingDir = path.resolve(task.cwd, customCwd) |
| 235 | } |
| 236 | |
| 237 | try { |
| 238 | await fs.access(workingDir) |
| 239 | } catch (error) { |
| 240 | return [false, `Working directory '${workingDir}' does not exist.`] |
| 241 | } |
| 242 | |
| 243 | let message: { text?: string; images?: string[] } | undefined |
| 244 | let runInBackground = false |
| 245 | let completed = false |
| 246 | let result: string = "" |
| 247 | let persistedResult: PersistedCommandOutput | undefined |
| 248 | let exitDetails: ExitCodeDetails | undefined |
| 249 | let shellIntegrationError: ShellIntegrationError | undefined |
| 250 | let hasAskedForCommandOutput = false |
| 251 | |
| 252 | const { terminalProvider, isCmdExeFallback } = getTerminalProviderForExecution(terminalShellIntegrationDisabled) |
| 253 | const provider = await task.providerRef.deref() |
| 254 | |
| 255 | // cmd.exe can't use shell integration — tell the webview to expand the output |
| 256 | // panel immediately (same effect as the retry-fallback path). |
| 257 | if (isCmdExeFallback) { |
| 258 | const status: CommandExecutionStatus = { executionId, status: "fallback" } |
| 259 | provider?.postMessageToWebview({ type: "commandExecutionStatus", text: JSON.stringify(status) }) |
| 260 | } |
| 261 | |
| 262 | // Get global storage path for persisted output artifacts |
| 263 | const globalStoragePath = provider?.context?.globalStorageUri?.fsPath |
| 264 | let interceptor: OutputInterceptor | undefined |
| 265 | |
| 266 | // Create OutputInterceptor if we have storage available |
| 267 | if (globalStoragePath) { |
| 268 | const taskDir = await getTaskDirectoryPath(globalStoragePath, task.taskId) |
| 269 | const storageDir = path.join(taskDir, "command-output") |
| 270 | const providerState = await provider?.getState() |
| 271 | const terminalOutputPreviewSize = |
no test coverage detected