From 448a9768f4861e4b06a870815702695ff0dedea5 Mon Sep 17 00:00:00 2001 From: Ozan Dogrultan Date: Tue, 20 Oct 2026 23:00:06 +0200 Subject: [PATCH 1/2] fix(tui): preserve wrapped sidebar todo height --- .../tui/src/feature-plugins/sidebar/todo.tsx | 2 +- .../feature-plugins/sidebar-todo.test.tsx | 109 ++++++++++++++++++ 2 files changed, 110 insertions(+), 1 deletion(-) create mode 100644 packages/tui/test/feature-plugins/sidebar-todo.test.tsx diff --git a/packages/tui/src/feature-plugins/sidebar/todo.tsx b/packages/tui/src/feature-plugins/sidebar/todo.tsx index d1cf0df2dd12..5de2c97accee 100644 --- a/packages/tui/src/feature-plugins/sidebar/todo.tsx +++ b/packages/tui/src/feature-plugins/sidebar/todo.tsx @@ -18,7 +18,7 @@ export function SidebarTodo(props: { context: Plugin.Context; sessionID: string return ( 0}> - + [{ open: true }, async () => {}] }, + data: { + session: { + get: () => ({}), + message: { + list: () => [ + { + type: "assistant", + content: [{ type: "tool", name: "todowrite", state: { status: "completed", input: { todos } } }], + }, + ], + }, + }, + }, + } as unknown as Context +} + +const content = [ + "Review the sample output at several terminal widths and verify all displayed labels", + "Check example descriptions for wrapping and maintain consistent section spacing", + "Run the sample checks, inspect the terminal output, and document expected results", + "Prepare a sample report with before and after captures; record the verification results", +] + +const cases = [3, 4, 8].flatMap((count) => + [40, 50].flatMap((width) => + [false, true].flatMap((wrapped) => [false, true].map((completed) => ({ count, width, wrapped, completed }))), + ), +) + +test.each(cases)("sidebar preserves todo content and section spacing %j", async (input) => { + const todos = Array.from( + { length: input.count }, + (_, index): Todo => ({ + content: input.wrapped ? content[index % content.length] : `Task ${index + 1}`, + status: input.completed ? "completed" : index === 0 ? "in_progress" : "pending", + }), + ) + const app = await testRender( + () => ( + + + + + + + Next section + + + index)}> + {(index) => ( + + Item {index} + + )} + + + + + + + ), + { width: input.width, height: 40 }, + ) + + try { + await app.renderOnce() + const rows = app + .captureCharFrame() + .split("\n") + .map((row) => row.trim()) + const next = rows.indexOf("Next section") + expect(next).toBeGreaterThan(0) + expect(rows[next - 1]).toBe("") + expect(rows[next - 2]).not.toBe("") + expect( + rows + .slice(1, next) + .map((row) => row.replace(/^\[[^\]]+\]\s*/, "")) + .join(" ") + .replace(/\s+/g, ""), + ).toBe( + todos + .map((todo) => todo.content) + .join("") + .replace(/\s+/g, ""), + ) + } finally { + app.renderer.destroy() + } +}) From eb720e3c18d2263acd0b6f8ee1b085fec219ba5b Mon Sep 17 00:00:00 2001 From: Ozan Dogrultan Date: Tue, 20 Oct 2026 23:14:50 +0200 Subject: [PATCH 2/2] test(tui): focus sidebar todo regression --- .../feature-plugins/sidebar-todo.test.tsx | 21 +++++++------------ 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/packages/tui/test/feature-plugins/sidebar-todo.test.tsx b/packages/tui/test/feature-plugins/sidebar-todo.test.tsx index 3896b6cfe9e8..e98ca14b0ae1 100644 --- a/packages/tui/test/feature-plugins/sidebar-todo.test.tsx +++ b/packages/tui/test/feature-plugins/sidebar-todo.test.tsx @@ -35,23 +35,16 @@ const content = [ "Prepare a sample report with before and after captures; record the verification results", ] -const cases = [3, 4, 8].flatMap((count) => - [40, 50].flatMap((width) => - [false, true].flatMap((wrapped) => [false, true].map((completed) => ({ count, width, wrapped, completed }))), - ), -) - -test.each(cases)("sidebar preserves todo content and section spacing %j", async (input) => { - const todos = Array.from( - { length: input.count }, - (_, index): Todo => ({ - content: input.wrapped ? content[index % content.length] : `Task ${index + 1}`, - status: input.completed ? "completed" : index === 0 ? "in_progress" : "pending", +test("sidebar preserves wrapped todo content and spacing before a growing section", async () => { + const todos = content.map( + (content, index): Todo => ({ + content, + status: index === 0 ? "in_progress" : "pending", }), ) const app = await testRender( () => ( - + ), - { width: input.width, height: 40 }, + { width: 40, height: 40 }, ) try {