From 8e067046d779e4ace70f4ccff2f63341b815d6fc Mon Sep 17 00:00:00 2001 From: Roomote Date: Thu, 22 Oct 2026 03:53:24 +0000 Subject: [PATCH 1/2] refactor(task): make Task.create delegate startup to Task.run (#2145) --- src/core/task/Task.ts | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index ebb362f7eb..57eb59fac4 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -1381,21 +1381,13 @@ export class Task extends EventEmitter implements TaskLike { } static create(options: TaskOptions): [Task, Promise] { - const instance = new Task({ ...options, startTask: false }) - const { images, task, historyItem } = options - let promise - - instance.startIdleTelemetryCheck() - - if (images || task) { - promise = instance.startTask(task, images) - } else if (historyItem) { - promise = instance.resumeTaskFromHistory() - } else { + if (!options.task && !options.images && !options.historyItem) { throw new Error("Either historyItem or task/images must be provided") } - return [instance, promise] + const instance = new Task({ ...options, startTask: false }) + + return [instance, instance.run()] } // API Messages From 66d4b885908beef4dcfdeb087028b23b80725b44 Mon Sep 17 00:00:00 2001 From: Elliott de Launay Date: Fri, 23 Oct 2026 02:42:59 +0000 Subject: [PATCH 2/2] fix(task): document create input precedence and test startup contract --- src/core/task/Task.ts | 1 + src/core/task/__tests__/Task.spec.ts | 29 ++++++++++++++++++++++++++++ 2 files changed, 30 insertions(+) diff --git a/src/core/task/Task.ts b/src/core/task/Task.ts index 57eb59fac4..99a7f38324 100644 --- a/src/core/task/Task.ts +++ b/src/core/task/Task.ts @@ -1380,6 +1380,7 @@ export class Task extends EventEmitter implements TaskLike { this.blanketDeniedCommandThisTurn = true } + /** When provided, historyItem overrides task and images in the startup metadata. */ static create(options: TaskOptions): [Task, Promise] { if (!options.task && !options.images && !options.historyItem) { throw new Error("Either historyItem or task/images must be provided") diff --git a/src/core/task/__tests__/Task.spec.ts b/src/core/task/__tests__/Task.spec.ts index 3066613263..ad07230204 100644 --- a/src/core/task/__tests__/Task.spec.ts +++ b/src/core/task/__tests__/Task.spec.ts @@ -1440,6 +1440,35 @@ describe("Cline", () => { }) }) + describe("create", () => { + it("rejects missing task inputs before constructing the task", () => { + const onCreated = vi.fn() + + expect(() => Task.create({ provider: mockProvider, apiConfiguration: mockApiConfig, onCreated })).toThrow( + "Either historyItem or task/images must be provided", + ) + expect(onCreated).not.toHaveBeenCalled() + }) + + it("returns the cached run promise", async () => { + const startTaskSpy = vi.spyOn(getTaskTestAccess(Task.prototype), "startTask").mockResolvedValue(undefined) + + try { + const [task, promise] = Task.create({ + provider: mockProvider, + apiConfiguration: mockApiConfig, + task: "x", + }) + + expect(task.run()).toBe(promise) + expect(startTaskSpy).toHaveBeenCalledExactlyOnceWith("x", undefined) + await promise + } finally { + startTaskSpy.mockRestore() + } + }) + }) + describe("constructor", () => { it.each([{ apiConfigName: "parent-local-profile" }, { apiConfigName: undefined }])( "uses an explicit delegated-child context without shared state or startup persistence",