From 9c7de470313bacdb7b6c9a3f1ad7baa8c5b7c2e4 Mon Sep 17 00:00:00 2001 From: "opencode-agent[bot]" Date: Mon, 25 May 2026 02:06:42 +0000 Subject: [PATCH] chore: generate --- bun.lock | 2 +- .../session-timeline-collapse-state.spec.ts | 118 ++++++++++++------ .../session-timeline-context-resize.spec.ts | 45 +++++-- .../src/pages/session/message-timeline.tsx | 15 ++- packages/ui/src/components/file.tsx | 8 +- packages/ui/src/components/message-part.tsx | 7 +- .../ui/src/components/session-diff.test.ts | 3 +- .../ui/src/components/tool-error-card.tsx | 7 +- 8 files changed, 142 insertions(+), 63 deletions(-) diff --git a/bun.lock b/bun.lock index 2734426922..51cc671ad1 100644 --- a/bun.lock +++ b/bun.lock @@ -719,10 +719,10 @@ "patchedDependencies": { "solid-js@1.9.10": "patches/solid-js@1.9.10.patch", "@ai-sdk/xai@3.0.82": "patches/@ai-sdk%2Fxai@3.0.82.patch", + "virtua@0.49.1": "patches/virtua@0.49.1.patch", "@standard-community/standard-openapi@0.2.9": "patches/@standard-community%2Fstandard-openapi@0.2.9.patch", "@npmcli/agent@4.0.0": "patches/@npmcli%2Fagent@4.0.0.patch", "@silvia-odwyer/photon-node@0.3.4": "patches/@silvia-odwyer%2Fphoton-node@0.3.4.patch", - "virtua@0.49.1": "patches/virtua@0.49.1.patch", }, "overrides": { "@opentui/core": "catalog:", diff --git a/packages/app/e2e/regression/session-timeline-collapse-state.spec.ts b/packages/app/e2e/regression/session-timeline-collapse-state.spec.ts index 18e63e2a1f..db191d2575 100644 --- a/packages/app/e2e/regression/session-timeline-collapse-state.spec.ts +++ b/packages/app/e2e/regression/session-timeline-collapse-state.spec.ts @@ -168,7 +168,9 @@ test.describe("regression: session timeline local row state", () => { }, }) - await expect(wrapper.locator('[data-slot="diff-changes-additions"]').filter({ hasText: "+2" }).first()).toBeVisible({ timeout: 10_000 }) + await expect(wrapper.locator('[data-slot="diff-changes-additions"]').filter({ hasText: "+2" }).first()).toBeVisible( + { timeout: 10_000 }, + ) expect(await readDiffProbe(page)).toEqual({ fileMarker: "before", shadowRoots: 0, toolMarker: "before" }) }) }) @@ -194,23 +196,29 @@ async function expectExpanded(locator: Locator, expected: boolean) { } async function readToolState(page: Page) { - return page.locator(`[data-timeline-part-id="${editPartID}"]`).first().evaluate((element, textPartID) => ({ - expanded: (() => { - const trigger = element.querySelector('[data-slot="collapsible-trigger"]') - const aria = trigger?.getAttribute("aria-expanded") - if (aria === "true") return true - if (aria === "false") return false + return page + .locator(`[data-timeline-part-id="${editPartID}"]`) + .first() + .evaluate( + (element, textPartID) => ({ + expanded: (() => { + const trigger = element.querySelector('[data-slot="collapsible-trigger"]') + const aria = trigger?.getAttribute("aria-expanded") + if (aria === "true") return true + if (aria === "false") return false - const root = element.querySelector('[data-component="collapsible"]') - if (root?.hasAttribute("data-expanded")) return true - if (root?.hasAttribute("data-closed")) return false + const root = element.querySelector('[data-component="collapsible"]') + if (root?.hasAttribute("data-expanded")) return true + if (root?.hasAttribute("data-closed")) return false - const content = element.querySelector('[data-slot="collapsible-content"]') - return !!content && content.getBoundingClientRect().height > 0 - })(), - row: element.closest("[data-timeline-row]")?.getAttribute("data-timeline-row"), - streamedTextVisible: !!document.querySelector(`[data-timeline-part-id="${textPartID}"]`), - }), textPartID) + const content = element.querySelector('[data-slot="collapsible-content"]') + return !!content && content.getBoundingClientRect().height > 0 + })(), + row: element.closest("[data-timeline-row]")?.getAttribute("data-timeline-row"), + streamedTextVisible: !!document.querySelector(`[data-timeline-part-id="${textPartID}"]`), + }), + textPartID, + ) } async function installDiffProbe(page: Page) { @@ -231,27 +239,33 @@ async function installDiffProbe(page: Page) { } async function markDiffProbe(page: Page) { - await page.locator(`[data-timeline-part-id="${editPartID}"]`).first().evaluate((element) => { - const tool = element as HTMLElement - const file = tool.querySelector('[data-component="file"][data-mode="diff"]') - if (!file) throw new Error("missing edit diff file") + await page + .locator(`[data-timeline-part-id="${editPartID}"]`) + .first() + .evaluate((element) => { + const tool = element as HTMLElement + const file = tool.querySelector('[data-component="file"][data-mode="diff"]') + if (!file) throw new Error("missing edit diff file") - tool.dataset.timelineProbe = "before" - file.dataset.timelineProbe = "before" - window.__timelineDiffProbe.reset() - }) + tool.dataset.timelineProbe = "before" + file.dataset.timelineProbe = "before" + window.__timelineDiffProbe.reset() + }) } async function readDiffProbe(page: Page) { - return page.locator(`[data-timeline-part-id="${editPartID}"]`).first().evaluate((element) => { - const tool = element as HTMLElement - const file = tool.querySelector('[data-component="file"][data-mode="diff"]') - return { - fileMarker: file?.dataset.timelineProbe, - shadowRoots: window.__timelineDiffProbe.shadowRoots(), - toolMarker: tool.dataset.timelineProbe, - } - }) + return page + .locator(`[data-timeline-part-id="${editPartID}"]`) + .first() + .evaluate((element) => { + const tool = element as HTMLElement + const file = tool.querySelector('[data-component="file"][data-mode="diff"]') + return { + fileMarker: file?.dataset.timelineProbe, + shadowRoots: window.__timelineDiffProbe.shadowRoots(), + toolMarker: tool.dataset.timelineProbe, + } + }) } function editPartWithAdditions(additions: number) { @@ -292,10 +306,23 @@ async function mockServer(page: Page, events: EventPayload[]) { const path = url.pathname if (path === "/global/event") return sse(route, events.splice(0)) - if (path === "/global/config" || path === "/config" || path === "/provider/auth" || path === "/mcp" || path === "/session/status") return json(route, {}) - if (["/skill", "/command", "/lsp", "/formatter", "/permission", "/question", "/vcs/status", "/vcs/diff"].includes(path)) return json(route, []) + if ( + path === "/global/config" || + path === "/config" || + path === "/provider/auth" || + path === "/mcp" || + path === "/session/status" + ) + return json(route, {}) + if ( + ["/skill", "/command", "/lsp", "/formatter", "/permission", "/question", "/vcs/status", "/vcs/diff"].includes( + path, + ) + ) + return json(route, []) if (path === "/provider") return json(route, provider()) - if (path === "/path") return json(route, { state: directory, config: directory, worktree: directory, directory, home: "C:/OpenCode" }) + if (path === "/path") + return json(route, { state: directory, config: directory, worktree: directory, directory, home: "C:/OpenCode" }) if (path === "/project") return json(route, [project()]) if (path === "/project/current") return json(route, project()) if (path === "/agent") return json(route, [{ name: "build", mode: "primary" }]) @@ -309,11 +336,26 @@ async function mockServer(page: Page, events: EventPayload[]) { } function project() { - return { id: projectID, worktree: directory, vcs: "git", name: "timeline-state-regression", time: { created: 1700000000000, updated: 1700000000000 }, sandboxes: [] } + return { + id: projectID, + worktree: directory, + vcs: "git", + name: "timeline-state-regression", + time: { created: 1700000000000, updated: 1700000000000 }, + sandboxes: [], + } } function session() { - return { id: sessionID, slug: "timeline-state-regression", projectID, directory, title, version: "dev", time: { created: 1700000000000, updated: 1700000000000 } } + return { + id: sessionID, + slug: "timeline-state-regression", + projectID, + directory, + title, + version: "dev", + time: { created: 1700000000000, updated: 1700000000000 }, + } } function provider() { diff --git a/packages/app/e2e/regression/session-timeline-context-resize.spec.ts b/packages/app/e2e/regression/session-timeline-context-resize.spec.ts index 50ea86e3c4..98f34b2b9c 100644 --- a/packages/app/e2e/regression/session-timeline-context-resize.spec.ts +++ b/packages/app/e2e/regression/session-timeline-context-resize.spec.ts @@ -8,12 +8,12 @@ const model = { providerID: "opencode", modelID: "claude-opus-4-6", variant: "ma const contextIDs = ["prt_0100_read", "prt_0101_glob", "prt_0102_grep", "prt_0103_list"] const followingTextID = "prt_0104_text" -type Message = { info: Record & { id: string; role: "user" | "assistant" }; parts: Record[] } +type Message = { + info: Record & { id: string; role: "user" | "assistant" } + parts: Record[] +} -const messages = [ - ...Array.from({ length: 8 }, (_, index) => turn(index, false)).flat(), - ...turn(10, true), -] +const messages = [...Array.from({ length: 8 }, (_, index) => turn(index, false)).flat(), ...turn(10, true)] test.describe("regression: session timeline context group resize", () => { test("remeasures a recent explored context group before the next paint", async ({ page }) => { @@ -76,7 +76,8 @@ async function sampleExpansion(page: Page) { const trigger = context?.querySelector('[data-slot="collapsible-trigger"]') const contextRow = context?.closest('[data-timeline-row="AssistantPart"]') const textRow = text?.closest('[data-timeline-row="AssistantPart"]') - if (!context || !text || !scroller || !trigger || !contextRow || !textRow) throw new Error("missing regression nodes") + if (!context || !text || !scroller || !trigger || !contextRow || !textRow) + throw new Error("missing regression nodes") scroller.scrollTop = scroller.scrollHeight const samples: { @@ -213,10 +214,17 @@ async function mockServer(page: Page) { const path = url.pathname if (path === "/global/event" || path === "/event") return sse(route) - if (["/global/config", "/config", "/provider/auth", "/mcp", "/session/status"].includes(path)) return json(route, {}) - if (["/skill", "/command", "/lsp", "/formatter", "/permission", "/question", "/vcs/status", "/vcs/diff"].includes(path)) return json(route, []) + if (["/global/config", "/config", "/provider/auth", "/mcp", "/session/status"].includes(path)) + return json(route, {}) + if ( + ["/skill", "/command", "/lsp", "/formatter", "/permission", "/question", "/vcs/status", "/vcs/diff"].includes( + path, + ) + ) + return json(route, []) if (path === "/provider") return json(route, provider()) - if (path === "/path") return json(route, { state: directory, config: directory, worktree: directory, directory, home: "C:/OpenCode" }) + if (path === "/path") + return json(route, { state: directory, config: directory, worktree: directory, directory, home: "C:/OpenCode" }) if (path === "/project") return json(route, [project()]) if (path === "/project/current") return json(route, project()) if (path === "/agent") return json(route, [{ name: "build", mode: "primary" }]) @@ -238,11 +246,26 @@ function id(prefix: string, index: number) { } function project() { - return { id: projectID, worktree: directory, vcs: "git", name: "context-resize-regression", time: { created: 1700000000000, updated: 1700000000000 }, sandboxes: [] } + return { + id: projectID, + worktree: directory, + vcs: "git", + name: "context-resize-regression", + time: { created: 1700000000000, updated: 1700000000000 }, + sandboxes: [], + } } function session() { - return { id: sessionID, slug: "context-resize-regression", projectID, directory, title, version: "dev", time: { created: 1700000000000, updated: 1700000000000 } } + return { + id: sessionID, + slug: "context-resize-regression", + projectID, + directory, + title, + version: "dev", + time: { created: 1700000000000, updated: 1700000000000 }, + } } function provider() { diff --git a/packages/app/src/pages/session/message-timeline.tsx b/packages/app/src/pages/session/message-timeline.tsx index c7b6176f09..c014cb5d96 100644 --- a/packages/app/src/pages/session/message-timeline.tsx +++ b/packages/app/src/pages/session/message-timeline.tsx @@ -1018,7 +1018,9 @@ export function MessageTimeline(props: { return ( ) @@ -1149,7 +1151,11 @@ export function MessageTimeline(props: { {(message) => (
- +
)} @@ -1178,7 +1184,10 @@ export function MessageTimeline(props: { return (
-
+
{renderAssistantPartGroup(assistantPartRow)}
diff --git a/packages/ui/src/components/file.tsx b/packages/ui/src/components/file.tsx index 51dae80584..bfcc05b40a 100644 --- a/packages/ui/src/components/file.tsx +++ b/packages/ui/src/components/file.tsx @@ -1089,8 +1089,12 @@ function DiffViewer(props: DiffFileProps) { return sampledChecksum(contents) } - const before = local.before ? { ...local.before, contents: beforeContents, cacheKey: cacheKey(beforeContents) } : undefined - const after = local.after ? { ...local.after, contents: afterContents, cacheKey: cacheKey(afterContents) } : undefined + const before = local.before + ? { ...local.before, contents: beforeContents, cacheKey: cacheKey(beforeContents) } + : undefined + const after = local.after + ? { ...local.after, contents: afterContents, cacheKey: cacheKey(afterContents) } + : undefined const targetChanged = local.fileDiff !== undefined ? instanceFileDiff !== local.fileDiff diff --git a/packages/ui/src/components/message-part.tsx b/packages/ui/src/components/message-part.tsx index ad3be26cb2..35912e119d 100644 --- a/packages/ui/src/components/message-part.tsx +++ b/packages/ui/src/components/message-part.tsx @@ -2278,7 +2278,12 @@ ToolRegistry.register({ } >
- +
diff --git a/packages/ui/src/components/session-diff.test.ts b/packages/ui/src/components/session-diff.test.ts index 617d7f4713..ba8fd395ea 100644 --- a/packages/ui/src/components/session-diff.test.ts +++ b/packages/ui/src/components/session-diff.test.ts @@ -71,7 +71,8 @@ describe("session diff", () => { test("keeps capped header-only patches partial", () => { const fileDiff = resolveFileDiff({ file: "a.ts", - patch: "Index: a.ts\n===================================================================\n--- a.ts\t\n+++ a.ts\t\n", + patch: + "Index: a.ts\n===================================================================\n--- a.ts\t\n+++ a.ts\t\n", }) expect(fileDiff.name).toBe("a.ts") diff --git a/packages/ui/src/components/tool-error-card.tsx b/packages/ui/src/components/tool-error-card.tsx index b75671bae5..ade7cc4b01 100644 --- a/packages/ui/src/components/tool-error-card.tsx +++ b/packages/ui/src/components/tool-error-card.tsx @@ -92,12 +92,7 @@ export function ToolErrorCard(props: ToolErrorCardProps) { return ( - +