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"));
});