From 30b4339804cf8d521ff3267a83320eb8b5278a06 Mon Sep 17 00:00:00 2001 From: cte Date: Tue, 10 Feb 2026 00:11:11 -0800 Subject: [PATCH 1/2] Fix task resumption in the API module --- src/extension/api.ts | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-) diff --git a/src/extension/api.ts b/src/extension/api.ts index a2b389abdc6..25c81a65896 100644 --- a/src/extension/api.ts +++ b/src/extension/api.ts @@ -4,6 +4,7 @@ import * as path from "path" import * as os from "os" import * as vscode from "vscode" +import pWaitFor from "p-wait-for" import { type RooCodeAPI, @@ -208,9 +209,19 @@ export class API extends EventEmitter implements RooCodeAPI { } public async resumeTask(taskId: string): Promise { + await vscode.commands.executeCommand(`${Package.name}.SidebarProvider.focus`) + await this.waitForWebviewLaunch(5_000) + const { historyItem } = await this.sidebarProvider.getTaskWithId(taskId) await this.sidebarProvider.createTaskWithHistoryItem(historyItem) - await this.sidebarProvider.postMessageToWebview({ type: "action", action: "chatButtonClicked" }) + + if (this.sidebarProvider.viewLaunched) { + await this.sidebarProvider.postMessageToWebview({ type: "action", action: "chatButtonClicked" }) + } else { + this.log( + `[API#resumeTask] webview not launched after resume for task ${taskId}; continuing in headless mode`, + ) + } } public async isTaskInHistory(taskId: string): Promise { @@ -237,6 +248,21 @@ export class API extends EventEmitter implements RooCodeAPI { } public async sendMessage(text?: string, images?: string[]) { + const currentTask = this.sidebarProvider.getCurrentTask() + + // In headless/sandbox flows the webview may not be launched, so routing + // through invoke=sendMessage drops the message. Deliver directly to the + // task ask-response channel instead. + if (!this.sidebarProvider.viewLaunched) { + if (!currentTask) { + this.log("[API#sendMessage] no current task in headless mode; message dropped") + return + } + + await currentTask.submitUserMessage(text ?? "", images) + return + } + await this.sidebarProvider.postMessageToWebview({ type: "invoke", invoke: "sendMessage", text, images }) } @@ -252,6 +278,20 @@ export class API extends EventEmitter implements RooCodeAPI { return this.sidebarProvider.viewLaunched } + private async waitForWebviewLaunch(timeoutMs: number): Promise { + try { + await pWaitFor(() => this.sidebarProvider.viewLaunched, { + timeout: timeoutMs, + interval: 50, + }) + + return true + } catch { + this.log(`[API#waitForWebviewLaunch] webview did not launch within ${timeoutMs}ms`) + return false + } + } + private registerListeners(provider: ClineProvider) { provider.on(RooCodeEventName.TaskCreated, (task) => { // Task Lifecycle From 9ac20a2abb4498eb32860ea18019c6ee2fd83a45 Mon Sep 17 00:00:00 2001 From: cte Date: Tue, 10 Feb 2026 00:20:49 -0800 Subject: [PATCH 2/2] Fix tests --- src/extension/__tests__/api-send-message.spec.ts | 1 + 1 file changed, 1 insertion(+) diff --git a/src/extension/__tests__/api-send-message.spec.ts b/src/extension/__tests__/api-send-message.spec.ts index ea1331f618c..6d9895ade1d 100644 --- a/src/extension/__tests__/api-send-message.spec.ts +++ b/src/extension/__tests__/api-send-message.spec.ts @@ -28,6 +28,7 @@ describe("API - SendMessage Command", () => { postMessageToWebview: mockPostMessageToWebview, on: vi.fn(), getCurrentTaskStack: vi.fn().mockReturnValue([]), + getCurrentTask: vi.fn().mockReturnValue(undefined), viewLaunched: true, } as unknown as ClineProvider