@@ -4,6 +4,7 @@ import * as path from "path"
44import delay from "delay"
55
66import { Cline } from "../Cline"
7+ import { CommandExecutionStatus } from "../../schemas"
78import { ToolUse , AskApproval , HandleError , PushToolResult , RemoveClosingTag , ToolResponse } from "../../shared/tools"
89import { formatResponse } from "../prompts/responses"
910import { unescapeHtmlEntities } from "../../utils/text-normalization"
@@ -47,8 +48,9 @@ export async function executeCommandTool(
4748
4849 cline . consecutiveMistakeCount = 0
4950
51+ const executionId = Date . now ( ) . toString ( )
5052 command = unescapeHtmlEntities ( command ) // Unescape HTML entities.
51- const didApprove = await askApproval ( "command" , command )
53+ const didApprove = await askApproval ( "command" , command , { id : executionId } )
5254
5355 if ( ! didApprove ) {
5456 return
@@ -59,6 +61,7 @@ export async function executeCommandTool(
5961 const { terminalOutputLineLimit = 500 , terminalShellIntegrationDisabled = false } = clineProviderState ?? { }
6062
6163 const options : ExecuteCommandOptions = {
64+ executionId,
6265 command,
6366 customCwd,
6467 terminalShellIntegrationDisabled,
@@ -74,8 +77,10 @@ export async function executeCommandTool(
7477
7578 pushToolResult ( result )
7679 } catch ( error : unknown ) {
77- await cline . say ( "shell_integration_warning" )
80+ const status : CommandExecutionStatus = { executionId, status : "fallback" }
81+ clineProvider ?. postMessageToWebview ( { type : "commandExecutionStatus" , text : JSON . stringify ( status ) } )
7882 clineProvider ?. setValue ( "terminalShellIntegrationDisabled" , true )
83+ await cline . say ( "shell_integration_warning" )
7984
8085 if ( error instanceof ShellIntegrationError ) {
8186 const [ rejected , result ] = await executeCommand ( cline , {
@@ -102,6 +107,7 @@ export async function executeCommandTool(
102107}
103108
104109export type ExecuteCommandOptions = {
110+ executionId : string
105111 command : string
106112 customCwd ?: string
107113 terminalShellIntegrationDisabled ?: boolean
@@ -111,6 +117,7 @@ export type ExecuteCommandOptions = {
111117export async function executeCommand (
112118 cline : Cline ,
113119 {
120+ executionId,
114121 command,
115122 customCwd,
116123 terminalShellIntegrationDisabled = false ,
@@ -141,6 +148,7 @@ export async function executeCommand(
141148 let shellIntegrationError : string | undefined
142149
143150 const terminalProvider = terminalShellIntegrationDisabled ? "execa" : "vscode"
151+ const clineProvider = await cline . providerRef . deref ( )
144152
145153 const callbacks : RooTerminalCallbacks = {
146154 onLine : async ( output : string , process : RooTerminalProcess ) => {
@@ -165,7 +173,15 @@ export async function executeCommand(
165173 result = Terminal . compressTerminalOutput ( output ?? "" , terminalOutputLineLimit )
166174 completed = true
167175 } ,
168- onShellExecutionComplete : ( details : ExitCodeDetails ) => ( exitDetails = details ) ,
176+ onShellExecutionStarted : ( pid : number | undefined ) => {
177+ const status : CommandExecutionStatus = { executionId, status : "running" , pid }
178+ clineProvider ?. postMessageToWebview ( { type : "commandExecutionStatus" , text : JSON . stringify ( status ) } )
179+ } ,
180+ onShellExecutionComplete : ( details : ExitCodeDetails ) => {
181+ const status : CommandExecutionStatus = { executionId, status : "exited" , exitCode : details . exitCode }
182+ clineProvider ?. postMessageToWebview ( { type : "commandExecutionStatus" , text : JSON . stringify ( status ) } )
183+ exitDetails = details
184+ } ,
169185 }
170186
171187 if ( terminalProvider === "vscode" ) {
0 commit comments