@@ -4,6 +4,7 @@ import * as path from "path"
44import * as os from "os"
55
66import * as vscode from "vscode"
7+ import pWaitFor from "p-wait-for"
78
89import {
910 type RooCodeAPI ,
@@ -154,9 +155,19 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
154155 }
155156
156157 public async resumeTask ( taskId : string ) : Promise < void > {
158+ await vscode . commands . executeCommand ( `${ Package . name } .SidebarProvider.focus` )
159+ await this . waitForWebviewLaunch ( 5_000 )
160+
157161 const { historyItem } = await this . sidebarProvider . getTaskWithId ( taskId )
158162 await this . sidebarProvider . createTaskWithHistoryItem ( historyItem )
159- await this . sidebarProvider . postMessageToWebview ( { type : "action" , action : "chatButtonClicked" } )
163+
164+ if ( this . sidebarProvider . viewLaunched ) {
165+ await this . sidebarProvider . postMessageToWebview ( { type : "action" , action : "chatButtonClicked" } )
166+ } else {
167+ this . log (
168+ `[API#resumeTask] webview not launched after resume for task ${ taskId } ; continuing in headless mode` ,
169+ )
170+ }
160171 }
161172
162173 public async isTaskInHistory ( taskId : string ) : Promise < boolean > {
@@ -183,6 +194,21 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
183194 }
184195
185196 public async sendMessage ( text ?: string , images ?: string [ ] ) {
197+ const currentTask = this . sidebarProvider . getCurrentTask ( )
198+
199+ // In headless/sandbox flows the webview may not be launched, so routing
200+ // through invoke=sendMessage drops the message. Deliver directly to the
201+ // task ask-response channel instead.
202+ if ( ! this . sidebarProvider . viewLaunched ) {
203+ if ( ! currentTask ) {
204+ this . log ( "[API#sendMessage] no current task in headless mode; message dropped" )
205+ return
206+ }
207+
208+ await currentTask . submitUserMessage ( text ?? "" , images )
209+ return
210+ }
211+
186212 await this . sidebarProvider . postMessageToWebview ( { type : "invoke" , invoke : "sendMessage" , text, images } )
187213 }
188214
@@ -198,6 +224,20 @@ export class API extends EventEmitter<RooCodeEvents> implements RooCodeAPI {
198224 return this . sidebarProvider . viewLaunched
199225 }
200226
227+ private async waitForWebviewLaunch ( timeoutMs : number ) : Promise < boolean > {
228+ try {
229+ await pWaitFor ( ( ) => this . sidebarProvider . viewLaunched , {
230+ timeout : timeoutMs ,
231+ interval : 50 ,
232+ } )
233+
234+ return true
235+ } catch {
236+ this . log ( `[API#waitForWebviewLaunch] webview did not launch within ${ timeoutMs } ms` )
237+ return false
238+ }
239+ }
240+
201241 private registerListeners ( provider : ClineProvider ) {
202242 provider . on ( RooCodeEventName . TaskCreated , ( task ) => {
203243 // Task Lifecycle
0 commit comments