From d8525d71fbc351a74f86c6fb0a85d2deeb203b09 Mon Sep 17 00:00:00 2001 From: LukeParkerDev <10430890+Hona@users.noreply.github.com> Date: Thu, 9 Jul 2026 14:41:28 +1000 Subject: [PATCH] fix(app): preserve framed row paint --- .../session-timeline-shell-outline.spec.ts | 39 +++++++++++++++++++ .../session/timeline/message-timeline.tsx | 4 +- 2 files changed, 41 insertions(+), 2 deletions(-) diff --git a/packages/app/e2e/regression/session-timeline-shell-outline.spec.ts b/packages/app/e2e/regression/session-timeline-shell-outline.spec.ts index 7e901b9d81..54139cc371 100644 --- a/packages/app/e2e/regression/session-timeline-shell-outline.spec.ts +++ b/packages/app/e2e/regression/session-timeline-shell-outline.spec.ts @@ -3,6 +3,7 @@ import { assistantMessage, setupTimeline, shell, + textPart, toolPart, userMessage, } from "../performance/timeline-stability/fixture" @@ -119,6 +120,44 @@ test("keeps the patch card inside a fractionally short virtual row", async ({ pa expect(geometry.clipMargin).toBe("0.5px") }) +test("allows paint rounding for every framed row but not fixed turn gaps", async ({ page }) => { + const secondUserID = "msg_outline_second_user" + await setupTimeline(page, { + messages: [ + userMessage(undefined, { + summary: { + diffs: [ + { + file: "src/summary.ts", + additions: 1, + deletions: 1, + patch: "@@ -1 +1 @@\n-export const value = 1\n+export const value = 2", + }, + ], + }, + }), + assistantMessage([textPart("prt_outline_text", "Assistant text")]), + userMessage(undefined, { id: secondUserID, created: 1700000010000 }), + assistantMessage([], { + id: "msg_outline_second_assistant", + parentID: secondUserID, + created: 1700000011000, + }), + ], + }) + await expect(page.locator('[data-timeline-row="DiffSummary"]')).toBeVisible() + await expect(page.locator('[data-timeline-row="TurnGap"]')).toBeVisible() + + const rows = await page.locator("[data-timeline-key]").evaluateAll((elements) => + elements.map((element) => ({ + tag: element.querySelector("[data-timeline-row]")?.dataset.timelineRow, + clipMargin: getComputedStyle(element).overflowClipMargin, + })), + ) + expect(rows.filter((row) => row.tag !== "TurnGap").every((row) => row.clipMargin === "0.5px")).toBe(true) + expect(rows.filter((row) => row.tag === "TurnGap")).toEqual([{ tag: "TurnGap", clipMargin: "0px" }]) +}) + async function captureCardEdges(page: Page, card: Locator) { const box = await card.boundingBox() if (!box) throw new Error("Tool card bounds are unavailable") diff --git a/packages/app/src/pages/session/timeline/message-timeline.tsx b/packages/app/src/pages/session/timeline/message-timeline.tsx index 5b17b60852..68fc4d3f4f 100644 --- a/packages/app/src/pages/session/timeline/message-timeline.tsx +++ b/packages/app/src/pages/session/timeline/message-timeline.tsx @@ -1279,8 +1279,8 @@ export function MessageTimeline(props: { width: "100%", height: `${item().size}px`, overflow: "clip", - // Rounded virtual measurements can otherwise clip a tool card's outer border pixel. - "overflow-clip-margin": tool() ? "0.5px" : undefined, + // Rounded virtual measurements can otherwise clip a framed row's outer paint. + "overflow-clip-margin": row()._tag === "TurnGap" ? undefined : "0.5px", }} >