From 10f6a4a50ce7e00a9e1207022f35fdf1384e5be4 Mon Sep 17 00:00:00 2001 From: spoukyii <61633921+spoukyii@users.noreply.github.com> Date: Tue, 3 Nov 2026 13:19:11 -0800 Subject: [PATCH 1/3] test(web): diff Copy path in a Windows workspace Renders the diff file header's copy button for a file in a Windows workspace and checks what reaches the clipboard. Since #19201 the Copy path item on an open file's tab writes Windows separators for a Windows workspace; the diff button still writes the Git path with forward slashes, and fails here. The existing case now names a POSIX workspace and keeps forward slashes. --- .../DiffFilePathCopyButton.browser.test.tsx | 16 +++++++++++++++- 1 file changed, 15 insertions(+), 1 deletion(-) diff --git a/apps/web/src/components/DiffFilePathCopyButton.browser.test.tsx b/apps/web/src/components/DiffFilePathCopyButton.browser.test.tsx index a2bec09ca960d..47f4cf1210ce2 100644 --- a/apps/web/src/components/DiffFilePathCopyButton.browser.test.tsx +++ b/apps/web/src/components/DiffFilePathCopyButton.browser.test.tsx @@ -8,7 +8,7 @@ import { AnchoredToastProvider } from "./ui/toast"; it("explains a denied clipboard write and lets the same path be copied again", async () => { await using screen = await render( - + , ); using write = vi @@ -28,3 +28,17 @@ it("explains a denied clipboard write and lets the same path be copied again", a expect(write).toHaveBeenCalledTimes(2); expect(write).toHaveBeenLastCalledWith("apps/web/src/index.ts"); }); + +it("copies a Windows workspace's file path with Windows separators", async () => { + await using screen = await render( + + + , + ); + using write = vi.spyOn(navigator.clipboard, "writeText").mockResolvedValue(undefined); + + await screen.getByRole("button", { name: "Copy file path" }).click(); + + await expect.element(page.getByText("Copied!", { exact: true })).toBeVisible(); + expect(write).toHaveBeenCalledWith("apps\\web\\src\\index.ts"); +}); From a8a3affae2713ffcfb89b29874f0521daee7c6c0 Mon Sep 17 00:00:00 2001 From: spoukyii <61633921+spoukyii@users.noreply.github.com> Date: Tue, 3 Nov 2026 13:19:11 -0800 Subject: [PATCH 2/3] fix(web): diff Copy path uses Windows separators in a Windows workspace The copy button on each file header in the diff panel wrote the Git path, so a file in a Windows workspace reached the clipboard as apps/web/src/index.ts. Since #19201 the Copy path item on an open file's tab writes apps\web\src\index.ts, and forward slashes are what Windows Open dialogs reject. The button now formats the path with formatFilePathForClipboard against the thread's workspace root, the helper #19201 put behind the other file path copy actions. POSIX workspaces keep forward slashes. Bug: diff panel Copy path copies forward slashes for a file in a Windows workspace --- apps/web/src/components/DiffFilePathCopyButton.tsx | 13 +++++++++++-- apps/web/src/components/DiffPanel.tsx | 5 ++++- 2 files changed, 15 insertions(+), 3 deletions(-) diff --git a/apps/web/src/components/DiffFilePathCopyButton.tsx b/apps/web/src/components/DiffFilePathCopyButton.tsx index ab42f126189ec..e77fdb48ab311 100644 --- a/apps/web/src/components/DiffFilePathCopyButton.tsx +++ b/apps/web/src/components/DiffFilePathCopyButton.tsx @@ -1,3 +1,4 @@ +import { formatFilePathForClipboard } from "@t3tools/client-runtime/media-actions"; import { Check, Copy } from "lucide"; import { useRef } from "react"; import { useCopyToClipboard } from "../hooks/useCopyToClipboard"; @@ -11,7 +12,13 @@ import { Button } from "./ui/button"; import { MorphIcon } from "~/components/MorphIcon"; import { Tooltip, TooltipPopup, TooltipTrigger } from "./ui/tooltip"; -export function DiffFilePathCopyButton({ filePath }: { filePath: string }) { +export function DiffFilePathCopyButton({ + filePath, + workspaceRoot, +}: { + filePath: string; + workspaceRoot: string | undefined; +}) { const ref = useRef(null); const { copyToClipboard, isCopied } = useCopyToClipboard({ onCopy: () => showAnchoredCopySuccessToast(ref), @@ -28,7 +35,9 @@ export function DiffFilePathCopyButton({ filePath }: { filePath: string }) { size="icon-micro" variant="ghost-muted" aria-label="Copy file path" - onClick={() => copyToClipboard(filePath, undefined)} + onClick={() => + copyToClipboard(formatFilePathForClipboard(filePath, workspaceRoot), undefined) + } /> } > diff --git a/apps/web/src/components/DiffPanel.tsx b/apps/web/src/components/DiffPanel.tsx index 0f1d1e9e28379..a7534e9371654 100644 --- a/apps/web/src/components/DiffPanel.tsx +++ b/apps/web/src/components/DiffPanel.tsx @@ -174,12 +174,14 @@ function DiffFileCollapseToggle({ function DiffFileHeaderSuffix({ filePath, + workspaceRoot, hasStat, error, truncated, onRetry, }: { filePath: string; + workspaceRoot: string | undefined; hasStat: boolean; error: boolean; truncated: boolean; @@ -188,7 +190,7 @@ function DiffFileHeaderSuffix({ return ( <> - + {hasStat ? ( onRetry(filePath)} /> @@ -1403,6 +1405,7 @@ export default function DiffPanel({ return ( Date: Sat, 14 Nov 2026 22:45:21 +0000 Subject: [PATCH 3/3] test(web): drop copy-success toast assertion removed on main Co-Authored-By: Claude Opus 5.5 --- .../web/src/components/DiffFilePathCopyButton.browser.test.tsx | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/apps/web/src/components/DiffFilePathCopyButton.browser.test.tsx b/apps/web/src/components/DiffFilePathCopyButton.browser.test.tsx index 71e1525b2fd01..0c5d46395f3ae 100644 --- a/apps/web/src/components/DiffFilePathCopyButton.browser.test.tsx +++ b/apps/web/src/components/DiffFilePathCopyButton.browser.test.tsx @@ -39,6 +39,5 @@ it("copies a Windows workspace's file path with Windows separators", async () => await screen.getByRole("button", { name: "Copy file path" }).click(); - await expect.element(page.getByText("Copied!", { exact: true })).toBeVisible(); - expect(write).toHaveBeenCalledWith("apps\\web\\src\\index.ts"); + await vi.waitFor(() => expect(write).toHaveBeenCalledWith("apps\\web\\src\\index.ts")); });