From 82b76e2138db7fcf8f8c1613184dc94777b2196e Mon Sep 17 00:00:00 2001 From: Arham Amin <132888838+arhxam@users.noreply.github.com> Date: Tue, 4 Aug 2026 18:49:12 +0530 Subject: [PATCH] fix(server): use a Cursor todo's title when its content is blank (#5073) Co-authored-by: Claude Opus 4.8 (1M context) --- .../provider/acp/CursorAcpExtension.test.ts | 19 +++++++++++++++++++ .../src/provider/acp/CursorAcpExtension.ts | 5 ++++- 2 files changed, 23 insertions(+), 1 deletion(-) diff --git a/apps/server/src/provider/acp/CursorAcpExtension.test.ts b/apps/server/src/provider/acp/CursorAcpExtension.test.ts index 0a6adb75fc494bafbf3c36be6aac5809b0d51595..ba070c91295228b47a664baacaaf7ede8860b964 100644 --- a/apps/server/src/provider/acp/CursorAcpExtension.test.ts +++ b/apps/server/src/provider/acp/CursorAcpExtension.test.ts @@ -107,6 +107,25 @@ describe("CursorAcpExtension", () => { }); }); + it("falls back to the title when content is present but blank", () => { + expect( + extractTodosAsPlan({ + toolCallId: "todos-2", + todos: [ + { id: "1", content: "", title: "Titled step", status: "pending" }, + { id: "2", content: " ", title: "Whitespace content", status: "in_progress" }, + { id: "3", content: "", title: "", status: "pending" }, + ], + merge: true, + }), + ).toEqual({ + plan: [ + { step: "Titled step", status: "pending" }, + { step: "Whitespace content", status: "inProgress" }, + ], + }); + }); + it("decodes Cursor list_available_models responses with per-model config options", () => { const decoded = CursorListAvailableModelsResponse.make({ models: [ diff --git a/apps/server/src/provider/acp/CursorAcpExtension.ts b/apps/server/src/provider/acp/CursorAcpExtension.ts index 2e131a61608b113e540b55c7adbce8db314ebf93..05fc53f4a6b57dfc16320f990e41e9b944003d27 100644 --- a/apps/server/src/provider/acp/CursorAcpExtension.ts +++ b/apps/server/src/provider/acp/CursorAcpExtension.ts @@ -94,7 +94,10 @@ export function extractTodosAsPlan(params: typeof CursorUpdateTodosRequest.Type) }>; } { const plan = params.todos.flatMap((todo) => { - const step = todo.content?.trim() ?? todo.title?.trim() ?? ""; + // Fall back to the title when content is missing OR blank. `??` only + // covers a missing content, so a present-but-empty content ("" or + // whitespace) would shadow a real title and drop the step below. + const step = todo.content?.trim() || todo.title?.trim() || ""; if (step === "") { return []; } -- 2.54.0