Skip to content
This repository was archived by the owner on May 15, 2026. It is now read-only.

Commit b2340d7

Browse files
ctehannesrudolph
authored andcommitted
Fix task resumption in the API module (#11369)
1 parent 761bef4 commit b2340d7

2 files changed

Lines changed: 42 additions & 1 deletion

File tree

src/extension/__tests__/api-send-message.spec.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@ describe("API - SendMessage Command", () => {
2828
postMessageToWebview: mockPostMessageToWebview,
2929
on: vi.fn(),
3030
getCurrentTaskStack: vi.fn().mockReturnValue([]),
31+
getCurrentTask: vi.fn().mockReturnValue(undefined),
3132
viewLaunched: true,
3233
} as unknown as ClineProvider
3334

src/extension/api.ts

Lines changed: 41 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import * as path from "path"
44
import * as os from "os"
55

66
import * as vscode from "vscode"
7+
import pWaitFor from "p-wait-for"
78

89
import {
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

Comments
 (0)